@omnicross/daemon 0.1.3 → 0.1.5

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/index.cjs CHANGED
@@ -80,6 +80,7 @@ var CodexOAuthSessionStore = class {
80
80
  ttlMs;
81
81
  sessions = /* @__PURE__ */ new Map();
82
82
  activeSessionId = null;
83
+ aborters = /* @__PURE__ */ new Map();
83
84
  /** Whether a codex sign-in is currently in flight (port 1455 held). */
84
85
  isBusy() {
85
86
  this.sweep();
@@ -91,13 +92,22 @@ var CodexOAuthSessionStore = class {
91
92
  const sessionId = import_node_crypto.default.randomBytes(24).toString("base64url");
92
93
  this.sessions.set(sessionId, { status: "pending", createdAt: Date.now() });
93
94
  this.activeSessionId = sessionId;
94
- return sessionId;
95
+ const controller = new AbortController();
96
+ this.aborters.set(sessionId, controller);
97
+ return { sessionId, signal: controller.signal };
95
98
  }
96
99
  /** Settle a flow (done/error) + free the active slot. */
97
100
  settle(sessionId, status, error) {
98
101
  const prior = this.sessions.get(sessionId);
99
102
  this.sessions.set(sessionId, { status, error, createdAt: prior?.createdAt ?? Date.now() });
100
103
  if (this.activeSessionId === sessionId) this.activeSessionId = null;
104
+ this.aborters.delete(sessionId);
105
+ }
106
+ cancel(sessionId) {
107
+ if (!this.sessions.has(sessionId)) return false;
108
+ this.aborters.get(sessionId)?.abort();
109
+ this.settle(sessionId, "error", "login: cancelled");
110
+ return true;
101
111
  }
102
112
  /** Read a flow's status (token-free), or null when unknown/expired. */
103
113
  get(sessionId) {
@@ -126,13 +136,13 @@ function handleCodexOAuthStart(deps) {
126
136
  );
127
137
  }
128
138
  const { authUrl, codeVerifier, state } = import_subscriptions.codexOAuth.generateAuthParams();
129
- const sessionId = deps.codexSessions.begin();
130
- void runCodexLoopback(sessionId, codeVerifier, state, deps);
139
+ const { sessionId, signal } = deps.codexSessions.begin();
140
+ void runCodexLoopback(sessionId, codeVerifier, state, signal, deps);
131
141
  return { status: 200, body: { authUrl, sessionId } };
132
142
  }
133
- async function runCodexLoopback(sessionId, codeVerifier, state, deps) {
143
+ async function runCodexLoopback(sessionId, codeVerifier, state, signal, deps) {
134
144
  try {
135
- const code = await deps.codexAwaitLoopback(state);
145
+ const code = await deps.codexAwaitLoopback(state, void 0, signal);
136
146
  const result = await import_subscriptions.codexOAuth.exchangeCodeForTokens(
137
147
  { authorizationCode: code, codeVerifier, state },
138
148
  deps.oauthExchangeFetch
@@ -154,6 +164,10 @@ async function runCodexLoopback(sessionId, codeVerifier, state, deps) {
154
164
  deps.codexSessions.settle(sessionId, "error", reason);
155
165
  }
156
166
  }
167
+ function handleCodexOAuthCancel(sessionId, deps) {
168
+ if (!deps.codexSessions.cancel(sessionId)) return err(404, "unknown or expired codex sign-in session");
169
+ return { status: 200, body: { ok: true } };
170
+ }
157
171
  function handleCodexOAuthStatus(sessionId, deps) {
158
172
  const s = deps.codexSessions.get(sessionId);
159
173
  if (!s) return err(404, "unknown or expired codex sign-in session");
@@ -1889,12 +1903,16 @@ function preserveWebhookSecrets(incoming, current) {
1889
1903
  }
1890
1904
 
1891
1905
  // src/audit/auditRuntime.ts
1906
+ var import_node_path3 = require("path");
1892
1907
  var import_auditSink = require("@omnicross/core/pipeline/auditSink");
1908
+ var import_upstreamTrace = require("@omnicross/core/pipeline/upstreamTrace");
1893
1909
  var writer = null;
1894
1910
  var sweeper = null;
1895
- function setAuditRuntime(w, s) {
1911
+ var auditDir = "";
1912
+ function setAuditRuntime(w, s, dir) {
1896
1913
  writer = w;
1897
1914
  sweeper = s;
1915
+ auditDir = dir;
1898
1916
  }
1899
1917
  function applyAuditConfig(config) {
1900
1918
  const enabled = config?.enabled === true && writer !== null;
@@ -1906,9 +1924,11 @@ function applyAuditConfig(config) {
1906
1924
  sweeper.configure(config);
1907
1925
  sweeper.start();
1908
1926
  }
1927
+ (0, import_upstreamTrace.setUpstreamTracePath)(config.captureBodies ? (0, import_node_path3.join)(auditDir, "upstream-trace.jsonl") : null);
1909
1928
  } else {
1910
1929
  (0, import_auditSink.setAuditCaptureConfig)(null);
1911
1930
  (0, import_auditSink.setAuditSink)(null);
1931
+ (0, import_upstreamTrace.setUpstreamTracePath)(null);
1912
1932
  if (sweeper) {
1913
1933
  if (config) sweeper.configure(config);
1914
1934
  sweeper.dispose();
@@ -1918,9 +1938,11 @@ function applyAuditConfig(config) {
1918
1938
  function resetAuditRuntimeForTests() {
1919
1939
  (0, import_auditSink.setAuditCaptureConfig)(null);
1920
1940
  (0, import_auditSink.setAuditSink)(null);
1941
+ (0, import_upstreamTrace.setUpstreamTracePath)(null);
1921
1942
  if (sweeper) sweeper.dispose();
1922
1943
  writer = null;
1923
1944
  sweeper = null;
1945
+ auditDir = "";
1924
1946
  }
1925
1947
 
1926
1948
  // src/billing/billingRuntime.ts
@@ -3535,6 +3557,10 @@ async function handleAccounts(req, res, method, rest, deps) {
3535
3557
  const result = handleCodexOAuthStatus(rest[2], deps);
3536
3558
  return writeJson2(res, result.status, result.body);
3537
3559
  }
3560
+ if (method === "DELETE" && rest[0] === "codex" && rest[1] === "oauth" && rest[2]) {
3561
+ const result = handleCodexOAuthCancel(rest[2], deps);
3562
+ return writeJson2(res, result.status, result.body);
3563
+ }
3538
3564
  if (method === "PUT" || method === "POST" || method === "DELETE") {
3539
3565
  const providerId = asSubscriptionProviderId(rest[0]);
3540
3566
  if (!providerId) {
@@ -3782,7 +3808,7 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
3782
3808
  var import_node_fs4 = require("fs");
3783
3809
  var import_promises = require("fs/promises");
3784
3810
  var import_node_module = require("module");
3785
- var import_node_path3 = __toESM(require("path"), 1);
3811
+ var import_node_path4 = __toESM(require("path"), 1);
3786
3812
  var import_meta = {};
3787
3813
  var CONTENT_TYPES = {
3788
3814
  ".html": "text/html; charset=utf-8",
@@ -3803,13 +3829,13 @@ var CONTENT_TYPES = {
3803
3829
  function resolveUiDist() {
3804
3830
  const fromEnv = process.env["OMNICROSS_UI_DIST"];
3805
3831
  if (fromEnv) {
3806
- return (0, import_node_fs4.existsSync)(import_node_path3.default.join(fromEnv, "index.html")) ? import_node_path3.default.resolve(fromEnv) : null;
3832
+ return (0, import_node_fs4.existsSync)(import_node_path4.default.join(fromEnv, "index.html")) ? import_node_path4.default.resolve(fromEnv) : null;
3807
3833
  }
3808
3834
  try {
3809
3835
  const req = (0, import_node_module.createRequire)(typeof __filename !== "undefined" ? __filename : import_meta.url);
3810
3836
  const pkgJson = req.resolve("@omnicross/ui/package.json");
3811
- const dist = import_node_path3.default.join(import_node_path3.default.dirname(pkgJson), "dist");
3812
- return (0, import_node_fs4.existsSync)(import_node_path3.default.join(dist, "index.html")) ? dist : null;
3837
+ const dist = import_node_path4.default.join(import_node_path4.default.dirname(pkgJson), "dist");
3838
+ return (0, import_node_fs4.existsSync)(import_node_path4.default.join(dist, "index.html")) ? dist : null;
3813
3839
  } catch {
3814
3840
  return null;
3815
3841
  }
@@ -3851,16 +3877,16 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
3851
3877
  res.end(JSON.stringify({ error: { type: "bad_request", message: "invalid path" } }));
3852
3878
  return true;
3853
3879
  }
3854
- const filePath = import_node_path3.default.resolve(uiDist, rel === "" ? "index.html" : rel);
3855
- if (filePath !== uiDist && !filePath.startsWith(uiDist + import_node_path3.default.sep)) {
3880
+ const filePath = import_node_path4.default.resolve(uiDist, rel === "" ? "index.html" : rel);
3881
+ if (filePath !== uiDist && !filePath.startsWith(uiDist + import_node_path4.default.sep)) {
3856
3882
  res.writeHead(403, { "Content-Type": "application/json" });
3857
3883
  res.end(JSON.stringify({ error: { type: "forbidden", message: "path outside ui root" } }));
3858
3884
  return true;
3859
3885
  }
3860
3886
  let target = filePath;
3861
3887
  if (!(0, import_node_fs4.existsSync)(target) || (0, import_node_fs4.statSync)(target).isDirectory()) {
3862
- if (import_node_path3.default.extname(rel) === "") {
3863
- target = import_node_path3.default.join(uiDist, "index.html");
3888
+ if (import_node_path4.default.extname(rel) === "") {
3889
+ target = import_node_path4.default.join(uiDist, "index.html");
3864
3890
  } else {
3865
3891
  res.writeHead(404, { "Content-Type": "application/json" });
3866
3892
  res.end(JSON.stringify({ error: { type: "not_found", message: "no such ui asset" } }));
@@ -3868,14 +3894,14 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
3868
3894
  }
3869
3895
  }
3870
3896
  const body = await (0, import_promises.readFile)(target);
3871
- const type = CONTENT_TYPES[import_node_path3.default.extname(target).toLowerCase()] ?? "application/octet-stream";
3897
+ const type = CONTENT_TYPES[import_node_path4.default.extname(target).toLowerCase()] ?? "application/octet-stream";
3872
3898
  res.writeHead(200, { "Content-Type": type, "Content-Length": body.length });
3873
3899
  res.end(req.method === "HEAD" ? void 0 : body);
3874
3900
  return true;
3875
3901
  }
3876
3902
 
3877
3903
  // src/admin/version.ts
3878
- var DAEMON_VERSION = true ? "0.1.3" : "0.0.0-dev";
3904
+ var DAEMON_VERSION = true ? "0.1.5" : "0.0.0-dev";
3879
3905
 
3880
3906
  // src/admin/AdminServer.ts
3881
3907
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -4130,7 +4156,7 @@ var DEFAULT_TIMEOUT_MS = 5 * 6e4;
4130
4156
  function pageHtml(message) {
4131
4157
  return `<!doctype html><meta charset="utf-8"><title>omnicross login</title><body style="font-family:sans-serif;padding:2rem"><h2>${message}</h2><p>You can close this window and return to the terminal.</p></body>`;
4132
4158
  }
4133
- function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS) {
4159
+ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
4134
4160
  return new Promise((resolve, reject) => {
4135
4161
  let settled = false;
4136
4162
  const finish = (server2, fn) => {
@@ -4164,6 +4190,12 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS) {
4164
4190
  res.end(pageHtml("Login complete."));
4165
4191
  finish(server, () => resolve(code));
4166
4192
  });
4193
+ const abort = () => finish(server, () => reject(new Error("login: cancelled")));
4194
+ if (signal?.aborted) {
4195
+ abort();
4196
+ return;
4197
+ }
4198
+ signal?.addEventListener("abort", abort, { once: true });
4167
4199
  server.on("error", (err5) => {
4168
4200
  if (settled) return;
4169
4201
  settled = true;
@@ -4251,21 +4283,21 @@ function createPoolKeysLoader(getProviderRow, autoDisabled) {
4251
4283
  }
4252
4284
 
4253
4285
  // src/commands/paths.ts
4254
- var import_node_path4 = require("path");
4286
+ var import_node_path5 = require("path");
4255
4287
  function defaultVouchersPath(configPath) {
4256
- return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "vouchers.json");
4288
+ return (0, import_node_path5.join)((0, import_node_path5.dirname)(configPath), "vouchers.json");
4257
4289
  }
4258
4290
  function defaultPricingPath(configPath) {
4259
- return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "pricing.json");
4291
+ return (0, import_node_path5.join)((0, import_node_path5.dirname)(configPath), "pricing.json");
4260
4292
  }
4261
4293
  function defaultUsageEventsPath(configPath) {
4262
- return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "usage-events.jsonl");
4294
+ return (0, import_node_path5.join)((0, import_node_path5.dirname)(configPath), "usage-events.jsonl");
4263
4295
  }
4264
4296
  function defaultAuditDir(configPath) {
4265
- return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "audit");
4297
+ return (0, import_node_path5.join)((0, import_node_path5.dirname)(configPath), "audit");
4266
4298
  }
4267
4299
  function defaultBillingDir(configPath) {
4268
- return (0, import_node_path4.join)((0, import_node_path4.dirname)(configPath), "billing");
4300
+ return (0, import_node_path5.join)((0, import_node_path5.dirname)(configPath), "billing");
4269
4301
  }
4270
4302
 
4271
4303
  // src/ports/ConfigFileProviderConfigSource.ts
@@ -5262,7 +5294,7 @@ var JsonVoucherDb = class {
5262
5294
 
5263
5295
  // src/ports/JsonSubscriptionCredentialStore.ts
5264
5296
  var import_node_fs13 = require("fs");
5265
- var import_node_path7 = require("path");
5297
+ var import_node_path8 = require("path");
5266
5298
  var import_SubscriptionAccountHealth = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
5267
5299
  var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
5268
5300
  var import_SubscriptionIdentityStore = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
@@ -5344,9 +5376,9 @@ function findDuplicateCredentialIds(accounts) {
5344
5376
  // src/ports/external-cli-credentials.ts
5345
5377
  var import_node_fs11 = require("fs");
5346
5378
  var import_node_os2 = require("os");
5347
- var import_node_path5 = require("path");
5379
+ var import_node_path6 = require("path");
5348
5380
  function externalStorePath(provider, home = (0, import_node_os2.homedir)()) {
5349
- return provider === "claude" ? (0, import_node_path5.join)(home, ".claude", ".credentials.json") : (0, import_node_path5.join)(home, ".codex", "auth.json");
5381
+ return provider === "claude" ? (0, import_node_path6.join)(home, ".claude", ".credentials.json") : (0, import_node_path6.join)(home, ".codex", "auth.json");
5350
5382
  }
5351
5383
  function decodeJwtExpiryMs(token) {
5352
5384
  try {
@@ -5409,7 +5441,7 @@ function readExternalCliCredentials(provider, home = (0, import_node_os2.homedir
5409
5441
  // src/ports/external-cli-store.ts
5410
5442
  var import_node_fs12 = require("fs");
5411
5443
  var import_node_os3 = require("os");
5412
- var import_node_path6 = require("path");
5444
+ var import_node_path7 = require("path");
5413
5445
  function markerPath(provider, home) {
5414
5446
  return `${externalStorePath(provider, home)}.omnicross-managed`;
5415
5447
  }
@@ -5444,7 +5476,7 @@ function readExistingObject(path2) {
5444
5476
  }
5445
5477
  }
5446
5478
  function writeAtomic(path2, content) {
5447
- (0, import_node_fs12.mkdirSync)((0, import_node_path6.dirname)(path2), { recursive: true });
5479
+ (0, import_node_fs12.mkdirSync)((0, import_node_path7.dirname)(path2), { recursive: true });
5448
5480
  const temp = `${path2}.omnicross-tmp`;
5449
5481
  (0, import_node_fs12.writeFileSync)(temp, content, "utf8");
5450
5482
  (0, import_node_fs12.renameSync)(temp, path2);
@@ -6115,7 +6147,7 @@ var JsonSubscriptionCredentialStore = class {
6115
6147
  * → `enc:v1:`; already-`enc:`/`$ENV` untouched) before serializing, so any
6116
6148
  * write — incl. child 4's future refresh writes — lands encrypted. */
6117
6149
  persist(config) {
6118
- (0, import_node_fs13.mkdirSync)((0, import_node_path7.dirname)(this.tokensPath), { recursive: true });
6150
+ (0, import_node_fs13.mkdirSync)((0, import_node_path8.dirname)(this.tokensPath), { recursive: true });
6119
6151
  const encrypted = encryptTokens(config, this.box);
6120
6152
  (0, import_node_fs13.writeFileSync)(this.tokensPath, JSON.stringify(encrypted, null, 2) + "\n", "utf8");
6121
6153
  }
@@ -6465,7 +6497,7 @@ var AccountHealthSweeper = class {
6465
6497
 
6466
6498
  // src/audit/AuditPruneSweeper.ts
6467
6499
  var import_node_fs14 = require("fs");
6468
- var import_node_path8 = require("path");
6500
+ var import_node_path9 = require("path");
6469
6501
 
6470
6502
  // src/audit/auditFiles.ts
6471
6503
  var AUDIT_FILE_RE = /^audit-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
@@ -6491,8 +6523,8 @@ function auditFileDateMs(fileName) {
6491
6523
  var DAY_MS = 24 * 60 * 6e4;
6492
6524
  var SWEEP_INTERVAL_MS2 = 60 * 6e4;
6493
6525
  var AuditPruneSweeper = class {
6494
- constructor(auditDir, logger, config, intervalMs = SWEEP_INTERVAL_MS2, now = Date.now) {
6495
- this.auditDir = auditDir;
6526
+ constructor(auditDir2, logger, config, intervalMs = SWEEP_INTERVAL_MS2, now = Date.now) {
6527
+ this.auditDir = auditDir2;
6496
6528
  this.logger = logger;
6497
6529
  this.config = config;
6498
6530
  this.intervalMs = intervalMs;
@@ -6548,7 +6580,7 @@ var AuditPruneSweeper = class {
6548
6580
  const dateMs = auditFileDateMs(file);
6549
6581
  if (dateMs === null || dateMs >= cutoff) continue;
6550
6582
  try {
6551
- (0, import_node_fs14.unlinkSync)((0, import_node_path8.join)(this.auditDir, file));
6583
+ (0, import_node_fs14.unlinkSync)((0, import_node_path9.join)(this.auditDir, file));
6552
6584
  removed += 1;
6553
6585
  } catch (error) {
6554
6586
  this.logger.warn("[AuditPruneSweeper] failed to unlink expired audit file", {
@@ -6572,14 +6604,14 @@ var AuditPruneSweeper = class {
6572
6604
 
6573
6605
  // src/audit/auditReader.ts
6574
6606
  var import_node_fs15 = require("fs");
6575
- var import_node_path9 = require("path");
6607
+ var import_node_path10 = require("path");
6576
6608
  var DEFAULT_LIMIT = 200;
6577
6609
  var MAX_LIMIT = 2e3;
6578
- function readAuditRecords(auditDir, query = {}) {
6579
- if (!(0, import_node_fs15.existsSync)(auditDir)) return [];
6610
+ function readAuditRecords(auditDir2, query = {}) {
6611
+ if (!(0, import_node_fs15.existsSync)(auditDir2)) return [];
6580
6612
  let files;
6581
6613
  try {
6582
- files = (0, import_node_fs15.readdirSync)(auditDir).filter((f) => AUDIT_FILE_RE.test(f));
6614
+ files = (0, import_node_fs15.readdirSync)(auditDir2).filter((f) => AUDIT_FILE_RE.test(f));
6583
6615
  } catch {
6584
6616
  return [];
6585
6617
  }
@@ -6590,7 +6622,7 @@ function readAuditRecords(auditDir, query = {}) {
6590
6622
  for (const file of files.sort().reverse()) {
6591
6623
  let raw;
6592
6624
  try {
6593
- raw = (0, import_node_fs15.readFileSync)((0, import_node_path9.join)(auditDir, file), "utf8");
6625
+ raw = (0, import_node_fs15.readFileSync)((0, import_node_path10.join)(auditDir2, file), "utf8");
6594
6626
  } catch {
6595
6627
  continue;
6596
6628
  }
@@ -6620,10 +6652,10 @@ function isAuditRecord(value) {
6620
6652
 
6621
6653
  // src/audit/AuditWriter.ts
6622
6654
  var import_node_fs16 = require("fs");
6623
- var import_node_path10 = require("path");
6655
+ var import_node_path11 = require("path");
6624
6656
  var AuditWriter = class {
6625
- constructor(auditDir, logger, defer = (fn) => setTimeout(fn, 0)) {
6626
- this.auditDir = auditDir;
6657
+ constructor(auditDir2, logger, defer = (fn) => setTimeout(fn, 0)) {
6658
+ this.auditDir = auditDir2;
6627
6659
  this.logger = logger;
6628
6660
  this.defer = defer;
6629
6661
  }
@@ -6656,7 +6688,7 @@ var AuditWriter = class {
6656
6688
  (0, import_node_fs16.mkdirSync)(this.auditDir, { recursive: true });
6657
6689
  this.dirEnsured = true;
6658
6690
  }
6659
- const file = (0, import_node_path10.join)(this.auditDir, auditFileName(record.ts));
6691
+ const file = (0, import_node_path11.join)(this.auditDir, auditFileName(record.ts));
6660
6692
  (0, import_node_fs16.appendFileSync)(file, JSON.stringify(record) + "\n", "utf8");
6661
6693
  }
6662
6694
  };
@@ -6664,7 +6696,7 @@ var AuditWriter = class {
6664
6696
  // src/billing/BillingPublisher.ts
6665
6697
  var import_node_fs17 = require("fs");
6666
6698
  var import_node_crypto10 = require("crypto");
6667
- var import_node_path11 = require("path");
6699
+ var import_node_path12 = require("path");
6668
6700
  var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
6669
6701
 
6670
6702
  // src/billing/billingFiles.ts
@@ -6735,7 +6767,7 @@ var BillingPublisher = class {
6735
6767
  */
6736
6768
  appendNow(event) {
6737
6769
  this.ensureDir();
6738
- const file = (0, import_node_path11.join)(this.billingDir, billingFileName(event.ts));
6770
+ const file = (0, import_node_path12.join)(this.billingDir, billingFileName(event.ts));
6739
6771
  (0, import_node_fs17.appendFileSync)(file, JSON.stringify(event) + "\n", "utf8");
6740
6772
  }
6741
6773
  /**
@@ -6785,7 +6817,7 @@ var BillingPublisher = class {
6785
6817
  markDelivered(event) {
6786
6818
  try {
6787
6819
  this.ensureDir();
6788
- const file = (0, import_node_path11.join)(this.billingDir, deliveredFileName(event.ts));
6820
+ const file = (0, import_node_path12.join)(this.billingDir, deliveredFileName(event.ts));
6789
6821
  (0, import_node_fs17.appendFileSync)(file, JSON.stringify({ id: event.id, deliveredAt: this.now() }) + "\n", "utf8");
6790
6822
  } catch (error) {
6791
6823
  this.logger.warn("[BillingPublisher] failed to append delivery marker", {
@@ -6802,7 +6834,7 @@ var BillingPublisher = class {
6802
6834
 
6803
6835
  // src/billing/billingReader.ts
6804
6836
  var import_node_fs18 = require("fs");
6805
- var import_node_path12 = require("path");
6837
+ var import_node_path13 = require("path");
6806
6838
  function readBillingLedger(billingDir) {
6807
6839
  const view = { events: [], deliveredIds: /* @__PURE__ */ new Set() };
6808
6840
  if (!(0, import_node_fs18.existsSync)(billingDir)) return view;
@@ -6839,7 +6871,7 @@ function readBillingStatus(billingDir) {
6839
6871
  function parseLines(dir, file) {
6840
6872
  let raw;
6841
6873
  try {
6842
- raw = (0, import_node_fs18.readFileSync)((0, import_node_path12.join)(dir, file), "utf8");
6874
+ raw = (0, import_node_fs18.readFileSync)((0, import_node_path13.join)(dir, file), "utf8");
6843
6875
  } catch {
6844
6876
  return [];
6845
6877
  }
@@ -7280,7 +7312,7 @@ function buildDaemon(config, paths) {
7280
7312
  // lines through the injected logger (honors level/format/file sink).
7281
7313
  logger
7282
7314
  });
7283
- const auditDir = defaultAuditDir(paths.configPath);
7315
+ const auditDir2 = defaultAuditDir(paths.configPath);
7284
7316
  const billingDir = defaultBillingDir(paths.configPath);
7285
7317
  const adminServer = new AdminServer({
7286
7318
  configPath: paths.configPath,
@@ -7321,7 +7353,7 @@ function buildDaemon(config, paths) {
7321
7353
  // the app polls the token-free status. A test seam (`paths.codexAwaitLoopback`)
7322
7354
  // can inject a mock so no real port is bound.
7323
7355
  codexSessions: new CodexOAuthSessionStore(),
7324
- codexAwaitLoopback: paths.codexAwaitLoopback ?? ((state, timeoutMs) => awaitLoopbackCode(state, timeoutMs)),
7356
+ codexAwaitLoopback: paths.codexAwaitLoopback ?? ((state, timeoutMs, signal) => awaitLoopbackCode(state, timeoutMs, signal)),
7325
7357
  // Migration pack (app-parity child 6, design D2/D3) — the concrete credential
7326
7358
  // store provides BOTH the full DECRYPTED read (`getFullConfig`, export) and
7327
7359
  // the multi-account append (`appendProviderAccount`, import re-encrypts at-
@@ -7356,7 +7388,7 @@ function buildDaemon(config, paths) {
7356
7388
  // date-rotated audit store. Bound to the store dir here so the AdminServer
7357
7389
  // carries no path/store coupling. Records hold IP/UA/bodies → admin-only,
7358
7390
  // NEVER unauth, NEVER on `/health`. Routed in `AdminServer` (not `adminApi.ts`).
7359
- auditReader: (query) => readAuditRecords(auditDir, query),
7391
+ auditReader: (query) => readAuditRecords(auditDir2, query),
7360
7392
  // billing-event-stream: the AUTHED `GET /admin/api/billing-status` returns the
7361
7393
  // secret-free total/delivered/pending counts of the durable ledger.
7362
7394
  billingStatusReader: () => readBillingStatus(billingDir)
@@ -7366,9 +7398,9 @@ function buildDaemon(config, paths) {
7366
7398
  fetchImpl: (url, init) => (0, import_upstreamFetch7.fetchUpstream)(url, init)
7367
7399
  });
7368
7400
  setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth2.getSharedAccountHealth)());
7369
- const auditWriter = new AuditWriter(auditDir, logger);
7370
- const auditPruneSweeper = new AuditPruneSweeper(auditDir, logger, import_audit_types.DEFAULT_AUDIT_CONFIG);
7371
- setAuditRuntime(auditWriter, auditPruneSweeper);
7401
+ const auditWriter = new AuditWriter(auditDir2, logger);
7402
+ const auditPruneSweeper = new AuditPruneSweeper(auditDir2, logger, import_audit_types.DEFAULT_AUDIT_CONFIG);
7403
+ setAuditRuntime(auditWriter, auditPruneSweeper, auditDir2);
7372
7404
  const billingPublisher = new BillingPublisher(billingDir, logger);
7373
7405
  const billingRetrySweeper = new BillingRetrySweeper(
7374
7406
  billingDir,
package/dist/index.d.cts CHANGED
@@ -1048,7 +1048,7 @@ interface SubscriptionAccountAppender {
1048
1048
  */
1049
1049
 
1050
1050
  /** The loopback-listener fn (injected so tests need not bind a real port). */
1051
- type CodexLoopbackFn = (state: string, timeoutMs?: number) => Promise<string>;
1051
+ type CodexLoopbackFn = (state: string, timeoutMs?: number, signal?: AbortSignal) => Promise<string>;
1052
1052
  /** One codex sign-in flow's polled status (NEVER carries a token). */
1053
1053
  interface CodexFlowState {
1054
1054
  status: 'pending' | 'done' | 'error';
@@ -1066,13 +1066,18 @@ declare class CodexOAuthSessionStore {
1066
1066
  private readonly ttlMs;
1067
1067
  private readonly sessions;
1068
1068
  private activeSessionId;
1069
+ private readonly aborters;
1069
1070
  constructor(ttlMs?: number);
1070
1071
  /** Whether a codex sign-in is currently in flight (port 1455 held). */
1071
1072
  isBusy(): boolean;
1072
1073
  /** Mint a fresh sessionId, mark it pending + active, return the id. */
1073
- begin(): string;
1074
+ begin(): {
1075
+ sessionId: string;
1076
+ signal: AbortSignal;
1077
+ };
1074
1078
  /** Settle a flow (done/error) + free the active slot. */
1075
1079
  settle(sessionId: string, status: 'done' | 'error', error?: string): void;
1080
+ cancel(sessionId: string): boolean;
1076
1081
  /** Read a flow's status (token-free), or null when unknown/expired. */
1077
1082
  get(sessionId: string): CodexFlowState | null;
1078
1083
  /** Drop expired flows; free the active slot if the active flow expired. */
package/dist/index.d.ts CHANGED
@@ -1048,7 +1048,7 @@ interface SubscriptionAccountAppender {
1048
1048
  */
1049
1049
 
1050
1050
  /** The loopback-listener fn (injected so tests need not bind a real port). */
1051
- type CodexLoopbackFn = (state: string, timeoutMs?: number) => Promise<string>;
1051
+ type CodexLoopbackFn = (state: string, timeoutMs?: number, signal?: AbortSignal) => Promise<string>;
1052
1052
  /** One codex sign-in flow's polled status (NEVER carries a token). */
1053
1053
  interface CodexFlowState {
1054
1054
  status: 'pending' | 'done' | 'error';
@@ -1066,13 +1066,18 @@ declare class CodexOAuthSessionStore {
1066
1066
  private readonly ttlMs;
1067
1067
  private readonly sessions;
1068
1068
  private activeSessionId;
1069
+ private readonly aborters;
1069
1070
  constructor(ttlMs?: number);
1070
1071
  /** Whether a codex sign-in is currently in flight (port 1455 held). */
1071
1072
  isBusy(): boolean;
1072
1073
  /** Mint a fresh sessionId, mark it pending + active, return the id. */
1073
- begin(): string;
1074
+ begin(): {
1075
+ sessionId: string;
1076
+ signal: AbortSignal;
1077
+ };
1074
1078
  /** Settle a flow (done/error) + free the active slot. */
1075
1079
  settle(sessionId: string, status: 'done' | 'error', error?: string): void;
1080
+ cancel(sessionId: string): boolean;
1076
1081
  /** Read a flow's status (token-free), or null when unknown/expired. */
1077
1082
  get(sessionId: string): CodexFlowState | null;
1078
1083
  /** Drop expired flows; free the active slot if the active flow expired. */