Files
rohitg00__agentmemory/tsdown.config.ts
T
Rohit Ghumare 249d8ff032 feat(commits): link agent sessions to git commits (#498)
* feat(commits): link agent sessions to git commits

Adds a commit-link layer so memories captured during an agent session
can be traced back to the git commit they produced, and vice versa.

What ships:

- KV.commits namespace storing CommitLink records keyed by full SHA.
- Session.commitShas[] back-reference for fast forward lookup.
- POST /agentmemory/session/commit upserts a link (sha, branch, repo,
  message, author, authoredAt, files, sessionId); merges sessionIds on
  re-link and preserves linkedAt.
- GET /agentmemory/session/by-commit?sha= hydrates the link plus its
  sessions.
- GET /agentmemory/commits?branch=&repo=&limit= lists recent links,
  filtered and sorted desc by linkedAt, limit clamp 1..500 (default 100).
- src/hooks/post-commit.ts shells git rev-parse/log/diff-tree and POSTs
  to /agentmemory/session/commit. Honors AGENTMEMORY_URL,
  AGENTMEMORY_SECRET, AGENTMEMORY_CWD, AGENTMEMORY_SESSION_ID,
  AGENTMEMORY_COMMIT_SHA. Best-effort, 1500 ms timeout. Wired into
  tsdown hookEntries so it bundles to dist/hooks/ and plugin/scripts/.
- Two MCP tools: memory_commit_lookup, memory_commits.
- Four user-invocable plugin skills:
  - commit-context: traces a file/function/line via git blame plus
    memory_commit_lookup plus memory_recall.
  - commit-history: lists agent-linked commits; parses branch=/repo=/
    limit= from $ARGUMENTS.
  - handoff: resumes the most recent session for cwd; surfaces an
    unanswered user-facing question before the brief.
  - recap: summarizes the last N sessions for cwd, grouped by date;
    parses last <n> / today / this week.

Wire-up to capture from a real repo:

    ln -sf "$(realpath node_modules/agentmemory/dist/hooks/post-commit.mjs)" .git/hooks/post-commit
    chmod +x .git/hooks/post-commit

No new dependencies. Additive only.

* fix(commits): address CI + review findings on commit-link feature

- Update mcp-standalone.test.ts to expect 14 CORE_TOOLS (was 12) now that
  memory_commit_lookup and memory_commits are registered. Restores CI on
  Node 20 and 22.
- Wrap CommitLink upsert and session.commitShas mutation in withKeyedLock
  to prevent lost updates when concurrent post-commit hooks race against
  each other or against api::session::commit callers. Locks keyed by
  `commit:<sha>` and `session:<sessionId>` so unrelated writers do not
  serialize.
- Parallelize hydration of linked sessions via Promise.all in both
  api::session::by-commit and the memory_commit_lookup MCP handler;
  serial kv.get loops dragged response time for commits with many
  sessions.
- Sharpen handoff SKILL.md project-path matching: resolve relative
  $ARGUMENTS to an absolute normalized path and require directory-
  boundary equality, not raw string prefix, so sibling repos sharing a
  prefix do not collide.
- Sharpen commit-history SKILL.md HTTP fallback: build the
  /agentmemory/commits URL with URL-encoded query values so branch and
  repo values containing `?`, `&`, or `#` cannot corrupt the request.

* chore(consistency): bump documented tool and endpoint counts

Bring README.md, AGENTS.md, and the boot log in src/index.ts in line
with the live tool registry (53 MCP tools, +2 from this branch) and
the live REST registration (124 endpoints, +3 from this branch).

The Consistency test in test/consistency.test.ts derives both counts
from source and asserts the markdown matches; this commit only updates
the literal numbers, no behavior change.
2026-05-18 11:19:47 +01:00

79 lines
1.9 KiB
TypeScript

import { defineConfig } from "tsdown";
const hookEntries = [
"src/hooks/session-start.ts",
"src/hooks/prompt-submit.ts",
"src/hooks/pre-tool-use.ts",
"src/hooks/post-tool-use.ts",
"src/hooks/post-tool-failure.ts",
"src/hooks/pre-compact.ts",
"src/hooks/subagent-start.ts",
"src/hooks/subagent-stop.ts",
"src/hooks/notification.ts",
"src/hooks/task-completed.ts",
"src/hooks/stop.ts",
"src/hooks/session-end.ts",
"src/hooks/post-commit.ts",
];
const shared = {
format: ["esm"] as const,
target: "node20" as const,
inlineOnly: false as const,
// Keep as node_modules imports. We never import onnxruntime-{node,web}
// directly; they come in transitively through @xenova/transformers, which
// is lazy-loaded from src/providers/embedding/{clip,local}.ts and
// src/state/reranker.ts. Bundling inlines relative paths like
// `../bin/napi-v3/darwin/arm64/onnxruntime_binding.node` that no longer
// resolve from dist/. All three are declared as optionalDependencies in
// package.json so users can install them only when they enable local
// embeddings / CLIP / reranker.
external: [
"@xenova/transformers",
"onnxruntime-node",
"onnxruntime-web",
"@anthropic-ai/claude-agent-sdk",
"@anthropic-ai/sdk",
] as const,
};
export default defineConfig([
{
entry: ["src/index.ts"],
outDir: "dist",
...shared,
dts: true,
clean: true,
sourcemap: true,
banner: { js: "#!/usr/bin/env node" },
},
{
entry: ["src/cli.ts"],
outDir: "dist",
...shared,
clean: false,
sourcemap: false,
},
{
entry: ["src/mcp/standalone.ts"],
outDir: "dist",
...shared,
clean: false,
sourcemap: false,
},
{
entry: hookEntries,
outDir: "dist/hooks",
...shared,
clean: false,
sourcemap: false,
},
{
entry: hookEntries,
outDir: "plugin/scripts",
...shared,
clean: false,
sourcemap: false,
},
]);