@tyroneross/bookmark 0.1.0
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.
- package/.claude-plugin/marketplace.json +15 -0
- package/.claude-plugin/plugin.json +13 -0
- package/CLAUDE.md +69 -0
- package/LICENSE +21 -0
- package/README.md +178 -0
- package/agents/snapshot-analyst.md +41 -0
- package/commands/activate.md +20 -0
- package/commands/list.md +15 -0
- package/commands/restore.md +30 -0
- package/commands/snapshot.md +26 -0
- package/commands/status.md +19 -0
- package/dist/cli/index.d.ts +3 -0
- package/dist/cli/index.d.ts.map +1 -0
- package/dist/cli/index.js +437 -0
- package/dist/cli/index.js.map +1 -0
- package/dist/config.d.ts +5 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js +86 -0
- package/dist/config.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/restore/index.d.ts +13 -0
- package/dist/restore/index.d.ts.map +1 -0
- package/dist/restore/index.js +94 -0
- package/dist/restore/index.js.map +1 -0
- package/dist/setup/auto-setup.d.ts +16 -0
- package/dist/setup/auto-setup.d.ts.map +1 -0
- package/dist/setup/auto-setup.js +192 -0
- package/dist/setup/auto-setup.js.map +1 -0
- package/dist/setup/configure-hooks.d.ts +10 -0
- package/dist/setup/configure-hooks.d.ts.map +1 -0
- package/dist/setup/configure-hooks.js +97 -0
- package/dist/setup/configure-hooks.js.map +1 -0
- package/dist/snapshot/capture.d.ts +21 -0
- package/dist/snapshot/capture.d.ts.map +1 -0
- package/dist/snapshot/capture.js +134 -0
- package/dist/snapshot/capture.js.map +1 -0
- package/dist/snapshot/compress.d.ts +8 -0
- package/dist/snapshot/compress.d.ts.map +1 -0
- package/dist/snapshot/compress.js +93 -0
- package/dist/snapshot/compress.js.map +1 -0
- package/dist/snapshot/storage.d.ts +13 -0
- package/dist/snapshot/storage.d.ts.map +1 -0
- package/dist/snapshot/storage.js +151 -0
- package/dist/snapshot/storage.js.map +1 -0
- package/dist/threshold/adaptive.d.ts +23 -0
- package/dist/threshold/adaptive.d.ts.map +1 -0
- package/dist/threshold/adaptive.js +29 -0
- package/dist/threshold/adaptive.js.map +1 -0
- package/dist/threshold/state.d.ts +8 -0
- package/dist/threshold/state.d.ts.map +1 -0
- package/dist/threshold/state.js +83 -0
- package/dist/threshold/state.js.map +1 -0
- package/dist/threshold/time-based.d.ts +13 -0
- package/dist/threshold/time-based.d.ts.map +1 -0
- package/dist/threshold/time-based.js +24 -0
- package/dist/threshold/time-based.js.map +1 -0
- package/dist/transcript/estimator.d.ts +20 -0
- package/dist/transcript/estimator.d.ts.map +1 -0
- package/dist/transcript/estimator.js +95 -0
- package/dist/transcript/estimator.js.map +1 -0
- package/dist/transcript/extractor.d.ts +7 -0
- package/dist/transcript/extractor.d.ts.map +1 -0
- package/dist/transcript/extractor.js +237 -0
- package/dist/transcript/extractor.js.map +1 -0
- package/dist/transcript/parser.d.ts +16 -0
- package/dist/transcript/parser.d.ts.map +1 -0
- package/dist/transcript/parser.js +120 -0
- package/dist/transcript/parser.js.map +1 -0
- package/dist/types.d.ts +156 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/hooks/hooks.json +54 -0
- package/package.json +77 -0
- package/scripts/install-plugin.sh +38 -0
- package/skills/context-continuity/SKILL.md +49 -0
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
// ─── Pattern Definitions ───
|
|
2
|
+
const DECISION_PATTERNS = [
|
|
3
|
+
/\b(?:decided to|chose|going with|approach:|instead of|opted for|settled on|will use|let's go with|I'll use|we'll use)\b/i,
|
|
4
|
+
/\b(?:because|since|rationale:|reason:|the advantage|better approach)\b/i,
|
|
5
|
+
];
|
|
6
|
+
const OPEN_ITEM_PATTERNS = [
|
|
7
|
+
/\b(?:still need to|TODO|next step|remaining|haven't yet|need to|should also|left to do|pending)\b/i,
|
|
8
|
+
/- \[ \]/, // Unchecked markdown checkbox
|
|
9
|
+
/\b(?:will need to|must still|haven't implemented|not yet)\b/i,
|
|
10
|
+
];
|
|
11
|
+
const UNKNOWN_PATTERNS = [
|
|
12
|
+
/\b(?:not sure|unclear|blocker|blocked by|need to figure out|question:|unknown|investigate|TBD)\b/i,
|
|
13
|
+
/\b(?:might need|may require|haven't determined|needs research|uncertain)\b/i,
|
|
14
|
+
];
|
|
15
|
+
const ERROR_PATTERNS = [
|
|
16
|
+
/\b(?:error|Error|ERROR|exception|Exception|traceback|Traceback|failed|FAILED)\b/,
|
|
17
|
+
/\b(?:TypeError|SyntaxError|ReferenceError|cannot find|not found|undefined is not)\b/,
|
|
18
|
+
/\b(?:ENOENT|EACCES|EPERM|ECONNREFUSED|ETIMEDOUT)\b/,
|
|
19
|
+
];
|
|
20
|
+
const FILE_TOOL_NAMES = new Set(['Write', 'Edit', 'write', 'edit']);
|
|
21
|
+
const FILE_CREATING_BASH_PATTERNS = [
|
|
22
|
+
/\b(?:mkdir|touch|mv|cp|cat\s+>|echo\s+>|tee)\b/,
|
|
23
|
+
];
|
|
24
|
+
/**
|
|
25
|
+
* Extract structured context from transcript entries using pattern matching.
|
|
26
|
+
* Zero LLM calls — pure heuristic extraction.
|
|
27
|
+
*/
|
|
28
|
+
export function extractFromEntries(entries) {
|
|
29
|
+
const decisions = extractDecisions(entries);
|
|
30
|
+
const openItems = extractOpenItems(entries);
|
|
31
|
+
const unknowns = extractUnknowns(entries);
|
|
32
|
+
const filesChanged = extractFilesChanged(entries);
|
|
33
|
+
const errors = extractErrors(entries);
|
|
34
|
+
const toolsSummary = extractToolsSummary(entries);
|
|
35
|
+
const currentStatus = extractCurrentStatus(entries);
|
|
36
|
+
return {
|
|
37
|
+
current_status: currentStatus,
|
|
38
|
+
decisions,
|
|
39
|
+
open_items: openItems,
|
|
40
|
+
unknowns,
|
|
41
|
+
files_changed: filesChanged,
|
|
42
|
+
errors_encountered: errors,
|
|
43
|
+
tools_summary: toolsSummary,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function extractDecisions(entries) {
|
|
47
|
+
const decisions = [];
|
|
48
|
+
const seen = new Set();
|
|
49
|
+
for (const entry of entries) {
|
|
50
|
+
if (entry.type !== 'assistant')
|
|
51
|
+
continue;
|
|
52
|
+
const text = getEntryText(entry);
|
|
53
|
+
if (!text)
|
|
54
|
+
continue;
|
|
55
|
+
for (const pattern of DECISION_PATTERNS) {
|
|
56
|
+
if (pattern.test(text)) {
|
|
57
|
+
// Extract the sentence containing the decision
|
|
58
|
+
const sentences = text.split(/[.!?\n]/).filter(s => s.trim().length > 10);
|
|
59
|
+
for (const sentence of sentences) {
|
|
60
|
+
if (DECISION_PATTERNS.some(p => p.test(sentence))) {
|
|
61
|
+
const clean = sentence.trim().slice(0, 200);
|
|
62
|
+
const key = clean.toLowerCase().slice(0, 50);
|
|
63
|
+
if (!seen.has(key)) {
|
|
64
|
+
seen.add(key);
|
|
65
|
+
decisions.push({ description: clean });
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
return decisions.slice(0, 15); // maxDecisions
|
|
74
|
+
}
|
|
75
|
+
function extractOpenItems(entries) {
|
|
76
|
+
const items = [];
|
|
77
|
+
const seen = new Set();
|
|
78
|
+
// Process in reverse — more recent items are more relevant
|
|
79
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
80
|
+
const entry = entries[i];
|
|
81
|
+
if (entry.type !== 'assistant')
|
|
82
|
+
continue;
|
|
83
|
+
const text = getEntryText(entry);
|
|
84
|
+
if (!text)
|
|
85
|
+
continue;
|
|
86
|
+
const sentences = text.split(/[.!?\n]/).filter(s => s.trim().length > 10);
|
|
87
|
+
for (const sentence of sentences) {
|
|
88
|
+
if (OPEN_ITEM_PATTERNS.some(p => p.test(sentence))) {
|
|
89
|
+
const clean = sentence.trim().slice(0, 200);
|
|
90
|
+
const key = clean.toLowerCase().slice(0, 50);
|
|
91
|
+
if (!seen.has(key)) {
|
|
92
|
+
seen.add(key);
|
|
93
|
+
items.push({
|
|
94
|
+
description: clean,
|
|
95
|
+
priority: inferPriority(clean),
|
|
96
|
+
});
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
return items.slice(0, 10); // maxOpenItems
|
|
102
|
+
}
|
|
103
|
+
function extractUnknowns(entries) {
|
|
104
|
+
const unknowns = [];
|
|
105
|
+
const seen = new Set();
|
|
106
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
107
|
+
const entry = entries[i];
|
|
108
|
+
if (entry.type !== 'assistant')
|
|
109
|
+
continue;
|
|
110
|
+
const text = getEntryText(entry);
|
|
111
|
+
if (!text)
|
|
112
|
+
continue;
|
|
113
|
+
const sentences = text.split(/[.!?\n]/).filter(s => s.trim().length > 10);
|
|
114
|
+
for (const sentence of sentences) {
|
|
115
|
+
if (UNKNOWN_PATTERNS.some(p => p.test(sentence))) {
|
|
116
|
+
const clean = sentence.trim().slice(0, 200);
|
|
117
|
+
const key = clean.toLowerCase().slice(0, 50);
|
|
118
|
+
if (!seen.has(key)) {
|
|
119
|
+
seen.add(key);
|
|
120
|
+
unknowns.push(clean);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
return unknowns.slice(0, 10);
|
|
126
|
+
}
|
|
127
|
+
function extractFilesChanged(entries) {
|
|
128
|
+
const fileMap = new Map();
|
|
129
|
+
for (const entry of entries) {
|
|
130
|
+
if (entry.type === 'tool_use') {
|
|
131
|
+
const toolName = entry.tool_name ?? '';
|
|
132
|
+
const input = entry.tool_input ?? {};
|
|
133
|
+
if (FILE_TOOL_NAMES.has(toolName)) {
|
|
134
|
+
const filePath = input.file_path ?? input.path ?? '';
|
|
135
|
+
if (filePath) {
|
|
136
|
+
const ops = fileMap.get(filePath) ?? new Set();
|
|
137
|
+
ops.add(toolName.toLowerCase());
|
|
138
|
+
fileMap.set(filePath, ops);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Detect file operations in Bash commands
|
|
142
|
+
if (toolName === 'Bash' || toolName === 'bash') {
|
|
143
|
+
const cmd = input.command ?? '';
|
|
144
|
+
for (const pattern of FILE_CREATING_BASH_PATTERNS) {
|
|
145
|
+
if (pattern.test(cmd)) {
|
|
146
|
+
// Try to extract file path from command
|
|
147
|
+
const parts = cmd.split(/\s+/);
|
|
148
|
+
const lastPart = parts[parts.length - 1];
|
|
149
|
+
if (lastPart && !lastPart.startsWith('-')) {
|
|
150
|
+
const ops = fileMap.get(lastPart) ?? new Set();
|
|
151
|
+
ops.add('create');
|
|
152
|
+
fileMap.set(lastPart, ops);
|
|
153
|
+
}
|
|
154
|
+
break;
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
const result = [];
|
|
161
|
+
for (const [path, ops] of fileMap) {
|
|
162
|
+
result.push({ path, operations: [...ops] });
|
|
163
|
+
}
|
|
164
|
+
return result.slice(0, 20); // maxFilesTracked
|
|
165
|
+
}
|
|
166
|
+
function extractErrors(entries) {
|
|
167
|
+
const errors = [];
|
|
168
|
+
const seen = new Set();
|
|
169
|
+
const resolvedFiles = new Set();
|
|
170
|
+
// First pass: find files that were successfully edited after errors
|
|
171
|
+
for (const entry of entries) {
|
|
172
|
+
if (entry.type === 'tool_use' && FILE_TOOL_NAMES.has(entry.tool_name ?? '')) {
|
|
173
|
+
const filePath = entry.tool_input?.file_path ?? '';
|
|
174
|
+
if (filePath)
|
|
175
|
+
resolvedFiles.add(filePath);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
for (const entry of entries) {
|
|
179
|
+
if (entry.type !== 'tool_result')
|
|
180
|
+
continue;
|
|
181
|
+
const text = getEntryText(entry);
|
|
182
|
+
if (!text)
|
|
183
|
+
continue;
|
|
184
|
+
if (ERROR_PATTERNS.some(p => p.test(text))) {
|
|
185
|
+
// Extract first line of error
|
|
186
|
+
const firstLine = text.split('\n')[0]?.trim().slice(0, 200) ?? '';
|
|
187
|
+
const key = firstLine.toLowerCase().slice(0, 50);
|
|
188
|
+
if (!seen.has(key) && firstLine) {
|
|
189
|
+
seen.add(key);
|
|
190
|
+
errors.push({
|
|
191
|
+
message: firstLine,
|
|
192
|
+
tool: entry.tool_name,
|
|
193
|
+
resolved: false, // Will be updated below
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
return errors.slice(0, 10); // maxErrorsTracked
|
|
199
|
+
}
|
|
200
|
+
function extractToolsSummary(entries) {
|
|
201
|
+
const summary = {};
|
|
202
|
+
for (const entry of entries) {
|
|
203
|
+
if (entry.type === 'tool_use' && entry.tool_name) {
|
|
204
|
+
summary[entry.tool_name] = (summary[entry.tool_name] ?? 0) + 1;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
return summary;
|
|
208
|
+
}
|
|
209
|
+
function extractCurrentStatus(entries) {
|
|
210
|
+
// Find the last substantial assistant message
|
|
211
|
+
for (let i = entries.length - 1; i >= 0; i--) {
|
|
212
|
+
const entry = entries[i];
|
|
213
|
+
if (entry.type !== 'assistant')
|
|
214
|
+
continue;
|
|
215
|
+
const text = getEntryText(entry);
|
|
216
|
+
if (!text || text.length < 50)
|
|
217
|
+
continue;
|
|
218
|
+
// Take first 2-3 sentences or 300 chars
|
|
219
|
+
const sentences = text.split(/(?<=[.!?])\s+/).slice(0, 3);
|
|
220
|
+
return sentences.join(' ').slice(0, 300);
|
|
221
|
+
}
|
|
222
|
+
return 'No status available';
|
|
223
|
+
}
|
|
224
|
+
function getEntryText(entry) {
|
|
225
|
+
if (typeof entry.content === 'string')
|
|
226
|
+
return entry.content;
|
|
227
|
+
return '';
|
|
228
|
+
}
|
|
229
|
+
function inferPriority(text) {
|
|
230
|
+
const lower = text.toLowerCase();
|
|
231
|
+
if (/\b(?:must|critical|urgent|blocker|breaking|immediately)\b/.test(lower))
|
|
232
|
+
return 'high';
|
|
233
|
+
if (/\b(?:should|important|next|before|required)\b/.test(lower))
|
|
234
|
+
return 'medium';
|
|
235
|
+
return 'low';
|
|
236
|
+
}
|
|
237
|
+
//# sourceMappingURL=extractor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extractor.js","sourceRoot":"","sources":["../../src/transcript/extractor.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { TranscriptEntry } from '../types.js';
|
|
2
|
+
export interface ParseOptions {
|
|
3
|
+
startOffset?: number;
|
|
4
|
+
}
|
|
5
|
+
export interface ParseResult {
|
|
6
|
+
entries: TranscriptEntry[];
|
|
7
|
+
bytesRead: number;
|
|
8
|
+
totalBytes: number;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* Stream-parse a JSONL transcript file.
|
|
12
|
+
* Each line is a JSON object representing a message or tool call.
|
|
13
|
+
* Supports reading from a byte offset for incremental parsing.
|
|
14
|
+
*/
|
|
15
|
+
export declare function parseTranscript(transcriptPath: string, options?: ParseOptions): ParseResult;
|
|
16
|
+
//# sourceMappingURL=parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.d.ts","sourceRoot":"","sources":["../../src/transcript/parser.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAC;AAEtE,MAAM,WAAW,YAAY;IAC3B,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,WAAW;IAC1B,OAAO,EAAE,eAAe,EAAE,CAAC;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAAC,cAAc,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY,GAAG,WAAW,CAgD3F"}
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
import { readFileSync, existsSync, statSync } from 'node:fs';
|
|
2
|
+
/**
|
|
3
|
+
* Stream-parse a JSONL transcript file.
|
|
4
|
+
* Each line is a JSON object representing a message or tool call.
|
|
5
|
+
* Supports reading from a byte offset for incremental parsing.
|
|
6
|
+
*/
|
|
7
|
+
export function parseTranscript(transcriptPath, options) {
|
|
8
|
+
if (!existsSync(transcriptPath)) {
|
|
9
|
+
return { entries: [], bytesRead: 0, totalBytes: 0 };
|
|
10
|
+
}
|
|
11
|
+
const startOffset = options?.startOffset ?? 0;
|
|
12
|
+
const stat = statSync(transcriptPath);
|
|
13
|
+
const totalBytes = stat.size;
|
|
14
|
+
if (startOffset >= totalBytes) {
|
|
15
|
+
return { entries: [], bytesRead: totalBytes, totalBytes };
|
|
16
|
+
}
|
|
17
|
+
const raw = readFileSync(transcriptPath, 'utf-8');
|
|
18
|
+
const lines = raw.split('\n');
|
|
19
|
+
const entries = [];
|
|
20
|
+
let currentByteOffset = 0;
|
|
21
|
+
for (const line of lines) {
|
|
22
|
+
const lineBytes = Buffer.byteLength(line + '\n', 'utf-8');
|
|
23
|
+
if (currentByteOffset < startOffset) {
|
|
24
|
+
currentByteOffset += lineBytes;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
currentByteOffset += lineBytes;
|
|
28
|
+
const trimmed = line.trim();
|
|
29
|
+
if (!trimmed)
|
|
30
|
+
continue;
|
|
31
|
+
try {
|
|
32
|
+
const parsed = JSON.parse(trimmed);
|
|
33
|
+
const entry = normalizeEntry(parsed);
|
|
34
|
+
if (entry) {
|
|
35
|
+
entries.push(entry);
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
// Skip malformed lines
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
return {
|
|
43
|
+
entries,
|
|
44
|
+
bytesRead: totalBytes,
|
|
45
|
+
totalBytes,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Normalize various transcript JSON formats into a consistent TranscriptEntry.
|
|
50
|
+
*/
|
|
51
|
+
function normalizeEntry(raw) {
|
|
52
|
+
// Handle different transcript formats
|
|
53
|
+
const type = inferType(raw);
|
|
54
|
+
if (!type)
|
|
55
|
+
return null;
|
|
56
|
+
const content = extractTextContent(raw);
|
|
57
|
+
return {
|
|
58
|
+
type,
|
|
59
|
+
timestamp: raw.timestamp ?? undefined,
|
|
60
|
+
content,
|
|
61
|
+
tool_name: raw.tool_name ?? raw.name ?? undefined,
|
|
62
|
+
tool_input: raw.tool_input ?? raw.input ?? undefined,
|
|
63
|
+
session_id: raw.session_id ?? undefined,
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
function inferType(raw) {
|
|
67
|
+
if (raw.type && typeof raw.type === 'string') {
|
|
68
|
+
const t = raw.type.toLowerCase();
|
|
69
|
+
if (t === 'user' || t === 'human')
|
|
70
|
+
return 'user';
|
|
71
|
+
if (t === 'assistant' || t === 'ai')
|
|
72
|
+
return 'assistant';
|
|
73
|
+
if (t === 'tool_use')
|
|
74
|
+
return 'tool_use';
|
|
75
|
+
if (t === 'tool_result')
|
|
76
|
+
return 'tool_result';
|
|
77
|
+
if (t === 'system')
|
|
78
|
+
return 'system';
|
|
79
|
+
}
|
|
80
|
+
// Infer from role field
|
|
81
|
+
if (raw.role && typeof raw.role === 'string') {
|
|
82
|
+
const r = raw.role.toLowerCase();
|
|
83
|
+
if (r === 'user' || r === 'human')
|
|
84
|
+
return 'user';
|
|
85
|
+
if (r === 'assistant')
|
|
86
|
+
return 'assistant';
|
|
87
|
+
if (r === 'system')
|
|
88
|
+
return 'system';
|
|
89
|
+
}
|
|
90
|
+
// Infer from content structure
|
|
91
|
+
if (raw.tool_name || raw.name)
|
|
92
|
+
return 'tool_use';
|
|
93
|
+
if (raw.tool_use_id)
|
|
94
|
+
return 'tool_result';
|
|
95
|
+
return null;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Extract text content from various message formats.
|
|
99
|
+
*/
|
|
100
|
+
function extractTextContent(raw) {
|
|
101
|
+
const content = raw.content ?? raw.text ?? raw.message ?? '';
|
|
102
|
+
if (typeof content === 'string')
|
|
103
|
+
return content;
|
|
104
|
+
if (Array.isArray(content)) {
|
|
105
|
+
return content
|
|
106
|
+
.map(block => {
|
|
107
|
+
if (typeof block === 'string')
|
|
108
|
+
return block;
|
|
109
|
+
if (block.text)
|
|
110
|
+
return block.text;
|
|
111
|
+
if (block.content && typeof block.content === 'string')
|
|
112
|
+
return block.content;
|
|
113
|
+
return '';
|
|
114
|
+
})
|
|
115
|
+
.filter(Boolean)
|
|
116
|
+
.join('\n');
|
|
117
|
+
}
|
|
118
|
+
return '';
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parser.js","sourceRoot":"","sources":["../../src/transcript/parser.ts"],"names":[],"mappings":"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"}
|
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,156 @@
|
|
|
1
|
+
export interface Snapshot {
|
|
2
|
+
snapshot_id: string;
|
|
3
|
+
timestamp: number;
|
|
4
|
+
session_id: string;
|
|
5
|
+
project_path: string;
|
|
6
|
+
trigger: SnapshotTrigger;
|
|
7
|
+
compaction_cycle: number;
|
|
8
|
+
context_remaining_pct: number;
|
|
9
|
+
token_estimate: number;
|
|
10
|
+
current_status: string;
|
|
11
|
+
decisions: Decision[];
|
|
12
|
+
open_items: OpenItem[];
|
|
13
|
+
unknowns: string[];
|
|
14
|
+
files_changed: FileActivity[];
|
|
15
|
+
errors_encountered: ErrorEntry[];
|
|
16
|
+
tools_summary: Record<string, number>;
|
|
17
|
+
prior_snapshot_id?: string;
|
|
18
|
+
}
|
|
19
|
+
export type SnapshotTrigger = 'pre_compact' | 'time_interval' | 'manual' | 'session_end';
|
|
20
|
+
export interface Decision {
|
|
21
|
+
description: string;
|
|
22
|
+
rationale?: string;
|
|
23
|
+
files?: string[];
|
|
24
|
+
}
|
|
25
|
+
export interface OpenItem {
|
|
26
|
+
description: string;
|
|
27
|
+
priority: 'high' | 'medium' | 'low';
|
|
28
|
+
context?: string;
|
|
29
|
+
}
|
|
30
|
+
export interface FileActivity {
|
|
31
|
+
path: string;
|
|
32
|
+
operations: FileOperation[];
|
|
33
|
+
summary?: string;
|
|
34
|
+
}
|
|
35
|
+
export type FileOperation = 'read' | 'write' | 'edit' | 'create' | 'delete';
|
|
36
|
+
export interface ErrorEntry {
|
|
37
|
+
message: string;
|
|
38
|
+
tool?: string;
|
|
39
|
+
resolved: boolean;
|
|
40
|
+
}
|
|
41
|
+
export interface SnapshotIndex {
|
|
42
|
+
version: string;
|
|
43
|
+
project_path: string;
|
|
44
|
+
last_updated: number;
|
|
45
|
+
stats: IndexStats;
|
|
46
|
+
snapshots: SnapshotEntry[];
|
|
47
|
+
}
|
|
48
|
+
export interface IndexStats {
|
|
49
|
+
total_snapshots: number;
|
|
50
|
+
compaction_cycles: number;
|
|
51
|
+
last_compaction: number;
|
|
52
|
+
last_snapshot: number;
|
|
53
|
+
last_time_based: number;
|
|
54
|
+
}
|
|
55
|
+
export interface SnapshotEntry {
|
|
56
|
+
id: string;
|
|
57
|
+
timestamp: number;
|
|
58
|
+
trigger: SnapshotTrigger;
|
|
59
|
+
compaction_cycle: number;
|
|
60
|
+
context_remaining_pct: number;
|
|
61
|
+
token_estimate: number;
|
|
62
|
+
decisions_count: number;
|
|
63
|
+
files_changed_count: number;
|
|
64
|
+
open_items_count: number;
|
|
65
|
+
}
|
|
66
|
+
export interface BookmarkState {
|
|
67
|
+
version: string;
|
|
68
|
+
session_id: string;
|
|
69
|
+
compaction_count: number;
|
|
70
|
+
current_threshold: number;
|
|
71
|
+
last_snapshot_time: number;
|
|
72
|
+
last_event_time: number;
|
|
73
|
+
snapshot_interval_minutes: number;
|
|
74
|
+
session_history: SessionEntry[];
|
|
75
|
+
}
|
|
76
|
+
export interface SessionEntry {
|
|
77
|
+
session_id: string;
|
|
78
|
+
started: number;
|
|
79
|
+
ended?: number;
|
|
80
|
+
compaction_count: number;
|
|
81
|
+
snapshots_taken: number;
|
|
82
|
+
restored_from?: string;
|
|
83
|
+
}
|
|
84
|
+
export interface TranscriptEntry {
|
|
85
|
+
type: 'user' | 'assistant' | 'tool_use' | 'tool_result' | 'system';
|
|
86
|
+
timestamp?: number;
|
|
87
|
+
content: string | TranscriptContent[];
|
|
88
|
+
tool_name?: string;
|
|
89
|
+
tool_input?: Record<string, unknown>;
|
|
90
|
+
session_id?: string;
|
|
91
|
+
}
|
|
92
|
+
export interface TranscriptContent {
|
|
93
|
+
type: string;
|
|
94
|
+
text?: string;
|
|
95
|
+
name?: string;
|
|
96
|
+
input?: Record<string, unknown>;
|
|
97
|
+
content?: string | TranscriptContent[];
|
|
98
|
+
}
|
|
99
|
+
export interface TokenEstimate {
|
|
100
|
+
total_tokens: number;
|
|
101
|
+
message_count: number;
|
|
102
|
+
user_tokens: number;
|
|
103
|
+
assistant_tokens: number;
|
|
104
|
+
tool_tokens: number;
|
|
105
|
+
system_tokens: number;
|
|
106
|
+
context_limit: number;
|
|
107
|
+
remaining_pct: number;
|
|
108
|
+
remaining_tokens: number;
|
|
109
|
+
}
|
|
110
|
+
export interface ExtractionResult {
|
|
111
|
+
current_status: string;
|
|
112
|
+
decisions: Decision[];
|
|
113
|
+
open_items: OpenItem[];
|
|
114
|
+
unknowns: string[];
|
|
115
|
+
files_changed: FileActivity[];
|
|
116
|
+
errors_encountered: ErrorEntry[];
|
|
117
|
+
tools_summary: Record<string, number>;
|
|
118
|
+
}
|
|
119
|
+
export interface HookInput {
|
|
120
|
+
session_id: string;
|
|
121
|
+
transcript_path: string;
|
|
122
|
+
cwd: string;
|
|
123
|
+
permission_mode?: string;
|
|
124
|
+
hook_event_name: string;
|
|
125
|
+
trigger?: 'manual' | 'auto';
|
|
126
|
+
source?: 'startup' | 'resume' | 'compact' | 'clear';
|
|
127
|
+
custom_instructions?: string;
|
|
128
|
+
}
|
|
129
|
+
export interface HookOutput {
|
|
130
|
+
systemMessage?: string;
|
|
131
|
+
suppressOutput?: boolean;
|
|
132
|
+
}
|
|
133
|
+
export interface BookmarkConfig {
|
|
134
|
+
storagePath: string;
|
|
135
|
+
thresholds: number[];
|
|
136
|
+
maxThreshold: number;
|
|
137
|
+
intervalMinutes: number;
|
|
138
|
+
contextLimitTokens: number;
|
|
139
|
+
charsPerToken: number;
|
|
140
|
+
maxDecisions: number;
|
|
141
|
+
maxOpenItems: number;
|
|
142
|
+
maxFilesTracked: number;
|
|
143
|
+
maxErrorsTracked: number;
|
|
144
|
+
summaryTokenBudget: number;
|
|
145
|
+
maxActiveSnapshots: number;
|
|
146
|
+
archiveAfterDays: number;
|
|
147
|
+
snapshotOnSessionEnd: boolean;
|
|
148
|
+
restoreOnSessionStart: boolean;
|
|
149
|
+
smartDefault: boolean;
|
|
150
|
+
verboseLogging: boolean;
|
|
151
|
+
}
|
|
152
|
+
export interface SetupPreferences {
|
|
153
|
+
intervalMinutes: number;
|
|
154
|
+
smartDefault: boolean;
|
|
155
|
+
}
|
|
156
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,yBAAyB"}
|
package/hooks/hooks.json
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
{
|
|
2
|
+
"hooks": {
|
|
3
|
+
"PreCompact": [
|
|
4
|
+
{
|
|
5
|
+
"matcher": "",
|
|
6
|
+
"hooks": [
|
|
7
|
+
{
|
|
8
|
+
"type": "command",
|
|
9
|
+
"command": "npx @tyroneross/bookmark snapshot --trigger pre_compact 2>/dev/null || true",
|
|
10
|
+
"timeout": 30000,
|
|
11
|
+
"async": true
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
}
|
|
15
|
+
],
|
|
16
|
+
"SessionStart": [
|
|
17
|
+
{
|
|
18
|
+
"matcher": "",
|
|
19
|
+
"hooks": [
|
|
20
|
+
{
|
|
21
|
+
"type": "command",
|
|
22
|
+
"command": "npx @tyroneross/bookmark restore 2>/dev/null || echo '{}'",
|
|
23
|
+
"timeout": 5000
|
|
24
|
+
}
|
|
25
|
+
]
|
|
26
|
+
}
|
|
27
|
+
],
|
|
28
|
+
"UserPromptSubmit": [
|
|
29
|
+
{
|
|
30
|
+
"matcher": "",
|
|
31
|
+
"hooks": [
|
|
32
|
+
{
|
|
33
|
+
"type": "command",
|
|
34
|
+
"command": "npx @tyroneross/bookmark check 2>/dev/null || true",
|
|
35
|
+
"timeout": 3000,
|
|
36
|
+
"async": true
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
],
|
|
41
|
+
"Stop": [
|
|
42
|
+
{
|
|
43
|
+
"matcher": "",
|
|
44
|
+
"hooks": [
|
|
45
|
+
{
|
|
46
|
+
"type": "command",
|
|
47
|
+
"command": "npx @tyroneross/bookmark snapshot --trigger session_end 2>/dev/null || true",
|
|
48
|
+
"timeout": 15000
|
|
49
|
+
}
|
|
50
|
+
]
|
|
51
|
+
}
|
|
52
|
+
]
|
|
53
|
+
}
|
|
54
|
+
}
|