@omnicross/daemon 0.1.8 → 0.1.10

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/cli.cjs CHANGED
@@ -23,87 +23,634 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
23
23
  mod
24
24
  ));
25
25
 
26
- // src/commands/import-ccr.ts
27
- var import_node_fs3 = require("fs");
26
+ // src/commands/audit.ts
27
+ var import_node_fs5 = require("fs");
28
+ var import_node_path5 = require("path");
28
29
  var import_node_util = require("util");
29
30
 
30
- // src/ccr-import.ts
31
- function parseCcrConfig(raw) {
32
- if (!raw || typeof raw !== "object") {
33
- throw new Error("CCR config: top-level value must be an object");
31
+ // src/audit/auditBodyReader.ts
32
+ var import_node_fs3 = require("fs");
33
+ var import_node_path2 = require("path");
34
+ var import_node_zlib = require("zlib");
35
+
36
+ // src/audit/auditBodyStore.ts
37
+ var ANCHOR_EVERY = 64;
38
+ var ANCHOR_DELTA_RATIO = 0.75;
39
+ var DIVERGED_PREFIX_RATIO = 0.25;
40
+ var MAX_BASE_CHARS = 4e6;
41
+ var CACHE_BUDGET_CHARS = 16e6;
42
+ var CACHE_MAX_SESSIONS = 32;
43
+ var MAX_BASES_PER_SESSION = 4;
44
+ var isHighSurrogate = (code) => code >= 55296 && code <= 56319;
45
+ var isLowSurrogate = (code) => code >= 56320 && code <= 57343;
46
+ function computeBodyDelta(prev, next) {
47
+ const shortest = Math.min(prev.length, next.length);
48
+ let pre = 0;
49
+ while (pre < shortest && prev.charCodeAt(pre) === next.charCodeAt(pre)) pre += 1;
50
+ if (pre > 0 && isHighSurrogate(prev.charCodeAt(pre - 1))) pre -= 1;
51
+ const maxSuf = shortest - pre;
52
+ let suf = 0;
53
+ while (suf < maxSuf && prev.charCodeAt(prev.length - 1 - suf) === next.charCodeAt(next.length - 1 - suf)) {
54
+ suf += 1;
55
+ }
56
+ if (suf > 0 && isLowSurrogate(prev.charCodeAt(prev.length - suf))) suf -= 1;
57
+ return { pre, suf, ins: next.slice(pre, next.length - suf) };
58
+ }
59
+ function applyBodyDelta(prev, delta) {
60
+ const head = delta.pre > 0 ? prev.slice(0, delta.pre) : "";
61
+ const tail = delta.suf > 0 ? prev.slice(prev.length - delta.suf) : "";
62
+ return head + delta.ins + tail;
63
+ }
64
+ var SessionBaseCache = class {
65
+ constructor(maxSessions = CACHE_MAX_SESSIONS, budgetChars = CACHE_BUDGET_CHARS, maxBaseChars = MAX_BASE_CHARS, maxHeads = MAX_BASES_PER_SESSION) {
66
+ this.maxSessions = maxSessions;
67
+ this.budgetChars = budgetChars;
68
+ this.maxBaseChars = maxBaseChars;
69
+ this.maxHeads = maxHeads;
70
+ }
71
+ maxSessions;
72
+ budgetChars;
73
+ maxBaseChars;
74
+ maxHeads;
75
+ /** Session key to its retained heads, most-recent first. */
76
+ entries = /* @__PURE__ */ new Map();
77
+ chars = 0;
78
+ /** Retained sessions (tests + diagnostics). */
79
+ get size() {
80
+ return this.entries.size;
81
+ }
82
+ /** A session's retained heads, most-recent first. Refreshes LRU recency. */
83
+ get(sessionKey) {
84
+ const found = this.entries.get(sessionKey);
85
+ if (!found) return [];
86
+ this.entries.delete(sessionKey);
87
+ this.entries.set(sessionKey, found);
88
+ return found;
34
89
  }
35
- const obj = raw;
36
- const Providers = Array.isArray(obj["Providers"]) ? obj["Providers"] : [];
37
- const Router = obj["Router"] && typeof obj["Router"] === "object" ? obj["Router"] : {};
38
- return { Providers, Router };
90
+ /**
91
+ * Retain `base` as a head of `sessionKey`.
92
+ *
93
+ * `replacesId` is the head this turn CONTINUES (its body was preserved whole
94
+ * inside the new one), which is swapped out so a linear conversation keeps
95
+ * exactly one head. Omit it when the turn started a distinct stream %s that
96
+ * head is added alongside, which is what keeps a fork's branches apart.
97
+ *
98
+ * A body larger than `maxBaseChars` is not retained: the next turn anchors
99
+ * rather than letting one oversized session monopolize the budget.
100
+ */
101
+ remember(sessionKey, base, replacesId) {
102
+ const heads = this.entries.get(sessionKey) ?? [];
103
+ if (replacesId !== void 0) {
104
+ const at = heads.findIndex((head) => head.lastId === replacesId);
105
+ if (at >= 0) {
106
+ this.chars -= heads[at].text.length;
107
+ heads.splice(at, 1);
108
+ }
109
+ }
110
+ if (base.text.length <= this.maxBaseChars) {
111
+ heads.unshift(base);
112
+ this.chars += base.text.length;
113
+ }
114
+ while (heads.length > this.maxHeads) {
115
+ const dropped = heads.pop();
116
+ if (dropped) this.chars -= dropped.text.length;
117
+ }
118
+ this.entries.delete(sessionKey);
119
+ if (heads.length > 0) this.entries.set(sessionKey, heads);
120
+ this.evict();
121
+ }
122
+ /** Drop a session's heads (eviction, or a write failure invalidating them). */
123
+ forget(sessionKey) {
124
+ const heads = this.entries.get(sessionKey);
125
+ if (!heads) return;
126
+ for (const head of heads) this.chars -= head.text.length;
127
+ this.entries.delete(sessionKey);
128
+ }
129
+ /** Drop everything (writer disposal / test teardown). */
130
+ clear() {
131
+ this.entries.clear();
132
+ this.chars = 0;
133
+ }
134
+ /** Evict least-recently-used sessions until both bounds hold. */
135
+ evict() {
136
+ while (this.entries.size > this.maxSessions || this.chars > this.budgetChars && this.entries.size > 1) {
137
+ const oldest = this.entries.keys().next();
138
+ if (oldest.done) break;
139
+ this.forget(oldest.value);
140
+ }
141
+ }
142
+ };
143
+ function anchorReason(base, dayDir, delta, nextLength) {
144
+ if (!base || !delta) return "new";
145
+ if (base.dayDir !== dayDir) return "day";
146
+ if (base.chainLen >= ANCHOR_EVERY) return "chain";
147
+ if (delta.pre < base.text.length * DIVERGED_PREFIX_RATIO) return "diverged";
148
+ if (delta.ins.length > nextLength * ANCHOR_DELTA_RATIO) return "costly";
149
+ return null;
39
150
  }
40
- function inferApiFormat(provider) {
41
- const hay = `${provider.api_base_url ?? ""} ${provider.name ?? ""}`.toLowerCase();
42
- if (hay.includes("anthropic") || hay.includes("claude")) {
43
- return { format: "anthropic", ambiguous: false };
151
+ function pickBase(heads, next) {
152
+ let best = null;
153
+ for (const base of heads) {
154
+ const delta = computeBodyDelta(base.text, next);
155
+ if (best !== null && delta.ins.length >= best.delta.ins.length) continue;
156
+ best = { base, delta, continues: delta.pre + delta.suf >= base.text.length };
157
+ }
158
+ return best;
159
+ }
160
+ function encodeBodyEntry(record, sessionKey, dayDir, cache) {
161
+ const requestBody = record.requestBody;
162
+ const responseBody = record.responseBody;
163
+ if (requestBody === void 0 && responseBody === void 0) return null;
164
+ const entry = { id: record.id, ts: record.ts };
165
+ if (requestBody !== void 0) {
166
+ const heads = cache.get(sessionKey);
167
+ const sameDay = heads.filter((head) => head.dayDir === dayDir);
168
+ const chosen = pickBase(sameDay, requestBody);
169
+ const reason = heads.length > 0 && sameDay.length === 0 ? "day" : anchorReason(chosen?.base, dayDir, chosen?.delta ?? null, requestBody.length);
170
+ if (reason !== null) {
171
+ entry.req = { base: null, anchor: reason, pre: 0, suf: 0, ins: requestBody };
172
+ cache.remember(
173
+ sessionKey,
174
+ { dayDir, lastId: record.id, text: requestBody, chainLen: 0 },
175
+ chosen?.continues === true ? chosen.base.lastId : void 0
176
+ );
177
+ } else {
178
+ const picked = chosen;
179
+ entry.req = {
180
+ base: picked.base.lastId,
181
+ ...picked.continues ? { cont: true } : {},
182
+ pre: picked.delta.pre,
183
+ suf: picked.delta.suf,
184
+ ins: picked.delta.ins
185
+ };
186
+ cache.remember(
187
+ sessionKey,
188
+ { dayDir, lastId: record.id, text: requestBody, chainLen: picked.base.chainLen + 1 },
189
+ picked.continues ? picked.base.lastId : void 0
190
+ );
191
+ }
44
192
  }
45
- if (hay.includes("generativelanguage") || hay.includes("gemini") || hay.includes("google")) {
46
- return { format: "gemini", ambiguous: false };
193
+ if (responseBody !== void 0) entry.res = responseBody;
194
+ return JSON.stringify(entry);
195
+ }
196
+ function isAuditBodyEntry(value) {
197
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
198
+ const entry = value;
199
+ if (typeof entry["id"] !== "string" || typeof entry["ts"] !== "number") return false;
200
+ if (entry["res"] !== void 0 && typeof entry["res"] !== "string") return false;
201
+ const req = entry["req"];
202
+ if (req === void 0) return true;
203
+ if (!req || typeof req !== "object" || Array.isArray(req)) return false;
204
+ const delta = req;
205
+ if (delta["anchor"] !== void 0 && typeof delta["anchor"] !== "string") return false;
206
+ if (delta["cont"] !== void 0 && typeof delta["cont"] !== "boolean") return false;
207
+ return (delta["base"] === null || typeof delta["base"] === "string") && Number.isSafeInteger(delta["pre"]) && delta["pre"] >= 0 && Number.isSafeInteger(delta["suf"]) && delta["suf"] >= 0 && typeof delta["ins"] === "string";
208
+ }
209
+
210
+ // src/audit/auditDictionary.ts
211
+ var import_node_fs = require("fs");
212
+ var import_node_path = require("path");
213
+
214
+ // src/audit/auditFiles.ts
215
+ var AUDIT_FILE_RE = /^audit-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
216
+ var AUDIT_DAY_DIR_RE = /^audit-(\d{4})-(\d{2})-(\d{2})$/;
217
+ var AUDIT_META_FILE = "meta.jsonl";
218
+ var AUDIT_BODIES_DIR = "bodies";
219
+ var AUDIT_SESSION_KEY_RE = /^[0-9a-f]{8,64}$/;
220
+ var pad2 = (n) => String(n).padStart(2, "0");
221
+ var localDateStamp = (ts) => {
222
+ const d = new Date(ts);
223
+ return `${d.getFullYear()}-${pad2(d.getMonth() + 1)}-${pad2(d.getDate())}`;
224
+ };
225
+ function auditDayDirName(ts) {
226
+ return `audit-${localDateStamp(ts)}`;
227
+ }
228
+ function isAuditDayDir(name) {
229
+ return AUDIT_DAY_DIR_RE.test(name);
230
+ }
231
+ function isSafeSessionKey(key) {
232
+ return typeof key === "string" && AUDIT_SESSION_KEY_RE.test(key);
233
+ }
234
+ function auditBodyFileName(sessionKey) {
235
+ return `${sessionKey}.jsonl`;
236
+ }
237
+ function auditFileDateMs(name) {
238
+ const m = AUDIT_FILE_RE.exec(name) ?? AUDIT_DAY_DIR_RE.exec(name);
239
+ if (!m) return null;
240
+ const year = Number(m[1]);
241
+ const month = Number(m[2]);
242
+ const day = Number(m[3]);
243
+ const d = new Date(year, month - 1, day);
244
+ if (d.getFullYear() !== year || d.getMonth() !== month - 1 || d.getDate() !== day) {
245
+ return null;
47
246
  }
48
- if (hay.includes("/responses")) {
49
- return { format: "openai-response", ambiguous: false };
247
+ return d.getTime();
248
+ }
249
+
250
+ // src/audit/auditDictionary.ts
251
+ var AUDIT_DICT_FILE = "_dict.jsonl";
252
+ var DICT_BASE_PREFIX = "dict:";
253
+ var DICT_CANDIDATES = 3;
254
+ var MIN_SAVING_RATIO = 0.2;
255
+ function parseEntries(raw) {
256
+ const entries = [];
257
+ for (const line of raw.split("\n")) {
258
+ const trimmed = line.trim();
259
+ if (!trimmed) continue;
260
+ try {
261
+ const parsed = JSON.parse(trimmed);
262
+ if (isAuditBodyEntry(parsed)) entries.push(parsed);
263
+ } catch {
264
+ }
50
265
  }
51
- if (hay.includes("openai") || hay.includes("/v1") || hay.includes("chat/completions")) {
52
- return { format: "openai", ambiguous: false };
266
+ return entries;
267
+ }
268
+ function plainShards(bodiesPath) {
269
+ try {
270
+ return (0, import_node_fs.readdirSync)(bodiesPath).filter(
271
+ (file) => file.endsWith(".jsonl") && isSafeSessionKey(file.slice(0, -".jsonl".length))
272
+ );
273
+ } catch {
274
+ return [];
53
275
  }
54
- return { format: "openai", ambiguous: true };
55
276
  }
56
- function mapProviders(providers, notes) {
57
- const rows = [];
58
- for (const [i, p] of providers.entries()) {
59
- const id = p.name?.trim();
60
- if (!id) {
61
- notes.push(`Providers[${i}] has no name \u2014 skipped.`);
277
+ function chooseDictionary(anchors) {
278
+ if (anchors.length < 2) return null;
279
+ const total = anchors.reduce((sum, body) => sum + body.length, 0);
280
+ const candidates = [...anchors].sort((a, b) => b.length - a.length).slice(0, DICT_CANDIDATES);
281
+ let best = null;
282
+ for (const candidate of candidates) {
283
+ let cost = candidate.length;
284
+ for (const body of anchors) {
285
+ cost += body === candidate ? 0 : computeBodyDelta(candidate, body).ins.length;
286
+ }
287
+ if (best === null || cost < best.cost) best = { body: candidate, cost };
288
+ }
289
+ if (best === null) return null;
290
+ return total - best.cost >= total * MIN_SAVING_RATIO ? best.body : null;
291
+ }
292
+ var EMPTY = { shards: 0, anchors: 0, savedBytes: 0 };
293
+ function compactAuditDay(dayPath) {
294
+ const bodiesPath = (0, import_node_path.join)(dayPath, AUDIT_BODIES_DIR);
295
+ if (!(0, import_node_fs.existsSync)(bodiesPath)) return EMPTY;
296
+ const dictPath = (0, import_node_path.join)(bodiesPath, AUDIT_DICT_FILE);
297
+ if ((0, import_node_fs.existsSync)(dictPath) || (0, import_node_fs.existsSync)(`${dictPath}.gz`)) return EMPTY;
298
+ const shardFiles = plainShards(bodiesPath);
299
+ if (shardFiles.length < 2) return EMPTY;
300
+ const loaded = /* @__PURE__ */ new Map();
301
+ const anchors = [];
302
+ for (const file of shardFiles) {
303
+ let entries;
304
+ try {
305
+ entries = parseEntries((0, import_node_fs.readFileSync)((0, import_node_path.join)(bodiesPath, file), "utf8"));
306
+ } catch {
62
307
  continue;
63
308
  }
64
- const { format, ambiguous } = inferApiFormat(p);
65
- if (ambiguous) {
66
- notes.push(
67
- `Provider '${id}': could not infer apiFormat from base URL \u2014 defaulted to 'openai'. Edit the config if this provider speaks a different wire format.`
68
- );
309
+ loaded.set(file, entries);
310
+ for (const entry of entries) {
311
+ if (entry.req && entry.req.base === null) anchors.push(entry.req.ins);
69
312
  }
70
- rows.push({
71
- id,
72
- apiFormat: format,
73
- baseUrl: p.api_base_url ?? "",
74
- apiKey: p.api_key ?? "",
75
- models: Array.isArray(p.models) ? p.models : void 0
313
+ }
314
+ if (anchors.length < 2) return EMPTY;
315
+ const dictionary = chooseDictionary(anchors);
316
+ if (dictionary === null) return EMPTY;
317
+ const dictEntry = {
318
+ id: `${DICT_BASE_PREFIX}0`,
319
+ ts: 0,
320
+ req: { base: null, anchor: "dict", pre: 0, suf: 0, ins: dictionary }
321
+ };
322
+ (0, import_node_fs.writeFileSync)(dictPath, JSON.stringify(dictEntry) + "\n", "utf8");
323
+ const result = { shards: 0, anchors: 0, savedBytes: 0 };
324
+ for (const [file, entries] of loaded) {
325
+ let changed = false;
326
+ let saved = 0;
327
+ const rewritten = entries.map((entry) => {
328
+ if (!entry.req || entry.req.base !== null || entry.req.ins === dictionary) return entry;
329
+ const delta = computeBodyDelta(dictionary, entry.req.ins);
330
+ if (delta.ins.length >= entry.req.ins.length) return entry;
331
+ changed = true;
332
+ saved += entry.req.ins.length - delta.ins.length;
333
+ return {
334
+ ...entry,
335
+ req: { base: dictEntry.id, pre: delta.pre, suf: delta.suf, ins: delta.ins }
336
+ };
76
337
  });
338
+ if (!changed) continue;
339
+ const target = (0, import_node_path.join)(bodiesPath, file);
340
+ const temp = `${target}.compacting`;
341
+ try {
342
+ (0, import_node_fs.writeFileSync)(temp, rewritten.map((e) => JSON.stringify(e)).join("\n") + "\n", "utf8");
343
+ (0, import_node_fs.renameSync)(temp, target);
344
+ } catch {
345
+ try {
346
+ if ((0, import_node_fs.existsSync)(temp)) (0, import_node_fs.unlinkSync)(temp);
347
+ } catch {
348
+ }
349
+ continue;
350
+ }
351
+ result.shards += 1;
352
+ result.anchors += rewritten.filter((e) => e.req?.base === dictEntry.id).length;
353
+ result.savedBytes += saved;
77
354
  }
78
- return rows;
355
+ if (result.shards === 0) {
356
+ try {
357
+ (0, import_node_fs.unlinkSync)(dictPath);
358
+ } catch {
359
+ }
360
+ }
361
+ return result;
79
362
  }
80
- function noteRouterRoles(router, notes) {
81
- if (router.think) {
82
- notes.push(`Router.think \u2192 folded into 'default' (omnicross has no think slot).`);
363
+ function compactAllClosedAuditDays(auditDir, now = Date.now) {
364
+ const run = { days: 0, shards: 0, savedBytes: 0 };
365
+ if (!(0, import_node_fs.existsSync)(auditDir)) return run;
366
+ const today = auditDayDirName(now());
367
+ let names;
368
+ try {
369
+ names = (0, import_node_fs.readdirSync)(auditDir).filter(isAuditDayDir).sort();
370
+ } catch {
371
+ return run;
83
372
  }
84
- if (router.longContext) {
85
- notes.push(
86
- `Router.longContext \u2192 folded into 'default' (no longContext slot; longContextThreshold dropped).`
87
- );
373
+ for (const name of names) {
374
+ if (name === today) continue;
375
+ try {
376
+ const result = compactAuditDay((0, import_node_path.join)(auditDir, name));
377
+ if (result.shards === 0) continue;
378
+ run.days += 1;
379
+ run.shards += result.shards;
380
+ run.savedBytes += result.savedBytes;
381
+ } catch {
382
+ }
88
383
  }
89
- if (router.image) {
90
- notes.push(`Router.image \u2192 mapped to 'vision' (CCR forceUseImageAgent dropped).`);
384
+ return run;
385
+ }
386
+
387
+ // src/audit/auditJsonl.ts
388
+ var import_node_fs2 = require("fs");
389
+ var WINDOW_BYTES = 1 << 20;
390
+ var MAX_LINE_BYTES = 32 * 1024 * 1024;
391
+ var NEWLINE = 10;
392
+ function forEachLineFromTail(path2, onLine) {
393
+ let fd;
394
+ let end;
395
+ try {
396
+ end = (0, import_node_fs2.statSync)(path2).size;
397
+ if (end === 0) return;
398
+ fd = (0, import_node_fs2.openSync)(path2, "r");
399
+ } catch {
400
+ return;
91
401
  }
92
- if (router.webSearch) {
93
- notes.push(
94
- `Router.webSearch \u2192 DROPPED. omnicross injects web search via an interception port rather than routing to a natively-online model; the CCR webSearch model ('${router.webSearch}') was not carried over.`
95
- );
402
+ try {
403
+ let carry = Buffer.alloc(0);
404
+ while (end > 0) {
405
+ const start = Math.max(0, end - WINDOW_BYTES);
406
+ const window = Buffer.allocUnsafe(end - start);
407
+ let read;
408
+ try {
409
+ read = (0, import_node_fs2.readSync)(fd, window, 0, end - start, start);
410
+ } catch {
411
+ return;
412
+ }
413
+ const chunk = carry.length > 0 ? Buffer.concat([window.subarray(0, read), carry]) : window.subarray(0, read);
414
+ let lineEnd = chunk.length;
415
+ let nl = lineEnd > 0 ? chunk.lastIndexOf(NEWLINE, lineEnd - 1) : -1;
416
+ while (nl >= 0) {
417
+ if (nl + 1 < lineEnd) {
418
+ const line = chunk.subarray(nl + 1, lineEnd).toString("utf8").trim();
419
+ if (line && onLine(line)) return;
420
+ }
421
+ lineEnd = nl;
422
+ nl = lineEnd > 0 ? chunk.lastIndexOf(NEWLINE, lineEnd - 1) : -1;
423
+ }
424
+ if (start === 0) {
425
+ if (lineEnd > 0) {
426
+ const line = chunk.subarray(0, lineEnd).toString("utf8").trim();
427
+ if (line) onLine(line);
428
+ }
429
+ return;
430
+ }
431
+ if (lineEnd > MAX_LINE_BYTES) return;
432
+ carry = Buffer.from(chunk.subarray(0, lineEnd));
433
+ end = start;
434
+ }
435
+ } finally {
436
+ try {
437
+ (0, import_node_fs2.closeSync)(fd);
438
+ } catch {
439
+ }
96
440
  }
97
441
  }
98
- function mapCcrToOmnicross(ccr) {
99
- const notes = [];
100
- const providers = mapProviders(ccr.Providers ?? [], notes);
101
- noteRouterRoles(ccr.Router ?? {}, notes);
102
- return { config: { providers }, notes };
442
+
443
+ // src/audit/auditBodyReader.ts
444
+ function candidateDays(auditDir, ts) {
445
+ if (typeof ts === "number" && Number.isFinite(ts)) {
446
+ const named = auditDayDirName(ts);
447
+ if ((0, import_node_fs3.existsSync)((0, import_node_path2.join)(auditDir, named))) return [named];
448
+ }
449
+ try {
450
+ return (0, import_node_fs3.readdirSync)(auditDir).filter(isAuditDayDir).sort().reverse();
451
+ } catch {
452
+ return [];
453
+ }
454
+ }
455
+ function readShard(auditDir, day, sessionKey) {
456
+ const base = (0, import_node_path2.join)(auditDir, day, AUDIT_BODIES_DIR, auditBodyFileName(sessionKey));
457
+ try {
458
+ if ((0, import_node_fs3.existsSync)(base)) return (0, import_node_fs3.readFileSync)(base, "utf8");
459
+ const gz = `${base}.gz`;
460
+ if ((0, import_node_fs3.existsSync)(gz)) return (0, import_node_zlib.gunzipSync)((0, import_node_fs3.readFileSync)(gz)).toString("utf8");
461
+ } catch {
462
+ return null;
463
+ }
464
+ return null;
465
+ }
466
+ function parseShard(raw) {
467
+ const entries = /* @__PURE__ */ new Map();
468
+ for (const line of raw.split("\n")) {
469
+ const trimmed = line.trim();
470
+ if (!trimmed) continue;
471
+ let parsed;
472
+ try {
473
+ parsed = JSON.parse(trimmed);
474
+ } catch {
475
+ continue;
476
+ }
477
+ if (isAuditBodyEntry(parsed)) entries.set(parsed.id, parsed);
478
+ }
479
+ return entries;
480
+ }
481
+ function withDictionary(auditDir, day, entries) {
482
+ let needed = false;
483
+ for (const entry of entries.values()) {
484
+ if (entry.req?.base?.startsWith(DICT_BASE_PREFIX)) {
485
+ needed = true;
486
+ break;
487
+ }
488
+ }
489
+ if (!needed) return entries;
490
+ const base = (0, import_node_path2.join)(auditDir, day, AUDIT_BODIES_DIR, AUDIT_DICT_FILE);
491
+ let raw = null;
492
+ try {
493
+ if ((0, import_node_fs3.existsSync)(base)) raw = (0, import_node_fs3.readFileSync)(base, "utf8");
494
+ else if ((0, import_node_fs3.existsSync)(`${base}.gz`)) raw = (0, import_node_zlib.gunzipSync)((0, import_node_fs3.readFileSync)(`${base}.gz`)).toString("utf8");
495
+ } catch {
496
+ return entries;
497
+ }
498
+ if (raw === null) return entries;
499
+ for (const [id, entry] of parseShard(raw)) entries.set(id, entry);
500
+ return entries;
501
+ }
502
+ function reconstructRequest(entries, entry) {
503
+ if (!entry.req) return void 0;
504
+ const chain = [];
505
+ const visited = /* @__PURE__ */ new Set();
506
+ let cursor = entry;
507
+ while (cursor?.req) {
508
+ if (visited.has(cursor.id)) return void 0;
509
+ visited.add(cursor.id);
510
+ chain.push(cursor);
511
+ if (cursor.req.base === null) break;
512
+ cursor = entries.get(cursor.req.base);
513
+ }
514
+ const anchor = chain[chain.length - 1];
515
+ if (!anchor?.req || anchor.req.base !== null) return void 0;
516
+ let text = anchor.req.ins;
517
+ for (let i = chain.length - 2; i >= 0; i -= 1) {
518
+ const delta = chain[i]?.req;
519
+ if (!delta) return void 0;
520
+ if (delta.pre > text.length || delta.suf > text.length - delta.pre) return void 0;
521
+ text = applyBodyDelta(text, delta);
522
+ }
523
+ return text;
524
+ }
525
+ function assignStreams(entries) {
526
+ const rootOf = /* @__PURE__ */ new Map();
527
+ for (const entry of entries.values()) {
528
+ const seen = /* @__PURE__ */ new Set();
529
+ let cursor = entry;
530
+ while (cursor?.req?.cont === true && cursor.req.base !== null && !seen.has(cursor.id)) {
531
+ seen.add(cursor.id);
532
+ const next = entries.get(cursor.req.base);
533
+ if (!next) break;
534
+ cursor = next;
535
+ }
536
+ rootOf.set(entry.id, cursor?.id ?? entry.id);
537
+ }
538
+ const firstTs = /* @__PURE__ */ new Map();
539
+ for (const entry of entries.values()) {
540
+ const root = rootOf.get(entry.id);
541
+ const known = firstTs.get(root);
542
+ if (known === void 0 || entry.ts < known) firstTs.set(root, entry.ts);
543
+ }
544
+ const order = [...firstTs.entries()].sort((a, b) => a[1] - b[1]).map(([root]) => root);
545
+ const index = new Map(order.map((root, i) => [root, i]));
546
+ const streams = /* @__PURE__ */ new Map();
547
+ for (const entry of entries.values()) {
548
+ streams.set(entry.id, index.get(rootOf.get(entry.id)) ?? 0);
549
+ }
550
+ return streams;
551
+ }
552
+ function readAuditBody(auditDir, query2) {
553
+ if (!isSafeSessionKey(query2.sessionKey) || !query2.id) return {};
554
+ if (!(0, import_node_fs3.existsSync)(auditDir)) return {};
555
+ for (const day of candidateDays(auditDir, query2.ts)) {
556
+ const raw = readShard(auditDir, day, query2.sessionKey);
557
+ if (raw === null) continue;
558
+ const entries = withDictionary(auditDir, day, parseShard(raw));
559
+ const entry = entries.get(query2.id);
560
+ if (!entry) continue;
561
+ const result = {};
562
+ const requestBody = reconstructRequest(entries, entry);
563
+ if (requestBody !== void 0) result.requestBody = requestBody;
564
+ if (entry.res !== void 0) result.responseBody = entry.res;
565
+ return result;
566
+ }
567
+ return readLegacyInlineBody(auditDir, query2.id);
568
+ }
569
+ function readLegacyInlineBody(auditDir, id) {
570
+ let names;
571
+ try {
572
+ names = (0, import_node_fs3.readdirSync)(auditDir).filter((name) => AUDIT_FILE_RE.test(name)).sort().reverse();
573
+ } catch {
574
+ return {};
575
+ }
576
+ const needle = JSON.stringify(id);
577
+ let found = {};
578
+ for (const name of names) {
579
+ forEachLineFromTail((0, import_node_path2.join)(auditDir, name), (line) => {
580
+ if (!line.includes(needle)) return false;
581
+ let parsed;
582
+ try {
583
+ parsed = JSON.parse(line);
584
+ } catch {
585
+ return false;
586
+ }
587
+ const record = parsed;
588
+ if (record.id !== id) return false;
589
+ const result = {};
590
+ if (typeof record.requestBody === "string") result.requestBody = record.requestBody;
591
+ if (typeof record.responseBody === "string") result.responseBody = record.responseBody;
592
+ found = result;
593
+ return true;
594
+ });
595
+ if (found.requestBody !== void 0 || found.responseBody !== void 0) break;
596
+ }
597
+ return found;
598
+ }
599
+ function readAuditSessionTurns(auditDir, sessionKey, ts) {
600
+ if (!isSafeSessionKey(sessionKey) || !(0, import_node_fs3.existsSync)(auditDir)) return [];
601
+ for (const day of candidateDays(auditDir, ts)) {
602
+ const raw = readShard(auditDir, day, sessionKey);
603
+ if (raw === null) continue;
604
+ const shardEntries = parseShard(raw);
605
+ const streams = assignStreams(shardEntries);
606
+ const entries = withDictionary(auditDir, day, shardEntries);
607
+ const turns = [];
608
+ for (const entry of entries.values()) {
609
+ if (entry.id.startsWith(DICT_BASE_PREFIX)) continue;
610
+ const turn = { id: entry.id, ts: entry.ts, stream: streams.get(entry.id) ?? 0 };
611
+ if (entry.req?.anchor === "diverged") turn.diverged = true;
612
+ const requestBody = reconstructRequest(entries, entry);
613
+ if (requestBody !== void 0) turn.requestBody = requestBody;
614
+ if (entry.res !== void 0) turn.responseBody = entry.res;
615
+ turns.push(turn);
616
+ }
617
+ turns.sort((a, b) => a.stream === b.stream ? a.ts - b.ts : a.stream - b.stream);
618
+ return turns;
619
+ }
620
+ return [];
621
+ }
622
+ function listAuditSessions(auditDir, ts) {
623
+ if (!(0, import_node_fs3.existsSync)(auditDir)) return [];
624
+ const summaries = [];
625
+ for (const day of candidateDays(auditDir, ts)) {
626
+ const bodiesPath = (0, import_node_path2.join)(auditDir, day, AUDIT_BODIES_DIR);
627
+ let files;
628
+ try {
629
+ files = (0, import_node_fs3.readdirSync)(bodiesPath);
630
+ } catch {
631
+ continue;
632
+ }
633
+ for (const file of files) {
634
+ const compressed = file.endsWith(".jsonl.gz");
635
+ const sessionKey = file.replace(/\.jsonl(\.gz)?$/, "");
636
+ if (!isSafeSessionKey(sessionKey) || !compressed && !file.endsWith(".jsonl")) continue;
637
+ let bytes = 0;
638
+ try {
639
+ bytes = (0, import_node_fs3.statSync)((0, import_node_path2.join)(bodiesPath, file)).size;
640
+ } catch {
641
+ continue;
642
+ }
643
+ const raw = readShard(auditDir, day, sessionKey);
644
+ const turns = raw === null ? 0 : parseShard(raw).size;
645
+ summaries.push({ sessionKey, day, turns, bytes, compressed });
646
+ }
647
+ }
648
+ summaries.sort((a, b) => a.day === b.day ? b.bytes - a.bytes : a.day < b.day ? 1 : -1);
649
+ return summaries;
103
650
  }
104
651
 
105
- // src/config.ts
106
- var import_node_fs2 = require("fs");
652
+ // src/commands/paths.ts
653
+ var import_node_path4 = require("path");
107
654
 
108
655
  // src/secrets/envelope.ts
109
656
  var import_node_crypto = require("crypto");
@@ -162,13 +709,13 @@ function decryptValue(envelope, key) {
162
709
 
163
710
  // src/secrets/masterKey.ts
164
711
  var import_node_crypto2 = require("crypto");
165
- var import_node_fs = require("fs");
712
+ var import_node_fs4 = require("fs");
166
713
  var import_node_os = require("os");
167
- var import_node_path = require("path");
714
+ var import_node_path3 = require("path");
168
715
  var MASTER_KEY_ENV = "OMNICROSS_MASTER_KEY";
169
716
  var KEY_BYTES2 = 32;
170
717
  function defaultMasterKeyPath() {
171
- return (0, import_node_path.join)((0, import_node_os.homedir)(), ".omnicross", "master.key");
718
+ return (0, import_node_path3.join)((0, import_node_os.homedir)(), ".omnicross", "master.key");
172
719
  }
173
720
  function decodeEnvKey(raw) {
174
721
  const trimmed = raw.trim();
@@ -184,7 +731,7 @@ function decodeEnvKey(raw) {
184
731
  return buf;
185
732
  }
186
733
  function readKeyFile(path2) {
187
- const raw = (0, import_node_fs.readFileSync)(path2);
734
+ const raw = (0, import_node_fs4.readFileSync)(path2);
188
735
  if (raw.length === KEY_BYTES2) return raw;
189
736
  const text = raw.toString("utf8").trim();
190
737
  if (/^[0-9a-fA-F]{64}$/.test(text)) return Buffer.from(text, "hex");
@@ -196,10 +743,10 @@ function readKeyFile(path2) {
196
743
  }
197
744
  function generateKeyFile(path2) {
198
745
  const key = (0, import_node_crypto2.randomBytes)(KEY_BYTES2);
199
- (0, import_node_fs.mkdirSync)((0, import_node_path.dirname)(path2), { recursive: true });
200
- (0, import_node_fs.writeFileSync)(path2, key, { mode: 384 });
746
+ (0, import_node_fs4.mkdirSync)((0, import_node_path3.dirname)(path2), { recursive: true });
747
+ (0, import_node_fs4.writeFileSync)(path2, key, { mode: 384 });
201
748
  try {
202
- (0, import_node_fs.chmodSync)(path2, 384);
749
+ (0, import_node_fs4.chmodSync)(path2, 384);
203
750
  } catch {
204
751
  }
205
752
  return key;
@@ -210,7 +757,7 @@ function resolveMasterKey(options = {}) {
210
757
  return decodeEnvKey(envRaw);
211
758
  }
212
759
  const keyFilePath = options.keyFilePath ?? defaultMasterKeyPath();
213
- if ((0, import_node_fs.existsSync)(keyFilePath)) {
760
+ if ((0, import_node_fs4.existsSync)(keyFilePath)) {
214
761
  return readKeyFile(keyFilePath);
215
762
  }
216
763
  return generateKeyFile(keyFilePath);
@@ -458,7 +1005,234 @@ function decryptTokens(tokens, box) {
458
1005
  return transformTokens(tokens, (v) => box.decryptMaybe(v));
459
1006
  }
460
1007
 
1008
+ // src/commands/paths.ts
1009
+ function defaultKeysPath(configPath) {
1010
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "keys.json");
1011
+ }
1012
+ function defaultVouchersPath(configPath) {
1013
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "vouchers.json");
1014
+ }
1015
+ function defaultTokensPath(configPath) {
1016
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "tokens.json");
1017
+ }
1018
+ function defaultIntegrationsPath(configPath) {
1019
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "integrations.json");
1020
+ }
1021
+ function defaultPricingPath(configPath) {
1022
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "pricing.json");
1023
+ }
1024
+ function defaultPricingRefreshStatePath(configPath) {
1025
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "pricing-refresh.json");
1026
+ }
1027
+ function defaultAccountAllowancePath(configPath) {
1028
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "allowance-cache.json");
1029
+ }
1030
+ function defaultUsageEventsPath(configPath) {
1031
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "usage-events.jsonl");
1032
+ }
1033
+ function defaultAuditDir(configPath) {
1034
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "audit");
1035
+ }
1036
+ function defaultBillingDir(configPath) {
1037
+ return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "billing");
1038
+ }
1039
+ function resolveSecretBox(masterKeyFilePath) {
1040
+ return new SecretBox(() => resolveMasterKey({ keyFilePath: masterKeyFilePath }));
1041
+ }
1042
+
1043
+ // src/commands/audit.ts
1044
+ function parseDate(value) {
1045
+ if (!value) return void 0;
1046
+ const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(value.trim());
1047
+ if (!m) throw new Error(`audit: --date must be YYYY-MM-DD (got ${value})`);
1048
+ const d = new Date(Number(m[1]), Number(m[2]) - 1, Number(m[3]));
1049
+ return d.getTime();
1050
+ }
1051
+ function formatBytes(bytes) {
1052
+ if (bytes < 1024) return `${bytes} B`;
1053
+ if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
1054
+ return `${(bytes / (1024 * 1024)).toFixed(1)} MB`;
1055
+ }
1056
+ async function runAudit(argv) {
1057
+ const { values, positionals } = (0, import_node_util.parseArgs)({
1058
+ args: argv,
1059
+ options: {
1060
+ config: { type: "string", short: "c" },
1061
+ session: { type: "string", short: "s" },
1062
+ date: { type: "string", short: "d" },
1063
+ id: { type: "string" }
1064
+ },
1065
+ allowPositionals: true
1066
+ });
1067
+ const configPath = values.config;
1068
+ if (!configPath) throw new Error("audit: --config <path> is required");
1069
+ const auditDir = defaultAuditDir(configPath);
1070
+ const ts = parseDate(values.date);
1071
+ const action = positionals[0];
1072
+ if (action === "sessions") {
1073
+ const sessions2 = listAuditSessions(auditDir, ts);
1074
+ if (sessions2.length === 0) {
1075
+ console.info("No audit body shards found. Is `captureBodies` enabled?");
1076
+ return;
1077
+ }
1078
+ console.info(["DAY", "SESSION", "TURNS", "SIZE", "ARCHIVED"].join(" "));
1079
+ for (const s of sessions2) {
1080
+ console.info(
1081
+ [s.day, s.sessionKey, String(s.turns), formatBytes(s.bytes), s.compressed ? "gz" : "-"].join(" ")
1082
+ );
1083
+ }
1084
+ return;
1085
+ }
1086
+ if (action === "show") {
1087
+ const sessionKey = values.session;
1088
+ if (!sessionKey) throw new Error("audit show: --session <key> is required");
1089
+ if (values.id) {
1090
+ const body = readAuditBody(auditDir, { id: values.id, sessionKey, ...ts !== void 0 ? { ts } : {} });
1091
+ if (body.requestBody === void 0 && body.responseBody === void 0) {
1092
+ throw new Error(`audit show: no body found for record ${values.id}`);
1093
+ }
1094
+ if (body.requestBody !== void 0) console.info(`--- request ${values.id} ---
1095
+ ${body.requestBody}`);
1096
+ if (body.responseBody !== void 0) console.info(`--- response ${values.id} ---
1097
+ ${body.responseBody}`);
1098
+ return;
1099
+ }
1100
+ const turns = readAuditSessionTurns(auditDir, sessionKey, ts);
1101
+ if (turns.length === 0) throw new Error(`audit show: no shard found for session ${sessionKey}`);
1102
+ let stream = -1;
1103
+ for (const turn of turns) {
1104
+ const when = new Date(turn.ts).toISOString();
1105
+ if (turn.stream !== stream) {
1106
+ stream = turn.stream;
1107
+ console.info(`
1108
+ ########## stream ${stream} ##########`);
1109
+ }
1110
+ if (turn.diverged) {
1111
+ console.info("=== prefix diverged here (system prompt changed, or a restart reused this session) ===");
1112
+ }
1113
+ if (turn.requestBody !== void 0) {
1114
+ console.info(`--- request ${turn.id} @ ${when} ---
1115
+ ${turn.requestBody}`);
1116
+ }
1117
+ if (turn.responseBody !== void 0) {
1118
+ console.info(`--- response ${turn.id} @ ${when} ---
1119
+ ${turn.responseBody}`);
1120
+ }
1121
+ }
1122
+ return;
1123
+ }
1124
+ if (action === "compact") {
1125
+ const todayDir = auditDayDirName(Date.now());
1126
+ let names;
1127
+ try {
1128
+ names = (0, import_node_fs5.readdirSync)(auditDir).filter(isAuditDayDir).sort();
1129
+ } catch {
1130
+ names = [];
1131
+ }
1132
+ const targets = ts !== void 0 ? names.filter((name) => name === auditDayDirName(ts)) : names.filter((name) => name !== todayDir);
1133
+ if (targets.length === 0) {
1134
+ console.info("Nothing to compact (today is skipped; a day is compacted once).");
1135
+ return;
1136
+ }
1137
+ let shards = 0;
1138
+ let saved = 0;
1139
+ for (const name of targets) {
1140
+ if (name === todayDir) {
1141
+ console.info(`Skipping ${name}: the current day is still being written.`);
1142
+ continue;
1143
+ }
1144
+ const result = compactAuditDay((0, import_node_path5.join)(auditDir, name));
1145
+ shards += result.shards;
1146
+ saved += result.savedBytes;
1147
+ console.info(`${name}: ${result.shards} shard(s), ${result.anchors} anchor(s), ${formatBytes(result.savedBytes)} saved`);
1148
+ }
1149
+ console.info(`Done: ${shards} shard(s) rewritten, ${formatBytes(saved)} saved.`);
1150
+ return;
1151
+ }
1152
+ throw new Error("audit: expected `sessions`, `show`, or `compact` (see `omnicross help`)");
1153
+ }
1154
+
1155
+ // src/commands/import-ccr.ts
1156
+ var import_node_fs7 = require("fs");
1157
+ var import_node_util2 = require("util");
1158
+
1159
+ // src/ccr-import.ts
1160
+ function parseCcrConfig(raw) {
1161
+ if (!raw || typeof raw !== "object") {
1162
+ throw new Error("CCR config: top-level value must be an object");
1163
+ }
1164
+ const obj = raw;
1165
+ const Providers = Array.isArray(obj["Providers"]) ? obj["Providers"] : [];
1166
+ const Router = obj["Router"] && typeof obj["Router"] === "object" ? obj["Router"] : {};
1167
+ return { Providers, Router };
1168
+ }
1169
+ function inferApiFormat(provider) {
1170
+ const hay = `${provider.api_base_url ?? ""} ${provider.name ?? ""}`.toLowerCase();
1171
+ if (hay.includes("anthropic") || hay.includes("claude")) {
1172
+ return { format: "anthropic", ambiguous: false };
1173
+ }
1174
+ if (hay.includes("generativelanguage") || hay.includes("gemini") || hay.includes("google")) {
1175
+ return { format: "gemini", ambiguous: false };
1176
+ }
1177
+ if (hay.includes("/responses")) {
1178
+ return { format: "openai-response", ambiguous: false };
1179
+ }
1180
+ if (hay.includes("openai") || hay.includes("/v1") || hay.includes("chat/completions")) {
1181
+ return { format: "openai", ambiguous: false };
1182
+ }
1183
+ return { format: "openai", ambiguous: true };
1184
+ }
1185
+ function mapProviders(providers, notes) {
1186
+ const rows = [];
1187
+ for (const [i, p] of providers.entries()) {
1188
+ const id = p.name?.trim();
1189
+ if (!id) {
1190
+ notes.push(`Providers[${i}] has no name \u2014 skipped.`);
1191
+ continue;
1192
+ }
1193
+ const { format, ambiguous } = inferApiFormat(p);
1194
+ if (ambiguous) {
1195
+ notes.push(
1196
+ `Provider '${id}': could not infer apiFormat from base URL \u2014 defaulted to 'openai'. Edit the config if this provider speaks a different wire format.`
1197
+ );
1198
+ }
1199
+ rows.push({
1200
+ id,
1201
+ apiFormat: format,
1202
+ baseUrl: p.api_base_url ?? "",
1203
+ apiKey: p.api_key ?? "",
1204
+ models: Array.isArray(p.models) ? p.models : void 0
1205
+ });
1206
+ }
1207
+ return rows;
1208
+ }
1209
+ function noteRouterRoles(router, notes) {
1210
+ if (router.think) {
1211
+ notes.push(`Router.think \u2192 folded into 'default' (omnicross has no think slot).`);
1212
+ }
1213
+ if (router.longContext) {
1214
+ notes.push(
1215
+ `Router.longContext \u2192 folded into 'default' (no longContext slot; longContextThreshold dropped).`
1216
+ );
1217
+ }
1218
+ if (router.image) {
1219
+ notes.push(`Router.image \u2192 mapped to 'vision' (CCR forceUseImageAgent dropped).`);
1220
+ }
1221
+ if (router.webSearch) {
1222
+ notes.push(
1223
+ `Router.webSearch \u2192 DROPPED. omnicross injects web search via an interception port rather than routing to a natively-online model; the CCR webSearch model ('${router.webSearch}') was not carried over.`
1224
+ );
1225
+ }
1226
+ }
1227
+ function mapCcrToOmnicross(ccr) {
1228
+ const notes = [];
1229
+ const providers = mapProviders(ccr.Providers ?? [], notes);
1230
+ noteRouterRoles(ccr.Router ?? {}, notes);
1231
+ return { config: { providers }, notes };
1232
+ }
1233
+
461
1234
  // src/config.ts
1235
+ var import_node_fs6 = require("fs");
462
1236
  var DEFAULT_ADMIN_PORT = 8766;
463
1237
  function validateAdmin(raw) {
464
1238
  if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
@@ -520,6 +1294,35 @@ function validateApiKeys(raw) {
520
1294
  }
521
1295
  return out.length > 0 ? out : void 0;
522
1296
  }
1297
+ var THINK_LEVELS = /* @__PURE__ */ new Set([
1298
+ "none",
1299
+ "minimal",
1300
+ "low",
1301
+ "medium",
1302
+ "high",
1303
+ "xhigh",
1304
+ "max"
1305
+ ]);
1306
+ function validateThinkingLevels(raw) {
1307
+ if (!Array.isArray(raw)) return void 0;
1308
+ if (!raw.every((level) => typeof level === "string" && THINK_LEVELS.has(level))) {
1309
+ return void 0;
1310
+ }
1311
+ return [...raw];
1312
+ }
1313
+ function validateThinkingTokenLimit(raw) {
1314
+ if (!raw || typeof raw !== "object" || Array.isArray(raw)) return void 0;
1315
+ const bounds = raw;
1316
+ const min = bounds["min"];
1317
+ const max = bounds["max"];
1318
+ if (typeof min !== "number" || !Number.isFinite(min) || !Number.isInteger(min) || min < 0) {
1319
+ return void 0;
1320
+ }
1321
+ if (typeof max !== "number" || !Number.isFinite(max) || !Number.isInteger(max) || max < min) {
1322
+ return void 0;
1323
+ }
1324
+ return { min, max };
1325
+ }
523
1326
  function validateModelConfigs(raw) {
524
1327
  if (!Array.isArray(raw)) return void 0;
525
1328
  const out = [];
@@ -534,6 +1337,10 @@ function validateModelConfigs(raw) {
534
1337
  if (typeof m["enabled"] === "boolean") entry.enabled = m["enabled"];
535
1338
  if (typeof m["vision"] === "boolean") entry.vision = m["vision"];
536
1339
  if (typeof m["reasoning"] === "boolean") entry.reasoning = m["reasoning"];
1340
+ const thinkingLevels = validateThinkingLevels(m["thinkingLevels"]);
1341
+ if (thinkingLevels) entry.thinkingLevels = thinkingLevels;
1342
+ const thinkingTokenLimit = validateThinkingTokenLimit(m["thinkingTokenLimit"]);
1343
+ if (thinkingTokenLimit) entry.thinkingTokenLimit = thinkingTokenLimit;
537
1344
  out.push(entry);
538
1345
  }
539
1346
  return out.length > 0 ? out : void 0;
@@ -718,7 +1525,7 @@ function setSecretBox(box) {
718
1525
  function loadConfig(path2) {
719
1526
  let raw;
720
1527
  try {
721
- raw = (0, import_node_fs2.readFileSync)(path2, "utf8");
1528
+ raw = (0, import_node_fs6.readFileSync)(path2, "utf8");
722
1529
  } catch {
723
1530
  throw new Error(`config: cannot read file at '${path2}'`);
724
1531
  }
@@ -733,48 +1540,12 @@ function loadConfig(path2) {
733
1540
  }
734
1541
  function saveConfig(path2, cfg) {
735
1542
  const toWrite = secretBox ? encryptConfigSecrets(cfg, secretBox) : cfg;
736
- (0, import_node_fs2.writeFileSync)(path2, JSON.stringify(toWrite, null, 2) + "\n", "utf8");
737
- }
738
-
739
- // src/commands/paths.ts
740
- var import_node_path2 = require("path");
741
- function defaultKeysPath(configPath) {
742
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "keys.json");
743
- }
744
- function defaultVouchersPath(configPath) {
745
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "vouchers.json");
746
- }
747
- function defaultTokensPath(configPath) {
748
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "tokens.json");
749
- }
750
- function defaultIntegrationsPath(configPath) {
751
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "integrations.json");
752
- }
753
- function defaultPricingPath(configPath) {
754
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "pricing.json");
755
- }
756
- function defaultPricingRefreshStatePath(configPath) {
757
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "pricing-refresh.json");
758
- }
759
- function defaultAccountAllowancePath(configPath) {
760
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "allowance-cache.json");
761
- }
762
- function defaultUsageEventsPath(configPath) {
763
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "usage-events.jsonl");
764
- }
765
- function defaultAuditDir(configPath) {
766
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "audit");
767
- }
768
- function defaultBillingDir(configPath) {
769
- return (0, import_node_path2.join)((0, import_node_path2.dirname)(configPath), "billing");
770
- }
771
- function resolveSecretBox(masterKeyFilePath) {
772
- return new SecretBox(() => resolveMasterKey({ keyFilePath: masterKeyFilePath }));
1543
+ (0, import_node_fs6.writeFileSync)(path2, JSON.stringify(toWrite, null, 2) + "\n", "utf8");
773
1544
  }
774
1545
 
775
1546
  // src/commands/import-ccr.ts
776
1547
  async function runImportCcr(argv) {
777
- const { values, positionals } = (0, import_node_util.parseArgs)({
1548
+ const { values, positionals } = (0, import_node_util2.parseArgs)({
778
1549
  args: argv,
779
1550
  options: {
780
1551
  out: { type: "string", short: "o" },
@@ -789,7 +1560,7 @@ async function runImportCcr(argv) {
789
1560
  const outPath = values.out ?? "omnicross.config.json";
790
1561
  let raw;
791
1562
  try {
792
- raw = JSON.parse((0, import_node_fs3.readFileSync)(ccrPath, "utf8"));
1563
+ raw = JSON.parse((0, import_node_fs7.readFileSync)(ccrPath, "utf8"));
793
1564
  } catch {
794
1565
  throw new Error(`import-ccr: cannot read or parse '${ccrPath}'`);
795
1566
  }
@@ -810,19 +1581,19 @@ async function runImportCcr(argv) {
810
1581
  }
811
1582
 
812
1583
  // src/commands/integrations.ts
813
- var import_node_path5 = require("path");
814
- var import_node_util2 = require("util");
1584
+ var import_node_path8 = require("path");
1585
+ var import_node_util3 = require("util");
815
1586
 
816
1587
  // src/integrations/IntegrationManager.ts
817
1588
  var import_node_crypto3 = require("crypto");
818
- var import_node_fs5 = require("fs");
1589
+ var import_node_fs9 = require("fs");
819
1590
  var import_node_os2 = require("os");
820
- var import_node_path4 = require("path");
1591
+ var import_node_path7 = require("path");
821
1592
  var import_core = require("@omnicross/core");
822
1593
 
823
1594
  // src/integrations/IntegrationStateStore.ts
824
- var import_node_fs4 = require("fs");
825
- var import_node_path3 = require("path");
1595
+ var import_node_fs8 = require("fs");
1596
+ var import_node_path6 = require("path");
826
1597
  var EMPTY_STATE = { version: 1, clients: {} };
827
1598
  var IntegrationStateStore = class {
828
1599
  constructor(path2, box) {
@@ -832,10 +1603,10 @@ var IntegrationStateStore = class {
832
1603
  path;
833
1604
  box;
834
1605
  load() {
835
- if (!(0, import_node_fs4.existsSync)(this.path)) return { ...EMPTY_STATE, clients: {} };
1606
+ if (!(0, import_node_fs8.existsSync)(this.path)) return { ...EMPTY_STATE, clients: {} };
836
1607
  let raw;
837
1608
  try {
838
- raw = JSON.parse((0, import_node_fs4.readFileSync)(this.path, "utf8"));
1609
+ raw = JSON.parse((0, import_node_fs8.readFileSync)(this.path, "utf8"));
839
1610
  } catch {
840
1611
  throw new Error(`integration state '${this.path}' is not valid JSON`);
841
1612
  }
@@ -903,21 +1674,21 @@ function isManagedFileRecord(value) {
903
1674
  return typeof row.path === "string" && typeof row.originalExisted === "boolean" && typeof row.originalContent === "string" && typeof row.originalHash === "string" && typeof row.installedHash === "string";
904
1675
  }
905
1676
  function atomicWrite(path2, content) {
906
- (0, import_node_fs4.mkdirSync)((0, import_node_path3.dirname)(path2), { recursive: true });
1677
+ (0, import_node_fs8.mkdirSync)((0, import_node_path6.dirname)(path2), { recursive: true });
907
1678
  const temp = `${path2}.tmp-${process.pid}-${Date.now()}`;
908
- (0, import_node_fs4.writeFileSync)(temp, content, { encoding: "utf8", mode: 384 });
1679
+ (0, import_node_fs8.writeFileSync)(temp, content, { encoding: "utf8", mode: 384 });
909
1680
  try {
910
- (0, import_node_fs4.renameSync)(temp, path2);
1681
+ (0, import_node_fs8.renameSync)(temp, path2);
911
1682
  } catch (error) {
912
1683
  try {
913
- (0, import_node_fs4.unlinkSync)(temp);
1684
+ (0, import_node_fs8.unlinkSync)(temp);
914
1685
  } catch {
915
1686
  }
916
1687
  throw error;
917
1688
  } finally {
918
- if ((0, import_node_fs4.existsSync)(path2)) {
1689
+ if ((0, import_node_fs8.existsSync)(path2)) {
919
1690
  try {
920
- (0, import_node_fs4.chmodSync)(path2, 384);
1691
+ (0, import_node_fs8.chmodSync)(path2, 384);
921
1692
  } catch {
922
1693
  }
923
1694
  }
@@ -1109,7 +1880,7 @@ var IntegrationManager = class {
1109
1880
  async plan(client, configPath = this.defaultConfigPath(client)) {
1110
1881
  const state = this.options.stateStore.load();
1111
1882
  const record = state.clients[client];
1112
- const target = record?.configPath ?? (0, import_node_path4.resolve)(configPath);
1883
+ const target = record?.configPath ?? (0, import_node_path7.resolve)(configPath);
1113
1884
  const status = this.statusFor(client, state, await this.isKeyUsable(state));
1114
1885
  const changes = client === "codex" ? [
1115
1886
  "model_provider",
@@ -1132,7 +1903,7 @@ var IntegrationManager = class {
1132
1903
  };
1133
1904
  }
1134
1905
  async install(client, configPath = this.defaultConfigPath(client)) {
1135
- const target = (0, import_node_path4.resolve)(configPath);
1906
+ const target = (0, import_node_path7.resolve)(configPath);
1136
1907
  const state = this.options.stateStore.load();
1137
1908
  const existingRecord = state.clients[client];
1138
1909
  if (existingRecord) {
@@ -1409,10 +2180,10 @@ var IntegrationManager = class {
1409
2180
  };
1410
2181
  }
1411
2182
  defaultConfigPath(client) {
1412
- return client === "codex" ? (0, import_node_path4.join)(this.homeDir, ".codex", "config.toml") : (0, import_node_path4.join)(this.homeDir, ".claude", "settings.json");
2183
+ return client === "codex" ? (0, import_node_path7.join)(this.homeDir, ".codex", "config.toml") : (0, import_node_path7.join)(this.homeDir, ".claude", "settings.json");
1413
2184
  }
1414
2185
  codexAuthPathForConfig(configPath) {
1415
- return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "auth.json");
2186
+ return (0, import_node_path7.join)((0, import_node_path7.dirname)(configPath), "auth.json");
1416
2187
  }
1417
2188
  renderInstalled(client, base, secret) {
1418
2189
  if (client === "claude") {
@@ -1425,7 +2196,7 @@ var IntegrationManager = class {
1425
2196
  }
1426
2197
  };
1427
2198
  function readOptional(path2) {
1428
- return (0, import_node_fs5.existsSync)(path2) ? (0, import_node_fs5.readFileSync)(path2, "utf8") : null;
2199
+ return (0, import_node_fs9.existsSync)(path2) ? (0, import_node_fs9.readFileSync)(path2, "utf8") : null;
1429
2200
  }
1430
2201
  function sha256(value) {
1431
2202
  return (0, import_node_crypto3.createHash)("sha256").update(value, "utf8").digest("hex");
@@ -1489,7 +2260,7 @@ function writeOptional(path2, content) {
1489
2260
  atomicWrite(path2, content);
1490
2261
  return;
1491
2262
  }
1492
- if ((0, import_node_fs5.existsSync)(path2)) (0, import_node_fs5.unlinkSync)(path2);
2263
+ if ((0, import_node_fs9.existsSync)(path2)) (0, import_node_fs9.unlinkSync)(path2);
1493
2264
  }
1494
2265
  function assertLoopbackGatewayUrl(value) {
1495
2266
  let url;
@@ -1506,7 +2277,7 @@ function assertLoopbackGatewayUrl(value) {
1506
2277
  }
1507
2278
 
1508
2279
  // src/ports/JsonOutboundKeyDb.ts
1509
- var import_node_fs6 = require("fs");
2280
+ var import_node_fs10 = require("fs");
1510
2281
  var JsonOutboundKeyDb = class {
1511
2282
  /**
1512
2283
  * @param secretBox OPTIONAL reversible-secret codec. When present, a created
@@ -1639,16 +2410,16 @@ var JsonOutboundKeyDb = class {
1639
2410
  }
1640
2411
  /** Read the key rows, tolerating a missing/corrupt file (→ empty list). */
1641
2412
  readRows() {
1642
- if (!(0, import_node_fs6.existsSync)(this.keysPath)) return [];
2413
+ if (!(0, import_node_fs10.existsSync)(this.keysPath)) return [];
1643
2414
  try {
1644
- const parsed = JSON.parse((0, import_node_fs6.readFileSync)(this.keysPath, "utf8"));
2415
+ const parsed = JSON.parse((0, import_node_fs10.readFileSync)(this.keysPath, "utf8"));
1645
2416
  return Array.isArray(parsed) ? parsed : [];
1646
2417
  } catch {
1647
2418
  return [];
1648
2419
  }
1649
2420
  }
1650
2421
  writeRows(rows) {
1651
- (0, import_node_fs6.writeFileSync)(this.keysPath, JSON.stringify(rows, null, 2) + "\n", "utf8");
2422
+ (0, import_node_fs10.writeFileSync)(this.keysPath, JSON.stringify(rows, null, 2) + "\n", "utf8");
1652
2423
  }
1653
2424
  };
1654
2425
  function applyPolicyField(row, field, value) {
@@ -1659,7 +2430,7 @@ function applyPolicyField(row, field, value) {
1659
2430
 
1660
2431
  // src/commands/integrations.ts
1661
2432
  async function runIntegrations(argv) {
1662
- const { values, positionals } = (0, import_node_util2.parseArgs)({
2433
+ const { values, positionals } = (0, import_node_util3.parseArgs)({
1663
2434
  args: argv,
1664
2435
  options: {
1665
2436
  config: { type: "string", short: "c" },
@@ -1680,7 +2451,7 @@ async function runIntegrations(argv) {
1680
2451
  const savedUrl = saved.clients.codex?.gatewayBaseUrl ?? saved.clients.claude?.gatewayBaseUrl;
1681
2452
  const gatewayBaseUrl = values["gateway-base-url"] ?? savedUrl ?? "http://127.0.0.1:8765";
1682
2453
  const manager = new IntegrationManager({
1683
- configPath: (0, import_node_path5.resolve)(values.config),
2454
+ configPath: (0, import_node_path8.resolve)(values.config),
1684
2455
  gatewayBaseUrl,
1685
2456
  keyDb: new JsonOutboundKeyDb(defaultKeysPath(values.config)),
1686
2457
  stateStore: store
@@ -1709,10 +2480,10 @@ function isClient(value) {
1709
2480
  }
1710
2481
 
1711
2482
  // src/commands/keys.ts
1712
- var import_node_util3 = require("util");
2483
+ var import_node_util4 = require("util");
1713
2484
  var import_outbound_api = require("@omnicross/core/outbound-api");
1714
2485
  async function runKeys(argv) {
1715
- const { values, positionals } = (0, import_node_util3.parseArgs)({
2486
+ const { values, positionals } = (0, import_node_util4.parseArgs)({
1716
2487
  args: argv,
1717
2488
  options: { config: { type: "string", short: "c" } },
1718
2489
  allowPositionals: true
@@ -1766,14 +2537,14 @@ async function keysRevoke(db, id) {
1766
2537
  // src/commands/launch.ts
1767
2538
  var import_node_child_process2 = require("child_process");
1768
2539
  var import_node_crypto15 = require("crypto");
1769
- var import_node_fs25 = require("fs");
1770
- var import_node_path17 = require("path");
1771
- var import_node_util4 = require("util");
2540
+ var import_node_fs29 = require("fs");
2541
+ var import_node_path20 = require("path");
2542
+ var import_node_util5 = require("util");
1772
2543
  var import_cli_launcher3 = require("@omnicross/cli-launcher");
1773
2544
  var import_provider_proxy5 = require("@omnicross/core/provider-proxy");
1774
2545
 
1775
2546
  // src/bootstrap.ts
1776
- var import_node_fs24 = require("fs");
2547
+ var import_node_fs28 = require("fs");
1777
2548
  var import_audit_types = require("@omnicross/contracts/audit-types");
1778
2549
  var import_billing_types = require("@omnicross/contracts/billing-types");
1779
2550
  var import_GeminiCodeAssistProjectResolver = require("@omnicross/core/auth/GeminiCodeAssistProjectResolver");
@@ -1789,7 +2560,7 @@ var import_gemini_code_assist_resolver = require("@omnicross/core/ports/gemini-c
1789
2560
  var import_provider_proxy4 = require("@omnicross/core/provider-proxy");
1790
2561
  var import_cli_launcher2 = require("@omnicross/cli-launcher");
1791
2562
  var import_outbound_api6 = require("@omnicross/core/outbound-api");
1792
- var import_usage = require("@omnicross/core/usage");
2563
+ var import_usage2 = require("@omnicross/core/usage");
1793
2564
  var import_subscriptions4 = require("@omnicross/subscriptions");
1794
2565
 
1795
2566
  // src/admin/accountsCodexOAuth.ts
@@ -2282,8 +3053,8 @@ var ClaudeAllowanceRefreshScheduler = class {
2282
3053
 
2283
3054
  // src/allowance/JsonAccountAllowancePersistence.ts
2284
3055
  var import_node_crypto5 = require("crypto");
2285
- var import_node_fs7 = require("fs");
2286
- var import_node_path6 = require("path");
3056
+ var import_node_fs11 = require("fs");
3057
+ var import_node_path9 = require("path");
2287
3058
  var import_AccountAllowanceStore3 = require("@omnicross/core/pipeline/AccountAllowanceStore");
2288
3059
  var ACCOUNT_ALLOWANCE_CACHE_VERSION = 1;
2289
3060
  var MAX_PERSISTED_ALLOWANCE_SNAPSHOTS = 256;
@@ -2295,10 +3066,10 @@ var JsonAccountAllowancePersistence = class {
2295
3066
  cachePath;
2296
3067
  /** Read only the `snapshots` payload; all row validation remains defensive. */
2297
3068
  load() {
2298
- if (!(0, import_node_fs7.existsSync)(this.cachePath)) return [];
3069
+ if (!(0, import_node_fs11.existsSync)(this.cachePath)) return [];
2299
3070
  try {
2300
- if ((0, import_node_fs7.statSync)(this.cachePath).size > MAX_ALLOWANCE_CACHE_BYTES) return [];
2301
- const raw = (0, import_node_fs7.readFileSync)(this.cachePath, "utf8");
3071
+ if ((0, import_node_fs11.statSync)(this.cachePath).size > MAX_ALLOWANCE_CACHE_BYTES) return [];
3072
+ const raw = (0, import_node_fs11.readFileSync)(this.cachePath, "utf8");
2302
3073
  if (!raw.trim()) return [];
2303
3074
  const parsed = JSON.parse(raw);
2304
3075
  if (Array.isArray(parsed)) return parsed;
@@ -2326,13 +3097,13 @@ var JsonAccountAllowancePersistence = class {
2326
3097
  if (Buffer.byteLength(serialized, "utf8") > MAX_ALLOWANCE_CACHE_BYTES) {
2327
3098
  throw new Error("account allowance cache exceeds its size limit");
2328
3099
  }
2329
- (0, import_node_fs7.mkdirSync)((0, import_node_path6.dirname)(this.cachePath), { recursive: true });
3100
+ (0, import_node_fs11.mkdirSync)((0, import_node_path9.dirname)(this.cachePath), { recursive: true });
2330
3101
  const temporaryPath = `${this.cachePath}.${process.pid}.${(0, import_node_crypto5.randomUUID)()}.tmp`;
2331
3102
  try {
2332
- (0, import_node_fs7.writeFileSync)(temporaryPath, serialized, { encoding: "utf8", flag: "wx" });
2333
- (0, import_node_fs7.renameSync)(temporaryPath, this.cachePath);
3103
+ (0, import_node_fs11.writeFileSync)(temporaryPath, serialized, { encoding: "utf8", flag: "wx" });
3104
+ (0, import_node_fs11.renameSync)(temporaryPath, this.cachePath);
2334
3105
  } finally {
2335
- (0, import_node_fs7.rmSync)(temporaryPath, { force: true });
3106
+ (0, import_node_fs11.rmSync)(temporaryPath, { force: true });
2336
3107
  }
2337
3108
  }
2338
3109
  };
@@ -2370,6 +3141,37 @@ function handleAuditQuery(req, res, reader) {
2370
3141
  res.writeHead(200, { "Content-Type": "application/json" });
2371
3142
  res.end(JSON.stringify({ records }));
2372
3143
  }
3144
+ function handleAuditBodyQuery(req, res, reader) {
3145
+ const url = new URL(req.url ?? "/", "http://localhost");
3146
+ const id = url.searchParams.get("id")?.trim();
3147
+ const sessionKey = url.searchParams.get("session")?.trim();
3148
+ if (!id || !sessionKey) {
3149
+ res.writeHead(400, { "Content-Type": "application/json" });
3150
+ res.end(JSON.stringify({ error: "id and session are required" }));
3151
+ return;
3152
+ }
3153
+ const query2 = { id, sessionKey };
3154
+ const ts = intParam(url.searchParams.get("ts"));
3155
+ if (ts !== void 0) query2.ts = ts;
3156
+ const body = reader ? reader(query2) : {};
3157
+ res.writeHead(200, { "Content-Type": "application/json" });
3158
+ res.end(JSON.stringify(body));
3159
+ }
3160
+ function handleAuditCompact(res, compact) {
3161
+ if (!compact) {
3162
+ res.writeHead(200, { "Content-Type": "application/json" });
3163
+ res.end(JSON.stringify({ days: 0, shards: 0, savedBytes: 0 }));
3164
+ return;
3165
+ }
3166
+ try {
3167
+ const result = compact();
3168
+ res.writeHead(200, { "Content-Type": "application/json" });
3169
+ res.end(JSON.stringify(result));
3170
+ } catch (error) {
3171
+ res.writeHead(500, { "Content-Type": "application/json" });
3172
+ res.end(JSON.stringify({ error: error instanceof Error ? error.message : "compaction failed" }));
3173
+ }
3174
+ }
2373
3175
  async function handleAuditStatsQuery(req, res, reader) {
2374
3176
  const url = new URL(req.url ?? "/", "http://localhost");
2375
3177
  const query2 = {};
@@ -3100,10 +3902,10 @@ async function exchangeGemini(code, codeVerifier, exchangeFetch) {
3100
3902
  // src/admin/cliLaunch.ts
3101
3903
  var import_node_child_process = require("child_process");
3102
3904
  var import_node_crypto6 = require("crypto");
3103
- var import_node_fs8 = require("fs");
3905
+ var import_node_fs12 = require("fs");
3104
3906
  var import_node_net = require("net");
3105
3907
  var import_node_os3 = require("os");
3106
- var import_node_path7 = require("path");
3908
+ var import_node_path10 = require("path");
3107
3909
  var import_cli_launcher = require("@omnicross/cli-launcher");
3108
3910
  var import_provider_proxy2 = require("@omnicross/core/provider-proxy");
3109
3911
 
@@ -3150,10 +3952,10 @@ function isLaunchCliId(id) {
3150
3952
  return id !== void 0 && LAUNCHABLE_IDS.has(id);
3151
3953
  }
3152
3954
  function probeDefault(candidate) {
3153
- const segments = (process.env["PATH"] ?? "").split(import_node_path7.delimiter).filter(Boolean);
3955
+ const segments = (process.env["PATH"] ?? "").split(import_node_path10.delimiter).filter(Boolean);
3154
3956
  for (const seg of segments) {
3155
- const full = (0, import_node_path7.join)(seg, candidate);
3156
- if ((0, import_node_fs8.existsSync)(full)) return full;
3957
+ const full = (0, import_node_path10.join)(seg, candidate);
3958
+ if ((0, import_node_fs12.existsSync)(full)) return full;
3157
3959
  }
3158
3960
  return null;
3159
3961
  }
@@ -3257,10 +4059,10 @@ function openTerminal({ cli, command, extraArgs, env, cwd, platform, onFailure }
3257
4059
  const runLine = [command, ...extraArgs].map(shq).join(" ");
3258
4060
  const script = `${cwd ? `cd ${shq(cwd)}; ` : ""}${runLine}`;
3259
4061
  if (platform === "darwin") {
3260
- const launchDir = (0, import_node_fs8.mkdtempSync)((0, import_node_path7.join)((0, import_node_os3.tmpdir)(), "omnicross-terminal-"));
3261
- const commandFile = (0, import_node_path7.join)(launchDir, "launch.command");
3262
- const bootstrapFile = (0, import_node_path7.join)(launchDir, "bootstrap.cjs");
3263
- const socketPath = macIpc.socketPath ?? (0, import_node_path7.join)(launchDir, "descriptor.sock");
4062
+ const launchDir = (0, import_node_fs12.mkdtempSync)((0, import_node_path10.join)((0, import_node_os3.tmpdir)(), "omnicross-terminal-"));
4063
+ const commandFile = (0, import_node_path10.join)(launchDir, "launch.command");
4064
+ const bootstrapFile = (0, import_node_path10.join)(launchDir, "bootstrap.cjs");
4065
+ const socketPath = macIpc.socketPath ?? (0, import_node_path10.join)(launchDir, "descriptor.sock");
3264
4066
  const openerEnv = { ...process.env };
3265
4067
  for (const key of Object.keys(env)) delete openerEnv[key];
3266
4068
  let claimed = false;
@@ -3319,7 +4121,7 @@ function openTerminal({ cli, command, extraArgs, env, cwd, platform, onFailure }
3319
4121
  if (macIpc.removeArtifacts) {
3320
4122
  macIpc.removeArtifacts(launchDir);
3321
4123
  } else {
3322
- (0, import_node_fs8.rmSync)(launchDir, {
4124
+ (0, import_node_fs12.rmSync)(launchDir, {
3323
4125
  recursive: true,
3324
4126
  force: true,
3325
4127
  maxRetries: 3,
@@ -3330,23 +4132,23 @@ function openTerminal({ cli, command, extraArgs, env, cwd, platform, onFailure }
3330
4132
  }
3331
4133
  };
3332
4134
  try {
3333
- (0, import_node_fs8.writeFileSync)(bootstrapFile, MAC_TERMINAL_BOOTSTRAP_SOURCE, { encoding: "utf8", mode: 448 });
3334
- (0, import_node_fs8.writeFileSync)(commandFile, `#!/bin/bash
4135
+ (0, import_node_fs12.writeFileSync)(bootstrapFile, MAC_TERMINAL_BOOTSTRAP_SOURCE, { encoding: "utf8", mode: 448 });
4136
+ (0, import_node_fs12.writeFileSync)(commandFile, `#!/bin/bash
3335
4137
  rm -f -- "$0"
3336
4138
  exec ${shq(process.execPath)} ${shq(bootstrapFile)} ${shq(socketPath)} ${shq(launchDir)} ${shq(cwd ?? "")} ${runLine}
3337
4139
  `, {
3338
4140
  encoding: "utf8",
3339
4141
  mode: 448
3340
4142
  });
3341
- (0, import_node_fs8.chmodSync)(commandFile, 448);
3342
- (0, import_node_fs8.chmodSync)(bootstrapFile, 448);
4143
+ (0, import_node_fs12.chmodSync)(commandFile, 448);
4144
+ (0, import_node_fs12.chmodSync)(bootstrapFile, 448);
3343
4145
  server.once("error", handleLaunchFailure);
3344
4146
  server.listen(socketPath, () => {
3345
4147
  if (cleaned) return;
3346
4148
  try {
3347
4149
  macIpc.onListening?.();
3348
4150
  if (cleaned) return;
3349
- if (process.platform !== "win32") (0, import_node_fs8.chmodSync)(socketPath, 384);
4151
+ if (process.platform !== "win32") (0, import_node_fs12.chmodSync)(socketPath, 384);
3350
4152
  const opener = spawnProcess("open", ["-n", "-a", "Terminal", commandFile], {
3351
4153
  env: openerEnv,
3352
4154
  detached: true,
@@ -3992,6 +4794,7 @@ function applyAuditConfig(config) {
3992
4794
  } else {
3993
4795
  (0, import_auditSink.setAuditCaptureConfig)(null);
3994
4796
  (0, import_auditSink.setAuditSink)(null);
4797
+ writer?.reset();
3995
4798
  if (sweeper) {
3996
4799
  if (config) sweeper.configure(config);
3997
4800
  sweeper.dispose();
@@ -4578,6 +5381,7 @@ async function handleImport(body, deps) {
4578
5381
  }
4579
5382
 
4580
5383
  // src/admin/usagePricing.ts
5384
+ var import_usage = require("@omnicross/core/usage");
4581
5385
  var err4 = (status, message) => ({
4582
5386
  status,
4583
5387
  body: { error: { type: "admin_api_error", message } }
@@ -4603,6 +5407,9 @@ var BUCKET_SPAN_MS = {
4603
5407
  };
4604
5408
  var MAX_TIMESERIES_BUCKETS = 2e3;
4605
5409
  async function handleUsageGet(view, query2, deps) {
5410
+ if (view === "throughput") {
5411
+ return { status: 200, body: (0, import_usage.getSharedUsageThroughputTracker)().snapshot() };
5412
+ }
4606
5413
  const range = parseRange(query2);
4607
5414
  if (!isRange(range)) return range;
4608
5415
  switch (view) {
@@ -5405,6 +6212,12 @@ function parseModelConfigsInput(raw, existing) {
5405
6212
  else if (typeof prior?.vision === "boolean") entry.vision = prior.vision;
5406
6213
  if (typeof m["reasoning"] === "boolean") entry.reasoning = m["reasoning"];
5407
6214
  else if (typeof prior?.reasoning === "boolean") entry.reasoning = prior.reasoning;
6215
+ const thinkingLevels = validateThinkingLevels(m["thinkingLevels"]);
6216
+ if (thinkingLevels) entry.thinkingLevels = thinkingLevels;
6217
+ else if (prior?.thinkingLevels) entry.thinkingLevels = prior.thinkingLevels;
6218
+ const thinkingTokenLimit = validateThinkingTokenLimit(m["thinkingTokenLimit"]);
6219
+ if (thinkingTokenLimit) entry.thinkingTokenLimit = thinkingTokenLimit;
6220
+ else if (prior?.thinkingTokenLimit) entry.thinkingTokenLimit = prior.thinkingTokenLimit;
5408
6221
  out.push(entry);
5409
6222
  }
5410
6223
  return out.length > 0 ? out : void 0;
@@ -6230,10 +7043,10 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
6230
7043
  }
6231
7044
 
6232
7045
  // src/admin/uiStatic.ts
6233
- var import_node_fs9 = require("fs");
7046
+ var import_node_fs13 = require("fs");
6234
7047
  var import_promises = require("fs/promises");
6235
7048
  var import_node_module = require("module");
6236
- var import_node_path8 = __toESM(require("path"), 1);
7049
+ var import_node_path11 = __toESM(require("path"), 1);
6237
7050
  var import_meta = {};
6238
7051
  var CONTENT_TYPES = {
6239
7052
  ".html": "text/html; charset=utf-8",
@@ -6254,13 +7067,13 @@ var CONTENT_TYPES = {
6254
7067
  function resolveUiDist() {
6255
7068
  const fromEnv = process.env["OMNICROSS_UI_DIST"];
6256
7069
  if (fromEnv) {
6257
- return (0, import_node_fs9.existsSync)(import_node_path8.default.join(fromEnv, "index.html")) ? import_node_path8.default.resolve(fromEnv) : null;
7070
+ return (0, import_node_fs13.existsSync)(import_node_path11.default.join(fromEnv, "index.html")) ? import_node_path11.default.resolve(fromEnv) : null;
6258
7071
  }
6259
7072
  try {
6260
7073
  const req = (0, import_node_module.createRequire)(typeof __filename !== "undefined" ? __filename : import_meta.url);
6261
7074
  const pkgJson = req.resolve("@omnicross/ui/package.json");
6262
- const dist = import_node_path8.default.join(import_node_path8.default.dirname(pkgJson), "dist");
6263
- return (0, import_node_fs9.existsSync)(import_node_path8.default.join(dist, "index.html")) ? dist : null;
7075
+ const dist = import_node_path11.default.join(import_node_path11.default.dirname(pkgJson), "dist");
7076
+ return (0, import_node_fs13.existsSync)(import_node_path11.default.join(dist, "index.html")) ? dist : null;
6264
7077
  } catch {
6265
7078
  return null;
6266
7079
  }
@@ -6302,16 +7115,16 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
6302
7115
  res.end(JSON.stringify({ error: { type: "bad_request", message: "invalid path" } }));
6303
7116
  return true;
6304
7117
  }
6305
- const filePath = import_node_path8.default.resolve(uiDist, rel === "" ? "index.html" : rel);
6306
- if (filePath !== uiDist && !filePath.startsWith(uiDist + import_node_path8.default.sep)) {
7118
+ const filePath = import_node_path11.default.resolve(uiDist, rel === "" ? "index.html" : rel);
7119
+ if (filePath !== uiDist && !filePath.startsWith(uiDist + import_node_path11.default.sep)) {
6307
7120
  res.writeHead(403, { "Content-Type": "application/json" });
6308
7121
  res.end(JSON.stringify({ error: { type: "forbidden", message: "path outside ui root" } }));
6309
7122
  return true;
6310
7123
  }
6311
7124
  let target = filePath;
6312
- if (!(0, import_node_fs9.existsSync)(target) || (0, import_node_fs9.statSync)(target).isDirectory()) {
6313
- if (import_node_path8.default.extname(rel) === "") {
6314
- target = import_node_path8.default.join(uiDist, "index.html");
7125
+ if (!(0, import_node_fs13.existsSync)(target) || (0, import_node_fs13.statSync)(target).isDirectory()) {
7126
+ if (import_node_path11.default.extname(rel) === "") {
7127
+ target = import_node_path11.default.join(uiDist, "index.html");
6315
7128
  } else {
6316
7129
  res.writeHead(404, { "Content-Type": "application/json" });
6317
7130
  res.end(JSON.stringify({ error: { type: "not_found", message: "no such ui asset" } }));
@@ -6319,14 +7132,14 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
6319
7132
  }
6320
7133
  }
6321
7134
  const body = await (0, import_promises.readFile)(target);
6322
- const type = CONTENT_TYPES[import_node_path8.default.extname(target).toLowerCase()] ?? "application/octet-stream";
7135
+ const type = CONTENT_TYPES[import_node_path11.default.extname(target).toLowerCase()] ?? "application/octet-stream";
6323
7136
  res.writeHead(200, { "Content-Type": type, "Content-Length": body.length });
6324
7137
  res.end(req.method === "HEAD" ? void 0 : body);
6325
7138
  return true;
6326
7139
  }
6327
7140
 
6328
7141
  // src/admin/version.ts
6329
- var DAEMON_VERSION = true ? "0.1.8" : "0.0.0-dev";
7142
+ var DAEMON_VERSION = true ? "0.1.10" : "0.0.0-dev";
6330
7143
 
6331
7144
  // src/admin/AdminServer.ts
6332
7145
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -6438,6 +7251,14 @@ var AdminServer = class {
6438
7251
  await handleAuditStatsQuery(req, res, this.deps.auditStatsReader);
6439
7252
  return;
6440
7253
  }
7254
+ if (path2 === "/admin/api/audit/body" && (req.method === "GET" || req.method === "HEAD")) {
7255
+ handleAuditBodyQuery(req, res, this.deps.auditBodyReader);
7256
+ return;
7257
+ }
7258
+ if (path2 === "/admin/api/audit/compact" && req.method === "POST") {
7259
+ handleAuditCompact(res, this.deps.auditCompactor);
7260
+ return;
7261
+ }
6441
7262
  if (path2 === "/admin/api/billing-status" && (req.method === "GET" || req.method === "HEAD")) {
6442
7263
  handleBillingStatus(res, this.deps.billingStatusReader);
6443
7264
  return;
@@ -6867,6 +7688,15 @@ function toLLMProvider(row) {
6867
7688
  api_base_url: row.baseUrl,
6868
7689
  api_key: resolvePreferredApiKey(row),
6869
7690
  models,
7691
+ modelConfigs: row.modelConfigs?.map((config) => ({
7692
+ id: config.id,
7693
+ name: config.name ?? config.id,
7694
+ enabled: config.enabled ?? true,
7695
+ vision: config.vision,
7696
+ reasoning: config.reasoning,
7697
+ thinkingLevels: config.thinkingLevels,
7698
+ thinkingTokenLimit: config.thinkingTokenLimit
7699
+ })),
6870
7700
  enabled: true,
6871
7701
  transformer,
6872
7702
  // app-parity-2 child 3: POPULATE the coding-plan endpoint onto the core
@@ -6893,7 +7723,7 @@ function toLLMProvider(row) {
6893
7723
  }
6894
7724
 
6895
7725
  // src/ports/ConfigurableLogger.ts
6896
- var import_node_fs10 = require("fs");
7726
+ var import_node_fs14 = require("fs");
6897
7727
  var LEVEL_ORDER = { error: 0, warn: 1, info: 2, debug: 3 };
6898
7728
  var RESERVED_JSON_KEYS = /* @__PURE__ */ new Set(["ts", "level", "msg", "error"]);
6899
7729
  var ConfigurableLogger = class {
@@ -6969,7 +7799,7 @@ var ConfigurableLogger = class {
6969
7799
  if (this.fileDisabled || !this.filePath) return null;
6970
7800
  if (this.fileStream) return this.fileStream;
6971
7801
  try {
6972
- const stream = (0, import_node_fs10.createWriteStream)(this.filePath, { flags: "a" });
7802
+ const stream = (0, import_node_fs14.createWriteStream)(this.filePath, { flags: "a" });
6973
7803
  stream.on("error", () => {
6974
7804
  this.fileDisabled = true;
6975
7805
  this.fileStream = null;
@@ -7038,7 +7868,7 @@ function safeStringify(value) {
7038
7868
  }
7039
7869
 
7040
7870
  // src/ports/JsonApiServerSettingsStore.ts
7041
- var import_node_fs11 = require("fs");
7871
+ var import_node_fs15 = require("fs");
7042
7872
  var import_outbound_api4 = require("@omnicross/core/outbound-api");
7043
7873
  var JsonApiServerSettingsStore = class {
7044
7874
  /**
@@ -7065,7 +7895,7 @@ var JsonApiServerSettingsStore = class {
7065
7895
  if (key !== import_outbound_api4.OUTBOUND_API_SERVER_CONFIG_KEY) return;
7066
7896
  const file = this.readFile();
7067
7897
  file.server = this.encryptSecrets(value);
7068
- (0, import_node_fs11.writeFileSync)(this.configPath, JSON.stringify(file, null, 2) + "\n", "utf8");
7898
+ (0, import_node_fs15.writeFileSync)(this.configPath, JSON.stringify(file, null, 2) + "\n", "utf8");
7069
7899
  }
7070
7900
  /** Encrypt the proxy passwords + webhook + billing secrets before persisting (no-op without a box). */
7071
7901
  encryptSecrets(config) {
@@ -7088,7 +7918,7 @@ var JsonApiServerSettingsStore = class {
7088
7918
  /** Read the config.json, tolerating a missing/corrupt file (→ empty shape). */
7089
7919
  readFile() {
7090
7920
  try {
7091
- const raw = (0, import_node_fs11.readFileSync)(this.configPath, "utf8");
7921
+ const raw = (0, import_node_fs15.readFileSync)(this.configPath, "utf8");
7092
7922
  const parsed = JSON.parse(raw);
7093
7923
  if (parsed && typeof parsed === "object") return parsed;
7094
7924
  } catch {
@@ -7099,7 +7929,7 @@ var JsonApiServerSettingsStore = class {
7099
7929
 
7100
7930
  // src/ports/JsonlUsageEventStore.ts
7101
7931
  var import_node_crypto11 = require("crypto");
7102
- var import_node_fs12 = require("fs");
7932
+ var import_node_fs16 = require("fs");
7103
7933
  var JsonlUsageEventStore = class {
7104
7934
  constructor(eventsPath, isPriced) {
7105
7935
  this.eventsPath = eventsPath;
@@ -7114,7 +7944,7 @@ var JsonlUsageEventStore = class {
7114
7944
  id: (0, import_node_crypto11.randomUUID)(),
7115
7945
  ts: input.ts ?? Date.now()
7116
7946
  };
7117
- (0, import_node_fs12.appendFileSync)(this.eventsPath, JSON.stringify(row) + "\n", "utf8");
7947
+ (0, import_node_fs16.appendFileSync)(this.eventsPath, JSON.stringify(row) + "\n", "utf8");
7118
7948
  return row.id;
7119
7949
  }
7120
7950
  async getTotals(range) {
@@ -7313,10 +8143,10 @@ var JsonlUsageEventStore = class {
7313
8143
  }
7314
8144
  /** Parse every line, skipping malformed/torn lines defensively. */
7315
8145
  readAllRows() {
7316
- if (!(0, import_node_fs12.existsSync)(this.eventsPath)) return [];
8146
+ if (!(0, import_node_fs16.existsSync)(this.eventsPath)) return [];
7317
8147
  let raw;
7318
8148
  try {
7319
- raw = (0, import_node_fs12.readFileSync)(this.eventsPath, "utf8");
8149
+ raw = (0, import_node_fs16.readFileSync)(this.eventsPath, "utf8");
7320
8150
  } catch {
7321
8151
  return [];
7322
8152
  }
@@ -7355,15 +8185,15 @@ function nextBoundary(ts, bucket) {
7355
8185
  return new Date(d.getFullYear(), d.getMonth() + 1, 1).getTime();
7356
8186
  }
7357
8187
  }
7358
- var pad2 = (n) => String(n).padStart(2, "0");
8188
+ var pad22 = (n) => String(n).padStart(2, "0");
7359
8189
  function bucketLabel(bucketStartTs, bucket) {
7360
8190
  const d = new Date(bucketStartTs);
7361
8191
  const y = d.getFullYear();
7362
- const mo = pad2(d.getMonth() + 1);
7363
- const day = pad2(d.getDate());
8192
+ const mo = pad22(d.getMonth() + 1);
8193
+ const day = pad22(d.getDate());
7364
8194
  switch (bucket) {
7365
8195
  case "hour":
7366
- return `${mo}-${day} ${pad2(d.getHours())}:00`;
8196
+ return `${mo}-${day} ${pad22(d.getHours())}:00`;
7367
8197
  case "day":
7368
8198
  return `${y}-${mo}-${day}`;
7369
8199
  case "month":
@@ -7419,7 +8249,7 @@ function median(values) {
7419
8249
  }
7420
8250
 
7421
8251
  // src/ports/JsonPricingStore.ts
7422
- var import_node_fs13 = require("fs");
8252
+ var import_node_fs17 = require("fs");
7423
8253
  var import_node_crypto12 = require("crypto");
7424
8254
  var JsonPricingStore = class {
7425
8255
  constructor(pricingPath) {
@@ -7434,9 +8264,9 @@ var JsonPricingStore = class {
7434
8264
  * otherwise unusable pricing table after a crash or manual file edit.
7435
8265
  */
7436
8266
  hasUsableSnapshot() {
7437
- if (!(0, import_node_fs13.existsSync)(this.pricingPath)) return false;
8267
+ if (!(0, import_node_fs17.existsSync)(this.pricingPath)) return false;
7438
8268
  try {
7439
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(this.pricingPath, "utf8"));
8269
+ const parsed = JSON.parse((0, import_node_fs17.readFileSync)(this.pricingPath, "utf8"));
7440
8270
  return Array.isArray(parsed) && parsed.some(isUsablePricingRow);
7441
8271
  } catch {
7442
8272
  return false;
@@ -7549,9 +8379,9 @@ var JsonPricingStore = class {
7549
8379
  }
7550
8380
  /** Read the pricing rows, tolerating a missing/corrupt file (→ empty list). */
7551
8381
  readRows() {
7552
- if (!(0, import_node_fs13.existsSync)(this.pricingPath)) return [];
8382
+ if (!(0, import_node_fs17.existsSync)(this.pricingPath)) return [];
7553
8383
  try {
7554
- const parsed = JSON.parse((0, import_node_fs13.readFileSync)(this.pricingPath, "utf8"));
8384
+ const parsed = JSON.parse((0, import_node_fs17.readFileSync)(this.pricingPath, "utf8"));
7555
8385
  return Array.isArray(parsed) ? parsed : [];
7556
8386
  } catch {
7557
8387
  return [];
@@ -7560,18 +8390,18 @@ var JsonPricingStore = class {
7560
8390
  writeRows(rows) {
7561
8391
  const temporaryPath = `${this.pricingPath}.${process.pid}.${(0, import_node_crypto12.randomUUID)()}.tmp`;
7562
8392
  try {
7563
- (0, import_node_fs13.writeFileSync)(temporaryPath, JSON.stringify(rows, null, 2) + "\n", {
8393
+ (0, import_node_fs17.writeFileSync)(temporaryPath, JSON.stringify(rows, null, 2) + "\n", {
7564
8394
  encoding: "utf8",
7565
8395
  flag: "wx"
7566
8396
  });
7567
8397
  this.replaceFile(temporaryPath);
7568
8398
  } finally {
7569
- (0, import_node_fs13.rmSync)(temporaryPath, { force: true });
8399
+ (0, import_node_fs17.rmSync)(temporaryPath, { force: true });
7570
8400
  }
7571
8401
  }
7572
8402
  /** Isolated for deterministic failure testing; never removes the target. */
7573
8403
  replaceFile(temporaryPath) {
7574
- (0, import_node_fs13.renameSync)(temporaryPath, this.pricingPath);
8404
+ (0, import_node_fs17.renameSync)(temporaryPath, this.pricingPath);
7575
8405
  }
7576
8406
  };
7577
8407
  function isUsablePricingRow(value) {
@@ -7581,7 +8411,7 @@ function isUsablePricingRow(value) {
7581
8411
  }
7582
8412
 
7583
8413
  // src/pricing/PricingRefreshScheduler.ts
7584
- var import_node_fs14 = require("fs");
8414
+ var import_node_fs18 = require("fs");
7585
8415
  var EMPTY_STATE2 = {
7586
8416
  lastAttemptAt: null,
7587
8417
  lastSuccessAt: null,
@@ -7619,9 +8449,9 @@ var PricingRefreshScheduler = class {
7619
8449
  this.timer = null;
7620
8450
  }
7621
8451
  getState() {
7622
- if (!(0, import_node_fs14.existsSync)(this.statePath)) return { ...EMPTY_STATE2, sources: [] };
8452
+ if (!(0, import_node_fs18.existsSync)(this.statePath)) return { ...EMPTY_STATE2, sources: [] };
7623
8453
  try {
7624
- const value = JSON.parse((0, import_node_fs14.readFileSync)(this.statePath, "utf8"));
8454
+ const value = JSON.parse((0, import_node_fs18.readFileSync)(this.statePath, "utf8"));
7625
8455
  return {
7626
8456
  lastAttemptAt: finiteOrNull(value.lastAttemptAt),
7627
8457
  lastSuccessAt: finiteOrNull(value.lastSuccessAt),
@@ -7674,9 +8504,9 @@ var PricingRefreshScheduler = class {
7674
8504
  }
7675
8505
  writeState(state) {
7676
8506
  const temporaryPath = `${this.statePath}.tmp`;
7677
- (0, import_node_fs14.writeFileSync)(temporaryPath, `${JSON.stringify(state, null, 2)}
8507
+ (0, import_node_fs18.writeFileSync)(temporaryPath, `${JSON.stringify(state, null, 2)}
7678
8508
  `, "utf8");
7679
- (0, import_node_fs14.renameSync)(temporaryPath, this.statePath);
8509
+ (0, import_node_fs18.renameSync)(temporaryPath, this.statePath);
7680
8510
  }
7681
8511
  };
7682
8512
  function finiteOrNull(value) {
@@ -7684,7 +8514,7 @@ function finiteOrNull(value) {
7684
8514
  }
7685
8515
 
7686
8516
  // src/ports/JsonVoucherDb.ts
7687
- var import_node_fs15 = require("fs");
8517
+ var import_node_fs19 = require("fs");
7688
8518
  var JsonVoucherDb = class {
7689
8519
  constructor(vouchersPath) {
7690
8520
  this.vouchersPath = vouchersPath;
@@ -7762,22 +8592,22 @@ var JsonVoucherDb = class {
7762
8592
  }
7763
8593
  /** Read the voucher rows, tolerating a missing/corrupt file (→ empty list). */
7764
8594
  readRows() {
7765
- if (!(0, import_node_fs15.existsSync)(this.vouchersPath)) return [];
8595
+ if (!(0, import_node_fs19.existsSync)(this.vouchersPath)) return [];
7766
8596
  try {
7767
- const parsed = JSON.parse((0, import_node_fs15.readFileSync)(this.vouchersPath, "utf8"));
8597
+ const parsed = JSON.parse((0, import_node_fs19.readFileSync)(this.vouchersPath, "utf8"));
7768
8598
  return Array.isArray(parsed) ? parsed : [];
7769
8599
  } catch {
7770
8600
  return [];
7771
8601
  }
7772
8602
  }
7773
8603
  writeRows(rows) {
7774
- (0, import_node_fs15.writeFileSync)(this.vouchersPath, JSON.stringify(rows, null, 2) + "\n", "utf8");
8604
+ (0, import_node_fs19.writeFileSync)(this.vouchersPath, JSON.stringify(rows, null, 2) + "\n", "utf8");
7775
8605
  }
7776
8606
  };
7777
8607
 
7778
8608
  // src/ports/JsonSubscriptionCredentialStore.ts
7779
- var import_node_fs17 = require("fs");
7780
- var import_node_path10 = require("path");
8609
+ var import_node_fs21 = require("fs");
8610
+ var import_node_path13 = require("path");
7781
8611
  var import_SubscriptionAccountHealth2 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
7782
8612
  var import_AccountAllowanceScheduling3 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
7783
8613
  var import_upstreamFetch4 = require("@omnicross/core/pipeline/upstreamFetch");
@@ -7826,11 +8656,11 @@ function findDuplicateCredentialIds(accounts) {
7826
8656
  }
7827
8657
 
7828
8658
  // src/ports/external-cli-credentials.ts
7829
- var import_node_fs16 = require("fs");
8659
+ var import_node_fs20 = require("fs");
7830
8660
  var import_node_os4 = require("os");
7831
- var import_node_path9 = require("path");
8661
+ var import_node_path12 = require("path");
7832
8662
  function externalStorePath(provider, home = (0, import_node_os4.homedir)()) {
7833
- return provider === "claude" ? (0, import_node_path9.join)(home, ".claude", ".credentials.json") : (0, import_node_path9.join)(home, ".codex", "auth.json");
8663
+ return provider === "claude" ? (0, import_node_path12.join)(home, ".claude", ".credentials.json") : (0, import_node_path12.join)(home, ".codex", "auth.json");
7834
8664
  }
7835
8665
  function decodeJwtExpiryMs(token) {
7836
8666
  try {
@@ -7879,10 +8709,10 @@ function parseCodexTokensEnvelope(raw) {
7879
8709
  }
7880
8710
  function readExternalCliCredentials(provider, home = (0, import_node_os4.homedir)()) {
7881
8711
  const path2 = externalStorePath(provider, home);
7882
- if (!(0, import_node_fs16.existsSync)(path2)) return null;
8712
+ if (!(0, import_node_fs20.existsSync)(path2)) return null;
7883
8713
  let raw;
7884
8714
  try {
7885
- const parsed = JSON.parse((0, import_node_fs16.readFileSync)(path2, "utf8"));
8715
+ const parsed = JSON.parse((0, import_node_fs20.readFileSync)(path2, "utf8"));
7886
8716
  raw = parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : void 0;
7887
8717
  } catch {
7888
8718
  return null;
@@ -8453,9 +9283,9 @@ var JsonSubscriptionCredentialStore = class {
8453
9283
  * `enc:v1:`; already-`enc:`/`$ENV` untouched) before serializing, so any
8454
9284
  * write incl. child 4's future refresh writes lands encrypted. */
8455
9285
  persist(config) {
8456
- (0, import_node_fs17.mkdirSync)((0, import_node_path10.dirname)(this.tokensPath), { recursive: true });
9286
+ (0, import_node_fs21.mkdirSync)((0, import_node_path13.dirname)(this.tokensPath), { recursive: true });
8457
9287
  const encrypted = encryptTokens(config, this.box);
8458
- (0, import_node_fs17.writeFileSync)(this.tokensPath, JSON.stringify(encrypted, null, 2) + "\n", "utf8");
9288
+ (0, import_node_fs21.writeFileSync)(this.tokensPath, JSON.stringify(encrypted, null, 2) + "\n", "utf8");
8459
9289
  }
8460
9290
  /**
8461
9291
  * Read + parse `tokens.json`, tolerating a missing/corrupt file, then DECRYPT
@@ -8471,10 +9301,10 @@ var JsonSubscriptionCredentialStore = class {
8471
9301
  * `config.ts loadConfig`, which decrypts outside its parse try.
8472
9302
  */
8473
9303
  readConfig() {
8474
- if (!(0, import_node_fs17.existsSync)(this.tokensPath)) return { updatedAt: "" };
9304
+ if (!(0, import_node_fs21.existsSync)(this.tokensPath)) return { updatedAt: "" };
8475
9305
  let parsed;
8476
9306
  try {
8477
- const raw = JSON.parse((0, import_node_fs17.readFileSync)(this.tokensPath, "utf8"));
9307
+ const raw = JSON.parse((0, import_node_fs21.readFileSync)(this.tokensPath, "utf8"));
8478
9308
  parsed = raw && typeof raw === "object" && !Array.isArray(raw) ? raw : null;
8479
9309
  } catch {
8480
9310
  parsed = null;
@@ -8991,32 +9821,14 @@ var AccountHealthSweeper = class {
8991
9821
  };
8992
9822
 
8993
9823
  // src/audit/AuditPruneSweeper.ts
8994
- var import_node_fs19 = require("fs");
8995
- var import_node_path12 = require("path");
8996
-
8997
- // src/audit/auditFiles.ts
8998
- var AUDIT_FILE_RE = /^audit-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
8999
- var pad22 = (n) => String(n).padStart(2, "0");
9000
- function auditFileName(ts) {
9001
- const d = new Date(ts);
9002
- return `audit-${d.getFullYear()}-${pad22(d.getMonth() + 1)}-${pad22(d.getDate())}.jsonl`;
9003
- }
9004
- function auditFileDateMs(fileName) {
9005
- const m = AUDIT_FILE_RE.exec(fileName);
9006
- if (!m) return null;
9007
- const year = Number(m[1]);
9008
- const month = Number(m[2]);
9009
- const day = Number(m[3]);
9010
- const d = new Date(year, month - 1, day);
9011
- if (d.getFullYear() !== year || d.getMonth() !== month - 1 || d.getDate() !== day) {
9012
- return null;
9013
- }
9014
- return d.getTime();
9015
- }
9824
+ var import_node_fs23 = require("fs");
9825
+ var import_node_path15 = require("path");
9826
+ var import_promises2 = require("stream/promises");
9827
+ var import_node_zlib2 = require("zlib");
9016
9828
 
9017
9829
  // src/audit/auditStats.ts
9018
- var import_node_fs18 = require("fs");
9019
- var import_node_path11 = require("path");
9830
+ var import_node_fs22 = require("fs");
9831
+ var import_node_path14 = require("path");
9020
9832
  var SIDECAR_VERSION = 1;
9021
9833
  var META_PREFIX_BYTES = 64 * 1024;
9022
9834
  var READ_CHUNK_BYTES = 4 * 1024 * 1024;
@@ -9024,9 +9836,9 @@ function auditStatsFileName(auditFile) {
9024
9836
  return auditFile.replace(/\.jsonl$/, ".stats.json");
9025
9837
  }
9026
9838
  function readPersisted(path2) {
9027
- if (!(0, import_node_fs18.existsSync)(path2)) return null;
9839
+ if (!(0, import_node_fs22.existsSync)(path2)) return null;
9028
9840
  try {
9029
- const value = JSON.parse((0, import_node_fs18.readFileSync)(path2, "utf8"));
9841
+ const value = JSON.parse((0, import_node_fs22.readFileSync)(path2, "utf8"));
9030
9842
  if (value.version !== SIDECAR_VERSION || !Number.isSafeInteger(value.auditBytes) || (value.auditBytes ?? -1) < 0 || !Number.isSafeInteger(value.requestCount) || (value.requestCount ?? -1) < 0 || !Number.isSafeInteger(value.errorCount) || (value.errorCount ?? -1) < 0 || (value.errorCount ?? 0) > (value.requestCount ?? -1) || typeof value.complete !== "boolean" || value.minTs !== null && !Number.isFinite(value.minTs) || value.maxTs !== null && !Number.isFinite(value.maxTs)) {
9031
9843
  return null;
9032
9844
  }
@@ -9036,7 +9848,7 @@ function readPersisted(path2) {
9036
9848
  }
9037
9849
  }
9038
9850
  function updateAuditStatsAfterAppend(auditPath, auditBytesBefore, auditBytesAfter, record) {
9039
- const statsPath = (0, import_node_path11.join)((0, import_node_path11.dirname)(auditPath), auditStatsFileName((0, import_node_path11.basename)(auditPath)));
9851
+ const statsPath = (0, import_node_path14.join)((0, import_node_path14.dirname)(auditPath), auditStatsFileName((0, import_node_path14.basename)(auditPath)));
9040
9852
  const previous = auditBytesBefore === 0 ? {
9041
9853
  version: SIDECAR_VERSION,
9042
9854
  auditBytes: 0,
@@ -9056,13 +9868,13 @@ function updateAuditStatsAfterAppend(auditPath, auditBytesBefore, auditBytesAfte
9056
9868
  minTs: previous.minTs === null ? record.ts : Math.min(previous.minTs, record.ts),
9057
9869
  maxTs: previous.maxTs === null ? record.ts : Math.max(previous.maxTs, record.ts)
9058
9870
  };
9059
- (0, import_node_fs18.writeFileSync)(statsPath, JSON.stringify(next), "utf8");
9871
+ (0, import_node_fs22.writeFileSync)(statsPath, JSON.stringify(next), "utf8");
9060
9872
  }
9061
9873
  function queryCovers(stats, from, to) {
9062
9874
  return stats.requestCount === 0 || stats.minTs !== null && stats.maxTs !== null && from <= stats.minTs && to >= stats.maxTs;
9063
9875
  }
9064
- function fileOverlaps(file, from, to) {
9065
- const start = auditFileDateMs(file);
9876
+ function fileOverlaps(name, from, to) {
9877
+ const start = auditFileDateMs(name);
9066
9878
  if (start === null) return false;
9067
9879
  const date = new Date(start);
9068
9880
  const end = new Date(date.getFullYear(), date.getMonth(), date.getDate() + 1).getTime();
@@ -9114,7 +9926,7 @@ async function scanAuditFile(auditPath, startByte, auditBytes, from, to) {
9114
9926
  prefixTruncated = false;
9115
9927
  };
9116
9928
  if (auditBytes > startByte) {
9117
- const stream = (0, import_node_fs18.createReadStream)(auditPath, {
9929
+ const stream = (0, import_node_fs22.createReadStream)(auditPath, {
9118
9930
  start: startByte,
9119
9931
  end: auditBytes - 1,
9120
9932
  highWaterMark: READ_CHUNK_BYTES
@@ -9167,21 +9979,27 @@ function mergePersistedStats(previous, appended) {
9167
9979
  };
9168
9980
  }
9169
9981
  async function readAuditStats(auditDir, query2 = {}) {
9170
- if (!(0, import_node_fs18.existsSync)(auditDir)) return { requestCount: 0, errorCount: 0, complete: true };
9982
+ if (!(0, import_node_fs22.existsSync)(auditDir)) return { requestCount: 0, errorCount: 0, complete: true };
9171
9983
  const from = typeof query2.from === "number" ? query2.from : -Infinity;
9172
9984
  const to = typeof query2.to === "number" ? query2.to : Infinity;
9173
- let files;
9985
+ let sources;
9174
9986
  try {
9175
- files = (0, import_node_fs18.readdirSync)(auditDir).filter((file) => AUDIT_FILE_RE.test(file) && fileOverlaps(file, from, to)).sort();
9987
+ sources = (0, import_node_fs22.readdirSync)(auditDir).filter((name) => fileOverlaps(name, from, to)).sort().map(
9988
+ (name) => AUDIT_DAY_DIR_RE.test(name) ? {
9989
+ auditPath: (0, import_node_path14.join)(auditDir, name, AUDIT_META_FILE),
9990
+ statsPath: (0, import_node_path14.join)(auditDir, name, auditStatsFileName(AUDIT_META_FILE))
9991
+ } : {
9992
+ auditPath: (0, import_node_path14.join)(auditDir, name),
9993
+ statsPath: (0, import_node_path14.join)(auditDir, auditStatsFileName(name))
9994
+ }
9995
+ ).filter((source) => (0, import_node_fs22.existsSync)(source.auditPath));
9176
9996
  } catch {
9177
9997
  return { requestCount: 0, errorCount: 0, complete: false };
9178
9998
  }
9179
9999
  const total = { requestCount: 0, errorCount: 0, complete: true };
9180
- for (const file of files) {
9181
- const auditPath = (0, import_node_path11.join)(auditDir, file);
10000
+ for (const { auditPath, statsPath } of sources) {
9182
10001
  try {
9183
- const auditBytes = (0, import_node_fs18.statSync)(auditPath).size;
9184
- const statsPath = (0, import_node_path11.join)(auditDir, auditStatsFileName(file));
10002
+ const auditBytes = (0, import_node_fs22.statSync)(auditPath).size;
9185
10003
  const persisted = readPersisted(statsPath);
9186
10004
  if (persisted && persisted.complete && persisted.auditBytes === auditBytes && queryCovers(persisted, from, to)) {
9187
10005
  total.requestCount += persisted.requestCount;
@@ -9200,7 +10018,7 @@ async function readAuditStats(auditDir, query2 = {}) {
9200
10018
  total.errorCount += scanned.filtered.errorCount + (resumable?.errorCount ?? 0);
9201
10019
  total.complete = total.complete && scanned.filtered.complete;
9202
10020
  const current = resumable ? mergePersistedStats(resumable, scanned.all) : scanned.all;
9203
- if (current.complete) (0, import_node_fs18.writeFileSync)(statsPath, JSON.stringify(current), "utf8");
10021
+ if (current.complete) (0, import_node_fs22.writeFileSync)(statsPath, JSON.stringify(current), "utf8");
9204
10022
  } catch {
9205
10023
  total.complete = false;
9206
10024
  }
@@ -9211,6 +10029,7 @@ async function readAuditStats(auditDir, query2 = {}) {
9211
10029
  // src/audit/AuditPruneSweeper.ts
9212
10030
  var DAY_MS = 24 * 60 * 6e4;
9213
10031
  var SWEEP_INTERVAL_MS2 = 60 * 6e4;
10032
+ var ARCHIVE_BATCH = 64;
9214
10033
  var AuditPruneSweeper = class {
9215
10034
  constructor(auditDir, logger, config, intervalMs = SWEEP_INTERVAL_MS2, now = Date.now) {
9216
10035
  this.auditDir = auditDir;
@@ -9226,6 +10045,7 @@ var AuditPruneSweeper = class {
9226
10045
  now;
9227
10046
  timer = null;
9228
10047
  sweeping = false;
10048
+ archiving = false;
9229
10049
  /** Whether pruning is active (audit enabled). */
9230
10050
  get enabled() {
9231
10051
  return this.config.enabled;
@@ -9235,13 +10055,13 @@ var AuditPruneSweeper = class {
9235
10055
  this.config = config;
9236
10056
  }
9237
10057
  /**
9238
- * Arm the prune interval AND run one prune immediately (boot cleanup). No-op
9239
- * when audit is disabled (zero regression). Idempotent.
10058
+ * Arm the interval AND run one pass immediately (boot cleanup). No-op when
10059
+ * audit is disabled (zero regression). Idempotent.
9240
10060
  */
9241
10061
  start() {
9242
10062
  if (this.timer || !this.config.enabled) return;
9243
- void this.sweep();
9244
- this.timer = setInterval(() => void this.sweep(), this.intervalMs);
10063
+ void this.runOnce();
10064
+ this.timer = setInterval(() => void this.runOnce(), this.intervalMs);
9245
10065
  this.timer.unref?.();
9246
10066
  }
9247
10067
  /** Clear the interval (daemon shutdown / test teardown). Idempotent. */
@@ -9251,31 +10071,43 @@ var AuditPruneSweeper = class {
9251
10071
  this.timer = null;
9252
10072
  }
9253
10073
  }
10074
+ /** Prune first, then archive — never spend CPU compressing a day about to go. */
10075
+ async runOnce() {
10076
+ await this.sweep();
10077
+ await this.archive();
10078
+ }
10079
+ /** The LOCAL-midnight epoch ms of the current day. */
10080
+ todayMidnight() {
10081
+ const today = new Date(this.now());
10082
+ return new Date(today.getFullYear(), today.getMonth(), today.getDate()).getTime();
10083
+ }
9254
10084
  /**
9255
- * One prune: unlink every audit date file strictly OLDER than the retention
9256
- * cutoff (`now - retentionDays` days, at local-midnight granularity). Exposed
9257
- * for tests; never throws. Returns the number of files removed.
10085
+ * One prune: remove every audit day strictly OLDER than the retention cutoff
10086
+ * (`now - retentionDays` days, at local-midnight granularity). Exposed for
10087
+ * tests; never throws. Returns the number of days removed.
9258
10088
  */
9259
10089
  async sweep() {
9260
10090
  if (!this.config.enabled || this.sweeping) return 0;
9261
10091
  this.sweeping = true;
9262
10092
  try {
9263
- if (!(0, import_node_fs19.existsSync)(this.auditDir)) return 0;
9264
- const today = new Date(this.now());
9265
- const todayMidnight = new Date(today.getFullYear(), today.getMonth(), today.getDate()).getTime();
9266
- const cutoff = todayMidnight - (this.config.retentionDays - 1) * DAY_MS;
10093
+ if (!(0, import_node_fs23.existsSync)(this.auditDir)) return 0;
10094
+ const cutoff = this.todayMidnight() - (this.config.retentionDays - 1) * DAY_MS;
9267
10095
  let removed = 0;
9268
- for (const file of (0, import_node_fs19.readdirSync)(this.auditDir)) {
9269
- const dateMs = auditFileDateMs(file);
10096
+ for (const name of (0, import_node_fs23.readdirSync)(this.auditDir)) {
10097
+ const dateMs = auditFileDateMs(name);
9270
10098
  if (dateMs === null || dateMs >= cutoff) continue;
9271
10099
  try {
9272
- (0, import_node_fs19.unlinkSync)((0, import_node_path12.join)(this.auditDir, file));
10100
+ if (isAuditDayDir(name)) {
10101
+ (0, import_node_fs23.rmSync)((0, import_node_path15.join)(this.auditDir, name), { recursive: true, force: true });
10102
+ } else {
10103
+ (0, import_node_fs23.unlinkSync)((0, import_node_path15.join)(this.auditDir, name));
10104
+ const statsPath = (0, import_node_path15.join)(this.auditDir, auditStatsFileName(name));
10105
+ if ((0, import_node_fs23.existsSync)(statsPath)) (0, import_node_fs23.unlinkSync)(statsPath);
10106
+ }
9273
10107
  removed += 1;
9274
- const statsPath = (0, import_node_path12.join)(this.auditDir, auditStatsFileName(file));
9275
- if ((0, import_node_fs19.existsSync)(statsPath)) (0, import_node_fs19.unlinkSync)(statsPath);
9276
10108
  } catch (error) {
9277
- this.logger.warn("[AuditPruneSweeper] failed to unlink expired audit file", {
9278
- file,
10109
+ this.logger.warn("[AuditPruneSweeper] failed to remove expired audit day", {
10110
+ name,
9279
10111
  error: error instanceof Error ? error.message : String(error)
9280
10112
  });
9281
10113
  }
@@ -9291,59 +10123,158 @@ var AuditPruneSweeper = class {
9291
10123
  this.sweeping = false;
9292
10124
  }
9293
10125
  }
10126
+ /**
10127
+ * Gzip the body shards of every CLOSED day (anything before today). Today is
10128
+ * deliberately left as plain text so it stays greppable while it is the day you
10129
+ * are debugging. Exposed for tests; never throws. Returns shards compressed.
10130
+ */
10131
+ async archive() {
10132
+ if (!this.config.enabled || this.archiving) return 0;
10133
+ this.archiving = true;
10134
+ try {
10135
+ if (!(0, import_node_fs23.existsSync)(this.auditDir)) return 0;
10136
+ const today = this.todayMidnight();
10137
+ let compressed = 0;
10138
+ for (const name of (0, import_node_fs23.readdirSync)(this.auditDir)) {
10139
+ if (compressed >= ARCHIVE_BATCH) break;
10140
+ const dateMs = auditFileDateMs(name);
10141
+ if (dateMs === null || dateMs >= today || !isAuditDayDir(name)) continue;
10142
+ const dayPath = (0, import_node_path15.join)(this.auditDir, name);
10143
+ try {
10144
+ const compaction = compactAuditDay(dayPath);
10145
+ if (compaction.shards > 0) {
10146
+ this.logger.debug("audit cross-session compaction complete", {
10147
+ day: name,
10148
+ shards: compaction.shards,
10149
+ anchors: compaction.anchors,
10150
+ savedBytes: compaction.savedBytes
10151
+ });
10152
+ }
10153
+ } catch (error) {
10154
+ this.logger.warn("[AuditPruneSweeper] cross-session compaction failed", {
10155
+ day: name,
10156
+ error: error instanceof Error ? error.message : String(error)
10157
+ });
10158
+ }
10159
+ compressed += await this.archiveDay(
10160
+ (0, import_node_path15.join)(dayPath, AUDIT_BODIES_DIR),
10161
+ ARCHIVE_BATCH - compressed
10162
+ );
10163
+ }
10164
+ if (compressed > 0) this.logger.debug("audit archive complete", { compressed });
10165
+ return compressed;
10166
+ } catch (error) {
10167
+ this.logger.warn("audit archive pass failed", {
10168
+ error: error instanceof Error ? error.message : String(error)
10169
+ });
10170
+ return 0;
10171
+ } finally {
10172
+ this.archiving = false;
10173
+ }
10174
+ }
10175
+ /** Gzip up to `budget` plain shards in one day's `bodies/` directory. */
10176
+ async archiveDay(bodiesPath, budget) {
10177
+ let shards;
10178
+ try {
10179
+ shards = (0, import_node_fs23.readdirSync)(bodiesPath).filter((file) => file.endsWith(".jsonl"));
10180
+ } catch {
10181
+ return 0;
10182
+ }
10183
+ let compressed = 0;
10184
+ for (const shard of shards) {
10185
+ if (compressed >= budget) break;
10186
+ const source = (0, import_node_path15.join)(bodiesPath, shard);
10187
+ const target = `${source}.gz`;
10188
+ try {
10189
+ if ((0, import_node_fs23.existsSync)(target)) {
10190
+ (0, import_node_fs23.unlinkSync)(source);
10191
+ continue;
10192
+ }
10193
+ await (0, import_promises2.pipeline)((0, import_node_fs23.createReadStream)(source), (0, import_node_zlib2.createGzip)(), (0, import_node_fs23.createWriteStream)(target));
10194
+ (0, import_node_fs23.unlinkSync)(source);
10195
+ compressed += 1;
10196
+ } catch (error) {
10197
+ try {
10198
+ if ((0, import_node_fs23.existsSync)(target)) (0, import_node_fs23.unlinkSync)(target);
10199
+ } catch {
10200
+ }
10201
+ this.logger.warn("[AuditPruneSweeper] failed to archive audit body shard", {
10202
+ shard,
10203
+ error: error instanceof Error ? error.message : String(error)
10204
+ });
10205
+ }
10206
+ }
10207
+ return compressed;
10208
+ }
9294
10209
  };
9295
10210
 
9296
10211
  // src/audit/auditReader.ts
9297
- var import_node_fs20 = require("fs");
9298
- var import_node_path13 = require("path");
10212
+ var import_node_fs24 = require("fs");
10213
+ var import_node_path16 = require("path");
9299
10214
  var DEFAULT_LIMIT = 200;
9300
10215
  var MAX_LIMIT = 2e3;
9301
- function readAuditRecords(auditDir, query2 = {}) {
9302
- if (!(0, import_node_fs20.existsSync)(auditDir)) return [];
9303
- let files;
10216
+ var OVERSCAN = 256;
10217
+ function daySources(auditDir) {
10218
+ let names;
9304
10219
  try {
9305
- files = (0, import_node_fs20.readdirSync)(auditDir).filter((f) => AUDIT_FILE_RE.test(f));
10220
+ names = (0, import_node_fs24.readdirSync)(auditDir);
9306
10221
  } catch {
9307
10222
  return [];
9308
10223
  }
10224
+ const sources = [];
10225
+ for (const name of names) {
10226
+ const dateMs = auditFileDateMs(name);
10227
+ if (dateMs === null) continue;
10228
+ if (AUDIT_DAY_DIR_RE.test(name)) {
10229
+ const path2 = (0, import_node_path16.join)(auditDir, name, AUDIT_META_FILE);
10230
+ if ((0, import_node_fs24.existsSync)(path2)) sources.push({ path: path2, dateMs });
10231
+ } else if (AUDIT_FILE_RE.test(name)) {
10232
+ sources.push({ path: (0, import_node_path16.join)(auditDir, name), dateMs });
10233
+ }
10234
+ }
10235
+ return sources.sort((a, b) => b.dateMs - a.dateMs);
10236
+ }
10237
+ function isAuditRecord(value) {
10238
+ if (!value || typeof value !== "object" || Array.isArray(value)) return false;
10239
+ const r = value;
10240
+ return typeof r["id"] === "string" && typeof r["ts"] === "number" && typeof r["method"] === "string" && typeof r["path"] === "string" && typeof r["status"] === "number";
10241
+ }
10242
+ function toMetaRecord(record) {
10243
+ if (record.requestBody === void 0 && record.responseBody === void 0) return record;
10244
+ const { requestBody: _req, responseBody: _res, ...meta } = record;
10245
+ return { ...meta, hasBody: true };
10246
+ }
10247
+ function readAuditRecords(auditDir, query2 = {}) {
10248
+ if (!(0, import_node_fs24.existsSync)(auditDir)) return [];
9309
10249
  const from = typeof query2.from === "number" ? query2.from : -Infinity;
9310
10250
  const to = typeof query2.to === "number" ? query2.to : Infinity;
9311
10251
  const limit = Math.min(MAX_LIMIT, Math.max(1, Math.trunc(query2.limit ?? DEFAULT_LIMIT)));
9312
10252
  const matched = [];
9313
- for (const file of files.sort().reverse()) {
9314
- let raw;
9315
- try {
9316
- raw = (0, import_node_fs20.readFileSync)((0, import_node_path13.join)(auditDir, file), "utf8");
9317
- } catch {
9318
- continue;
9319
- }
9320
- for (const line of raw.split("\n")) {
9321
- const trimmed = line.trim();
9322
- if (!trimmed) continue;
9323
- let rec;
10253
+ for (const source of daySources(auditDir)) {
10254
+ const before = matched.length;
10255
+ forEachLineFromTail(source.path, (line) => {
10256
+ let parsed;
9324
10257
  try {
9325
- rec = JSON.parse(trimmed);
10258
+ parsed = JSON.parse(line);
9326
10259
  } catch {
9327
- continue;
10260
+ return false;
9328
10261
  }
9329
- if (!isAuditRecord(rec)) continue;
9330
- if (query2.keyId !== void 0 && rec.keyId !== query2.keyId) continue;
9331
- if (rec.ts < from || rec.ts > to) continue;
9332
- matched.push(rec);
9333
- }
10262
+ if (!isAuditRecord(parsed)) return false;
10263
+ if (query2.keyId !== void 0 && parsed.keyId !== query2.keyId) return false;
10264
+ if (query2.sessionKey !== void 0 && parsed.sessionKey !== query2.sessionKey) return false;
10265
+ if (parsed.ts < from || parsed.ts > to) return false;
10266
+ matched.push(toMetaRecord(parsed));
10267
+ return matched.length - before >= limit + OVERSCAN;
10268
+ });
10269
+ if (matched.length >= limit) break;
9334
10270
  }
9335
10271
  matched.sort((a, b) => b.ts - a.ts);
9336
10272
  return matched.slice(0, limit);
9337
10273
  }
9338
- function isAuditRecord(value) {
9339
- if (!value || typeof value !== "object" || Array.isArray(value)) return false;
9340
- const r = value;
9341
- return typeof r["id"] === "string" && typeof r["ts"] === "number" && typeof r["method"] === "string" && typeof r["path"] === "string" && typeof r["status"] === "number";
9342
- }
9343
10274
 
9344
10275
  // src/audit/AuditWriter.ts
9345
- var import_node_fs21 = require("fs");
9346
- var import_node_path14 = require("path");
10276
+ var import_node_fs25 = require("fs");
10277
+ var import_node_path17 = require("path");
9347
10278
  var AuditWriter = class {
9348
10279
  constructor(auditDir, logger, defer = (fn) => setTimeout(fn, 0)) {
9349
10280
  this.auditDir = auditDir;
@@ -9353,10 +10284,13 @@ var AuditWriter = class {
9353
10284
  auditDir;
9354
10285
  logger;
9355
10286
  defer;
9356
- dirEnsured = false;
10287
+ /** Day directories already created this process (avoids an mkdir per record). */
10288
+ ensuredDirs = /* @__PURE__ */ new Set();
10289
+ /** Per-session encoding bases. Memory-only; a miss simply writes a full snapshot. */
10290
+ bases = new SessionBaseCache();
9357
10291
  /**
9358
- * Enqueue one record for append. Returns IMMEDIATELY (fire-and-forget); the fs
9359
- * write happens on the deferred tick. A failure is logged, never thrown.
10292
+ * Enqueue one record. Returns IMMEDIATELY (fire-and-forget); every fs write and
10293
+ * the delta encoding happen on the deferred tick. A failure is logged, never thrown.
9360
10294
  */
9361
10295
  record(record) {
9362
10296
  this.defer(() => {
@@ -9369,25 +10303,41 @@ var AuditWriter = class {
9369
10303
  }
9370
10304
  });
9371
10305
  }
10306
+ /** Drop all retained encoding bases (config reload / shutdown / test teardown). */
10307
+ reset() {
10308
+ this.bases.clear();
10309
+ this.ensuredDirs.clear();
10310
+ }
9372
10311
  /**
9373
- * Append synchronously — the awaitable form tests use to assert the line landed.
9374
- * Ensures the `audit/` directory exists on first write (lazy, like the usage
9375
- * store's lazy file creation).
10312
+ * Append synchronously — the awaitable form tests use to assert a line landed.
10313
+ * Writes the metadata line first (canonical), then the body shard.
9376
10314
  */
9377
10315
  appendNow(record) {
9378
- if (!this.dirEnsured) {
9379
- (0, import_node_fs21.mkdirSync)(this.auditDir, { recursive: true });
9380
- this.dirEnsured = true;
9381
- }
9382
- const file = (0, import_node_path14.join)(this.auditDir, auditFileName(record.ts));
9383
- const line = JSON.stringify(record) + "\n";
9384
- const auditBytesBefore = (0, import_node_fs21.existsSync)(file) ? (0, import_node_fs21.statSync)(file).size : 0;
9385
- (0, import_node_fs21.appendFileSync)(file, line, "utf8");
10316
+ const dayDir = auditDayDirName(record.ts);
10317
+ const dayPath = this.ensureDir((0, import_node_path17.join)(this.auditDir, dayDir));
10318
+ this.appendMeta(dayPath, record);
10319
+ this.appendBody(dayPath, dayDir, record);
10320
+ }
10321
+ /** Create a directory once per process and remember it. */
10322
+ ensureDir(path2) {
10323
+ if (!this.ensuredDirs.has(path2)) {
10324
+ (0, import_node_fs25.mkdirSync)(path2, { recursive: true });
10325
+ this.ensuredDirs.add(path2);
10326
+ }
10327
+ return path2;
10328
+ }
10329
+ /** Write the body-free metadata line + refresh the exact-count sidecar. */
10330
+ appendMeta(dayPath, record) {
10331
+ const { requestBody: _req, responseBody: _res, ...meta } = record;
10332
+ const file = (0, import_node_path17.join)(dayPath, AUDIT_META_FILE);
10333
+ const line = JSON.stringify(meta) + "\n";
10334
+ const bytesBefore = (0, import_node_fs25.existsSync)(file) ? (0, import_node_fs25.statSync)(file).size : 0;
10335
+ (0, import_node_fs25.appendFileSync)(file, line, "utf8");
9386
10336
  try {
9387
10337
  updateAuditStatsAfterAppend(
9388
10338
  file,
9389
- auditBytesBefore,
9390
- auditBytesBefore + Buffer.byteLength(line, "utf8"),
10339
+ bytesBefore,
10340
+ bytesBefore + Buffer.byteLength(line, "utf8"),
9391
10341
  record
9392
10342
  );
9393
10343
  } catch (error) {
@@ -9396,12 +10346,39 @@ var AuditWriter = class {
9396
10346
  });
9397
10347
  }
9398
10348
  }
10349
+ /**
10350
+ * Write the delta-encoded body shard for one record. A no-op when nothing was
10351
+ * captured or when the session key is missing/unsafe — in which case the body
10352
+ * is dropped rather than written to an unvalidated path.
10353
+ */
10354
+ appendBody(dayPath, dayDir, record) {
10355
+ if (record.requestBody === void 0 && record.responseBody === void 0) return;
10356
+ const sessionKey = record.sessionKey;
10357
+ if (!isSafeSessionKey(sessionKey)) {
10358
+ this.logger.warn("[AuditWriter] dropping audit body with no usable session key", {
10359
+ id: record.id
10360
+ });
10361
+ return;
10362
+ }
10363
+ try {
10364
+ const line = encodeBodyEntry(record, sessionKey, dayDir, this.bases);
10365
+ if (line === null) return;
10366
+ const bodiesPath = this.ensureDir((0, import_node_path17.join)(dayPath, AUDIT_BODIES_DIR));
10367
+ (0, import_node_fs25.appendFileSync)((0, import_node_path17.join)(bodiesPath, auditBodyFileName(sessionKey)), line + "\n", "utf8");
10368
+ } catch (error) {
10369
+ this.bases.forget(sessionKey);
10370
+ this.logger.warn("[AuditWriter] failed to append audit body shard", {
10371
+ id: record.id,
10372
+ error: error instanceof Error ? error.message : String(error)
10373
+ });
10374
+ }
10375
+ }
9399
10376
  };
9400
10377
 
9401
10378
  // src/billing/BillingPublisher.ts
9402
- var import_node_fs22 = require("fs");
10379
+ var import_node_fs26 = require("fs");
9403
10380
  var import_node_crypto13 = require("crypto");
9404
- var import_node_path15 = require("path");
10381
+ var import_node_path18 = require("path");
9405
10382
  var import_upstreamFetch6 = require("@omnicross/core/pipeline/upstreamFetch");
9406
10383
 
9407
10384
  // src/billing/billingFiles.ts
@@ -9472,8 +10449,8 @@ var BillingPublisher = class {
9472
10449
  */
9473
10450
  appendNow(event) {
9474
10451
  this.ensureDir();
9475
- const file = (0, import_node_path15.join)(this.billingDir, billingFileName(event.ts));
9476
- (0, import_node_fs22.appendFileSync)(file, JSON.stringify(event) + "\n", "utf8");
10452
+ const file = (0, import_node_path18.join)(this.billingDir, billingFileName(event.ts));
10453
+ (0, import_node_fs26.appendFileSync)(file, JSON.stringify(event) + "\n", "utf8");
9477
10454
  }
9478
10455
  /**
9479
10456
  * One best-effort delivery attempt for an event ALREADY in the ledger. POSTs the
@@ -9522,8 +10499,8 @@ var BillingPublisher = class {
9522
10499
  markDelivered(event) {
9523
10500
  try {
9524
10501
  this.ensureDir();
9525
- const file = (0, import_node_path15.join)(this.billingDir, deliveredFileName(event.ts));
9526
- (0, import_node_fs22.appendFileSync)(file, JSON.stringify({ id: event.id, deliveredAt: this.now() }) + "\n", "utf8");
10502
+ const file = (0, import_node_path18.join)(this.billingDir, deliveredFileName(event.ts));
10503
+ (0, import_node_fs26.appendFileSync)(file, JSON.stringify({ id: event.id, deliveredAt: this.now() }) + "\n", "utf8");
9527
10504
  } catch (error) {
9528
10505
  this.logger.warn("[BillingPublisher] failed to append delivery marker", {
9529
10506
  error: error instanceof Error ? error.message : String(error)
@@ -9532,20 +10509,20 @@ var BillingPublisher = class {
9532
10509
  }
9533
10510
  ensureDir() {
9534
10511
  if (this.dirEnsured) return;
9535
- (0, import_node_fs22.mkdirSync)(this.billingDir, { recursive: true });
10512
+ (0, import_node_fs26.mkdirSync)(this.billingDir, { recursive: true });
9536
10513
  this.dirEnsured = true;
9537
10514
  }
9538
10515
  };
9539
10516
 
9540
10517
  // src/billing/billingReader.ts
9541
- var import_node_fs23 = require("fs");
9542
- var import_node_path16 = require("path");
10518
+ var import_node_fs27 = require("fs");
10519
+ var import_node_path19 = require("path");
9543
10520
  function readBillingLedger(billingDir) {
9544
10521
  const view = { events: [], deliveredIds: /* @__PURE__ */ new Set() };
9545
- if (!(0, import_node_fs23.existsSync)(billingDir)) return view;
10522
+ if (!(0, import_node_fs27.existsSync)(billingDir)) return view;
9546
10523
  let files;
9547
10524
  try {
9548
- files = (0, import_node_fs23.readdirSync)(billingDir);
10525
+ files = (0, import_node_fs27.readdirSync)(billingDir);
9549
10526
  } catch {
9550
10527
  return view;
9551
10528
  }
@@ -9576,7 +10553,7 @@ function readBillingStatus(billingDir) {
9576
10553
  function parseLines(dir, file) {
9577
10554
  let raw;
9578
10555
  try {
9579
- raw = (0, import_node_fs23.readFileSync)((0, import_node_path16.join)(dir, file), "utf8");
10556
+ raw = (0, import_node_fs27.readFileSync)((0, import_node_path19.join)(dir, file), "utf8");
9580
10557
  } catch {
9581
10558
  return [];
9582
10559
  }
@@ -10062,7 +11039,7 @@ function buildDaemon(config, paths) {
10062
11039
  }
10063
11040
  );
10064
11041
  const pricingStore = new JsonPricingStore(defaultPricingPath(paths.configPath));
10065
- const pricingEngine = new import_usage.PricingEngine(pricingStore, logger, {
11042
+ const pricingEngine = new import_usage2.PricingEngine(pricingStore, logger, {
10066
11043
  // Catalog egress follows the same global/env proxy policy as every other
10067
11044
  // daemon upstream call; no provider/account override applies here.
10068
11045
  fetchImpl: ((input, init) => (0, import_upstreamFetch8.fetchUpstream)(String(input), init ?? {}))
@@ -10078,8 +11055,10 @@ function buildDaemon(config, paths) {
10078
11055
  async (providerId, model) => await pricingEngine.getEntry(providerId, model) !== null
10079
11056
  );
10080
11057
  const keySpendTracker = new import_outbound_api6.KeySpendTracker(usageEventStore);
10081
- const usageRecorder = new import_usage.UsageRecorder(usageEventStore, pricingEngine, logger, {
10082
- onRecord: (apiKeyId, costUsd, at) => keySpendTracker.add(apiKeyId, costUsd, at)
11058
+ const usageThroughput = (0, import_usage2.getSharedUsageThroughputTracker)();
11059
+ const usageRecorder = new import_usage2.UsageRecorder(usageEventStore, pricingEngine, logger, {
11060
+ onRecord: (apiKeyId, costUsd, at) => keySpendTracker.add(apiKeyId, costUsd, at),
11061
+ onEvent: (row, at) => usageThroughput.record(row, at)
10083
11062
  });
10084
11063
  const providerProxy = (0, import_provider_proxy4.getProviderProxy)({ llmConfig, apiKeyPool, usageRecorder });
10085
11064
  const routeLeaseManager = new import_provider_proxy4.RouteLeaseManager(
@@ -10228,6 +11207,11 @@ function buildDaemon(config, paths) {
10228
11207
  // NEVER unauth, NEVER on `/health`. Routed in `AdminServer` (not `adminApi.ts`).
10229
11208
  auditReader: (query2) => readAuditRecords(auditDir, query2),
10230
11209
  auditStatsReader: (query2) => readAuditStats(auditDir, query2),
11210
+ // audit-store-sharding: bodies live in per-session shards, so opening ONE
11211
+ // record's payload is a separate authed call that replays its delta chain.
11212
+ auditBodyReader: (query2) => readAuditBody(auditDir, query2),
11213
+ // audit-store-sharding D8: the manual counterpart to the daily pass.
11214
+ auditCompactor: () => compactAllClosedAuditDays(auditDir),
10231
11215
  // billing-event-stream: the AUTHED `GET /admin/api/billing-status` returns the
10232
11216
  // secret-free total/delivered/pending counts of the durable ledger.
10233
11217
  billingStatusReader: () => readBillingStatus(billingDir)
@@ -10286,8 +11270,8 @@ function buildDaemon(config, paths) {
10286
11270
  }
10287
11271
  function isTokensStoreReadable(tokensPath) {
10288
11272
  try {
10289
- if (!(0, import_node_fs24.existsSync)(tokensPath)) return true;
10290
- (0, import_node_fs24.accessSync)(tokensPath, import_node_fs24.constants.R_OK);
11273
+ if (!(0, import_node_fs28.existsSync)(tokensPath)) return true;
11274
+ (0, import_node_fs28.accessSync)(tokensPath, import_node_fs28.constants.R_OK);
10291
11275
  return true;
10292
11276
  } catch {
10293
11277
  return false;
@@ -10332,10 +11316,10 @@ function buildCliSpawnPlan(opts) {
10332
11316
  };
10333
11317
  }
10334
11318
  function resolveInPathDefault(candidate) {
10335
- const segments = (process.env["PATH"] ?? "").split(import_node_path17.delimiter).filter(Boolean);
11319
+ const segments = (process.env["PATH"] ?? "").split(import_node_path20.delimiter).filter(Boolean);
10336
11320
  for (const seg of segments) {
10337
- const full = (0, import_node_path17.join)(seg, candidate);
10338
- if ((0, import_node_fs25.existsSync)(full)) return full;
11321
+ const full = (0, import_node_path20.join)(seg, candidate);
11322
+ if ((0, import_node_fs29.existsSync)(full)) return full;
10339
11323
  }
10340
11324
  return null;
10341
11325
  }
@@ -10343,7 +11327,7 @@ async function runLaunch(argv, deps) {
10343
11327
  const sep = argv.indexOf("--");
10344
11328
  const own = sep === -1 ? argv : argv.slice(0, sep);
10345
11329
  const passthrough = sep === -1 ? [] : argv.slice(sep + 1);
10346
- const { values, positionals } = (0, import_node_util4.parseArgs)({
11330
+ const { values, positionals } = (0, import_node_util5.parseArgs)({
10347
11331
  args: own,
10348
11332
  options: {
10349
11333
  provider: { type: "string", short: "p" },
@@ -10513,12 +11497,12 @@ function spawnCliInherit(plan) {
10513
11497
  // src/commands/login.ts
10514
11498
  var import_node_child_process3 = require("child_process");
10515
11499
  var import_node_readline = require("readline");
10516
- var import_node_util5 = require("util");
11500
+ var import_node_util6 = require("util");
10517
11501
  var import_upstreamFetch9 = require("@omnicross/core/pipeline/upstreamFetch");
10518
11502
  var import_subscriptions5 = require("@omnicross/subscriptions");
10519
11503
  var PROVIDERS2 = ["claude", "codex", "gemini"];
10520
11504
  async function runLogin(argv, deps) {
10521
- const { values, positionals } = (0, import_node_util5.parseArgs)({
11505
+ const { values, positionals } = (0, import_node_util6.parseArgs)({
10522
11506
  args: argv,
10523
11507
  options: {
10524
11508
  config: { type: "string", short: "c" },
@@ -10686,9 +11670,9 @@ function promptPaste(prompt) {
10686
11670
 
10687
11671
  // src/commands/providers.ts
10688
11672
  var import_node_crypto16 = require("crypto");
10689
- var import_node_util6 = require("util");
11673
+ var import_node_util7 = require("util");
10690
11674
  async function runProviders(argv) {
10691
- const { values, positionals } = (0, import_node_util6.parseArgs)({
11675
+ const { values, positionals } = (0, import_node_util7.parseArgs)({
10692
11676
  args: argv,
10693
11677
  options: {
10694
11678
  config: { type: "string", short: "c" },
@@ -10835,10 +11819,10 @@ function providersRmKey(configPath, providerId, keyId) {
10835
11819
  }
10836
11820
 
10837
11821
  // src/commands/secrets.ts
10838
- var import_node_fs26 = require("fs");
10839
- var import_node_util7 = require("util");
11822
+ var import_node_fs30 = require("fs");
11823
+ var import_node_util8 = require("util");
10840
11824
  async function runSecrets(argv) {
10841
- const { values, positionals } = (0, import_node_util7.parseArgs)({
11825
+ const { values, positionals } = (0, import_node_util8.parseArgs)({
10842
11826
  args: argv,
10843
11827
  options: {
10844
11828
  config: { type: "string", short: "c" },
@@ -10908,12 +11892,12 @@ function secretsStatus(args) {
10908
11892
  reportField("admin.token", cfg.admin.token);
10909
11893
  }
10910
11894
  const tokensPath = defaultTokensPath(args.config);
10911
- if ((0, import_node_fs26.existsSync)(tokensPath)) {
11895
+ if ((0, import_node_fs30.existsSync)(tokensPath)) {
10912
11896
  console.info(`Secret status for ${tokensPath}:`);
10913
11897
  reportTokenFields(tokensPath);
10914
11898
  }
10915
11899
  const integrationsPath = defaultIntegrationsPath(args.config);
10916
- if ((0, import_node_fs26.existsSync)(integrationsPath)) {
11900
+ if ((0, import_node_fs30.existsSync)(integrationsPath)) {
10917
11901
  const state = readRawJson(integrationsPath);
10918
11902
  const key = state.gatewayKey;
10919
11903
  if (key && typeof key === "object" && !Array.isArray(key)) {
@@ -10967,8 +11951,8 @@ async function secretsRotate(args) {
10967
11951
  const integrationsPath = defaultIntegrationsPath(args.config);
10968
11952
  try {
10969
11953
  cfg = loadConfig(args.config);
10970
- if ((0, import_node_fs26.existsSync)(tokensPath)) tokensPlain = decryptTokensFile(tokensPath, oldBox);
10971
- if ((0, import_node_fs26.existsSync)(integrationsPath)) {
11954
+ if ((0, import_node_fs30.existsSync)(tokensPath)) tokensPlain = decryptTokensFile(tokensPath, oldBox);
11955
+ if ((0, import_node_fs30.existsSync)(integrationsPath)) {
10972
11956
  integrationsPlain = new IntegrationStateStore(integrationsPath, oldBox).load();
10973
11957
  }
10974
11958
  } finally {
@@ -11003,20 +11987,20 @@ function secretsDecrypt(args) {
11003
11987
  let tokensPlain = null;
11004
11988
  try {
11005
11989
  cfg = loadConfig(args.config);
11006
- if ((0, import_node_fs26.existsSync)(tokensPath)) tokensPlain = decryptTokensFile(tokensPath, box);
11990
+ if ((0, import_node_fs30.existsSync)(tokensPath)) tokensPlain = decryptTokensFile(tokensPath, box);
11007
11991
  } finally {
11008
11992
  setSecretBox(null);
11009
11993
  }
11010
11994
  saveConfig(args.config, cfg);
11011
11995
  if (tokensPlain) {
11012
- (0, import_node_fs26.writeFileSync)(tokensPath, JSON.stringify(tokensPlain, null, 2) + "\n", "utf8");
11996
+ (0, import_node_fs30.writeFileSync)(tokensPath, JSON.stringify(tokensPlain, null, 2) + "\n", "utf8");
11013
11997
  }
11014
11998
  console.info(`Decrypted secrets to plaintext in ${args.config}` + tokensSuffix(args.config));
11015
11999
  }
11016
12000
  function readRawConfig(path2) {
11017
12001
  let parsed;
11018
12002
  try {
11019
- parsed = JSON.parse((0, import_node_fs26.readFileSync)(path2, "utf8"));
12003
+ parsed = JSON.parse((0, import_node_fs30.readFileSync)(path2, "utf8"));
11020
12004
  } catch {
11021
12005
  throw new Error(`secrets: cannot read or parse '${path2}'`);
11022
12006
  }
@@ -11024,7 +12008,7 @@ function readRawConfig(path2) {
11024
12008
  }
11025
12009
  function readRawJson(path2) {
11026
12010
  try {
11027
- const parsed = JSON.parse((0, import_node_fs26.readFileSync)(path2, "utf8"));
12011
+ const parsed = JSON.parse((0, import_node_fs30.readFileSync)(path2, "utf8"));
11028
12012
  if (parsed && typeof parsed === "object" && !Array.isArray(parsed)) {
11029
12013
  return parsed;
11030
12014
  }
@@ -11034,13 +12018,13 @@ function readRawJson(path2) {
11034
12018
  }
11035
12019
  function encryptTokensFileInPlace(configPath, box) {
11036
12020
  const tokensPath = defaultTokensPath(configPath);
11037
- if (!(0, import_node_fs26.existsSync)(tokensPath)) return;
12021
+ if (!(0, import_node_fs30.existsSync)(tokensPath)) return;
11038
12022
  const plain = decryptTokensFile(tokensPath, box);
11039
12023
  writeTokensEncrypted(tokensPath, plain, box);
11040
12024
  }
11041
12025
  function rewriteIntegrationState(configPath, readBox, writeBox) {
11042
12026
  const path2 = defaultIntegrationsPath(configPath);
11043
- if (!(0, import_node_fs26.existsSync)(path2)) return;
12027
+ if (!(0, import_node_fs30.existsSync)(path2)) return;
11044
12028
  const state = new IntegrationStateStore(path2, readBox).load();
11045
12029
  new IntegrationStateStore(path2, writeBox).save(state);
11046
12030
  }
@@ -11053,7 +12037,7 @@ function writeTokensEncrypted(tokensPath, plain, box) {
11053
12037
  { updatedAt: "", ...plain },
11054
12038
  box
11055
12039
  );
11056
- (0, import_node_fs26.writeFileSync)(tokensPath, JSON.stringify(encrypted, null, 2) + "\n", "utf8");
12040
+ (0, import_node_fs30.writeFileSync)(tokensPath, JSON.stringify(encrypted, null, 2) + "\n", "utf8");
11057
12041
  }
11058
12042
  var TOKEN_FIELDS2 = {
11059
12043
  claude: ["accessToken", "refreshToken"],
@@ -11076,11 +12060,11 @@ function walkTokens(raw, fn) {
11076
12060
  return next;
11077
12061
  }
11078
12062
  function tokensSuffix(configPath) {
11079
- return (0, import_node_fs26.existsSync)(defaultTokensPath(configPath)) ? " (+ tokens.json)" : "";
12063
+ return (0, import_node_fs30.existsSync)(defaultTokensPath(configPath)) ? " (+ tokens.json)" : "";
11080
12064
  }
11081
12065
 
11082
12066
  // src/commands/start.ts
11083
- var import_node_util8 = require("util");
12067
+ var import_node_util9 = require("util");
11084
12068
  var import_outbound_api7 = require("@omnicross/core/outbound-api");
11085
12069
  var import_SubscriptionAccountHealth5 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
11086
12070
  var import_AccountAllowanceScheduling6 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
@@ -11119,7 +12103,7 @@ async function seedIdentities(store, credentialStore) {
11119
12103
 
11120
12104
  // src/commands/start.ts
11121
12105
  async function runStart(argv) {
11122
- const { values } = (0, import_node_util8.parseArgs)({
12106
+ const { values } = (0, import_node_util9.parseArgs)({
11123
12107
  args: argv,
11124
12108
  options: {
11125
12109
  config: { type: "string", short: "c" },
@@ -11259,6 +12243,10 @@ Usage:
11259
12243
  omnicross secrets encrypt --config <p> Encrypt all at-rest secrets in place.
11260
12244
  omnicross secrets status --config <p> Report each secret field (no values shown).
11261
12245
  omnicross secrets rotate --config <p> --new-master-key-file <p> Re-seal under a new master key.
12246
+
12247
+ omnicross audit sessions --config <p> [--date YYYY-MM-DD] List captured body shards per session.
12248
+ omnicross audit show --config <p> --session <key> [--id <recordId>] Print reconstructed request/response bodies.
12249
+ omnicross audit compact --config <p> [--date YYYY-MM-DD] Run cross-session body compaction now.
11262
12250
  `;
11263
12251
  async function main() {
11264
12252
  const [, , subcommand, ...rest] = process.argv;
@@ -11290,6 +12278,9 @@ async function main() {
11290
12278
  case "secrets":
11291
12279
  await runSecrets(rest);
11292
12280
  return;
12281
+ case "audit":
12282
+ await runAudit(rest);
12283
+ return;
11293
12284
  case void 0:
11294
12285
  case "-h":
11295
12286
  case "--help":