greprag 5.32.0 → 5.34.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 +230 -0
- package/dist/commands/desk-line.js.map +1 -0
- 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
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
12
|
exports.refreshCmd = refreshCmd;
|
|
13
13
|
exports.sourcesCmd = sourcesCmd;
|
|
14
|
+
exports.auditCmd = auditCmd;
|
|
14
15
|
const client_1 = require("./client");
|
|
15
16
|
async function refreshCmd(args) {
|
|
16
17
|
const cfg = (0, client_1.getConfig)();
|
|
@@ -89,6 +90,65 @@ async function sourcesCmd(args) {
|
|
|
89
90
|
console.log(`Manual policy — re-check on demand: greprag corpus refresh ${JSON.stringify(store.name)}\n`);
|
|
90
91
|
}
|
|
91
92
|
}
|
|
93
|
+
async function auditCmd(args) {
|
|
94
|
+
const cfg = (0, client_1.getConfig)();
|
|
95
|
+
if (!cfg.apiKey)
|
|
96
|
+
(0, client_1.abortNotConfigured)();
|
|
97
|
+
const ref = args[0];
|
|
98
|
+
if (!ref) {
|
|
99
|
+
console.error('Usage: greprag corpus audit <storeIdOrName> [--limit N]\n Show immutable evidence from recent source refreshes.');
|
|
100
|
+
process.exit(1);
|
|
101
|
+
}
|
|
102
|
+
const store = await (0, client_1.resolveStore)(ref, cfg.apiUrl, cfg.apiKey);
|
|
103
|
+
const limit = numFlag(args, '--limit', 3);
|
|
104
|
+
const res = await (0, client_1.apiGet)(`${cfg.apiUrl}/v1/stores/${store.id}/refresh/audits?limit=${limit}`, cfg.apiKey);
|
|
105
|
+
if (!res.ok)
|
|
106
|
+
throw new Error(res.error || 'audit failed');
|
|
107
|
+
console.log(`\n${store.name} · refresh audits`);
|
|
108
|
+
const audits = res.audits || [];
|
|
109
|
+
if (audits.length === 0) {
|
|
110
|
+
console.log(' No refresh audits recorded yet. Run a refresh after deploying migration 055.');
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
for (const a of audits) {
|
|
114
|
+
const fresh = a.details?.freshNodes || [];
|
|
115
|
+
const removed = a.details?.removedNodes || [];
|
|
116
|
+
console.log(`\n ${a.createdAt} · ${a.status}`);
|
|
117
|
+
if (a.changeSignal)
|
|
118
|
+
console.log(` Signal: ${a.changeSignal}`);
|
|
119
|
+
console.log(` Nodes: ${a.oldNodeCount} → ${a.newNodeCount} (${a.preservedCount} preserved, ${a.freshCount} fresh, ${a.removedCount} removed)`);
|
|
120
|
+
console.log(` Hashes: old ${shortHash(a.oldContentHash)} → new ${shortHash(a.newContentHash)}`);
|
|
121
|
+
if (a.sourceContentHash)
|
|
122
|
+
console.log(` Source: ${shortHash(a.sourceContentHash)}`);
|
|
123
|
+
console.log(` Enrich: ${a.enriched ? `${a.enrichmentQueued} queued` : 'raw corpus; skipped'}`);
|
|
124
|
+
if (a.reason)
|
|
125
|
+
console.log(` Reason: ${a.reason}`);
|
|
126
|
+
renderNodes('Fresh', fresh);
|
|
127
|
+
renderNodes('Removed', removed);
|
|
128
|
+
}
|
|
129
|
+
console.log('');
|
|
130
|
+
}
|
|
131
|
+
function numFlag(args, flag, fallback) {
|
|
132
|
+
const idx = args.indexOf(flag);
|
|
133
|
+
if (idx < 0 || idx + 1 >= args.length)
|
|
134
|
+
return fallback;
|
|
135
|
+
const n = Number(args[idx + 1]);
|
|
136
|
+
return Number.isFinite(n) && n > 0 ? Math.floor(n) : fallback;
|
|
137
|
+
}
|
|
138
|
+
function shortHash(h) {
|
|
139
|
+
return h ? h.slice(0, 12) : '(none)';
|
|
140
|
+
}
|
|
141
|
+
function renderNodes(label, nodes) {
|
|
142
|
+
if (nodes.length === 0)
|
|
143
|
+
return;
|
|
144
|
+
const shown = nodes.slice(0, 5);
|
|
145
|
+
console.log(` ${label}:`);
|
|
146
|
+
for (const n of shown) {
|
|
147
|
+
console.log(` ${n.nodeId} pos=${n.position} ${n.blockType} ${shortHash(n.contentHash)} ${JSON.stringify(n.preview)}`);
|
|
148
|
+
}
|
|
149
|
+
if (nodes.length > shown.length)
|
|
150
|
+
console.log(` … ${nodes.length - shown.length} more`);
|
|
151
|
+
}
|
|
92
152
|
/** Render an ISO timestamp as "ISO (Nh ago)"; em-dash when never. Uses only
|
|
93
153
|
* Date math available in the CLI runtime (no extra deps). */
|
|
94
154
|
function fmtTime(iso) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../../src/commands/corpus/refresh.ts"],"names":[],"mappings":";AAAA;;;;;;;;gFAQgF;;
|
|
1
|
+
{"version":3,"file":"refresh.js","sourceRoot":"","sources":["../../../src/commands/corpus/refresh.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
/** greprag desk — the machine's desk-line.
|
|
2
|
+
*
|
|
3
|
+
* One process per machine that holds a line open to the cloud and answers, from
|
|
4
|
+
* LOCAL ground truth, the only questions the cloud can't answer for itself:
|
|
5
|
+
* "what sessions are truly live?" and (later) "deliver this to session X".
|
|
6
|
+
*
|
|
7
|
+
* Why it exists: the operator's machine is behind NAT — the cloud can't dial it.
|
|
8
|
+
* So the machine dials out and long-polls GET /v1/desk/poll; the cloud parks the
|
|
9
|
+
* request until it has a job, then the desk-line answers and POSTs the result to
|
|
10
|
+
* /v1/desk/reply. The cloud holds NO session registry; a machine that's down
|
|
11
|
+
* simply stops polling, and that silence is the offline signal. This replaces
|
|
12
|
+
* the stale cloud whiteboard (InboxDO /attached) as the source of the
|
|
13
|
+
* live-session list. adr: adr/desk-line-relay.md, docs/registry-freshness-design.md
|
|
14
|
+
*
|
|
15
|
+
* Singleton per machine via a pidfile lock (~/.greprag/desk-line.json) — a second
|
|
16
|
+
* `desk run` exits if a live one already holds the lock.
|
|
17
|
+
*/
|
|
18
|
+
interface DeskLock {
|
|
19
|
+
pid: number;
|
|
20
|
+
startedAt: number;
|
|
21
|
+
}
|
|
22
|
+
/** Is a live desk-line already running on this machine? */
|
|
23
|
+
export declare function deskLineRunning(): DeskLock | null;
|
|
24
|
+
/** The long-poll loop. Runs until the AbortSignal fires (or forever). */
|
|
25
|
+
export declare function runDeskLine(opts?: {
|
|
26
|
+
signal?: AbortSignal;
|
|
27
|
+
once?: boolean;
|
|
28
|
+
}): Promise<void>;
|
|
29
|
+
/** Idempotently ensure a desk-line is running, spawning a detached one if not.
|
|
30
|
+
* Safe to call on every SessionStart — the singleton lock makes extra calls a
|
|
31
|
+
* no-op. Returns true if a desk-line is (now) running. */
|
|
32
|
+
export declare function ensureDeskLine(): boolean;
|
|
33
|
+
/** `greprag desk status` — is a desk-line up, and what's the local truth it would
|
|
34
|
+
* report right now? */
|
|
35
|
+
export declare function deskLineStatus(): void;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** greprag desk — the machine's desk-line.
|
|
3
|
+
*
|
|
4
|
+
* One process per machine that holds a line open to the cloud and answers, from
|
|
5
|
+
* LOCAL ground truth, the only questions the cloud can't answer for itself:
|
|
6
|
+
* "what sessions are truly live?" and (later) "deliver this to session X".
|
|
7
|
+
*
|
|
8
|
+
* Why it exists: the operator's machine is behind NAT — the cloud can't dial it.
|
|
9
|
+
* So the machine dials out and long-polls GET /v1/desk/poll; the cloud parks the
|
|
10
|
+
* request until it has a job, then the desk-line answers and POSTs the result to
|
|
11
|
+
* /v1/desk/reply. The cloud holds NO session registry; a machine that's down
|
|
12
|
+
* simply stops polling, and that silence is the offline signal. This replaces
|
|
13
|
+
* the stale cloud whiteboard (InboxDO /attached) as the source of the
|
|
14
|
+
* live-session list. adr: adr/desk-line-relay.md, docs/registry-freshness-design.md
|
|
15
|
+
*
|
|
16
|
+
* Singleton per machine via a pidfile lock (~/.greprag/desk-line.json) — a second
|
|
17
|
+
* `desk run` exits if a live one already holds the lock.
|
|
18
|
+
*/
|
|
19
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
20
|
+
if (k2 === undefined) k2 = k;
|
|
21
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
22
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
23
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
24
|
+
}
|
|
25
|
+
Object.defineProperty(o, k2, desc);
|
|
26
|
+
}) : (function(o, m, k, k2) {
|
|
27
|
+
if (k2 === undefined) k2 = k;
|
|
28
|
+
o[k2] = m[k];
|
|
29
|
+
}));
|
|
30
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
31
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
32
|
+
}) : function(o, v) {
|
|
33
|
+
o["default"] = v;
|
|
34
|
+
});
|
|
35
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
36
|
+
var ownKeys = function(o) {
|
|
37
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
38
|
+
var ar = [];
|
|
39
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
40
|
+
return ar;
|
|
41
|
+
};
|
|
42
|
+
return ownKeys(o);
|
|
43
|
+
};
|
|
44
|
+
return function (mod) {
|
|
45
|
+
if (mod && mod.__esModule) return mod;
|
|
46
|
+
var result = {};
|
|
47
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
48
|
+
__setModuleDefault(result, mod);
|
|
49
|
+
return result;
|
|
50
|
+
};
|
|
51
|
+
})();
|
|
52
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
53
|
+
exports.deskLineRunning = deskLineRunning;
|
|
54
|
+
exports.runDeskLine = runDeskLine;
|
|
55
|
+
exports.ensureDeskLine = ensureDeskLine;
|
|
56
|
+
exports.deskLineStatus = deskLineStatus;
|
|
57
|
+
const fs = __importStar(require("fs"));
|
|
58
|
+
const path = __importStar(require("path"));
|
|
59
|
+
const child_process_1 = require("child_process");
|
|
60
|
+
const watcher_registry_1 = require("./watcher-registry");
|
|
61
|
+
const API_URL_DEFAULT = 'https://api.greprag.com';
|
|
62
|
+
const LOG = '[greprag desk]';
|
|
63
|
+
const BACKOFF_INITIAL_MS = 1_000;
|
|
64
|
+
const BACKOFF_MAX_MS = 30_000;
|
|
65
|
+
function grepragHome() {
|
|
66
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
67
|
+
return path.join(home, '.greprag');
|
|
68
|
+
}
|
|
69
|
+
function lockPath() { return path.join(grepragHome(), 'desk-line.json'); }
|
|
70
|
+
function pidAlive(pid) {
|
|
71
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
72
|
+
return false;
|
|
73
|
+
try {
|
|
74
|
+
process.kill(pid, 0);
|
|
75
|
+
return true;
|
|
76
|
+
}
|
|
77
|
+
catch (e) {
|
|
78
|
+
return e?.code === 'EPERM';
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
/** Is a live desk-line already running on this machine? */
|
|
82
|
+
function deskLineRunning() {
|
|
83
|
+
try {
|
|
84
|
+
const rec = JSON.parse(fs.readFileSync(lockPath(), 'utf-8'));
|
|
85
|
+
if (rec && typeof rec.pid === 'number' && pidAlive(rec.pid))
|
|
86
|
+
return rec;
|
|
87
|
+
fs.rmSync(lockPath(), { force: true }); // stale lock → sweep
|
|
88
|
+
}
|
|
89
|
+
catch { /* no lock */ }
|
|
90
|
+
return null;
|
|
91
|
+
}
|
|
92
|
+
function writeLock() {
|
|
93
|
+
try {
|
|
94
|
+
fs.mkdirSync(grepragHome(), { recursive: true });
|
|
95
|
+
fs.writeFileSync(lockPath(), JSON.stringify({ pid: process.pid, startedAt: Date.now() }));
|
|
96
|
+
}
|
|
97
|
+
catch { /* best-effort */ }
|
|
98
|
+
}
|
|
99
|
+
function removeLock() { try {
|
|
100
|
+
fs.rmSync(lockPath(), { force: true });
|
|
101
|
+
}
|
|
102
|
+
catch { /* noop */ } }
|
|
103
|
+
function getConfig() {
|
|
104
|
+
return {
|
|
105
|
+
apiUrl: process.env.GREPRAG_API_URL || API_URL_DEFAULT,
|
|
106
|
+
apiKey: process.env.GREPRAG_API_KEY || '',
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
/** Compute the answer to a job from local ground truth. */
|
|
110
|
+
function answerJob(job) {
|
|
111
|
+
if (job.kind === 'list') {
|
|
112
|
+
const live = (0, watcher_registry_1.listLocalLiveWatchers)();
|
|
113
|
+
return {
|
|
114
|
+
watchers: live.map(w => ({
|
|
115
|
+
session_id: w.short, pid: w.pid, owner_pid: w.ownerPid ?? null, started_at: w.startedAt,
|
|
116
|
+
})),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
// 'deliver' is reserved for the delivery-cutover phase — until then, inbound
|
|
120
|
+
// still flows via the existing cloud broadcast path, so the desk-line declines.
|
|
121
|
+
return { ok: false, reason: 'deliver-not-implemented' };
|
|
122
|
+
}
|
|
123
|
+
/** The long-poll loop. Runs until the AbortSignal fires (or forever). */
|
|
124
|
+
async function runDeskLine(opts = {}) {
|
|
125
|
+
const { apiUrl, apiKey } = getConfig();
|
|
126
|
+
if (!apiKey) {
|
|
127
|
+
console.error(`${LOG} not configured (GREPRAG_API_KEY unset). Run: greprag init`);
|
|
128
|
+
process.exitCode = 64;
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const existing = deskLineRunning();
|
|
132
|
+
if (existing && existing.pid !== process.pid) {
|
|
133
|
+
console.error(`${LOG} already running (pid ${existing.pid}) — exiting (singleton).`);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
writeLock();
|
|
137
|
+
const cleanup = () => { removeLock(); };
|
|
138
|
+
process.on('exit', cleanup);
|
|
139
|
+
for (const sig of ['SIGINT', 'SIGTERM']) {
|
|
140
|
+
process.on(sig, () => { cleanup(); process.exit(0); });
|
|
141
|
+
}
|
|
142
|
+
console.error(`${LOG} up — holding the line to ${apiUrl} (pid ${process.pid})`);
|
|
143
|
+
let backoff = BACKOFF_INITIAL_MS;
|
|
144
|
+
while (!opts.signal?.aborted) {
|
|
145
|
+
try {
|
|
146
|
+
const res = await fetch(`${apiUrl}/v1/desk/poll`, {
|
|
147
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
148
|
+
signal: opts.signal,
|
|
149
|
+
});
|
|
150
|
+
backoff = BACKOFF_INITIAL_MS; // a successful poll resets backoff
|
|
151
|
+
if (res.status === 204) {
|
|
152
|
+
if (opts.once)
|
|
153
|
+
break;
|
|
154
|
+
continue;
|
|
155
|
+
} // idle hold elapsed → re-poll
|
|
156
|
+
if (!res.ok) {
|
|
157
|
+
await sleep(backoff, opts.signal);
|
|
158
|
+
backoff = Math.min(backoff * 2, BACKOFF_MAX_MS);
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
const { job } = (await res.json());
|
|
162
|
+
if (!job) {
|
|
163
|
+
if (opts.once)
|
|
164
|
+
break;
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
const answer = answerJob(job);
|
|
168
|
+
await fetch(`${apiUrl}/v1/desk/reply`, {
|
|
169
|
+
method: 'POST',
|
|
170
|
+
headers: { Authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },
|
|
171
|
+
body: JSON.stringify({ jobId: job.id, answer }),
|
|
172
|
+
signal: opts.signal,
|
|
173
|
+
}).catch(() => { });
|
|
174
|
+
console.error(`${LOG} answered ${job.kind} ${job.id}`);
|
|
175
|
+
if (opts.once)
|
|
176
|
+
break;
|
|
177
|
+
}
|
|
178
|
+
catch (e) {
|
|
179
|
+
if (opts.signal?.aborted)
|
|
180
|
+
break;
|
|
181
|
+
console.error(`${LOG} poll error: ${e?.message ?? e} — backing off ${backoff}ms`);
|
|
182
|
+
await sleep(backoff, opts.signal);
|
|
183
|
+
backoff = Math.min(backoff * 2, BACKOFF_MAX_MS);
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
cleanup();
|
|
187
|
+
}
|
|
188
|
+
function sleep(ms, signal) {
|
|
189
|
+
return new Promise(resolve => {
|
|
190
|
+
const t = setTimeout(resolve, ms);
|
|
191
|
+
signal?.addEventListener('abort', () => { clearTimeout(t); resolve(); }, { once: true });
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
/** Idempotently ensure a desk-line is running, spawning a detached one if not.
|
|
195
|
+
* Safe to call on every SessionStart — the singleton lock makes extra calls a
|
|
196
|
+
* no-op. Returns true if a desk-line is (now) running. */
|
|
197
|
+
function ensureDeskLine() {
|
|
198
|
+
if (deskLineRunning())
|
|
199
|
+
return true;
|
|
200
|
+
try {
|
|
201
|
+
const child = (0, child_process_1.spawn)(process.execPath, [path.join(__dirname, '..', 'index.js'), 'desk', 'run'], {
|
|
202
|
+
detached: true,
|
|
203
|
+
stdio: 'ignore',
|
|
204
|
+
env: process.env,
|
|
205
|
+
});
|
|
206
|
+
child.unref();
|
|
207
|
+
return true;
|
|
208
|
+
}
|
|
209
|
+
catch (e) {
|
|
210
|
+
console.error(`${LOG} failed to spawn desk-line: ${e?.message ?? e}`);
|
|
211
|
+
return false;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
/** `greprag desk status` — is a desk-line up, and what's the local truth it would
|
|
215
|
+
* report right now? */
|
|
216
|
+
function deskLineStatus() {
|
|
217
|
+
const lock = deskLineRunning();
|
|
218
|
+
if (lock) {
|
|
219
|
+
const ageMs = Date.now() - (lock.startedAt || Date.now());
|
|
220
|
+
console.log(`desk-line: UP (pid ${lock.pid}, ${Math.floor(ageMs / 1000)}s)`);
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
console.log('desk-line: DOWN');
|
|
224
|
+
}
|
|
225
|
+
const live = (0, watcher_registry_1.listLocalLiveWatchers)();
|
|
226
|
+
console.log(`local live sessions: ${live.length}`);
|
|
227
|
+
for (const w of live)
|
|
228
|
+
console.log(` ${w.short} (pid ${w.pid})`);
|
|
229
|
+
}
|
|
230
|
+
//# sourceMappingURL=desk-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desk-line.js","sourceRoot":"","sources":["../../src/commands/desk-line.ts"],"names":[],"mappings":"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"}
|
package/dist/commands/init.js
CHANGED
|
@@ -428,15 +428,55 @@ async function runOpenCodeInit(opts) {
|
|
|
428
428
|
console.warn(' Inbox registration skipped (network)');
|
|
429
429
|
}
|
|
430
430
|
// Step 7: Install plugin to ~/.config/opencode/plugins/greprag-memory.js
|
|
431
|
+
// adr: adr/opencode-monitor-relay.md (2026-06-06 (f))
|
|
432
|
+
// The helpers file does NOT live in the opencode plugins dir — opencode
|
|
433
|
+
// auto-loads every `.js` file in `~/.config/opencode/plugins/` as a
|
|
434
|
+
// plugin, and the helpers file (a barrel of named function exports with
|
|
435
|
+
// `__esModule: true` tsc marker) would trip the same `getLegacyPlugins`
|
|
436
|
+
// shape check the main file used to. Helpers go to `~/.greprag/` and the
|
|
437
|
+
// main plugin requires them by absolute path. Only the main file is
|
|
438
|
+
// registered with opencode.
|
|
439
|
+
//
|
|
440
|
+
// The main plugin source uses `export = { id, server }` which tsc
|
|
441
|
+
// compiles to `module.exports = { id, server }` with no `__esModule: true`
|
|
442
|
+
// marker — so the legacy plugin loader's `Object.values(mod)` sees
|
|
443
|
+
// exactly one entry and registers the plugin. See ADR entry 2026-06-06
|
|
444
|
+
// (f) for the full diagnosis.
|
|
431
445
|
const pluginDir = path.join(os.homedir(), '.config', 'opencode', 'plugins');
|
|
432
|
-
const
|
|
433
|
-
const
|
|
446
|
+
const grepragHome = path.join(os.homedir(), '.greprag');
|
|
447
|
+
const pluginMain = path.join(pluginDir, 'greprag-memory.js');
|
|
448
|
+
const helpersDest = path.join(grepragHome, 'opencode-plugin-helpers.js');
|
|
449
|
+
const pluginMainSrc = path.join(__dirname, '../opencode-plugin.js');
|
|
450
|
+
const helpersSrc = path.join(__dirname, '../opencode-plugin-helpers.js');
|
|
434
451
|
let pluginInstalled = false;
|
|
435
|
-
if (fs.existsSync(
|
|
452
|
+
if (fs.existsSync(pluginMainSrc)) {
|
|
436
453
|
if (!fs.existsSync(pluginDir))
|
|
437
454
|
fs.mkdirSync(pluginDir, { recursive: true });
|
|
438
|
-
fs.
|
|
439
|
-
|
|
455
|
+
if (!fs.existsSync(grepragHome))
|
|
456
|
+
fs.mkdirSync(grepragHome, { recursive: true });
|
|
457
|
+
if (!fs.existsSync(helpersSrc)) {
|
|
458
|
+
console.warn(` Helpers artifact missing: ${helpersSrc} — run \`npm run build\` in packages/cli and retry`);
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
fs.copyFileSync(helpersSrc, helpersDest);
|
|
462
|
+
}
|
|
463
|
+
fs.copyFileSync(pluginMainSrc, pluginMain);
|
|
464
|
+
// Stale cleanup: prior deploys (commit 5d1a384, 2026-06-06) installed
|
|
465
|
+
// the helpers as `opencode-plugin-helpers.js` INSIDE the plugins dir.
|
|
466
|
+
// opencode auto-loads every `.js` there as a plugin, and the helpers
|
|
467
|
+
// file is a barrel of function exports with `__esModule: true` — it
|
|
468
|
+
// trips the loader's shape check and logs "Plugin export is not a
|
|
469
|
+
// function". It's stale now that the helpers live in ~/.greprag/.
|
|
470
|
+
const staleHelpers = path.join(pluginDir, 'opencode-plugin-helpers.js');
|
|
471
|
+
if (fs.existsSync(staleHelpers)) {
|
|
472
|
+
try {
|
|
473
|
+
fs.unlinkSync(staleHelpers);
|
|
474
|
+
console.log(` Removed stale plugin: ${staleHelpers}`);
|
|
475
|
+
}
|
|
476
|
+
catch { }
|
|
477
|
+
}
|
|
478
|
+
console.log(` Plugin installed: ${pluginMain}`);
|
|
479
|
+
console.log(` Helpers installed: ${helpersDest}`);
|
|
440
480
|
pluginInstalled = true;
|
|
441
481
|
}
|
|
442
482
|
else {
|
|
@@ -448,7 +488,7 @@ async function runOpenCodeInit(opts) {
|
|
|
448
488
|
console.log(` - ${c}`);
|
|
449
489
|
console.log(` - Project anchor: ${anchor.anchorPath} (source: ${anchor.source})`);
|
|
450
490
|
if (pluginInstalled)
|
|
451
|
-
console.log(` - Plugin: ${
|
|
491
|
+
console.log(` - Plugin: ${pluginMain}`);
|
|
452
492
|
console.log(` - Shared env: ${getGrepragEnvPath()}`);
|
|
453
493
|
console.log(' OpenCode will load the plugin automatically on next session start.');
|
|
454
494
|
console.log(' The /greprag skill is also available for on-demand briefings.\n');
|
|
@@ -547,7 +587,7 @@ async function runCodexInit(opts) {
|
|
|
547
587
|
}
|
|
548
588
|
console.log(`\n Codex hooks file: ${hooksPath}`);
|
|
549
589
|
console.log(` Project anchor: ${anchor.anchorPath}`);
|
|
550
|
-
console.log(' Start a fresh Codex session, then open Settings -> Settings -> Hooks and trust the
|
|
590
|
+
console.log(' Start a fresh Codex session, then open Settings -> Settings -> Hooks and trust the 8 GrepRAG hook definitions.');
|
|
551
591
|
console.log(' For live inbox push, run: greprag codex startup install');
|
|
552
592
|
console.log(' Memory hooks will activate on your next Codex session.\n');
|
|
553
593
|
}
|
|
@@ -994,6 +1034,32 @@ function applyCodexHooks(config) {
|
|
|
994
1034
|
else {
|
|
995
1035
|
changes.push('Codex PostToolUse inbox hook already configured (skipped)');
|
|
996
1036
|
}
|
|
1037
|
+
const permissionHook = {
|
|
1038
|
+
matcher: '',
|
|
1039
|
+
hooks: [commandHook('codex-permission-context', 3, 'Loading GrepRAG approval context')],
|
|
1040
|
+
};
|
|
1041
|
+
if (!hasGrepragHook(config.hooks.PermissionRequest, 'codex-permission-context')) {
|
|
1042
|
+
if (!config.hooks.PermissionRequest)
|
|
1043
|
+
config.hooks.PermissionRequest = [];
|
|
1044
|
+
config.hooks.PermissionRequest.push(permissionHook);
|
|
1045
|
+
changes.push('Added Codex PermissionRequest hook (approval context)');
|
|
1046
|
+
}
|
|
1047
|
+
else {
|
|
1048
|
+
changes.push('Codex PermissionRequest context hook already configured (skipped)');
|
|
1049
|
+
}
|
|
1050
|
+
const subagentStartHook = {
|
|
1051
|
+
matcher: '',
|
|
1052
|
+
hooks: [commandHook('codex-subagent-start', 3, 'Recording GrepRAG subagent metadata')],
|
|
1053
|
+
};
|
|
1054
|
+
if (!hasGrepragHook(config.hooks.SubagentStart, 'codex-subagent-start')) {
|
|
1055
|
+
if (!config.hooks.SubagentStart)
|
|
1056
|
+
config.hooks.SubagentStart = [];
|
|
1057
|
+
config.hooks.SubagentStart.push(subagentStartHook);
|
|
1058
|
+
changes.push('Added Codex SubagentStart hook (subagent metadata)');
|
|
1059
|
+
}
|
|
1060
|
+
else {
|
|
1061
|
+
changes.push('Codex SubagentStart metadata hook already configured (skipped)');
|
|
1062
|
+
}
|
|
997
1063
|
const storeHook = {
|
|
998
1064
|
matcher: '',
|
|
999
1065
|
hooks: [commandHook('codex-store', 10, 'Storing GrepRAG turn')],
|
|
@@ -1034,6 +1100,8 @@ function normalizeCodexHookCommands(hooks) {
|
|
|
1034
1100
|
'session-id': { timeout: 3, statusMessage: 'Loading GrepRAG session id' },
|
|
1035
1101
|
'codex-notify': { timeout: 5, statusMessage: 'Checking GrepRAG inbox' },
|
|
1036
1102
|
'codex-inbox': { timeout: 5, statusMessage: 'Checking GrepRAG inbox' },
|
|
1103
|
+
'codex-permission-context': { timeout: 3, statusMessage: 'Loading GrepRAG approval context' },
|
|
1104
|
+
'codex-subagent-start': { timeout: 3, statusMessage: 'Recording GrepRAG subagent metadata' },
|
|
1037
1105
|
'codex-store': { timeout: 10, statusMessage: 'Storing GrepRAG turn' },
|
|
1038
1106
|
};
|
|
1039
1107
|
let count = 0;
|