@tyroneross/bookmark 0.2.0 → 0.3.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (105) hide show
  1. package/.claude-plugin/marketplace.json +29 -12
  2. package/.claude-plugin/plugin.json +12 -8
  3. package/.codex-plugin/plugin.json +31 -0
  4. package/.mcp.json +8 -0
  5. package/CLAUDE.md +82 -38
  6. package/LICENSE +202 -21
  7. package/README.md +150 -57
  8. package/agents/snapshot-analyst.md +1 -1
  9. package/commands/bookmark.md +29 -0
  10. package/commands/feedback.md +37 -0
  11. package/commands/restore.md +14 -4
  12. package/commands/snapshot.md +19 -7
  13. package/commands/status.md +1 -1
  14. package/dist/cli/index.js +600 -66
  15. package/dist/cli/index.js.map +1 -1
  16. package/dist/cli/snapshot-resolution.d.ts +15 -0
  17. package/dist/cli/snapshot-resolution.d.ts.map +1 -0
  18. package/dist/cli/snapshot-resolution.js +21 -0
  19. package/dist/cli/snapshot-resolution.js.map +1 -0
  20. package/dist/config.d.ts +19 -0
  21. package/dist/config.d.ts.map +1 -1
  22. package/dist/config.js +150 -19
  23. package/dist/config.js.map +1 -1
  24. package/dist/context/freshness.d.ts +3 -0
  25. package/dist/context/freshness.d.ts.map +1 -0
  26. package/dist/context/freshness.js +29 -0
  27. package/dist/context/freshness.js.map +1 -0
  28. package/dist/context/handoff-prompt.d.ts +12 -0
  29. package/dist/context/handoff-prompt.d.ts.map +1 -0
  30. package/dist/context/handoff-prompt.js +29 -0
  31. package/dist/context/handoff-prompt.js.map +1 -0
  32. package/dist/index.d.ts +7 -4
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +5 -3
  35. package/dist/index.js.map +1 -1
  36. package/dist/mcp/server.d.ts +9 -0
  37. package/dist/mcp/server.d.ts.map +1 -0
  38. package/dist/mcp/server.js +85 -0
  39. package/dist/mcp/server.js.map +1 -0
  40. package/dist/mcp/tools.d.ts +97 -0
  41. package/dist/mcp/tools.d.ts.map +1 -0
  42. package/dist/mcp/tools.js +304 -0
  43. package/dist/mcp/tools.js.map +1 -0
  44. package/dist/registry.d.ts +40 -0
  45. package/dist/registry.d.ts.map +1 -0
  46. package/dist/registry.js +134 -0
  47. package/dist/registry.js.map +1 -0
  48. package/dist/restore/index.d.ts +13 -1
  49. package/dist/restore/index.d.ts.map +1 -1
  50. package/dist/restore/index.js +154 -256
  51. package/dist/restore/index.js.map +1 -1
  52. package/dist/setup/auto-setup.d.ts +8 -2
  53. package/dist/setup/auto-setup.d.ts.map +1 -1
  54. package/dist/setup/auto-setup.js +281 -66
  55. package/dist/setup/auto-setup.js.map +1 -1
  56. package/dist/setup/configure-hooks.d.ts +14 -3
  57. package/dist/setup/configure-hooks.d.ts.map +1 -1
  58. package/dist/setup/configure-hooks.js +156 -24
  59. package/dist/setup/configure-hooks.js.map +1 -1
  60. package/dist/snapshot/capture.d.ts +12 -10
  61. package/dist/snapshot/capture.d.ts.map +1 -1
  62. package/dist/snapshot/capture.js +36 -48
  63. package/dist/snapshot/capture.js.map +1 -1
  64. package/dist/snapshot/compress.d.ts +3 -3
  65. package/dist/snapshot/compress.d.ts.map +1 -1
  66. package/dist/snapshot/compress.js +16 -51
  67. package/dist/snapshot/compress.js.map +1 -1
  68. package/dist/snapshot/storage.d.ts +1 -0
  69. package/dist/snapshot/storage.d.ts.map +1 -1
  70. package/dist/snapshot/storage.js +7 -6
  71. package/dist/snapshot/storage.js.map +1 -1
  72. package/dist/threshold/state.d.ts +5 -0
  73. package/dist/threshold/state.d.ts.map +1 -1
  74. package/dist/threshold/state.js +28 -2
  75. package/dist/threshold/state.js.map +1 -1
  76. package/dist/threshold/token-usage.d.ts +29 -0
  77. package/dist/threshold/token-usage.d.ts.map +1 -0
  78. package/dist/threshold/token-usage.js +128 -0
  79. package/dist/threshold/token-usage.js.map +1 -0
  80. package/dist/trails/identity.d.ts +76 -0
  81. package/dist/trails/identity.d.ts.map +1 -0
  82. package/dist/trails/identity.js +117 -0
  83. package/dist/trails/identity.js.map +1 -0
  84. package/dist/trails/reader.d.ts +1 -1
  85. package/dist/trails/reader.js +2 -2
  86. package/dist/trails/reader.js.map +1 -1
  87. package/dist/trails/writer.d.ts +2 -8
  88. package/dist/trails/writer.d.ts.map +1 -1
  89. package/dist/trails/writer.js +33 -191
  90. package/dist/trails/writer.js.map +1 -1
  91. package/dist/transcript/extractor.d.ts +8 -9
  92. package/dist/transcript/extractor.d.ts.map +1 -1
  93. package/dist/transcript/extractor.js +97 -360
  94. package/dist/transcript/extractor.js.map +1 -1
  95. package/dist/types.d.ts +34 -41
  96. package/dist/types.d.ts.map +1 -1
  97. package/hooks/hooks.json +12 -14
  98. package/package.json +13 -7
  99. package/scripts/install-plugin.sh +48 -0
  100. package/skills/context-continuity/SKILL.md +43 -24
  101. package/commands/activate.md +0 -20
  102. package/dist/transcript/estimator.d.ts +0 -20
  103. package/dist/transcript/estimator.d.ts.map +0 -1
  104. package/dist/transcript/estimator.js +0 -95
  105. package/dist/transcript/estimator.js.map +0 -1
