@oatelauser/crosschat 1.0.1 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"send.js","sourceRoot":"","sources":["../../src/commands/send.ts"],"names":[],"mappings":"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"}
package/dist/outbox.js CHANGED
@@ -1,43 +1,81 @@
1
- import { mkdirSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync } from 'node:fs';
1
+ import { appendFileSync, closeSync, mkdirSync, openSync, readFileSync, readdirSync, renameSync, rmSync, writeFileSync, writeSync, } from 'node:fs';
2
2
  import { homedir } from 'node:os';
3
3
  import { join } from 'node:path';
4
4
  import process from 'node:process';
5
+ import { randomBytes } from 'node:crypto';
5
6
  import { MultichatError } from './errors.js';
6
7
  import { checkAndRecord, rateKey } from './rate-limit.js';
7
8
  /**
8
- * Opportunistic outbox (B10): when a codex delivery fails with
9
- * CODEX_THREAD_BUSY_TIMEOUT / CODEX_THREAD_LOCKED, the fully composed envelope
10
- * is parked on disk (one JSON file per thread under
9
+ * Opportunistic outbox (B10/B11, reworked B12): when a codex delivery fails
10
+ * with CODEX_THREAD_BUSY_TIMEOUT / CODEX_THREAD_LOCKED, the fully composed
11
+ * envelope is parked on disk (one JSON file per thread under
11
12
  * %LOCALAPPDATA%/crosschat/outbox/) and re-delivered verbatim by the next
12
- * send/status invocation. No daemon; drains are short-wait and never block
13
- * the invoking command for long.
13
+ * send/status invocation or by the detached watchdog loop (src/watchdog.ts).
14
+ *
15
+ * B12 invariants, learned from the 2026-10-02 incident:
16
+ * - busy/locked is a THREAD-level state: one failing attempt aborts the whole
17
+ * thread for this round instead of burning the budget on guaranteed failures
18
+ * (the old loop starved queue tails to attempts=0 for 12h).
19
+ * - new sends join the queue instead of jumping it (enforced in send.ts).
20
+ * - every parked/delivered/dropped item is mirrored into a human-readable
21
+ * mailbox file so stuck content is always readable.
22
+ * - park/drain mutations take a per-thread lockfile so the watchdog and CLI
23
+ * drains cannot lose items by racing read-modify-write cycles.
14
24
  */
15
- export const OUTBOX_MAX_PER_THREAD = 20;
25
+ export const OUTBOX_MAX_PER_THREAD = 200;
16
26
  /** Short wait for drains: opportunistic relief must not block the real command. */
17
27
  const DEFAULT_DRAIN_BUSY_TIMEOUT_MS = 5_000;
18
28
  /** B11: a drain round re-delivers at most this many items (rest waits for the next round). */
19
29
  const DEFAULT_DRAIN_MAX_ITEMS = 5;
20
30
  /** B11: wall-clock budget for one drain round, judged on the injected clock. */
21
31
  const DEFAULT_DRAIN_BUDGET_MS = 15_000;
32
+ /** Per-thread lockfile staleness; a crashed holder is stolen after this. */
33
+ const LOCK_STALE_MS = 60_000;
22
34
  export function defaultOutboxDir() {
23
35
  return join(process.env.LOCALAPPDATA ?? homedir(), 'crosschat', 'outbox');
24
36
  }
37
+ /** Mailbox mirror lives next to the outbox root (sibling "mailbox" directory). */
38
+ export function mailboxDirFor(outboxDir) {
39
+ return join(outboxDir, '..', 'mailbox');
40
+ }
41
+ export function mailboxFileFor(outboxDir, threadId) {
42
+ return join(mailboxDirFor(outboxDir), `${threadId}.md`);
43
+ }
44
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
45
+ function genId(nowMs) {
46
+ return `${nowMs.toString(36)}-${randomBytes(3).toString('hex')}`;
47
+ }
48
+ function isoOf(nowMs) {
49
+ return new Date(nowMs).toISOString();
50
+ }
25
51
  /** Append one parked item (FIFO); refuses honestly past the per-thread cap. */
26
- export function park(dir, threadId, item, nowMs = Date.now()) {
27
- const items = readItems(dir, threadId) ?? []; // missing/corrupt: self-heal as empty
28
- if (items.length >= OUTBOX_MAX_PER_THREAD) {
29
- throw new MultichatError('OUTBOX_FULL', `Outbox full for codex thread ${threadId} (${OUTBOX_MAX_PER_THREAD} parked). ` +
30
- `线程疑似已死:改投其它线程,或人工清理 ${threadFile(dir, threadId)}。`);
52
+ export function park(dir, threadId, item, nowMs = Date.now(), mailboxDir = mailboxDirFor(dir)) {
53
+ // Best-effort lock: a contended park falls through lockless (ms-scale window,
54
+ // same risk as pre-B12) rather than blocking the sending command.
55
+ const locked = acquireThreadLock(dir, threadId, Date.now());
56
+ try {
57
+ const items = readItems(dir, threadId) ?? []; // missing/corrupt: self-heal as empty
58
+ if (items.length >= OUTBOX_MAX_PER_THREAD) {
59
+ throw new MultichatError('OUTBOX_FULL', `Outbox full for codex thread ${threadId} (${OUTBOX_MAX_PER_THREAD} parked). ` +
60
+ `对方线程持续忙或已死:读 ${join(mailboxDir, `${threadId}.md`)} 取回内容,` +
61
+ `或确认线程仍存在后重发。`);
62
+ }
63
+ const parked = { ...item, id: genId(nowMs), parkedAt: nowMs, attempts: 0 };
64
+ writeItems(dir, threadId, [...items, parked]);
65
+ appendMailbox(mailboxDir, threadId, `\n## ${parked.id} 寄存 ${isoOf(nowMs)}(队列第 ${items.length + 1} 位)\n${parked.envelope}\n`);
66
+ return parked;
67
+ }
68
+ finally {
69
+ if (locked)
70
+ releaseThreadLock(dir, threadId);
31
71
  }
32
- const parked = { ...item, parkedAt: nowMs, attempts: 0 };
33
- writeItems(dir, threadId, [...items, parked]);
34
- return parked;
35
72
  }
36
73
  /**
37
- * Try parked items once, in FIFO order, under a per-round budget. Success
38
- * removes the item; a still busy/locked thread keeps it with attempts+1;
39
- * CODEX_THREAD_NOT_FOUND dead-letters the whole thread (deleted threads are
40
- * unreachable forever); any other error keeps the item for a later drain.
74
+ * Deliver parked items head-first, one at a time: each delivery re-reads the
75
+ * file under the thread lock and removes exactly the delivered id, so a
76
+ * concurrent park is never lost. A busy/locked failure aborts the thread for
77
+ * this round (the state is thread-level); CODEX_THREAD_NOT_FOUND dead-letters
78
+ * the whole thread; any other error skips just that item for this round.
41
79
  * Never throws (corrupt files are skipped, a missing dir is a no-op), so it
42
80
  * can run before any command without failing it.
43
81
  */
@@ -45,6 +83,7 @@ export async function drain(dir, deliverFn, opts = {}) {
45
83
  const busyTimeoutMs = opts.busyTimeoutMs ?? DEFAULT_DRAIN_BUSY_TIMEOUT_MS;
46
84
  const maxItems = opts.maxItems ?? DEFAULT_DRAIN_MAX_ITEMS;
47
85
  const budgetMs = opts.budgetMs ?? DEFAULT_DRAIN_BUDGET_MS;
86
+ const mailboxDir = opts.mailboxDir ?? mailboxDirFor(dir);
48
87
  const now = opts.now ?? Date.now;
49
88
  const deadline = now() + budgetMs;
50
89
  let allowance = maxItems;
@@ -60,25 +99,32 @@ export async function drain(dir, deliverFn, opts = {}) {
60
99
  if (!file.endsWith('.json'))
61
100
  continue;
62
101
  const threadId = file.slice(0, -'.json'.length);
63
- const items = readItems(dir, threadId);
64
- if (items === undefined)
65
- continue; // missing/corrupt: leave the file alone
66
- const remaining = [];
102
+ // Items to ignore for the rest of this round (rate-window full, unknown
103
+ // delivery error): kept verbatim, retried by the next round.
104
+ const skipIds = new Set();
67
105
  let delivered = 0;
68
106
  let dropped = 0;
69
- let deliveredName = '';
70
- for (const item of items) {
71
- if (allowance <= 0 || now() >= deadline) {
72
- remaining.push(item); // round budget exhausted: keep verbatim for the next drain
73
- continue;
74
- }
107
+ let toName = '';
108
+ for (;;) {
109
+ if (allowance <= 0 || now() >= deadline)
110
+ break;
111
+ const head = await withThreadLock(dir, threadId, 2_000, () => {
112
+ const items = readItems(dir, threadId);
113
+ if (items === undefined || items.length === 0)
114
+ return undefined;
115
+ const item = items.find((candidate) => !skipIds.has(candidate.id));
116
+ return item === undefined ? undefined : { item };
117
+ });
118
+ if (head === undefined)
119
+ break;
120
+ toName = head.item.toName;
75
121
  if (opts.rateDir !== undefined) {
76
122
  try {
77
- checkAndRecord(opts.rateDir, rateKey(item.callerKey ?? 'human', `codex:${threadId}`), now());
123
+ checkAndRecord(opts.rateDir, rateKey(head.item.callerKey ?? 'human', `codex:${threadId}`), now());
78
124
  }
79
125
  catch (err) {
80
126
  if (err instanceof MultichatError && err.code === 'RATE_LIMITED') {
81
- remaining.push(item); // window full: skip this round, retry next drain
127
+ skipIds.add(head.item.id); // window full: skip this round, retry next drain
82
128
  continue;
83
129
  }
84
130
  throw err;
@@ -86,44 +132,51 @@ export async function drain(dir, deliverFn, opts = {}) {
86
132
  }
87
133
  allowance -= 1;
88
134
  try {
89
- await deliverFn(threadId, item.envelope, busyTimeoutMs);
135
+ await deliverFn(threadId, head.item.envelope, busyTimeoutMs);
90
136
  delivered++;
91
- deliveredName = item.toName;
137
+ appendMailbox(mailboxDir, threadId, `> ${head.item.id} 送达 ${isoOf(now())}\n`);
138
+ await withThreadLock(dir, threadId, 2_000, () => {
139
+ removeById(dir, threadId, head.item.id);
140
+ });
92
141
  }
93
142
  catch (err) {
94
143
  if (err instanceof MultichatError && err.code === 'CODEX_THREAD_NOT_FOUND') {
95
144
  // Dead letter: the thread is gone, so every parked item for it is
96
145
  // unreachable — discard all of them, not just this one.
97
- dropped = items.length - delivered;
98
- remaining.length = 0;
146
+ const removed = (await withThreadLock(dir, threadId, 2_000, () => {
147
+ const items = readItems(dir, threadId) ?? [];
148
+ writeItems(dir, threadId, []);
149
+ return items.length;
150
+ })) ?? 0;
151
+ dropped += removed;
152
+ appendMailbox(mailboxDir, threadId, `> 线程已不存在,丢弃 ${removed} 条(${isoOf(now())})\n`);
99
153
  break;
100
154
  }
101
155
  if (err instanceof MultichatError &&
102
156
  (err.code === 'CODEX_THREAD_BUSY_TIMEOUT' || err.code === 'CODEX_THREAD_LOCKED')) {
103
- // ponytail: attempts grows unbounded; cap/age-out if a stuck thread ever floods the file.
104
- remaining.push({ ...item, attempts: item.attempts + 1 });
105
- }
106
- else {
107
- remaining.push(item); // unknown state: keep, try again next drain
157
+ // Thread-level state: everything after the head would fail too.
158
+ await withThreadLock(dir, threadId, 2_000, () => {
159
+ bumpAttempts(dir, threadId, head.item.id);
160
+ });
161
+ break;
108
162
  }
163
+ skipIds.add(head.item.id); // unknown state: keep, try again next drain
109
164
  }
110
165
  }
111
- const changed = remaining.length !== items.length || remaining.some((item, i) => item !== items[i]);
112
- if (changed)
113
- writeItems(dir, threadId, remaining);
114
- if (delivered > 0 || remaining.length > 0 || dropped > 0) {
166
+ const remaining = countItems(dir, threadId);
167
+ if (delivered > 0 || remaining > 0 || dropped > 0) {
115
168
  results.push({
116
169
  threadId,
117
- toName: deliveredName || items.at(-1)?.toName || threadId,
170
+ toName: toName || shortThread(threadId),
118
171
  delivered,
119
- remaining: remaining.length,
172
+ remaining,
120
173
  dropped,
121
174
  });
122
175
  }
123
176
  }
124
177
  return results;
125
178
  }
126
- /** Parked item count per thread (doctor display); corrupt/empty files are skipped. */
179
+ /** Parked item count + oldest age per thread (doctor display); corrupt files are skipped. */
127
180
  export function outboxSummary(dir) {
128
181
  let files;
129
182
  try {
@@ -138,18 +191,36 @@ export function outboxSummary(dir) {
138
191
  continue;
139
192
  const threadId = file.slice(0, -'.json'.length);
140
193
  const items = readItems(dir, threadId);
141
- if (items !== undefined && items.length > 0)
142
- summary.push({ threadId, count: items.length });
194
+ if (items !== undefined && items.length > 0) {
195
+ summary.push({
196
+ threadId,
197
+ count: items.length,
198
+ oldestParkedAt: Math.min(...items.map((item) => item.parkedAt)),
199
+ });
200
+ }
143
201
  }
144
202
  return summary;
145
203
  }
204
+ /** Queue depth for one thread (0 when nothing is parked). */
205
+ export function outboxCount(dir, threadId) {
206
+ return readItems(dir, threadId)?.length ?? 0;
207
+ }
208
+ function shortThread(threadId) {
209
+ return `codex/${threadId.slice(0, 8)}`;
210
+ }
146
211
  function threadFile(dir, threadId) {
147
212
  return join(dir, `${threadId}.json`);
148
213
  }
214
+ function lockFile(dir, threadId) {
215
+ return join(dir, `${threadId}.lock`);
216
+ }
149
217
  function readItems(dir, threadId) {
150
218
  try {
151
219
  const parsed = JSON.parse(readFileSync(threadFile(dir, threadId), 'utf8'));
152
- return Array.isArray(parsed.items) ? parsed.items : undefined;
220
+ if (!Array.isArray(parsed.items))
221
+ return undefined;
222
+ // Pre-B12 files carry no id: synthesize a stable one from parkedAt+index.
223
+ return parsed.items.map((item, index) => item.id === undefined ? { ...item, id: `${item.parkedAt.toString(36)}-${index.toString(36)}` } : item);
153
224
  }
154
225
  catch {
155
226
  return undefined;
@@ -163,10 +234,91 @@ function writeItems(dir, threadId, items) {
163
234
  return;
164
235
  }
165
236
  mkdirSync(dir, { recursive: true });
166
- // ponytail: no cross-process locking; two concurrent drains can double-deliver
167
- // one item — rare and downstream-idempotent enough; add a lockfile if it bites.
168
237
  const tmp = join(dir, `${threadId}.${process.pid}.${Date.now()}.tmp`);
169
238
  writeFileSync(tmp, JSON.stringify({ items }), 'utf8');
170
239
  renameSync(tmp, file);
171
240
  }
241
+ function removeById(dir, threadId, id) {
242
+ const items = readItems(dir, threadId);
243
+ if (items === undefined)
244
+ return;
245
+ writeItems(dir, threadId, items.filter((item) => item.id !== id));
246
+ }
247
+ function bumpAttempts(dir, threadId, id) {
248
+ const items = readItems(dir, threadId);
249
+ if (items === undefined)
250
+ return;
251
+ writeItems(dir, threadId, items.map((item) => (item.id === id ? { ...item, attempts: item.attempts + 1 } : item)));
252
+ }
253
+ function countItems(dir, threadId) {
254
+ return readItems(dir, threadId)?.length ?? 0;
255
+ }
256
+ function appendMailbox(mailboxDir, threadId, text) {
257
+ try {
258
+ mkdirSync(mailboxDir, { recursive: true });
259
+ appendFileSync(join(mailboxDir, `${threadId}.md`), text, 'utf8');
260
+ }
261
+ catch {
262
+ // ponytail: the mirror is best-effort observability; outbox json stays authoritative.
263
+ }
264
+ }
265
+ function acquireThreadLock(dir, threadId, nowMs) {
266
+ const file = lockFile(dir, threadId);
267
+ for (let attempt = 0; attempt < 2; attempt++) {
268
+ try {
269
+ const fd = openExclusive(file);
270
+ writeSyncClose(fd, `${process.pid} ${nowMs}`);
271
+ return true;
272
+ }
273
+ catch (err) {
274
+ if (err.code !== 'EEXIST')
275
+ return false;
276
+ try {
277
+ const [, ts] = readFileSync(file, 'utf8').trim().split(/\s+/);
278
+ const written = Number(ts);
279
+ if (Number.isFinite(written) && nowMs - written > LOCK_STALE_MS) {
280
+ rmSync(file, { force: true }); // steal a crashed holder's lock
281
+ continue;
282
+ }
283
+ }
284
+ catch {
285
+ return false;
286
+ }
287
+ return false;
288
+ }
289
+ }
290
+ return false;
291
+ }
292
+ function releaseThreadLock(dir, threadId) {
293
+ rmSync(lockFile(dir, threadId), { force: true });
294
+ }
295
+ /** Run fn under the per-thread lock, waiting up to waitMs; undefined = never ran. */
296
+ async function withThreadLock(dir, threadId, waitMs, fn) {
297
+ const deadline = Date.now() + waitMs;
298
+ for (;;) {
299
+ if (acquireThreadLock(dir, threadId, Date.now())) {
300
+ try {
301
+ return fn();
302
+ }
303
+ finally {
304
+ releaseThreadLock(dir, threadId);
305
+ }
306
+ }
307
+ if (Date.now() >= deadline)
308
+ return undefined;
309
+ await sleep(25);
310
+ }
311
+ }
312
+ // fs.open with "wx" lives behind openSync's flag form; keep it tiny and local.
313
+ function openExclusive(file) {
314
+ return openSync(file, 'wx');
315
+ }
316
+ function writeSyncClose(fd, text) {
317
+ try {
318
+ writeSync(fd, text, null, 'utf8');
319
+ }
320
+ finally {
321
+ closeSync(fd);
322
+ }
323
+ }
172
324
  //# sourceMappingURL=outbox.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../src/outbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"outbox.js","sourceRoot":"","sources":["../src/outbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,74 @@
1
+ import { appendFileSync, closeSync, mkdirSync, openSync, readSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ import process from 'node:process';
5
+ import { findRolloutFile } from './codex/rollout-meta.js';
6
+ /**
7
+ * Sender-side send log (B14, F4): every send's final outcome is appended as
8
+ * one JSON line so a delivery whose CLI invocation already returned (tool
9
+ * timeout → background continuation) stays observable after the fact, and a
10
+ * codex delivery is confirmed against the target's rollout file — turning
11
+ * "delivered" from "the server accepted the turn" into "the message is
12
+ * verifiably in the recipient's conversation history". Metadata only; no
13
+ * message bodies are ever written here.
14
+ */
15
+ export function defaultSendLogFile() {
16
+ return join(process.env.LOCALAPPDATA ?? homedir(), 'crosschat', 'send-log.jsonl');
17
+ }
18
+ export function appendSendLog(file, entry) {
19
+ try {
20
+ mkdirSync(dirname(file), { recursive: true });
21
+ appendFileSync(file, `${JSON.stringify(entry)}\n`, 'utf8');
22
+ }
23
+ catch {
24
+ // ponytail: observability must never break the send itself.
25
+ }
26
+ }
27
+ const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
28
+ /**
29
+ * Poll the recipient thread's rollout file until the marker (the unique
30
+ * reply-ref embedded in every envelope) shows up — the receipt. The rollout
31
+ * write can lag turn/start acceptance by a moment, hence the short retry.
32
+ * Never throws; 'unconfirmed' means "not seen within the budget", not "lost".
33
+ */
34
+ export async function confirmInRollout(codexHome, threadId, marker, opts = {}) {
35
+ const tries = opts.tries ?? 5;
36
+ const delayMs = opts.delayMs ?? 300;
37
+ for (let attempt = 0; attempt < tries; attempt++) {
38
+ const file = findRolloutFile(codexHome, threadId);
39
+ if (file !== undefined && fileContains(file, marker))
40
+ return 'confirmed';
41
+ await sleep(delayMs);
42
+ }
43
+ return 'unconfirmed';
44
+ }
45
+ /** Chunked substring scan; carries a tail so a marker spanning chunks is found. */
46
+ function fileContains(path, marker) {
47
+ let fd;
48
+ try {
49
+ fd = openSync(path, 'r');
50
+ }
51
+ catch {
52
+ return false;
53
+ }
54
+ try {
55
+ const buf = Buffer.alloc(64 * 1024);
56
+ let carry = '';
57
+ for (;;) {
58
+ const n = readSync(fd, buf, 0, buf.length, null);
59
+ if (n <= 0)
60
+ return false;
61
+ const text = carry + buf.subarray(0, n).toString('utf8');
62
+ if (text.includes(marker))
63
+ return true;
64
+ carry = text.slice(Math.max(0, text.length - marker.length));
65
+ }
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ finally {
71
+ closeSync(fd);
72
+ }
73
+ }
74
+ //# sourceMappingURL=send-log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"send-log.js","sourceRoot":"","sources":["../src/send-log.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,104 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import process from 'node:process';
5
+ import { drain, outboxSummary } from './outbox.js';
6
+ /**
7
+ * Detached outbox watchdog (B12): the 2026-10-02 incident showed parked
8
+ * messages starve unless some CLI call happens to run while the target thread
9
+ * is idle. After any park, send spawns `crosschat __drain --watch` detached;
10
+ * it retries with backoff until the outbox empties, then exits. Single
11
+ * instance via a pid+timestamp lockfile in the outbox dir (no resident
12
+ * daemon: the process only lives while work is pending).
13
+ */
14
+ export const WATCHDOG_BACKOFF_STEPS_MS = [30_000, 60_000, 120_000, 300_000];
15
+ /** Backoff after N consecutive empty-handed rounds; any delivery resets it. */
16
+ export function nextBackoffMs(consecutiveEmptyRounds) {
17
+ const index = Math.min(Math.max(consecutiveEmptyRounds, 0), WATCHDOG_BACKOFF_STEPS_MS.length - 1);
18
+ return WATCHDOG_BACKOFF_STEPS_MS[index];
19
+ }
20
+ const WATCHDOG_LOCK = 'watchdog.lock';
21
+ /** Heartbeat freshness; a holder without a heartbeat is considered dead. */
22
+ const WATCHDOG_STALE_MS = 90_000;
23
+ export function watchdogStatus(outboxDir, nowMs = Date.now()) {
24
+ try {
25
+ const [pidText, tsText] = readFileSync(join(outboxDir, WATCHDOG_LOCK), 'utf8').trim().split(/\s+/);
26
+ const pid = Number(pidText);
27
+ const ts = Number(tsText);
28
+ if (!Number.isFinite(ts))
29
+ return { running: false };
30
+ if (nowMs - ts < WATCHDOG_STALE_MS)
31
+ return { running: true, pid: Number.isFinite(pid) ? pid : undefined };
32
+ if (Number.isFinite(pid) && pid > 0) {
33
+ try {
34
+ process.kill(pid, 0); // throws when the pid is gone
35
+ return { running: true, pid };
36
+ }
37
+ catch {
38
+ /* stale and dead */
39
+ }
40
+ }
41
+ }
42
+ catch {
43
+ /* no lock file */
44
+ }
45
+ return { running: false };
46
+ }
47
+ /**
48
+ * Best-effort spawn of the detached watchdog loop; never throws and never
49
+ * spawns a second instance while one is alive. No-op under vitest so tests
50
+ * cannot leak background processes.
51
+ */
52
+ export function spawnWatchdog(outboxDir) {
53
+ if (watchdogStatus(outboxDir).running)
54
+ return;
55
+ const entry = process.argv[1];
56
+ if (entry === undefined || entry.includes('vitest'))
57
+ return;
58
+ try {
59
+ const child = spawn(process.execPath, [entry, '__drain', '--watch'], {
60
+ detached: true,
61
+ stdio: 'ignore',
62
+ windowsHide: true,
63
+ });
64
+ child.unref();
65
+ }
66
+ catch {
67
+ // ponytail: watchdog is liveness relief, not correctness; the next send retries the spawn.
68
+ }
69
+ }
70
+ /** The watchdog loop itself; returns when the outbox is empty. Never throws. */
71
+ export async function runWatchdog(outboxDir, rateDir, deps) {
72
+ const sleep = deps.sleep ?? ((ms) => new Promise((resolve) => setTimeout(resolve, ms)));
73
+ try {
74
+ mkdirSync(outboxDir, { recursive: true });
75
+ writeFileSync(join(outboxDir, WATCHDOG_LOCK), `${process.pid} ${Date.now()}`, 'utf8');
76
+ let emptyRounds = 0;
77
+ for (;;) {
78
+ const results = await drain(outboxDir, (threadId, content, busyTimeoutMs) => deps.deliverCodex(threadId, content, busyTimeoutMs), { rateDir });
79
+ const delivered = results.reduce((total, result) => total + result.delivered, 0);
80
+ const dropped = results.reduce((total, result) => total + result.dropped, 0);
81
+ if (delivered > 0)
82
+ deps.err(`watchdog: 补投 ${delivered} 条`);
83
+ if (dropped > 0)
84
+ deps.err(`watchdog: 线程已不存在,丢弃 ${dropped} 条`);
85
+ if (outboxSummary(outboxDir).every((thread) => thread.count === 0))
86
+ break;
87
+ writeFileSync(join(outboxDir, WATCHDOG_LOCK), `${process.pid} ${Date.now()}`, 'utf8'); // heartbeat
88
+ await sleep(nextBackoffMs(emptyRounds));
89
+ emptyRounds = delivered > 0 ? 0 : emptyRounds + 1;
90
+ }
91
+ }
92
+ catch {
93
+ // Never throw out of the detached loop; the next park re-spawns a fresh watchdog.
94
+ }
95
+ finally {
96
+ try {
97
+ rmSync(join(outboxDir, WATCHDOG_LOCK), { force: true });
98
+ }
99
+ catch {
100
+ /* already gone */
101
+ }
102
+ }
103
+ }
104
+ //# sourceMappingURL=watchdog.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watchdog.js","sourceRoot":"","sources":["../src/watchdog.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oatelauser/crosschat",
3
- "version": "1.0.1",
3
+ "version": "1.1.0",
4
4
  "type": "module",
5
5
  "description": "Let Claude Code and Codex CLI talk to each other on your machine: native delivery via named pipe and app-server, stateless CLI, no daemon.",
6
6
  "repository": {
@@ -9,8 +9,7 @@
9
9
  },
10
10
  "license": "MIT",
11
11
  "bin": {
12
- "crosschat": "dist/cli.js",
13
- "multichat": "dist/cli.js"
12
+ "crosschat": "dist/cli.js"
14
13
  },
15
14
  "engines": {
16
15
  "node": ">=22"