greprag 5.41.0 → 5.42.1
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/dist/archive/glyph-font.d.ts +22 -0
- package/dist/archive/glyph-font.js +72 -0
- package/dist/archive/glyph-font.js.map +1 -0
- package/dist/archive/page-renderer.d.ts +67 -0
- package/dist/archive/page-renderer.js +197 -0
- package/dist/archive/page-renderer.js.map +1 -0
- package/dist/archive/png-codec.d.ts +21 -0
- package/dist/archive/png-codec.js +197 -0
- package/dist/archive/png-codec.js.map +1 -0
- package/dist/archive/transcript-extract.d.ts +39 -0
- package/dist/archive/transcript-extract.js +187 -0
- package/dist/archive/transcript-extract.js.map +1 -0
- package/dist/ccr-store.d.ts +49 -0
- package/dist/ccr-store.js +171 -0
- package/dist/ccr-store.js.map +1 -0
- package/dist/commands/archive.d.ts +81 -0
- package/dist/commands/archive.js +358 -0
- package/dist/commands/archive.js.map +1 -0
- package/dist/commands/context-governor.d.ts +82 -0
- package/dist/commands/context-governor.js +344 -0
- package/dist/commands/context-governor.js.map +1 -0
- package/dist/commands/crush-stats.d.ts +36 -0
- package/dist/commands/crush-stats.js +142 -0
- package/dist/commands/crush-stats.js.map +1 -0
- package/dist/commands/crush.d.ts +24 -0
- package/dist/commands/crush.js +183 -0
- package/dist/commands/crush.js.map +1 -0
- package/dist/commands/inbox-watch-supervisor.js +8 -65
- package/dist/commands/inbox-watch-supervisor.js.map +1 -1
- package/dist/commands/init.js +93 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/pipe-wrap.d.ts +97 -0
- package/dist/commands/pipe-wrap.js +324 -0
- package/dist/commands/pipe-wrap.js.map +1 -0
- package/dist/commands/watcher-registry.d.ts +1 -8
- package/dist/commands/watcher-registry.js +10 -47
- package/dist/commands/watcher-registry.js.map +1 -1
- package/dist/crush/adaptive-sizer.d.ts +40 -0
- package/dist/crush/adaptive-sizer.js +156 -0
- package/dist/crush/adaptive-sizer.js.map +1 -0
- package/dist/crush/crush-keywords.d.ts +40 -0
- package/dist/crush/crush-keywords.js +110 -0
- package/dist/crush/crush-keywords.js.map +1 -0
- package/dist/crush/crush-types.d.ts +38 -0
- package/dist/crush/crush-types.js +36 -0
- package/dist/crush/crush-types.js.map +1 -0
- package/dist/crush/index.d.ts +16 -0
- package/dist/crush/index.js +48 -0
- package/dist/crush/index.js.map +1 -0
- package/dist/crush/json-crusher.d.ts +38 -0
- package/dist/crush/json-crusher.js +250 -0
- package/dist/crush/json-crusher.js.map +1 -0
- package/dist/crush/json-detectors.d.ts +48 -0
- package/dist/crush/json-detectors.js +211 -0
- package/dist/crush/json-detectors.js.map +1 -0
- package/dist/crush/log-compressor.d.ts +60 -0
- package/dist/crush/log-compressor.js +394 -0
- package/dist/crush/log-compressor.js.map +1 -0
- package/dist/crush/search-compressor.d.ts +60 -0
- package/dist/crush/search-compressor.js +210 -0
- package/dist/crush/search-compressor.js.map +1 -0
- package/dist/hook.js +49 -1
- package/dist/hook.js.map +1 -1
- package/dist/index.js +487 -449
- package/dist/index.js.map +1 -1
- package/dist/session-id.js +7 -12
- package/dist/session-id.js.map +1 -1
- package/package.json +2 -2
- package/skill/mechanic/SKILL.md +1 -1
- package/skill/templates/chip-spawn.md +4 -2
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// adr: adr/governed-compact.md
|
|
3
|
+
/** Transcript extraction for the PNG archive — JSONL -> flat conversation
|
|
4
|
+
* text with turn-numbered section headers.
|
|
5
|
+
*
|
|
6
|
+
* Main chain only: sidechain (subagent) entries are skipped — the archive
|
|
7
|
+
* is the record of THIS conversation, which is what compaction is about to
|
|
8
|
+
* summarize away. A "turn" increments on each real user message (one with
|
|
9
|
+
* text content, not a tool_result carrier), matching the turn notion used
|
|
10
|
+
* across the hook layer.
|
|
11
|
+
*
|
|
12
|
+
* Section headers (`=== T<n> USER ===` etc.) give the vision model anchors
|
|
13
|
+
* to scan for, and give the indexer the char offsets it needs to stamp a
|
|
14
|
+
* turn range onto every rendered page.
|
|
15
|
+
*/
|
|
16
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
19
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
20
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
21
|
+
}
|
|
22
|
+
Object.defineProperty(o, k2, desc);
|
|
23
|
+
}) : (function(o, m, k, k2) {
|
|
24
|
+
if (k2 === undefined) k2 = k;
|
|
25
|
+
o[k2] = m[k];
|
|
26
|
+
}));
|
|
27
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
28
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
29
|
+
}) : function(o, v) {
|
|
30
|
+
o["default"] = v;
|
|
31
|
+
});
|
|
32
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
33
|
+
var ownKeys = function(o) {
|
|
34
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
35
|
+
var ar = [];
|
|
36
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
37
|
+
return ar;
|
|
38
|
+
};
|
|
39
|
+
return ownKeys(o);
|
|
40
|
+
};
|
|
41
|
+
return function (mod) {
|
|
42
|
+
if (mod && mod.__esModule) return mod;
|
|
43
|
+
var result = {};
|
|
44
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
45
|
+
__setModuleDefault(result, mod);
|
|
46
|
+
return result;
|
|
47
|
+
};
|
|
48
|
+
})();
|
|
49
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
50
|
+
exports.extractConversation = extractConversation;
|
|
51
|
+
exports.extractTranscriptFile = extractTranscriptFile;
|
|
52
|
+
exports.turnRangeForWindow = turnRangeForWindow;
|
|
53
|
+
const fs = __importStar(require("fs"));
|
|
54
|
+
function textBlocks(content) {
|
|
55
|
+
if (typeof content === 'string')
|
|
56
|
+
return content.trim();
|
|
57
|
+
if (!Array.isArray(content))
|
|
58
|
+
return '';
|
|
59
|
+
return content
|
|
60
|
+
.filter((b) => b?.type === 'text' && typeof b.text === 'string')
|
|
61
|
+
.map((b) => b.text)
|
|
62
|
+
.join('\n')
|
|
63
|
+
.trim();
|
|
64
|
+
}
|
|
65
|
+
function toolResultText(content) {
|
|
66
|
+
if (typeof content === 'string')
|
|
67
|
+
return content;
|
|
68
|
+
if (!Array.isArray(content))
|
|
69
|
+
return '';
|
|
70
|
+
return content
|
|
71
|
+
.filter((b) => typeof b === 'string' || b?.type === 'text')
|
|
72
|
+
.map((b) => typeof b === 'string' ? b : (b.text || ''))
|
|
73
|
+
.join('\n');
|
|
74
|
+
}
|
|
75
|
+
/** One-line summary of a tool_use block: name + its most identifying input. */
|
|
76
|
+
function toolUseLine(block) {
|
|
77
|
+
const name = block.name || 'unknown';
|
|
78
|
+
const input = (block.input || {});
|
|
79
|
+
const target = input.file_path ||
|
|
80
|
+
input.command ||
|
|
81
|
+
input.pattern ||
|
|
82
|
+
input.url ||
|
|
83
|
+
input.query ||
|
|
84
|
+
input.description ||
|
|
85
|
+
'';
|
|
86
|
+
const brief = target.length > 200 ? target.slice(0, 200) + '…' : target;
|
|
87
|
+
return brief ? `>> ${name}: ${brief}` : `>> ${name}`;
|
|
88
|
+
}
|
|
89
|
+
/** Extract the main-chain conversation from a transcript JSONL string. */
|
|
90
|
+
function extractConversation(jsonl) {
|
|
91
|
+
const sections = [];
|
|
92
|
+
const turnMarks = [];
|
|
93
|
+
let turn = 0;
|
|
94
|
+
let offset = 0;
|
|
95
|
+
const push = (header, body) => {
|
|
96
|
+
const section = `=== ${header} ===\n${body}\n`;
|
|
97
|
+
sections.push(section);
|
|
98
|
+
offset += section.length;
|
|
99
|
+
};
|
|
100
|
+
for (const line of jsonl.split('\n')) {
|
|
101
|
+
const trimmed = line.trim();
|
|
102
|
+
if (!trimmed)
|
|
103
|
+
continue;
|
|
104
|
+
let entry;
|
|
105
|
+
try {
|
|
106
|
+
entry = JSON.parse(trimmed);
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
if (entry.isSidechain === true)
|
|
112
|
+
continue;
|
|
113
|
+
const msg = (entry.message || entry);
|
|
114
|
+
const role = (msg.role || entry.type || '');
|
|
115
|
+
if (role === 'user') {
|
|
116
|
+
const content = msg.content;
|
|
117
|
+
// Tool results ride user-role entries — archive them under the turn.
|
|
118
|
+
if (Array.isArray(content)) {
|
|
119
|
+
for (const b of content) {
|
|
120
|
+
if (b?.type === 'tool_result') {
|
|
121
|
+
const out = toolResultText(b.content).trim();
|
|
122
|
+
if (out)
|
|
123
|
+
push(`T${turn} TOOL RESULT`, out);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
const text = textBlocks(content);
|
|
128
|
+
if (text) {
|
|
129
|
+
turn += 1;
|
|
130
|
+
turnMarks.push({ turn, charStart: offset });
|
|
131
|
+
push(`T${turn} USER`, text);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
else if (role === 'assistant') {
|
|
135
|
+
const content = msg.content;
|
|
136
|
+
const text = textBlocks(content);
|
|
137
|
+
const toolLines = [];
|
|
138
|
+
if (Array.isArray(content)) {
|
|
139
|
+
for (const b of content) {
|
|
140
|
+
if (b?.type === 'tool_use')
|
|
141
|
+
toolLines.push(toolUseLine(b));
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
const body = [text, toolLines.join('\n')].filter(Boolean).join('\n');
|
|
145
|
+
if (body)
|
|
146
|
+
push(`T${turn} ASSISTANT`, body);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
return { text: sections.join(''), turnMarks, turns: turn };
|
|
150
|
+
}
|
|
151
|
+
/** File wrapper. Returns null when the transcript can't be read. */
|
|
152
|
+
function extractTranscriptFile(transcriptPath) {
|
|
153
|
+
try {
|
|
154
|
+
return extractConversation(fs.readFileSync(transcriptPath, 'utf-8'));
|
|
155
|
+
}
|
|
156
|
+
catch {
|
|
157
|
+
return null;
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
/** Turn range [first, last] overlapping a char window. turnMarks must be
|
|
161
|
+
* ascending and in the SAME offset space as the window (callers re-map
|
|
162
|
+
* marks through sanitizeWithMarks before paginating). A turn spans from
|
|
163
|
+
* its mark to the next mark (the last turn runs to infinity). Content
|
|
164
|
+
* before the first mark (rare T0 preamble) reports as turn 0. */
|
|
165
|
+
function turnRangeForWindow(marks, charStart, charEnd) {
|
|
166
|
+
let turnStart = null;
|
|
167
|
+
let turnEnd = null;
|
|
168
|
+
for (let i = 0; i < marks.length; i++) {
|
|
169
|
+
const begin = marks[i].charStart;
|
|
170
|
+
const end = i + 1 < marks.length ? marks[i + 1].charStart : Number.MAX_SAFE_INTEGER;
|
|
171
|
+
if (begin < charEnd && end > charStart) {
|
|
172
|
+
if (turnStart === null)
|
|
173
|
+
turnStart = marks[i].turn;
|
|
174
|
+
turnEnd = marks[i].turn;
|
|
175
|
+
}
|
|
176
|
+
if (begin >= charEnd)
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
if (turnStart === null || turnEnd === null)
|
|
180
|
+
return { turnStart: 0, turnEnd: 0 };
|
|
181
|
+
// Window opens before the first overlapping mark -> preamble included.
|
|
182
|
+
if (marks.length && charStart < marks[0].charStart && turnStart === marks[0].turn) {
|
|
183
|
+
turnStart = Math.min(turnStart, marks[0].turn);
|
|
184
|
+
}
|
|
185
|
+
return { turnStart, turnEnd };
|
|
186
|
+
}
|
|
187
|
+
//# sourceMappingURL=transcript-extract.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"transcript-extract.js","sourceRoot":"","sources":["../../src/archive/transcript-extract.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* CCR (Cached Content Retrieval) store — local sqlite stash for tool
|
|
3
|
+
* output the crush engine elided. `greprag crush --ccr` puts the
|
|
4
|
+
* original here and appends a `<<ccr:HASH>>` marker; `greprag retrieve
|
|
5
|
+
* <hash>` reads it back. Chip D's PNG-archive indexing consumes the
|
|
6
|
+
* same API — keep it stable.
|
|
7
|
+
*
|
|
8
|
+
* Backed by sql.js (the CLI's existing sqlite dep — WASM, no native
|
|
9
|
+
* build). The DB lives at ~/.greprag/ccr.db; override with
|
|
10
|
+
* GREPRAG_CCR_DB (tests point it at a temp file).
|
|
11
|
+
*
|
|
12
|
+
* Keys are sha256: the full 64-hex digest is stored; lookups accept any
|
|
13
|
+
* unique prefix >= 16 hex chars (the marker carries the first 16).
|
|
14
|
+
*/
|
|
15
|
+
/** Marker appended to crushed output: first 16 hex of the sha256. */
|
|
16
|
+
export declare const CCR_MARKER_HASH_LEN = 16;
|
|
17
|
+
export declare function defaultCcrDbPath(): string;
|
|
18
|
+
export declare function ccrMarker(hash: string): string;
|
|
19
|
+
export declare class CcrStore {
|
|
20
|
+
private db;
|
|
21
|
+
private dbPath;
|
|
22
|
+
private constructor();
|
|
23
|
+
/** Open (creating file + schema as needed). */
|
|
24
|
+
static open(dbPath?: string): Promise<CcrStore>;
|
|
25
|
+
/**
|
|
26
|
+
* Store an original. Returns the first 16 hex chars of its sha256 —
|
|
27
|
+
* the marker-friendly key. Idempotent (same content -> same hash).
|
|
28
|
+
*/
|
|
29
|
+
put(original: string, sourceType?: string): string;
|
|
30
|
+
/**
|
|
31
|
+
* Retrieve an original by hash (full digest or any prefix >= 8 hex).
|
|
32
|
+
* Returns null when not found or ambiguous-by-prefix.
|
|
33
|
+
*/
|
|
34
|
+
get(hash: string): string | null;
|
|
35
|
+
/** All entries of one source_type, newest first. Additive for Chip D:
|
|
36
|
+
* 'png-archive' rows hold JSON metadata (file path + char/turn ranges)
|
|
37
|
+
* pointing at rendered archive pages — `greprag archive list` reads
|
|
38
|
+
* them back out. */
|
|
39
|
+
listBySourceType(sourceType: string): Array<{
|
|
40
|
+
hash: string;
|
|
41
|
+
content: string;
|
|
42
|
+
createdAt: string;
|
|
43
|
+
}>;
|
|
44
|
+
/** Number of stored entries. */
|
|
45
|
+
count(): number;
|
|
46
|
+
/** Flush to disk (atomic: temp file + rename). */
|
|
47
|
+
private persist;
|
|
48
|
+
close(): void;
|
|
49
|
+
}
|
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// adr: adr/crush-engine.md
|
|
3
|
+
/**
|
|
4
|
+
* CCR (Cached Content Retrieval) store — local sqlite stash for tool
|
|
5
|
+
* output the crush engine elided. `greprag crush --ccr` puts the
|
|
6
|
+
* original here and appends a `<<ccr:HASH>>` marker; `greprag retrieve
|
|
7
|
+
* <hash>` reads it back. Chip D's PNG-archive indexing consumes the
|
|
8
|
+
* same API — keep it stable.
|
|
9
|
+
*
|
|
10
|
+
* Backed by sql.js (the CLI's existing sqlite dep — WASM, no native
|
|
11
|
+
* build). The DB lives at ~/.greprag/ccr.db; override with
|
|
12
|
+
* GREPRAG_CCR_DB (tests point it at a temp file).
|
|
13
|
+
*
|
|
14
|
+
* Keys are sha256: the full 64-hex digest is stored; lookups accept any
|
|
15
|
+
* unique prefix >= 16 hex chars (the marker carries the first 16).
|
|
16
|
+
*/
|
|
17
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
18
|
+
if (k2 === undefined) k2 = k;
|
|
19
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
20
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
21
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
22
|
+
}
|
|
23
|
+
Object.defineProperty(o, k2, desc);
|
|
24
|
+
}) : (function(o, m, k, k2) {
|
|
25
|
+
if (k2 === undefined) k2 = k;
|
|
26
|
+
o[k2] = m[k];
|
|
27
|
+
}));
|
|
28
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
29
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
30
|
+
}) : function(o, v) {
|
|
31
|
+
o["default"] = v;
|
|
32
|
+
});
|
|
33
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
34
|
+
var ownKeys = function(o) {
|
|
35
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
36
|
+
var ar = [];
|
|
37
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
38
|
+
return ar;
|
|
39
|
+
};
|
|
40
|
+
return ownKeys(o);
|
|
41
|
+
};
|
|
42
|
+
return function (mod) {
|
|
43
|
+
if (mod && mod.__esModule) return mod;
|
|
44
|
+
var result = {};
|
|
45
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
46
|
+
__setModuleDefault(result, mod);
|
|
47
|
+
return result;
|
|
48
|
+
};
|
|
49
|
+
})();
|
|
50
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
51
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
52
|
+
};
|
|
53
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
54
|
+
exports.CcrStore = exports.CCR_MARKER_HASH_LEN = void 0;
|
|
55
|
+
exports.defaultCcrDbPath = defaultCcrDbPath;
|
|
56
|
+
exports.ccrMarker = ccrMarker;
|
|
57
|
+
const crypto = __importStar(require("crypto"));
|
|
58
|
+
const fs = __importStar(require("fs"));
|
|
59
|
+
const os = __importStar(require("os"));
|
|
60
|
+
const path = __importStar(require("path"));
|
|
61
|
+
const sql_js_1 = __importDefault(require("sql.js"));
|
|
62
|
+
/** Marker appended to crushed output: first 16 hex of the sha256. */
|
|
63
|
+
exports.CCR_MARKER_HASH_LEN = 16;
|
|
64
|
+
function defaultCcrDbPath() {
|
|
65
|
+
return process.env.GREPRAG_CCR_DB || path.join(os.homedir(), '.greprag', 'ccr.db');
|
|
66
|
+
}
|
|
67
|
+
function ccrMarker(hash) {
|
|
68
|
+
return `<<ccr:${hash.slice(0, exports.CCR_MARKER_HASH_LEN)}>>`;
|
|
69
|
+
}
|
|
70
|
+
let sqlJs = null;
|
|
71
|
+
async function loadSqlJs() {
|
|
72
|
+
if (!sqlJs) {
|
|
73
|
+
sqlJs = await (0, sql_js_1.default)({
|
|
74
|
+
locateFile: (f) => path.join(path.dirname(require.resolve('sql.js')), f),
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
return sqlJs;
|
|
78
|
+
}
|
|
79
|
+
class CcrStore {
|
|
80
|
+
constructor(db, dbPath) {
|
|
81
|
+
this.db = db;
|
|
82
|
+
this.dbPath = dbPath;
|
|
83
|
+
}
|
|
84
|
+
/** Open (creating file + schema as needed). */
|
|
85
|
+
static async open(dbPath) {
|
|
86
|
+
const resolved = dbPath || defaultCcrDbPath();
|
|
87
|
+
const SQL = await loadSqlJs();
|
|
88
|
+
let db;
|
|
89
|
+
if (fs.existsSync(resolved)) {
|
|
90
|
+
db = new SQL.Database(fs.readFileSync(resolved));
|
|
91
|
+
}
|
|
92
|
+
else {
|
|
93
|
+
db = new SQL.Database();
|
|
94
|
+
}
|
|
95
|
+
db.run(`CREATE TABLE IF NOT EXISTS ccr_entries (
|
|
96
|
+
hash TEXT PRIMARY KEY,
|
|
97
|
+
content TEXT NOT NULL,
|
|
98
|
+
source_type TEXT,
|
|
99
|
+
created_at TEXT NOT NULL
|
|
100
|
+
)`);
|
|
101
|
+
return new CcrStore(db, resolved);
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Store an original. Returns the first 16 hex chars of its sha256 —
|
|
105
|
+
* the marker-friendly key. Idempotent (same content -> same hash).
|
|
106
|
+
*/
|
|
107
|
+
put(original, sourceType) {
|
|
108
|
+
const fullHash = crypto.createHash('sha256').update(original, 'utf8').digest('hex');
|
|
109
|
+
this.db.run('INSERT OR IGNORE INTO ccr_entries (hash, content, source_type, created_at) VALUES (?, ?, ?, ?)', [fullHash, original, sourceType ?? null, new Date().toISOString()]);
|
|
110
|
+
this.persist();
|
|
111
|
+
return fullHash.slice(0, exports.CCR_MARKER_HASH_LEN);
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Retrieve an original by hash (full digest or any prefix >= 8 hex).
|
|
115
|
+
* Returns null when not found or ambiguous-by-prefix.
|
|
116
|
+
*/
|
|
117
|
+
get(hash) {
|
|
118
|
+
const needle = hash.trim().toLowerCase().replace(/^<<ccr:/, '').replace(/>>$/, '');
|
|
119
|
+
if (!/^[0-9a-f]{8,64}$/.test(needle))
|
|
120
|
+
return null;
|
|
121
|
+
const stmt = this.db.prepare("SELECT content FROM ccr_entries WHERE hash LIKE ? || '%' LIMIT 2");
|
|
122
|
+
const rows = [];
|
|
123
|
+
try {
|
|
124
|
+
stmt.bind([needle]);
|
|
125
|
+
while (stmt.step()) {
|
|
126
|
+
rows.push(stmt.get()[0]);
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
finally {
|
|
130
|
+
stmt.free();
|
|
131
|
+
}
|
|
132
|
+
return rows.length === 1 ? rows[0] : null;
|
|
133
|
+
}
|
|
134
|
+
/** All entries of one source_type, newest first. Additive for Chip D:
|
|
135
|
+
* 'png-archive' rows hold JSON metadata (file path + char/turn ranges)
|
|
136
|
+
* pointing at rendered archive pages — `greprag archive list` reads
|
|
137
|
+
* them back out. */
|
|
138
|
+
listBySourceType(sourceType) {
|
|
139
|
+
const stmt = this.db.prepare('SELECT hash, content, created_at FROM ccr_entries WHERE source_type = ? ORDER BY created_at DESC');
|
|
140
|
+
const rows = [];
|
|
141
|
+
try {
|
|
142
|
+
stmt.bind([sourceType]);
|
|
143
|
+
while (stmt.step()) {
|
|
144
|
+
const [hash, content, createdAt] = stmt.get();
|
|
145
|
+
rows.push({ hash, content, createdAt });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
finally {
|
|
149
|
+
stmt.free();
|
|
150
|
+
}
|
|
151
|
+
return rows;
|
|
152
|
+
}
|
|
153
|
+
/** Number of stored entries. */
|
|
154
|
+
count() {
|
|
155
|
+
const res = this.db.exec('SELECT COUNT(*) FROM ccr_entries');
|
|
156
|
+
return Number(res[0]?.values?.[0]?.[0] ?? 0);
|
|
157
|
+
}
|
|
158
|
+
/** Flush to disk (atomic: temp file + rename). */
|
|
159
|
+
persist() {
|
|
160
|
+
const dir = path.dirname(this.dbPath);
|
|
161
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
162
|
+
const tmp = this.dbPath + '.tmp.' + process.pid;
|
|
163
|
+
fs.writeFileSync(tmp, Buffer.from(this.db.export()));
|
|
164
|
+
fs.renameSync(tmp, this.dbPath);
|
|
165
|
+
}
|
|
166
|
+
close() {
|
|
167
|
+
this.db.close();
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
exports.CcrStore = CcrStore;
|
|
171
|
+
//# sourceMappingURL=ccr-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ccr-store.js","sourceRoot":"","sources":["../src/ccr-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
/** greprag archive — the governed compact's PNG archive.
|
|
2
|
+
*
|
|
3
|
+
* Before compaction summarizes history away, the PreCompact hook renders
|
|
4
|
+
* the transcript's main chain to dense pixel-font PNGs (Snapcompact
|
|
5
|
+
* pattern: ~3x token density via the vision path) and indexes every page
|
|
6
|
+
* in the CCR store. After compaction, a SessionStart(matcher=compact)
|
|
7
|
+
* hook injects a pointer so the post-compact model knows the verbatim
|
|
8
|
+
* record exists and can Read the pages back.
|
|
9
|
+
*
|
|
10
|
+
* Verified hook contract (2026-06-12, code.claude.com/docs/en/hooks):
|
|
11
|
+
* PreCompact CANNOT inject or modify compaction instructions — so the
|
|
12
|
+
* instructions ship as a documented `/compact <snippet>` block
|
|
13
|
+
* (`greprag archive snippet`) referenced by the context governor's
|
|
14
|
+
* advisory, and the post-compact pointer rides SessionStart(compact),
|
|
15
|
+
* whose stdout/additionalContext IS added to context.
|
|
16
|
+
*
|
|
17
|
+
* Surfaces:
|
|
18
|
+
* greprag archive render --transcript <path> [--out-dir <dir>] [--session <8hex>]
|
|
19
|
+
* greprag archive list [--session <8hex>]
|
|
20
|
+
* greprag archive snippet [--session <8hex>]
|
|
21
|
+
* hook: runPreCompactArchive (PreCompact), buildArchivePointer (SessionStart)
|
|
22
|
+
*/
|
|
23
|
+
export declare const SOURCE_TYPE = "png-archive";
|
|
24
|
+
export declare const ARCHIVE_HELP: string;
|
|
25
|
+
export declare function archiveEnabled(cwd: string): boolean;
|
|
26
|
+
export declare function defaultArchiveDir(session: string): string;
|
|
27
|
+
/** Page metadata stored as the CCR row's content. Deliberately contains no
|
|
28
|
+
* timestamp: identical content -> identical JSON -> identical sha256 key,
|
|
29
|
+
* so re-rendering the same transcript state never duplicates rows. */
|
|
30
|
+
export interface PageMeta {
|
|
31
|
+
kind: typeof SOURCE_TYPE;
|
|
32
|
+
session: string;
|
|
33
|
+
renderId: string;
|
|
34
|
+
file: string;
|
|
35
|
+
page: number;
|
|
36
|
+
pages: number;
|
|
37
|
+
charStart: number;
|
|
38
|
+
charEnd: number;
|
|
39
|
+
chars: number;
|
|
40
|
+
turnStart: number;
|
|
41
|
+
turnEnd: number;
|
|
42
|
+
}
|
|
43
|
+
export interface RenderSummary {
|
|
44
|
+
session: string;
|
|
45
|
+
outDir: string;
|
|
46
|
+
renderId: string;
|
|
47
|
+
pages: number;
|
|
48
|
+
chars: number;
|
|
49
|
+
turns: number;
|
|
50
|
+
files: string[];
|
|
51
|
+
/** null = every page passed the pixel round-trip self-test. */
|
|
52
|
+
selfTestError: string | null;
|
|
53
|
+
}
|
|
54
|
+
/** Render a transcript to PNG pages, self-test, write, and index. */
|
|
55
|
+
export declare function renderArchive(opts: {
|
|
56
|
+
transcriptPath: string;
|
|
57
|
+
outDir?: string;
|
|
58
|
+
session?: string;
|
|
59
|
+
}): Promise<RenderSummary | null>;
|
|
60
|
+
interface ArchiveGroup {
|
|
61
|
+
session: string;
|
|
62
|
+
renderId: string;
|
|
63
|
+
createdAt: string;
|
|
64
|
+
pages: PageMeta[];
|
|
65
|
+
}
|
|
66
|
+
export declare function listArchives(session?: string | null): Promise<ArchiveGroup[]>;
|
|
67
|
+
export declare function buildCompactSnippet(session: string): string;
|
|
68
|
+
export interface ArchiveHookInput {
|
|
69
|
+
session_id?: string;
|
|
70
|
+
transcript_path?: string;
|
|
71
|
+
trigger?: string;
|
|
72
|
+
cwd?: string;
|
|
73
|
+
}
|
|
74
|
+
/** PreCompact — render + index, return a user-facing systemMessage (or null
|
|
75
|
+
* when disabled/empty/failed). NEVER throws; never blocks compaction. */
|
|
76
|
+
export declare function runPreCompactArchive(input: ArchiveHookInput): Promise<string | null>;
|
|
77
|
+
/** SessionStart(matcher=compact) — pointer for the post-compact model.
|
|
78
|
+
* Returns additionalContext text, or null when no archive exists. */
|
|
79
|
+
export declare function buildArchivePointer(input: ArchiveHookInput): Promise<string | null>;
|
|
80
|
+
export declare function runArchive(args: string[]): Promise<void>;
|
|
81
|
+
export {};
|