@tinycloud/cli 1.3.0-beta.48 → 1.3.0-beta.49

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.
@@ -4,10 +4,10 @@ var EXT = "https://tinycloud.xyz/ext/courier/v0";
4
4
  var DEFAULT_HOST = "https://tee.node.tinycloud.xyz";
5
5
  var COURIER_SPACE = "agents";
6
6
  var AGENT_GRANT_EXPIRY = "30d";
7
- var kv = (path18, actions) => ({
7
+ var kv = (path20, actions) => ({
8
8
  service: "tinycloud.kv",
9
9
  space: COURIER_SPACE,
10
- path: `${PREFIX}/${path18}`,
10
+ path: `${PREFIX}/${path20}`,
11
11
  actions: actions.map((action) => `tinycloud.kv/${action}`)
12
12
  });
13
13
  var AGENT_GRANT = [
@@ -416,6 +416,30 @@ function errInfo(e) {
416
416
  message: String(anyE.message ?? e).slice(0, 400)
417
417
  };
418
418
  }
419
+ var TRANSIENT_CODES = ["NETWORK_ERROR", "ECONNRESET", "ETIMEDOUT"];
420
+ function fieldOf(source, name2) {
421
+ return typeof source === "object" && source !== null ? Reflect.get(source, name2) : void 0;
422
+ }
423
+ function asStatus(value2) {
424
+ const n = typeof value2 === "string" && /^\d{3}$/.test(value2) ? Number(value2) : value2;
425
+ return typeof n === "number" && Number.isInteger(n) ? n : void 0;
426
+ }
427
+ function httpStatuses(error) {
428
+ return [fieldOf(error, "status"), fieldOf(fieldOf(error, "meta"), "status"), fieldOf(error, "code")].map(asStatus).filter((s) => s !== void 0);
429
+ }
430
+ function isPreconditionError(error) {
431
+ return fieldOf(error, "code") === "KV_PRECONDITION_FAILED" || httpStatuses(error).includes(412);
432
+ }
433
+ function isNotFoundError(error) {
434
+ return fieldOf(error, "code") === "KV_NOT_FOUND" || httpStatuses(error).includes(404);
435
+ }
436
+ function isTransientError(error) {
437
+ if (httpStatuses(error).some((s) => s >= 500 && s <= 599))
438
+ return true;
439
+ const code = fieldOf(error, "code");
440
+ const causeCode = fieldOf(fieldOf(error, "cause"), "code");
441
+ return TRANSIENT_CODES.some((c) => c === code || c === causeCode);
442
+ }
419
443
  function unwrap(r, what) {
420
444
  if (r && typeof r === "object" && "ok" in r) {
421
445
  const res = r;
@@ -569,7 +593,6 @@ function defer() {
569
593
 
570
594
  // ../courier/dist/store.js
571
595
  var FULL = { prefix: "" };
572
- var TRANSIENT = /fetch failed|NETWORK_ERROR|ECONNRESET|ETIMEDOUT|5\d\d/i;
573
596
  async function nap(ms2) {
574
597
  const { promise, resolve } = defer();
575
598
  setTimeout(resolve, ms2);
@@ -582,8 +605,7 @@ async function readRetry(fn) {
582
605
  const r = await fn();
583
606
  const res = r;
584
607
  if (res && typeof res === "object" && res.ok === false) {
585
- const m = `${res.error?.code ?? ""} ${res.error?.message ?? ""}`;
586
- if (TRANSIENT.test(m) && i < 2) {
608
+ if (isTransientError(res.error) && i < 2) {
587
609
  await nap(1500);
588
610
  continue;
589
611
  }
@@ -591,7 +613,8 @@ async function readRetry(fn) {
591
613
  return r;
592
614
  } catch (e) {
593
615
  last = e;
594
- if (!TRANSIENT.test(String(e.message ?? e)) || i === 2)
616
+ const undiciFetchFailure = e instanceof Error && e.message === "fetch failed";
617
+ if (!(isTransientError(e) || undiciFetchFailure) || i === 2)
595
618
  throw e;
596
619
  await nap(1500);
597
620
  }
@@ -607,7 +630,7 @@ async function putCreate(kv2, key, value2) {
607
630
  try {
608
631
  return putEtag(unwrap(r, `put ${key}`));
609
632
  } catch (e) {
610
- if (e instanceof CourierError && (e.code === "412" || /412|conflict|precondition/i.test(e.message))) {
633
+ if (e instanceof CourierError && r.ok === false && isPreconditionError(r.error)) {
611
634
  throw new CourierError("conflict", `${key} already exists (create-only write)`);
612
635
  }
613
636
  throw e;
@@ -618,7 +641,7 @@ async function putMatch(kv2, key, value2, etag) {
618
641
  try {
619
642
  return putEtag(unwrap(r, `put ${key}`));
620
643
  } catch (e) {
621
- if (e instanceof CourierError && (e.code === "412" || /412|conflict|precondition/i.test(e.message))) {
644
+ if (e instanceof CourierError && r.ok === false && isPreconditionError(r.error)) {
622
645
  throw new CourierError("conflict", `${key} changed under us; re-read and retry`);
623
646
  }
624
647
  throw e;
@@ -627,11 +650,10 @@ async function putMatch(kv2, key, value2, etag) {
627
650
  async function getJson(kv2, key) {
628
651
  const r = await readRetry(() => kv2.get(key, FULL));
629
652
  if (r && typeof r === "object" && "ok" in r && !r.ok) {
630
- const status = r.error?.status ?? r.error?.meta?.status ?? r.error?.code;
631
653
  if (/space not found/i.test(String(r.error?.message))) {
632
654
  throw new CourierError("no-space", String(r.error?.message));
633
655
  }
634
- if (status === 404 || String(status) === "404" || /not.found/i.test(String(r.error?.message)))
656
+ if (isNotFoundError(r.error))
635
657
  return void 0;
636
658
  unwrap(r, `get ${key}`);
637
659
  }
@@ -747,7 +769,7 @@ async function commitReceipts(selfKv, pending) {
747
769
  await putCreate(selfKv, key, receipts);
748
770
  break;
749
771
  } catch (error) {
750
- const conflict = /conflict|412|precondition/i.test(`${errInfo(error).code ?? ""} ${errInfo(error).message}`);
772
+ const conflict = error instanceof CourierError && error.code === "conflict";
751
773
  if (conflict && attempt < 2)
752
774
  continue;
753
775
  console.error(`warning: could not advance receipts for ${peer}: ${errInfo(error).message}`);
@@ -804,7 +826,7 @@ function authorityTuples(entries) {
804
826
  return tuples;
805
827
  }
806
828
  function renderTuples(tuples) {
807
- const shown = tuples.slice(0, 3).map(({ service, space, path: path18, action }) => `${service} ${space} ${path18 || '""'} ${action}`);
829
+ const shown = tuples.slice(0, 3).map(({ service, space, path: path20, action }) => `${service} ${space} ${path20 || '""'} ${action}`);
808
830
  if (tuples.length > 3)
809
831
  shown.push(`(+${tuples.length - 3} more)`);
810
832
  return shown.join("; ");
@@ -1943,13 +1965,13 @@ function contentReason(value2, field) {
1943
1965
  return "not-nfc";
1944
1966
  return void 0;
1945
1967
  }
1946
- function textVerdict(value2, field) {
1968
+ function textVerdict(value2, field, maxUnits) {
1947
1969
  let reason;
1948
1970
  if (typeof value2 !== "string")
1949
1971
  reason = "not-string";
1950
1972
  else if (value2.length === 0)
1951
1973
  reason = "empty";
1952
- else if (value2.length > (field === "multiline" ? MAX_ACTION : MAX_SUMMARY))
1974
+ else if (value2.length > (maxUnits ?? (field === "multiline" ? MAX_ACTION : MAX_SUMMARY)))
1953
1975
  reason = "too-long";
1954
1976
  else if (field !== "multiline" && (value2.startsWith(" ") || value2.endsWith(" ")))
1955
1977
  reason = "edge-whitespace";
@@ -7362,8 +7384,8 @@ var Watcher = class {
7362
7384
  const prefix = `${PREFIX}/to/${peer.handle}/threads/`;
7363
7385
  const keys = await listAll(this.deps.selfKv, prefix);
7364
7386
  const known = /* @__PURE__ */ new Set();
7365
- for (const path18 of keys) {
7366
- const match = /^([^/]+)\/(?:meta\.json|(?:msg|task)\/[^/]+\.json)$/.exec(path18.slice(prefix.length));
7387
+ for (const path20 of keys) {
7388
+ const match = /^([^/]+)\/(?:meta\.json|(?:msg|task)\/[^/]+\.json)$/.exec(path20.slice(prefix.length));
7367
7389
  if (match && SAFE_ID.test(match[1]))
7368
7390
  known.add(`${peer.handle}/${match[1]}`);
7369
7391
  }
@@ -8976,6 +8998,860 @@ async function cmdWatch(args) {
8976
8998
  }
8977
8999
  }
8978
9000
 
9001
+ // ../courier/dist/intake/intake.js
9002
+ import fs16 from "fs";
9003
+ import path18 from "path";
9004
+
9005
+ // ../courier/dist/intake/flags.js
9006
+ var FLAG_TABLE = {
9007
+ "too-long": { severity: "tiered", description: "text is over 8000 UTF-16 units; the text is still queued" },
9008
+ link: { severity: "soft", description: "a URL-like string is present" },
9009
+ instruction: { severity: "soft", description: "matches the fixed instruction-phrase table" },
9010
+ request: { severity: "soft", description: "asks the reader or its principal to take an action (fixed verb-phrase table)" },
9011
+ "secret-request": { severity: "hard", description: "asks for keys, tokens, passwords or credentials" },
9012
+ encoded: { severity: "hard", description: "a long base64- or hex-looking run is present" },
9013
+ unicode: { severity: "hard", description: "shared text verdict: not-nfc, disallowed-code-point, edge-whitespace, not-string or empty" },
9014
+ size: { severity: "hard", description: "original text exceeded the 16 KiB queue cap and was cut at a code-point boundary" },
9015
+ rate: { severity: "hard", description: "peer is over its inbound per-hour cap" }
9016
+ };
9017
+
9018
+ // ../courier/dist/intake/peers.js
9019
+ import fs14 from "fs";
9020
+ var DEFAULT_IN_PER_HOUR = 100;
9021
+ var DEFAULT_OUT_PER_HOUR = 100;
9022
+ var KEYS = { tier: true, ratePerHour: true, outPerHour: true };
9023
+ var TIERS = { trusted: true, strict: true };
9024
+ var ABSENT = { tier: "strict", ratePerHour: DEFAULT_IN_PER_HOUR, outPerHour: DEFAULT_OUT_PER_HOUR };
9025
+ function cap(value2, fallback) {
9026
+ if (value2 === void 0)
9027
+ return fallback;
9028
+ if (!Number.isInteger(value2) || value2 < 1 || value2 > fallback)
9029
+ return void 0;
9030
+ return value2;
9031
+ }
9032
+ function parseEntry(value2) {
9033
+ if (!isRecord(value2))
9034
+ return void 0;
9035
+ if (Object.keys(value2).some((key) => !Object.hasOwn(KEYS, key)))
9036
+ return void 0;
9037
+ const tier = value2.tier ?? "strict";
9038
+ if (typeof tier !== "string" || !Object.hasOwn(TIERS, tier))
9039
+ return void 0;
9040
+ const ratePerHour = cap(value2.ratePerHour, DEFAULT_IN_PER_HOUR);
9041
+ const outPerHour = cap(value2.outPerHour, DEFAULT_OUT_PER_HOUR);
9042
+ if (ratePerHour === void 0 || outPerHour === void 0)
9043
+ return void 0;
9044
+ return { tier, ratePerHour, outPerHour };
9045
+ }
9046
+ function loadPeers(path20, ownerUid = process.getuid?.()) {
9047
+ let fd;
9048
+ try {
9049
+ fd = fs14.openSync(path20, fs14.constants.O_RDONLY | fs14.constants.O_NOFOLLOW);
9050
+ } catch (error) {
9051
+ const code = error.code;
9052
+ if (code === "ENOENT")
9053
+ return /* @__PURE__ */ Object.create(null);
9054
+ if (code === "ELOOP")
9055
+ throw new CourierError("insecure-peers", `${path20} is a symbolic link; point the flag at the file itself.`);
9056
+ throw error;
9057
+ }
9058
+ try {
9059
+ const stat = fs14.fstatSync(fd);
9060
+ if (!stat.isFile())
9061
+ throw new CourierError("insecure-peers", `${path20} is not a regular file.`);
9062
+ if (ownerUid !== void 0 && stat.uid !== ownerUid)
9063
+ throw new CourierError("insecure-peers", `${path20} is not owned by the courier user.`);
9064
+ if ((stat.mode & 18) !== 0) {
9065
+ throw new CourierError("insecure-peers", `${path20} is writable by group or others; restrict it to the owner (chmod 600).`);
9066
+ }
9067
+ const parsed = JSON.parse(fs14.readFileSync(fd, "utf8"));
9068
+ if (!isRecord(parsed))
9069
+ throw new CourierError("bad-peers", `${path20} must be a JSON object keyed by peer id.`);
9070
+ const peers = /* @__PURE__ */ Object.create(null);
9071
+ for (const [peerId, value2] of Object.entries(parsed)) {
9072
+ const policy = parseEntry(value2);
9073
+ if (!policy)
9074
+ throw new CourierError("bad-peers", `${path20} has an invalid policy for peer "${peerId}"; fix the entry. Nothing was loaded.`);
9075
+ peers[peerId] = policy;
9076
+ }
9077
+ return peers;
9078
+ } finally {
9079
+ fs14.closeSync(fd);
9080
+ }
9081
+ }
9082
+ function policyOf(peers, peerId) {
9083
+ return Object.hasOwn(peers, peerId) ? peers[peerId] : { ...ABSENT };
9084
+ }
9085
+
9086
+ // ../courier/dist/intake/queue.js
9087
+ import fs15 from "fs";
9088
+ import path17 from "path";
9089
+ import { randomBytes as randomBytes3 } from "crypto";
9090
+ function ensureRealDir(dir, mode) {
9091
+ let existed = true;
9092
+ try {
9093
+ fs15.lstatSync(dir);
9094
+ } catch (error) {
9095
+ if (error.code !== "ENOENT")
9096
+ throw error;
9097
+ existed = false;
9098
+ }
9099
+ fs15.mkdirSync(dir, { recursive: true, mode });
9100
+ const stat = fs15.lstatSync(dir);
9101
+ if (stat.isSymbolicLink() || !stat.isDirectory()) {
9102
+ throw new CourierError("unsafe-dir", "queue or state path is not a real directory");
9103
+ }
9104
+ if (!existed && stat.uid === process.getuid?.() && (stat.mode & 4095) !== mode)
9105
+ fs15.chmodSync(dir, mode);
9106
+ }
9107
+ function fsyncDir(dir) {
9108
+ const fd = fs15.openSync(dir, "r");
9109
+ try {
9110
+ fs15.fsyncSync(fd);
9111
+ } finally {
9112
+ fs15.closeSync(fd);
9113
+ }
9114
+ }
9115
+ function writeTemp(dir, name2, body, mode) {
9116
+ const temp = path17.join(dir, `.${name2}.${randomBytes3(6).toString("hex")}.tmp`);
9117
+ const fd = fs15.openSync(temp, "wx", mode);
9118
+ try {
9119
+ fs15.writeFileSync(fd, body);
9120
+ fs15.fchmodSync(fd, mode);
9121
+ fs15.fsyncSync(fd);
9122
+ } catch (error) {
9123
+ fs15.closeSync(fd);
9124
+ fs15.rmSync(temp, { force: true });
9125
+ throw error;
9126
+ }
9127
+ fs15.closeSync(fd);
9128
+ return temp;
9129
+ }
9130
+ function writeNew(dir, name2, body, mode) {
9131
+ const temp = writeTemp(dir, name2, body, mode);
9132
+ try {
9133
+ fs15.linkSync(temp, path17.join(dir, name2));
9134
+ fsyncDir(dir);
9135
+ return true;
9136
+ } catch (error) {
9137
+ if (error.code === "EEXIST")
9138
+ return false;
9139
+ throw error;
9140
+ } finally {
9141
+ fs15.rmSync(temp, { force: true });
9142
+ }
9143
+ }
9144
+ function writeReplace(dir, name2, body, mode) {
9145
+ const target2 = path17.join(dir, name2);
9146
+ try {
9147
+ if (!fs15.lstatSync(target2).isFile())
9148
+ throw new CourierError("unsafe-target", "refusing to replace a non-regular file");
9149
+ } catch (error) {
9150
+ if (error.code !== "ENOENT")
9151
+ throw error;
9152
+ }
9153
+ const temp = writeTemp(dir, name2, body, mode);
9154
+ try {
9155
+ fs15.renameSync(temp, target2);
9156
+ fsyncDir(dir);
9157
+ } catch (error) {
9158
+ fs15.rmSync(temp, { force: true });
9159
+ throw error;
9160
+ }
9161
+ }
9162
+ function parseRecord(text) {
9163
+ if (/^\d+\n?$/.test(text)) {
9164
+ const pid = Number(text);
9165
+ return Number.isInteger(pid) && pid > 0 ? { pid, nonce: text } : void 0;
9166
+ }
9167
+ try {
9168
+ const value2 = JSON.parse(text);
9169
+ if (typeof value2 !== "object" || value2 === null)
9170
+ return void 0;
9171
+ const { pid, nonce } = value2;
9172
+ if (typeof pid !== "number" || !Number.isInteger(pid) || pid <= 0)
9173
+ return void 0;
9174
+ if (typeof nonce !== "string" || nonce.length === 0)
9175
+ return void 0;
9176
+ return { pid, nonce };
9177
+ } catch {
9178
+ return void 0;
9179
+ }
9180
+ }
9181
+ function recordBody(record) {
9182
+ return `${JSON.stringify({ pid: record.pid, nonce: record.nonce })}
9183
+ `;
9184
+ }
9185
+ function readRecordFile(file) {
9186
+ try {
9187
+ return parseRecord(fs15.readFileSync(file, "utf8"));
9188
+ } catch {
9189
+ return void 0;
9190
+ }
9191
+ }
9192
+ function readLock(file) {
9193
+ let text;
9194
+ try {
9195
+ text = fs15.readFileSync(file, "utf8");
9196
+ } catch (error) {
9197
+ if (error.code === "ENOENT")
9198
+ return { kind: "missing" };
9199
+ throw error;
9200
+ }
9201
+ const record = parseRecord(text);
9202
+ return record ? { kind: "held", record } : { kind: "corrupt" };
9203
+ }
9204
+ function pidAlive2(pid) {
9205
+ try {
9206
+ process.kill(pid, 0);
9207
+ return true;
9208
+ } catch (error) {
9209
+ return error.code === "EPERM";
9210
+ }
9211
+ }
9212
+ var MAX_BREAK_GUARDS = 8;
9213
+ function acquireLock(file, opts = {}) {
9214
+ const dir = path17.dirname(file);
9215
+ const name2 = path17.basename(file);
9216
+ const alive = opts.alive ?? pidAlive2;
9217
+ const self2 = { pid: opts.pid ?? process.pid, nonce: randomBytes3(6).toString("hex") };
9218
+ for (let attempt = 0; attempt < 3; attempt++) {
9219
+ if (writeNew(dir, name2, recordBody(self2), 384)) {
9220
+ return () => {
9221
+ const current = readLock(file);
9222
+ if (current.kind === "held" && current.record.nonce === self2.nonce)
9223
+ fs15.rmSync(file, { force: true });
9224
+ };
9225
+ }
9226
+ const seen = readLock(file);
9227
+ if (seen.kind === "missing")
9228
+ continue;
9229
+ if (seen.kind === "corrupt" || alive(seen.record.pid)) {
9230
+ throw new CourierError("locked", "another courier intake is running");
9231
+ }
9232
+ opts.afterObserve?.();
9233
+ if (!breakDead(file, seen.record, self2, alive)) {
9234
+ throw new CourierError("locked", "another courier intake is running");
9235
+ }
9236
+ }
9237
+ throw new CourierError("locked", "another courier intake is running");
9238
+ }
9239
+ function breakDead(file, stale, self2, alive) {
9240
+ const dir = path17.dirname(file);
9241
+ const tag = `${path17.basename(file)}.break.${stale.nonce.trim().replace(/[^A-Za-z0-9_-]/g, "_")}.`;
9242
+ const body = recordBody(self2);
9243
+ let claimed = false;
9244
+ for (let k2 = 1; k2 <= MAX_BREAK_GUARDS && !claimed; k2++) {
9245
+ const candidate = `${tag}${k2}`;
9246
+ if (writeNew(dir, candidate, body, 384)) {
9247
+ claimed = true;
9248
+ break;
9249
+ }
9250
+ const holder = readRecordFile(path17.join(dir, candidate));
9251
+ if (holder && alive(holder.pid))
9252
+ return false;
9253
+ }
9254
+ if (!claimed)
9255
+ return false;
9256
+ try {
9257
+ const now = readLock(file);
9258
+ if (now.kind === "held" && now.record.nonce === stale.nonce)
9259
+ fs15.rmSync(file, { force: true });
9260
+ return true;
9261
+ } finally {
9262
+ for (const entry of fs15.readdirSync(dir)) {
9263
+ if (entry.startsWith(tag))
9264
+ fs15.rmSync(path17.join(dir, entry), { force: true });
9265
+ }
9266
+ }
9267
+ }
9268
+ function emptyState() {
9269
+ return { v: 1, peers: /* @__PURE__ */ Object.create(null) };
9270
+ }
9271
+ function readState(file) {
9272
+ let raw;
9273
+ try {
9274
+ raw = fs15.readFileSync(file, "utf8");
9275
+ } catch (error) {
9276
+ if (error.code === "ENOENT")
9277
+ return emptyState();
9278
+ throw error;
9279
+ }
9280
+ let parsed;
9281
+ try {
9282
+ parsed = JSON.parse(raw);
9283
+ } catch {
9284
+ throw new CourierError("bad-state", "intake state is not valid JSON");
9285
+ }
9286
+ if (!isRecord(parsed) || parsed.v !== 1 || !isRecord(parsed.peers))
9287
+ throw new CourierError("bad-state", "intake state has an unknown shape");
9288
+ const peers = /* @__PURE__ */ Object.create(null);
9289
+ for (const [peerId, entry] of Object.entries(parsed.peers)) {
9290
+ if (!isRecord(entry) || !Array.isArray(entry.receipts) || entry.cursor !== void 0 && typeof entry.cursor !== "string") {
9291
+ throw new CourierError("bad-state", "intake state has an unknown shape");
9292
+ }
9293
+ const peer = { receipts: entry.receipts.map(readReceipt) };
9294
+ if (typeof entry.cursor === "string")
9295
+ peer.cursor = entry.cursor;
9296
+ peers[peerId] = peer;
9297
+ }
9298
+ return { v: 1, peers };
9299
+ }
9300
+ function readReceipt(raw, index) {
9301
+ if (typeof raw === "number")
9302
+ return { id: `legacy-${index}`, at: raw };
9303
+ if (isRecord(raw) && typeof raw.id === "string" && typeof raw.at === "number")
9304
+ return { id: raw.id, at: raw.at };
9305
+ throw new CourierError("bad-state", "intake state has an unknown shape");
9306
+ }
9307
+ function writeState(dir, file, state) {
9308
+ writeReplace(dir, path17.basename(file), `${JSON.stringify(state)}
9309
+ `, 384);
9310
+ }
9311
+
9312
+ // ../courier/dist/intake/intake.js
9313
+ var STATE_FILE = "intake-state.json";
9314
+ var LOCK_FILE = "intake.lock";
9315
+ var HOUR_MS = 60 * 6e4;
9316
+ var DAY_MS3 = 24 * HOUR_MS;
9317
+ var MAX_SKEW_MS = 10 * 6e4;
9318
+ var STALE_MS = 7 * DAY_MS3;
9319
+ var DONE_TTL_MS = 14 * DAY_MS3;
9320
+ var OVERFLOW_TTL_MS = STALE_MS;
9321
+ var OVERFLOW_MAX_FILES = 200;
9322
+ var OVERFLOW_MAX_BYTES = 1024 * 1024;
9323
+ var MIRROR_BATCH = 200;
9324
+ var JANITOR_BATCH = 500;
9325
+ var RATE_WINDOW_MS = HOUR_MS;
9326
+ var MAX_QUEUE_CHARS = 8e3;
9327
+ var MAX_QUEUE_BYTES = 16 * 1024;
9328
+ var RATE_TEXT = "This peer went over its inbound rate limit; further messages this hour are held outside the queue.";
9329
+ var ULID_RE = /^[0-7][0-9A-HJKMNP-TV-Z]{25}$/;
9330
+ var SAFE_ID2 = /^[0-9A-Za-z_-]{1,64}$/;
9331
+ var MSG_KEY2 = /\/threads\/([^/]+)\/msg\/([^/]+)\.json$/;
9332
+ var LINK = /(?:https?|ftp):\/\/|\bwww\.[a-z0-9-]+\./i;
9333
+ var ENCODED = /[A-Za-z0-9+\/=]{64,}/;
9334
+ var REQUEST = /(?:^|[.!?\n]\s*|\bplease\s+)(?:run|merge|send|open|forward|delete|reveal|deploy)\b/i;
9335
+ var SECRET_REQUEST = /\b(?:share|send|give|paste|reveal|tell|show|post)\b[^.!?\n]{0,40}\b(?:keys?|tokens?|passwords?|credentials?|secrets?|seed phrase)\b/i;
9336
+ var INSTRUCTION_PHRASES = [
9337
+ "ignore previous",
9338
+ "ignore all previous",
9339
+ "disregard previous",
9340
+ "forget your instructions",
9341
+ "you are now",
9342
+ "new instructions",
9343
+ "system prompt",
9344
+ "override your"
9345
+ ];
9346
+ function capUtf8(text, maxBytes) {
9347
+ if (Buffer.byteLength(text, "utf8") <= maxBytes)
9348
+ return { text, truncated: false };
9349
+ let out = "";
9350
+ let bytes = 0;
9351
+ for (const ch of text) {
9352
+ const n = Buffer.byteLength(ch, "utf8");
9353
+ if (bytes + n > maxBytes)
9354
+ break;
9355
+ out += ch;
9356
+ bytes += n;
9357
+ }
9358
+ return { text: out, truncated: true };
9359
+ }
9360
+ function flagsFor(input) {
9361
+ const found = /* @__PURE__ */ new Set();
9362
+ if (!input.verdict.allowed && input.verdict.reason === "too-long")
9363
+ found.add("too-long");
9364
+ if (hiddenTextProblem(input.text, true) || !input.verdict.allowed && input.verdict.reason !== "too-long")
9365
+ found.add("unicode");
9366
+ const lower = input.text.toLowerCase();
9367
+ if (LINK.test(input.text))
9368
+ found.add("link");
9369
+ if (INSTRUCTION_PHRASES.some((phrase) => lower.includes(phrase)))
9370
+ found.add("instruction");
9371
+ if (REQUEST.test(input.text))
9372
+ found.add("request");
9373
+ if (SECRET_REQUEST.test(input.text))
9374
+ found.add("secret-request");
9375
+ if (ENCODED.test(input.text))
9376
+ found.add("encoded");
9377
+ if (input.overRate)
9378
+ found.add("rate");
9379
+ if (input.truncated)
9380
+ found.add("size");
9381
+ return Object.keys(FLAG_TABLE).filter((flag) => found.has(flag));
9382
+ }
9383
+ function admit(receipts, id, at, cap2) {
9384
+ const recent = receipts.filter((r) => r.at > at - RATE_WINDOW_MS);
9385
+ if (recent.length >= cap2)
9386
+ return { admitted: false, remaining: 0, receipts: recent.slice(-cap2) };
9387
+ return { admitted: true, remaining: cap2 - recent.length - 1, receipts: [...recent, { id, at }].slice(-cap2) };
9388
+ }
9389
+ var reconciledPeers = /* @__PURE__ */ new WeakMap();
9390
+ function reconciledSet(state) {
9391
+ let set = reconciledPeers.get(state);
9392
+ if (!set) {
9393
+ set = /* @__PURE__ */ new Set();
9394
+ reconciledPeers.set(state, set);
9395
+ }
9396
+ return set;
9397
+ }
9398
+ function reconcileReceipts(input, peer, receipts, cap2) {
9399
+ const now = input.now();
9400
+ const byId = /* @__PURE__ */ new Map();
9401
+ for (const r of receipts)
9402
+ if (!byId.has(r.id))
9403
+ byId.set(r.id, r);
9404
+ for (const root of [input.queueRoot, input.doneRoot]) {
9405
+ const dir = path18.join(root, peer);
9406
+ let names;
9407
+ try {
9408
+ names = fs16.readdirSync(dir);
9409
+ } catch (error) {
9410
+ if (error.code === "ENOENT")
9411
+ continue;
9412
+ throw error;
9413
+ }
9414
+ for (const name2 of names) {
9415
+ if (!name2.endsWith(".json"))
9416
+ continue;
9417
+ const id = name2.slice(0, -".json".length);
9418
+ if (!ULID_RE.test(id) || byId.has(id))
9419
+ continue;
9420
+ const file = path18.join(dir, name2);
9421
+ let stat;
9422
+ try {
9423
+ stat = fs16.lstatSync(file);
9424
+ } catch {
9425
+ continue;
9426
+ }
9427
+ if (!stat.isFile() || stat.mtimeMs < now - RATE_WINDOW_MS - 6e4)
9428
+ continue;
9429
+ let record;
9430
+ try {
9431
+ record = JSON.parse(fs16.readFileSync(file, "utf8"));
9432
+ } catch {
9433
+ continue;
9434
+ }
9435
+ if (!isRecord(record) || typeof record.receivedAt !== "string")
9436
+ continue;
9437
+ const at = Date.parse(record.receivedAt);
9438
+ if (Number.isFinite(at))
9439
+ byId.set(id, { id, at });
9440
+ }
9441
+ }
9442
+ return [...byId.values()].filter((r) => r.at > now - RATE_WINDOW_MS).sort((a, b) => a.at - b.at).slice(-cap2);
9443
+ }
9444
+ function persist(input, peer) {
9445
+ try {
9446
+ writeState(input.stateDir, path18.join(input.stateDir, STATE_FILE), input.state);
9447
+ } catch (error) {
9448
+ reconciledSet(input.state).delete(peer);
9449
+ throw error;
9450
+ }
9451
+ }
9452
+ function presentIn(input, peer, name2) {
9453
+ for (const root of [input.queueRoot, input.doneRoot, input.overflowRoot]) {
9454
+ try {
9455
+ fs16.lstatSync(path18.join(root, peer, name2));
9456
+ return true;
9457
+ } catch (error) {
9458
+ if (error.code !== "ENOENT")
9459
+ throw error;
9460
+ }
9461
+ }
9462
+ return false;
9463
+ }
9464
+ function pathExists(file) {
9465
+ try {
9466
+ fs16.lstatSync(file);
9467
+ return true;
9468
+ } catch (error) {
9469
+ if (error.code === "ENOENT")
9470
+ return false;
9471
+ throw error;
9472
+ }
9473
+ }
9474
+ function markDone(input, peer, msgId, outcome) {
9475
+ const dir = path18.join(input.doneRoot, peer);
9476
+ ensureRealDir(dir, 448);
9477
+ const marker = { v: 1, msgId, peerId: peer, outcome, markedAt: new Date(input.now()).toISOString() };
9478
+ return writeNew(dir, `${msgId}.json`, `${JSON.stringify(marker)}
9479
+ `, 384);
9480
+ }
9481
+ function mirrorMessages(handle, keys, log) {
9482
+ const messages = [];
9483
+ for (const key of keys) {
9484
+ const match = MSG_KEY2.exec(key);
9485
+ if (!match)
9486
+ continue;
9487
+ const [, threadId, msgId] = match;
9488
+ if (!ULID_RE.test(threadId) || !ULID_RE.test(msgId)) {
9489
+ log("intake-skip", { peer: handle, code: "bad-id" });
9490
+ continue;
9491
+ }
9492
+ messages.push({ key, threadId, msgId });
9493
+ }
9494
+ return messages;
9495
+ }
9496
+ function writeRateRecord(input, peer, senderName, tier, at) {
9497
+ const msgId = `rate-${Math.floor(at / RATE_WINDOW_MS)}`;
9498
+ const dir = path18.join(input.queueRoot, peer);
9499
+ ensureRealDir(dir, 1512);
9500
+ const record = {
9501
+ v: 1,
9502
+ msgId,
9503
+ peerId: peer,
9504
+ threadId: "rate",
9505
+ sender: { id: peer, displayName: senderName },
9506
+ receivedAt: new Date(at).toISOString(),
9507
+ text: RATE_TEXT,
9508
+ cheapChecks: {
9509
+ textVerdict: textVerdict(RATE_TEXT, "multiline", MAX_QUEUE_CHARS),
9510
+ tier,
9511
+ peerRatePerHourRemaining: 0,
9512
+ flags: ["rate"]
9513
+ }
9514
+ };
9515
+ if (presentIn(input, peer, `${msgId}.json`))
9516
+ return false;
9517
+ const created = writeNew(dir, `${msgId}.json`, `${JSON.stringify(record)}
9518
+ `, 416);
9519
+ if (created)
9520
+ input.log("peer-over-rate", { peer, msgId });
9521
+ return created;
9522
+ }
9523
+ function pickBatch(items, cursor, cap2, floor) {
9524
+ if (cap2 < 1)
9525
+ return [];
9526
+ const after = [];
9527
+ const wrapped = [];
9528
+ const insertSorted = (list, item) => {
9529
+ if (list.length === cap2 && item.msgId >= list[cap2 - 1].msgId)
9530
+ return;
9531
+ let i = list.length;
9532
+ while (i > 0 && list[i - 1].msgId > item.msgId)
9533
+ i--;
9534
+ list.splice(i, 0, item);
9535
+ if (list.length > cap2)
9536
+ list.pop();
9537
+ };
9538
+ for (const item of items) {
9539
+ if (item.msgId < floor)
9540
+ continue;
9541
+ if (item.msgId > cursor)
9542
+ insertSorted(after, item);
9543
+ else
9544
+ insertSorted(wrapped, item);
9545
+ }
9546
+ return [...after, ...wrapped].slice(0, cap2);
9547
+ }
9548
+ async function intakePeer(input, peer) {
9549
+ const policy = policyOf(input.peers, peer.handle);
9550
+ const ps = Object.hasOwn(input.state.peers, peer.handle) ? input.state.peers[peer.handle] : { receipts: [] };
9551
+ input.state.peers[peer.handle] = ps;
9552
+ const reconciled = reconciledSet(input.state);
9553
+ if (!reconciled.has(peer.handle)) {
9554
+ ps.receipts = reconcileReceipts(input, peer.handle, ps.receipts, policy.ratePerHour);
9555
+ reconciled.add(peer.handle);
9556
+ }
9557
+ const senderName = typeof peer.label === "string" && textVerdict(peer.label, "summary").allowed ? peer.label : peer.handle;
9558
+ const keys = await listAll(input.kv, `${k.mirrorPrefix}${peer.handle}/threads/`);
9559
+ const all = mirrorMessages(peer.handle, keys, input.log);
9560
+ const cap2 = input.batch ?? MIRROR_BATCH;
9561
+ const floor = encodeTime(input.now() - STALE_MS, 10) + "0".repeat(16);
9562
+ const picked = pickBatch(all, ps.cursor ?? "", cap2, floor);
9563
+ let written = 0;
9564
+ let future = 0;
9565
+ let overflowed = false;
9566
+ try {
9567
+ for (const c of picked) {
9568
+ try {
9569
+ if (presentIn(input, peer.handle, `${c.msgId}.json`))
9570
+ continue;
9571
+ const at = input.now();
9572
+ let sentAt;
9573
+ try {
9574
+ sentAt = decodeTime(c.msgId);
9575
+ } catch {
9576
+ input.log("intake-skip", { peer: peer.handle, code: "bad-id" });
9577
+ markDone(input, peer.handle, c.msgId, "bad-id");
9578
+ continue;
9579
+ }
9580
+ if (sentAt > at + MAX_SKEW_MS) {
9581
+ future++;
9582
+ continue;
9583
+ }
9584
+ const got = await getJson(input.kv, c.key);
9585
+ if (!got || !isRecord(got.value) || got.value.messageId !== c.msgId || got.value.contextId !== c.threadId) {
9586
+ input.log("intake-skip", { peer: peer.handle, code: "mismatch" });
9587
+ markDone(input, peer.handle, c.msgId, "mismatch");
9588
+ continue;
9589
+ }
9590
+ const { admitted, remaining, receipts } = admit(ps.receipts, c.msgId, at, policy.ratePerHour);
9591
+ const parts = Array.isArray(got.value.parts) ? got.value.parts : [];
9592
+ const texts = [];
9593
+ for (const part of parts)
9594
+ if (isRecord(part) && typeof part.text === "string")
9595
+ texts.push(part.text);
9596
+ const text = texts.join("\n");
9597
+ const verdict = textVerdict(text, "multiline", MAX_QUEUE_CHARS);
9598
+ const capped = capUtf8(text, MAX_QUEUE_BYTES);
9599
+ const flags = flagsFor({ text, verdict, overRate: !admitted, truncated: capped.truncated });
9600
+ const record = {
9601
+ v: 1,
9602
+ msgId: c.msgId,
9603
+ peerId: peer.handle,
9604
+ threadId: c.threadId,
9605
+ sender: { id: peer.handle, displayName: senderName },
9606
+ receivedAt: new Date(at).toISOString(),
9607
+ text: capped.text,
9608
+ cheapChecks: { textVerdict: verdict, tier: policy.tier, peerRatePerHourRemaining: remaining, flags }
9609
+ };
9610
+ const body = `${JSON.stringify(record)}
9611
+ `;
9612
+ if (admitted) {
9613
+ const dir = path18.join(input.queueRoot, peer.handle);
9614
+ ensureRealDir(dir, 1512);
9615
+ const name2 = `${c.msgId}.json`;
9616
+ let published;
9617
+ try {
9618
+ published = writeNew(dir, name2, body, 416);
9619
+ } catch (error) {
9620
+ if (pathExists(path18.join(dir, name2)))
9621
+ ps.receipts = receipts;
9622
+ throw error;
9623
+ }
9624
+ if (published) {
9625
+ ps.receipts = receipts;
9626
+ persist(input, peer.handle);
9627
+ written++;
9628
+ input.log("intake-queued", { peer: peer.handle, msgId: c.msgId, tier: policy.tier, flags });
9629
+ }
9630
+ } else {
9631
+ const dir = path18.join(input.overflowRoot, peer.handle);
9632
+ ensureRealDir(dir, 448);
9633
+ writeNew(dir, `${c.msgId}.json`, body, 384);
9634
+ overflowed = true;
9635
+ ps.receipts = receipts;
9636
+ persist(input, peer.handle);
9637
+ if (writeRateRecord(input, peer.handle, senderName, policy.tier, at))
9638
+ written++;
9639
+ }
9640
+ } catch (error) {
9641
+ input.log("intake-error", { peer: peer.handle, msgId: c.msgId, code: errInfo(error).code ?? "error" });
9642
+ }
9643
+ }
9644
+ } finally {
9645
+ if (picked.length > 0)
9646
+ ps.cursor = picked[picked.length - 1].msgId;
9647
+ if (overflowed)
9648
+ capOverflow(input, peer.handle);
9649
+ persist(input, peer.handle);
9650
+ }
9651
+ if (future > 0)
9652
+ input.log("intake-skip", { peer: peer.handle, code: "stale", direction: "future", count: future });
9653
+ return written;
9654
+ }
9655
+ function jsonNames(dir) {
9656
+ return fs16.readdirSync(dir).filter((name2) => name2.endsWith(".json")).sort();
9657
+ }
9658
+ function nameTime(name2) {
9659
+ const base = name2.slice(0, -".json".length);
9660
+ if (ULID_RE.test(base))
9661
+ return decodeTime(base);
9662
+ const rate = /^rate-(\d+)$/.exec(base);
9663
+ return rate ? Number(rate[1]) * RATE_WINDOW_MS : void 0;
9664
+ }
9665
+ function retireOverflow(input, peer, name2) {
9666
+ const msgId = name2.slice(0, -".json".length);
9667
+ if (ULID_RE.test(msgId))
9668
+ markDone(input, peer, msgId, "overflow");
9669
+ fs16.unlinkSync(path18.join(input.overflowRoot, peer, name2));
9670
+ }
9671
+ function capOverflow(input, peer) {
9672
+ const dir = path18.join(input.overflowRoot, peer);
9673
+ const names = jsonNames(dir);
9674
+ const excess = Math.min(Math.max(0, names.length - OVERFLOW_MAX_FILES), JANITOR_BATCH);
9675
+ for (const name2 of names.slice(0, excess))
9676
+ retireOverflow(input, peer, name2);
9677
+ const kept = names.slice(excess);
9678
+ if (kept.length > OVERFLOW_MAX_FILES)
9679
+ return;
9680
+ const sizes = kept.map((name2) => fs16.statSync(path18.join(dir, name2)).size);
9681
+ let bytes = sizes.reduce((sum, size) => sum + size, 0);
9682
+ for (let i = 0; i < kept.length && bytes > OVERFLOW_MAX_BYTES; i++) {
9683
+ retireOverflow(input, peer, kept[i]);
9684
+ bytes -= sizes[i];
9685
+ }
9686
+ }
9687
+ function peerDirs(root) {
9688
+ return fs16.readdirSync(root, { withFileTypes: true }).filter((entry) => entry.isDirectory() && SAFE_ID2.test(entry.name)).map((entry) => entry.name);
9689
+ }
9690
+ function runJanitor(input) {
9691
+ const now = input.now();
9692
+ for (const peer of peerDirs(input.queueRoot)) {
9693
+ const dir = path18.join(input.queueRoot, peer);
9694
+ let budget = JANITOR_BATCH;
9695
+ for (const name2 of jsonNames(dir)) {
9696
+ const at = nameTime(name2);
9697
+ if (at === void 0 || !(at < now - STALE_MS))
9698
+ continue;
9699
+ if (budget-- <= 0)
9700
+ break;
9701
+ const file = path18.join(dir, name2);
9702
+ const body = fs16.readFileSync(file, "utf8");
9703
+ try {
9704
+ if (!isRecord(JSON.parse(body)))
9705
+ continue;
9706
+ } catch {
9707
+ continue;
9708
+ }
9709
+ const doneDir = path18.join(input.doneRoot, peer);
9710
+ ensureRealDir(doneDir, 448);
9711
+ writeNew(doneDir, name2, body, 384);
9712
+ fs16.unlinkSync(file);
9713
+ }
9714
+ }
9715
+ for (const peer of peerDirs(input.doneRoot)) {
9716
+ const dir = path18.join(input.doneRoot, peer);
9717
+ let budget = JANITOR_BATCH;
9718
+ for (const name2 of jsonNames(dir)) {
9719
+ const at = nameTime(name2);
9720
+ if (at === void 0 || !(at < now - DONE_TTL_MS))
9721
+ continue;
9722
+ if (budget-- <= 0)
9723
+ break;
9724
+ fs16.unlinkSync(path18.join(dir, name2));
9725
+ }
9726
+ }
9727
+ for (const peer of peerDirs(input.overflowRoot)) {
9728
+ const dir = path18.join(input.overflowRoot, peer);
9729
+ let budget = JANITOR_BATCH;
9730
+ for (const name2 of jsonNames(dir)) {
9731
+ const at = nameTime(name2);
9732
+ if (at === void 0 || !(at < now - OVERFLOW_TTL_MS))
9733
+ continue;
9734
+ if (budget-- <= 0)
9735
+ break;
9736
+ retireOverflow(input, peer, name2);
9737
+ }
9738
+ capOverflow(input, peer);
9739
+ }
9740
+ }
9741
+ async function intakeCycle(input) {
9742
+ for (const id of Object.keys(input.state.peers)) {
9743
+ if (!Object.hasOwn(input.profile.peers, id))
9744
+ delete input.state.peers[id];
9745
+ }
9746
+ runJanitor(input);
9747
+ let written = 0;
9748
+ for (const peer of Object.values(input.profile.peers)) {
9749
+ if (peer.status !== "paired")
9750
+ continue;
9751
+ if (!SAFE_ID2.test(peer.handle)) {
9752
+ input.log("intake-skip", { code: "bad-handle" });
9753
+ continue;
9754
+ }
9755
+ try {
9756
+ written += await intakePeer(input, peer);
9757
+ } catch (error) {
9758
+ input.log("intake-error", { peer: peer.handle, code: errInfo(error).code ?? "error" });
9759
+ }
9760
+ }
9761
+ return written;
9762
+ }
9763
+ async function initFromNow(input, force) {
9764
+ const paired = Object.values(input.profile.peers).filter((peer) => peer.status === "paired" && SAFE_ID2.test(peer.handle));
9765
+ const hasDone = paired.some((peer) => {
9766
+ const dir = path18.join(input.doneRoot, peer.handle);
9767
+ return fs16.existsSync(dir) && fs16.readdirSync(dir).length > 0;
9768
+ });
9769
+ if (hasDone && !force)
9770
+ throw new CourierError("init-exists", "done/ already has entries for a paired peer; pass --force to mark again");
9771
+ const marked = /* @__PURE__ */ new Map();
9772
+ for (const peer of paired) {
9773
+ const keys = await listAll(input.kv, `${k.mirrorPrefix}${peer.handle}/threads/`);
9774
+ let count = 0;
9775
+ for (const c of mirrorMessages(peer.handle, keys, input.log)) {
9776
+ if (markDone(input, peer.handle, c.msgId, "init"))
9777
+ count++;
9778
+ }
9779
+ marked.set(peer.handle, count);
9780
+ input.log("intake-init", { peer: peer.handle, marked: count });
9781
+ }
9782
+ return marked;
9783
+ }
9784
+ function intervalSeconds(raw) {
9785
+ if (raw === void 0)
9786
+ return 60;
9787
+ const n = /^\d+$/.test(raw) ? Number(raw) : NaN;
9788
+ if (!(n >= 5 && n <= 3600))
9789
+ throw new CourierError("usage", "--interval must be an integer from 5 to 3600");
9790
+ return n;
9791
+ }
9792
+ async function cmdIntake(args) {
9793
+ const base = path18.join(profileDir(), "intake");
9794
+ const queueRoot = args.get("queue-dir") ?? path18.join(base, "queue");
9795
+ const doneRoot = args.get("done-dir") ?? path18.join(base, "done");
9796
+ const overflowRoot = args.get("overflow-dir") ?? path18.join(base, "overflow");
9797
+ const stateDir = args.get("state-dir") ?? path18.join(base, "state");
9798
+ const peersFile = args.get("peers-file") ?? path18.join(base, "peers.json");
9799
+ const once = args.has("once");
9800
+ const intervalMs = intervalSeconds(args.get("interval")) * 1e3;
9801
+ const log = jsonLineLog();
9802
+ ensureRealDir(stateDir, 448);
9803
+ ensureRealDir(queueRoot, 488);
9804
+ ensureRealDir(doneRoot, 448);
9805
+ ensureRealDir(overflowRoot, 448);
9806
+ const release = acquireLock(path18.join(stateDir, LOCK_FILE));
9807
+ try {
9808
+ if (args.has("init-from-now")) {
9809
+ const profile = loadProfile();
9810
+ const node = await courierNode(profile);
9811
+ await initFromNow({ kv: node.kv, profile, doneRoot, now: Date.now, log }, args.has("force"));
9812
+ return;
9813
+ }
9814
+ const state = readState(path18.join(stateDir, STATE_FILE));
9815
+ let peers = loadPeers(peersFile);
9816
+ log("intake-start", { once, intervalSeconds: intervalMs / 1e3 });
9817
+ for (; ; ) {
9818
+ try {
9819
+ const profile = loadProfile();
9820
+ const node = await courierNode(profile);
9821
+ try {
9822
+ peers = loadPeers(peersFile);
9823
+ } catch (error) {
9824
+ log("intake-error", { code: errInfo(error).code ?? "bad-peers" });
9825
+ }
9826
+ const queued = await intakeCycle({
9827
+ kv: node.kv,
9828
+ profile,
9829
+ peers,
9830
+ queueRoot,
9831
+ doneRoot,
9832
+ overflowRoot,
9833
+ stateDir,
9834
+ state,
9835
+ now: Date.now,
9836
+ log
9837
+ });
9838
+ log("intake-cycle", { queued });
9839
+ } catch (error) {
9840
+ log("intake-error", { code: errInfo(error).code ?? "error" });
9841
+ if (once)
9842
+ throw error;
9843
+ }
9844
+ if (once)
9845
+ return;
9846
+ await new Promise((resolve) => {
9847
+ setTimeout(resolve, intervalMs);
9848
+ });
9849
+ }
9850
+ } finally {
9851
+ release();
9852
+ }
9853
+ }
9854
+
8979
9855
  // ../courier/dist/consumed.js
8980
9856
  function isKeyMissing(error) {
8981
9857
  const status = String(error.status ?? error.meta?.status ?? "");
@@ -9011,7 +9887,7 @@ async function markConsumed(kv2, id, at = /* @__PURE__ */ new Date()) {
9011
9887
  }
9012
9888
 
9013
9889
  // ../courier/dist/approval.js
9014
- var DAY_MS3 = 24 * 3600 * 1e3;
9890
+ var DAY_MS4 = 24 * 3600 * 1e3;
9015
9891
  var MAX_NOTE = 2e3;
9016
9892
  var FUTURE_SKEW_MS = 5 * 60 * 1e3;
9017
9893
  function fail3(code, message) {
@@ -9065,7 +9941,7 @@ function verifyApproval(id, request, approval, options = {}) {
9065
9941
  fail3("approval-mismatch", "The decision is dated in the future.");
9066
9942
  if (decidedAt >= expires)
9067
9943
  fail3("approval-expired", "The decision came after the request expired.");
9068
- if (now - decidedAt >= DAY_MS3)
9944
+ if (now - decidedAt >= DAY_MS4)
9069
9945
  fail3("approval-expired", "The approval is older than 24 hours; ask your owner again.");
9070
9946
  if (typeof request.peer !== "string" || typeof request.threadId !== "string" || typeof request.taskId !== "string") {
9071
9947
  fail3("approval-mismatch", "The request is missing peer, threadId or taskId.");
@@ -9163,9 +10039,9 @@ ${targetHelp()}`);
9163
10039
 
9164
10040
  // ../courier/dist/broker.js
9165
10041
  import { execFile } from "child_process";
9166
- import fs14 from "fs";
10042
+ import fs17 from "fs";
9167
10043
  import os8 from "os";
9168
- import path17 from "path";
10044
+ import path19 from "path";
9169
10045
  var MAX_OUTPUT = 4e3;
9170
10046
  var EXEC_TIMEOUT_MS = 12e4;
9171
10047
  var TOKEN = /^(gh[pousr]_[A-Za-z0-9]{20,255}|github_pat_[A-Za-z0-9_]{20,255})$/;
@@ -9177,7 +10053,7 @@ async function loadBrokerCredential(config, exec = execFileRunner) {
9177
10053
  const result = await exec(config.ghBin, ["auth", "token", "--hostname", "github.com"], {
9178
10054
  cwd: ownerHome,
9179
10055
  timeoutMs: 1e4,
9180
- env: { PATH: "/usr/bin:/bin", HOME: ownerHome, GH_CONFIG_DIR: path17.join(ownerHome, ".config/gh"), GH_PROMPT_DISABLED: "1", GH_NO_UPDATE_NOTIFIER: "1", LANG: "C" }
10056
+ env: { PATH: "/usr/bin:/bin", HOME: ownerHome, GH_CONFIG_DIR: path19.join(ownerHome, ".config/gh"), GH_PROMPT_DISABLED: "1", GH_NO_UPDATE_NOTIFIER: "1", LANG: "C" }
9181
10057
  });
9182
10058
  const token2 = result.stdout.trim();
9183
10059
  if (result.code !== 0 || !validToken(token2))
@@ -9227,9 +10103,9 @@ var execFileRunner = (bin, args, { cwd, env, timeoutMs }) => {
9227
10103
  };
9228
10104
  function brokerEnv(credential, scratch) {
9229
10105
  return {
9230
- PATH: `${path17.dirname(credential.ghBin)}:/usr/bin:/bin`,
10106
+ PATH: `${path19.dirname(credential.ghBin)}:/usr/bin:/bin`,
9231
10107
  HOME: scratch,
9232
- GH_CONFIG_DIR: path17.join(scratch, "gh"),
10108
+ GH_CONFIG_DIR: path19.join(scratch, "gh"),
9233
10109
  GH_TOKEN: credential.token,
9234
10110
  GH_PROMPT_DISABLED: "1",
9235
10111
  GH_NO_UPDATE_NOTIFIER: "1",
@@ -9261,8 +10137,8 @@ async function runApproved(id, deps) {
9261
10137
  if (await isConsumed(deps.kv, id))
9262
10138
  fail4("approval-used", `Approval ${id} was already used; an approval covers one action.`);
9263
10139
  const scratchRoot = deps.scratchRoot ?? brokerRoot();
9264
- fs14.mkdirSync(scratchRoot, { recursive: true, mode: 448 });
9265
- const scratch = fs14.mkdtempSync(path17.join(scratchRoot, "run-"));
10140
+ fs17.mkdirSync(scratchRoot, { recursive: true, mode: 448 });
10141
+ const scratch = fs17.mkdtempSync(path19.join(scratchRoot, "run-"));
9266
10142
  const env = brokerEnv(credential, scratch);
9267
10143
  const run2 = (args) => deps.exec(credential.ghBin, args, { cwd: scratch, env, timeoutMs: EXEC_TIMEOUT_MS });
9268
10144
  const clean = (text) => sanitizeOutput(text, [credential.token]);
@@ -9299,7 +10175,7 @@ ${merged.stderr}` : ""}`).trim(),
9299
10175
  ...ok2 ? {} : { note: "The approval is used up. If the merge should still happen, file a new request." }
9300
10176
  };
9301
10177
  } finally {
9302
- fs14.rmSync(scratch, { recursive: true, force: true });
10178
+ fs17.rmSync(scratch, { recursive: true, force: true });
9303
10179
  }
9304
10180
  }
9305
10181
  var runApprovedUsage = () => `Usage: ${cmd("run-approved <requestId>")}`;
@@ -9311,7 +10187,7 @@ async function cmdRunApproved(args) {
9311
10187
  const config = loadBrokerConfig(currentProfileId(), testOwnerRoot);
9312
10188
  assertPinnedProfile(config, loadProfile());
9313
10189
  const node = await courierNode(loadProfile(config.courierHome), config.courierHome);
9314
- const result = await runApproved(id, { kv: node.kv, credential: () => loadBrokerCredential(config), scratchRoot: path17.dirname(brokerFile(currentProfileId(), testOwnerRoot)), exec: execFileRunner, now: () => Date.now() });
10190
+ const result = await runApproved(id, { kv: node.kv, credential: () => loadBrokerCredential(config), scratchRoot: path19.dirname(brokerFile(currentProfileId(), testOwnerRoot)), exec: execFileRunner, now: () => Date.now() });
9315
10191
  await writeOut(`${JSON.stringify(result, null, 2)}
9316
10192
  `);
9317
10193
  if (!result.ok)
@@ -9339,7 +10215,7 @@ async function cmdBroker(args) {
9339
10215
  return;
9340
10216
  }
9341
10217
  if (sub2 === "clear") {
9342
- fs14.rmSync(file, { force: true });
10218
+ fs17.rmSync(file, { force: true });
9343
10219
  await writeOut('{"configured":false}\n');
9344
10220
  return;
9345
10221
  }
@@ -9349,33 +10225,33 @@ async function cmdBroker(args) {
9349
10225
  if (ghBin === "true")
9350
10226
  fail4("usage", "--gh-bin needs a path.");
9351
10227
  if (ghBin === void 0) {
9352
- for (const dir of (process.env.PATH ?? "").split(path17.delimiter)) {
9353
- const candidate = path17.join(dir || ".", "gh");
10228
+ for (const dir of (process.env.PATH ?? "").split(path19.delimiter)) {
10229
+ const candidate = path19.join(dir || ".", "gh");
9354
10230
  try {
9355
- fs14.accessSync(candidate, fs14.constants.X_OK);
9356
- ghBin = fs14.realpathSync(candidate);
10231
+ fs17.accessSync(candidate, fs17.constants.X_OK);
10232
+ ghBin = fs17.realpathSync(candidate);
9357
10233
  break;
9358
10234
  } catch {
9359
10235
  }
9360
10236
  }
9361
10237
  }
9362
- if (!ghBin || !path17.isAbsolute(ghBin))
10238
+ if (!ghBin || !path19.isAbsolute(ghBin))
9363
10239
  fail4("usage", "Could not find gh; pass --gh-bin <absolute path>.");
9364
10240
  try {
9365
- fs14.accessSync(ghBin, fs14.constants.X_OK);
10241
+ fs17.accessSync(ghBin, fs17.constants.X_OK);
9366
10242
  } catch {
9367
10243
  fail4("usage", `${ghBin} is not an executable file.`);
9368
10244
  }
9369
10245
  const profile = loadProfile();
9370
10246
  let testToken;
9371
10247
  if (testOwnerRoot !== void 0) {
9372
- testToken = fs14.readFileSync(0, "utf8").trim();
10248
+ testToken = fs17.readFileSync(0, "utf8").trim();
9373
10249
  if (testToken !== TEST_TOKEN)
9374
10250
  fail4("usage", "Tests accept only the fixed dummy token fixture on stdin");
9375
10251
  }
9376
- ghBin = fs14.realpathSync(ghBin);
9377
- const st = fs14.statSync(ghBin);
9378
- const config = { v: 2, courierHome: fs14.realpathSync(profileDir()), profile: pinProfile(profile), ghBin, ghIdentity: { dev: st.dev, ino: st.ino }, ...testToken ? { testToken } : {} };
10252
+ ghBin = fs17.realpathSync(ghBin);
10253
+ const st = fs17.statSync(ghBin);
10254
+ const config = { v: 2, courierHome: fs17.realpathSync(profileDir()), profile: pinProfile(profile), ghBin, ghIdentity: { dev: st.dev, ino: st.ino }, ...testToken ? { testToken } : {} };
9379
10255
  if (!testToken)
9380
10256
  await loadBrokerCredential(config);
9381
10257
  saveBrokerConfig(config, testOwnerRoot);
@@ -9470,6 +10346,9 @@ Delivery (one watcher per person per machine; never calls a model):
9470
10346
  watch \u2026 --install-launchd | --install-systemd [--dry-run] [--name n]
9471
10347
  Install the same watch command as a macOS launchd agent or a Linux
9472
10348
  systemd --user unit. --dry-run prints the exact file and commands.
10349
+ intake [--queue-dir d] [--peers-file f] [--state-dir d] [--interval 60] [--once]
10350
+ Intake reader: copy paired peers' mirrored messages into the local queue
10351
+ (one <msgId>.json per message) with cheap checks. Never calls a model.
9473
10352
 
9474
10353
  pause <peer> <threadId> [--reason "\u2026"] Humans: stop waking your agent for a thread; tells the peer
9475
10354
  resume <peer> <threadId> Humans: wake it again (the wake budget starts over)
@@ -9518,6 +10397,8 @@ async function run(argv) {
9518
10397
  return cmdOrders(sub2);
9519
10398
  case "watch":
9520
10399
  return cmdWatch(sub2);
10400
+ case "intake":
10401
+ return cmdIntake(sub2);
9521
10402
  case "approval":
9522
10403
  return cmdApproval(sub2);
9523
10404
  case "pause":