Repository navigation
Hook: project identity sidecar for multi-machine matching - #117
Conversation
JayantDevkar
left a comment
There was a problem hiding this comment.
Read through. Small, careful hook: silent exit 0 on every path, list-form git calls with timeouts, the encoded dir taken from transcript_path so it cannot disagree with Karma's encoding, atomic write with no mkdir. No blockers; three things to fix before it lands, and it lands together with #115.
Should fix
normalize_git_url(hooks/project_identity.py:56-64, and the same logic inapi/services/git_identity.py:71-86) collapses an Azure DevOps HTTPS URLhttps://dev.azure.com/org/proj/_git/repoto_git/repo, so unrelated Azure repos with the same name share one identity. Drop a_gitsegment before taking the last two parts, in both copies at once (the parity test requires them to agree), and add the case to the shared list.- The parity test's case list (
hooks/tests/test_project_identity.py:31-42) only has easy shapes. Add https with credentials,ssh://git@host:2222/o/r.gitwith a port, a trailing slash, an uppercase.GITsuffix, and Azure. SETUP.md:985-989, the "Removing a Hook" table has no row forproject_identity.py.
Nits
SETUP.md:979: give the snippet an explicit"timeout": 10like the other hook entries (worst case here is about 4 s of git on a synchronous SessionStart).- The hook never clears a stale sidecar if
originis later removed, and a change to the three key fields overwrites any extra fields. Fine, but say so in the doc, and confirm the four keys match what #115's indexer writes.
No CI covers hooks/, so none of the new tests have run anywhere yet; I'll add hooks/** to a workflow on main. Until then please run pytest hooks/tests on 3.9 before pushing the next revision.
Independent of the extra-session-roots stack (feature/extra-roots-core and feature/extra-roots-coverage); can merge in any order. SessionStart hook that writes karma-project.json (normalized git remote, subdir within the repo, project path) into the session's project dir. Machines whose ~/.claude is synced to a Karma install, but that don't run Karma themselves, use it so their projects match by git identity instead of by path. Stdlib only, Python 3.9+, never raises, writes atomically and only when the identity changed.
Review follow-up for JayantDevkar#117. - normalize_git_url (hook copy and api/services/git_identity.py): drop the Azure DevOps `_git` path segment before taking owner/repo, so https://dev.azure.com/org/proj/_git/repo yields proj/repo instead of _git/repo; strip the .git suffix case-insensitively. - Parity test cases: https with credentials, ssh:// with a port, trailing slash, uppercase .GIT, Azure (https and scp-style). The api parser tests get the same cases. - SETUP.md: explicit "timeout": 10 on the hook entry, a "Removing a Hook" row, and notes that the hook never clears a stale sidecar when origin is removed and overwrites extra keys when the identity changes.
… before the repo Two defects in the previous commit's normalize_git_url, in both copies: - The scp-style regex also matched scheme URLs with a port (ssh://git@host:2222/repo.git parsed as 2222/repo). Scheme URLs now go through the URL regex only, so that input is rejected. - Removing every `_git` segment lost a repo literally named _git. Only a `_git` directly before the repo (Azure DevOps) is dropped now, so https://github.com/owner/_git yields owner/_git. Parity and api tests cover both.
f342842 to
309a449
Compare
|
Rebased onto main and pushed two commits: Should fix
Nits
Verified on Python 3.9.13: |
…ir; honest temp-file assertion The sidecar now requires the transcript's grandparent to resolve to CLAUDE_CONFIG_DIR (or ~/.claude) /projects. The temp-file test globs the pid-suffixed name so it can fail. Claude-Session: https://claude.ai/code/session_019dHRodCxwuwTvnKtUNrUU7
|
Re-reviewed the two commits against the code: every item in your reply is as described (Azure Pushed 031d65f on top with three small things from the second read, so you don't have to round-trip:
40 + 31 tests pass, ruff clean. Lands together with #115 once that one's finishing commit is in. |
Summary
Adds
hooks/project_identity.py, an optionalSessionStarthook that writeskarma-project.jsoninto the session's project dir (~/.claude/projects/<encoded>/):{ "git_identity": "owner/repo", "subdir": "api", "project_path": "/home/me/code/repo/api", "written_by": "hook" }The file records which repository a project dir belongs to, independent of where the repo lives on disk. Extra session roots (#115) use it to match the same project across machines whose paths differ. Karma writes this file itself for machines running it; the hook covers machines whose
~/.claudeis synced to a Karma install but that don't run Karma.Independent of #115 and its follow-up: no shared code, merges in any order. Without #115 the file is simply not read.
Behavior
os.replace) and only when the identity changedoriginremote, when the repo root can't be determined, or when the cwd lies outside the repo root, so a wrongsubdirnever merges a subproject into its repo rootprojectsdir; reads stdin and git output as UTF-8 (non-ASCII paths on Windows)normalize_git_urlis a copy ofapi/services/git_identity.py's; a test compiles the API's version (without importing the API package) and checks both agreeDocs
SETUP.md→ Hook Configuration Reference → "Project Identity Sidecar (Multiple Machines)"Testing
hooks/tests/test_project_identity.py: URL normalization, subdir computation (Windows paths, case, unrelated paths), end-to-end runs against a temp git repo (write, skip unchanged, no remote, non-ASCII path, non-project dir, missing dir), malformed stdin, API parity. The 2 failures inhooks/tests(test_ticket_branch_detector.py) also fail on currentmainon Windows.