Skip to content

fix(coding-agents): resolve the project when the working directory is gone (supersedes #3110) - #3410

Merged
nicoloboschi merged 2 commits into
mainfrom
fix/coding-agents-project-resolution-3110
Aug 12, 2026
Merged

fix(coding-agents): resolve the project when the working directory is gone (supersedes #3110)#3410
nicoloboschi merged 2 commits into
mainfrom
fix/coding-agents-project-resolution-3110

Conversation

@nicoloboschi

Copy link
Copy Markdown
Collaborator

Ports #3110's idea to the Coding Agents plugin, which supersedes the per-agent Claude Code plugin that PR targets.

The failure

A hook runs after the fact, so the directory it reports can already be deleted — an ephemeral worktree removed once its task finished, or a checkout moved mid-session. git can only answer about a path that exists, so the probe fails and basename of the vanished path becomes the project identity: a throwaway name like agent-a33c4d63, scattering memory into orphan banks.

The fix, for every harness

@jouve's PR rescues this with CLAUDE_PROJECT_DIR. That works, but only for the one harness that exports it — we support eleven, and only Claude Code is known to publish such a variable. Inventing names for the other ten would be registering behaviour nothing implements.

So the primary mechanism here is harness-agnostic: walk up to the nearest ancestor that still exists and probe that. It needs nothing from the harness, and it covers the reported shape directly (<repo>/.agent/worktrees/agent-x deleted → <repo> resolves → the repository's name). For a live directory the walk returns it unchanged, so the common path is untouched and no existing bank moves.

CLAUDE_PROJECT_DIR is kept as a last rescue for the one case the walk cannot reach: a linked worktree is a sibling of the repository, not a child, so walking up from it leaves the repository entirely. Deliberately a list of one, easy to extend if another harness turns out to export an equivalent.

Also: no more empty project names

basename("/") is "", which produced bank ids like coding-agent:: that name nothing — flagged while reviewing #3286 and never fixed. Both {gitProject} and {project} now fall back to "unknown".

Test

453 passed, 21 skipped; tsc and lint clean.

Six new cases in their own file, using real git against real directories rather than the mocked child_process of bank.test.ts — what is under test is behaviour against paths that do and do not exist, which a mock can't tell you: the deleted leaf resolving to its repository, a live directory keeping its historical answer, the exported root rescuing a deleted linked worktree, a resolvable directory winning over that variable, no empty names, and a plain non-git directory still getting one.

… gone

Supersedes #3110, filed against the per-agent Claude Code plugin.

A hook runs after the fact, so the directory it reports can already be deleted —
an ephemeral worktree removed once the task finished, a checkout moved or deleted
mid-session. git can only answer about a path that exists, so the probe failed
and `basename` of the vanished path became the project identity: a throwaway name
like `agent-a33c4d63` that scatters memory into orphan banks.

Resolution now walks up to the nearest ancestor that still exists and probes
that. This is harness-agnostic on purpose: no harness has to export anything, so
it covers all eleven rather than the one that happens to publish a project-root
variable. For a live directory the walk returns it unchanged, so the common path
is untouched and no existing bank moves.

CLAUDE_PROJECT_DIR is kept as a last rescue for the one case the walk cannot
reach: a LINKED worktree is a sibling of the repository, not a child, so walking
up from it leaves the repository entirely. It is deliberately a list of one
rather than a guess at nine names — only Claude Code is known to export such a
variable, and inventing the others would register behaviour nothing implements.

Also stops project names from being empty. `basename("/")` is "", which produced
bank ids like `coding-agent::` naming nothing; both `{gitProject}` and
`{project}` now fall back to "unknown". That case was flagged reviewing #3286 and
never fixed.

Tests use real git against real directories rather than the mocked
child_process of bank.test.ts, since what is under test is behaviour against
paths that do and do not exist.
Generated artifact missing on main: #3394 added
hindsight-docs/docs-integrations/agent-plugin.md without regenerating the docs
skill, so skills/.../integrations/agent-plugin.md was never committed.

verify-generated-files only runs on PRs, so the drift is invisible on main and
surfaces as a failure on the next unrelated PR — this one. Separate commit
because it is not part of the project-resolution fix.
@nicoloboschi
nicoloboschi merged commit d3f97da into main Aug 12, 2026
90 checks passed
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.

1 participant