Skip to content

Windows: fix session-dir slug mismatch and Python detection#29

Merged
fdaviddpt merged 2 commits intoDigital-Process-Tools:mainfrom
evikzub:fix/windows-slug-and-python-detection
Apr 25, 2026
Merged

Windows: fix session-dir slug mismatch and Python detection#29
fdaviddpt merged 2 commits intoDigital-Process-Tools:mainfrom
evikzub:fix/windows-slug-and-python-detection

Conversation

@evikzub
Copy link
Copy Markdown
Contributor

@evikzub evikzub commented Apr 23, 2026

Summary

Two independent Windows-compatibility fixes. Together, they unblock the memory pipeline on Windows 11 + MSYS2 — on my machine, .remember/now.md and today-*.md were never being written before these changes even though the hooks were registered and running.

Independent of #28 (the bootstrap mkdir -p + TMPDIR + README PR) — no merge conflicts expected either way. Each commit is also independent and can be cherry-picked.

Commit 1 — fix(windows): match Claude Code's native session-dir slug

Every post-tool-hook.sh / session-start-hook.sh / save-session.sh run needs to locate the current session's JSONL under ~/.claude/projects/<slug>/, where <slug> is Claude Code's own slug of the project path.

  • On Linux/macOS: Claude Code slugs the native path (/home/u/p-home-u-p). Hook scripts see the same path. Works.
  • On Windows: Claude Code slugs the native Windows path with the drive letter lowercased (D:\Projects\Food--Projects-Foo). Hook scripts on Git Bash / MSYS receive the path in POSIX form (/d/Projects/Foo), which slugs to -d-Projects-Foo — a directory that never exists. post-tool-hook.sh then exits silently at line 46 (no JSONL found), and no save ever runs.

Teach session_dir_slug() in detect-tools.sh to detect MSYS/Cygwin via cygpath, convert the POSIX path back to Windows form, lowercase the drive letter, and slug. No behavior change where cygpath is absent (macOS/Linux).

Replace three inline sed '[^a-zA-Z0-9]/-/g' call sites with session_dir_slug() so the fix is centralized — the helper was already sourced in all three scripts but wasn't being used.

Repro

On Windows 11 + MSYS2 + project at D:\Projects\Foo:

```bash
$ echo "$PROJECT" # what the plugin sees
/d/Projects/Foo
$ echo "$PROJECT" | sed 's/[^a-zA-Z0-9]/-/g' # old slug
-d-Projects-Foo
$ ls ~/.claude/projects/ # what actually exists
d--Projects-Foo/
```

Mismatch → `post-tool-hook.sh:46 [ -n "$LATEST_JSONL" ] || exit 0` fires → no save.

Commit 2 — fix(windows): validate Python interpreter and add py launcher fallback

Separate failure mode on Windows without Store-installed Python: python3 and sometimes python resolve to a Microsoft Store placeholder (a stub in %LOCALAPPDATA%\Microsoft\WindowsApps\ that only opens the Store). command -v python3 returns success on the stub, but actually running it prints "Python was not found" and exits non-zero. save-session.sh then fails midway with arithmetic errors on unset variables the Python pipeline was supposed to set.

Switch detection from command -v to a validation loop: for each candidate, verify <candidate> -V actually runs. Also add the Windows py launcher (py -3, py) as further fallbacks.

\$PYTHON is already used unquoted throughout the scripts, so multi-word values like "py -3" expand as two tokens correctly.

Test plan

  • Applied both commits' changes locally at ~/.claude/plugins/cache/claude-plugins-official/remember/0.5.0/ on Windows 11 + MSYS2 + jq + Python 3.10 installed outside Store. Before: .remember/now.md never created; log showed only [hook] post-tool: breadcrumbs. After: full pipeline runs — [extract] 187 exchanges, [haiku] calling, [tokens], [write] appended, [ndc] running. .remember/now.md + .remember/today-*.md populated correctly.
  • scripts/run-tests.sh — not executed by this contributor on Windows (test harness assumes Unix mktemp paths). Maintainer Unix CI run would be appreciated.

Not changed (potential follow-ups)

  • pipeline/extract.py::_session_dir() uses the same Unix-form slug strategy. It was not exercised in my testing because save-session.sh passes the session ID directly, but code paths that call it standalone (e.g., recovery with only project_dir) may still produce the wrong Windows slug. Worth a follow-up.
  • scripts/run-tests.sh:135 has the same inline sed slug pattern. Test-only code; would be trivial to switch to session_dir_slug for consistency.

evikzub added 2 commits April 23, 2026 22:57
Every post-tool / session-start / save-session invocation needs to
locate the current session's JSONL file under ~/.claude/projects/<slug>/,
where <slug> is Claude Code's own slug of the project path.

On Windows, Claude Code slugs the **native Windows path** with a
lowercase drive letter (e.g. D:\Projects\Foo → d--Projects-Foo).
Hook scripts on Git Bash / MSYS receive the path in POSIX form
(/d/Projects/Foo), which slugs to -d-Projects-Foo — a directory that
never exists. post-tool-hook.sh then exits silently at line 46
(no JSONL found), and no save ever runs.

