Skip to content

Feature: auto-reindex on Bash file ops (rm/mv/cp/git-rm/redirection) #14

@gabiudrescu

Description

@gabiudrescu

User Story

As a developer using engram install-hook --auto-reindex (landing in #13), I want my knowledge graph to stay in sync when an agent uses Bash for file operations — not just Edit/Write/MultiEdit — so that rm src/foo.ts, mv old.ts new.ts, and git rm don't leave stale nodes in the graph until the next explicit edit.

Context

#13 wires engram reindex-hook into a PostToolUse entry with matcher Edit|Write|MultiEdit. That covers the native Claude Code editing tools but not file ops the agent routinely runs through Bash — rm, mv, cp, git rm, git mv, output redirection (cat ... > foo.ts). Those produce a PostToolUse event with tool_name: "Bash" and tool_input.command as a string, which the current matcher explicitly excludes.

Hit this live while testing #13: removed the probe file via rm, then had to manually run engram reindex <deleted-file> to get the prune. engram watch (long-running fs.watch) catches this case natively via the rename event handler added in #9/#12 — but the hook-based model loses it.

Proposal

Widen the auto-reindex PostToolUse matcher to also include Bash, and parse tool_input.command to extract affected paths. For each path found, call syncFile(absPath, projectRoot) — same primitive engram reindex and reindex-hook already use, same silent-skip behavior for non-code / missing-unindexed / ignored-dir cases.

Minimum viable coverage:

  • rm [-rf] <paths...> — each path becomes a prune candidate
  • mv <src> <dst> — prune src, reindex dst
  • cp <src> <dst> — reindex dst only
  • git rm [-r] <paths...> — prune candidates
  • git mv <src> <dst> — prune + reindex
  • > <path> / >> <path> redirections — reindex target

Defer or decline:

  • touch <path> — creates empty files, graph would be empty anyway
  • find ... | xargs rm / pipe-through-xargs — best left to engram watch or explicit engram reindex
  • Directory-level prune (rm -rf src/) — already called out in the current CHANGELOG under v2.2 as needing per-file directory-prefix pruning before it's safe

Precedent & primitives

src/intercept/handlers/bash.ts already parses Read-like bash (cat, head, less, etc.) for the PreToolUse interception path. Extending that module (or mirroring its lexer in a new parseWriteLikeBashCommand()) is the natural home — same quoting/glob/sudo edge cases already handled there.

The hook contract remains always exit 0 — any parser ambiguity resolves to "skip this path" rather than error.

Acceptance criteria

  1. engram install-hook --auto-reindex registers a PostToolUse entry whose matcher includes Bash (proposed: Edit|Write|MultiEdit|Bash).
  2. engram reindex-hook handles Bash payloads: detects the command verbs above, resolves each path against cwd, calls syncFile.
  3. Unrecognized commands (git log, npm install, tests, etc.) are silent no-ops.
  4. Unparseable commands (heavy piping, unusual quoting) are silent no-ops.
  5. Tests:
    • parseWriteLikeBashCommand("rm src/foo.ts")[{ action: "prune", path: "src/foo.ts" }]
    • parseWriteLikeBashCommand("mv a.ts b.ts")[{ action: "prune", path: "a.ts" }, { action: "reindex", path: "b.ts" }]
    • E2E: runReindexHook with a Bash payload re-indexes / prunes as expected.
    • Unknown commands leave the graph untouched.

Notes

Investigated with AI assistance and human review.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions