@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
@@ -1,12 +1,15 @@
1
1
  import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from 'node:fs';
2
+ import { randomBytes } from 'node:crypto';
2
3
  import { join } from 'node:path';
3
4
  const INDEX_VERSION = '1.0.0';
4
- function generateSnapshotId() {
5
+ export function generateSnapshotId() {
5
6
  const now = new Date();
6
7
  const pad = (n, len = 2) => String(n).padStart(len, '0');
7
8
  const date = `${now.getFullYear()}${pad(now.getMonth() + 1)}${pad(now.getDate())}`;
8
9
  const time = `${pad(now.getHours())}${pad(now.getMinutes())}${pad(now.getSeconds())}`;
9
- return `SNAP_${date}_${time}`;
10
+ const milliseconds = pad(now.getMilliseconds(), 3);
11
+ const entropy = randomBytes(2).toString('hex');
12
+ return `SNAP_${date}_${time}_${milliseconds}_${entropy}`;
10
13
  }
11
14
  export function getSnapshotsDir(storagePath) {
12
15
  return join(storagePath, 'snapshots');
@@ -40,7 +43,7 @@ export function storeSnapshot(storagePath, snapshot) {
40
43
  }
41
44
  export function loadSnapshot(storagePath, snapshotId) {
42
45
  // Validate snapshot ID format to prevent path traversal
43
- if (!/^SNAP_\d{8}_\d{6}$/.test(snapshotId)) {
46
+ if (!/^SNAP_\d{8}_\d{6}(?:_\d{3}_[a-f0-9]{4})?$/.test(snapshotId)) {
44
47
  return null;
45
48
  }
46
49
  const snapshotPath = join(getSnapshotsDir(storagePath), `${snapshotId}.json`);
@@ -112,11 +115,9 @@ function updateIndex(storagePath, snapshot) {
112
115
  timestamp: snapshot.timestamp,
113
116
  trigger: snapshot.trigger,
114
117
  compaction_cycle: snapshot.compaction_cycle,
118
+ files_changed_count: snapshot.files_changed.length,
115
119
  context_remaining_pct: snapshot.context_remaining_pct,
116
120
  token_estimate: snapshot.token_estimate,
117
- decisions_count: snapshot.decisions.length,
118
- files_changed_count: snapshot.files_changed.length,
119
- open_items_count: snapshot.open_items.length,
120
121
  };
121
122
  // Add to front (most recent first)
122
123
  index.snapshots.unshift(entry);
@@ -1 +1 @@
1
- {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/snapshot/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.js","sourceRoot":"","sources":["../../src/snapshot/storage.ts"],"names":[],"mappings":"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"}
@@ -5,4 +5,9 @@ export declare function saveState(storagePath: string, state: BookmarkState): vo
5
5
  export declare function incrementCompaction(state: BookmarkState, thresholds: number[]): BookmarkState;
6
6
  export declare function resetForNewSession(state: BookmarkState, sessionId: string, thresholds: number[]): BookmarkState;
7
7
  export declare function updateSnapshotTime(state: BookmarkState): BookmarkState;
8
+ /**
9
+ * Increment snapshots_taken for the current session in session_history.
10
+ * Previously this was never called — snapshots_taken was always 0.
11
+ */
12
+ export declare function incrementSnapshotCount(state: BookmarkState): BookmarkState;
8
13
  //# sourceMappingURL=state.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/threshold/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAkB/D,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAY5D;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAOzE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,aAAa,CAQ7F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,aAAa,CAyB/G;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAMtE"}
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../src/threshold/state.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAgB,MAAM,aAAa,CAAC;AAkB/D,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAExD;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,GAAG,aAAa,CAY5D;AAED,wBAAgB,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,aAAa,GAAG,IAAI,CAOzE;AAED,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,aAAa,CAY7F;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,GAAG,aAAa,CAgC/G;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAMtE;AAED;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,KAAK,EAAE,aAAa,GAAG,aAAa,CAW1E"}
@@ -10,7 +10,7 @@ function defaultState() {
10
10
  current_threshold: 0.20,
11
11
  last_snapshot_time: 0,
12
12
  last_event_time: 0,
13
- snapshot_interval_minutes: 20,
13
+ snapshot_interval_minutes: 5,
14
14
  session_history: [],
15
15
  };
16
16
  }
@@ -46,6 +46,10 @@ export function incrementCompaction(state, thresholds) {
46
46
  ...state,
47
47
  compaction_count: newCount,
48
48
  current_threshold: thresholds[thresholdIndex],
49
+ // The first prompt after compaction can still see the final pre-compaction
50
+ // usage record. Keep handled thresholds until a lower usage record proves
51
+ // the new context cycle is active.
52
+ token_thresholds_triggered: state.token_thresholds_triggered,
49
53
  };
50
54
  }
51
55
  export function resetForNewSession(state, sessionId, thresholds) {
@@ -57,7 +61,7 @@ export function resetForNewSession(state, sessionId, thresholds) {
57
61
  started: state.session_history.find(s => s.session_id === state.session_id)?.started ?? state.last_event_time,
58
62
  ended: Date.now(),
59
63
  compaction_count: state.compaction_count,
60
- snapshots_taken: 0, // Updated elsewhere
64
+ snapshots_taken: 0, // Incremented by incrementSnapshotCount on each capture
61
65
  };
62
66
  history.unshift(currentEntry);
63
67
  if (history.length > MAX_SESSION_HISTORY) {
@@ -71,6 +75,13 @@ export function resetForNewSession(state, sessionId, thresholds) {
71
75
  current_threshold: thresholds[0],
72
76
  last_event_time: Date.now(),
73
77
  session_history: history,
78
+ token_thresholds_triggered: [],
79
+ latest_model: undefined,
80
+ latest_context_tokens: undefined,
81
+ latest_context_limit_tokens: undefined,
82
+ latest_context_used_pct: undefined,
83
+ latest_context_observed_at: undefined,
84
+ unknown_context_limit_notified_model: undefined,
74
85
  };
75
86
  }
76
87
  export function updateSnapshotTime(state) {
@@ -80,4 +91,19 @@ export function updateSnapshotTime(state) {
80
91
  last_event_time: Date.now(),
81
92
  };
82
93
  }
94
+ /**
95
+ * Increment snapshots_taken for the current session in session_history.
96
+ * Previously this was never called — snapshots_taken was always 0.
97
+ */
98
+ export function incrementSnapshotCount(state) {
99
+ if (!state.session_id)
100
+ return state;
101
+ const history = state.session_history.map(entry => {
102
+ if (entry.session_id === state.session_id) {
103
+ return { ...entry, snapshots_taken: entry.snapshots_taken + 1 };
104
+ }
105
+ return entry;
106
+ });
107
+ return { ...state, session_history: history };
108
+ }
83
109
  //# sourceMappingURL=state.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/threshold/state.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"state.js","sourceRoot":"","sources":["../../src/threshold/state.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export interface ContextUsage {
2
+ status: 'measured';
3
+ model: string;
4
+ usedTokens: number;
5
+ contextLimitTokens: number;
6
+ usedFraction: number;
7
+ remainingFraction: number;
8
+ source: 'transcript_usage';
9
+ }
10
+ export interface UnknownContextLimitUsage {
11
+ status: 'unknown_context_limit';
12
+ model: string;
13
+ usedTokens: number;
14
+ source: 'transcript_usage';
15
+ }
16
+ export type ContextUsageObservation = ContextUsage | UnknownContextLimitUsage;
17
+ /**
18
+ * Resolve the context limit for models observed in Claude Code transcripts.
19
+ * An explicit override wins so users can handle provider/model changes without
20
+ * waiting for a Bookmark release. Unknown models return null so Bookmark can
21
+ * ask for a verified limit instead of guessing.
22
+ */
23
+ export declare function resolveContextLimit(model: string, override?: number): number | null;
24
+ /** Read only the transcript tail and return the latest assistant usage record. */
25
+ export declare function readLatestContextUsage(transcriptPath: string, contextLimitOverride?: number, pendingPrompt?: string): ContextUsageObservation | null;
26
+ export declare function newlyCrossedThresholds(usedFraction: number, configuredThresholds: number[], alreadyTriggered?: number[]): number[];
27
+ /** Re-arm alerts only after a lower usage record proves a new context cycle. */
28
+ export declare function handledThresholdsForUsage(usedFraction: number, configuredThresholds: number[], alreadyTriggered?: number[]): number[];
29
+ //# sourceMappingURL=token-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-usage.d.ts","sourceRoot":"","sources":["../../src/threshold/token-usage.ts"],"names":[],"mappings":"AAaA,MAAM,WAAW,YAAY;IAC3B,MAAM,EAAE,UAAU,CAAC;IACnB,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,WAAW,wBAAwB;IACvC,MAAM,EAAE,uBAAuB,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,kBAAkB,CAAC;CAC5B;AAED,MAAM,MAAM,uBAAuB,GAAG,YAAY,GAAG,wBAAwB,CAAC;AAE9E;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAkBnF;AAED,kFAAkF;AAClF,wBAAgB,sBAAsB,CACpC,cAAc,EAAE,MAAM,EACtB,oBAAoB,CAAC,EAAE,MAAM,EAC7B,aAAa,SAAK,GACjB,uBAAuB,GAAG,IAAI,CA0EhC;AAED,wBAAgB,sBAAsB,CACpC,YAAY,EAAE,MAAM,EACpB,oBAAoB,EAAE,MAAM,EAAE,EAC9B,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,EAAE,CAMV;AAED,gFAAgF;AAChF,wBAAgB,yBAAyB,CACvC,YAAY,EAAE,MAAM,EACpB,oBAAoB,EAAE,MAAM,EAAE,EAC9B,gBAAgB,GAAE,MAAM,EAAO,GAC9B,MAAM,EAAE,CAGV"}
@@ -0,0 +1,128 @@
1
+ import { closeSync, existsSync, fstatSync, openSync, readSync } from 'node:fs';
2
+ const MAX_TAIL_BYTES = 4 * 1024 * 1024;
3
+ /**
4
+ * Resolve the context limit for models observed in Claude Code transcripts.
5
+ * An explicit override wins so users can handle provider/model changes without
6
+ * waiting for a Bookmark release. Unknown models return null so Bookmark can
7
+ * ask for a verified limit instead of guessing.
8
+ */
9
+ export function resolveContextLimit(model, override) {
10
+ if (override && Number.isFinite(override) && override > 0)
11
+ return override;
12
+ const normalized = normalizeModelId(model);
13
+ const hasOneMillionContext = [
14
+ /^claude-(?:opus|sonnet|fable|mythos)-5(?:-|$)/,
15
+ /^claude-opus-4-(?:6|7|8)(?:-|$)/,
16
+ /^claude-sonnet-4-6(?:-|$)/,
17
+ /^claude-mythos-preview(?:-|$)/,
18
+ ].some(pattern => pattern.test(normalized));
19
+ if (hasOneMillionContext)
20
+ return 1_000_000;
21
+ const hasTwoHundredThousandContext = [
22
+ /^claude-(?:opus|sonnet|haiku)-4-5(?:-|$)/,
23
+ ].some(pattern => pattern.test(normalized));
24
+ return hasTwoHundredThousandContext ? 200_000 : null;
25
+ }
26
+ /** Read only the transcript tail and return the latest assistant usage record. */
27
+ export function readLatestContextUsage(transcriptPath, contextLimitOverride, pendingPrompt = '') {
28
+ if (!existsSync(transcriptPath))
29
+ return null;
30
+ let fd;
31
+ try {
32
+ fd = openSync(transcriptPath, 'r');
33
+ const size = fstatSync(fd).size;
34
+ if (size === 0)
35
+ return null;
36
+ const bytesToRead = Math.min(size, MAX_TAIL_BYTES);
37
+ const start = size - bytesToRead;
38
+ const buffer = Buffer.alloc(bytesToRead);
39
+ readSync(fd, buffer, 0, bytesToRead, start);
40
+ let text = buffer.toString('utf8');
41
+ if (start > 0) {
42
+ const firstNewline = text.indexOf('\n');
43
+ text = firstNewline >= 0 ? text.slice(firstNewline + 1) : '';
44
+ }
45
+ const lines = text.split('\n');
46
+ for (let index = lines.length - 1; index >= 0; index -= 1) {
47
+ const line = lines[index].trim();
48
+ if (!line)
49
+ continue;
50
+ try {
51
+ const record = JSON.parse(line);
52
+ if (typeof record.type === 'string' && record.type !== 'assistant')
53
+ continue;
54
+ const message = isRecord(record.message) ? record.message : record;
55
+ const usage = isRecord(message.usage) ? message.usage : null;
56
+ const model = typeof message.model === 'string' ? message.model : null;
57
+ if (!usage || !model || model === '<synthetic>')
58
+ continue;
59
+ const inputTokens = tokenCount(usage.input_tokens);
60
+ const cacheCreationTokens = tokenCount(usage.cache_creation_input_tokens);
61
+ const cacheReadTokens = tokenCount(usage.cache_read_input_tokens);
62
+ const outputTokens = tokenCount(usage.output_tokens);
63
+ const promptEstimate = pendingPrompt
64
+ ? Math.ceil(Buffer.byteLength(pendingPrompt, 'utf8') / 4)
65
+ : 0;
66
+ const usedTokens = inputTokens + cacheCreationTokens + cacheReadTokens + outputTokens + promptEstimate;
67
+ if (usedTokens <= 0)
68
+ continue;
69
+ const contextLimitTokens = resolveContextLimit(model, contextLimitOverride);
70
+ if (contextLimitTokens === null) {
71
+ return {
72
+ status: 'unknown_context_limit',
73
+ model,
74
+ usedTokens,
75
+ source: 'transcript_usage',
76
+ };
77
+ }
78
+ const usedFraction = Math.min(usedTokens / contextLimitTokens, 1);
79
+ return {
80
+ status: 'measured',
81
+ model,
82
+ usedTokens,
83
+ contextLimitTokens,
84
+ usedFraction,
85
+ remainingFraction: Math.max(0, 1 - usedFraction),
86
+ source: 'transcript_usage',
87
+ };
88
+ }
89
+ catch {
90
+ // Skip malformed or partial JSONL lines.
91
+ }
92
+ }
93
+ }
94
+ catch {
95
+ return null;
96
+ }
97
+ finally {
98
+ if (fd !== undefined)
99
+ closeSync(fd);
100
+ }
101
+ return null;
102
+ }
103
+ export function newlyCrossedThresholds(usedFraction, configuredThresholds, alreadyTriggered = []) {
104
+ const handled = new Set(alreadyTriggered.map(value => Number(value.toFixed(4))));
105
+ return [...configuredThresholds]
106
+ .filter(value => Number.isFinite(value) && value > 0 && value < 1)
107
+ .sort((a, b) => a - b)
108
+ .filter(value => usedFraction >= value && !handled.has(Number(value.toFixed(4))));
109
+ }
110
+ /** Re-arm alerts only after a lower usage record proves a new context cycle. */
111
+ export function handledThresholdsForUsage(usedFraction, configuredThresholds, alreadyTriggered = []) {
112
+ const lowestThreshold = Math.min(...configuredThresholds);
113
+ return usedFraction < lowestThreshold ? [] : alreadyTriggered;
114
+ }
115
+ function tokenCount(value) {
116
+ return typeof value === 'number' && Number.isFinite(value) && value > 0 ? value : 0;
117
+ }
118
+ function normalizeModelId(model) {
119
+ return model
120
+ .toLowerCase()
121
+ .replace(/^anthropic\./, '')
122
+ .replace(/-v\d+:\d+$/, '')
123
+ .replace(/@(\d{8})$/, '-$1');
124
+ }
125
+ function isRecord(value) {
126
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
127
+ }
128
+ //# sourceMappingURL=token-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token-usage.js","sourceRoot":"","sources":["../../src/threshold/token-usage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * BOOKMARK_IDENTITY block parser + validator.
3
+ *
4
+ * The identity block is an HTML comment at the top of bookmark.context.md
5
+ * that declares which project/repo/branch the summary belongs to. It makes
6
+ * cross-session restoration unambiguous — you can always verify the
7
+ * bookmark you're restoring from matches the CWD you're restoring into.
8
+ *
9
+ * Example:
10
+ * <!-- BOOKMARK_IDENTITY
11
+ * scope: repo
12
+ * project: travel-planner
13
+ * repo_path: /Users/me/Desktop/git-folder/Travel Planner
14
+ * branch: feature/summer-camps
15
+ * head: 4988383
16
+ * written: 2026-04-11
17
+ * -->
18
+ *
19
+ * Two scopes are supported:
20
+ * - `repo` — bookmark belongs to a specific git repo (or directory)
21
+ * - `home` — bookmark is a POINTER, no active context itself; delegates
22
+ * via `points_to_canonical` to a repo-scoped bookmark
23
+ */
24
+ export type BookmarkScope = 'repo' | 'home';
25
+ export interface BookmarkIdentity {
26
+ scope: BookmarkScope;
27
+ project?: string;
28
+ repo_path?: string;
29
+ repo_name?: string;
30
+ branch?: string;
31
+ head?: string;
32
+ base?: string;
33
+ written?: string;
34
+ written_by?: string;
35
+ points_to_project?: string;
36
+ points_to_repo?: string;
37
+ points_to_canonical?: string;
38
+ /** All raw key:value pairs, for forward-compat keys we don't model */
39
+ raw: Record<string, string>;
40
+ }
41
+ export interface IdentityParseResult {
42
+ identity: BookmarkIdentity | null;
43
+ /** Content with the identity block stripped, ready to present */
44
+ bodyWithoutIdentity: string;
45
+ }
46
+ /**
47
+ * Parse a bookmark.context.md file's content and extract the identity block.
48
+ * Returns `identity: null` if no block is present — callers should treat that
49
+ * as a legacy/untagged file and fall back to current behavior.
50
+ */
51
+ export declare function parseIdentity(content: string): IdentityParseResult;
52
+ /**
53
+ * Validate a repo-scoped identity against the storage path that was loaded.
54
+ *
55
+ * Returns a warning string if the identity's `repo_path` disagrees with the
56
+ * working directory, suggesting the bookmark file was moved or the CWD is
57
+ * not the repo it describes. Returns null when they match or when we can't
58
+ * determine (missing field).
59
+ */
60
+ export declare function validateRepoIdentity(identity: BookmarkIdentity, cwd: string): string | null;
61
+ /**
62
+ * Follow a home-scope pointer to its canonical file.
63
+ *
64
+ * If the identity is home-scoped and has `points_to_canonical`, return the
65
+ * content of that file (plus its own parsed identity). Returns null if the
66
+ * pointer target doesn't exist or isn't readable — caller should fall back
67
+ * to presenting the pointer body itself.
68
+ */
69
+ export interface PointerTarget {
70
+ canonical_path: string;
71
+ content: string;
72
+ identity: BookmarkIdentity | null;
73
+ staleness_hours: number | null;
74
+ }
75
+ export declare function followPointer(identity: BookmarkIdentity): PointerTarget | null;
76
+ //# sourceMappingURL=identity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/trails/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,MAAM,MAAM,aAAa,GAAG,MAAM,GAAG,MAAM,CAAC;AAE5C,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,aAAa,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B,sEAAsE;IACtE,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,iEAAiE;IACjE,mBAAmB,EAAE,MAAM,CAAC;CAC7B;AAID;;;;GAIG;AACH,wBAAgB,aAAa,CAAC,OAAO,EAAE,MAAM,GAAG,mBAAmB,CAwClE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,gBAAgB,EAC1B,GAAG,EAAE,MAAM,GACV,MAAM,GAAG,IAAI,CAiBf;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,gBAAgB,GAAG,aAAa,GAAG,IAAI,CAqB9E"}
@@ -0,0 +1,117 @@
1
+ /**
2
+ * BOOKMARK_IDENTITY block parser + validator.
3
+ *
4
+ * The identity block is an HTML comment at the top of bookmark.context.md
5
+ * that declares which project/repo/branch the summary belongs to. It makes
6
+ * cross-session restoration unambiguous — you can always verify the
7
+ * bookmark you're restoring from matches the CWD you're restoring into.
8
+ *
9
+ * Example:
10
+ * <!-- BOOKMARK_IDENTITY
11
+ * scope: repo
12
+ * project: travel-planner
13
+ * repo_path: /Users/me/Desktop/git-folder/Travel Planner
14
+ * branch: feature/summer-camps
15
+ * head: 4988383
16
+ * written: 2026-04-11
17
+ * -->
18
+ *
19
+ * Two scopes are supported:
20
+ * - `repo` — bookmark belongs to a specific git repo (or directory)
21
+ * - `home` — bookmark is a POINTER, no active context itself; delegates
22
+ * via `points_to_canonical` to a repo-scoped bookmark
23
+ */
24
+ import { existsSync, readFileSync, statSync } from 'node:fs';
25
+ import { resolve } from 'node:path';
26
+ const IDENTITY_BLOCK = /<!--\s*BOOKMARK_IDENTITY\s*\n([\s\S]*?)\n\s*-->/;
27
+ /**
28
+ * Parse a bookmark.context.md file's content and extract the identity block.
29
+ * Returns `identity: null` if no block is present — callers should treat that
30
+ * as a legacy/untagged file and fall back to current behavior.
31
+ */
32
+ export function parseIdentity(content) {
33
+ const match = content.match(IDENTITY_BLOCK);
34
+ if (!match) {
35
+ return { identity: null, bodyWithoutIdentity: content };
36
+ }
37
+ const raw = {};
38
+ for (const line of match[1].split('\n')) {
39
+ const colon = line.indexOf(':');
40
+ if (colon < 0)
41
+ continue;
42
+ const key = line.slice(0, colon).trim();
43
+ const value = line.slice(colon + 1).trim();
44
+ if (!key)
45
+ continue;
46
+ raw[key] = value;
47
+ }
48
+ const scopeRaw = (raw.scope ?? 'repo').toLowerCase();
49
+ const scope = scopeRaw === 'home' ? 'home' : 'repo';
50
+ const identity = {
51
+ scope,
52
+ project: raw.project,
53
+ repo_path: raw.repo_path,
54
+ repo_name: raw.repo_name,
55
+ branch: raw.branch,
56
+ head: raw.head,
57
+ base: raw.base,
58
+ written: raw.written,
59
+ written_by: raw.written_by,
60
+ points_to_project: raw.points_to_project,
61
+ points_to_repo: raw.points_to_repo,
62
+ points_to_canonical: raw.points_to_canonical,
63
+ raw,
64
+ };
65
+ // Body with block stripped — preserve surrounding content
66
+ const bodyWithoutIdentity = content.slice(0, match.index) + content.slice(match.index + match[0].length);
67
+ return { identity, bodyWithoutIdentity: bodyWithoutIdentity.replace(/^\s*\n+/, '') };
68
+ }
69
+ /**
70
+ * Validate a repo-scoped identity against the storage path that was loaded.
71
+ *
72
+ * Returns a warning string if the identity's `repo_path` disagrees with the
73
+ * working directory, suggesting the bookmark file was moved or the CWD is
74
+ * not the repo it describes. Returns null when they match or when we can't
75
+ * determine (missing field).
76
+ */
77
+ export function validateRepoIdentity(identity, cwd) {
78
+ if (identity.scope !== 'repo')
79
+ return null;
80
+ if (!identity.repo_path)
81
+ return null;
82
+ const declared = resolve(identity.repo_path);
83
+ const actual = resolve(cwd);
84
+ if (declared === actual)
85
+ return null;
86
+ // Allow the case where CWD is a subdirectory of the declared repo
87
+ if (actual.startsWith(declared + '/'))
88
+ return null;
89
+ return (`[Bookmark identity mismatch] This bookmark.context.md declares ` +
90
+ `repo_path=${declared} but was loaded from cwd=${actual}. ` +
91
+ `Verify you are in the correct project before acting on the context below.`);
92
+ }
93
+ export function followPointer(identity) {
94
+ if (identity.scope !== 'home')
95
+ return null;
96
+ if (!identity.points_to_canonical)
97
+ return null;
98
+ const target = identity.points_to_canonical;
99
+ if (!existsSync(target))
100
+ return null;
101
+ try {
102
+ const content = readFileSync(target, 'utf-8');
103
+ const mtime = statSync(target).mtimeMs;
104
+ const staleness_hours = Math.round((Date.now() - mtime) / (1000 * 60 * 60));
105
+ const { identity: targetIdentity } = parseIdentity(content);
106
+ return {
107
+ canonical_path: target,
108
+ content,
109
+ identity: targetIdentity,
110
+ staleness_hours,
111
+ };
112
+ }
113
+ catch {
114
+ return null;
115
+ }
116
+ }
117
+ //# sourceMappingURL=identity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"identity.js","sourceRoot":"","sources":["../../src/trails/identity.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAC7D,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2BpC,MAAM,cAAc,GAAG,iDAAiD,CAAC;AAEzE;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,OAAe;IAC3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,cAAc,CAAC,CAAC;IAC5C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,OAAO,EAAE,QAAQ,EAAE,IAAI,EAAE,mBAAmB,EAAE,OAAO,EAAE,CAAC;IAC1D,CAAC;IAED,MAAM,GAAG,GAA2B,EAAE,CAAC;IACvC,KAAK,MAAM,IAAI,IAAI,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAChC,IAAI,KAAK,GAAG,CAAC;YAAE,SAAS;QACxB,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;QACxC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3C,IAAI,CAAC,GAAG;YAAE,SAAS;QACnB,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;IACnB,CAAC;IAED,MAAM,QAAQ,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,WAAW,EAAE,CAAC;IACrD,MAAM,KAAK,GAAkB,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,CAAC;IAEnE,MAAM,QAAQ,GAAqB;QACjC,KAAK;QACL,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,SAAS,EAAE,GAAG,CAAC,SAAS;QACxB,MAAM,EAAE,GAAG,CAAC,MAAM;QAClB,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,IAAI,EAAE,GAAG,CAAC,IAAI;QACd,OAAO,EAAE,GAAG,CAAC,OAAO;QACpB,UAAU,EAAE,GAAG,CAAC,UAAU;QAC1B,iBAAiB,EAAE,GAAG,CAAC,iBAAiB;QACxC,cAAc,EAAE,GAAG,CAAC,cAAc;QAClC,mBAAmB,EAAE,GAAG,CAAC,mBAAmB;QAC5C,GAAG;KACJ,CAAC;IAEF,0DAA0D;IAC1D,MAAM,mBAAmB,GACvB,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,KAAM,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;IAEhF,OAAO,EAAE,QAAQ,EAAE,mBAAmB,EAAE,mBAAmB,CAAC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,EAAE,CAAC;AACvF,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAClC,QAA0B,EAC1B,GAAW;IAEX,IAAI,QAAQ,CAAC,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAErC,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC,CAAC;IAC7C,MAAM,MAAM,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;IAE5B,IAAI,QAAQ,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAErC,kEAAkE;IAClE,IAAI,MAAM,CAAC,UAAU,CAAC,QAAQ,GAAG,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAEnD,OAAO,CACL,iEAAiE;QACjE,aAAa,QAAQ,4BAA4B,MAAM,IAAI;QAC3D,2EAA2E,CAC5E,CAAC;AACJ,CAAC;AAiBD,MAAM,UAAU,aAAa,CAAC,QAA0B;IACtD,IAAI,QAAQ,CAAC,KAAK,KAAK,MAAM;QAAE,OAAO,IAAI,CAAC;IAC3C,IAAI,CAAC,QAAQ,CAAC,mBAAmB;QAAE,OAAO,IAAI,CAAC;IAE/C,MAAM,MAAM,GAAG,QAAQ,CAAC,mBAAmB,CAAC;IAC5C,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;QAAE,OAAO,IAAI,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;QAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,OAAO,CAAC;QACvC,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;QAC5E,MAAM,EAAE,QAAQ,EAAE,cAAc,EAAE,GAAG,aAAa,CAAC,OAAO,CAAC,CAAC;QAC5D,OAAO;YACL,cAAc,EAAE,MAAM;YACtB,OAAO;YACP,QAAQ,EAAE,cAAc;YACxB,eAAe;SAChB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Read the CONTEXT.md trailhead file.
2
+ * Read the bookmark.context.md trailhead file.
3
3
  * This is the primary restoration source — compact (<400 tokens)
4
4
  * with routing pointers to deeper trail files.
5
5
  */
@@ -1,12 +1,12 @@
1
1
  import { existsSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  /**
4
- * Read the CONTEXT.md trailhead file.
4
+ * Read the bookmark.context.md trailhead file.
5
5
  * This is the primary restoration source — compact (<400 tokens)
6
6
  * with routing pointers to deeper trail files.
7
7
  */
8
8
  export function readContextMd(storagePath) {
9
- const contextPath = join(storagePath, 'CONTEXT.md');
9
+ const contextPath = join(storagePath, 'bookmark.context.md');
10
10
  if (!existsSync(contextPath))
11
11
  return null;
12
12
  try {
@@ -1 +1 @@
1
- {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/trails/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;IACpD,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"reader.js","sourceRoot":"","sources":["../../src/trails/reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAAC,WAAmB;IAC/C,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,EAAE,qBAAqB,CAAC,CAAC;IAC7D,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC;QAAE,OAAO,IAAI,CAAC;IAC1C,IAAI,CAAC;QACH,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QACnD,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE;YAAE,OAAO,IAAI,CAAC;QACjC,OAAO,OAAO,CAAC;IACjB,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC"}
@@ -2,14 +2,8 @@ import type { Snapshot } from '../types.js';
2
2
  /**
3
3
  * Trail-routed memory writer.
4
4
  *
5
- * Writes two tiers of context:
6
- * 1. CONTEXT.md trailhead (~400 tokens), always injected on restore
7
- * 2. trails/ — detail files the LLM can Read if it needs more
8
- *
9
- * Each capture updates trails incrementally:
10
- * - Decisions get appended with timestamps, newer same-topic overrides older
11
- * - Files get merged (union by path, latest operations win)
12
- * - CONTEXT.md gets rewritten with current state + routing pointers
5
+ * Writes file tracking data to trails/files.md.
6
+ * bookmark.context.md is Claude's domain written via Stop/PreCompact prompt hooks.
13
7
  */
14
8
  export declare function writeTrails(storagePath: string, snapshot: Snapshot): void;
15
9
  //# sourceMappingURL=writer.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/trails/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAA0B,MAAM,aAAa,CAAC;AAEpE;;;;;;;;;;;GAWG;AAIH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CASzE"}
1
+ {"version":3,"file":"writer.d.ts","sourceRoot":"","sources":["../../src/trails/writer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,QAAQ,EAAgB,MAAM,aAAa,CAAC;AAE1D;;;;;GAKG;AAIH,wBAAgB,WAAW,CAAC,WAAW,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,IAAI,CAGzE"}