@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/cli.cjs +80 -50
- package/dist/cli.js +66 -36
- package/dist/index.cjs +85 -53
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +72 -40
- package/package.json +2 -2
package/dist/cli.cjs
CHANGED
|
@@ -934,7 +934,7 @@ async function keysRevoke(db, id) {
|
|
|
934
934
|
// src/commands/launch.ts
|
|
935
935
|
var import_node_child_process2 = require("child_process");
|
|
936
936
|
var import_node_fs21 = require("fs");
|
|
937
|
-
var
|
|
937
|
+
var import_node_path14 = require("path");
|
|
938
938
|
var import_node_util3 = require("util");
|
|
939
939
|
var import_cli_launcher2 = require("@omnicross/cli-launcher");
|
|
940
940
|
|
|
@@ -966,6 +966,7 @@ var CodexOAuthSessionStore = class {
|
|
|
966
966
|
ttlMs;
|
|
967
967
|
sessions = /* @__PURE__ */ new Map();
|
|
968
968
|
activeSessionId = null;
|
|
969
|
+
aborters = /* @__PURE__ */ new Map();
|
|
969
970
|
/** Whether a codex sign-in is currently in flight (port 1455 held). */
|
|
970
971
|
isBusy() {
|
|
971
972
|
this.sweep();
|
|
@@ -977,13 +978,22 @@ var CodexOAuthSessionStore = class {
|
|
|
977
978
|
const sessionId = import_node_crypto3.default.randomBytes(24).toString("base64url");
|
|
978
979
|
this.sessions.set(sessionId, { status: "pending", createdAt: Date.now() });
|
|
979
980
|
this.activeSessionId = sessionId;
|
|
980
|
-
|
|
981
|
+
const controller = new AbortController();
|
|
982
|
+
this.aborters.set(sessionId, controller);
|
|
983
|
+
return { sessionId, signal: controller.signal };
|
|
981
984
|
}
|
|
982
985
|
/** Settle a flow (done/error) + free the active slot. */
|
|
983
986
|
settle(sessionId, status, error) {
|
|
984
987
|
const prior = this.sessions.get(sessionId);
|
|
985
988
|
this.sessions.set(sessionId, { status, error, createdAt: prior?.createdAt ?? Date.now() });
|
|
986
989
|
if (this.activeSessionId === sessionId) this.activeSessionId = null;
|
|
990
|
+
this.aborters.delete(sessionId);
|
|
991
|
+
}
|
|
992
|
+
cancel(sessionId) {
|
|
993
|
+
if (!this.sessions.has(sessionId)) return false;
|
|
994
|
+
this.aborters.get(sessionId)?.abort();
|
|
995
|
+
this.settle(sessionId, "error", "login: cancelled");
|
|
996
|
+
return true;
|
|
987
997
|
}
|
|
988
998
|
/** Read a flow's status (token-free), or null when unknown/expired. */
|
|
989
999
|
get(sessionId) {
|
|
@@ -1012,13 +1022,13 @@ function handleCodexOAuthStart(deps) {
|
|
|
1012
1022
|
);
|
|
1013
1023
|
}
|
|
1014
1024
|
const { authUrl, codeVerifier, state } = import_subscriptions.codexOAuth.generateAuthParams();
|
|
1015
|
-
const sessionId = deps.codexSessions.begin();
|
|
1016
|
-
void runCodexLoopback(sessionId, codeVerifier, state, deps);
|
|
1025
|
+
const { sessionId, signal } = deps.codexSessions.begin();
|
|
1026
|
+
void runCodexLoopback(sessionId, codeVerifier, state, signal, deps);
|
|
1017
1027
|
return { status: 200, body: { authUrl, sessionId } };
|
|
1018
1028
|
}
|
|
1019
|
-
async function runCodexLoopback(sessionId, codeVerifier, state, deps) {
|
|
1029
|
+
async function runCodexLoopback(sessionId, codeVerifier, state, signal, deps) {
|
|
1020
1030
|
try {
|
|
1021
|
-
const code = await deps.codexAwaitLoopback(state);
|
|
1031
|
+
const code = await deps.codexAwaitLoopback(state, void 0, signal);
|
|
1022
1032
|
const result = await import_subscriptions.codexOAuth.exchangeCodeForTokens(
|
|
1023
1033
|
{ authorizationCode: code, codeVerifier, state },
|
|
1024
1034
|
deps.oauthExchangeFetch
|
|
@@ -1040,6 +1050,10 @@ async function runCodexLoopback(sessionId, codeVerifier, state, deps) {
|
|
|
1040
1050
|
deps.codexSessions.settle(sessionId, "error", reason);
|
|
1041
1051
|
}
|
|
1042
1052
|
}
|
|
1053
|
+
function handleCodexOAuthCancel(sessionId, deps) {
|
|
1054
|
+
if (!deps.codexSessions.cancel(sessionId)) return err(404, "unknown or expired codex sign-in session");
|
|
1055
|
+
return { status: 200, body: { ok: true } };
|
|
1056
|
+
}
|
|
1043
1057
|
function handleCodexOAuthStatus(sessionId, deps) {
|
|
1044
1058
|
const s = deps.codexSessions.get(sessionId);
|
|
1045
1059
|
if (!s) return err(404, "unknown or expired codex sign-in session");
|
|
@@ -2199,12 +2213,16 @@ function preserveWebhookSecrets(incoming, current) {
|
|
|
2199
2213
|
}
|
|
2200
2214
|
|
|
2201
2215
|
// src/audit/auditRuntime.ts
|
|
2216
|
+
var import_node_path4 = require("path");
|
|
2202
2217
|
var import_auditSink = require("@omnicross/core/pipeline/auditSink");
|
|
2218
|
+
var import_upstreamTrace = require("@omnicross/core/pipeline/upstreamTrace");
|
|
2203
2219
|
var writer = null;
|
|
2204
2220
|
var sweeper = null;
|
|
2205
|
-
|
|
2221
|
+
var auditDir = "";
|
|
2222
|
+
function setAuditRuntime(w, s, dir) {
|
|
2206
2223
|
writer = w;
|
|
2207
2224
|
sweeper = s;
|
|
2225
|
+
auditDir = dir;
|
|
2208
2226
|
}
|
|
2209
2227
|
function applyAuditConfig(config) {
|
|
2210
2228
|
const enabled = config?.enabled === true && writer !== null;
|
|
@@ -2216,9 +2234,11 @@ function applyAuditConfig(config) {
|
|
|
2216
2234
|
sweeper.configure(config);
|
|
2217
2235
|
sweeper.start();
|
|
2218
2236
|
}
|
|
2237
|
+
(0, import_upstreamTrace.setUpstreamTracePath)(config.captureBodies ? (0, import_node_path4.join)(auditDir, "upstream-trace.jsonl") : null);
|
|
2219
2238
|
} else {
|
|
2220
2239
|
(0, import_auditSink.setAuditCaptureConfig)(null);
|
|
2221
2240
|
(0, import_auditSink.setAuditSink)(null);
|
|
2241
|
+
(0, import_upstreamTrace.setUpstreamTracePath)(null);
|
|
2222
2242
|
if (sweeper) {
|
|
2223
2243
|
if (config) sweeper.configure(config);
|
|
2224
2244
|
sweeper.dispose();
|
|
@@ -3831,6 +3851,10 @@ async function handleAccounts(req, res, method, rest, deps) {
|
|
|
3831
3851
|
const result = handleCodexOAuthStatus(rest[2], deps);
|
|
3832
3852
|
return writeJson2(res, result.status, result.body);
|
|
3833
3853
|
}
|
|
3854
|
+
if (method === "DELETE" && rest[0] === "codex" && rest[1] === "oauth" && rest[2]) {
|
|
3855
|
+
const result = handleCodexOAuthCancel(rest[2], deps);
|
|
3856
|
+
return writeJson2(res, result.status, result.body);
|
|
3857
|
+
}
|
|
3834
3858
|
if (method === "PUT" || method === "POST" || method === "DELETE") {
|
|
3835
3859
|
const providerId = asSubscriptionProviderId(rest[0]);
|
|
3836
3860
|
if (!providerId) {
|
|
@@ -4078,7 +4102,7 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
|
|
|
4078
4102
|
var import_node_fs6 = require("fs");
|
|
4079
4103
|
var import_promises = require("fs/promises");
|
|
4080
4104
|
var import_node_module = require("module");
|
|
4081
|
-
var
|
|
4105
|
+
var import_node_path5 = __toESM(require("path"), 1);
|
|
4082
4106
|
var import_meta = {};
|
|
4083
4107
|
var CONTENT_TYPES = {
|
|
4084
4108
|
".html": "text/html; charset=utf-8",
|
|
@@ -4099,13 +4123,13 @@ var CONTENT_TYPES = {
|
|
|
4099
4123
|
function resolveUiDist() {
|
|
4100
4124
|
const fromEnv = process.env["OMNICROSS_UI_DIST"];
|
|
4101
4125
|
if (fromEnv) {
|
|
4102
|
-
return (0, import_node_fs6.existsSync)(
|
|
4126
|
+
return (0, import_node_fs6.existsSync)(import_node_path5.default.join(fromEnv, "index.html")) ? import_node_path5.default.resolve(fromEnv) : null;
|
|
4103
4127
|
}
|
|
4104
4128
|
try {
|
|
4105
4129
|
const req = (0, import_node_module.createRequire)(typeof __filename !== "undefined" ? __filename : import_meta.url);
|
|
4106
4130
|
const pkgJson = req.resolve("@omnicross/ui/package.json");
|
|
4107
|
-
const dist =
|
|
4108
|
-
return (0, import_node_fs6.existsSync)(
|
|
4131
|
+
const dist = import_node_path5.default.join(import_node_path5.default.dirname(pkgJson), "dist");
|
|
4132
|
+
return (0, import_node_fs6.existsSync)(import_node_path5.default.join(dist, "index.html")) ? dist : null;
|
|
4109
4133
|
} catch {
|
|
4110
4134
|
return null;
|
|
4111
4135
|
}
|
|
@@ -4147,16 +4171,16 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
|
|
|
4147
4171
|
res.end(JSON.stringify({ error: { type: "bad_request", message: "invalid path" } }));
|
|
4148
4172
|
return true;
|
|
4149
4173
|
}
|
|
4150
|
-
const filePath =
|
|
4151
|
-
if (filePath !== uiDist && !filePath.startsWith(uiDist +
|
|
4174
|
+
const filePath = import_node_path5.default.resolve(uiDist, rel === "" ? "index.html" : rel);
|
|
4175
|
+
if (filePath !== uiDist && !filePath.startsWith(uiDist + import_node_path5.default.sep)) {
|
|
4152
4176
|
res.writeHead(403, { "Content-Type": "application/json" });
|
|
4153
4177
|
res.end(JSON.stringify({ error: { type: "forbidden", message: "path outside ui root" } }));
|
|
4154
4178
|
return true;
|
|
4155
4179
|
}
|
|
4156
4180
|
let target = filePath;
|
|
4157
4181
|
if (!(0, import_node_fs6.existsSync)(target) || (0, import_node_fs6.statSync)(target).isDirectory()) {
|
|
4158
|
-
if (
|
|
4159
|
-
target =
|
|
4182
|
+
if (import_node_path5.default.extname(rel) === "") {
|
|
4183
|
+
target = import_node_path5.default.join(uiDist, "index.html");
|
|
4160
4184
|
} else {
|
|
4161
4185
|
res.writeHead(404, { "Content-Type": "application/json" });
|
|
4162
4186
|
res.end(JSON.stringify({ error: { type: "not_found", message: "no such ui asset" } }));
|
|
@@ -4164,14 +4188,14 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
|
|
|
4164
4188
|
}
|
|
4165
4189
|
}
|
|
4166
4190
|
const body = await (0, import_promises.readFile)(target);
|
|
4167
|
-
const type = CONTENT_TYPES[
|
|
4191
|
+
const type = CONTENT_TYPES[import_node_path5.default.extname(target).toLowerCase()] ?? "application/octet-stream";
|
|
4168
4192
|
res.writeHead(200, { "Content-Type": type, "Content-Length": body.length });
|
|
4169
4193
|
res.end(req.method === "HEAD" ? void 0 : body);
|
|
4170
4194
|
return true;
|
|
4171
4195
|
}
|
|
4172
4196
|
|
|
4173
4197
|
// src/admin/version.ts
|
|
4174
|
-
var DAEMON_VERSION = true ? "0.1.
|
|
4198
|
+
var DAEMON_VERSION = true ? "0.1.5" : "0.0.0-dev";
|
|
4175
4199
|
|
|
4176
4200
|
// src/admin/AdminServer.ts
|
|
4177
4201
|
var LOOPBACK_ADDR = "127.0.0.1";
|
|
@@ -4426,7 +4450,7 @@ var DEFAULT_TIMEOUT_MS = 5 * 6e4;
|
|
|
4426
4450
|
function pageHtml(message) {
|
|
4427
4451
|
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>`;
|
|
4428
4452
|
}
|
|
4429
|
-
function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
4453
|
+
function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal) {
|
|
4430
4454
|
return new Promise((resolve, reject) => {
|
|
4431
4455
|
let settled = false;
|
|
4432
4456
|
const finish = (server2, fn) => {
|
|
@@ -4460,6 +4484,12 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS) {
|
|
|
4460
4484
|
res.end(pageHtml("Login complete."));
|
|
4461
4485
|
finish(server, () => resolve(code));
|
|
4462
4486
|
});
|
|
4487
|
+
const abort = () => finish(server, () => reject(new Error("login: cancelled")));
|
|
4488
|
+
if (signal?.aborted) {
|
|
4489
|
+
abort();
|
|
4490
|
+
return;
|
|
4491
|
+
}
|
|
4492
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
4463
4493
|
server.on("error", (err5) => {
|
|
4464
4494
|
if (settled) return;
|
|
4465
4495
|
settled = true;
|
|
@@ -5418,7 +5448,7 @@ var JsonVoucherDb = class {
|
|
|
5418
5448
|
|
|
5419
5449
|
// src/ports/JsonSubscriptionCredentialStore.ts
|
|
5420
5450
|
var import_node_fs14 = require("fs");
|
|
5421
|
-
var
|
|
5451
|
+
var import_node_path8 = require("path");
|
|
5422
5452
|
var import_SubscriptionAccountHealth = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
|
|
5423
5453
|
var import_upstreamFetch3 = require("@omnicross/core/pipeline/upstreamFetch");
|
|
5424
5454
|
var import_SubscriptionIdentityStore = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
|
|
@@ -5500,9 +5530,9 @@ function findDuplicateCredentialIds(accounts) {
|
|
|
5500
5530
|
// src/ports/external-cli-credentials.ts
|
|
5501
5531
|
var import_node_fs12 = require("fs");
|
|
5502
5532
|
var import_node_os2 = require("os");
|
|
5503
|
-
var
|
|
5533
|
+
var import_node_path6 = require("path");
|
|
5504
5534
|
function externalStorePath(provider, home = (0, import_node_os2.homedir)()) {
|
|
5505
|
-
return provider === "claude" ? (0,
|
|
5535
|
+
return provider === "claude" ? (0, import_node_path6.join)(home, ".claude", ".credentials.json") : (0, import_node_path6.join)(home, ".codex", "auth.json");
|
|
5506
5536
|
}
|
|
5507
5537
|
function decodeJwtExpiryMs(token) {
|
|
5508
5538
|
try {
|
|
@@ -5565,7 +5595,7 @@ function readExternalCliCredentials(provider, home = (0, import_node_os2.homedir
|
|
|
5565
5595
|
// src/ports/external-cli-store.ts
|
|
5566
5596
|
var import_node_fs13 = require("fs");
|
|
5567
5597
|
var import_node_os3 = require("os");
|
|
5568
|
-
var
|
|
5598
|
+
var import_node_path7 = require("path");
|
|
5569
5599
|
function markerPath(provider, home) {
|
|
5570
5600
|
return `${externalStorePath(provider, home)}.omnicross-managed`;
|
|
5571
5601
|
}
|
|
@@ -5600,7 +5630,7 @@ function readExistingObject(path2) {
|
|
|
5600
5630
|
}
|
|
5601
5631
|
}
|
|
5602
5632
|
function writeAtomic(path2, content) {
|
|
5603
|
-
(0, import_node_fs13.mkdirSync)((0,
|
|
5633
|
+
(0, import_node_fs13.mkdirSync)((0, import_node_path7.dirname)(path2), { recursive: true });
|
|
5604
5634
|
const temp = `${path2}.omnicross-tmp`;
|
|
5605
5635
|
(0, import_node_fs13.writeFileSync)(temp, content, "utf8");
|
|
5606
5636
|
(0, import_node_fs13.renameSync)(temp, path2);
|
|
@@ -6271,7 +6301,7 @@ var JsonSubscriptionCredentialStore = class {
|
|
|
6271
6301
|
* → `enc:v1:`; already-`enc:`/`$ENV` untouched) before serializing, so any
|
|
6272
6302
|
* write — incl. child 4's future refresh writes — lands encrypted. */
|
|
6273
6303
|
persist(config) {
|
|
6274
|
-
(0, import_node_fs14.mkdirSync)((0,
|
|
6304
|
+
(0, import_node_fs14.mkdirSync)((0, import_node_path8.dirname)(this.tokensPath), { recursive: true });
|
|
6275
6305
|
const encrypted = encryptTokens(config, this.box);
|
|
6276
6306
|
(0, import_node_fs14.writeFileSync)(this.tokensPath, JSON.stringify(encrypted, null, 2) + "\n", "utf8");
|
|
6277
6307
|
}
|
|
@@ -6621,7 +6651,7 @@ var AccountHealthSweeper = class {
|
|
|
6621
6651
|
|
|
6622
6652
|
// src/audit/AuditPruneSweeper.ts
|
|
6623
6653
|
var import_node_fs15 = require("fs");
|
|
6624
|
-
var
|
|
6654
|
+
var import_node_path9 = require("path");
|
|
6625
6655
|
|
|
6626
6656
|
// src/audit/auditFiles.ts
|
|
6627
6657
|
var AUDIT_FILE_RE = /^audit-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
|
|
@@ -6647,8 +6677,8 @@ function auditFileDateMs(fileName) {
|
|
|
6647
6677
|
var DAY_MS = 24 * 60 * 6e4;
|
|
6648
6678
|
var SWEEP_INTERVAL_MS2 = 60 * 6e4;
|
|
6649
6679
|
var AuditPruneSweeper = class {
|
|
6650
|
-
constructor(
|
|
6651
|
-
this.auditDir =
|
|
6680
|
+
constructor(auditDir2, logger, config, intervalMs = SWEEP_INTERVAL_MS2, now = Date.now) {
|
|
6681
|
+
this.auditDir = auditDir2;
|
|
6652
6682
|
this.logger = logger;
|
|
6653
6683
|
this.config = config;
|
|
6654
6684
|
this.intervalMs = intervalMs;
|
|
@@ -6704,7 +6734,7 @@ var AuditPruneSweeper = class {
|
|
|
6704
6734
|
const dateMs = auditFileDateMs(file);
|
|
6705
6735
|
if (dateMs === null || dateMs >= cutoff) continue;
|
|
6706
6736
|
try {
|
|
6707
|
-
(0, import_node_fs15.unlinkSync)((0,
|
|
6737
|
+
(0, import_node_fs15.unlinkSync)((0, import_node_path9.join)(this.auditDir, file));
|
|
6708
6738
|
removed += 1;
|
|
6709
6739
|
} catch (error) {
|
|
6710
6740
|
this.logger.warn("[AuditPruneSweeper] failed to unlink expired audit file", {
|
|
@@ -6728,14 +6758,14 @@ var AuditPruneSweeper = class {
|
|
|
6728
6758
|
|
|
6729
6759
|
// src/audit/auditReader.ts
|
|
6730
6760
|
var import_node_fs16 = require("fs");
|
|
6731
|
-
var
|
|
6761
|
+
var import_node_path10 = require("path");
|
|
6732
6762
|
var DEFAULT_LIMIT = 200;
|
|
6733
6763
|
var MAX_LIMIT = 2e3;
|
|
6734
|
-
function readAuditRecords(
|
|
6735
|
-
if (!(0, import_node_fs16.existsSync)(
|
|
6764
|
+
function readAuditRecords(auditDir2, query = {}) {
|
|
6765
|
+
if (!(0, import_node_fs16.existsSync)(auditDir2)) return [];
|
|
6736
6766
|
let files;
|
|
6737
6767
|
try {
|
|
6738
|
-
files = (0, import_node_fs16.readdirSync)(
|
|
6768
|
+
files = (0, import_node_fs16.readdirSync)(auditDir2).filter((f) => AUDIT_FILE_RE.test(f));
|
|
6739
6769
|
} catch {
|
|
6740
6770
|
return [];
|
|
6741
6771
|
}
|
|
@@ -6746,7 +6776,7 @@ function readAuditRecords(auditDir, query = {}) {
|
|
|
6746
6776
|
for (const file of files.sort().reverse()) {
|
|
6747
6777
|
let raw;
|
|
6748
6778
|
try {
|
|
6749
|
-
raw = (0, import_node_fs16.readFileSync)((0,
|
|
6779
|
+
raw = (0, import_node_fs16.readFileSync)((0, import_node_path10.join)(auditDir2, file), "utf8");
|
|
6750
6780
|
} catch {
|
|
6751
6781
|
continue;
|
|
6752
6782
|
}
|
|
@@ -6776,10 +6806,10 @@ function isAuditRecord(value) {
|
|
|
6776
6806
|
|
|
6777
6807
|
// src/audit/AuditWriter.ts
|
|
6778
6808
|
var import_node_fs17 = require("fs");
|
|
6779
|
-
var
|
|
6809
|
+
var import_node_path11 = require("path");
|
|
6780
6810
|
var AuditWriter = class {
|
|
6781
|
-
constructor(
|
|
6782
|
-
this.auditDir =
|
|
6811
|
+
constructor(auditDir2, logger, defer = (fn) => setTimeout(fn, 0)) {
|
|
6812
|
+
this.auditDir = auditDir2;
|
|
6783
6813
|
this.logger = logger;
|
|
6784
6814
|
this.defer = defer;
|
|
6785
6815
|
}
|
|
@@ -6812,7 +6842,7 @@ var AuditWriter = class {
|
|
|
6812
6842
|
(0, import_node_fs17.mkdirSync)(this.auditDir, { recursive: true });
|
|
6813
6843
|
this.dirEnsured = true;
|
|
6814
6844
|
}
|
|
6815
|
-
const file = (0,
|
|
6845
|
+
const file = (0, import_node_path11.join)(this.auditDir, auditFileName(record.ts));
|
|
6816
6846
|
(0, import_node_fs17.appendFileSync)(file, JSON.stringify(record) + "\n", "utf8");
|
|
6817
6847
|
}
|
|
6818
6848
|
};
|
|
@@ -6820,7 +6850,7 @@ var AuditWriter = class {
|
|
|
6820
6850
|
// src/billing/BillingPublisher.ts
|
|
6821
6851
|
var import_node_fs18 = require("fs");
|
|
6822
6852
|
var import_node_crypto10 = require("crypto");
|
|
6823
|
-
var
|
|
6853
|
+
var import_node_path12 = require("path");
|
|
6824
6854
|
var import_upstreamFetch5 = require("@omnicross/core/pipeline/upstreamFetch");
|
|
6825
6855
|
|
|
6826
6856
|
// src/billing/billingFiles.ts
|
|
@@ -6891,7 +6921,7 @@ var BillingPublisher = class {
|
|
|
6891
6921
|
*/
|
|
6892
6922
|
appendNow(event) {
|
|
6893
6923
|
this.ensureDir();
|
|
6894
|
-
const file = (0,
|
|
6924
|
+
const file = (0, import_node_path12.join)(this.billingDir, billingFileName(event.ts));
|
|
6895
6925
|
(0, import_node_fs18.appendFileSync)(file, JSON.stringify(event) + "\n", "utf8");
|
|
6896
6926
|
}
|
|
6897
6927
|
/**
|
|
@@ -6941,7 +6971,7 @@ var BillingPublisher = class {
|
|
|
6941
6971
|
markDelivered(event) {
|
|
6942
6972
|
try {
|
|
6943
6973
|
this.ensureDir();
|
|
6944
|
-
const file = (0,
|
|
6974
|
+
const file = (0, import_node_path12.join)(this.billingDir, deliveredFileName(event.ts));
|
|
6945
6975
|
(0, import_node_fs18.appendFileSync)(file, JSON.stringify({ id: event.id, deliveredAt: this.now() }) + "\n", "utf8");
|
|
6946
6976
|
} catch (error) {
|
|
6947
6977
|
this.logger.warn("[BillingPublisher] failed to append delivery marker", {
|
|
@@ -6958,7 +6988,7 @@ var BillingPublisher = class {
|
|
|
6958
6988
|
|
|
6959
6989
|
// src/billing/billingReader.ts
|
|
6960
6990
|
var import_node_fs19 = require("fs");
|
|
6961
|
-
var
|
|
6991
|
+
var import_node_path13 = require("path");
|
|
6962
6992
|
function readBillingLedger(billingDir) {
|
|
6963
6993
|
const view = { events: [], deliveredIds: /* @__PURE__ */ new Set() };
|
|
6964
6994
|
if (!(0, import_node_fs19.existsSync)(billingDir)) return view;
|
|
@@ -6995,7 +7025,7 @@ function readBillingStatus(billingDir) {
|
|
|
6995
7025
|
function parseLines(dir, file) {
|
|
6996
7026
|
let raw;
|
|
6997
7027
|
try {
|
|
6998
|
-
raw = (0, import_node_fs19.readFileSync)((0,
|
|
7028
|
+
raw = (0, import_node_fs19.readFileSync)((0, import_node_path13.join)(dir, file), "utf8");
|
|
6999
7029
|
} catch {
|
|
7000
7030
|
return [];
|
|
7001
7031
|
}
|
|
@@ -7436,7 +7466,7 @@ function buildDaemon(config, paths) {
|
|
|
7436
7466
|
// lines through the injected logger (honors level/format/file sink).
|
|
7437
7467
|
logger
|
|
7438
7468
|
});
|
|
7439
|
-
const
|
|
7469
|
+
const auditDir2 = defaultAuditDir(paths.configPath);
|
|
7440
7470
|
const billingDir = defaultBillingDir(paths.configPath);
|
|
7441
7471
|
const adminServer = new AdminServer({
|
|
7442
7472
|
configPath: paths.configPath,
|
|
@@ -7477,7 +7507,7 @@ function buildDaemon(config, paths) {
|
|
|
7477
7507
|
// the app polls the token-free status. A test seam (`paths.codexAwaitLoopback`)
|
|
7478
7508
|
// can inject a mock so no real port is bound.
|
|
7479
7509
|
codexSessions: new CodexOAuthSessionStore(),
|
|
7480
|
-
codexAwaitLoopback: paths.codexAwaitLoopback ?? ((state, timeoutMs) => awaitLoopbackCode(state, timeoutMs)),
|
|
7510
|
+
codexAwaitLoopback: paths.codexAwaitLoopback ?? ((state, timeoutMs, signal) => awaitLoopbackCode(state, timeoutMs, signal)),
|
|
7481
7511
|
// Migration pack (app-parity child 6, design D2/D3) — the concrete credential
|
|
7482
7512
|
// store provides BOTH the full DECRYPTED read (`getFullConfig`, export) and
|
|
7483
7513
|
// the multi-account append (`appendProviderAccount`, import re-encrypts at-
|
|
@@ -7512,7 +7542,7 @@ function buildDaemon(config, paths) {
|
|
|
7512
7542
|
// date-rotated audit store. Bound to the store dir here so the AdminServer
|
|
7513
7543
|
// carries no path/store coupling. Records hold IP/UA/bodies → admin-only,
|
|
7514
7544
|
// NEVER unauth, NEVER on `/health`. Routed in `AdminServer` (not `adminApi.ts`).
|
|
7515
|
-
auditReader: (query) => readAuditRecords(
|
|
7545
|
+
auditReader: (query) => readAuditRecords(auditDir2, query),
|
|
7516
7546
|
// billing-event-stream: the AUTHED `GET /admin/api/billing-status` returns the
|
|
7517
7547
|
// secret-free total/delivered/pending counts of the durable ledger.
|
|
7518
7548
|
billingStatusReader: () => readBillingStatus(billingDir)
|
|
@@ -7522,9 +7552,9 @@ function buildDaemon(config, paths) {
|
|
|
7522
7552
|
fetchImpl: (url, init) => (0, import_upstreamFetch7.fetchUpstream)(url, init)
|
|
7523
7553
|
});
|
|
7524
7554
|
setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth2.getSharedAccountHealth)());
|
|
7525
|
-
const auditWriter = new AuditWriter(
|
|
7526
|
-
const auditPruneSweeper = new AuditPruneSweeper(
|
|
7527
|
-
setAuditRuntime(auditWriter, auditPruneSweeper);
|
|
7555
|
+
const auditWriter = new AuditWriter(auditDir2, logger);
|
|
7556
|
+
const auditPruneSweeper = new AuditPruneSweeper(auditDir2, logger, import_audit_types.DEFAULT_AUDIT_CONFIG);
|
|
7557
|
+
setAuditRuntime(auditWriter, auditPruneSweeper, auditDir2);
|
|
7528
7558
|
const billingPublisher = new BillingPublisher(billingDir, logger);
|
|
7529
7559
|
const billingRetrySweeper = new BillingRetrySweeper(
|
|
7530
7560
|
billingDir,
|
|
@@ -7613,9 +7643,9 @@ function buildCliSpawnPlan(opts) {
|
|
|
7613
7643
|
};
|
|
7614
7644
|
}
|
|
7615
7645
|
function resolveInPathDefault(candidate) {
|
|
7616
|
-
const segments = (process.env["PATH"] ?? "").split(
|
|
7646
|
+
const segments = (process.env["PATH"] ?? "").split(import_node_path14.delimiter).filter(Boolean);
|
|
7617
7647
|
for (const seg of segments) {
|
|
7618
|
-
const full = (0,
|
|
7648
|
+
const full = (0, import_node_path14.join)(seg, candidate);
|
|
7619
7649
|
if ((0, import_node_fs21.existsSync)(full)) return full;
|
|
7620
7650
|
}
|
|
7621
7651
|
return null;
|