@@ -0,0 +1,85 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Bookmark MCP Server
4
+ *
5
+ * JSON-RPC 2.0 over stdio (MCP protocol).
6
+ * Exposes context snapshot tools: snapshot, restore, status, list, show.
7
+ */
8
+ import { createInterface } from "readline";
9
+ import { TOOLS, handleToolCall } from "./tools.js";
10
+ // --- JSON-RPC transport over stdio ---
11
+ const rl = createInterface({ input: process.stdin, terminal: false });
12
+ let buffer = "";
13
+ rl.on("line", (line) => {
14
+ buffer += line;
15
+ try {
16
+ const msg = JSON.parse(buffer);
17
+ buffer = "";
18
+ handleMessage(msg);
19
+ }
20
+ catch {
21
+ // Incomplete JSON, keep buffering
22
+ }
23
+ });
24
+ function send(msg) {
25
+ process.stdout.write(JSON.stringify(msg) + "\n");
26
+ }
27
+ function sendResult(id, result) {
28
+ send({ jsonrpc: "2.0", id, result });
29
+ }
30
+ function sendError(id, code, message) {
31
+ send({ jsonrpc: "2.0", id, error: { code, message } });
32
+ }
33
+ // --- MCP Protocol ---
34
+ const SERVER_INFO = {
35
+ name: "bookmark",
36
+ version: "0.3.2",
37
+ };
38
+ const CAPABILITIES = {
39
+ tools: {},
40
+ };
41
+ // --- Message handler ---
42
+ async function handleMessage(msg) {
43
+ if (msg.jsonrpc !== "2.0")
44
+ return;
45
+ const { id, method, params } = msg;
46
+ try {
47
+ switch (method) {
48
+ case "initialize": {
49
+ sendResult(id, {
50
+ protocolVersion: "2025-11-25",
51
+ serverInfo: SERVER_INFO,
52
+ capabilities: CAPABILITIES,
53
+ });
54
+ break;
55
+ }
56
+ case "notifications/initialized": {
57
+ // Client acknowledged — no response needed
58
+ break;
59
+ }
60
+ case "tools/list": {
61
+ sendResult(id, { tools: TOOLS });
62
+ break;
63
+ }
64
+ case "tools/call": {
65
+ const { name, arguments: args } = params;
66
+ const result = await handleToolCall(name, args || {});
67
+ sendResult(id, result);
68
+ break;
69
+ }
70
+ default: {
71
+ if (id !== undefined) {
72
+ sendError(id, -32601, `Method not found: ${method}`);
73
+ }
74
+ }
75
+ }
76
+ }
77
+ catch (err) {
78
+ if (id !== undefined) {
79
+ sendError(id, -32000, err instanceof Error ? err.message : "Internal error");
80
+ }
81
+ }
82
+ }
83
+ // Log to stderr so it doesn't interfere with the protocol
84
+ process.stderr.write("Bookmark MCP server started\n");
85
+ //# sourceMappingURL=server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"server.js","sourceRoot":"","sources":["../../src/mcp/server.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * Bookmark MCP Tool Definitions
3
+ *
4
+ * Each tool maps to existing Bookmark programmatic APIs.
5
+ * Responses are formatted as concise text for LLM consumption.
6
+ */
7
+ export declare const TOOLS: ({
8
+ name: string;
9
+ description: string;
10
+ inputSchema: {
11
+ type: "object";
12
+ properties: {
13
+ trigger: {
14
+ type: string;
15
+ enum: string[];
16
+ description: string;
17
+ };
18
+ snapshot_id?: undefined;
19
+ limit?: undefined;
20
+ };
21
+ };
22
+ annotations: {
23
+ title: string;
24
+ readOnlyHint: boolean;
25
+ destructiveHint: boolean;
26
+ idempotentHint: boolean;
27
+ openWorldHint: boolean;
28
+ };
29
+ } | {
30
+ name: string;
31
+ description: string;
32
+ inputSchema: {
33
+ type: "object";
34
+ properties: {
35
+ snapshot_id: {
36
+ type: string;
37
+ description: string;
38
+ };
39
+ trigger?: undefined;
40
+ limit?: undefined;
41
+ };
42
+ };
43
+ annotations: {
44
+ title: string;
45
+ readOnlyHint: boolean;
46
+ destructiveHint: boolean;
47
+ idempotentHint: boolean;
48
+ openWorldHint: boolean;
49
+ };
50
+ } | {
51
+ name: string;
52
+ description: string;
53
+ inputSchema: {
54
+ type: "object";
55
+ properties: {
56
+ trigger?: undefined;
57
+ snapshot_id?: undefined;
58
+ limit?: undefined;
59
+ };
60
+ };
61
+ annotations: {
62
+ title: string;
63
+ readOnlyHint: boolean;
64
+ destructiveHint: boolean;
65
+ idempotentHint: boolean;
66
+ openWorldHint: boolean;
67
+ };
68
+ } | {
69
+ name: string;
70
+ description: string;
71
+ inputSchema: {
72
+ type: "object";
73
+ properties: {
74
+ limit: {
75
+ type: string;
76
+ description: string;
77
+ };
78
+ trigger?: undefined;
79
+ snapshot_id?: undefined;
80
+ };
81
+ };
82
+ annotations: {
83
+ title: string;
84
+ readOnlyHint: boolean;
85
+ destructiveHint: boolean;
86
+ idempotentHint: boolean;
87
+ openWorldHint: boolean;
88
+ };
89
+ })[];
90
+ export declare function handleToolCall(name: string, args: Record<string, unknown>): Promise<{
91
+ content: Array<{
92
+ type: string;
93
+ text: string;
94
+ }>;
95
+ isError?: boolean;
96
+ }>;
97
+ //# sourceMappingURL=tools.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.d.ts","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAgDH,eAAO,MAAM,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAwGjB,CAAC;AAIF,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC5B,OAAO,CAAC;IAAE,OAAO,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAqBhF"}
@@ -0,0 +1,304 @@
1
+ /**
2
+ * Bookmark MCP Tool Definitions
3
+ *
4
+ * Each tool maps to existing Bookmark programmatic APIs.
5
+ * Responses are formatted as concise text for LLM consumption.
6
+ */
7
+ import { loadConfig, getStoragePath } from "../config.js";
8
+ import { resolveProjectName } from "../registry.js";
9
+ import { captureSnapshot } from "../snapshot/capture.js";
10
+ import { compressToMarkdown } from "../snapshot/compress.js";
11
+ import { loadSnapshot, loadLatestSnapshot, listSnapshots, getSnapshotCount, } from "../snapshot/storage.js";
12
+ import { restoreContext } from "../restore/index.js";
13
+ import { loadState } from "../threshold/state.js";
14
+ import { readContextMd } from "../trails/reader.js";
15
+ import { parseIdentity, validateRepoIdentity } from "../trails/identity.js";
16
+ /**
17
+ * If the bookmark.context.md at `storagePath` declares a different repo_path
18
+ * than the current CWD, return a one-line warning to prepend to MCP output.
19
+ * Returns null when no bookmark file exists, no identity block is present,
20
+ * or the identity matches.
21
+ */
22
+ function identityMismatchWarning(storagePath, cwd) {
23
+ const raw = readContextMd(storagePath);
24
+ if (!raw)
25
+ return null;
26
+ const { identity } = parseIdentity(raw);
27
+ if (!identity)
28
+ return null;
29
+ return validateRepoIdentity(identity, cwd);
30
+ }
31
+ function prefixWarning(warning, body) {
32
+ return warning ? `${warning}\n\n${body}` : body;
33
+ }
34
+ // --- Response helpers ---
35
+ function textResponse(text) {
36
+ return { content: [{ type: "text", text }] };
37
+ }
38
+ function errorResponse(text) {
39
+ return { content: [{ type: "text", text }], isError: true };
40
+ }
41
+ // --- Tool definitions ---
42
+ export const TOOLS = [
43
+ {
44
+ name: "snapshot",
45
+ description: "Capture a context snapshot of the current session. Extracts decisions, open items, file changes, and progress from the transcript. Use before major refactors, before ending a session, or when you want to preserve current context.",
46
+ inputSchema: {
47
+ type: "object",
48
+ properties: {
49
+ trigger: {
50
+ type: "string",
51
+ enum: ["manual", "pre_refactor"],
52
+ description: "Why the snapshot is being taken (default: 'manual')",
53
+ },
54
+ },
55
+ },
56
+ annotations: {
57
+ title: "Capture Snapshot",
58
+ readOnlyHint: false,
59
+ destructiveHint: false,
60
+ idempotentHint: false,
61
+ openWorldHint: false,
62
+ },
63
+ },
64
+ {
65
+ name: "restore",
66
+ description: "Restore context from the latest or a specific snapshot. Returns the session context including intent, progress, decisions, and open items. Use to recover context after compaction or when resuming work.",
67
+ inputSchema: {
68
+ type: "object",
69
+ properties: {
70
+ snapshot_id: {
71
+ type: "string",
72
+ description: "Specific snapshot ID to restore from (default: latest)",
73
+ },
74
+ },
75
+ },
76
+ annotations: {
77
+ title: "Restore Context",
78
+ readOnlyHint: true,
79
+ destructiveHint: false,
80
+ idempotentHint: true,
81
+ openWorldHint: false,
82
+ },
83
+ },
84
+ {
85
+ name: "status",
86
+ description: "Snapshot stats — count, last capture time, freshness, and storage info. Quick overview of the snapshot inventory.",
87
+ inputSchema: {
88
+ type: "object",
89
+ properties: {},
90
+ },
91
+ annotations: {
92
+ title: "Snapshot Status",
93
+ readOnlyHint: true,
94
+ destructiveHint: false,
95
+ idempotentHint: true,
96
+ openWorldHint: false,
97
+ },
98
+ },
99
+ {
100
+ name: "list",
101
+ description: "List all snapshots with timestamps, triggers, and context remaining percentage. Most recent first.",
102
+ inputSchema: {
103
+ type: "object",
104
+ properties: {
105
+ limit: {
106
+ type: "number",
107
+ description: "Maximum number of snapshots to return (default: 10)",
108
+ },
109
+ },
110
+ },
111
+ annotations: {
112
+ title: "List Snapshots",
113
+ readOnlyHint: true,
114
+ destructiveHint: false,
115
+ idempotentHint: true,
116
+ openWorldHint: false,
117
+ },
118
+ },
119
+ {
120
+ name: "show",
121
+ description: "Show full snapshot content — decisions, progress, open items, file changes, and errors. Provides the complete context from a specific or the latest snapshot.",
122
+ inputSchema: {
123
+ type: "object",
124
+ properties: {
125
+ snapshot_id: {
126
+ type: "string",
127
+ description: "Snapshot ID to show (default: latest)",
128
+ },
129
+ },
130
+ },
131
+ annotations: {
132
+ title: "Show Snapshot",
133
+ readOnlyHint: true,
134
+ destructiveHint: false,
135
+ idempotentHint: true,
136
+ openWorldHint: false,
137
+ },
138
+ },
139
+ ];
140
+ // --- Tool handlers ---
141
+ export async function handleToolCall(name, args) {
142
+ try {
143
+ switch (name) {
144
+ case "snapshot":
145
+ return await handleSnapshot(args);
146
+ case "restore":
147
+ return await handleRestore(args);
148
+ case "status":
149
+ return await handleStatus();
150
+ case "list":
151
+ return await handleList(args);
152
+ case "show":
153
+ return await handleShow(args);
154
+ default:
155
+ return errorResponse(`Unknown tool: ${name}`);
156
+ }
157
+ }
158
+ catch (err) {
159
+ return errorResponse(err instanceof Error ? err.message : "Tool execution failed");
160
+ }
161
+ }
162
+ async function handleSnapshot(args) {
163
+ const cwd = process.cwd();
164
+ const trigger = args.trigger || "manual";
165
+ // Find the transcript file — look in standard Claude Code location
166
+ const transcriptDir = process.env.CLAUDE_TRANSCRIPT_DIR;
167
+ const sessionId = process.env.CLAUDE_SESSION_ID || "unknown";
168
+ if (!transcriptDir) {
169
+ return errorResponse("Cannot capture snapshot: CLAUDE_TRANSCRIPT_DIR not available. Snapshots require an active Claude Code session with transcript access.");
170
+ }
171
+ const fs = await import("fs");
172
+ const path = await import("path");
173
+ // Find the most recent transcript file
174
+ let transcriptPath = "";
175
+ try {
176
+ const files = fs.readdirSync(transcriptDir)
177
+ .filter((f) => f.endsWith(".jsonl"))
178
+ .sort()
179
+ .reverse();
180
+ if (files.length > 0) {
181
+ transcriptPath = path.join(transcriptDir, files[0]);
182
+ }
183
+ }
184
+ catch {
185
+ // Fall back to environment variable
186
+ }
187
+ if (!transcriptPath) {
188
+ return errorResponse("No transcript file found. Snapshots require an active session transcript.");
189
+ }
190
+ const snapshot = await captureSnapshot({
191
+ trigger,
192
+ transcriptPath,
193
+ cwd,
194
+ sessionId,
195
+ });
196
+ return textResponse([
197
+ `Snapshot captured: ${snapshot.snapshot_id}`,
198
+ `Trigger: ${trigger}`,
199
+ `Files tracked: ${snapshot.files_changed.length}`,
200
+ `Tools: ${Object.keys(snapshot.tools_summary).length}`,
201
+ ]
202
+ .join("\n"));
203
+ }
204
+ async function handleRestore(args) {
205
+ const cwd = process.cwd();
206
+ const snapshotId = args.snapshot_id;
207
+ if (snapshotId) {
208
+ // Load specific snapshot and compress to markdown
209
+ const config = loadConfig(cwd);
210
+ const storagePath = getStoragePath(cwd, config);
211
+ const snapshot = loadSnapshot(storagePath, snapshotId);
212
+ if (!snapshot) {
213
+ return errorResponse(`Snapshot "${snapshotId}" not found.`);
214
+ }
215
+ const warning = identityMismatchWarning(storagePath, cwd);
216
+ const markdown = compressToMarkdown(snapshot);
217
+ return textResponse(prefixWarning(warning, markdown));
218
+ }
219
+ // Restore latest context using the standard restoration logic
220
+ const result = restoreContext({
221
+ cwd,
222
+ format: "markdown",
223
+ });
224
+ if (result.systemMessage) {
225
+ return textResponse(result.systemMessage);
226
+ }
227
+ return textResponse("No snapshots found to restore from.");
228
+ }
229
+ async function handleStatus() {
230
+ const cwd = process.cwd();
231
+ const config = loadConfig(cwd);
232
+ const storagePath = getStoragePath(cwd, config);
233
+ const count = getSnapshotCount(storagePath);
234
+ const state = loadState(storagePath);
235
+ const latest = loadLatestSnapshot(storagePath);
236
+ const warning = identityMismatchWarning(storagePath, cwd);
237
+ const lines = [`Snapshot inventory: ${count} snapshots`];
238
+ lines.push(`Storage: ${storagePath}`);
239
+ if (latest) {
240
+ const age = Date.now() - latest.timestamp;
241
+ const ageStr = age < 60000
242
+ ? "< 1 minute ago"
243
+ : age < 3600000
244
+ ? `${Math.round(age / 60000)} minutes ago`
245
+ : `${Math.round(age / 3600000)} hours ago`;
246
+ lines.push(`Last snapshot: ${ageStr} (${latest.snapshot_id})`);
247
+ lines.push(`Last trigger: ${latest.trigger}`);
248
+ }
249
+ else {
250
+ lines.push("No snapshots captured yet.");
251
+ }
252
+ lines.push(`Compaction count: ${state.compaction_count}`);
253
+ lines.push(`New-session threshold: ${config.tokenThresholds.map(value => `${Math.round(value * 100)}% used`).join(', ')} when limit is known`);
254
+ if (state.latest_context_used_pct !== undefined) {
255
+ lines.push(`Latest context usage: ${Math.round(state.latest_context_used_pct * 100)}%`);
256
+ if (state.latest_model)
257
+ lines.push(`Active model: ${state.latest_model}`);
258
+ }
259
+ else if (state.latest_model && state.latest_context_tokens !== undefined) {
260
+ lines.push(`Latest context usage: ${state.latest_context_tokens} tokens; context limit unknown`);
261
+ lines.push(`Active model: ${state.latest_model}`);
262
+ lines.push('Required action: bookmark config --context-limit <tokens>');
263
+ }
264
+ lines.push(`Snapshot interval: ${state.snapshot_interval_minutes} minutes`);
265
+ return textResponse(prefixWarning(warning, lines.join("\n")));
266
+ }
267
+ async function handleList(args) {
268
+ const cwd = process.cwd();
269
+ const config = loadConfig(cwd);
270
+ const storagePath = getStoragePath(cwd, config);
271
+ const limit = args.limit || 10;
272
+ const snapshots = listSnapshots(storagePath, limit);
273
+ const warning = identityMismatchWarning(storagePath, cwd);
274
+ if (snapshots.length === 0) {
275
+ return textResponse(prefixWarning(warning, `No snapshots found in ${storagePath}.`));
276
+ }
277
+ const projectName = resolveProjectName(cwd);
278
+ const lines = [`Snapshots (${snapshots.length}, most recent first) in ${storagePath}:`];
279
+ for (const s of snapshots) {
280
+ const date = new Date(s.timestamp).toISOString().replace("T", " ").slice(0, 19);
281
+ const ctx = s.context_remaining_pct
282
+ ? ` | ${Math.round(s.context_remaining_pct * 100)}% ctx`
283
+ : "";
284
+ lines.push(`- ${s.id} | ${date} | ${s.trigger}${ctx} | ${projectName}`);
285
+ }
286
+ return textResponse(prefixWarning(warning, lines.join("\n")));
287
+ }
288
+ async function handleShow(args) {
289
+ const cwd = process.cwd();
290
+ const config = loadConfig(cwd);
291
+ const storagePath = getStoragePath(cwd, config);
292
+ const snapshotId = args.snapshot_id;
293
+ const snapshot = snapshotId
294
+ ? loadSnapshot(storagePath, snapshotId)
295
+ : loadLatestSnapshot(storagePath);
296
+ if (!snapshot) {
297
+ return errorResponse(snapshotId
298
+ ? `Snapshot "${snapshotId}" not found.`
299
+ : "No snapshots found.");
300
+ }
301
+ const warning = identityMismatchWarning(storagePath, cwd);
302
+ return textResponse(prefixWarning(warning, compressToMarkdown(snapshot)));
303
+ }
304
+ //# sourceMappingURL=tools.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../src/mcp/tools.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import type { Snapshot, SnapshotTrigger } from './types.js';
2
+ /**
3
+ * Resolve a human-readable project name from a directory path.
4
+ *
5
+ * Resolution order:
6
+ * 1. package.json "name" field in cwd
7
+ * 2. basename of git repo root (walk up until .git is found)
8
+ * 3. basename of cwd — unless it's the home directory
9
+ * 4. Fallback: basename(cwd) regardless
10
+ */
11
+ export declare function resolveProjectName(cwd: string): string;
12
+ export interface RegistryEntry {
13
+ id: string;
14
+ timestamp: number;
15
+ trigger: SnapshotTrigger;
16
+ project_path: string;
17
+ project_name: string;
18
+ canonical_file: string;
19
+ files_changed_count: number;
20
+ }
21
+ export interface LastProject {
22
+ path: string;
23
+ name: string;
24
+ last_activity_at: number;
25
+ }
26
+ export interface Registry {
27
+ version: string;
28
+ last_updated: number;
29
+ last_project?: LastProject;
30
+ snapshots: RegistryEntry[];
31
+ }
32
+ export declare function getRegistryPath(): string;
33
+ export declare function loadRegistry(): Registry;
34
+ export declare function appendToRegistry(snapshot: Snapshot, canonicalFile: string): void;
35
+ export declare function touchLastProject(projectPath: string): void;
36
+ export declare function findById(id: string): RegistryEntry | null;
37
+ export declare function getLastProject(): LastProject | null;
38
+ /** Prune entries whose canonical_file is missing. Lazy cleanup on read paths. */
39
+ export declare function pruneStale(): Registry;
40
+ //# sourceMappingURL=registry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"registry.d.ts","sourceRoot":"","sources":["../src/registry.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,QAAQ,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAK5D;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAkCtD;AAED,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,eAAe,CAAC;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB,cAAc,EAAE,MAAM,CAAC;IACvB,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,WAAW,CAAC;IAC3B,SAAS,EAAE,aAAa,EAAE,CAAC;CAC5B;AAED,wBAAgB,eAAe,IAAI,MAAM,CAExC;AAOD,wBAAgB,YAAY,IAAI,QAAQ,CAYvC;AAQD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,GAAG,IAAI,CA6BhF;AAED,wBAAgB,gBAAgB,CAAC,WAAW,EAAE,MAAM,GAAG,IAAI,CAY1D;AAED,wBAAgB,QAAQ,CAAC,EAAE,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAGzD;AAED,wBAAgB,cAAc,IAAI,WAAW,GAAG,IAAI,CAEnD;AAED,iFAAiF;AACjF,wBAAgB,UAAU,IAAI,QAAQ,CAQrC"}