Teach session_dir_slug() to detect MSYS/Cygwin (via cygpath), convert
the POSIX path back to the native Windows form, lowercase the drive
letter, and then slug. No behavior change on macOS/Linux where
cygpath is absent.

Replace the three inline `sed '[^a-zA-Z0-9]/-/g'` call sites with
session_dir_slug() so the fix is centralized.

Verified on Windows 11 + MSYS2 bash 5.2: computed slug now matches
the actual ~/.claude/projects directory; the save pipeline runs
extract → haiku → write end-to-end.
On Windows without Store-installed Python, `python3` and sometimes
`python` resolve to a Microsoft Store placeholder — a stub binary in
%LOCALAPPDATA%\Microsoft\WindowsApps that only opens the Store.
`command -v python3` returns success on the stub, but actually
running it prints a "Python was not found" message and exits
non-zero. save-session.sh then fails midway with arithmetic errors
on unset variables the Python pipeline was supposed to set.

Switch detection to a validation loop: for each candidate, check
that `<candidate> -V` actually runs successfully. Also add the
Windows `py` launcher (`py -3`, `py`) as further fallbacks.

$PYTHON is already used unquoted throughout the scripts, so a
multi-word value like "py -3" expands as two tokens correctly.

Verified on Windows 11 + MSYS2: detection now picks the real
Python interpreter instead of the Store stub, save pipeline
completes and writes to .remember/now.md.
@josemoreno801-netizen
Copy link
Copy Markdown
Contributor

Heads-up on a likely merge conflict — I just opened PR #30 (BSD mktemp portability fix on macOS), which touches the same mktemp template lines in scripts/save-session.sh and scripts/run-tests.sh that this PR also modifies. The intents are orthogonal (BSD compatibility vs. Windows path/Python detection), but the line overlap will produce conflict markers.

Suggested merge order to keep both clean:

  1. Land PR fix(shell): make mktemp templates work on BSD mktemp (macOS) #30 first — small, surgical, two-file scope.
  2. Quick rebase here on the new main (mktemp lines now end at XXXXXX); the rebase should be mechanical, not semantic.

Happy to coordinate or rebase from my side if helpful — and great work on the Windows fixes, the slug mismatch one in particular is subtle.

@evikzub
Copy link
Copy Markdown
Contributor Author

evikzub commented Apr 24, 2026

Thanks for the heads-up, appreciated.

I ran the merge both ways locally to check:

So the merge should be mechanical whichever order the maintainer picks, and no rebase is strictly required from my end. Happy to rebase anyway if you'd prefer to keep history linear — just say the word.

Great fix on the BSD mktemp issue, by the way — I didn't have a macOS box to catch that one.

Copy link
Copy Markdown
Contributor

@fdaviddpt fdaviddpt left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excellent work @evikzub — this is exactly what the plugin needed for Windows support. Thank you for the thorough approach!

The Python detection improvement is particularly smart: validating with -V to catch the Microsoft Store stub that passes command -v but doesn't actually run is the kind of edge case that only someone debugging on Windows would catch. The py -3 / py launcher fallback covers the common python.org install path too.

The session_dir_slug with cygpath is the correct fix for the slug mismatch — Git Bash receives Unix-style paths but Claude Code slugs the native Windows path. Without this, the plugin can't find session files on Windows at all.

Both changes are well-scoped, well-documented, and the commit messages explain the why clearly.

We just shipped PR #33 which touches some of the same files (bootstrap-dirs.sh, hooks.json, post-tool-hook.sh, session-start-hook.sh) — there may be minor merge conflicts but they should be trivial to resolve. Happy to help if needed.

Thanks again for making the plugin work on Windows — with 20k installs, every platform matters. 🙏

@fdaviddpt
Copy link
Copy Markdown
Contributor

Quick update on the items you flagged:

scripts/run-tests.sh — not executed by this contributor on Windows (test harness assumes Unix mktemp paths)

Already fixed in #33 commit 2 — all mktemp calls in run-tests.sh now use $SYS_TMPDIR (${TMPDIR:-/tmp}) instead of hardcoded /tmp/. Should work on Windows/Git Bash now.

scripts/run-tests.sh:135 has the same inline sed slug pattern

Good catch — after your PR merges, we'll update that line to use session_dir_slug for consistency. Trivial follow-up.

pipeline/extract.py::_session_dir() uses the same Unix-form slug strategy

Also noted — the Python side might need the same cygpath treatment for standalone recovery calls. Worth a follow-up issue if someone hits it.

Merging now — thanks again for the thorough testing and the honest checklist!

@fdaviddpt fdaviddpt merged commit 5093f96 into Digital-Process-Tools:main Apr 25, 2026
fdaviddpt pushed a commit that referenced this pull request May 2, 2026
)

Thanks @kanelavish-a11y — solid diagnosis, the POSIX form was a real gap left by #29. Patched the bash 3.2 compat issue (`^^` → `tr`) so the test runs green on macOS dev machines too.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants