greprag 5.32.0 → 5.35.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/dist/codex-hook-events.d.ts +20 -0
- package/dist/codex-hook-events.js +156 -0
- package/dist/codex-hook-events.js.map +1 -0
- package/dist/commands/codex-app-server.d.ts +1 -0
- package/dist/commands/codex-app-server.js +179 -0
- package/dist/commands/codex-app-server.js.map +1 -0
- package/dist/commands/codex-doctor.js +3 -1
- package/dist/commands/codex-doctor.js.map +1 -1
- package/dist/commands/codex.js +6 -0
- package/dist/commands/codex.js.map +1 -1
- package/dist/commands/corpus/index.d.ts +1 -0
- package/dist/commands/corpus/index.js +5 -0
- package/dist/commands/corpus/index.js.map +1 -1
- package/dist/commands/corpus/refresh.d.ts +1 -0
- package/dist/commands/corpus/refresh.js +60 -0
- package/dist/commands/corpus/refresh.js.map +1 -1
- package/dist/commands/desk-line.d.ts +36 -0
- package/dist/commands/desk-line.js +248 -0
- package/dist/commands/desk-line.js.map +1 -0
- package/dist/commands/inbox-spool.d.ts +27 -0
- package/dist/commands/inbox-spool.js +151 -0
- package/dist/commands/inbox-spool.js.map +1 -0
- package/dist/commands/inbox-watch.js +59 -8
- package/dist/commands/inbox-watch.js.map +1 -1
- package/dist/commands/init.js +75 -7
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/opencode-relay.d.ts +136 -0
- package/dist/commands/opencode-relay.js +529 -0
- package/dist/commands/opencode-relay.js.map +1 -0
- package/dist/commands/opencode-watch.d.ts +17 -0
- package/dist/commands/opencode-watch.js +493 -0
- package/dist/commands/opencode-watch.js.map +1 -0
- package/dist/commands/status.d.ts +2 -0
- package/dist/commands/status.js +5 -1
- package/dist/commands/status.js.map +1 -1
- package/dist/commands/watcher-registry.d.ts +8 -0
- package/dist/commands/watcher-registry.js +19 -0
- package/dist/commands/watcher-registry.js.map +1 -1
- package/dist/hook.js +54 -83
- package/dist/hook.js.map +1 -1
- package/dist/index.js +220 -1
- package/dist/index.js.map +1 -1
- package/dist/opencode-plugin-helpers.d.ts +200 -0
- package/dist/opencode-plugin-helpers.js +512 -0
- package/dist/opencode-plugin-helpers.js.map +1 -0
- package/dist/opencode-plugin.d.ts +37 -134
- package/dist/opencode-plugin.js +648 -364
- package/dist/opencode-plugin.js.map +1 -1
- package/dist/session-id.d.ts +8 -6
- package/dist/session-id.js +10 -9
- package/dist/session-id.js.map +1 -1
- package/package.json +8 -4
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** GrepRAG opencode plugin — test-friendly helpers.
|
|
3
|
+
*
|
|
4
|
+
* Pure functions and type definitions extracted from `opencode-plugin.ts` so
|
|
5
|
+
* the deployed plugin file can use a single `export = { id, server }` shape
|
|
6
|
+
* (no `__esModule: true` wrapper, no `__test` helper export). The opencode
|
|
7
|
+
* legacy plugin loader iterates `Object.values(mod)` and rejects any value
|
|
8
|
+
* that isn't a function or `{ server: function }`; an `__esModule: true`
|
|
9
|
+
* boolean in that iteration throws "Plugin export is not a function" and the
|
|
10
|
+
* plugin registers zero hooks. See `adr/opencode-monitor-relay.md` 2026-06-06
|
|
11
|
+
* entries (e) and (f) for the full diagnosis.
|
|
12
|
+
*
|
|
13
|
+
* Three callers, all out-of-band of opencode's loader:
|
|
14
|
+
* - `opencode-plugin.ts` — the deployed plugin source imports these for use
|
|
15
|
+
* inside the V1 server function (recap renderer + anchor + lockfile).
|
|
16
|
+
* - `hook.ts` — Claude/Codex SessionStart hook imports the recap renderer
|
|
17
|
+
* so the recap body pushed to the system prompt is identical between
|
|
18
|
+
* harnesses. The hook keeps its own preamble (setup warning, checkpoint
|
|
19
|
+
* hint) — those are session-start UX concerns, not recap content.
|
|
20
|
+
* - `tests/test-opencode-plugin.cjs` and `tests/test-opencode-relay-spawn.cjs`
|
|
21
|
+
* — unit tests pull the same helpers by `require()` to exercise envelope
|
|
22
|
+
* construction, anchor resolution, and lockfile dedup without booting
|
|
23
|
+
* opencode.
|
|
24
|
+
*
|
|
25
|
+
* opencode never loads this file directly. Its presence at
|
|
26
|
+
* `~/.config/opencode/plugins/greprag-memory-helpers.js` is incidental to the
|
|
27
|
+
* deploy step; only `greprag-memory.js` is registered in the user's
|
|
28
|
+
* `opencode.json` plugin list.
|
|
29
|
+
*/
|
|
30
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
31
|
+
if (k2 === undefined) k2 = k;
|
|
32
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
33
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
34
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
35
|
+
}
|
|
36
|
+
Object.defineProperty(o, k2, desc);
|
|
37
|
+
}) : (function(o, m, k, k2) {
|
|
38
|
+
if (k2 === undefined) k2 = k;
|
|
39
|
+
o[k2] = m[k];
|
|
40
|
+
}));
|
|
41
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
42
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
43
|
+
}) : function(o, v) {
|
|
44
|
+
o["default"] = v;
|
|
45
|
+
});
|
|
46
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
47
|
+
var ownKeys = function(o) {
|
|
48
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
49
|
+
var ar = [];
|
|
50
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
51
|
+
return ar;
|
|
52
|
+
};
|
|
53
|
+
return ownKeys(o);
|
|
54
|
+
};
|
|
55
|
+
return function (mod) {
|
|
56
|
+
if (mod && mod.__esModule) return mod;
|
|
57
|
+
var result = {};
|
|
58
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
59
|
+
__setModuleDefault(result, mod);
|
|
60
|
+
return result;
|
|
61
|
+
};
|
|
62
|
+
})();
|
|
63
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
64
|
+
exports.HOURLY_CAP = exports.HOME = void 0;
|
|
65
|
+
exports.isPidAlive = isPidAlive;
|
|
66
|
+
exports.formatUuid = formatUuid;
|
|
67
|
+
exports.computeGitDerivedProjectId = computeGitDerivedProjectId;
|
|
68
|
+
exports.deterministicProjectId = deterministicProjectId;
|
|
69
|
+
exports.isEphemeralCwd = isEphemeralCwd;
|
|
70
|
+
exports.readAnchorFile = readAnchorFile;
|
|
71
|
+
exports.findExistingAnchorFile = findExistingAnchorFile;
|
|
72
|
+
exports.readAnchor = readAnchor;
|
|
73
|
+
exports.extractText = extractText;
|
|
74
|
+
exports.extractToolCalls = extractToolCalls;
|
|
75
|
+
exports.extractFilesTouched = extractFilesTouched;
|
|
76
|
+
exports.classifyUserText = classifyUserText;
|
|
77
|
+
exports.provenanceElisionMarker = provenanceElisionMarker;
|
|
78
|
+
exports.buildEnvelope = buildEnvelope;
|
|
79
|
+
exports.relayLockPath = relayLockPath;
|
|
80
|
+
exports.tryClaimRelayLock = tryClaimRelayLock;
|
|
81
|
+
exports.stripRecapNoise = stripRecapNoise;
|
|
82
|
+
exports.fmtHoursAgo = fmtHoursAgo;
|
|
83
|
+
exports.buildRecapBody = buildRecapBody;
|
|
84
|
+
const crypto = __importStar(require("crypto"));
|
|
85
|
+
const fs = __importStar(require("fs"));
|
|
86
|
+
const path = __importStar(require("path"));
|
|
87
|
+
const child_process_1 = require("child_process");
|
|
88
|
+
const HOME = process.env.HOME || process.env.USERPROFILE || '';
|
|
89
|
+
exports.HOME = HOME;
|
|
90
|
+
function readAnchorFile(filePath) {
|
|
91
|
+
try {
|
|
92
|
+
const raw = JSON.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
93
|
+
if (!raw || typeof raw !== 'object')
|
|
94
|
+
return null;
|
|
95
|
+
const notify = raw.inbox_notify;
|
|
96
|
+
const inboxNotify = notify === 'off' || notify === 'session_start_only' ? notify : 'every_turn';
|
|
97
|
+
return {
|
|
98
|
+
projectId: typeof raw.project_id === 'string' ? raw.project_id : undefined,
|
|
99
|
+
projectName: typeof raw.project_name === 'string' ? raw.project_name : undefined,
|
|
100
|
+
memoryCapture: raw.memory_capture !== false,
|
|
101
|
+
sessionStartRecap: raw.session_start_recap !== false,
|
|
102
|
+
inboxNotify,
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
catch {
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
/** Walk up from cwd looking for an anchor file. Checks canonical `.greprag/`
|
|
110
|
+
* first, then legacy `.claude/` and `.opencode/` at each level. Returns the
|
|
111
|
+
* first hit. Skips home-level globals; those are reserved for the
|
|
112
|
+
* ephemeral-cwd path of the cascade. */
|
|
113
|
+
function findExistingAnchorFile(startDir) {
|
|
114
|
+
const globalAnchorPath = path.join(HOME, '.greprag', 'project.json');
|
|
115
|
+
const legacyGlobalAnchorPath = path.join(HOME, '.claude', 'project.json');
|
|
116
|
+
let dir = path.resolve(startDir);
|
|
117
|
+
while (true) {
|
|
118
|
+
for (const subdir of ['.greprag', '.claude', '.opencode']) {
|
|
119
|
+
const candidate = path.join(dir, subdir, 'project.json');
|
|
120
|
+
if (candidate !== globalAnchorPath && candidate !== legacyGlobalAnchorPath && fs.existsSync(candidate)) {
|
|
121
|
+
return candidate;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const parent = path.dirname(dir);
|
|
125
|
+
if (parent === dir)
|
|
126
|
+
return null;
|
|
127
|
+
dir = parent;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
/** Format the SHA-256 of an input string into a deterministic UUID v4-shape
|
|
131
|
+
* string. Must match the algorithm in packages/cli/src/project-anchor.ts so
|
|
132
|
+
* the plugin resolves identical IDs to the Claude Code CLI. */
|
|
133
|
+
function formatUuid(hashHex) {
|
|
134
|
+
return [
|
|
135
|
+
hashHex.slice(0, 8),
|
|
136
|
+
hashHex.slice(8, 12),
|
|
137
|
+
'4' + hashHex.slice(13, 16),
|
|
138
|
+
'8' + hashHex.slice(17, 20),
|
|
139
|
+
hashHex.slice(20, 32),
|
|
140
|
+
].join('-');
|
|
141
|
+
}
|
|
142
|
+
/** Derive a stable project_id from the repo's root commit SHA. Sorted +
|
|
143
|
+
* hashed so disjoint-history merges produce one deterministic id everywhere.
|
|
144
|
+
* Returns null when cwd isn't a git repo or has no commits yet. */
|
|
145
|
+
function computeGitDerivedProjectId(cwd) {
|
|
146
|
+
try {
|
|
147
|
+
const out = (0, child_process_1.execSync)('git rev-list --max-parents=0 HEAD', {
|
|
148
|
+
cwd,
|
|
149
|
+
encoding: 'utf-8',
|
|
150
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
151
|
+
});
|
|
152
|
+
const roots = out.trim().split(/\s+/).filter(Boolean).sort();
|
|
153
|
+
if (roots.length === 0)
|
|
154
|
+
return null;
|
|
155
|
+
const hash = crypto.createHash('sha256').update(roots.join('\n')).digest('hex');
|
|
156
|
+
return formatUuid(hash);
|
|
157
|
+
}
|
|
158
|
+
catch {
|
|
159
|
+
return null;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
/** Hash the cwd path into a stable UUID. Last-resort fallback — when no git
|
|
163
|
+
* history and no anchor file exist, this keeps capture flowing under a
|
|
164
|
+
* per-path identity that `greprag doctor` can later consolidate. */
|
|
165
|
+
function deterministicProjectId(cwd) {
|
|
166
|
+
const normalized = path.resolve(cwd).toLowerCase();
|
|
167
|
+
const hash = crypto.createHash('sha256').update(normalized).digest('hex');
|
|
168
|
+
return formatUuid(hash);
|
|
169
|
+
}
|
|
170
|
+
/** True when cwd is an ephemeral session path (Cowork, tmp dirs). The
|
|
171
|
+
* deterministic-hash fallback would mint a fresh id every session in those
|
|
172
|
+
* paths, so we prefer the global anchor instead. */
|
|
173
|
+
function isEphemeralCwd(cwd) {
|
|
174
|
+
const norm = path.resolve(cwd).replace(/\\/g, '/').toLowerCase();
|
|
175
|
+
if (norm.includes('/appdata/roaming/claude/local-agent-mode-sessions/'))
|
|
176
|
+
return true;
|
|
177
|
+
if (norm.includes('/appdata/local/claude/local-agent-mode-sessions/'))
|
|
178
|
+
return true;
|
|
179
|
+
if (norm.startsWith('/tmp/'))
|
|
180
|
+
return true;
|
|
181
|
+
if (norm.startsWith('/var/tmp/'))
|
|
182
|
+
return true;
|
|
183
|
+
if (norm.startsWith('/private/tmp/'))
|
|
184
|
+
return true;
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
/** Resolve the project anchor for `worktree` using the same 4-level cascade
|
|
188
|
+
* the Claude Code CLI uses (packages/cli/src/project-anchor.ts). Settings
|
|
189
|
+
* always come from the nearest repo-level file when one exists, regardless
|
|
190
|
+
* of which identity level resolved.
|
|
191
|
+
*
|
|
192
|
+
* 1. Anchor file with explicit `project_id` → file-based identity
|
|
193
|
+
* 2. Git repo with at least one commit → root-commit-derived UUID
|
|
194
|
+
* 3. Ephemeral cwd + ~/.greprag/project.json exists → global anchor
|
|
195
|
+
* 4. Path-hash fallback (never returns null; lets capture flow until
|
|
196
|
+
* `greprag init` runs and `greprag doctor` consolidates) */
|
|
197
|
+
function readAnchor(worktree) {
|
|
198
|
+
const filePath = findExistingAnchorFile(worktree);
|
|
199
|
+
const file = filePath ? readAnchorFile(filePath) : null;
|
|
200
|
+
const root = path.resolve(worktree);
|
|
201
|
+
// 1. File with explicit project_id
|
|
202
|
+
if (file && file.projectId && file.projectName) {
|
|
203
|
+
return {
|
|
204
|
+
projectId: file.projectId,
|
|
205
|
+
projectName: file.projectName,
|
|
206
|
+
memoryCapture: file.memoryCapture,
|
|
207
|
+
sessionStartRecap: file.sessionStartRecap,
|
|
208
|
+
inboxNotify: file.inboxNotify,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
// 2. Git-derived identity. Settings layer in from the settings-only file
|
|
212
|
+
// when one exists; otherwise defaults apply.
|
|
213
|
+
const gitId = computeGitDerivedProjectId(worktree);
|
|
214
|
+
if (gitId) {
|
|
215
|
+
return {
|
|
216
|
+
projectId: gitId,
|
|
217
|
+
projectName: file?.projectName || path.basename(root).toLowerCase(),
|
|
218
|
+
memoryCapture: file?.memoryCapture ?? true,
|
|
219
|
+
sessionStartRecap: file?.sessionStartRecap ?? true,
|
|
220
|
+
inboxNotify: file?.inboxNotify ?? 'every_turn',
|
|
221
|
+
};
|
|
222
|
+
}
|
|
223
|
+
// 3. Ephemeral cwd + global anchor
|
|
224
|
+
if (isEphemeralCwd(worktree)) {
|
|
225
|
+
const canonicalGlobal = path.join(HOME, '.greprag', 'project.json');
|
|
226
|
+
const legacyGlobal = path.join(HOME, '.claude', 'project.json');
|
|
227
|
+
const globalPath = fs.existsSync(canonicalGlobal) ? canonicalGlobal : legacyGlobal;
|
|
228
|
+
const globalFile = fs.existsSync(globalPath) ? readAnchorFile(globalPath) : null;
|
|
229
|
+
if (globalFile && globalFile.projectId && globalFile.projectName) {
|
|
230
|
+
return {
|
|
231
|
+
projectId: globalFile.projectId,
|
|
232
|
+
projectName: globalFile.projectName,
|
|
233
|
+
memoryCapture: globalFile.memoryCapture,
|
|
234
|
+
sessionStartRecap: globalFile.sessionStartRecap,
|
|
235
|
+
inboxNotify: globalFile.inboxNotify,
|
|
236
|
+
};
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// 4. Path-hash fallback — keep capture flowing for uninitialized repos.
|
|
240
|
+
return {
|
|
241
|
+
projectId: deterministicProjectId(worktree),
|
|
242
|
+
projectName: file?.projectName || path.basename(root).toLowerCase(),
|
|
243
|
+
memoryCapture: file?.memoryCapture ?? true,
|
|
244
|
+
sessionStartRecap: file?.sessionStartRecap ?? true,
|
|
245
|
+
inboxNotify: file?.inboxNotify ?? 'every_turn',
|
|
246
|
+
};
|
|
247
|
+
}
|
|
248
|
+
// ============================================================================
|
|
249
|
+
// Envelope construction (real opencode Part schema)
|
|
250
|
+
// ============================================================================
|
|
251
|
+
function extractText(parts) {
|
|
252
|
+
const out = [];
|
|
253
|
+
for (const p of parts) {
|
|
254
|
+
if (p.type !== 'text')
|
|
255
|
+
continue;
|
|
256
|
+
const tp = p;
|
|
257
|
+
if (tp.synthetic || tp.ignored)
|
|
258
|
+
continue;
|
|
259
|
+
if (tp.text)
|
|
260
|
+
out.push(tp.text);
|
|
261
|
+
}
|
|
262
|
+
return out.join('\n').trim();
|
|
263
|
+
}
|
|
264
|
+
/** Pull a one-line summary out of each tool call: name + a target string + an
|
|
265
|
+
* optional brief for shell commands. Mirrors the shape the Claude Code hook
|
|
266
|
+
* posts so server-side compaction sees identical structure regardless of
|
|
267
|
+
* client origin. */
|
|
268
|
+
function extractToolCalls(parts) {
|
|
269
|
+
const calls = [];
|
|
270
|
+
for (const p of parts) {
|
|
271
|
+
if (p.type !== 'tool')
|
|
272
|
+
continue;
|
|
273
|
+
const tp = p;
|
|
274
|
+
const name = tp.tool || 'unknown';
|
|
275
|
+
const input = (tp.state && tp.state.input) || {};
|
|
276
|
+
const call = { name };
|
|
277
|
+
if (input.command !== undefined) {
|
|
278
|
+
const desc = input.description;
|
|
279
|
+
call.target =
|
|
280
|
+
typeof desc === 'string' && desc
|
|
281
|
+
? desc
|
|
282
|
+
: String(input.command).split(/\s+/)[0] || '';
|
|
283
|
+
const cmd = String(input.command);
|
|
284
|
+
call.brief = cmd.length > 800 ? cmd.slice(0, 800) + '…' : cmd;
|
|
285
|
+
}
|
|
286
|
+
else if (typeof input.file_path === 'string') {
|
|
287
|
+
call.target = input.file_path;
|
|
288
|
+
}
|
|
289
|
+
else if (typeof input.filePath === 'string') {
|
|
290
|
+
call.target = input.filePath;
|
|
291
|
+
}
|
|
292
|
+
else if (typeof input.pattern === 'string') {
|
|
293
|
+
call.target = input.pattern;
|
|
294
|
+
}
|
|
295
|
+
else if (typeof input.url === 'string') {
|
|
296
|
+
call.target = input.url;
|
|
297
|
+
}
|
|
298
|
+
else if (typeof input.query === 'string') {
|
|
299
|
+
call.target = input.query;
|
|
300
|
+
}
|
|
301
|
+
calls.push(call);
|
|
302
|
+
}
|
|
303
|
+
return calls;
|
|
304
|
+
}
|
|
305
|
+
function extractFilesTouched(parts) {
|
|
306
|
+
const files = new Set();
|
|
307
|
+
for (const p of parts) {
|
|
308
|
+
if (p.type !== 'tool')
|
|
309
|
+
continue;
|
|
310
|
+
const tp = p;
|
|
311
|
+
const input = (tp.state && tp.state.input) || {};
|
|
312
|
+
if (typeof input.file_path === 'string')
|
|
313
|
+
files.add(input.file_path);
|
|
314
|
+
if (typeof input.filePath === 'string')
|
|
315
|
+
files.add(input.filePath);
|
|
316
|
+
}
|
|
317
|
+
return Array.from(files).sort();
|
|
318
|
+
}
|
|
319
|
+
function classifyUserText(text) {
|
|
320
|
+
const t = (text || '').trimStart();
|
|
321
|
+
if (!t)
|
|
322
|
+
return 'session-turn';
|
|
323
|
+
if (/^Base directory for this skill:/.test(t))
|
|
324
|
+
return 'skill-injection';
|
|
325
|
+
if (/^This session is being continued from a previous conversation/.test(t)) {
|
|
326
|
+
return 'continuation-summary';
|
|
327
|
+
}
|
|
328
|
+
if (/^You are a .{0,60}\bchip\b/.test(t) ||
|
|
329
|
+
(/\bgit worktree add\b/.test(t) &&
|
|
330
|
+
/(^|\n)\s*(\*\*Setup\b|Chip:|#\s*Chip\b|report back\b)/m.test(t))) {
|
|
331
|
+
return 'chip-prompt';
|
|
332
|
+
}
|
|
333
|
+
return 'session-turn';
|
|
334
|
+
}
|
|
335
|
+
function provenanceElisionMarker(p, text) {
|
|
336
|
+
const label = p === 'skill-injection' ? 'skill body' :
|
|
337
|
+
p === 'continuation-summary' ? 'context-continuation summary' :
|
|
338
|
+
p === 'chip-prompt' ? 'chip task prompt' : 'injected text';
|
|
339
|
+
let hint = '';
|
|
340
|
+
if (p === 'skill-injection') {
|
|
341
|
+
const m = (text || '').match(/skills[/\\]([A-Za-z0-9._-]+)/) ||
|
|
342
|
+
(text || '').match(/^#\s+(.+)$/m);
|
|
343
|
+
if (m)
|
|
344
|
+
hint = ` (${m[1].trim().slice(0, 40)})`;
|
|
345
|
+
}
|
|
346
|
+
return `[greprag: harness-injected ${label}${hint} elided from episodic capture]`;
|
|
347
|
+
}
|
|
348
|
+
function buildEnvelope(userParts, assistantParts, errored) {
|
|
349
|
+
// Elide harness-injected user text pre-LLM at capture (see the classifier
|
|
350
|
+
// above). The marker replaces the 1-6k-word block so it never reaches the
|
|
351
|
+
// server / content_tsv.
|
|
352
|
+
const rawUser = extractText(userParts);
|
|
353
|
+
const provenance = classifyUserText(rawUser);
|
|
354
|
+
const userPrompt = provenance === 'session-turn'
|
|
355
|
+
? rawUser
|
|
356
|
+
: provenanceElisionMarker(provenance, rawUser);
|
|
357
|
+
return {
|
|
358
|
+
userPrompt,
|
|
359
|
+
agentResponse: extractText(assistantParts),
|
|
360
|
+
toolCalls: extractToolCalls(assistantParts),
|
|
361
|
+
filesTouched: extractFilesTouched(assistantParts),
|
|
362
|
+
status: errored ? 'errored' : 'completed',
|
|
363
|
+
provenance,
|
|
364
|
+
};
|
|
365
|
+
}
|
|
366
|
+
// ============================================================================
|
|
367
|
+
// Process liveness + relay lockfile
|
|
368
|
+
// ============================================================================
|
|
369
|
+
/** True when the OS reports `pid` as a running process. Used to decide whether
|
|
370
|
+
* a stale-lockfile check should trust the recorded PID or treat the file as
|
|
371
|
+
* abandoned. */
|
|
372
|
+
function isPidAlive(pid) {
|
|
373
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
374
|
+
return false;
|
|
375
|
+
try {
|
|
376
|
+
process.kill(pid, 0);
|
|
377
|
+
return true;
|
|
378
|
+
}
|
|
379
|
+
catch {
|
|
380
|
+
return false;
|
|
381
|
+
}
|
|
382
|
+
}
|
|
383
|
+
const RELAY_LOCK_PREFIX = 'relay.';
|
|
384
|
+
const RELAY_STALE_MS = 30_000;
|
|
385
|
+
function relayLockPath(sessionId) {
|
|
386
|
+
const eight = sessionId.replace(/[^0-9a-f]/gi, '').slice(0, 8) || 'unknown';
|
|
387
|
+
return path.join(HOME, '.greprag', `${RELAY_LOCK_PREFIX}${eight}.pid`);
|
|
388
|
+
}
|
|
389
|
+
function tryClaimRelayLock(lockPath) {
|
|
390
|
+
try {
|
|
391
|
+
const fd = fs.openSync(lockPath, 'wx');
|
|
392
|
+
return { ok: true, fd };
|
|
393
|
+
}
|
|
394
|
+
catch (err) {
|
|
395
|
+
if (err.code !== 'EEXIST') {
|
|
396
|
+
return { ok: false, reason: 'lock-create-failed' };
|
|
397
|
+
}
|
|
398
|
+
try {
|
|
399
|
+
const stat = fs.statSync(lockPath);
|
|
400
|
+
const ageMs = Date.now() - stat.mtimeMs;
|
|
401
|
+
let pidAlive = false;
|
|
402
|
+
try {
|
|
403
|
+
const pid = parseInt(fs.readFileSync(lockPath, 'utf-8').trim(), 10);
|
|
404
|
+
pidAlive = pid > 0 && isPidAlive(pid);
|
|
405
|
+
}
|
|
406
|
+
catch { /* unreadable — treat as stale */ }
|
|
407
|
+
if (ageMs < RELAY_STALE_MS && pidAlive) {
|
|
408
|
+
return { ok: false, reason: 'busy' };
|
|
409
|
+
}
|
|
410
|
+
try {
|
|
411
|
+
fs.unlinkSync(lockPath);
|
|
412
|
+
}
|
|
413
|
+
catch { /* raced */ }
|
|
414
|
+
const fd = fs.openSync(lockPath, 'wx');
|
|
415
|
+
return { ok: true, fd };
|
|
416
|
+
}
|
|
417
|
+
catch (err2) {
|
|
418
|
+
return { ok: false, reason: 'lock-stale-replace-failed' };
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
}
|
|
422
|
+
/** Cap on the number of hourlies surfaced in the recap body. 3 — the hook's
|
|
423
|
+
* established value; if the user wants more they pull on demand via
|
|
424
|
+
* `greprag memory recap`. adr: adr/memory-recap-pyramid.md. */
|
|
425
|
+
const HOURLY_CAP = 3;
|
|
426
|
+
exports.HOURLY_CAP = HOURLY_CAP;
|
|
427
|
+
/** Strip noise blocks from compacted content before injection.
|
|
428
|
+
* Compactor contract: numbered items end with a trailer ("Open: ..." for
|
|
429
|
+
* hourly, "Shipped: ..." for daily) which may span multiple lines. Trailers
|
|
430
|
+
* always come AFTER the numbered list — so we drop from the trigger line
|
|
431
|
+
* through end-of-string.
|
|
432
|
+
*
|
|
433
|
+
* - daily: drop the deterministic "Shipped: <UUID-list>" trailer (useful for
|
|
434
|
+
* /greprag deep-dive, but a wall of IDs at session start)
|
|
435
|
+
* - hourly: drop the per-hour "Open:" block (stale snapshot of open items
|
|
436
|
+
* that were resolved or superseded in later hours) */
|
|
437
|
+
function stripRecapNoise(content, type) {
|
|
438
|
+
const target = type === 'daily' ? 'Shipped:' : 'Open:';
|
|
439
|
+
const lines = content.split('\n');
|
|
440
|
+
const cutAt = lines.findIndex(line => line.trim().startsWith(target));
|
|
441
|
+
const kept = cutAt === -1 ? lines : lines.slice(0, cutAt);
|
|
442
|
+
while (kept.length > 0 && kept[kept.length - 1].trim() === '')
|
|
443
|
+
kept.pop();
|
|
444
|
+
return kept.join('\n');
|
|
445
|
+
}
|
|
446
|
+
/** Render an hourly window's recency: "5 hours ago", "1 hour ago",
|
|
447
|
+
* "30 min ago", "just now". Reference is the end of the window — when the
|
|
448
|
+
* hour wrapped up. */
|
|
449
|
+
function fmtHoursAgo(windowEndIso, now) {
|
|
450
|
+
const diffMs = now.getTime() - new Date(windowEndIso).getTime();
|
|
451
|
+
const diffMin = Math.floor(diffMs / 60_000);
|
|
452
|
+
if (diffMin < 1)
|
|
453
|
+
return 'just now';
|
|
454
|
+
if (diffMin < 60)
|
|
455
|
+
return `${diffMin} min ago`;
|
|
456
|
+
const diffHrs = Math.round(diffMs / 3_600_000);
|
|
457
|
+
return diffHrs === 1 ? '1 hour ago' : `${diffHrs} hours ago`;
|
|
458
|
+
}
|
|
459
|
+
/** Build the recap body — hourlies-only render. Recap is hourlies-only by
|
|
460
|
+
* design: daily summaries used to render here (one prose paragraph per
|
|
461
|
+
* daily window) but added ~1500 tokens to every SessionStart for marginal
|
|
462
|
+
* value. Dailies still exist in the DB; agents who want historic context
|
|
463
|
+
* pull on demand via `greprag memory recap` (or
|
|
464
|
+
* `greprag memory search "<query>"` for a specific topic). Pull, don't push.
|
|
465
|
+
*
|
|
466
|
+
* Window: 2 days back to now (50-row pull), filtered to last 24h, sliced
|
|
467
|
+
* to HOURLY_CAP most-recent.
|
|
468
|
+
*
|
|
469
|
+
* Returns "" when there are no recent hourlies — caller treats that as
|
|
470
|
+
* "no recap block". Empty body is not an error; the query itself is the
|
|
471
|
+
* only network call and any failure is swallowed (returns ""). */
|
|
472
|
+
async function buildRecapBody(apiUrl, apiKey, anchor, now = new Date()) {
|
|
473
|
+
if (!anchor.projectId)
|
|
474
|
+
return '';
|
|
475
|
+
const hourlyFromIso = new Date(now.getTime() - 2 * 86_400_000).toISOString();
|
|
476
|
+
const toIso = now.toISOString();
|
|
477
|
+
const hourlyCutoffMs = now.getTime() - 24 * 3_600_000;
|
|
478
|
+
const url = `${apiUrl}/v1/memory/by-period`
|
|
479
|
+
+ `?projectId=${encodeURIComponent(anchor.projectId)}`
|
|
480
|
+
+ `&from=${encodeURIComponent(hourlyFromIso)}`
|
|
481
|
+
+ `&to=${encodeURIComponent(toIso)}`
|
|
482
|
+
+ `&type=hourly&limit=50`;
|
|
483
|
+
let hourlies = [];
|
|
484
|
+
try {
|
|
485
|
+
const res = await fetch(url, { headers: { 'Authorization': `Bearer ${apiKey}` } });
|
|
486
|
+
if (res.ok) {
|
|
487
|
+
const data = await res.json();
|
|
488
|
+
hourlies = data.memories || [];
|
|
489
|
+
}
|
|
490
|
+
}
|
|
491
|
+
catch {
|
|
492
|
+
// Network error / parse error — treat as no data, never block the hook.
|
|
493
|
+
}
|
|
494
|
+
const recent = hourlies
|
|
495
|
+
.filter(h => h.windowEnd && new Date(h.windowEnd).getTime() >= hourlyCutoffMs)
|
|
496
|
+
.slice(-HOURLY_CAP);
|
|
497
|
+
if (recent.length === 0)
|
|
498
|
+
return '';
|
|
499
|
+
const parts = [];
|
|
500
|
+
parts.push(`[GrepRAG memory: ${anchor.projectName}]`);
|
|
501
|
+
parts.push('');
|
|
502
|
+
parts.push('Recent sessions:');
|
|
503
|
+
for (const h of recent) {
|
|
504
|
+
if (!h.windowEnd)
|
|
505
|
+
continue;
|
|
506
|
+
parts.push('');
|
|
507
|
+
parts.push(`${fmtHoursAgo(h.windowEnd, now)}:`);
|
|
508
|
+
parts.push(stripRecapNoise(h.content.trim(), 'hourly'));
|
|
509
|
+
}
|
|
510
|
+
return parts.join('\n');
|
|
511
|
+
}
|
|
512
|
+
//# sourceMappingURL=opencode-plugin-helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"opencode-plugin-helpers.js","sourceRoot":"","sources":["../src/opencode-plugin-helpers.ts"],"names":[],"mappings":"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"}
|