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
|
@@ -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,248 @@
|
|
|
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 inbox_spool_1 = require("./inbox-spool");
|
|
62
|
+
const API_URL_DEFAULT = 'https://api.greprag.com';
|
|
63
|
+
const LOG = '[greprag desk]';
|
|
64
|
+
const BACKOFF_INITIAL_MS = 1_000;
|
|
65
|
+
const BACKOFF_MAX_MS = 30_000;
|
|
66
|
+
function grepragHome() {
|
|
67
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
68
|
+
return path.join(home, '.greprag');
|
|
69
|
+
}
|
|
70
|
+
function lockPath() { return path.join(grepragHome(), 'desk-line.json'); }
|
|
71
|
+
function pidAlive(pid) {
|
|
72
|
+
if (!Number.isFinite(pid) || pid <= 0)
|
|
73
|
+
return false;
|
|
74
|
+
try {
|
|
75
|
+
process.kill(pid, 0);
|
|
76
|
+
return true;
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
return e?.code === 'EPERM';
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** Is a live desk-line already running on this machine? */
|
|
83
|
+
function deskLineRunning() {
|
|
84
|
+
try {
|
|
85
|
+
const rec = JSON.parse(fs.readFileSync(lockPath(), 'utf-8'));
|
|
86
|
+
if (rec && typeof rec.pid === 'number' && pidAlive(rec.pid))
|
|
87
|
+
return rec;
|
|
88
|
+
fs.rmSync(lockPath(), { force: true }); // stale lock → sweep
|
|
89
|
+
}
|
|
90
|
+
catch { /* no lock */ }
|
|
91
|
+
return null;
|
|
92
|
+
}
|
|
93
|
+
function writeLock() {
|
|
94
|
+
try {
|
|
95
|
+
fs.mkdirSync(grepragHome(), { recursive: true });
|
|
96
|
+
fs.writeFileSync(lockPath(), JSON.stringify({ pid: process.pid, startedAt: Date.now() }));
|
|
97
|
+
}
|
|
98
|
+
catch { /* best-effort */ }
|
|
99
|
+
}
|
|
100
|
+
function removeLock() { try {
|
|
101
|
+
fs.rmSync(lockPath(), { force: true });
|
|
102
|
+
}
|
|
103
|
+
catch { /* noop */ } }
|
|
104
|
+
function getConfig() {
|
|
105
|
+
return {
|
|
106
|
+
apiUrl: process.env.GREPRAG_API_URL || API_URL_DEFAULT,
|
|
107
|
+
apiKey: process.env.GREPRAG_API_KEY || '',
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
/** Compute the answer to a job from local ground truth. */
|
|
111
|
+
function answerJob(job) {
|
|
112
|
+
if (job.kind === 'list') {
|
|
113
|
+
const live = (0, watcher_registry_1.listLocalLiveWatchers)();
|
|
114
|
+
return {
|
|
115
|
+
watchers: live.map(w => ({
|
|
116
|
+
session_id: w.short, pid: w.pid, owner_pid: w.ownerPid ?? null, started_at: w.startedAt,
|
|
117
|
+
})),
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// 'deliver': write the inbound message to the target session's local spool.
|
|
121
|
+
// The session's watcher tails that spool and injects it — delivery without a
|
|
122
|
+
// per-session cloud socket. payload = { session: <8hex>, message: {...} }.
|
|
123
|
+
if (job.kind === 'deliver') {
|
|
124
|
+
const p = (job.payload ?? {});
|
|
125
|
+
if (!p.session || p.message === undefined)
|
|
126
|
+
return { ok: false, reason: 'bad-deliver-payload' };
|
|
127
|
+
// Only deliver to a session whose watcher is actually live on this machine.
|
|
128
|
+
const live = new Set((0, watcher_registry_1.listLocalLiveWatchers)().map(w => w.short));
|
|
129
|
+
if (!live.has(p.session))
|
|
130
|
+
return { ok: false, reason: 'session-not-local' };
|
|
131
|
+
try {
|
|
132
|
+
(0, inbox_spool_1.appendToSpool)(p.session, p.message);
|
|
133
|
+
return { ok: true, delivered: true };
|
|
134
|
+
}
|
|
135
|
+
catch (e) {
|
|
136
|
+
return { ok: false, reason: e?.message ?? 'spool-write-failed' };
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { ok: false, reason: 'unknown-kind' };
|
|
140
|
+
}
|
|
141
|
+
/** The long-poll loop. Runs until the AbortSignal fires (or forever). */
|
|
142
|
+
async function runDeskLine(opts = {}) {
|
|
143
|
+
const { apiUrl, apiKey } = getConfig();
|
|
144
|
+
if (!apiKey) {
|
|
145
|
+
console.error(`${LOG} not configured (GREPRAG_API_KEY unset). Run: greprag init`);
|
|
146
|
+
process.exitCode = 64;
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const existing = deskLineRunning();
|
|
150
|
+
if (existing && existing.pid !== process.pid) {
|
|
151
|
+
console.error(`${LOG} already running (pid ${existing.pid}) — exiting (singleton).`);
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
writeLock();
|
|
155
|
+
const cleanup = () => { removeLock(); };
|
|
156
|
+
process.on('exit', cleanup);
|
|
157
|
+
for (const sig of ['SIGINT', 'SIGTERM']) {
|
|
158
|
+
process.on(sig, () => { cleanup(); process.exit(0); });
|
|
159
|
+
}
|
|
160
|
+
console.error(`${LOG} up — holding the line to ${apiUrl} (pid ${process.pid})`);
|
|
161
|
+
let backoff = BACKOFF_INITIAL_MS;
|
|
162
|
+
while (!opts.signal?.aborted) {
|
|
163
|
+
try {
|
|
164
|
+
const res = await fetch(`${apiUrl}/v1/desk/poll`, {
|
|
165
|
+
headers: { Authorization: `Bearer ${apiKey}` },
|
|
166
|
+
signal: opts.signal,
|
|
167
|
+
});
|
|
168
|
+
backoff = BACKOFF_INITIAL_MS; // a successful poll resets backoff
|
|
169
|
+
if (res.status === 204) {
|
|
170
|
+
if (opts.once)
|
|
171
|
+
break;
|
|
172
|
+
continue;
|
|
173
|
+
} // idle hold elapsed → re-poll
|
|
174
|
+
if (!res.ok) {
|
|
175
|
+
await sleep(backoff, opts.signal);
|
|
176
|
+
backoff = Math.min(backoff * 2, BACKOFF_MAX_MS);
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
const { job } = (await res.json());
|
|
180
|
+
if (!job) {
|
|
181
|
+
if (opts.once)
|
|
182
|
+
break;
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
const answer = answerJob(job);
|
|
186
|
+
await fetch(`${apiUrl}/v1/desk/reply`, {
|
|
187
|
+
method: 'POST',
|
|
188
|
+
headers: { Authorization: `Bearer ${apiKey}`, 'content-type': 'application/json' },
|
|
189
|
+
body: JSON.stringify({ jobId: job.id, answer }),
|
|
190
|
+
signal: opts.signal,
|
|
191
|
+
}).catch(() => { });
|
|
192
|
+
console.error(`${LOG} answered ${job.kind} ${job.id}`);
|
|
193
|
+
if (opts.once)
|
|
194
|
+
break;
|
|
195
|
+
}
|
|
196
|
+
catch (e) {
|
|
197
|
+
if (opts.signal?.aborted)
|
|
198
|
+
break;
|
|
199
|
+
console.error(`${LOG} poll error: ${e?.message ?? e} — backing off ${backoff}ms`);
|
|
200
|
+
await sleep(backoff, opts.signal);
|
|
201
|
+
backoff = Math.min(backoff * 2, BACKOFF_MAX_MS);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
cleanup();
|
|
205
|
+
}
|
|
206
|
+
function sleep(ms, signal) {
|
|
207
|
+
return new Promise(resolve => {
|
|
208
|
+
const t = setTimeout(resolve, ms);
|
|
209
|
+
signal?.addEventListener('abort', () => { clearTimeout(t); resolve(); }, { once: true });
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
/** Idempotently ensure a desk-line is running, spawning a detached one if not.
|
|
213
|
+
* Safe to call on every SessionStart — the singleton lock makes extra calls a
|
|
214
|
+
* no-op. Returns true if a desk-line is (now) running. */
|
|
215
|
+
function ensureDeskLine() {
|
|
216
|
+
if (deskLineRunning())
|
|
217
|
+
return true;
|
|
218
|
+
try {
|
|
219
|
+
const child = (0, child_process_1.spawn)(process.execPath, [path.join(__dirname, '..', 'index.js'), 'desk', 'run'], {
|
|
220
|
+
detached: true,
|
|
221
|
+
stdio: 'ignore',
|
|
222
|
+
env: process.env,
|
|
223
|
+
});
|
|
224
|
+
child.unref();
|
|
225
|
+
return true;
|
|
226
|
+
}
|
|
227
|
+
catch (e) {
|
|
228
|
+
console.error(`${LOG} failed to spawn desk-line: ${e?.message ?? e}`);
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/** `greprag desk status` — is a desk-line up, and what's the local truth it would
|
|
233
|
+
* report right now? */
|
|
234
|
+
function deskLineStatus() {
|
|
235
|
+
const lock = deskLineRunning();
|
|
236
|
+
if (lock) {
|
|
237
|
+
const ageMs = Date.now() - (lock.startedAt || Date.now());
|
|
238
|
+
console.log(`desk-line: UP (pid ${lock.pid}, ${Math.floor(ageMs / 1000)}s)`);
|
|
239
|
+
}
|
|
240
|
+
else {
|
|
241
|
+
console.log('desk-line: DOWN');
|
|
242
|
+
}
|
|
243
|
+
const live = (0, watcher_registry_1.listLocalLiveWatchers)();
|
|
244
|
+
console.log(`local live sessions: ${live.length}`);
|
|
245
|
+
for (const w of live)
|
|
246
|
+
console.log(` ${w.short} (pid ${w.pid})`);
|
|
247
|
+
}
|
|
248
|
+
//# sourceMappingURL=desk-line.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"desk-line.js","sourceRoot":"","sources":["../../src/commands/desk-line.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;GAgBG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BH,0CAOC;AA2CD,kCAiDC;AAYD,wCAcC;AAID,wCAWC;AAvKD,uCAAyB;AACzB,2CAA6B;AAC7B,iDAAsC;AACtC,yDAA2D;AAC3D,+CAA8C;AAE9C,MAAM,eAAe,GAAG,yBAAyB,CAAC;AAClD,MAAM,GAAG,GAAG,gBAAgB,CAAC;AAC7B,MAAM,kBAAkB,GAAG,KAAK,CAAC;AACjC,MAAM,cAAc,GAAG,MAAM,CAAC;AAK9B,SAAS,WAAW;IAClB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,WAAW,IAAI,EAAE,CAAC;IAC/D,OAAO,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,UAAU,CAAC,CAAC;AACrC,CAAC;AACD,SAAS,QAAQ,KAAa,OAAO,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;AAElF,SAAS,QAAQ,CAAC,GAAW;IAC3B,IAAI,CAAC,MAAM,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,GAAG,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACpD,IAAI,CAAC;QAAC,OAAO,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC;QAAC,OAAO,IAAI,CAAC;IAAC,CAAC;IAC1C,OAAO,CAAC,EAAE,CAAC;QAAC,OAAQ,CAA2B,EAAE,IAAI,KAAK,OAAO,CAAC;IAAC,CAAC;AACtE,CAAC;AAED,2DAA2D;AAC3D,SAAgB,eAAe;IAC7B,IAAI,CAAC;QACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,EAAE,CAAC,YAAY,CAAC,QAAQ,EAAE,EAAE,OAAO,CAAC,CAAa,CAAC;QACzE,IAAI,GAAG,IAAI,OAAO,GAAG,CAAC,GAAG,KAAK,QAAQ,IAAI,QAAQ,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,GAAG,CAAC;QACxE,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAG,qBAAqB;IACjE,CAAC;IAAC,MAAM,CAAC,CAAC,aAAa,CAAC,CAAC;IACzB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS;IAChB,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,WAAW,EAAE,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACjD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,SAAS,EAAE,IAAI,CAAC,GAAG,EAAE,EAAc,CAAC,CAAC,CAAC;IACxG,CAAC;IAAC,MAAM,CAAC,CAAC,iBAAiB,CAAC,CAAC;AAC/B,CAAC;AACD,SAAS,UAAU,KAAW,IAAI,CAAC;IAAC,EAAE,CAAC,MAAM,CAAC,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;AAAC,CAAC;AAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;AAEpG,SAAS,SAAS;IAChB,OAAO;QACL,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,eAAe;QACtD,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,EAAE;KAC1C,CAAC;AACJ,CAAC;AAED,2DAA2D;AAC3D,SAAS,SAAS,CAAC,GAAY;IAC7B,IAAI,GAAG,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,IAAA,wCAAqB,GAAE,CAAC;QACrC,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;gBACvB,UAAU,EAAE,CAAC,CAAC,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,GAAG,EAAE,SAAS,EAAE,CAAC,CAAC,QAAQ,IAAI,IAAI,EAAE,UAAU,EAAE,CAAC,CAAC,SAAS;aACxF,CAAC,CAAC;SACJ,CAAC;IACJ,CAAC;IACD,4EAA4E;IAC5E,6EAA6E;IAC7E,2EAA2E;IAC3E,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC3B,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAA4C,CAAC;QACzE,IAAI,CAAC,CAAC,CAAC,OAAO,IAAI,CAAC,CAAC,OAAO,KAAK,SAAS;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,qBAAqB,EAAE,CAAC;QAC/F,4EAA4E;QAC5E,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,IAAA,wCAAqB,GAAE,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC;QAChE,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC;YAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,mBAAmB,EAAE,CAAC;QAC5E,IAAI,CAAC;YAAC,IAAA,2BAAa,EAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC;QAAC,CAAC;QAClF,OAAO,CAAC,EAAE,CAAC;YAAC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAG,CAAW,EAAE,OAAO,IAAI,oBAAoB,EAAE,CAAC;QAAC,CAAC;IAC5F,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,cAAc,EAAE,CAAC;AAC/C,CAAC;AAED,yEAAyE;AAClE,KAAK,UAAU,WAAW,CAAC,OAAiD,EAAE;IACnF,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,SAAS,EAAE,CAAC;IACvC,IAAI,CAAC,MAAM,EAAE,CAAC;QAAC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,4DAA4D,CAAC,CAAC;QAAC,OAAO,CAAC,QAAQ,GAAG,EAAE,CAAC;QAAC,OAAO;IAAC,CAAC;IAElI,MAAM,QAAQ,GAAG,eAAe,EAAE,CAAC;IACnC,IAAI,QAAQ,IAAI,QAAQ,CAAC,GAAG,KAAK,OAAO,CAAC,GAAG,EAAE,CAAC;QAC7C,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,yBAAyB,QAAQ,CAAC,GAAG,0BAA0B,CAAC,CAAC;QACrF,OAAO;IACT,CAAC;IACD,SAAS,EAAE,CAAC;IACZ,MAAM,OAAO,GAAG,GAAG,EAAE,GAAG,UAAU,EAAE,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,CAAC,EAAE,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC5B,KAAK,MAAM,GAAG,IAAI,CAAC,QAAQ,EAAE,SAAS,CAAU,EAAE,CAAC;QACjD,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,OAAO,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;IACzD,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,6BAA6B,MAAM,SAAS,OAAO,CAAC,GAAG,GAAG,CAAC,CAAC;IAChF,IAAI,OAAO,GAAG,kBAAkB,CAAC;IAEjC,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,OAAO,EAAE,CAAC;QAC7B,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,MAAM,KAAK,CAAC,GAAG,MAAM,eAAe,EAAE;gBAChD,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE;gBAC9C,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAC;YACH,OAAO,GAAG,kBAAkB,CAAC,CAAa,mCAAmC;YAC7E,IAAI,GAAG,CAAC,MAAM,KAAK,GAAG,EAAE,CAAC;gBAAC,IAAI,IAAI,CAAC,IAAI;oBAAE,MAAM;gBAAC,SAAS;YAAC,CAAC,CAAG,8BAA8B;YAC5F,IAAI,CAAC,GAAG,CAAC,EAAE,EAAE,CAAC;gBAAC,MAAM,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;gBAAC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;gBAAC,SAAS;YAAC,CAAC;YAE9G,MAAM,EAAE,GAAG,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,IAAI,EAAE,CAAsB,CAAC;YACxD,IAAI,CAAC,GAAG,EAAE,CAAC;gBAAC,IAAI,IAAI,CAAC,IAAI;oBAAE,MAAM;gBAAC,SAAS;YAAC,CAAC;YAE7C,MAAM,MAAM,GAAG,SAAS,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,KAAK,CAAC,GAAG,MAAM,gBAAgB,EAAE;gBACrC,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,EAAE,aAAa,EAAE,UAAU,MAAM,EAAE,EAAE,cAAc,EAAE,kBAAkB,EAAE;gBAClF,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC;gBAC/C,MAAM,EAAE,IAAI,CAAC,MAAM;aACpB,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAA0D,CAAC,CAAC,CAAC;YAC3E,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,aAAa,GAAG,CAAC,IAAI,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC,CAAC;YACvD,IAAI,IAAI,CAAC,IAAI;gBAAE,MAAM;QACvB,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,IAAI,IAAI,CAAC,MAAM,EAAE,OAAO;gBAAE,MAAM;YAChC,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,gBAAiB,CAAW,EAAE,OAAO,IAAI,CAAC,kBAAkB,OAAO,IAAI,CAAC,CAAC;YAC7F,MAAM,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC,MAAM,CAAC,CAAC;YAClC,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,GAAG,CAAC,EAAE,cAAc,CAAC,CAAC;QAClD,CAAC;IACH,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,SAAS,KAAK,CAAC,EAAU,EAAE,MAAoB;IAC7C,OAAO,IAAI,OAAO,CAAC,OAAO,CAAC,EAAE;QAC3B,MAAM,CAAC,GAAG,UAAU,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QAClC,MAAM,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;IAC3F,CAAC,CAAC,CAAC;AACL,CAAC;AAED;;2DAE2D;AAC3D,SAAgB,cAAc;IAC5B,IAAI,eAAe,EAAE;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAA,qBAAK,EAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE;YAC7F,QAAQ,EAAE,IAAI;YACd,KAAK,EAAE,QAAQ;YACf,GAAG,EAAE,OAAO,CAAC,GAAG;SACjB,CAAC,CAAC;QACH,KAAK,CAAC,KAAK,EAAE,CAAC;QACd,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,OAAO,CAAC,KAAK,CAAC,GAAG,GAAG,+BAAgC,CAAW,EAAE,OAAO,IAAI,CAAC,EAAE,CAAC,CAAC;QACjF,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC;AAED;wBACwB;AACxB,SAAgB,cAAc;IAC5B,MAAM,IAAI,GAAG,eAAe,EAAE,CAAC;IAC/B,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,SAAS,IAAI,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC;IAC/E,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC;IACjC,CAAC;IACD,MAAM,IAAI,GAAG,IAAA,wCAAqB,GAAE,CAAC;IACrC,OAAO,CAAC,GAAG,CAAC,wBAAwB,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC;IACnD,KAAK,MAAM,CAAC,IAAI,IAAI;QAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC,GAAG,GAAG,CAAC,CAAC;AACpE,CAAC"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/** Local inbox spool — the delivery channel between the machine's desk-line and
|
|
2
|
+
* a session's watcher.
|
|
3
|
+
*
|
|
4
|
+
* The delivery-cutover counterpart to the live-list relay: instead of each
|
|
5
|
+
* session's watcher holding a cloud SSE socket to receive inbound (the path that
|
|
6
|
+
* keeps the stale InboxDO whiteboard alive), the desk-line APPENDS each inbound
|
|
7
|
+
* message to a per-session spool file here, and the watcher TAILS it locally. No
|
|
8
|
+
* NAT crossing on the delivery hot path, no per-session cloud socket — the
|
|
9
|
+
* watcher reads a file the desk-line wrote.
|
|
10
|
+
*
|
|
11
|
+
* Format: newline-delimited JSON (one message per line) at
|
|
12
|
+
* ~/.greprag/inbox/<short>.ndjson. Bounded to the last SPOOL_MAX lines so a
|
|
13
|
+
* long-lived session can't grow it without bound; the watcher dedups by message
|
|
14
|
+
* id, so the bound never drops an unseen message under normal cadence.
|
|
15
|
+
*
|
|
16
|
+
* adr: adr/desk-line-relay.md */
|
|
17
|
+
export declare function spoolPath(short: string): string;
|
|
18
|
+
/** Append a message to a session's spool (desk-line write side). Trims to the
|
|
19
|
+
* last SPOOL_MAX lines. Best-effort: a failed write is logged by the caller's
|
|
20
|
+
* catch, never throws into the relay loop. */
|
|
21
|
+
export declare function appendToSpool(short: string, message: unknown): void;
|
|
22
|
+
/** Tail a session's spool, invoking `onMessage` for each appended JSON line.
|
|
23
|
+
* Polls by byte offset (survives the file not existing yet). Fully
|
|
24
|
+
* error-isolated: every parse/read failure is swallowed so a malformed spool
|
|
25
|
+
* line can never crash the watcher's live SSE path. Returns when `signal`
|
|
26
|
+
* aborts. adr: adr/desk-line-relay.md */
|
|
27
|
+
export declare function tailSpool(short: string, onMessage: (msg: unknown) => void, signal: AbortSignal): Promise<void>;
|
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/** Local inbox spool — the delivery channel between the machine's desk-line and
|
|
3
|
+
* a session's watcher.
|
|
4
|
+
*
|
|
5
|
+
* The delivery-cutover counterpart to the live-list relay: instead of each
|
|
6
|
+
* session's watcher holding a cloud SSE socket to receive inbound (the path that
|
|
7
|
+
* keeps the stale InboxDO whiteboard alive), the desk-line APPENDS each inbound
|
|
8
|
+
* message to a per-session spool file here, and the watcher TAILS it locally. No
|
|
9
|
+
* NAT crossing on the delivery hot path, no per-session cloud socket — the
|
|
10
|
+
* watcher reads a file the desk-line wrote.
|
|
11
|
+
*
|
|
12
|
+
* Format: newline-delimited JSON (one message per line) at
|
|
13
|
+
* ~/.greprag/inbox/<short>.ndjson. Bounded to the last SPOOL_MAX lines so a
|
|
14
|
+
* long-lived session can't grow it without bound; the watcher dedups by message
|
|
15
|
+
* id, so the bound never drops an unseen message under normal cadence.
|
|
16
|
+
*
|
|
17
|
+
* adr: adr/desk-line-relay.md */
|
|
18
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
19
|
+
if (k2 === undefined) k2 = k;
|
|
20
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
21
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
22
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
23
|
+
}
|
|
24
|
+
Object.defineProperty(o, k2, desc);
|
|
25
|
+
}) : (function(o, m, k, k2) {
|
|
26
|
+
if (k2 === undefined) k2 = k;
|
|
27
|
+
o[k2] = m[k];
|
|
28
|
+
}));
|
|
29
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
30
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
31
|
+
}) : function(o, v) {
|
|
32
|
+
o["default"] = v;
|
|
33
|
+
});
|
|
34
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
35
|
+
var ownKeys = function(o) {
|
|
36
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
})();
|
|
51
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
52
|
+
exports.spoolPath = spoolPath;
|
|
53
|
+
exports.appendToSpool = appendToSpool;
|
|
54
|
+
exports.tailSpool = tailSpool;
|
|
55
|
+
const fs = __importStar(require("fs"));
|
|
56
|
+
const path = __importStar(require("path"));
|
|
57
|
+
const SPOOL_DIRNAME = 'inbox';
|
|
58
|
+
const SPOOL_MAX = 200; // keep the last N messages per session
|
|
59
|
+
const TAIL_POLL_MS = 400; // how often the watcher checks for appends
|
|
60
|
+
function grepragHome() {
|
|
61
|
+
const home = process.env.HOME || process.env.USERPROFILE || '';
|
|
62
|
+
return path.join(home, '.greprag');
|
|
63
|
+
}
|
|
64
|
+
function spoolDir() { return path.join(grepragHome(), SPOOL_DIRNAME); }
|
|
65
|
+
function spoolPath(short) { return path.join(spoolDir(), `${short}.ndjson`); }
|
|
66
|
+
/** Append a message to a session's spool (desk-line write side). Trims to the
|
|
67
|
+
* last SPOOL_MAX lines. Best-effort: a failed write is logged by the caller's
|
|
68
|
+
* catch, never throws into the relay loop. */
|
|
69
|
+
function appendToSpool(short, message) {
|
|
70
|
+
const dir = spoolDir();
|
|
71
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
72
|
+
const file = spoolPath(short);
|
|
73
|
+
fs.appendFileSync(file, JSON.stringify(message) + '\n');
|
|
74
|
+
// Trim if it grew past the cap (cheap: only re-read when the file is large).
|
|
75
|
+
try {
|
|
76
|
+
const stat = fs.statSync(file);
|
|
77
|
+
if (stat.size > SPOOL_MAX * 4096) {
|
|
78
|
+
const lines = fs.readFileSync(file, 'utf-8').split('\n').filter(Boolean);
|
|
79
|
+
if (lines.length > SPOOL_MAX) {
|
|
80
|
+
fs.writeFileSync(file, lines.slice(-SPOOL_MAX).join('\n') + '\n');
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch { /* trim is best-effort */ }
|
|
85
|
+
}
|
|
86
|
+
/** Tail a session's spool, invoking `onMessage` for each appended JSON line.
|
|
87
|
+
* Polls by byte offset (survives the file not existing yet). Fully
|
|
88
|
+
* error-isolated: every parse/read failure is swallowed so a malformed spool
|
|
89
|
+
* line can never crash the watcher's live SSE path. Returns when `signal`
|
|
90
|
+
* aborts. adr: adr/desk-line-relay.md */
|
|
91
|
+
async function tailSpool(short, onMessage, signal) {
|
|
92
|
+
const file = spoolPath(short);
|
|
93
|
+
// Start at the current end of file — the desk-line only writes NEW inbound, and
|
|
94
|
+
// the watcher already got history via the SSE replay / `greprag inbox`. (When
|
|
95
|
+
// the SSE path is eventually removed, switch this to 0 to replay the spool.)
|
|
96
|
+
let offset = 0;
|
|
97
|
+
try {
|
|
98
|
+
offset = fs.statSync(file).size;
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
offset = 0;
|
|
102
|
+
}
|
|
103
|
+
let carry = '';
|
|
104
|
+
while (!signal.aborted) {
|
|
105
|
+
try {
|
|
106
|
+
let size = 0;
|
|
107
|
+
try {
|
|
108
|
+
size = fs.statSync(file).size;
|
|
109
|
+
}
|
|
110
|
+
catch {
|
|
111
|
+
size = 0;
|
|
112
|
+
}
|
|
113
|
+
if (size < offset) {
|
|
114
|
+
offset = 0;
|
|
115
|
+
carry = '';
|
|
116
|
+
} // file was rotated/trimmed
|
|
117
|
+
if (size > offset) {
|
|
118
|
+
const fd = fs.openSync(file, 'r');
|
|
119
|
+
try {
|
|
120
|
+
const buf = Buffer.alloc(size - offset);
|
|
121
|
+
fs.readSync(fd, buf, 0, buf.length, offset);
|
|
122
|
+
offset = size;
|
|
123
|
+
carry += buf.toString('utf-8');
|
|
124
|
+
let nl;
|
|
125
|
+
while ((nl = carry.indexOf('\n')) >= 0) {
|
|
126
|
+
const line = carry.slice(0, nl).trim();
|
|
127
|
+
carry = carry.slice(nl + 1);
|
|
128
|
+
if (!line)
|
|
129
|
+
continue;
|
|
130
|
+
try {
|
|
131
|
+
onMessage(JSON.parse(line));
|
|
132
|
+
}
|
|
133
|
+
catch { /* skip bad line */ }
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
finally {
|
|
137
|
+
fs.closeSync(fd);
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
catch { /* read cycle best-effort — never throw into the watcher */ }
|
|
142
|
+
await sleep(TAIL_POLL_MS, signal);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
function sleep(ms, signal) {
|
|
146
|
+
return new Promise(resolve => {
|
|
147
|
+
const t = setTimeout(resolve, ms);
|
|
148
|
+
signal.addEventListener('abort', () => { clearTimeout(t); resolve(); }, { once: true });
|
|
149
|
+
});
|
|
150
|
+
}
|
|
151
|
+
//# sourceMappingURL=inbox-spool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"inbox-spool.js","sourceRoot":"","sources":["../../src/commands/inbox-spool.ts"],"names":[],"mappings":"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"}
|