@omnicross/daemon 0.4.4 → 0.4.6

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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  // src/bootstrap.ts
2
- import { accessSync, constants as fsConstants, existsSync as existsSync30, mkdirSync as mkdirSync9 } from "fs";
2
+ import { accessSync, constants as fsConstants, existsSync as existsSync31, mkdirSync as mkdirSync9 } from "fs";
3
3
  import { dirname as dirname17 } from "path";
4
4
  import { DEFAULT_AUDIT_CONFIG } from "@omnicross/contracts/audit-types";
5
5
  import { DEFAULT_BILLING_CONFIG } from "@omnicross/contracts/billing-types";
@@ -196,14 +196,14 @@ async function runKimiDevicePoll(sessionId, deviceCode, deviceId, fingerprint, s
196
196
  {
197
197
  fingerprint,
198
198
  deadlineMs: DEFAULT_KIMI_OAUTH_TTL_MS,
199
- sleep: (ms) => new Promise((resolve10, reject) => {
199
+ sleep: (ms) => new Promise((resolve11, reject) => {
200
200
  const onAbort = () => {
201
201
  clearTimeout(timer);
202
202
  reject(new Error("login: cancelled"));
203
203
  };
204
204
  const timer = setTimeout(() => {
205
205
  signal.removeEventListener("abort", onAbort);
206
- resolve10();
206
+ resolve11();
207
207
  }, ms);
208
208
  signal.addEventListener("abort", onAbort, { once: true });
209
209
  })
@@ -279,14 +279,14 @@ async function runGrokDevicePoll(sessionId, tokenEndpoint, deviceCode, signal, d
279
279
  fetchImpl,
280
280
  {
281
281
  deadlineMs: DEFAULT_GROK_OAUTH_TTL_MS,
282
- sleep: (ms) => new Promise((resolve10, reject) => {
282
+ sleep: (ms) => new Promise((resolve11, reject) => {
283
283
  const onAbort = () => {
284
284
  clearTimeout(timer);
285
285
  reject(new Error("login: cancelled"));
286
286
  };
287
287
  const timer = setTimeout(() => {
288
288
  signal.removeEventListener("abort", onAbort);
289
- resolve10();
289
+ resolve11();
290
290
  }, ms);
291
291
  signal.addEventListener("abort", onAbort, { once: true });
292
292
  })
@@ -364,14 +364,14 @@ async function runCopilotDevicePoll(sessionId, deviceCode, signal, deps, enterpr
364
364
  {
365
365
  deadlineMs: DEFAULT_COPILOT_OAUTH_TTL_MS,
366
366
  ...enterpriseUrl ? { enterpriseUrl } : {},
367
- sleep: (ms) => new Promise((resolve10, reject) => {
367
+ sleep: (ms) => new Promise((resolve11, reject) => {
368
368
  const onAbort = () => {
369
369
  clearTimeout(timer);
370
370
  reject(new Error("login: cancelled"));
371
371
  };
372
372
  const timer = setTimeout(() => {
373
373
  signal.removeEventListener("abort", onAbort);
374
- resolve10();
374
+ resolve11();
375
375
  }, ms);
376
376
  signal.addEventListener("abort", onAbort, { once: true });
377
377
  })
@@ -2764,19 +2764,19 @@ function resetWebhookRuntimeForTests() {
2764
2764
 
2765
2765
  // src/admin/webhookTestApi.ts
2766
2766
  function readJsonBody(req) {
2767
- return new Promise((resolve10) => {
2767
+ return new Promise((resolve11) => {
2768
2768
  const chunks = [];
2769
2769
  req.on("data", (c) => chunks.push(c));
2770
2770
  req.on("end", () => {
2771
2771
  try {
2772
2772
  const raw = Buffer.concat(chunks).toString("utf8");
2773
2773
  const parsed = raw ? JSON.parse(raw) : {};
2774
- resolve10(parsed && typeof parsed === "object" ? parsed : {});
2774
+ resolve11(parsed && typeof parsed === "object" ? parsed : {});
2775
2775
  } catch {
2776
- resolve10({});
2776
+ resolve11({});
2777
2777
  }
2778
2778
  });
2779
- req.on("error", () => resolve10({}));
2779
+ req.on("error", () => resolve11({}));
2780
2780
  });
2781
2781
  }
2782
2782
  async function handleWebhookTest(req, res) {
@@ -2879,13 +2879,771 @@ async function handleRouteLeaseApi(req, res, path2, deps) {
2879
2879
  }
2880
2880
  }
2881
2881
 
2882
+ // src/admin/codexSessionManager.ts
2883
+ import { homedir } from "os";
2884
+ import { basename, join, resolve, win32 } from "path";
2885
+ import {
2886
+ copyFile,
2887
+ open,
2888
+ readdir,
2889
+ readFile,
2890
+ rename,
2891
+ stat,
2892
+ unlink,
2893
+ writeFile
2894
+ } from "fs/promises";
2895
+ import { existsSync as existsSync2 } from "fs";
2896
+ import { randomUUID as randomUUID2 } from "crypto";
2897
+ import { TextDecoder as TextDecoder2 } from "util";
2898
+ var PROVIDER_PROPERTY_NAMES = /* @__PURE__ */ new Set(["model_provider", "model_provider_id"]);
2899
+ var FIRST_LINE_LIMIT = 4 * 1024 * 1024;
2900
+ var PROVIDER_ID_LIMIT = 256;
2901
+ var CodexSessionManagerError = class extends Error {
2902
+ constructor(message) {
2903
+ super(message);
2904
+ this.name = "CodexSessionManagerError";
2905
+ }
2906
+ };
2907
+ var CodexSessionManager = class {
2908
+ codexHome;
2909
+ stateDatabasePath;
2910
+ mutationTail = Promise.resolve();
2911
+ constructor(options = {}) {
2912
+ const configuredHome = options.codexHome?.trim() || process.env["CODEX_HOME"]?.trim();
2913
+ this.codexHome = configuredHome || join(homedir(), ".codex");
2914
+ this.stateDatabasePath = options.stateDatabasePath?.trim() || join(this.codexHome, "state_5.sqlite");
2915
+ }
2916
+ async list(projectPath) {
2917
+ const project = await validateProjectPath(projectPath);
2918
+ const [files, state] = await Promise.all([
2919
+ scanSessionFiles(join(this.codexHome, "sessions")),
2920
+ readStateThreads(this.stateDatabasePath)
2921
+ ]);
2922
+ return mergeSessionMetadata(project.displayPath, this.codexHome, files, state);
2923
+ }
2924
+ async preview(input) {
2925
+ const normalized2 = normalizeApplyInput(input);
2926
+ const project = await validateProjectPath(normalized2.projectPath);
2927
+ const [files, state] = await Promise.all([
2928
+ scanSessionFiles(join(this.codexHome, "sessions")),
2929
+ readStateThreads(this.stateDatabasePath)
2930
+ ]);
2931
+ const snapshot = mergeSessionMetadata(project.displayPath, this.codexHome, files, state);
2932
+ const plans = await buildProviderPlans(normalized2, snapshot, state.rows);
2933
+ return {
2934
+ projectPath: project.displayPath,
2935
+ fromProvider: normalized2.fromProvider ?? null,
2936
+ toProvider: normalized2.toProvider,
2937
+ stateDatabase: state.status,
2938
+ sessions: plans,
2939
+ warnings: snapshot.warnings
2940
+ };
2941
+ }
2942
+ async apply(input) {
2943
+ return this.withMutationLock(() => this.applyLocked(input));
2944
+ }
2945
+ async applyLocked(input) {
2946
+ const normalized2 = normalizeApplyInput(input);
2947
+ const project = await validateProjectPath(normalized2.projectPath);
2948
+ const [files, state] = await Promise.all([
2949
+ scanSessionFiles(join(this.codexHome, "sessions")),
2950
+ readStateThreads(this.stateDatabasePath)
2951
+ ]);
2952
+ if (!state.status.available) {
2953
+ throw new CodexSessionManagerError(
2954
+ state.status.reason || `Codex state database is unavailable: ${state.status.path}`
2955
+ );
2956
+ }
2957
+ const snapshot = mergeSessionMetadata(project.displayPath, this.codexHome, files, state);
2958
+ const plans = await buildProviderPlans(normalized2, snapshot, state.rows);
2959
+ const selected = plans.filter((plan) => plan.action !== "no_change");
2960
+ const blocked = selected.filter((plan) => plan.action === "blocked");
2961
+ if (blocked.length > 0) {
2962
+ const details = blocked.map((plan) => `${plan.id}: ${plan.reason || "blocked"}`).join("; ");
2963
+ throw new CodexSessionManagerError(`cannot update selected Codex sessions: ${details}`);
2964
+ }
2965
+ if (selected.length === 0) {
2966
+ return {
2967
+ ok: true,
2968
+ projectPath: project.displayPath,
2969
+ fromProvider: normalized2.fromProvider ?? null,
2970
+ toProvider: normalized2.toProvider,
2971
+ updatedSessions: 0,
2972
+ jsonlFiles: 0,
2973
+ jsonlFields: 0,
2974
+ sqliteRows: 0,
2975
+ backups: []
2976
+ };
2977
+ }
2978
+ const fileChanges = [];
2979
+ for (const plan of selected) {
2980
+ const file = files.get(plan.id);
2981
+ if (!file || file.status !== "ready") {
2982
+ throw new CodexSessionManagerError(
2983
+ `rollout for session '${plan.id}' is unavailable; no files were changed`
2984
+ );
2985
+ }
2986
+ const before = await snapshotFile(file.filePath);
2987
+ const inspection = await inspectAndTransformFile(file.filePath, normalized2.fromProvider, normalized2.toProvider);
2988
+ const after = await snapshotFile(file.filePath);
2989
+ if (!sameFileSnapshot(before, after)) {
2990
+ throw new CodexSessionManagerError(
2991
+ `rollout '${file.filePath}' changed while it was being read; no files were changed`
2992
+ );
2993
+ }
2994
+ if (inspection.changedFields > 0) {
2995
+ fileChanges.push({
2996
+ id: plan.id,
2997
+ filePath: file.filePath,
2998
+ before,
2999
+ transformedText: inspection.transformedText,
3000
+ changedFields: inspection.changedFields
3001
+ });
3002
+ }
3003
+ }
3004
+ const stateRowsById = new Map(state.rows.map((row) => [row.id, row]));
3005
+ const dbChanges = plans.filter((plan) => plan.action === "update").map((plan) => stateRowsById.get(plan.id)).filter((row) => {
3006
+ if (!row) return false;
3007
+ if (normalized2.fromProvider && row.modelProvider !== normalized2.fromProvider) return false;
3008
+ return row.modelProvider !== normalized2.toProvider;
3009
+ });
3010
+ const temporaryFiles = [];
3011
+ const backups = [];
3012
+ let database;
3013
+ let committed = false;
3014
+ try {
3015
+ for (const change of fileChanges) {
3016
+ const tempPath = `${change.filePath}.provider-switch-${randomUUID2()}.tmp`;
3017
+ await writeFile(tempPath, change.transformedText, "utf8");
3018
+ temporaryFiles.push(tempPath);
3019
+ }
3020
+ if (dbChanges.length > 0) {
3021
+ const sqlite = await loadSqlite();
3022
+ database = openDatabase(sqlite, this.stateDatabasePath, false);
3023
+ const databaseBackup = await createDatabaseBackup(sqlite, database, this.stateDatabasePath);
3024
+ backups.push(databaseBackup);
3025
+ database.exec("BEGIN IMMEDIATE");
3026
+ assertDatabaseRowsUnchanged(database, dbChanges);
3027
+ }
3028
+ for (let index = 0; index < fileChanges.length; index += 1) {
3029
+ const change = fileChanges[index];
3030
+ const tempPath = temporaryFiles[index];
3031
+ const current = await snapshotFile(change.filePath);
3032
+ if (!sameFileSnapshot(change.before, current)) {
3033
+ throw new CodexSessionManagerError(
3034
+ `rollout '${change.filePath}' changed before replacement; no files were changed`
3035
+ );
3036
+ }
3037
+ const backupPath = await createUniqueBackupPath(change.filePath);
3038
+ await copyFile(change.filePath, backupPath);
3039
+ backups.push(backupPath);
3040
+ await replaceFileAtomically(tempPath, change.filePath);
3041
+ temporaryFiles[index] = "";
3042
+ }
3043
+ if (database && dbChanges.length > 0) {
3044
+ const update = database.prepare("UPDATE threads SET model_provider = ? WHERE id = ?");
3045
+ for (const row of dbChanges) update.run(normalized2.toProvider, row.id);
3046
+ database.exec("COMMIT");
3047
+ committed = true;
3048
+ } else {
3049
+ committed = true;
3050
+ }
3051
+ return {
3052
+ ok: true,
3053
+ projectPath: project.displayPath,
3054
+ fromProvider: normalized2.fromProvider ?? null,
3055
+ toProvider: normalized2.toProvider,
3056
+ updatedSessions: (/* @__PURE__ */ new Set([...fileChanges.map((change) => change.id), ...dbChanges.map((row) => row.id)])).size,
3057
+ jsonlFiles: fileChanges.length,
3058
+ jsonlFields: fileChanges.reduce((total, change) => total + change.changedFields, 0),
3059
+ sqliteRows: dbChanges.length,
3060
+ backups
3061
+ };
3062
+ } catch (error) {
3063
+ if (database?.isTransaction) {
3064
+ try {
3065
+ database.exec("ROLLBACK");
3066
+ } catch {
3067
+ }
3068
+ }
3069
+ if (!committed) {
3070
+ try {
3071
+ await restoreBackups(backups.filter((path2) => /\.jsonl\.provider-switch-[^/\\]+\.bak$/iu.test(path2)));
3072
+ } catch (restoreError) {
3073
+ const original = error instanceof Error ? error.message : String(error);
3074
+ const restoration = restoreError instanceof Error ? restoreError.message : String(restoreError);
3075
+ throw new CodexSessionManagerError(
3076
+ `${original}; JSONL restoration also failed: ${restoration}`
3077
+ );
3078
+ }
3079
+ }
3080
+ throw error;
3081
+ } finally {
3082
+ if (database?.isOpen) database.close();
3083
+ for (const tempPath of temporaryFiles) {
3084
+ if (!tempPath) continue;
3085
+ await unlinkIfPresent(tempPath);
3086
+ }
3087
+ }
3088
+ }
3089
+ async withMutationLock(operation) {
3090
+ const previous = this.mutationTail;
3091
+ let release;
3092
+ this.mutationTail = new Promise((resolve11) => {
3093
+ release = resolve11;
3094
+ });
3095
+ await previous;
3096
+ try {
3097
+ return await operation();
3098
+ } finally {
3099
+ release();
3100
+ }
3101
+ }
3102
+ };
3103
+ function normalizeApplyInput(input) {
3104
+ const projectPath = typeof input.projectPath === "string" ? input.projectPath.trim() : "";
3105
+ const toProvider = typeof input.toProvider === "string" ? input.toProvider.trim() : "";
3106
+ const fromProvider = typeof input.fromProvider === "string" ? input.fromProvider.trim() : void 0;
3107
+ if (!projectPath) throw new CodexSessionManagerError("projectPath must be a non-empty string");
3108
+ validateProviderId(toProvider, "toProvider");
3109
+ if (fromProvider) validateProviderId(fromProvider, "fromProvider");
3110
+ if (!Array.isArray(input.sessionIds) || input.sessionIds.length === 0) {
3111
+ throw new CodexSessionManagerError("sessionIds must contain at least one session id");
3112
+ }
3113
+ const sessionIds = [
3114
+ ...new Set(
3115
+ input.sessionIds.filter((id) => typeof id === "string" && id.trim().length > 0).map((id) => id.trim())
3116
+ )
3117
+ ];
3118
+ if (sessionIds.length === 0) throw new CodexSessionManagerError("sessionIds must contain at least one session id");
3119
+ if (sessionIds.length > 1e4) throw new CodexSessionManagerError("too many sessionIds");
3120
+ return { projectPath, sessionIds, toProvider, ...fromProvider ? { fromProvider } : {} };
3121
+ }
3122
+ function validateProviderId(value, name) {
3123
+ if (!value) throw new CodexSessionManagerError(`${name} must be a non-empty string`);
3124
+ if (value.length > PROVIDER_ID_LIMIT || /[\u0000-\u001f\u007f]/u.test(value)) {
3125
+ throw new CodexSessionManagerError(`${name} is invalid`);
3126
+ }
3127
+ }
3128
+ async function validateProjectPath(projectPath) {
3129
+ if (typeof projectPath !== "string" || !projectPath.trim()) {
3130
+ throw new CodexSessionManagerError("projectPath must be a non-empty string");
3131
+ }
3132
+ const displayPath = resolve(projectPath.trim());
3133
+ let info;
3134
+ try {
3135
+ info = await stat(displayPath);
3136
+ } catch {
3137
+ throw new CodexSessionManagerError(`project path does not exist: ${displayPath}`);
3138
+ }
3139
+ if (!info.isDirectory()) throw new CodexSessionManagerError(`project path is not a directory: ${displayPath}`);
3140
+ return { displayPath };
3141
+ }
3142
+ async function scanSessionFiles(sessionsRoot) {
3143
+ const files = await collectJsonlFiles(sessionsRoot);
3144
+ const records = /* @__PURE__ */ new Map();
3145
+ for (const filePath of files) {
3146
+ let fileStat;
3147
+ try {
3148
+ fileStat = await stat(filePath);
3149
+ const firstLine = await readFirstLine(filePath);
3150
+ const parsed = parseSessionMetadata(firstLine, filePath);
3151
+ if (!parsed.id) continue;
3152
+ const record = {
3153
+ id: parsed.id,
3154
+ filePath,
3155
+ cwd: parsed.cwd,
3156
+ jsonlProvider: parsed.provider,
3157
+ timestamp: parsed.timestamp,
3158
+ size: fileStat.size,
3159
+ mtimeMs: fileStat.mtimeMs,
3160
+ status: "ready"
3161
+ };
3162
+ const existing = records.get(record.id);
3163
+ if (!existing || record.mtimeMs > existing.mtimeMs) records.set(record.id, record);
3164
+ } catch {
3165
+ const id = sessionIdFromRolloutPath(filePath);
3166
+ if (!id) continue;
3167
+ let fallbackStat;
3168
+ try {
3169
+ fallbackStat = await stat(filePath);
3170
+ } catch {
3171
+ continue;
3172
+ }
3173
+ const existing = records.get(id);
3174
+ if (!existing || fallbackStat.mtimeMs > existing.mtimeMs) {
3175
+ records.set(id, {
3176
+ id,
3177
+ filePath,
3178
+ cwd: null,
3179
+ jsonlProvider: null,
3180
+ timestamp: null,
3181
+ size: fallbackStat.size,
3182
+ mtimeMs: fallbackStat.mtimeMs,
3183
+ status: "unreadable_rollout"
3184
+ });
3185
+ }
3186
+ }
3187
+ }
3188
+ return records;
3189
+ }
3190
+ async function collectJsonlFiles(root) {
3191
+ if (!existsSync2(root)) return [];
3192
+ const result = [];
3193
+ const pending = [root];
3194
+ while (pending.length > 0) {
3195
+ const current = pending.pop();
3196
+ let entries;
3197
+ try {
3198
+ entries = await readdir(current, { withFileTypes: true });
3199
+ } catch {
3200
+ continue;
3201
+ }
3202
+ for (const entry of entries) {
3203
+ const fullPath = join(current, entry.name);
3204
+ if (entry.isDirectory()) pending.push(fullPath);
3205
+ else if (entry.isFile() && entry.name.toLowerCase().endsWith(".jsonl")) result.push(fullPath);
3206
+ }
3207
+ }
3208
+ return result.sort((a, b) => a.localeCompare(b));
3209
+ }
3210
+ async function readFirstLine(filePath) {
3211
+ const handle = await open(filePath, "r");
3212
+ const chunks = [];
3213
+ let total = 0;
3214
+ try {
3215
+ while (total < FIRST_LINE_LIMIT) {
3216
+ const chunk = Buffer.allocUnsafe(Math.min(128 * 1024, FIRST_LINE_LIMIT - total));
3217
+ const result = await handle.read(chunk, 0, chunk.length, null);
3218
+ if (result.bytesRead === 0) break;
3219
+ const used = chunk.subarray(0, result.bytesRead);
3220
+ const lineEnd = findLineEnd(used);
3221
+ if (lineEnd >= 0) {
3222
+ chunks.push(used.subarray(0, lineEnd));
3223
+ return decodeUtf8(Buffer.concat(chunks));
3224
+ }
3225
+ chunks.push(used);
3226
+ total += result.bytesRead;
3227
+ }
3228
+ } finally {
3229
+ await handle.close();
3230
+ }
3231
+ if (total > 0 && total < FIRST_LINE_LIMIT) return decodeUtf8(Buffer.concat(chunks));
3232
+ throw new CodexSessionManagerError(`session metadata line is too large or incomplete: ${filePath}`);
3233
+ }
3234
+ function findLineEnd(buffer) {
3235
+ for (let index = 0; index < buffer.length; index += 1) {
3236
+ if (buffer[index] === 10 || buffer[index] === 13) return index;
3237
+ }
3238
+ return -1;
3239
+ }
3240
+ function parseSessionMetadata(line, filePath) {
3241
+ const value = JSON.parse(line.replace(/^\uFEFF/u, ""));
3242
+ if (!isRecord6(value)) throw new Error("metadata is not an object");
3243
+ const payload = isRecord6(value["payload"]) ? value["payload"] : {};
3244
+ const id = sessionIdFromRolloutPath(filePath) || firstString(payload["session_id"], payload["id"]);
3245
+ return {
3246
+ id,
3247
+ cwd: firstString(payload["cwd"]),
3248
+ provider: firstString(payload["model_provider"]),
3249
+ timestamp: firstString(payload["timestamp"]) || firstString(value["timestamp"])
3250
+ };
3251
+ }
3252
+ function sessionIdFromRolloutPath(filePath) {
3253
+ const match = basename(filePath).match(/([0-9a-z]{8}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{4}-[0-9a-z]{12})\.jsonl$/iu);
3254
+ return match?.[1] ?? null;
3255
+ }
3256
+ async function readStateThreads(databasePath) {
3257
+ const unavailable = (reason) => ({
3258
+ status: { path: databasePath, available: false, reason },
3259
+ rows: []
3260
+ });
3261
+ if (!existsSync2(databasePath)) return unavailable(`Codex state database not found: ${databasePath}`);
3262
+ let sqlite;
3263
+ try {
3264
+ sqlite = await loadSqlite();
3265
+ } catch (error) {
3266
+ return unavailable(error instanceof Error ? error.message : String(error));
3267
+ }
3268
+ let database;
3269
+ try {
3270
+ database = openDatabase(sqlite, databasePath, true);
3271
+ const columns = new Set(
3272
+ database.prepare("PRAGMA table_info('threads')").all().map((row) => String(row["name"] ?? ""))
3273
+ );
3274
+ for (const required of ["id", "rollout_path", "cwd", "model_provider"]) {
3275
+ if (!columns.has(required)) return unavailable(`state_5.sqlite is missing threads.${required}`);
3276
+ }
3277
+ const selected = ["id", "rollout_path", "cwd", "model_provider", "model", "created_at", "updated_at", "created_at_ms", "updated_at_ms"].filter((column) => columns.has(column));
3278
+ const rows = database.prepare(`SELECT ${selected.join(", ")} FROM threads`).all();
3279
+ return {
3280
+ status: { path: databasePath, available: true },
3281
+ rows: rows.map(toStateThreadRow)
3282
+ };
3283
+ } catch (error) {
3284
+ return unavailable(`could not read Codex state database: ${error instanceof Error ? error.message : String(error)}`);
3285
+ } finally {
3286
+ if (database?.isOpen) database.close();
3287
+ }
3288
+ }
3289
+ async function loadSqlite() {
3290
+ const specifier = "node:sqlite";
3291
+ try {
3292
+ return await import(specifier);
3293
+ } catch (error) {
3294
+ const cause = error instanceof Error ? error.message : String(error);
3295
+ throw new CodexSessionManagerError(
3296
+ `Codex session SQLite support requires Node.js 22.16 or newer (node:sqlite); this daemon runs ${process.version} (import failed: ${cause})`
3297
+ );
3298
+ }
3299
+ }
3300
+ function openDatabase(sqlite, databasePath, readOnly) {
3301
+ const database = new sqlite.DatabaseSync(databasePath, { readOnly, timeout: 5e3 });
3302
+ database.exec("PRAGMA busy_timeout = 5000");
3303
+ return database;
3304
+ }
3305
+ function toStateThreadRow(row) {
3306
+ return {
3307
+ id: String(row["id"] ?? ""),
3308
+ rolloutPath: String(row["rollout_path"] ?? ""),
3309
+ cwd: String(row["cwd"] ?? ""),
3310
+ modelProvider: String(row["model_provider"] ?? ""),
3311
+ model: row["model"] == null ? null : String(row["model"]),
3312
+ createdAt: timestampFromSqlite(row["created_at_ms"] ?? row["created_at"]),
3313
+ updatedAt: timestampFromSqlite(row["updated_at_ms"] ?? row["updated_at"])
3314
+ };
3315
+ }
3316
+ function timestampFromSqlite(value) {
3317
+ const numeric = typeof value === "bigint" ? Number(value) : typeof value === "number" ? value : Number(value);
3318
+ if (!Number.isFinite(numeric) || numeric <= 0) return null;
3319
+ const milliseconds = numeric < 1e11 ? numeric * 1e3 : numeric;
3320
+ const date = new Date(milliseconds);
3321
+ return Number.isNaN(date.getTime()) ? null : date.toISOString();
3322
+ }
3323
+ function mergeSessionMetadata(projectPath, codexHome, files, state) {
3324
+ const stateRows = new Map(state.rows.map((row) => [row.id, row]));
3325
+ const ids = /* @__PURE__ */ new Set();
3326
+ for (const [id, file] of files) {
3327
+ if (file.cwd && isPathInside(projectPath, file.cwd)) ids.add(id);
3328
+ }
3329
+ for (const row of state.rows) {
3330
+ if (isPathInside(projectPath, row.cwd)) ids.add(row.id);
3331
+ }
3332
+ const sessions2 = [];
3333
+ for (const id of ids) {
3334
+ const file = files.get(id);
3335
+ const row = stateRows.get(id);
3336
+ const cwd = row?.cwd || file?.cwd || projectPath;
3337
+ if (!isPathInside(projectPath, cwd)) continue;
3338
+ const rolloutPath = file?.filePath || row?.rolloutPath || "";
3339
+ const provider = row?.modelProvider || file?.jsonlProvider || null;
3340
+ sessions2.push({
3341
+ id,
3342
+ cwd,
3343
+ rolloutPath,
3344
+ provider,
3345
+ jsonlProvider: file?.jsonlProvider ?? null,
3346
+ model: row?.model ?? null,
3347
+ createdAt: row?.createdAt ?? file?.timestamp ?? null,
3348
+ updatedAt: row?.updatedAt ?? (file ? new Date(file.mtimeMs).toISOString() : null),
3349
+ fileSize: file?.size ?? null,
3350
+ fileModifiedAt: file ? new Date(file.mtimeMs).toISOString() : null,
3351
+ status: file?.status ?? "missing_rollout",
3352
+ inStateDatabase: Boolean(row)
3353
+ });
3354
+ }
3355
+ sessions2.sort((a, b) => (b.updatedAt ?? "").localeCompare(a.updatedAt ?? "") || a.id.localeCompare(b.id));
3356
+ const warnings = [];
3357
+ if (!state.status.available) warnings.push(state.status.reason || "state database unavailable");
3358
+ return { projectPath, codexHome, stateDatabase: state.status, sessions: sessions2, warnings };
3359
+ }
3360
+ async function buildProviderPlans(input, snapshot, stateRows) {
3361
+ const byId = new Map(snapshot.sessions.map((session) => [session.id, session]));
3362
+ const stateById = new Map(stateRows.map((row) => [row.id, row]));
3363
+ const plans = [];
3364
+ for (const id of input.sessionIds) {
3365
+ const session = byId.get(id);
3366
+ const row = stateById.get(id);
3367
+ if (!session) {
3368
+ plans.push({
3369
+ id,
3370
+ provider: null,
3371
+ model: null,
3372
+ rolloutPath: "",
3373
+ status: "blocked",
3374
+ providers: [],
3375
+ matchingFields: 0,
3376
+ changedFields: 0,
3377
+ sqliteWillUpdate: false,
3378
+ action: "blocked",
3379
+ reason: "session is not associated with the requested project"
3380
+ });
3381
+ continue;
3382
+ }
3383
+ if (session.status !== "ready") {
3384
+ plans.push({
3385
+ id,
3386
+ provider: session.provider,
3387
+ model: session.model,
3388
+ rolloutPath: session.rolloutPath,
3389
+ status: session.status,
3390
+ providers: [],
3391
+ matchingFields: 0,
3392
+ changedFields: 0,
3393
+ sqliteWillUpdate: false,
3394
+ action: "blocked",
3395
+ reason: "rollout file is missing or unreadable"
3396
+ });
3397
+ continue;
3398
+ }
3399
+ const inspection = await inspectAndTransformFile(session.rolloutPath, input.fromProvider, input.toProvider);
3400
+ const sqliteWillUpdate = Boolean(
3401
+ row && (!input.fromProvider || row.modelProvider === input.fromProvider) && row.modelProvider !== input.toProvider
3402
+ );
3403
+ const changed = inspection.changedFields > 0 || sqliteWillUpdate;
3404
+ plans.push({
3405
+ id,
3406
+ provider: session.provider,
3407
+ model: session.model,
3408
+ rolloutPath: session.rolloutPath,
3409
+ status: "ready",
3410
+ providers: inspection.providers,
3411
+ matchingFields: inspection.matchingFields,
3412
+ changedFields: inspection.changedFields,
3413
+ sqliteWillUpdate,
3414
+ action: changed ? "update" : "no_change"
3415
+ });
3416
+ }
3417
+ return plans;
3418
+ }
3419
+ async function inspectAndTransformFile(filePath, fromProvider, toProvider) {
3420
+ const bytes = await readFile(filePath);
3421
+ const originalText = decodeUtf8(bytes);
3422
+ const parts = originalText.split(/(\r\n|\n|\r)/u);
3423
+ const providers = /* @__PURE__ */ new Set();
3424
+ let matchingFields = 0;
3425
+ let changedFields = 0;
3426
+ const hasBom = parts[0].startsWith("\uFEFF");
3427
+ for (let index = 0; index < parts.length; index += 2) {
3428
+ const line = parts[index];
3429
+ if (!line.trim()) continue;
3430
+ let value;
3431
+ try {
3432
+ value = JSON.parse(line.replace(index === 0 ? /^\uFEFF/u : /^/u, ""));
3433
+ } catch (error) {
3434
+ throw new CodexSessionManagerError(
3435
+ `invalid JSONL at ${filePath}:${Math.floor(index / 2) + 1}: ${error instanceof Error ? error.message : String(error)}`
3436
+ );
3437
+ }
3438
+ const result = replaceStructuredProviderFields(value, fromProvider, toProvider, providers);
3439
+ matchingFields += result.matchingFields;
3440
+ changedFields += result.changedFields;
3441
+ if (result.changedFields > 0) {
3442
+ parts[index] = `${index === 0 && hasBom ? "\uFEFF" : ""}${JSON.stringify(value)}`;
3443
+ }
3444
+ }
3445
+ return {
3446
+ transformedText: parts.join(""),
3447
+ providers: [...providers].sort(),
3448
+ matchingFields,
3449
+ changedFields
3450
+ };
3451
+ }
3452
+ function replaceStructuredProviderFields(value, fromProvider, toProvider, providers = /* @__PURE__ */ new Set()) {
3453
+ let matchingFields = 0;
3454
+ let changedFields = 0;
3455
+ const visit = (node) => {
3456
+ if (Array.isArray(node)) {
3457
+ for (const child of node) visit(child);
3458
+ return;
3459
+ }
3460
+ if (!isRecord6(node)) return;
3461
+ for (const [key, child] of Object.entries(node)) {
3462
+ if (PROVIDER_PROPERTY_NAMES.has(key) && typeof child === "string") {
3463
+ providers.add(child);
3464
+ if (!fromProvider || child === fromProvider) {
3465
+ matchingFields += 1;
3466
+ if (child !== toProvider) {
3467
+ node[key] = toProvider;
3468
+ changedFields += 1;
3469
+ }
3470
+ }
3471
+ }
3472
+ visit(node[key]);
3473
+ }
3474
+ };
3475
+ visit(value);
3476
+ return { matchingFields, changedFields };
3477
+ }
3478
+ async function snapshotFile(filePath) {
3479
+ const info = await stat(filePath);
3480
+ return { size: info.size, mtimeMs: info.mtimeMs };
3481
+ }
3482
+ function sameFileSnapshot(a, b) {
3483
+ return a.size === b.size && a.mtimeMs === b.mtimeMs;
3484
+ }
3485
+ async function createUniqueBackupPath(filePath) {
3486
+ const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[.:]/gu, "-");
3487
+ let candidate = `${filePath}.provider-switch-${stamp}.bak`;
3488
+ let suffix = 1;
3489
+ while (existsSync2(candidate)) {
3490
+ candidate = `${filePath}.provider-switch-${stamp}-${suffix}.bak`;
3491
+ suffix += 1;
3492
+ }
3493
+ return candidate;
3494
+ }
3495
+ async function createDatabaseBackup(sqlite, database, databasePath) {
3496
+ const backupPath = await createUniqueBackupPath(databasePath);
3497
+ if (typeof sqlite.backup !== "function") {
3498
+ throw new CodexSessionManagerError(
3499
+ "Codex session updates require the node:sqlite backup API (Node.js 22.16 or newer)"
3500
+ );
3501
+ }
3502
+ await sqlite.backup(database, backupPath);
3503
+ return backupPath;
3504
+ }
3505
+ function assertDatabaseRowsUnchanged(database, rows) {
3506
+ const read = database.prepare("SELECT model_provider FROM threads WHERE id = ?");
3507
+ for (const row of rows) {
3508
+ const current = read.get(row.id);
3509
+ if (!current || String(current["model_provider"] ?? "") !== row.modelProvider) {
3510
+ throw new CodexSessionManagerError(
3511
+ `SQLite session '${row.id}' changed while the update was prepared; no files were changed`
3512
+ );
3513
+ }
3514
+ }
3515
+ }
3516
+ async function replaceFileAtomically(tempPath, targetPath) {
3517
+ try {
3518
+ await rename(tempPath, targetPath);
3519
+ } catch (error) {
3520
+ if (process.platform !== "win32") throw error;
3521
+ await copyFile(tempPath, targetPath);
3522
+ await unlinkIfPresent(tempPath);
3523
+ }
3524
+ }
3525
+ async function restoreBackups(backupPaths) {
3526
+ for (const backupPath of backupPaths.reverse()) {
3527
+ if (!existsSync2(backupPath)) continue;
3528
+ const targetPath = backupPath.replace(/\.provider-switch-[^.]+(?:-[0-9]+)?\.bak$/u, "");
3529
+ if (targetPath === backupPath) continue;
3530
+ const tempPath = `${targetPath}.provider-restore-${randomUUID2()}.tmp`;
3531
+ try {
3532
+ await copyFile(backupPath, tempPath);
3533
+ await replaceFileAtomically(tempPath, targetPath);
3534
+ } finally {
3535
+ await unlinkIfPresent(tempPath);
3536
+ }
3537
+ }
3538
+ }
3539
+ async function unlinkIfPresent(filePath) {
3540
+ try {
3541
+ await unlink(filePath);
3542
+ } catch {
3543
+ }
3544
+ }
3545
+ function decodeUtf8(bytes) {
3546
+ try {
3547
+ return new TextDecoder2("utf-8", { fatal: true }).decode(bytes);
3548
+ } catch {
3549
+ throw new CodexSessionManagerError("Codex session contains invalid UTF-8");
3550
+ }
3551
+ }
3552
+ function isRecord6(value) {
3553
+ return value !== null && typeof value === "object" && !Array.isArray(value);
3554
+ }
3555
+ function firstString(...values) {
3556
+ for (const value of values) if (typeof value === "string" && value.trim()) return value;
3557
+ return null;
3558
+ }
3559
+ function normalizeComparablePath(value) {
3560
+ const stripped = value.trim().replace(/^\\\\\?\\/u, "");
3561
+ if (process.platform === "win32") {
3562
+ const normalized2 = win32.normalize(stripped).replace(/[\\/]+$/u, "");
3563
+ return normalized2.toLowerCase();
3564
+ }
3565
+ return stripped.replace(/\/+$/u, "") || "/";
3566
+ }
3567
+ function isPathInside(projectPath, candidatePath) {
3568
+ const project = normalizeComparablePath(projectPath);
3569
+ const candidate = normalizeComparablePath(candidatePath);
3570
+ if (project === candidate) return true;
3571
+ const separator = process.platform === "win32" ? "\\" : "/";
3572
+ return candidate.startsWith(`${project}${separator}`);
3573
+ }
3574
+
3575
+ // src/admin/codexSessionApi.ts
3576
+ async function handleCodexSessionApi(req, res, path2, manager) {
3577
+ if (!manager) return writeJsonError(res, 501, "Codex session management is not available");
3578
+ try {
3579
+ const method = (req.method ?? "GET").toUpperCase();
3580
+ if (path2 === "/admin/api/codex-sessions" && (method === "GET" || method === "HEAD")) {
3581
+ const projectPath = new URL(req.url ?? "/", "http://localhost").searchParams.get("projectPath") ?? "";
3582
+ return writeJson(res, 200, await manager.list(projectPath));
3583
+ }
3584
+ if (path2 === "/admin/api/codex-sessions/preview" && method === "POST") {
3585
+ const body = await readJsonBody2(req);
3586
+ return writeJson(res, 200, await manager.preview(parseApplyInput(body)));
3587
+ }
3588
+ if (path2 === "/admin/api/codex-sessions/apply" && method === "POST") {
3589
+ const body = await readJsonBody2(req);
3590
+ return writeJson(res, 200, await manager.apply(parseApplyInput(body)));
3591
+ }
3592
+ return writeJsonError(res, 404, "unknown Codex session admin route");
3593
+ } catch (error) {
3594
+ const message = error instanceof Error ? error.message : String(error);
3595
+ return writeJsonError(res, error instanceof CodexSessionManagerError ? 400 : 500, message);
3596
+ }
3597
+ }
3598
+ async function readJsonBody2(req) {
3599
+ const chunks = [];
3600
+ for await (const chunk of req) chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk));
3601
+ if (chunks.length === 0) return {};
3602
+ try {
3603
+ const value = JSON.parse(Buffer.concat(chunks).toString("utf8"));
3604
+ return isRecord7(value) ? value : {};
3605
+ } catch {
3606
+ throw new CodexSessionManagerError("request body must be a JSON object");
3607
+ }
3608
+ }
3609
+ function parseApplyInput(body) {
3610
+ const projectPath = body["projectPath"];
3611
+ const sessionIds = body["sessionIds"];
3612
+ const toProvider = body["toProvider"];
3613
+ const fromProvider = body["fromProvider"];
3614
+ if (typeof projectPath !== "string") throw new CodexSessionManagerError("projectPath must be a string");
3615
+ if (!Array.isArray(sessionIds) || !sessionIds.every((value) => typeof value === "string")) {
3616
+ throw new CodexSessionManagerError("sessionIds must be an array of strings");
3617
+ }
3618
+ if (typeof toProvider !== "string") throw new CodexSessionManagerError("toProvider must be a string");
3619
+ if (fromProvider !== void 0 && typeof fromProvider !== "string") {
3620
+ throw new CodexSessionManagerError("fromProvider must be a string when provided");
3621
+ }
3622
+ return {
3623
+ projectPath,
3624
+ sessionIds,
3625
+ toProvider,
3626
+ ...fromProvider === void 0 ? {} : { fromProvider }
3627
+ };
3628
+ }
3629
+ function writeJson(res, status, body) {
3630
+ res.writeHead(status, { "Content-Type": "application/json" });
3631
+ res.end(JSON.stringify(body));
3632
+ }
3633
+ function writeJsonError(res, status, message) {
3634
+ writeJson(res, status, { error: { type: "admin_api_error", message } });
3635
+ }
3636
+ function isRecord7(value) {
3637
+ return Boolean(value && typeof value === "object" && !Array.isArray(value));
3638
+ }
3639
+
2882
3640
  // src/admin/adminApi.ts
2883
3641
  import http from "http";
2884
3642
  import {
2885
3643
  createNamedKey,
2886
3644
  DEFAULT_IMAGES_SERVER_CONFIG,
2887
3645
  DEFAULT_SEARCH_SERVER_CONFIG as DEFAULT_SEARCH_SERVER_CONFIG2,
2888
- effectiveOutboundPermissions as effectiveOutboundPermissions2,
3646
+ effectiveOutboundPermissions as effectiveOutboundPermissions3,
2889
3647
  gatewayBindingToEndpointConfig,
2890
3648
  isKindMappedEndpoint,
2891
3649
  loadServerConfig as loadServerConfig3,
@@ -2903,6 +3661,34 @@ import { getSharedAccountHealth } from "@omnicross/core/pipeline/SubscriptionAcc
2903
3661
  import { fetchUpstream as fetchUpstream10 } from "@omnicross/core/pipeline/upstreamFetch";
2904
3662
  import { mergeExtraHeaders } from "@omnicross/core";
2905
3663
 
3664
+ // src/admin/testEgressIdentity.ts
3665
+ import {
3666
+ getOpenCodeGoUserAgent as getOpenCodeGoUserAgent2,
3667
+ OPENCODE_SESSION_HEADER
3668
+ } from "@omnicross/core/provider-proxy/identity/openCodeGoHeaders";
3669
+ var ADMIN_PROBE_OPENCODE_SESSION = "omnicross-admin-probe";
3670
+ function isOpenCodeUpstream(baseUrl) {
3671
+ if (!baseUrl) return false;
3672
+ try {
3673
+ const host = new URL(baseUrl).hostname.toLowerCase();
3674
+ return host === "opencode.ai" || host.endsWith(".opencode.ai");
3675
+ } catch {
3676
+ return false;
3677
+ }
3678
+ }
3679
+ function hasHeader2(headers, name) {
3680
+ const lower = name.toLowerCase();
3681
+ return Object.keys(headers).some((key) => key.toLowerCase() === lower);
3682
+ }
3683
+ function applyAdminProbeIdentity(headers, row) {
3684
+ if (!hasHeader2(headers, "user-agent")) {
3685
+ headers["user-agent"] = getOpenCodeGoUserAgent2();
3686
+ }
3687
+ if (isOpenCodeUpstream(row.baseUrl) && !hasHeader2(headers, OPENCODE_SESSION_HEADER)) {
3688
+ headers[OPENCODE_SESSION_HEADER] = ADMIN_PROBE_OPENCODE_SESSION;
3689
+ }
3690
+ }
3691
+
2906
3692
  // src/image-generation/imagesConfigValidation.ts
2907
3693
  import { validateImagesServerConfig } from "@omnicross/core/outbound-api";
2908
3694
 
@@ -2910,7 +3696,7 @@ import { validateImagesServerConfig } from "@omnicross/core/outbound-api";
2910
3696
  import { randomBytes } from "crypto";
2911
3697
  import {
2912
3698
  chmodSync,
2913
- existsSync as existsSync2,
3699
+ existsSync as existsSync3,
2914
3700
  lstatSync,
2915
3701
  mkdirSync as mkdirSync2,
2916
3702
  realpathSync,
@@ -2918,20 +3704,20 @@ import {
2918
3704
  statSync as statSync2,
2919
3705
  unlinkSync
2920
3706
  } from "fs";
2921
- import { homedir, tmpdir } from "os";
3707
+ import { homedir as homedir2, tmpdir } from "os";
2922
3708
  import {
2923
- basename,
3709
+ basename as basename2,
2924
3710
  dirname as dirname2,
2925
3711
  isAbsolute,
2926
- join,
3712
+ join as join2,
2927
3713
  parse,
2928
3714
  relative,
2929
- resolve
3715
+ resolve as resolve2
2930
3716
  } from "path";
2931
3717
  var OPAQUE_NAME = /^(?:file|directory)-[a-f0-9]{32}(?:\.(?:bin|json|tmp))?$/u;
2932
3718
  var MOUNT_MANIFEST_NAME = "catalog.v1.json";
2933
3719
  function normalized(path2) {
2934
- const canonical = resolve(path2);
3720
+ const canonical = resolve2(path2);
2935
3721
  return process.platform === "win32" ? canonical.toLowerCase() : canonical;
2936
3722
  }
2937
3723
  function samePath(left, right) {
@@ -2942,26 +3728,26 @@ function isSameOrDescendant(candidate, parent) {
2942
3728
  return rel === "" || !rel.startsWith("..") && !isAbsolute(rel);
2943
3729
  }
2944
3730
  function assertNoSymlinkComponents(target) {
2945
- const absolute = resolve(target);
3731
+ const absolute = resolve2(target);
2946
3732
  const filesystemRoot = parse(absolute).root;
2947
3733
  let cursor = filesystemRoot;
2948
3734
  for (const segment of relative(filesystemRoot, absolute).split(/[\\/]+/u).filter(Boolean)) {
2949
- cursor = join(cursor, segment);
2950
- if (!existsSync2(cursor)) break;
3735
+ cursor = join2(cursor, segment);
3736
+ if (!existsSync3(cursor)) break;
2951
3737
  if (lstatSync(cursor).isSymbolicLink()) {
2952
3738
  throw new TypeError("image storage paths must not traverse a symbolic link");
2953
3739
  }
2954
3740
  }
2955
3741
  }
2956
3742
  function isInsideDetectedWorktree(target) {
2957
- let cursor = resolve(target);
2958
- while (!existsSync2(cursor)) {
3743
+ let cursor = resolve2(target);
3744
+ while (!existsSync3(cursor)) {
2959
3745
  const parent = dirname2(cursor);
2960
3746
  if (parent === cursor) break;
2961
3747
  cursor = parent;
2962
3748
  }
2963
3749
  while (true) {
2964
- if (existsSync2(join(cursor, ".git"))) return true;
3750
+ if (existsSync3(join2(cursor, ".git"))) return true;
2965
3751
  const parent = dirname2(cursor);
2966
3752
  if (parent === cursor) return false;
2967
3753
  cursor = parent;
@@ -2969,15 +3755,15 @@ function isInsideDetectedWorktree(target) {
2969
3755
  }
2970
3756
  function isBroadRoot(target, options) {
2971
3757
  const filesystemRoot = parse(target).root;
2972
- const processDirectory = resolve(options.processDirectory ?? process.cwd());
2973
- const userHome = resolve(options.userHome ?? homedir());
2974
- const temporaryDirectory = resolve(options.temporaryDirectory ?? tmpdir());
3758
+ const processDirectory = resolve2(options.processDirectory ?? process.cwd());
3759
+ const userHome = resolve2(options.userHome ?? homedir2());
3760
+ const temporaryDirectory = resolve2(options.temporaryDirectory ?? tmpdir());
2975
3761
  return samePath(target, filesystemRoot) || samePath(target, userHome) || samePath(target, temporaryDirectory) || isSameOrDescendant(processDirectory, target) || isSameOrDescendant(userHome, target) || isSameOrDescendant(temporaryDirectory, target);
2976
3762
  }
2977
3763
  function validateImageRootCandidate(candidate, options = {}) {
2978
3764
  const label = options.label ?? "image storage root";
2979
3765
  if (!candidate.trim() || !isAbsolute(candidate)) return [`${label} must be an absolute path`];
2980
- const target = resolve(candidate);
3766
+ const target = resolve2(candidate);
2981
3767
  const errors = [];
2982
3768
  if (isBroadRoot(target, options)) errors.push(`${label} is too broad`);
2983
3769
  try {
@@ -3015,22 +3801,22 @@ var DaemonImagePathResolver = class {
3015
3801
  #issued = /* @__PURE__ */ new WeakSet();
3016
3802
  constructor(options) {
3017
3803
  if (!isAbsolute(options.configPath)) throw new TypeError("daemon configPath must be absolute");
3018
- const applicationDataRoot = resolve(dirname2(options.configPath));
3804
+ const applicationDataRoot = resolve2(dirname2(options.configPath));
3019
3805
  const applicationErrors = validateImageRootCandidate(applicationDataRoot, {
3020
3806
  ...options,
3021
3807
  label: "daemon application data root"
3022
3808
  });
3023
3809
  if (applicationErrors.length > 0) throw new TypeError(applicationErrors.join("; "));
3024
- const imagesRoot = join(applicationDataRoot, "images");
3025
- const durableRoot = resolve(options.storageRoot ?? join(imagesRoot, "storage"));
3810
+ const imagesRoot = join2(applicationDataRoot, "images");
3811
+ const durableRoot = resolve2(options.storageRoot ?? join2(imagesRoot, "storage"));
3026
3812
  const durableErrors = validateImageRootCandidate(durableRoot, {
3027
3813
  ...options,
3028
3814
  label: "image durable storage root"
3029
3815
  });
3030
3816
  const reservedRoots = [
3031
- join(imagesRoot, "temporary"),
3032
- join(imagesRoot, "evidence"),
3033
- join(imagesRoot, "mount-catalog")
3817
+ join2(imagesRoot, "temporary"),
3818
+ join2(imagesRoot, "evidence"),
3819
+ join2(imagesRoot, "mount-catalog")
3034
3820
  ];
3035
3821
  if (reservedRoots.some((reserved) => isSameOrDescendant(durableRoot, reserved) || isSameOrDescendant(reserved, durableRoot))) {
3036
3822
  durableErrors.push("image durable storage root must not overlap daemon image control roots");
@@ -3039,13 +3825,13 @@ var DaemonImagePathResolver = class {
3039
3825
  const paths = Object.freeze({
3040
3826
  applicationDataRoot,
3041
3827
  imagesRoot,
3042
- temporaryRoot: join(imagesRoot, "temporary"),
3828
+ temporaryRoot: join2(imagesRoot, "temporary"),
3043
3829
  durableRoot,
3044
- artifactsRoot: join(durableRoot, "artifacts"),
3045
- stateRoot: join(durableRoot, "state"),
3046
- evidenceRoot: join(imagesRoot, "evidence"),
3047
- mountManifestRoot: join(imagesRoot, "mount-catalog"),
3048
- mountManifestPath: join(imagesRoot, "mount-catalog", MOUNT_MANIFEST_NAME)
3830
+ artifactsRoot: join2(durableRoot, "artifacts"),
3831
+ stateRoot: join2(durableRoot, "state"),
3832
+ evidenceRoot: join2(imagesRoot, "evidence"),
3833
+ mountManifestRoot: join2(imagesRoot, "mount-catalog"),
3834
+ mountManifestPath: join2(imagesRoot, "mount-catalog", MOUNT_MANIFEST_NAME)
3049
3835
  });
3050
3836
  const rootEntries = [
3051
3837
  ["temporary", paths.temporaryRoot],
@@ -3077,7 +3863,7 @@ var DaemonImagePathResolver = class {
3077
3863
  /** Revalidate immediately before unlinking a resolver-issued file capability. */
3078
3864
  removeFile(target) {
3079
3865
  const path2 = this.verifyDestructiveTarget(target, ["opaque-file", "mount-manifest"]);
3080
- if (!existsSync2(path2)) return;
3866
+ if (!existsSync3(path2)) return;
3081
3867
  const info = lstatSync(path2);
3082
3868
  if (info.isSymbolicLink() || !info.isFile()) {
3083
3869
  throw new TypeError("refusing to unlink an unverified image file");
@@ -3087,7 +3873,7 @@ var DaemonImagePathResolver = class {
3087
3873
  /** Only empty opaque directories may be removed until the owned-marker layer is composed. */
3088
3874
  removeEmptyDirectory(target) {
3089
3875
  const path2 = this.verifyDestructiveTarget(target, ["opaque-directory"]);
3090
- if (!existsSync2(path2)) return;
3876
+ if (!existsSync3(path2)) return;
3091
3877
  const info = lstatSync(path2);
3092
3878
  if (info.isSymbolicLink() || !info.isDirectory()) {
3093
3879
  throw new TypeError("refusing to remove an unverified image directory");
@@ -3097,7 +3883,7 @@ var DaemonImagePathResolver = class {
3097
3883
  issue(area, name, kind) {
3098
3884
  const handle = Object.freeze({
3099
3885
  area,
3100
- absolutePath: join(this.#roots[area].path, name),
3886
+ absolutePath: join2(this.#roots[area].path, name),
3101
3887
  kind
3102
3888
  });
3103
3889
  this.#issued.add(handle);
@@ -3112,11 +3898,11 @@ var DaemonImagePathResolver = class {
3112
3898
  }
3113
3899
  const root = this.#roots[target.area];
3114
3900
  assertRootIdentity(root);
3115
- const candidate = resolve(target.absolutePath);
3901
+ const candidate = resolve2(target.absolutePath);
3116
3902
  if (!samePath(dirname2(candidate), root.path) || !isSameOrDescendant(candidate, root.path)) {
3117
3903
  throw new TypeError("refusing a destructive operation outside the verified image root");
3118
3904
  }
3119
- const name = basename(candidate);
3905
+ const name = basename2(candidate);
3120
3906
  const validName = target.kind === "mount-manifest" ? name === MOUNT_MANIFEST_NAME : OPAQUE_NAME.test(name);
3121
3907
  if (!validName) throw new TypeError("refusing a caller-derived image filename");
3122
3908
  assertNoSymlinkComponents(candidate);
@@ -3273,13 +4059,13 @@ function decryptValue(envelope, key) {
3273
4059
 
3274
4060
  // src/secrets/masterKey.ts
3275
4061
  import { randomBytes as randomBytes3 } from "crypto";
3276
- import { chmodSync as chmodSync2, existsSync as existsSync3, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
3277
- import { homedir as homedir2 } from "os";
3278
- import { dirname as dirname3, join as join2 } from "path";
4062
+ import { chmodSync as chmodSync2, existsSync as existsSync4, mkdirSync as mkdirSync3, readFileSync as readFileSync2, writeFileSync as writeFileSync2 } from "fs";
4063
+ import { homedir as homedir3 } from "os";
4064
+ import { dirname as dirname3, join as join3 } from "path";
3279
4065
  var MASTER_KEY_ENV = "OMNICROSS_MASTER_KEY";
3280
4066
  var KEY_BYTES2 = 32;
3281
4067
  function defaultMasterKeyPath() {
3282
- return join2(homedir2(), ".omnicross", "master.key");
4068
+ return join3(homedir3(), ".omnicross", "master.key");
3283
4069
  }
3284
4070
  function decodeEnvKey(raw) {
3285
4071
  const trimmed = raw.trim();
@@ -3321,7 +4107,7 @@ function resolveMasterKey(options = {}) {
3321
4107
  return decodeEnvKey(envRaw);
3322
4108
  }
3323
4109
  const keyFilePath = options.keyFilePath ?? defaultMasterKeyPath();
3324
- if (existsSync3(keyFilePath)) {
4110
+ if (existsSync4(keyFilePath)) {
3325
4111
  return readKeyFile(keyFilePath);
3326
4112
  }
3327
4113
  return generateKeyFile(keyFilePath);
@@ -3939,29 +4725,29 @@ function resolveEnvKey(rawKey) {
3939
4725
 
3940
4726
  // src/integrations/IntegrationManager.ts
3941
4727
  import { createHash } from "crypto";
3942
- import { existsSync as existsSync5, readFileSync as readFileSync5, unlinkSync as unlinkSync3 } from "fs";
3943
- import { homedir as homedir3 } from "os";
3944
- import { join as join3, resolve as resolve3 } from "path";
4728
+ import { existsSync as existsSync6, readFileSync as readFileSync5, unlinkSync as unlinkSync3 } from "fs";
4729
+ import { homedir as homedir4 } from "os";
4730
+ import { join as join4, resolve as resolve4 } from "path";
3945
4731
  import {
3946
4732
  createIntegrationKey,
3947
4733
  effectiveOutboundPermissions
3948
4734
  } from "@omnicross/core";
3949
4735
 
3950
4736
  // src/integrations/codexAuthHelper.ts
3951
- import { resolve as resolve2 } from "path";
4737
+ import { resolve as resolve3 } from "path";
3952
4738
  function currentProcessCodexAuthHelper(configPath, masterKeyFilePath) {
3953
4739
  const entrypoint = process.argv[1];
3954
4740
  if (!entrypoint) throw new Error("cannot configure Codex auth helper without a daemon CLI entrypoint");
3955
4741
  return {
3956
4742
  command: process.execPath,
3957
4743
  args: [
3958
- resolve2(entrypoint),
4744
+ resolve3(entrypoint),
3959
4745
  "integrations",
3960
4746
  "token",
3961
4747
  "codex",
3962
4748
  "--config",
3963
- resolve2(configPath),
3964
- ...masterKeyFilePath ? ["--master-key-file", resolve2(masterKeyFilePath)] : []
4749
+ resolve3(configPath),
4750
+ ...masterKeyFilePath ? ["--master-key-file", resolve3(masterKeyFilePath)] : []
3965
4751
  ]
3966
4752
  };
3967
4753
  }
@@ -3969,7 +4755,7 @@ function currentProcessCodexAuthHelper(configPath, masterKeyFilePath) {
3969
4755
  // src/integrations/IntegrationStateStore.ts
3970
4756
  import {
3971
4757
  chmodSync as chmodSync3,
3972
- existsSync as existsSync4,
4758
+ existsSync as existsSync5,
3973
4759
  mkdirSync as mkdirSync4,
3974
4760
  readFileSync as readFileSync4,
3975
4761
  renameSync as renameSync2,
@@ -3986,7 +4772,7 @@ var IntegrationStateStore = class {
3986
4772
  path;
3987
4773
  box;
3988
4774
  load() {
3989
- if (!existsSync4(this.path)) return { ...EMPTY_STATE, clients: {} };
4775
+ if (!existsSync5(this.path)) return { ...EMPTY_STATE, clients: {} };
3990
4776
  let raw;
3991
4777
  try {
3992
4778
  raw = JSON.parse(readFileSync4(this.path, "utf8"));
@@ -4092,7 +4878,7 @@ function atomicWrite(path2, content) {
4092
4878
  }
4093
4879
  throw error;
4094
4880
  } finally {
4095
- if (existsSync4(path2)) {
4881
+ if (existsSync5(path2)) {
4096
4882
  try {
4097
4883
  chmodSync3(path2, 384);
4098
4884
  } catch {
@@ -4277,7 +5063,7 @@ var IntegrationManager = class {
4277
5063
  constructor(options) {
4278
5064
  this.options = options;
4279
5065
  assertLoopbackGatewayUrl(options.gatewayBaseUrl);
4280
- this.homeDir = options.homeDir ?? homedir3();
5066
+ this.homeDir = options.homeDir ?? homedir4();
4281
5067
  this.codexAuthHelper = options.codexAuthHelper ?? currentProcessCodexAuthHelper(options.configPath);
4282
5068
  }
4283
5069
  options;
@@ -4291,7 +5077,7 @@ var IntegrationManager = class {
4291
5077
  async plan(client, configPath = this.defaultConfigPath(client)) {
4292
5078
  const state = this.options.stateStore.load();
4293
5079
  const record = state.clients[client];
4294
- const target = record?.configPath ?? resolve3(configPath);
5080
+ const target = record?.configPath ?? resolve4(configPath);
4295
5081
  const status = await this.statusFor(client, state, await this.options.keyDb.outboundApiKeysList());
4296
5082
  const changes = client === "codex" ? ["model_provider", "model_providers.omnicross", "model_providers.omnicross.auth"] : ["env.ANTHROPIC_BASE_URL", "env.ANTHROPIC_AUTH_TOKEN", "env.ANTHROPIC_API_KEY"];
4297
5083
  if (!record) {
@@ -4307,7 +5093,7 @@ var IntegrationManager = class {
4307
5093
  return { client, configPath: target, action: "repair", canApply: true, changes, warnings };
4308
5094
  }
4309
5095
  async install(client, configPath = this.defaultConfigPath(client)) {
4310
- const target = resolve3(configPath);
5096
+ const target = resolve4(configPath);
4311
5097
  const state = this.options.stateStore.load();
4312
5098
  const previousState = cloneState(state);
4313
5099
  const existingRecord = state.clients[client];
@@ -4514,6 +5300,33 @@ var IntegrationManager = class {
4514
5300
  }
4515
5301
  return details.secret;
4516
5302
  }
5303
+ /**
5304
+ * Resolve ONE access key's plaintext by id — the `--key-id` variant the
5305
+ * command-auth helper serves for key-scoped Codex launches (each terminal
5306
+ * picks its own gateway key, so concurrent sessions can route to different
5307
+ * upstreams through their keys' bindings). Enforces the SAME usability
5308
+ * contract as the client-bound path: existing, enabled, not revoked,
5309
+ * revealable, and holding the codex-required endpoint permissions.
5310
+ */
5311
+ async getKeyToken(keyId) {
5312
+ const rows = await this.options.keyDb.outboundApiKeysList();
5313
+ const row = rows.find((candidate) => candidate.id === keyId);
5314
+ if (!row) {
5315
+ throw new IntegrationConflictError(`access key '${keyId}' does not exist`);
5316
+ }
5317
+ const secret = await this.options.keyDb.outboundApiKeysReveal(keyId);
5318
+ if (!row.enabled || row.revokedAt !== null || !secret) {
5319
+ throw new IntegrationConflictError(
5320
+ `access key '${keyId}' is disabled, revoked, or not revealable`
5321
+ );
5322
+ }
5323
+ if (!hasRequiredPermissions(row, "codex")) {
5324
+ throw new IntegrationConflictError(
5325
+ `access key '${keyId}' lacks the responses+images endpoint permissions Codex requires`
5326
+ );
5327
+ }
5328
+ return secret;
5329
+ }
4517
5330
  /** Compatibility alias for callers predating per-client bindings. */
4518
5331
  async getGatewayToken(client = "codex") {
4519
5332
  return this.getIntegrationToken(client);
@@ -4654,7 +5467,7 @@ var IntegrationManager = class {
4654
5467
  }
4655
5468
  }
4656
5469
  defaultConfigPath(client) {
4657
- return client === "codex" ? join3(this.homeDir, ".codex", "config.toml") : join3(this.homeDir, ".claude", "settings.json");
5470
+ return client === "codex" ? join4(this.homeDir, ".codex", "config.toml") : join4(this.homeDir, ".claude", "settings.json");
4658
5471
  }
4659
5472
  renderInstalled(client, base, secret) {
4660
5473
  if (client === "claude") {
@@ -4697,7 +5510,7 @@ function cloneState(state) {
4697
5510
  };
4698
5511
  }
4699
5512
  function readOptional(path2) {
4700
- return existsSync5(path2) ? readFileSync5(path2, "utf8") : null;
5513
+ return existsSync6(path2) ? readFileSync5(path2, "utf8") : null;
4701
5514
  }
4702
5515
  function sha256(value) {
4703
5516
  return createHash("sha256").update(value, "utf8").digest("hex");
@@ -4757,7 +5570,7 @@ function writeOptional(path2, content) {
4757
5570
  atomicWrite(path2, content);
4758
5571
  return;
4759
5572
  }
4760
- if (existsSync5(path2)) unlinkSync3(path2);
5573
+ if (existsSync6(path2)) unlinkSync3(path2);
4761
5574
  }
4762
5575
  async function bestEffortRevoke(db, keyId) {
4763
5576
  try {
@@ -5074,7 +5887,7 @@ import { SUBSCRIPTION_MODEL_CATALOG } from "@omnicross/contracts/subscription-mo
5074
5887
  import { ANTIGRAVITY_CODE_ASSIST_ENDPOINT as ANTIGRAVITY_CODE_ASSIST_ENDPOINT2 } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
5075
5888
  import { fetchUpstream as fetchUpstream9 } from "@omnicross/core/pipeline/upstreamFetch";
5076
5889
  import { getAntigravityUserAgent as getAntigravityUserAgent2 } from "@omnicross/core/transformer/transformers/antigravityIdentity";
5077
- function isRecord6(value) {
5890
+ function isRecord8(value) {
5078
5891
  return !!value && typeof value === "object" && !Array.isArray(value);
5079
5892
  }
5080
5893
  function optionalString(value) {
@@ -5087,13 +5900,13 @@ function optionalBoolean(value) {
5087
5900
  return typeof value === "boolean" ? value : void 0;
5088
5901
  }
5089
5902
  function parseAntigravityAvailableModels(payload) {
5090
- if (!isRecord6(payload)) return [];
5903
+ if (!isRecord8(payload)) return [];
5091
5904
  const models = payload["models"];
5092
- if (!isRecord6(models)) return [];
5905
+ if (!isRecord8(models)) return [];
5093
5906
  const out = [];
5094
5907
  for (const [id, raw] of Object.entries(models)) {
5095
5908
  if (ANTIGRAVITY_DISCOVERY_DENYLIST.has(id)) continue;
5096
- if (!isRecord6(raw)) continue;
5909
+ if (!isRecord8(raw)) continue;
5097
5910
  if (raw["isInternal"] === true) continue;
5098
5911
  out.push({
5099
5912
  id,
@@ -5154,7 +5967,7 @@ async function fetchAntigravityAvailableModels(accessToken, fetchImpl = (url, in
5154
5967
  }
5155
5968
  if (!response.ok) return null;
5156
5969
  const payload = await response.json().catch(() => null);
5157
- if (!isRecord6(payload) || !isRecord6(payload["models"])) return null;
5970
+ if (!isRecord8(payload) || !isRecord8(payload["models"])) return null;
5158
5971
  return parseAntigravityAvailableModels(payload);
5159
5972
  }
5160
5973
  async function handleAntigravityModelsRoute(deps) {
@@ -5510,21 +6323,26 @@ async function exchangeGemini(code, codeVerifier, exchangeFetch) {
5510
6323
 
5511
6324
  // src/admin/cliLaunch.ts
5512
6325
  import { exec, spawn } from "child_process";
5513
- import { randomUUID as randomUUID2 } from "crypto";
5514
- import { chmodSync as chmodSync4, existsSync as existsSync6, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
6326
+ import { randomUUID as randomUUID3 } from "crypto";
6327
+ import { chmodSync as chmodSync4, existsSync as existsSync7, mkdtempSync, rmSync as rmSync2, writeFileSync as writeFileSync5 } from "fs";
5515
6328
  import { createServer } from "net";
5516
6329
  import { tmpdir as tmpdir2 } from "os";
5517
- import { delimiter, join as join4 } from "path";
6330
+ import { delimiter, join as join5 } from "path";
5518
6331
  import {
5519
6332
  buildChatCliLaunchConfig,
5520
6333
  buildClaudeCliLaunchConfig,
5521
6334
  buildCodexLaunchConfig,
5522
- buildGeminiCliLaunchConfig
6335
+ buildGeminiCliLaunchConfig,
6336
+ CODEX_PROXY_PROVIDER_NAME
5523
6337
  } from "@omnicross/cli-launcher";
5524
6338
  import {
5525
6339
  ROUTE_LEASE_REQUEST_SCHEMA,
5526
6340
  RouteLeaseError as RouteLeaseError2
5527
6341
  } from "@omnicross/core/provider-proxy";
6342
+ import {
6343
+ candidateGatewayBindings,
6344
+ effectiveOutboundPermissions as effectiveOutboundPermissions2
6345
+ } from "@omnicross/core/outbound-api";
5528
6346
 
5529
6347
  // src/routeLeaseRenewal.ts
5530
6348
  var TERMINAL_LEASE_TTL_SECONDS = 600;
@@ -5571,8 +6389,8 @@ function isLaunchCliId(id) {
5571
6389
  function probeDefault(candidate) {
5572
6390
  const segments = (process.env["PATH"] ?? "").split(delimiter).filter(Boolean);
5573
6391
  for (const seg of segments) {
5574
- const full = join4(seg, candidate);
5575
- if (existsSync6(full)) return full;
6392
+ const full = join5(seg, candidate);
6393
+ if (existsSync7(full)) return full;
5576
6394
  }
5577
6395
  return null;
5578
6396
  }
@@ -5605,6 +6423,75 @@ function resolveLaunchTarget(providers, requested) {
5605
6423
  function firstModel(p) {
5606
6424
  return p.models?.[0] ?? p.modelConfigs?.[0]?.id;
5607
6425
  }
6426
+ var CMD_METACHAR_RE = /[&|<>^%]/;
6427
+ var KEY_SCOPED_CODEX_PERMISSIONS = ["responses", "images"];
6428
+ function buildKeyScopedCodexArgs(input) {
6429
+ let root = input.gatewayBaseUrl;
6430
+ while (root.endsWith("/")) root = root.slice(0, -1);
6431
+ const name = CODEX_PROXY_PROVIDER_NAME;
6432
+ const helperArgs = [...input.authHelper.args, "--key-id", input.keyId];
6433
+ return [
6434
+ "-c",
6435
+ `model_provider="${name}"`,
6436
+ "-c",
6437
+ `model_providers.${name}.name="OmniCross Local Gateway"`,
6438
+ "-c",
6439
+ `model_providers.${name}.base_url="${root}/v1"`,
6440
+ "-c",
6441
+ `model_providers.${name}.wire_api="responses"`,
6442
+ "-c",
6443
+ `model_providers.${name}.supports_websockets=false`,
6444
+ "-c",
6445
+ `model_providers.${name}.http_headers={"X-OpenAI-Actor-Authorization"="omnicross"}`,
6446
+ "-c",
6447
+ `model_providers.${name}.auth.command=${JSON.stringify(input.authHelper.command)}`,
6448
+ "-c",
6449
+ `model_providers.${name}.auth.args=${JSON.stringify(helperArgs)}`,
6450
+ "-c",
6451
+ `model_providers.${name}.auth.refresh_interval_ms=0`,
6452
+ "-c",
6453
+ `model_providers.${name}.auth.timeout_ms=5000`,
6454
+ "-c",
6455
+ "disable_response_storage=true"
6456
+ ];
6457
+ }
6458
+ async function preflightKeyScopedLaunch(deps, keyId) {
6459
+ if (!deps.gatewayRunning) {
6460
+ return {
6461
+ ok: false,
6462
+ status: 409,
6463
+ message: "the outbound gateway is not running \u2014 key-scoped launches route through it"
6464
+ };
6465
+ }
6466
+ const rows = await deps.keyDb.outboundApiKeysList();
6467
+ const row = rows.find((candidate) => candidate.id === keyId);
6468
+ if (!row) return { ok: false, status: 404, message: `access key '${keyId}' does not exist` };
6469
+ if (!row.enabled || row.revokedAt !== null) {
6470
+ return { ok: false, status: 400, message: `access key '${row.name}' is disabled or revoked` };
6471
+ }
6472
+ const secret = await deps.keyDb.outboundApiKeysReveal(keyId);
6473
+ if (!secret) {
6474
+ return { ok: false, status: 400, message: `access key '${row.name}' is not revealable` };
6475
+ }
6476
+ const allowed = effectiveOutboundPermissions2(row.allowedEndpoints);
6477
+ for (const permission of KEY_SCOPED_CODEX_PERMISSIONS) {
6478
+ if (!allowed.includes(permission)) {
6479
+ return {
6480
+ ok: false,
6481
+ status: 400,
6482
+ message: `access key '${row.name}' lacks the '${permission}' endpoint permission Codex requires`
6483
+ };
6484
+ }
6485
+ }
6486
+ if (candidateGatewayBindings(deps.bindings, keyId, "responses").length === 0) {
6487
+ return {
6488
+ ok: false,
6489
+ status: 400,
6490
+ message: `access key '${row.name}' has no enabled responses route \u2014 bind it to a downstream route on the API Service page first`
6491
+ };
6492
+ }
6493
+ return { ok: true, keyName: row.name };
6494
+ }
5608
6495
  async function buildLaunchEnv(cli, llmConfig, target) {
5609
6496
  const common = {
5610
6497
  llmConfig,
@@ -5676,10 +6563,10 @@ function openTerminal({ cli, command, extraArgs, env, cwd, platform, onFailure }
5676
6563
  const runLine = [command, ...extraArgs].map(shq).join(" ");
5677
6564
  const script = `${cwd ? `cd ${shq(cwd)}; ` : ""}${runLine}`;
5678
6565
  if (platform === "darwin") {
5679
- const launchDir = mkdtempSync(join4(tmpdir2(), "omnicross-terminal-"));
5680
- const commandFile = join4(launchDir, "launch.command");
5681
- const bootstrapFile = join4(launchDir, "bootstrap.cjs");
5682
- const socketPath = macIpc.socketPath ?? join4(launchDir, "descriptor.sock");
6566
+ const launchDir = mkdtempSync(join5(tmpdir2(), "omnicross-terminal-"));
6567
+ const commandFile = join5(launchDir, "launch.command");
6568
+ const bootstrapFile = join5(launchDir, "bootstrap.cjs");
6569
+ const socketPath = macIpc.socketPath ?? join5(launchDir, "descriptor.sock");
5683
6570
  const openerEnv = { ...process.env };
5684
6571
  for (const key of Object.keys(env)) delete openerEnv[key];
5685
6572
  let claimed = false;
@@ -5808,10 +6695,10 @@ function resetCliSessions() {
5808
6695
  function errBody(message) {
5809
6696
  return { error: { type: "admin_api_error", message } };
5810
6697
  }
5811
- var defaultCommandRunner = (command) => new Promise((resolve10) => {
6698
+ var defaultCommandRunner = (command) => new Promise((resolve11) => {
5812
6699
  exec(command, { timeout: 18e4 }, (err9, _stdout, stderr) => {
5813
- if (err9) resolve10({ ok: false, error: stderr.trim() || err9.message });
5814
- else resolve10({ ok: true });
6700
+ if (err9) resolve11({ ok: false, error: stderr.trim() || err9.message });
6701
+ else resolve11({ ok: true });
5815
6702
  });
5816
6703
  });
5817
6704
  async function handleCliInstall(cli, runner = defaultCommandRunner) {
@@ -5850,44 +6737,84 @@ async function handleCliLaunch(cli, body, ctx) {
5850
6737
  if (!isCliInstalled(meta.command, platform, probe)) {
5851
6738
  return { status: 400, body: errBody(`"${meta.command}" is not installed (not found on PATH)`) };
5852
6739
  }
6740
+ const keyId = typeof body["keyId"] === "string" && body["keyId"].trim() ? body["keyId"].trim() : void 0;
5853
6741
  let target;
5854
- try {
5855
- target = resolveLaunchTarget(ctx.providers, {
5856
- providerId: typeof body["providerId"] === "string" ? body["providerId"] : void 0,
5857
- model: typeof body["model"] === "string" ? body["model"] : void 0
5858
- });
5859
- } catch (err9) {
5860
- return { status: 400, body: errBody(err9 instanceof Error ? err9.message : "no launch target") };
5861
- }
5862
- const id = randomUUID2();
6742
+ let keyLaunch;
6743
+ const id = randomUUID3();
5863
6744
  let leaseId2;
5864
6745
  let launch;
5865
- try {
5866
- if ((cli === "claude" || cli === "codex") && ctx.routeLeaseManager) {
5867
- const outcome = await ctx.routeLeaseManager.createFromRequest({
5868
- schemaVersion: ROUTE_LEASE_REQUEST_SCHEMA,
5869
- consumer: "omnicross-terminal",
5870
- runtime: cli,
5871
- upstream: { kind: "provider", providerId: target.providerId },
5872
- model: target.model,
5873
- execution: { sessionId: id }
5874
- }, `omnicross-terminal:${id}`);
5875
- leaseId2 = outcome.result.leaseId;
5876
- const stopRenewal = startTerminalLeaseRenewal(ctx.routeLeaseManager, leaseId2);
5877
- launch = {
5878
- env: outcome.result.launch.env,
5879
- extraArgs: outcome.result.launch.extraArgs,
5880
- onSessionEnd: () => {
5881
- stopRenewal();
5882
- ctx.routeLeaseManager?.release(outcome.result.leaseId);
5883
- }
5884
- };
5885
- } else {
5886
- launch = await buildLaunchEnv(cli, ctx.llmConfig, target);
6746
+ if (keyId) {
6747
+ if (cli !== "codex") {
6748
+ return { status: 400, body: errBody("key-scoped launch is only supported for codex") };
6749
+ }
6750
+ const deps = ctx.keyScoped;
6751
+ if (!deps) {
6752
+ return { status: 501, body: errBody("key-scoped launch is not available in this build") };
6753
+ }
6754
+ const preflight = await preflightKeyScopedLaunch(deps, keyId);
6755
+ if (!preflight.ok) return { status: preflight.status, body: errBody(preflight.message) };
6756
+ if (platform === "win32") {
6757
+ const unsafe = [deps.codexAuthHelper.command, ...deps.codexAuthHelper.args].filter((value) => CMD_METACHAR_RE.test(value));
6758
+ if (unsafe.length > 0) {
6759
+ return {
6760
+ status: 400,
6761
+ body: errBody(
6762
+ "the Codex auth-helper path contains cmd.exe metacharacters and cannot be passed through a Windows terminal launch"
6763
+ )
6764
+ };
6765
+ }
6766
+ }
6767
+ keyLaunch = { keyId, keyName: preflight.keyName };
6768
+ launch = {
6769
+ env: {},
6770
+ extraArgs: buildKeyScopedCodexArgs({
6771
+ gatewayBaseUrl: deps.gatewayBaseUrl,
6772
+ authHelper: deps.codexAuthHelper,
6773
+ keyId
6774
+ }),
6775
+ // No route or lease exists to release — the gateway key outlives the
6776
+ // terminal and its bindings route every request.
6777
+ onSessionEnd: () => {
6778
+ }
6779
+ };
6780
+ } else {
6781
+ let resolved;
6782
+ try {
6783
+ resolved = resolveLaunchTarget(ctx.providers, {
6784
+ providerId: typeof body["providerId"] === "string" ? body["providerId"] : void 0,
6785
+ model: typeof body["model"] === "string" ? body["model"] : void 0
6786
+ });
6787
+ } catch (err9) {
6788
+ return { status: 400, body: errBody(err9 instanceof Error ? err9.message : "no launch target") };
6789
+ }
6790
+ target = resolved;
6791
+ try {
6792
+ if ((cli === "claude" || cli === "codex") && ctx.routeLeaseManager) {
6793
+ const outcome = await ctx.routeLeaseManager.createFromRequest({
6794
+ schemaVersion: ROUTE_LEASE_REQUEST_SCHEMA,
6795
+ consumer: "omnicross-terminal",
6796
+ runtime: cli,
6797
+ upstream: { kind: "provider", providerId: resolved.providerId },
6798
+ model: resolved.model,
6799
+ execution: { sessionId: id }
6800
+ }, `omnicross-terminal:${id}`);
6801
+ leaseId2 = outcome.result.leaseId;
6802
+ const stopRenewal = startTerminalLeaseRenewal(ctx.routeLeaseManager, leaseId2);
6803
+ launch = {
6804
+ env: outcome.result.launch.env,
6805
+ extraArgs: outcome.result.launch.extraArgs,
6806
+ onSessionEnd: () => {
6807
+ stopRenewal();
6808
+ ctx.routeLeaseManager?.release(outcome.result.leaseId);
6809
+ }
6810
+ };
6811
+ } else {
6812
+ launch = await buildLaunchEnv(cli, ctx.llmConfig, resolved);
6813
+ }
6814
+ } catch (err9) {
6815
+ const status = err9 instanceof RouteLeaseError2 ? err9.status : 400;
6816
+ return { status, body: errBody(err9 instanceof Error ? err9.message : "failed to build launch env") };
5887
6817
  }
5888
- } catch (err9) {
5889
- const status = err9 instanceof RouteLeaseError2 ? err9.status : 400;
5890
- return { status, body: errBody(err9 instanceof Error ? err9.message : "failed to build launch env") };
5891
6818
  }
5892
6819
  const cwd = typeof body["cwd"] === "string" && body["cwd"].trim() ? body["cwd"].trim() : void 0;
5893
6820
  const opener = ctx.opener ?? defaultTerminalOpener;
@@ -5926,15 +6853,19 @@ async function handleCliLaunch(cli, body, ctx) {
5926
6853
  sessions.set(id, {
5927
6854
  id,
5928
6855
  cli,
5929
- providerId: target.providerId,
5930
- model: target.model,
6856
+ providerId: target?.providerId ?? "",
6857
+ model: target?.model ?? "",
6858
+ ...keyLaunch ? { keyId: keyLaunch.keyId, keyName: keyLaunch.keyName } : {},
5931
6859
  ...leaseId2 ? { leaseId: leaseId2 } : {},
5932
6860
  startedAt: (/* @__PURE__ */ new Date()).toISOString(),
5933
6861
  onSessionEnd
5934
6862
  });
5935
6863
  published = true;
5936
6864
  if (ended) sessions.delete(id);
5937
- return { status: 200, body: { sessionId: id, providerId: target.providerId, model: target.model } };
6865
+ return {
6866
+ status: 200,
6867
+ body: keyLaunch ? { sessionId: id, keyId: keyLaunch.keyId, keyName: keyLaunch.keyName } : { sessionId: id, providerId: target?.providerId, model: target?.model }
6868
+ };
5938
6869
  }
5939
6870
 
5940
6871
  // src/admin/auditConfigBody.ts
@@ -6254,17 +7185,17 @@ function sanitizeResultField(value, cap) {
6254
7185
  const text = typeof value === "string" ? value : value === null || value === void 0 ? "" : String(value);
6255
7186
  return text.replace(/[\u0000-\u001f\u007f]/gu, "").slice(0, cap);
6256
7187
  }
6257
- function writeJson(res, status, body) {
7188
+ function writeJson2(res, status, body) {
6258
7189
  res.writeHead(status, { "Content-Type": "application/json" });
6259
7190
  res.end(JSON.stringify(body));
6260
7191
  }
6261
7192
  function writeErr(res, status, message) {
6262
- writeJson(res, status, { error: { type: "admin_api_error", message } });
7193
+ writeJson2(res, status, { error: { type: "admin_api_error", message } });
6263
7194
  }
6264
7195
  var SEARCH_MAX_BODY_BYTES = 64 * 1024;
6265
7196
  var SearchBodyTooLargeError = class extends Error {
6266
7197
  };
6267
- async function readJsonBody2(req) {
7198
+ async function readJsonBody3(req) {
6268
7199
  const chunks = [];
6269
7200
  let bytes = 0;
6270
7201
  for await (const chunk of req) {
@@ -6284,7 +7215,7 @@ async function readJsonBody2(req) {
6284
7215
  }
6285
7216
  async function readBodyOrReject(req, res) {
6286
7217
  try {
6287
- return await readJsonBody2(req);
7218
+ return await readJsonBody3(req);
6288
7219
  } catch (error) {
6289
7220
  if (error instanceof SearchBodyTooLargeError) {
6290
7221
  writeErr(res, 400, error.message);
@@ -6342,7 +7273,7 @@ async function handleSearchDiagnostics(res, deps) {
6342
7273
  },
6343
7274
  applySemantics: { codex: "immediate", rest: "restart" }
6344
7275
  };
6345
- return writeJson(res, 200, { diagnostics: snapshot });
7276
+ return writeJson2(res, 200, { diagnostics: snapshot });
6346
7277
  }
6347
7278
  function persistedSearchContributions(search, fetchImpl) {
6348
7279
  if (fetchImpl) {
@@ -6388,11 +7319,11 @@ async function handleSearchTest(req, res, deps) {
6388
7319
  checkedAt
6389
7320
  );
6390
7321
  const response = { diagnostic, resultCount: results.length };
6391
- return writeJson(res, 200, { result: response });
7322
+ return writeJson2(res, 200, { result: response });
6392
7323
  } catch (error) {
6393
7324
  const diagnostic = classifyLiveSearchOutcome(contribution.id, { kind: "failure", error }, checkedAt);
6394
7325
  const response = { diagnostic };
6395
- return writeJson(res, 200, { result: response });
7326
+ return writeJson2(res, 200, { result: response });
6396
7327
  }
6397
7328
  }
6398
7329
  async function handleSearchQuery(req, res, deps) {
@@ -6455,18 +7386,18 @@ async function handleSearchQuery(req, res, deps) {
6455
7386
  resultCount: sanitized.length,
6456
7387
  results: sanitized
6457
7388
  };
6458
- return writeJson(res, 200, { result: response });
7389
+ return writeJson2(res, 200, { result: response });
6459
7390
  } catch (error) {
6460
7391
  const diagnostic = classifyLiveSearchOutcome(providerId, { kind: "failure", error }, checkedAt);
6461
7392
  const response = { diagnostic };
6462
- return writeJson(res, 200, { result: response });
7393
+ return writeJson2(res, 200, { result: response });
6463
7394
  }
6464
7395
  }
6465
7396
 
6466
7397
  // src/admin/searchAdminView.ts
6467
7398
  var API_KEY_PROVIDERS = /* @__PURE__ */ new Set(["tavily", "jina", "zhipu", "z.ai"]);
6468
7399
  var BASIC_AUTH_PROVIDERS = /* @__PURE__ */ new Set(["searxng"]);
6469
- function isRecord7(value) {
7400
+ function isRecord9(value) {
6470
7401
  return value !== null && typeof value === "object" && !Array.isArray(value);
6471
7402
  }
6472
7403
  function redactSearchServerConfig(search) {
@@ -6516,13 +7447,13 @@ function resolveSecretField(entry, field, stored) {
6516
7447
  else delete entry[field];
6517
7448
  }
6518
7449
  function preserveSearchSecrets(incoming, current) {
6519
- if (!isRecord7(incoming)) return incoming;
7450
+ if (!isRecord9(incoming)) return incoming;
6520
7451
  const section = { ...incoming };
6521
7452
  const providersValue = section["providers"];
6522
- if (!isRecord7(providersValue)) return section;
7453
+ if (!isRecord9(providersValue)) return section;
6523
7454
  const providers = {};
6524
7455
  for (const [id, entryValue] of Object.entries(providersValue)) {
6525
- if (!isRecord7(entryValue)) {
7456
+ if (!isRecord9(entryValue)) {
6526
7457
  providers[id] = entryValue;
6527
7458
  continue;
6528
7459
  }
@@ -6600,7 +7531,8 @@ function parseKeyPolicyBody(body) {
6600
7531
  var ENDPOINTS = /* @__PURE__ */ new Set(["chat", "responses", "messages", "gemini"]);
6601
7532
  var TARGET_KINDS = /* @__PURE__ */ new Set(["account", "account-group", "account-pool", "provider"]);
6602
7533
  var FALLBACKS = /* @__PURE__ */ new Set(["next", "fail", "global"]);
6603
- function isRecord8(value) {
7534
+ var EFFORT_MAX_LENGTH = 32;
7535
+ function isRecord10(value) {
6604
7536
  return !!value && typeof value === "object" && !Array.isArray(value);
6605
7537
  }
6606
7538
  function nonBlank(value) {
@@ -6620,7 +7552,7 @@ function validateGatewayBindingsSegment(patch) {
6620
7552
  const ids = /* @__PURE__ */ new Set();
6621
7553
  raw.forEach((entry, index) => {
6622
7554
  const path2 = `bindings[${index}]`;
6623
- if (!isRecord8(entry)) {
7555
+ if (!isRecord10(entry)) {
6624
7556
  errors.push(`${path2} must be an object`);
6625
7557
  return;
6626
7558
  }
@@ -6649,12 +7581,18 @@ function validateGatewayBindingsSegment(patch) {
6649
7581
  } else if (entry.modelMappings.length > 100) {
6650
7582
  errors.push(`${path2}.modelMappings cannot contain more than 100 entries`);
6651
7583
  } else if (entry.modelMappings.some(
6652
- (mapping) => !isRecord8(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
7584
+ (mapping) => !isRecord10(mapping) || !nonBlank(mapping.source) || !nonBlank(mapping.target)
6653
7585
  )) {
6654
7586
  errors.push(`${path2}.modelMappings must contain non-empty source and target strings`);
7587
+ } else if (entry.modelMappings.some(
7588
+ (mapping) => mapping.effort !== void 0 && (typeof mapping.effort !== "string" || mapping.effort.trim() === "" || mapping.effort.trim().length > EFFORT_MAX_LENGTH)
7589
+ )) {
7590
+ errors.push(
7591
+ `${path2}.modelMappings effort must be a non-empty string of at most ${EFFORT_MAX_LENGTH} characters`
7592
+ );
6655
7593
  }
6656
7594
  }
6657
- if (!isRecord8(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
7595
+ if (!isRecord10(entry.target) || !TARGET_KINDS.has(String(entry.target.kind))) {
6658
7596
  errors.push(`${path2}.target is invalid`);
6659
7597
  } else {
6660
7598
  if (!nonBlank(entry.target.providerId)) errors.push(`${path2}.target.providerId is required`);
@@ -6669,7 +7607,7 @@ function validateGatewayBindingsSegment(patch) {
6669
7607
  }
6670
7608
  }
6671
7609
  if (entry.modelMap !== void 0) {
6672
- if (!isRecord8(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
7610
+ if (!isRecord10(entry.modelMap) || Object.values(entry.modelMap).some((value) => typeof value !== "string")) {
6673
7611
  errors.push(`${path2}.modelMap must contain string values`);
6674
7612
  }
6675
7613
  }
@@ -6695,23 +7633,23 @@ import {
6695
7633
  toVoucherInfo,
6696
7634
  voucherCodePrefix
6697
7635
  } from "@omnicross/core/outbound-api";
6698
- function writeJson2(res, status, body) {
7636
+ function writeJson3(res, status, body) {
6699
7637
  res.writeHead(status, { "Content-Type": "application/json" });
6700
7638
  res.end(JSON.stringify(body));
6701
7639
  }
6702
7640
  function writeErr2(res, status, message) {
6703
- writeJson2(res, status, { error: { type: "voucher_error", message } });
7641
+ writeJson3(res, status, { error: { type: "voucher_error", message } });
6704
7642
  }
6705
- function readJsonBody3(req) {
6706
- return new Promise((resolve10, reject) => {
7643
+ function readJsonBody4(req) {
7644
+ return new Promise((resolve11, reject) => {
6707
7645
  const chunks = [];
6708
7646
  req.on("data", (c) => chunks.push(c));
6709
7647
  req.on("end", () => {
6710
7648
  const raw = Buffer.concat(chunks).toString("utf8");
6711
- if (!raw.trim()) return resolve10({});
7649
+ if (!raw.trim()) return resolve11({});
6712
7650
  try {
6713
7651
  const parsed = JSON.parse(raw);
6714
- resolve10(parsed && typeof parsed === "object" ? parsed : {});
7652
+ resolve11(parsed && typeof parsed === "object" ? parsed : {});
6715
7653
  } catch {
6716
7654
  reject(new Error("invalid-json"));
6717
7655
  }
@@ -6761,13 +7699,13 @@ async function handleVoucher(req, res, method, rest, deps) {
6761
7699
  if (!voucherDb) return writeErr2(res, 501, "Voucher feature is not available");
6762
7700
  if (method === "GET" && rest.length === 0) {
6763
7701
  const rows = await voucherDb.voucherList();
6764
- return writeJson2(res, 200, { vouchers: rows.map(toVoucherInfo) });
7702
+ return writeJson3(res, 200, { vouchers: rows.map(toVoucherInfo) });
6765
7703
  }
6766
7704
  if (method === "POST" && rest.length === 0) {
6767
7705
  if (!await voucherEnabled(deps)) return writeErr2(res, 403, "Voucher feature is disabled");
6768
7706
  let body;
6769
7707
  try {
6770
- body = await readJsonBody3(req);
7708
+ body = await readJsonBody4(req);
6771
7709
  } catch {
6772
7710
  return writeErr2(res, 400, "Invalid JSON in request body");
6773
7711
  }
@@ -6780,7 +7718,7 @@ async function handleVoucher(req, res, method, rest, deps) {
6780
7718
  codePrefix: voucherCodePrefix(code),
6781
7719
  ...parsed.input
6782
7720
  });
6783
- return writeJson2(res, 201, {
7721
+ return writeJson3(res, 201, {
6784
7722
  id: created.id,
6785
7723
  codePrefix: created.codePrefix,
6786
7724
  type: created.type,
@@ -6793,7 +7731,7 @@ async function handleVoucher(req, res, method, rest, deps) {
6793
7731
  if (method === "POST" && id && rest[1] === "revoke") {
6794
7732
  if (!await voucherEnabled(deps)) return writeErr2(res, 403, "Voucher feature is disabled");
6795
7733
  const ok = await voucherDb.voucherRevokeCas(id, Date.now());
6796
- return writeJson2(res, ok ? 200 : 409, { ok });
7734
+ return writeJson3(res, ok ? 200 : 409, { ok });
6797
7735
  }
6798
7736
  return writeErr2(res, 405, `method ${method} not allowed on voucher`);
6799
7737
  }
@@ -6970,7 +7908,7 @@ import {
6970
7908
  } from "@omnicross/core/outbound-api";
6971
7909
 
6972
7910
  // src/ports/account-multi.ts
6973
- import { randomUUID as randomUUID3 } from "crypto";
7911
+ import { randomUUID as randomUUID4 } from "crypto";
6974
7912
  var PROVIDER_KEYS = {
6975
7913
  claude: { block: "claude", accounts: "claudeAccounts", active: "activeClaudeAccountId" },
6976
7914
  codex: { block: "codex", accounts: "codexAccounts", active: "activeCodexAccountId" },
@@ -7044,7 +7982,7 @@ function migrateLazily(config) {
7044
7982
  }
7045
7983
  function addAccount(config, p, tokens, label) {
7046
7984
  const accounts = [...getAccounts(config, p)];
7047
- const id = randomUUID3();
7985
+ const id = randomUUID4();
7048
7986
  accounts.push({
7049
7987
  id,
7050
7988
  label: label ?? `Account ${accounts.length + 1}`,
@@ -7733,22 +8671,22 @@ async function handlePricingResolveConflicts(body, deps) {
7733
8671
  }
7734
8672
 
7735
8673
  // src/admin/accountAllowanceApi.ts
7736
- function writeJson3(res, status, body) {
8674
+ function writeJson4(res, status, body) {
7737
8675
  res.writeHead(status, { "Content-Type": "application/json" });
7738
8676
  res.end(JSON.stringify(body));
7739
8677
  }
7740
8678
  function writeError2(res, status, message) {
7741
- writeJson3(res, status, { error: { type: "account_allowance_error", message } });
8679
+ writeJson4(res, status, { error: { type: "account_allowance_error", message } });
7742
8680
  }
7743
8681
  function readJson2(req) {
7744
- return new Promise((resolve10, reject) => {
8682
+ return new Promise((resolve11, reject) => {
7745
8683
  const chunks = [];
7746
8684
  req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
7747
8685
  req.on("end", () => {
7748
8686
  try {
7749
8687
  const text = Buffer.concat(chunks).toString("utf8");
7750
8688
  const parsed = text ? JSON.parse(text) : {};
7751
- resolve10(parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {});
8689
+ resolve11(parsed && typeof parsed === "object" && !Array.isArray(parsed) ? parsed : {});
7752
8690
  } catch (error) {
7753
8691
  reject(error);
7754
8692
  }
@@ -7771,7 +8709,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7771
8709
  if (!service.getSchedulingStatus) {
7772
8710
  return writeError2(res, 501, "allowance scheduling diagnostics are not available");
7773
8711
  }
7774
- return writeJson3(res, 200, { scheduling: service.getSchedulingStatus() });
8712
+ return writeJson4(res, 200, { scheduling: service.getSchedulingStatus() });
7775
8713
  }
7776
8714
  if (method === "GET") {
7777
8715
  const params = query(req);
@@ -7782,7 +8720,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7782
8720
  }
7783
8721
  const accountId = rest.length >= 2 ? rest[1] : params.get("accountId") ?? void 0;
7784
8722
  const allowances = await service.list({ providerId, accountId });
7785
- return writeJson3(res, 200, { allowances });
8723
+ return writeJson4(res, 200, { allowances });
7786
8724
  }
7787
8725
  if (method === "POST" && rest[0] === "refresh") {
7788
8726
  const body = await readJson2(req);
@@ -7798,7 +8736,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7798
8736
  if (accountId && allowances2.length === 0) {
7799
8737
  return writeError2(res, 404, `Codex account '${accountId}' not found`);
7800
8738
  }
7801
- return writeJson3(res, 200, { allowances: allowances2 });
8739
+ return writeJson4(res, 200, { allowances: allowances2 });
7802
8740
  }
7803
8741
  if (requestedProvider === "kimi") {
7804
8742
  if (!service.refreshKimi) {
@@ -7808,7 +8746,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7808
8746
  if (accountId && allowances2.length === 0) {
7809
8747
  return writeError2(res, 404, `Kimi account '${accountId}' not found`);
7810
8748
  }
7811
- return writeJson3(res, 200, { allowances: allowances2 });
8749
+ return writeJson4(res, 200, { allowances: allowances2 });
7812
8750
  }
7813
8751
  if (requestedProvider === "opencodego") {
7814
8752
  if (!service.refreshOpenCodeGo) {
@@ -7818,7 +8756,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7818
8756
  if (accountId && allowances2.length === 0) {
7819
8757
  return writeError2(res, 404, `OpenCodeGo account '${accountId}' not found`);
7820
8758
  }
7821
- return writeJson3(res, 200, { allowances: allowances2 });
8759
+ return writeJson4(res, 200, { allowances: allowances2 });
7822
8760
  }
7823
8761
  if (requestedProvider === "copilot") {
7824
8762
  if (!service.refreshCopilot) {
@@ -7828,7 +8766,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7828
8766
  if (accountId && allowances2.length === 0) {
7829
8767
  return writeError2(res, 404, `Copilot account '${accountId}' not found`);
7830
8768
  }
7831
- return writeJson3(res, 200, { allowances: allowances2 });
8769
+ return writeJson4(res, 200, { allowances: allowances2 });
7832
8770
  }
7833
8771
  if (requestedProvider === "grok") {
7834
8772
  if (!service.refreshGrok) {
@@ -7838,7 +8776,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7838
8776
  if (accountId && allowances2.length === 0) {
7839
8777
  return writeError2(res, 404, `Grok account '${accountId}' not found`);
7840
8778
  }
7841
- return writeJson3(res, 200, { allowances: allowances2 });
8779
+ return writeJson4(res, 200, { allowances: allowances2 });
7842
8780
  }
7843
8781
  if (requestedProvider === "antigravity") {
7844
8782
  if (!service.refreshAntigravity) {
@@ -7848,7 +8786,7 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7848
8786
  if (accountId && allowances2.length === 0) {
7849
8787
  return writeError2(res, 404, `Antigravity account '${accountId}' not found`);
7850
8788
  }
7851
- return writeJson3(res, 200, { allowances: allowances2 });
8789
+ return writeJson4(res, 200, { allowances: allowances2 });
7852
8790
  }
7853
8791
  if (requestedProvider === "gemini") {
7854
8792
  if (!service.refreshGemini) {
@@ -7858,13 +8796,13 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
7858
8796
  if (accountId && allowances2.length === 0) {
7859
8797
  return writeError2(res, 404, `Gemini account '${accountId}' not found`);
7860
8798
  }
7861
- return writeJson3(res, 200, { allowances: allowances2 });
8799
+ return writeJson4(res, 200, { allowances: allowances2 });
7862
8800
  }
7863
8801
  const allowances = await service.refreshClaude(accountId);
7864
8802
  if (accountId && allowances.length === 0) {
7865
8803
  return writeError2(res, 404, `Claude account '${accountId}' not found`);
7866
8804
  }
7867
- return writeJson3(res, 200, { allowances });
8805
+ return writeJson4(res, 200, { allowances });
7868
8806
  }
7869
8807
  return writeError2(res, 405, `method ${method} not allowed on account allowances`);
7870
8808
  }
@@ -7876,14 +8814,14 @@ import {
7876
8814
  } from "@omnicross/core/pipeline/AccountRouteActivity";
7877
8815
  import { getSharedOverloadCounter } from "@omnicross/core/pipeline/ServerOverloadCounter";
7878
8816
  function readBody(req) {
7879
- return new Promise((resolve10, reject) => {
8817
+ return new Promise((resolve11, reject) => {
7880
8818
  const chunks = [];
7881
8819
  req.on("data", (chunk) => chunks.push(chunk));
7882
- req.on("end", () => resolve10(Buffer.concat(chunks).toString("utf8")));
8820
+ req.on("end", () => resolve11(Buffer.concat(chunks).toString("utf8")));
7883
8821
  req.on("error", reject);
7884
8822
  });
7885
8823
  }
7886
- async function readJsonBody4(req) {
8824
+ async function readJsonBody5(req) {
7887
8825
  const raw = await readBody(req);
7888
8826
  if (!raw.trim()) return {};
7889
8827
  try {
@@ -7893,12 +8831,12 @@ async function readJsonBody4(req) {
7893
8831
  return {};
7894
8832
  }
7895
8833
  }
7896
- function writeJson4(res, status, body) {
8834
+ function writeJson5(res, status, body) {
7897
8835
  res.writeHead(status, { "Content-Type": "application/json" });
7898
8836
  res.end(JSON.stringify(body));
7899
8837
  }
7900
- function writeJsonError(res, status, message) {
7901
- writeJson4(res, status, { error: { type: "admin_api_error", message } });
8838
+ function writeJsonError2(res, status, message) {
8839
+ writeJson5(res, status, { error: { type: "admin_api_error", message } });
7902
8840
  }
7903
8841
  function maskProviderApiKey(apiKey) {
7904
8842
  if (!apiKey) return "";
@@ -7919,7 +8857,7 @@ function toKeyInfo(row) {
7919
8857
  lastUsedAt: row.lastUsedAt,
7920
8858
  revoked: row.revokedAt !== null,
7921
8859
  kind: row.kind,
7922
- allowedEndpoints: [...effectiveOutboundPermissions2(row.allowedEndpoints)],
8860
+ allowedEndpoints: [...effectiveOutboundPermissions3(row.allowedEndpoints)],
7923
8861
  legacyPermissions: row.allowedEndpoints === void 0,
7924
8862
  loopbackOnly: row.loopbackOnly,
7925
8863
  maxConcurrency: row.maxConcurrency,
@@ -7937,7 +8875,12 @@ function toKeyInfo(row) {
7937
8875
  // Per-key model restriction (#6) — secret-free scalars the UI pre-fills.
7938
8876
  enableModelRestriction: row.enableModelRestriction,
7939
8877
  restrictionMode: row.restrictionMode,
7940
- restrictedModels: row.restrictedModels
8878
+ restrictedModels: row.restrictedModels,
8879
+ // Direct upstream passthrough target (key→upstream binding) — references
8880
+ // only, never a credential. Absent = the key is served by the downstream
8881
+ // routes. `boundUpstreamProviderId` is the legacy first-cut shape.
8882
+ boundUpstream: row.boundUpstream,
8883
+ boundUpstreamProviderId: row.boundUpstreamProviderId
7941
8884
  };
7942
8885
  }
7943
8886
  function toProviderView(row) {
@@ -8031,10 +8974,10 @@ async function handleAdminApi(req, res, path2, deps) {
8031
8974
  case "pricing":
8032
8975
  return await handlePricing(req, res, method, rest, deps);
8033
8976
  default:
8034
- return writeJsonError(res, 404, `unknown admin resource '${resource}'`);
8977
+ return writeJsonError2(res, 404, `unknown admin resource '${resource}'`);
8035
8978
  }
8036
8979
  } catch (err9) {
8037
- writeJsonError(res, 500, err9 instanceof Error ? err9.message : String(err9));
8980
+ writeJsonError2(res, 500, err9 instanceof Error ? err9.message : String(err9));
8038
8981
  }
8039
8982
  }
8040
8983
  function requestQuery(req) {
@@ -8043,35 +8986,35 @@ function requestQuery(req) {
8043
8986
  return new URLSearchParams(qIdx >= 0 ? raw.slice(qIdx + 1) : "");
8044
8987
  }
8045
8988
  function writeResult(res, result) {
8046
- writeJson4(res, result.status, result.body);
8989
+ writeJson5(res, result.status, result.body);
8047
8990
  }
8048
8991
  async function handleUsage(req, res, method, rest, deps) {
8049
- if (method !== "GET") return writeJsonError(res, 405, `method ${method} not allowed on usage`);
8992
+ if (method !== "GET") return writeJsonError2(res, 405, `method ${method} not allowed on usage`);
8050
8993
  return writeResult(res, await handleUsageGet(rest[0], requestQuery(req), deps));
8051
8994
  }
8052
8995
  async function handleDashboardRoute(res, method, deps) {
8053
- if (method !== "GET") return writeJsonError(res, 405, `method ${method} not allowed on dashboard`);
8996
+ if (method !== "GET") return writeJsonError2(res, 405, `method ${method} not allowed on dashboard`);
8054
8997
  const result = await handleDashboard(deps);
8055
- return writeJson4(res, result.status, result.body);
8998
+ return writeJson5(res, result.status, result.body);
8056
8999
  }
8057
9000
  async function handlePricing(req, res, method, rest, deps) {
8058
9001
  if (rest.length === 0) {
8059
9002
  if (method === "GET") return writeResult(res, await handlePricingList(deps));
8060
9003
  if (method === "PUT") {
8061
- return writeResult(res, await handlePricingUpsert(await readJsonBody4(req), deps));
9004
+ return writeResult(res, await handlePricingUpsert(await readJsonBody5(req), deps));
8062
9005
  }
8063
9006
  if (method === "DELETE") {
8064
9007
  return writeResult(res, await handlePricingDelete(requestQuery(req), deps));
8065
9008
  }
8066
- return writeJsonError(res, 405, `method ${method} not allowed on pricing`);
9009
+ return writeJsonError2(res, 405, `method ${method} not allowed on pricing`);
8067
9010
  }
8068
9011
  if (method === "POST" && rest.length === 1 && rest[0] === "fetch-latest") {
8069
9012
  return writeResult(res, await handlePricingFetchLatest(deps));
8070
9013
  }
8071
9014
  if (method === "POST" && rest.length === 1 && rest[0] === "resolve-conflicts") {
8072
- return writeResult(res, await handlePricingResolveConflicts(await readJsonBody4(req), deps));
9015
+ return writeResult(res, await handlePricingResolveConflicts(await readJsonBody5(req), deps));
8073
9016
  }
8074
- return writeJsonError(res, 404, `unknown pricing route '${rest.join("/")}'`);
9017
+ return writeJsonError2(res, 404, `unknown pricing route '${rest.join("/")}'`);
8075
9018
  }
8076
9019
  function migrationDeps(deps) {
8077
9020
  return {
@@ -8082,16 +9025,16 @@ function migrationDeps(deps) {
8082
9025
  };
8083
9026
  }
8084
9027
  async function handleMigrationExport(req, res, method, deps) {
8085
- if (method !== "POST") return writeJsonError(res, 405, `method ${method} not allowed on export`);
8086
- const body = await readJsonBody4(req);
9028
+ if (method !== "POST") return writeJsonError2(res, 405, `method ${method} not allowed on export`);
9029
+ const body = await readJsonBody5(req);
8087
9030
  const result = await handleExport(body, migrationDeps(deps));
8088
- return writeJson4(res, result.status, result.body);
9031
+ return writeJson5(res, result.status, result.body);
8089
9032
  }
8090
9033
  async function handleMigrationImport(req, res, method, deps) {
8091
- if (method !== "POST") return writeJsonError(res, 405, `method ${method} not allowed on import`);
8092
- const body = await readJsonBody4(req);
9034
+ if (method !== "POST") return writeJsonError2(res, 405, `method ${method} not allowed on import`);
9035
+ const body = await readJsonBody5(req);
8093
9036
  const result = await handleImport(body, migrationDeps(deps));
8094
- return writeJson4(res, result.status, result.body);
9037
+ return writeJson5(res, result.status, result.body);
8095
9038
  }
8096
9039
  async function handleProviders(req, res, method, rest, deps) {
8097
9040
  const cfg = loadConfig(deps.configPath);
@@ -8124,52 +9067,52 @@ async function handleProviders(req, res, method, rest, deps) {
8124
9067
  }
8125
9068
  if (method === "GET" && rest.length === 2 && rest[1] === "reveal-key") {
8126
9069
  const row = cfg.providers.find((p) => p.id === rest[0]);
8127
- if (!row) return writeJsonError(res, 404, `provider '${rest[0]}' not found`);
8128
- return writeJson4(res, 200, { apiKey: row.apiKey ?? "" });
9070
+ if (!row) return writeJsonError2(res, 404, `provider '${rest[0]}' not found`);
9071
+ return writeJson5(res, 200, { apiKey: row.apiKey ?? "" });
8129
9072
  }
8130
9073
  if (method === "GET") {
8131
- return writeJson4(res, 200, { providers: cfg.providers.map(toProviderView) });
9074
+ return writeJson5(res, 200, { providers: cfg.providers.map(toProviderView) });
8132
9075
  }
8133
9076
  if (method === "POST") {
8134
- const body = await readJsonBody4(req);
9077
+ const body = await readJsonBody5(req);
8135
9078
  const provider = parseProviderInput(body, void 0);
8136
- if (!provider) return writeJsonError(res, 400, "invalid provider (id, apiFormat, baseUrl required)");
9079
+ if (!provider) return writeJsonError2(res, 400, "invalid provider (id, apiFormat, baseUrl required)");
8137
9080
  if (cfg.providers.some((p) => p.id === provider.id)) {
8138
- return writeJsonError(res, 409, `provider '${provider.id}' already exists`);
9081
+ return writeJsonError2(res, 409, `provider '${provider.id}' already exists`);
8139
9082
  }
8140
9083
  cfg.providers.push(provider);
8141
9084
  persistProviders(cfg, deps);
8142
- return writeJson4(res, 201, { provider: toProviderView(provider) });
9085
+ return writeJson5(res, 201, { provider: toProviderView(provider) });
8143
9086
  }
8144
9087
  const id = rest[0];
8145
- if (!id) return writeJsonError(res, 400, "provider id required in path");
9088
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
8146
9089
  const idx = cfg.providers.findIndex((p) => p.id === id);
8147
- if (idx < 0) return writeJsonError(res, 404, `provider '${id}' not found`);
9090
+ if (idx < 0) return writeJsonError2(res, 404, `provider '${id}' not found`);
8148
9091
  if (method === "PUT") {
8149
- const body = await readJsonBody4(req);
9092
+ const body = await readJsonBody5(req);
8150
9093
  const existing = cfg.providers[idx];
8151
9094
  const updated = parseProviderInput(body, existing);
8152
- if (!updated) return writeJsonError(res, 400, "invalid provider (apiFormat, baseUrl required)");
9095
+ if (!updated) return writeJsonError2(res, 400, "invalid provider (apiFormat, baseUrl required)");
8153
9096
  cfg.providers[idx] = updated;
8154
9097
  persistProviders(cfg, deps);
8155
- return writeJson4(res, 200, { provider: toProviderView(updated) });
9098
+ return writeJson5(res, 200, { provider: toProviderView(updated) });
8156
9099
  }
8157
9100
  if (method === "DELETE") {
8158
9101
  cfg.providers.splice(idx, 1);
8159
9102
  persistProviders(cfg, deps);
8160
- return writeJson4(res, 200, { ok: true });
9103
+ return writeJson5(res, 200, { ok: true });
8161
9104
  }
8162
- return writeJsonError(res, 405, `method ${method} not allowed on providers`);
9105
+ return writeJsonError2(res, 405, `method ${method} not allowed on providers`);
8163
9106
  }
8164
9107
  function persistProviders(cfg, deps) {
8165
9108
  saveConfig(deps.configPath, cfg);
8166
9109
  deps.llmConfig.reload(cfg);
8167
9110
  }
8168
9111
  async function handleProviderReorder(req, res, cfg, deps) {
8169
- const body = await readJsonBody4(req);
9112
+ const body = await readJsonBody5(req);
8170
9113
  const rawOrder = body["order"];
8171
9114
  if (!Array.isArray(rawOrder)) {
8172
- return writeJsonError(res, 400, "reorder requires { order: string[] }");
9115
+ return writeJsonError2(res, 400, "reorder requires { order: string[] }");
8173
9116
  }
8174
9117
  const order = rawOrder.filter((x) => typeof x === "string");
8175
9118
  const byId = new Map(cfg.providers.map((p) => [p.id, p]));
@@ -8190,17 +9133,17 @@ async function handleProviderReorder(req, res, cfg, deps) {
8190
9133
  }
8191
9134
  cfg.providers = reordered;
8192
9135
  persistProviders(cfg, deps);
8193
- return writeJson4(res, 200, { ok: true, providers: cfg.providers.map(toProviderView) });
9136
+ return writeJson5(res, 200, { ok: true, providers: cfg.providers.map(toProviderView) });
8194
9137
  }
8195
9138
  function expandRowExtraHeaders(row) {
8196
9139
  return mergeExtraHeaders({}, row.extraHeaders);
8197
9140
  }
8198
9141
  async function handleDiscoverModels(res, id, cfg) {
8199
- if (!id) return writeJsonError(res, 400, "provider id required in path");
9142
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
8200
9143
  const row = cfg.providers.find((p) => p.id === id);
8201
- if (!row) return writeJsonError(res, 404, `provider '${id}' not found`);
9144
+ if (!row) return writeJsonError2(res, 404, `provider '${id}' not found`);
8202
9145
  if (row.apiFormat !== "openai" && row.apiFormat !== "openai-response") {
8203
- return writeJson4(res, 200, { models: [], unsupportedFormat: true });
9146
+ return writeJson5(res, 200, { models: [], unsupportedFormat: true });
8204
9147
  }
8205
9148
  const resolvedKey = resolveEnvKey(row.apiKey);
8206
9149
  const base = row.baseUrl.replace(/\/+$/, "");
@@ -8209,6 +9152,7 @@ async function handleDiscoverModels(res, id, cfg) {
8209
9152
  const headers = { Accept: "application/json" };
8210
9153
  if (resolvedKey) headers["Authorization"] = `Bearer ${resolvedKey}`;
8211
9154
  Object.assign(headers, expandRowExtraHeaders(row));
9155
+ applyAdminProbeIdentity(headers, row);
8212
9156
  const response = await fetchUpstream10(url, { method: "GET", headers }, { providerId: "byo" });
8213
9157
  if (!response.ok) {
8214
9158
  const text = await response.text().catch(() => "");
@@ -8218,32 +9162,32 @@ async function handleDiscoverModels(res, id, cfg) {
8218
9162
  message = parsed?.error?.message || parsed?.message || message;
8219
9163
  } catch {
8220
9164
  }
8221
- return writeJson4(res, 200, {
9165
+ return writeJson5(res, 200, {
8222
9166
  models: [],
8223
9167
  error: `discovery failed (${response.status})${message ? `: ${message}` : ""}`
8224
9168
  });
8225
9169
  }
8226
9170
  const data = await response.json();
8227
9171
  const models = Array.isArray(data?.data) ? data.data.map((m) => typeof m?.id === "string" ? m.id : "").filter((m) => m.length > 0) : [];
8228
- return writeJson4(res, 200, { models });
9172
+ return writeJson5(res, 200, { models });
8229
9173
  } catch (err9) {
8230
9174
  const message = err9 instanceof Error ? err9.message : String(err9);
8231
- return writeJson4(res, 200, { models: [], error: `discovery failed: ${message}` });
9175
+ return writeJson5(res, 200, { models: [], error: `discovery failed: ${message}` });
8232
9176
  }
8233
9177
  }
8234
9178
  async function handleTestModel(req, res, id, cfg) {
8235
- if (!id) return writeJsonError(res, 400, "provider id required in path");
9179
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
8236
9180
  const row = cfg.providers.find((p) => p.id === id);
8237
- if (!row) return writeJsonError(res, 404, `provider '${id}' not found`);
8238
- const body = await readJsonBody4(req);
9181
+ if (!row) return writeJsonError2(res, 404, `provider '${id}' not found`);
9182
+ const body = await readJsonBody5(req);
8239
9183
  const model = typeof body["model"] === "string" ? body["model"].trim() : "";
8240
- if (!model) return writeJsonError(res, 400, "test requires a { model } string");
9184
+ if (!model) return writeJsonError2(res, 400, "test requires a { model } string");
8241
9185
  if (row.apiFormat === "gemini") {
8242
- return writeJson4(res, 200, { ok: false, unsupportedFormat: true });
9186
+ return writeJson5(res, 200, { ok: false, unsupportedFormat: true });
8243
9187
  }
8244
9188
  const resolvedKey = resolveEnvKey(row.apiKey);
8245
9189
  if (!resolvedKey) {
8246
- return writeJson4(res, 200, { ok: false, message: "no API key configured for this provider" });
9190
+ return writeJson5(res, 200, { ok: false, message: "no API key configured for this provider" });
8247
9191
  }
8248
9192
  let url = row.baseUrl.replace(/\/+$/, "");
8249
9193
  const prompt = "Reply with the single word: OK.";
@@ -8267,6 +9211,7 @@ async function handleTestModel(req, res, id, cfg) {
8267
9211
  };
8268
9212
  }
8269
9213
  Object.assign(headers, expandRowExtraHeaders(row));
9214
+ applyAdminProbeIdentity(headers, row);
8270
9215
  const startedAt = Date.now();
8271
9216
  try {
8272
9217
  const response = await fetchUpstream10(
@@ -8283,9 +9228,9 @@ async function handleTestModel(req, res, id, cfg) {
8283
9228
  message = parsed?.error?.message || parsed?.message || message;
8284
9229
  } catch {
8285
9230
  }
8286
- return writeJson4(res, 200, { ok: false, status: response.status, latencyMs, message });
9231
+ return writeJson5(res, 200, { ok: false, status: response.status, latencyMs, message });
8287
9232
  }
8288
- return writeJson4(res, 200, {
9233
+ return writeJson5(res, 200, {
8289
9234
  ok: true,
8290
9235
  status: response.status,
8291
9236
  latencyMs,
@@ -8293,7 +9238,7 @@ async function handleTestModel(req, res, id, cfg) {
8293
9238
  });
8294
9239
  } catch (err9) {
8295
9240
  const message = err9 instanceof Error ? err9.message : String(err9);
8296
- return writeJson4(res, 200, { ok: false, latencyMs: Date.now() - startedAt, message });
9241
+ return writeJson5(res, 200, { ok: false, latencyMs: Date.now() - startedAt, message });
8297
9242
  }
8298
9243
  }
8299
9244
  function extractSampleText(text, apiFormat) {
@@ -8330,9 +9275,9 @@ function toPoolKeyView(row, cooldown, deps) {
8330
9275
  });
8331
9276
  }
8332
9277
  async function handleProviderKeys(res, id, cfg, deps) {
8333
- if (!id) return writeJsonError(res, 400, "provider id required in path");
9278
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
8334
9279
  const row = cfg.providers.find((p) => p.id === id);
8335
- if (!row) return writeJsonError(res, 404, `provider '${id}' not found`);
9280
+ if (!row) return writeJsonError2(res, 404, `provider '${id}' not found`);
8336
9281
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
8337
9282
  const views = toPoolKeyView(row, cooldown, deps);
8338
9283
  if (deps.providerKeyQuota) {
@@ -8344,19 +9289,19 @@ async function handleProviderKeys(res, id, cfg, deps) {
8344
9289
  if (settled.status === "fulfilled" && settled.value) view.quota = settled.value;
8345
9290
  });
8346
9291
  }
8347
- return writeJson4(res, 200, { keys: views });
9292
+ return writeJson5(res, 200, { keys: views });
8348
9293
  }
8349
9294
  async function handleProviderKeyQuotaRefresh(res, id, keyId, cfg, deps) {
8350
- if (!deps.providerKeyQuota) return writeJsonError(res, 501, "provider key quota is not available");
8351
- if (!id || !keyId) return writeJsonError(res, 400, "provider id and key id required in path");
9295
+ if (!deps.providerKeyQuota) return writeJsonError2(res, 501, "provider key quota is not available");
9296
+ if (!id || !keyId) return writeJsonError2(res, 400, "provider id and key id required in path");
8352
9297
  const row = cfg.providers.find((p) => p.id === id);
8353
- if (!row) return writeJsonError(res, 404, `provider '${id}' not found`);
9298
+ if (!row) return writeJsonError2(res, 404, `provider '${id}' not found`);
8354
9299
  try {
8355
9300
  const quota = await deps.providerKeyQuota.quotaFor(row, keyId, { force: true });
8356
- if (!quota) return writeJsonError(res, 404, `no quota endpoint for key '${keyId}'`);
8357
- return writeJson4(res, 200, { quota });
9301
+ if (!quota) return writeJsonError2(res, 404, `no quota endpoint for key '${keyId}'`);
9302
+ return writeJson5(res, 200, { quota });
8358
9303
  } catch {
8359
- return writeJsonError(res, 502, "quota refresh failed");
9304
+ return writeJsonError2(res, 502, "quota refresh failed");
8360
9305
  }
8361
9306
  }
8362
9307
  function parsePoolKeyInput(body, existing) {
@@ -8373,12 +9318,12 @@ function parsePoolKeyInput(body, existing) {
8373
9318
  return out;
8374
9319
  }
8375
9320
  async function handleAddProviderKey(req, res, id, cfg, deps) {
8376
- if (!id) return writeJsonError(res, 400, "provider id required in path");
9321
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
8377
9322
  const idx = cfg.providers.findIndex((p) => p.id === id);
8378
- if (idx < 0) return writeJsonError(res, 404, `provider '${id}' not found`);
8379
- const body = await readJsonBody4(req);
9323
+ if (idx < 0) return writeJsonError2(res, 404, `provider '${id}' not found`);
9324
+ const body = await readJsonBody5(req);
8380
9325
  const parsed = parsePoolKeyInput(body);
8381
- if (!parsed.apiKey) return writeJsonError(res, 400, "add requires a non-empty apiKey");
9326
+ if (!parsed.apiKey) return writeJsonError2(res, 400, "add requires a non-empty apiKey");
8382
9327
  const keyId = `key-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
8383
9328
  const entry = { id: keyId, apiKey: parsed.apiKey };
8384
9329
  if (parsed.label !== void 0) entry.label = parsed.label;
@@ -8388,17 +9333,17 @@ async function handleAddProviderKey(req, res, id, cfg, deps) {
8388
9333
  row.apiKeys = [...row.apiKeys ?? [], entry];
8389
9334
  persistProviders(cfg, deps);
8390
9335
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
8391
- return writeJson4(res, 201, { keys: toPoolKeyView(row, cooldown, deps) });
9336
+ return writeJson5(res, 201, { keys: toPoolKeyView(row, cooldown, deps) });
8392
9337
  }
8393
9338
  async function handleUpdateProviderKey(req, res, id, keyId, cfg, deps) {
8394
- if (!id) return writeJsonError(res, 400, "provider id required in path");
8395
- if (!keyId) return writeJsonError(res, 400, "key id required in path");
9339
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
9340
+ if (!keyId) return writeJsonError2(res, 400, "key id required in path");
8396
9341
  const idx = cfg.providers.findIndex((p) => p.id === id);
8397
- if (idx < 0) return writeJsonError(res, 404, `provider '${id}' not found`);
9342
+ if (idx < 0) return writeJsonError2(res, 404, `provider '${id}' not found`);
8398
9343
  const row = cfg.providers[idx];
8399
9344
  const keyIdx = (row.apiKeys ?? []).findIndex((k) => k.id === keyId);
8400
- if (keyIdx < 0) return writeJsonError(res, 404, `pool key '${keyId}' not found`);
8401
- const body = await readJsonBody4(req);
9345
+ if (keyIdx < 0) return writeJsonError2(res, 404, `pool key '${keyId}' not found`);
9346
+ const body = await readJsonBody5(req);
8402
9347
  const existing = row.apiKeys[keyIdx];
8403
9348
  const parsed = parsePoolKeyInput(body, existing);
8404
9349
  const entry = { id: keyId, apiKey: parsed.apiKey || existing.apiKey };
@@ -8408,35 +9353,35 @@ async function handleUpdateProviderKey(req, res, id, keyId, cfg, deps) {
8408
9353
  row.apiKeys[keyIdx] = entry;
8409
9354
  persistProviders(cfg, deps);
8410
9355
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
8411
- return writeJson4(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
9356
+ return writeJson5(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
8412
9357
  }
8413
9358
  async function handleDeleteProviderKey(res, id, keyId, cfg, deps) {
8414
- if (!id) return writeJsonError(res, 400, "provider id required in path");
8415
- if (!keyId) return writeJsonError(res, 400, "key id required in path");
9359
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
9360
+ if (!keyId) return writeJsonError2(res, 400, "key id required in path");
8416
9361
  const idx = cfg.providers.findIndex((p) => p.id === id);
8417
- if (idx < 0) return writeJsonError(res, 404, `provider '${id}' not found`);
9362
+ if (idx < 0) return writeJsonError2(res, 404, `provider '${id}' not found`);
8418
9363
  const row = cfg.providers[idx];
8419
9364
  const keyIdx = (row.apiKeys ?? []).findIndex((k) => k.id === keyId);
8420
- if (keyIdx < 0) return writeJsonError(res, 404, `pool key '${keyId}' not found`);
9365
+ if (keyIdx < 0) return writeJsonError2(res, 404, `pool key '${keyId}' not found`);
8421
9366
  row.apiKeys.splice(keyIdx, 1);
8422
9367
  if (row.apiKeys.length === 0) row.apiKeys = void 0;
8423
9368
  persistProviders(cfg, deps);
8424
9369
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
8425
- return writeJson4(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
9370
+ return writeJson5(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
8426
9371
  }
8427
9372
  async function handleToggleProviderKey(req, res, id, keyId, cfg, deps) {
8428
- if (!id) return writeJsonError(res, 400, "provider id required in path");
8429
- if (!keyId) return writeJsonError(res, 400, "key id required in path");
9373
+ if (!id) return writeJsonError2(res, 400, "provider id required in path");
9374
+ if (!keyId) return writeJsonError2(res, 400, "key id required in path");
8430
9375
  const idx = cfg.providers.findIndex((p) => p.id === id);
8431
- if (idx < 0) return writeJsonError(res, 404, `provider '${id}' not found`);
9376
+ if (idx < 0) return writeJsonError2(res, 404, `provider '${id}' not found`);
8432
9377
  const row = cfg.providers[idx];
8433
9378
  const keyIdx = (row.apiKeys ?? []).findIndex((k) => k.id === keyId);
8434
- if (keyIdx < 0) return writeJsonError(res, 404, `pool key '${keyId}' not found`);
8435
- const body = await readJsonBody4(req);
9379
+ if (keyIdx < 0) return writeJsonError2(res, 404, `pool key '${keyId}' not found`);
9380
+ const body = await readJsonBody5(req);
8436
9381
  row.apiKeys[keyIdx].enabled = Boolean(body["enabled"]);
8437
9382
  persistProviders(cfg, deps);
8438
9383
  const cooldown = await deps.apiKeyPool.getKeyHealth(id);
8439
- return writeJson4(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
9384
+ return writeJson5(res, 200, { keys: toPoolKeyView(row, cooldown, deps) });
8440
9385
  }
8441
9386
  function parseApiKeysInput(raw, existing) {
8442
9387
  if (!Array.isArray(raw)) return existing;
@@ -8608,7 +9553,7 @@ function parseProviderInput(body, existing) {
8608
9553
  };
8609
9554
  }
8610
9555
  function handlePresets(res, method) {
8611
- if (method !== "GET") return writeJsonError(res, 405, `method ${method} not allowed on presets`);
9556
+ if (method !== "GET") return writeJsonError2(res, 405, `method ${method} not allowed on presets`);
8612
9557
  const { mappable, excluded } = listMappablePresets();
8613
9558
  const presets = mappable.map((p) => ({
8614
9559
  id: p.id,
@@ -8627,13 +9572,13 @@ function handlePresets(res, method) {
8627
9572
  // row (the write gateway re-validates via the shared allowlist).
8628
9573
  extraHeaders: p.extraHeaders
8629
9574
  }));
8630
- return writeJson4(res, 200, { presets, excluded });
9575
+ return writeJson5(res, 200, { presets, excluded });
8631
9576
  }
8632
9577
  async function handleKeys(req, res, method, rest, deps) {
8633
9578
  if (method === "GET" && rest.length === 0) {
8634
9579
  const rows = await deps.keyDb.outboundApiKeysList();
8635
9580
  const reader = deps.keySpendReader;
8636
- if (!reader) return writeJson4(res, 200, { keys: rows.map(toKeyInfo) });
9581
+ if (!reader) return writeJson5(res, 200, { keys: rows.map(toKeyInfo) });
8637
9582
  const now = Date.now();
8638
9583
  const keys = await Promise.all(
8639
9584
  rows.map(async (row) => {
@@ -8645,13 +9590,13 @@ async function handleKeys(req, res, method, rest, deps) {
8645
9590
  return info;
8646
9591
  })
8647
9592
  );
8648
- return writeJson4(res, 200, { keys });
9593
+ return writeJson5(res, 200, { keys });
8649
9594
  }
8650
9595
  if (method === "POST" && rest.length === 0) {
8651
- const body = await readJsonBody4(req);
9596
+ const body = await readJsonBody5(req);
8652
9597
  const name = typeof body["name"] === "string" && body["name"].trim() ? body["name"].trim() : "key";
8653
9598
  const created = await createNamedKey(deps.keyDb, name);
8654
- return writeJson4(res, 201, {
9599
+ return writeJson5(res, 201, {
8655
9600
  id: created.id,
8656
9601
  name: created.name,
8657
9602
  keyPrefix: created.keyPrefix,
@@ -8662,10 +9607,10 @@ async function handleKeys(req, res, method, rest, deps) {
8662
9607
  }
8663
9608
  if (method === "GET" && rest.length === 2 && rest[1] === "reveal") {
8664
9609
  const revealed = await deps.keyDb.outboundApiKeysReveal(rest[0]);
8665
- if (revealed !== null) return writeJson4(res, 200, { key: revealed });
9610
+ if (revealed !== null) return writeJson5(res, 200, { key: revealed });
8666
9611
  const exists = (await deps.keyDb.outboundApiKeysList()).some((r) => r.id === rest[0]);
8667
- if (!exists) return writeJsonError(res, 404, `key '${rest[0]}' not found`);
8668
- return writeJsonError(
9612
+ if (!exists) return writeJsonError2(res, 404, `key '${rest[0]}' not found`);
9613
+ return writeJsonError2(
8669
9614
  res,
8670
9615
  409,
8671
9616
  `key '${rest[0]}' is not revealable (created before revealable key storage)`
@@ -8675,55 +9620,55 @@ async function handleKeys(req, res, method, rest, deps) {
8675
9620
  const action = rest[1];
8676
9621
  if (method === "POST" && id && action === "revoke") {
8677
9622
  const bound = await integrationKeyRequirement(deps, id);
8678
- if (bound) return writeJsonError(res, 409, bound);
9623
+ if (bound) return writeJsonError2(res, 409, bound);
8679
9624
  const ok = await deps.keyDb.outboundApiKeysRevoke(id);
8680
- return writeJson4(res, ok ? 200 : 404, { ok });
9625
+ return writeJson5(res, ok ? 200 : 404, { ok });
8681
9626
  }
8682
9627
  if (method === "DELETE" && id && !action) {
8683
9628
  const bound = await integrationKeyRequirement(deps, id);
8684
- if (bound) return writeJsonError(res, 409, bound);
9629
+ if (bound) return writeJsonError2(res, 409, bound);
8685
9630
  const ok = await deps.keyDb.outboundApiKeysDelete(id);
8686
- return writeJson4(res, ok ? 200 : 404, { ok });
9631
+ return writeJson5(res, ok ? 200 : 404, { ok });
8687
9632
  }
8688
9633
  if (method === "POST" && id && action === "enabled") {
8689
- const body = await readJsonBody4(req);
9634
+ const body = await readJsonBody5(req);
8690
9635
  const enabled = body["enabled"] === true;
8691
9636
  if (!enabled) {
8692
9637
  const bound = await integrationKeyRequirement(deps, id);
8693
- if (bound) return writeJsonError(res, 409, bound);
9638
+ if (bound) return writeJsonError2(res, 409, bound);
8694
9639
  }
8695
9640
  const ok = await deps.keyDb.outboundApiKeysSetEnabled(id, enabled);
8696
- return writeJson4(res, ok ? 200 : 404, { ok, enabled });
9641
+ return writeJson5(res, ok ? 200 : 404, { ok, enabled });
8697
9642
  }
8698
9643
  if (method === "POST" && id && action === "permissions") {
8699
- const body = await readJsonBody4(req);
9644
+ const body = await readJsonBody5(req);
8700
9645
  if (Object.keys(body).length !== 1 || !Object.prototype.hasOwnProperty.call(body, "permissions")) {
8701
- return writeJsonError(res, 400, "body must contain only permissions");
9646
+ return writeJsonError2(res, 400, "body must contain only permissions");
8702
9647
  }
8703
9648
  let permissions;
8704
9649
  try {
8705
9650
  permissions = validateOutboundPermissions(body["permissions"]);
8706
9651
  } catch {
8707
- return writeJsonError(
9652
+ return writeJsonError2(
8708
9653
  res,
8709
9654
  400,
8710
9655
  "permissions must be an array of unique chat, responses, messages, gemini, or images values"
8711
9656
  );
8712
9657
  }
8713
9658
  const before = (await deps.keyDb.outboundApiKeysList()).find((row) => row.id === id);
8714
- if (!before) return writeJson4(res, 404, { ok: false });
8715
- if (before.revokedAt !== null) return writeJson4(res, 409, { ok: false });
9659
+ if (!before) return writeJson5(res, 404, { ok: false });
9660
+ if (before.revokedAt !== null) return writeJson5(res, 409, { ok: false });
8716
9661
  const required = await integrationKeyRequirement(deps, id, permissions);
8717
- if (required) return writeJsonError(res, 409, required);
9662
+ if (required) return writeJsonError2(res, 409, required);
8718
9663
  const ok = await deps.keyDb.outboundApiKeysSetPermissions(id, permissions);
8719
9664
  if (!ok) {
8720
9665
  const current = (await deps.keyDb.outboundApiKeysList()).find((row) => row.id === id);
8721
- return writeJson4(res, current?.revokedAt !== null ? 409 : 404, { ok: false });
9666
+ return writeJson5(res, current?.revokedAt !== null ? 409 : 404, { ok: false });
8722
9667
  }
8723
- return writeJson4(res, 200, { ok: true, allowedEndpoints: permissions });
9668
+ return writeJson5(res, 200, { ok: true, allowedEndpoints: permissions });
8724
9669
  }
8725
9670
  if (method === "POST" && id && action === "max-concurrency") {
8726
- const body = await readJsonBody4(req);
9671
+ const body = await readJsonBody5(req);
8727
9672
  const raw = body["maxConcurrency"];
8728
9673
  let value;
8729
9674
  if (raw === null) {
@@ -8731,23 +9676,73 @@ async function handleKeys(req, res, method, rest, deps) {
8731
9676
  } else if (typeof raw === "number" && Number.isInteger(raw) && raw >= 1 && raw <= 1e3) {
8732
9677
  value = raw;
8733
9678
  } else {
8734
- return writeJsonError(
9679
+ return writeJsonError2(
8735
9680
  res,
8736
9681
  400,
8737
9682
  "maxConcurrency must be an integer 1..1000 or null"
8738
9683
  );
8739
9684
  }
8740
9685
  const ok = await deps.keyDb.outboundApiKeysSetMaxConcurrency(id, value);
8741
- return writeJson4(res, ok ? 200 : 404, { ok, maxConcurrency: value });
9686
+ return writeJson5(res, ok ? 200 : 404, { ok, maxConcurrency: value });
9687
+ }
9688
+ if (method === "POST" && id && action === "upstream") {
9689
+ const body = await readJsonBody5(req);
9690
+ let raw;
9691
+ if (Object.prototype.hasOwnProperty.call(body, "target")) {
9692
+ raw = body["target"];
9693
+ } else if (Object.prototype.hasOwnProperty.call(body, "providerId")) {
9694
+ const legacy = body["providerId"];
9695
+ raw = legacy === null || legacy === void 0 ? null : { kind: "provider", providerId: legacy };
9696
+ } else {
9697
+ return writeJsonError2(res, 400, "body must contain target (or the legacy providerId)");
9698
+ }
9699
+ if (raw === null || raw === void 0) {
9700
+ const ok2 = await deps.keyDb.outboundApiKeysSetUpstream(id, null);
9701
+ return writeJson5(res, ok2 ? 200 : 404, { ok: ok2, target: null });
9702
+ }
9703
+ if (typeof raw !== "object" || Array.isArray(raw)) {
9704
+ return writeJsonError2(res, 400, "target must be an object or null");
9705
+ }
9706
+ const t = raw;
9707
+ const kind = t["kind"];
9708
+ const providerId = typeof t["providerId"] === "string" ? t["providerId"].trim() : "";
9709
+ if (!providerId) {
9710
+ return writeJsonError2(res, 400, "target.providerId is required");
9711
+ }
9712
+ if (kind === "provider") {
9713
+ const cfg = loadConfig(deps.configPath);
9714
+ if (!cfg.providers.some((p) => p.id === providerId)) {
9715
+ return writeJsonError2(res, 404, `provider '${providerId}' not found`);
9716
+ }
9717
+ } else if (kind === "account" || kind === "account-group" || kind === "account-pool") {
9718
+ if (providerId !== "claude" && providerId !== "kimi") {
9719
+ return writeJsonError2(
9720
+ res,
9721
+ 400,
9722
+ `subscription provider '${providerId}' cannot be direct-bound: its upstream wire differs from the client wire (translation required \u2014 use a downstream route); only claude and kimi subscriptions speak the same Anthropic Messages wire as the client`
9723
+ );
9724
+ }
9725
+ if (kind === "account" && typeof t["accountId"] !== "string") {
9726
+ return writeJsonError2(res, 400, "target.accountId is required for kind account");
9727
+ }
9728
+ if (kind === "account-group" && typeof t["group"] !== "string") {
9729
+ return writeJsonError2(res, 400, "target.group is required for kind account-group");
9730
+ }
9731
+ } else {
9732
+ return writeJsonError2(res, 400, "target.kind must be provider, account, account-group, or account-pool");
9733
+ }
9734
+ const target = raw;
9735
+ const ok = await deps.keyDb.outboundApiKeysSetUpstream(id, target);
9736
+ return writeJson5(res, ok ? 200 : 404, { ok, target });
8742
9737
  }
8743
9738
  if (method === "POST" && id && action === "policy") {
8744
- const body = await readJsonBody4(req);
9739
+ const body = await readJsonBody5(req);
8745
9740
  const parsed = parseKeyPolicyBody(body);
8746
- if (!parsed.ok) return writeJsonError(res, 400, parsed.message);
9741
+ if (!parsed.ok) return writeJsonError2(res, 400, parsed.message);
8747
9742
  const ok = await deps.keyDb.outboundApiKeysSetPolicy(id, parsed.policy);
8748
- return writeJson4(res, ok ? 200 : 404, { ok });
9743
+ return writeJson5(res, ok ? 200 : 404, { ok });
8749
9744
  }
8750
- return writeJsonError(res, 405, `method ${method} not allowed on keys`);
9745
+ return writeJsonError2(res, 405, `method ${method} not allowed on keys`);
8751
9746
  }
8752
9747
  function validateQueueSegments(patch) {
8753
9748
  const errors = [];
@@ -8911,17 +9906,17 @@ async function handleServer(req, res, method, deps) {
8911
9906
  search: redactSearchServerConfig(config.search)
8912
9907
  };
8913
9908
  }
8914
- return writeJson4(res, 200, { server: projectImagesConfigForAdmin(server) });
9909
+ return writeJson5(res, 200, { server: projectImagesConfigForAdmin(server) });
8915
9910
  }
8916
9911
  if (method === "PUT") {
8917
- const patch = await readJsonBody4(req);
9912
+ const patch = await readJsonBody5(req);
8918
9913
  const queueErrors = validateQueueSegments(patch);
8919
9914
  if (queueErrors.length > 0) {
8920
- return writeJsonError(res, 400, `invalid queue config: ${queueErrors.join("; ")}`);
9915
+ return writeJsonError2(res, 400, `invalid queue config: ${queueErrors.join("; ")}`);
8921
9916
  }
8922
9917
  const allowanceErrors = validateAllowanceSchedulingSegment(patch);
8923
9918
  if (allowanceErrors.length > 0) {
8924
- return writeJsonError(
9919
+ return writeJsonError2(
8925
9920
  res,
8926
9921
  400,
8927
9922
  `invalid allowance scheduling config: ${allowanceErrors.join("; ")}`
@@ -8929,19 +9924,19 @@ async function handleServer(req, res, method, deps) {
8929
9924
  }
8930
9925
  const bindingErrors = validateGatewayBindingsSegment(patch);
8931
9926
  if (bindingErrors.length > 0) {
8932
- return writeJsonError(res, 400, `invalid gateway bindings: ${bindingErrors.join("; ")}`);
9927
+ return writeJsonError2(res, 400, `invalid gateway bindings: ${bindingErrors.join("; ")}`);
8933
9928
  }
8934
9929
  const webhookErrors = validateWebhookSegment(patch);
8935
9930
  if (webhookErrors.length > 0) {
8936
- return writeJsonError(res, 400, `invalid webhook config: ${webhookErrors.join("; ")}`);
9931
+ return writeJsonError2(res, 400, `invalid webhook config: ${webhookErrors.join("; ")}`);
8937
9932
  }
8938
9933
  const auditErrors = validateAuditSegment(patch);
8939
9934
  if (auditErrors.length > 0) {
8940
- return writeJsonError(res, 400, `invalid audit config: ${auditErrors.join("; ")}`);
9935
+ return writeJsonError2(res, 400, `invalid audit config: ${auditErrors.join("; ")}`);
8941
9936
  }
8942
9937
  const billingErrors = validateBillingSegment(patch);
8943
9938
  if (billingErrors.length > 0) {
8944
- return writeJsonError(res, 400, `invalid billing config: ${billingErrors.join("; ")}`);
9939
+ return writeJsonError2(res, 400, `invalid billing config: ${billingErrors.join("; ")}`);
8945
9940
  }
8946
9941
  const current = await loadServerConfig3(deps.settingsStore);
8947
9942
  let effectivePatch = patch;
@@ -8960,7 +9955,7 @@ async function handleServer(req, res, method, deps) {
8960
9955
  remoteResolverAvailable: deps.imageRemoteResolverAvailable
8961
9956
  });
8962
9957
  if (imageErrors.length > 0) {
8963
- return writeJsonError(res, 400, `invalid Images config: ${imageErrors.join("; ")}`);
9958
+ return writeJsonError2(res, 400, `invalid Images config: ${imageErrors.join("; ")}`);
8964
9959
  }
8965
9960
  effectivePatch = { ...effectivePatch, images };
8966
9961
  }
@@ -8971,7 +9966,7 @@ async function handleServer(req, res, method, deps) {
8971
9966
  );
8972
9967
  const searchErrors = validateSearchServerConfig(searchPatch);
8973
9968
  if (searchErrors.length > 0) {
8974
- return writeJsonError(res, 400, `invalid search config: ${searchErrors.join("; ")}`);
9969
+ return writeJsonError2(res, 400, `invalid search config: ${searchErrors.join("; ")}`);
8975
9970
  }
8976
9971
  effectivePatch = {
8977
9972
  ...effectivePatch,
@@ -9013,7 +10008,7 @@ async function handleServer(req, res, method, deps) {
9013
10008
  });
9014
10009
  } catch (error) {
9015
10010
  if (error instanceof ServerConfigTransactionError) {
9016
- return writeJsonError(res, 500, error.message);
10011
+ return writeJsonError2(res, 500, error.message);
9017
10012
  }
9018
10013
  throw error;
9019
10014
  }
@@ -9034,24 +10029,27 @@ async function handleServer(req, res, method, deps) {
9034
10029
  ...merged,
9035
10030
  search: redactSearchServerConfig(merged.search)
9036
10031
  } : merged;
9037
- return writeJson4(res, 200, { server: projectImagesConfigForAdmin(mergedForAdmin) });
10032
+ return writeJson5(res, 200, { server: projectImagesConfigForAdmin(mergedForAdmin) });
9038
10033
  }
9039
- return writeJsonError(res, 405, `method ${method} not allowed on server`);
10034
+ return writeJsonError2(res, 405, `method ${method} not allowed on server`);
9040
10035
  }
9041
10036
  async function handleAccounts(req, res, method, rest, deps) {
9042
10037
  if (rest[0] === "route-activity" && rest.length === 1) {
9043
10038
  if (method !== "GET") {
9044
- return writeJsonError(res, 405, `method ${method} not allowed on account route activity`);
10039
+ return writeJsonError2(res, 405, `method ${method} not allowed on account route activity`);
9045
10040
  }
9046
10041
  const query2 = requestQuery(req);
9047
10042
  const parsedLimit = Number(query2.get("limit") ?? "100");
10043
+ const kindParam = query2.get("credentialKind");
10044
+ const credentialKind = kindParam === "subscription-account" || kindParam === "provider-key" ? kindParam : void 0;
9048
10045
  const records = getSharedAccountRouteActivity().list({
9049
10046
  providerId: query2.get("providerId") ?? void 0,
9050
10047
  accountId: query2.get("accountId") ?? void 0,
9051
10048
  sessionKey: query2.get("sessionKey") ?? void 0,
10049
+ credentialKind,
9052
10050
  limit: Number.isFinite(parsedLimit) ? parsedLimit : 100
9053
10051
  });
9054
- return writeJson4(res, 200, {
10052
+ return writeJson5(res, 200, {
9055
10053
  available: true,
9056
10054
  records,
9057
10055
  capacity: ACCOUNT_ROUTE_ACTIVITY_LIMIT,
@@ -9060,14 +10058,14 @@ async function handleAccounts(req, res, method, rest, deps) {
9060
10058
  }
9061
10059
  if (rest[0] === "overload-counters" && rest.length === 1) {
9062
10060
  if (method !== "GET") {
9063
- return writeJsonError(res, 405, `method ${method} not allowed on overload counters`);
10061
+ return writeJsonError2(res, 405, `method ${method} not allowed on overload counters`);
9064
10062
  }
9065
10063
  const query2 = requestQuery(req);
9066
10064
  const entries = getSharedOverloadCounter().list({
9067
10065
  providerId: query2.get("providerId") ?? void 0,
9068
10066
  accountId: query2.get("accountId") ?? void 0
9069
10067
  });
9070
- return writeJson4(res, 200, {
10068
+ return writeJson5(res, 200, {
9071
10069
  available: true,
9072
10070
  entries,
9073
10071
  collectedAt: Date.now()
@@ -9086,21 +10084,21 @@ async function handleAccounts(req, res, method, rest, deps) {
9086
10084
  const result = await handleAntigravityModelsRoute({
9087
10085
  resolveAntigravityAccessToken: deps.resolveAntigravityAccessToken ?? (async () => null)
9088
10086
  });
9089
- return writeJson4(res, result.status, result.body);
10087
+ return writeJson5(res, result.status, result.body);
9090
10088
  }
9091
10089
  if (method === "GET" && rest.length === 0) {
9092
10090
  const accounts = await deps.subscriptionAccounts.listAll();
9093
10091
  const providerAccounts = await deps.subscriptionTokenWriter.listSanitizedAccounts();
9094
10092
  const externalCli = await deps.subscriptionTokenWriter.listExternalCliAvailability();
9095
- return writeJson4(res, 200, { accounts, providerAccounts, externalCli });
10093
+ return writeJson5(res, 200, { accounts, providerAccounts, externalCli });
9096
10094
  }
9097
10095
  if (method === "POST" && rest[0] === "batch" && rest.length === 1) {
9098
- const body = await readJsonBody4(req);
10096
+ const body = await readJsonBody5(req);
9099
10097
  const parsed = validateAccountBatchBody(body);
9100
- if (!parsed) return writeJsonError(res, 400, "invalid account batch request");
10098
+ if (!parsed) return writeJsonError2(res, 400, "invalid account batch request");
9101
10099
  const result = await deps.subscriptionTokenWriter.batchManageAccounts(parsed.refs, parsed.mutation);
9102
10100
  if (!result.ok) {
9103
- return writeJsonError(
10101
+ return writeJsonError2(
9104
10102
  res,
9105
10103
  404,
9106
10104
  `account '${result.missing.accountId}' not found for provider '${result.missing.providerId}'`
@@ -9111,23 +10109,23 @@ async function handleAccounts(req, res, method, rest, deps) {
9111
10109
  deps.accountAllowanceService?.removeAccountSnapshot?.(ref.providerId, ref.accountId);
9112
10110
  }
9113
10111
  }
9114
- return writeJson4(res, 200, { ok: true, affected: result.affected });
10112
+ return writeJson5(res, 200, { ok: true, affected: result.affected });
9115
10113
  }
9116
10114
  if (method === "GET" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot" || rest[0] === "antigravity") && rest[1] === "oauth" && rest[3] === "status") {
9117
10115
  const result = rest[0] === "codex" ? handleCodexOAuthStatus(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthStatus(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthStatus(rest[2], deps) : rest[0] === "copilot" ? handleCopilotOAuthStatus(rest[2], deps) : handleAntigravityOAuthStatus(rest[2], deps);
9118
- return writeJson4(res, result.status, result.body);
10116
+ return writeJson5(res, result.status, result.body);
9119
10117
  }
9120
10118
  if (method === "DELETE" && (rest[0] === "codex" || rest[0] === "kimi" || rest[0] === "grok" || rest[0] === "copilot" || rest[0] === "antigravity") && rest[1] === "oauth" && rest[2]) {
9121
10119
  const result = rest[0] === "codex" ? handleCodexOAuthCancel(rest[2], deps) : rest[0] === "kimi" ? handleKimiOAuthCancel(rest[2], deps) : rest[0] === "grok" ? handleGrokOAuthCancel(rest[2], deps) : rest[0] === "copilot" ? handleCopilotOAuthCancel(rest[2], deps) : handleAntigravityOAuthCancel(rest[2], deps);
9122
- return writeJson4(res, result.status, result.body);
10120
+ return writeJson5(res, result.status, result.body);
9123
10121
  }
9124
10122
  if (method === "GET" && rest.length === 3 && rest[2] === "diagnostics") {
9125
10123
  const providerId = asSubscriptionProviderId(rest[0]);
9126
- if (!providerId) return writeJsonError(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
10124
+ if (!providerId) return writeJsonError2(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
9127
10125
  const accountId = rest[1];
9128
10126
  const listed = await deps.subscriptionTokenWriter.listSanitizedAccounts();
9129
10127
  if (!(listed[providerId] ?? []).some((account) => account.id === accountId)) {
9130
- return writeJsonError(res, 404, `account '${accountId}' not found`);
10128
+ return writeJsonError2(res, 404, `account '${accountId}' not found`);
9131
10129
  }
9132
10130
  const health2 = getSharedAccountHealth().getDiagnostics({ providerId, accountId });
9133
10131
  const allowance = deps.accountAllowanceService?.getSchedulingStatus?.()?.history.filter((entry) => entry.providerId === providerId && entry.accountId === accountId).map((entry) => ({
@@ -9141,88 +10139,88 @@ async function handleAccounts(req, res, method, rest, deps) {
9141
10139
  resumeAt: entry.resumeAt
9142
10140
  })) ?? [];
9143
10141
  const diagnostics = [...health2, ...allowance].sort((left, right) => right.at - left.at).slice(0, 200);
9144
- return writeJson4(res, 200, { diagnostics });
10142
+ return writeJson5(res, 200, { diagnostics });
9145
10143
  }
9146
10144
  if (method === "GET" && rest.length === 3 && rest[2] === "events") {
9147
10145
  const providerId = asSubscriptionProviderId(rest[0]);
9148
- if (!providerId) return writeJsonError(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
10146
+ if (!providerId) return writeJsonError2(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
9149
10147
  const accountId = rest[1];
9150
10148
  const listed = await deps.subscriptionTokenWriter.listSanitizedAccounts();
9151
10149
  if (!(listed[providerId] ?? []).some((account) => account.id === accountId)) {
9152
- return writeJsonError(res, 404, `account '${accountId}' not found`);
10150
+ return writeJsonError2(res, 404, `account '${accountId}' not found`);
9153
10151
  }
9154
10152
  const snapshot = deps.accountProbeService?.getAllHistory().find((entry) => entry.providerId === providerId && entry.accountId === accountId);
9155
10153
  const diagnostics = getSharedAccountHealth().getDiagnostics({ providerId, accountId });
9156
- return writeJson4(res, 200, { events: snapshot?.records ?? [], diagnostics });
10154
+ return writeJson5(res, 200, { events: snapshot?.records ?? [], diagnostics });
9157
10155
  }
9158
10156
  if (method === "PATCH" && rest.length === 2) {
9159
10157
  const providerId = asSubscriptionProviderId(rest[0]);
9160
- if (!providerId) return writeJsonError(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
9161
- const body = await readJsonBody4(req);
10158
+ if (!providerId) return writeJsonError2(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
10159
+ const body = await readJsonBody5(req);
9162
10160
  const patch = validateAccountMetadataPatch(body);
9163
- if (!patch) return writeJsonError(res, 400, "invalid account metadata patch");
10161
+ if (!patch) return writeJsonError2(res, 400, "invalid account metadata patch");
9164
10162
  const result = await deps.subscriptionTokenWriter.patchAccountMetadata(providerId, rest[1], patch);
9165
- if (!result.ok) return writeJsonError(res, 404, `account '${rest[1]}' not found`);
9166
- return writeJson4(res, 200, { ok: true });
10163
+ if (!result.ok) return writeJsonError2(res, 404, `account '${rest[1]}' not found`);
10164
+ return writeJson5(res, 200, { ok: true });
9167
10165
  }
9168
10166
  if (method === "PUT" || method === "POST" || method === "DELETE") {
9169
10167
  const providerId = asSubscriptionProviderId(rest[0]);
9170
10168
  if (!providerId) {
9171
- return writeJsonError(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
10169
+ return writeJsonError2(res, 400, `unknown subscription provider '${rest[0] ?? ""}'`);
9172
10170
  }
9173
10171
  if (method === "POST" && rest[1] === "oauth" && rest[2] === "start") {
9174
10172
  if (providerId === "codex") {
9175
10173
  const result2 = handleCodexOAuthStart(deps);
9176
- return writeJson4(res, result2.status, result2.body);
10174
+ return writeJson5(res, result2.status, result2.body);
9177
10175
  }
9178
10176
  if (providerId === "kimi") {
9179
10177
  const result2 = await handleKimiOAuthStart(deps);
9180
- return writeJson4(res, result2.status, result2.body);
10178
+ return writeJson5(res, result2.status, result2.body);
9181
10179
  }
9182
10180
  if (providerId === "grok") {
9183
10181
  const result2 = await handleGrokOAuthStart(deps);
9184
- return writeJson4(res, result2.status, result2.body);
10182
+ return writeJson5(res, result2.status, result2.body);
9185
10183
  }
9186
10184
  if (providerId === "copilot") {
9187
- const body2 = await readJsonBody4(req);
10185
+ const body2 = await readJsonBody5(req);
9188
10186
  const result2 = await handleCopilotOAuthStart(deps, body2["enterpriseUrl"]);
9189
- return writeJson4(res, result2.status, result2.body);
10187
+ return writeJson5(res, result2.status, result2.body);
9190
10188
  }
9191
10189
  if (providerId === "antigravity") {
9192
10190
  const result2 = handleAntigravityOAuthStart(deps);
9193
- return writeJson4(res, result2.status, result2.body);
10191
+ return writeJson5(res, result2.status, result2.body);
9194
10192
  }
9195
10193
  const result = handleOAuthStart(providerId, deps);
9196
- return writeJson4(res, result.status, result.body);
10194
+ return writeJson5(res, result.status, result.body);
9197
10195
  }
9198
10196
  if (method === "POST" && rest[1] === "oauth" && rest[2] === "complete") {
9199
- const body2 = await readJsonBody4(req);
10197
+ const body2 = await readJsonBody5(req);
9200
10198
  const result = await handleOAuthComplete(providerId, body2, deps);
9201
- return writeJson4(res, result.status, result.body);
10199
+ return writeJson5(res, result.status, result.body);
9202
10200
  }
9203
10201
  if (method === "POST" && rest[1] === "accounts") {
9204
- const body2 = await readJsonBody4(req);
10202
+ const body2 = await readJsonBody5(req);
9205
10203
  const block = validateTokenBody(providerId, body2);
9206
10204
  if (!block) {
9207
- return writeJsonError(res, 400, `malformed token body for provider '${providerId}'`);
10205
+ return writeJsonError2(res, 400, `malformed token body for provider '${providerId}'`);
9208
10206
  }
9209
10207
  const label = typeof body2["label"] === "string" && body2["label"].trim() ? body2["label"].trim() : void 0;
9210
10208
  await deps.subscriptionAccountAppender.appendProviderAccount(providerId, block, label);
9211
10209
  const status2 = await statusEntryFor(deps.subscriptionAccounts, providerId);
9212
- return writeJson4(res, 200, status2 ? { account: status2 } : { ok: true });
10210
+ return writeJson5(res, 200, status2 ? { account: status2 } : { ok: true });
9213
10211
  }
9214
10212
  if (method === "POST" && rest[1] === "import-external") {
9215
10213
  if (providerId !== "claude" && providerId !== "codex") {
9216
- return writeJsonError(res, 400, `provider '${providerId}' has no external CLI store`);
10214
+ return writeJsonError2(res, 400, `provider '${providerId}' has no external CLI store`);
9217
10215
  }
9218
- const body2 = await readJsonBody4(req);
10216
+ const body2 = await readJsonBody5(req);
9219
10217
  const label = typeof body2["label"] === "string" && body2["label"].trim() ? body2["label"].trim() : void 0;
9220
10218
  const result = await deps.subscriptionTokenWriter.importExternalCliAccount(providerId, label);
9221
10219
  if (!result.ok) {
9222
- return writeJsonError(res, 409, `no usable external ${providerId} CLI credential found`);
10220
+ return writeJsonError2(res, 409, `no usable external ${providerId} CLI credential found`);
9223
10221
  }
9224
10222
  const status2 = await statusEntryFor(deps.subscriptionAccounts, providerId);
9225
- return writeJson4(res, 200, {
10223
+ return writeJson5(res, 200, {
9226
10224
  ok: true,
9227
10225
  account: status2 ?? void 0,
9228
10226
  nativeCredentialMode: result.nativeCredentialMode,
@@ -9232,22 +10230,22 @@ async function handleAccounts(req, res, method, rest, deps) {
9232
10230
  }
9233
10231
  if (method === "POST" && rest[1] === "refresh") {
9234
10232
  if (providerId === "opencodego") {
9235
- return writeJsonError(res, 400, "opencodego credentials are not refreshable");
10233
+ return writeJsonError2(res, 400, "opencodego credentials are not refreshable");
9236
10234
  }
9237
10235
  const writer2 = deps.subscriptionTokenWriter;
9238
10236
  const ok = providerId === "claude" ? await writer2.refreshClaudeToken() : providerId === "codex" ? await writer2.refreshCodexToken() : await writer2.refreshGeminiToken();
9239
10237
  const status2 = await statusEntryFor(deps.subscriptionAccounts, providerId);
9240
- return writeJson4(res, 200, { ok, account: status2 ?? void 0 });
10238
+ return writeJson5(res, 200, { ok, account: status2 ?? void 0 });
9241
10239
  }
9242
10240
  if (method === "POST" && rest.length === 3 && rest[2] === "test") {
9243
10241
  const accountId = rest[1];
9244
- if (!deps.accountProbeService) return writeJsonError(res, 501, "account probe service unavailable");
10242
+ if (!deps.accountProbeService) return writeJsonError2(res, 501, "account probe service unavailable");
9245
10243
  const listed = await deps.subscriptionTokenWriter.listSanitizedAccounts();
9246
10244
  if (!(listed[providerId] ?? []).some((account) => account.id === accountId)) {
9247
- return writeJsonError(res, 404, `account '${accountId}' not found`);
10245
+ return writeJsonError2(res, 404, `account '${accountId}' not found`);
9248
10246
  }
9249
10247
  const result = await deps.accountProbeService.testAccountConnection(providerId, accountId);
9250
- return writeJson4(res, 200, {
10248
+ return writeJson5(res, 200, {
9251
10249
  ok: result.ok,
9252
10250
  marked: result.marked,
9253
10251
  tier: result.tier,
@@ -9256,176 +10254,189 @@ async function handleAccounts(req, res, method, rest, deps) {
9256
10254
  }
9257
10255
  if (method === "POST" && rest[2] === "label") {
9258
10256
  const accountId = rest[1];
9259
- const body2 = await readJsonBody4(req);
10257
+ const body2 = await readJsonBody5(req);
9260
10258
  const label = typeof body2["label"] === "string" ? body2["label"].trim() : "";
9261
10259
  const result = await deps.subscriptionTokenWriter.renameAccount(providerId, accountId, label);
9262
- if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
9263
- return writeJson4(res, 200, { ok: true });
10260
+ if (!result.ok) return writeJsonError2(res, 404, `account '${accountId}' not found`);
10261
+ return writeJson5(res, 200, { ok: true });
9264
10262
  }
9265
10263
  if (method === "POST" && rest[2] === "priority") {
9266
10264
  const accountId = rest[1];
9267
- const body2 = await readJsonBody4(req);
10265
+ const body2 = await readJsonBody5(req);
9268
10266
  const raw = body2["priority"];
9269
10267
  const priority = typeof raw === "number" ? raw : Number(raw);
9270
10268
  if (!Number.isFinite(priority)) {
9271
- return writeJsonError(res, 400, "priority must be a finite number");
10269
+ return writeJsonError2(res, 400, "priority must be a finite number");
9272
10270
  }
9273
10271
  const result = await deps.subscriptionTokenWriter.setAccountPriority(providerId, accountId, priority);
9274
- if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
9275
- return writeJson4(res, 200, { ok: true });
10272
+ if (!result.ok) return writeJsonError2(res, 404, `account '${accountId}' not found`);
10273
+ return writeJson5(res, 200, { ok: true });
9276
10274
  }
9277
10275
  if (method === "POST" && rest[2] === "proxy") {
9278
10276
  const accountId = rest[1];
9279
- const body2 = await readJsonBody4(req);
10277
+ const body2 = await readJsonBody5(req);
9280
10278
  const rawProxy = body2["proxy"];
9281
10279
  let proxy;
9282
10280
  if (rawProxy !== null && rawProxy !== void 0) {
9283
10281
  proxy = normalizeProxyConfig(rawProxy);
9284
- if (!proxy) return writeJsonError(res, 400, "invalid proxy config");
10282
+ if (!proxy) return writeJsonError2(res, 400, "invalid proxy config");
9285
10283
  }
9286
10284
  const result = await deps.subscriptionTokenWriter.setAccountProxy(providerId, accountId, proxy);
9287
- if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
9288
- return writeJson4(res, 200, { ok: true });
10285
+ if (!result.ok) return writeJsonError2(res, 404, `account '${accountId}' not found`);
10286
+ return writeJson5(res, 200, { ok: true });
9289
10287
  }
9290
10288
  if (method === "POST" && rest[2] === "supported-models") {
9291
10289
  const accountId = rest[1];
9292
- const body2 = await readJsonBody4(req);
10290
+ const body2 = await readJsonBody5(req);
9293
10291
  const parsed = validateSupportedModelsBody(body2["supportedModels"]);
9294
- if (!parsed.ok) return writeJsonError(res, 400, "invalid supportedModels");
10292
+ if (!parsed.ok) return writeJsonError2(res, 400, "invalid supportedModels");
9295
10293
  const result = await deps.subscriptionTokenWriter.setAccountSupportedModels(providerId, accountId, parsed.value);
9296
- if (!result.ok) return writeJsonError(res, 404, `account '${accountId}' not found`);
9297
- return writeJson4(res, 200, { ok: true });
10294
+ if (!result.ok) return writeJsonError2(res, 404, `account '${accountId}' not found`);
10295
+ return writeJson5(res, 200, { ok: true });
9298
10296
  }
9299
10297
  if (method === "PUT" && rest[1] === "active") {
9300
- const body2 = await readJsonBody4(req);
10298
+ const body2 = await readJsonBody5(req);
9301
10299
  const id = typeof body2["id"] === "string" ? body2["id"] : "";
9302
- if (!id) return writeJsonError(res, 400, "active switch requires { id }");
10300
+ if (!id) return writeJsonError2(res, 400, "active switch requires { id }");
9303
10301
  const result = await deps.subscriptionTokenWriter.setActiveAccount(providerId, id);
9304
- if (!result.ok) return writeJsonError(res, 404, `account '${id}' not found`);
9305
- return writeJson4(res, 200, { ok: true });
10302
+ if (!result.ok) return writeJsonError2(res, 404, `account '${id}' not found`);
10303
+ return writeJson5(res, 200, { ok: true });
9306
10304
  }
9307
10305
  if (method === "DELETE" && rest.length === 2) {
9308
10306
  const accountId = rest[1];
9309
10307
  const result = await deps.subscriptionTokenWriter.removeAccount(providerId, accountId);
9310
- if (!result.removed) return writeJsonError(res, 404, `account '${accountId}' not found`);
10308
+ if (!result.removed) return writeJsonError2(res, 404, `account '${accountId}' not found`);
9311
10309
  deps.accountAllowanceService?.removeAccountSnapshot?.(providerId, accountId);
9312
- return writeJson4(res, 200, { ok: true });
10310
+ return writeJson5(res, 200, { ok: true });
9313
10311
  }
9314
10312
  if (method === "DELETE" && rest.length === 1) {
9315
10313
  await deps.subscriptionTokenWriter.clearProvider(providerId);
9316
10314
  deps.accountAllowanceService?.removeProviderSnapshots?.(providerId);
9317
- return writeJson4(res, 200, { ok: true });
10315
+ return writeJson5(res, 200, { ok: true });
9318
10316
  }
9319
10317
  if (method === "DELETE") {
9320
- return writeJsonError(res, 405, "method DELETE not allowed on this accounts path");
10318
+ return writeJsonError2(res, 405, "method DELETE not allowed on this accounts path");
9321
10319
  }
9322
- const body = await readJsonBody4(req);
10320
+ const body = await readJsonBody5(req);
9323
10321
  const config = validateTokenBody(providerId, body);
9324
10322
  if (!config) {
9325
- return writeJsonError(res, 400, `malformed token body for provider '${providerId}'`);
10323
+ return writeJsonError2(res, 400, `malformed token body for provider '${providerId}'`);
9326
10324
  }
9327
10325
  await deps.subscriptionTokenWriter.writeProviderTokens(providerId, config);
9328
10326
  const status = await statusEntryFor(deps.subscriptionAccounts, providerId);
9329
- return writeJson4(res, 200, status ? { account: status } : { ok: true });
10327
+ return writeJson5(res, 200, status ? { account: status } : { ok: true });
9330
10328
  }
9331
- return writeJsonError(res, 405, `method ${method} not allowed on accounts`);
10329
+ return writeJsonError2(res, 405, `method ${method} not allowed on accounts`);
9332
10330
  }
9333
10331
  async function handleCli(req, res, method, rest, deps) {
9334
10332
  if (method === "GET" && rest.length === 0) {
9335
10333
  const result = handleCliList(process.platform, deps.cliPathProbe);
9336
- return writeJson4(res, result.status, result.body);
10334
+ return writeJson5(res, result.status, result.body);
9337
10335
  }
9338
10336
  if (method === "GET" && rest[0] === "sessions") {
9339
10337
  const result = handleCliSessions();
9340
- return writeJson4(res, result.status, result.body);
10338
+ return writeJson5(res, result.status, result.body);
9341
10339
  }
9342
10340
  if (method === "DELETE" && rest[0] === "sessions" && rest[1]) {
9343
10341
  const result = handleCliStop(rest[1]);
9344
- return writeJson4(res, result.status, result.body);
10342
+ return writeJson5(res, result.status, result.body);
9345
10343
  }
9346
10344
  if (method === "POST" && rest[1] === "install") {
9347
10345
  const cli = rest[0];
9348
10346
  if (!isLaunchCliId(cli)) {
9349
- return writeJsonError(res, 400, `unknown cli '${cli ?? ""}'`);
10347
+ return writeJsonError2(res, 400, `unknown cli '${cli ?? ""}'`);
9350
10348
  }
9351
10349
  const result = await handleCliInstall(cli, deps.cliCommandRunner);
9352
- return writeJson4(res, result.status, result.body);
10350
+ return writeJson5(res, result.status, result.body);
9353
10351
  }
9354
10352
  if (method === "POST" && rest[1] === "launch") {
9355
10353
  const cli = rest[0];
9356
10354
  if (!isLaunchCliId(cli)) {
9357
- return writeJsonError(res, 400, `unknown cli '${cli ?? ""}'`);
10355
+ return writeJsonError2(res, 400, `unknown cli '${cli ?? ""}'`);
9358
10356
  }
9359
- const body = await readJsonBody4(req);
10357
+ const body = await readJsonBody5(req);
9360
10358
  const providers = loadConfig(deps.configPath).providers ?? [];
10359
+ const codexAuthHelper = deps.codexAuthHelper;
10360
+ const keyScoped = codexAuthHelper ? await (async () => {
10361
+ const gateway = deps.outboundApiServer.getStatus();
10362
+ const serverConfig = await loadServerConfig3(deps.settingsStore);
10363
+ return {
10364
+ keyDb: deps.keyDb,
10365
+ bindings: serverConfig.bindings ?? [],
10366
+ gatewayRunning: gateway.running,
10367
+ gatewayBaseUrl: gateway.loopbackUrl ?? `http://127.0.0.1:${gateway.port}`,
10368
+ codexAuthHelper
10369
+ };
10370
+ })() : void 0;
9361
10371
  const result = await handleCliLaunch(cli, body, {
9362
10372
  llmConfig: deps.llmConfig,
9363
10373
  providers,
9364
10374
  routeLeaseManager: deps.routeLeaseManager,
10375
+ keyScoped,
9365
10376
  opener: deps.cliTerminalOpener,
9366
10377
  probe: deps.cliPathProbe
9367
10378
  });
9368
- return writeJson4(res, result.status, result.body);
10379
+ return writeJson5(res, result.status, result.body);
9369
10380
  }
9370
- return writeJsonError(res, 405, `method ${method} not allowed on cli`);
10381
+ return writeJsonError2(res, 405, `method ${method} not allowed on cli`);
9371
10382
  }
9372
10383
  async function handleIntegrations(req, res, method, rest, deps) {
9373
10384
  const factory = deps.integrationManagerFactory;
9374
- if (!factory) return writeJsonError(res, 501, "native CLI integration is not available");
10385
+ if (!factory) return writeJsonError2(res, 501, "native CLI integration is not available");
9375
10386
  const manager = factory();
9376
10387
  try {
9377
10388
  if (method === "GET" && rest.length === 0) {
9378
- return writeJson4(res, 200, {
10389
+ return writeJson5(res, 200, {
9379
10390
  integrations: await manager.listStatus(),
9380
10391
  gateway: deps.outboundApiServer.getStatus()
9381
10392
  });
9382
10393
  }
9383
10394
  if (method === "POST" && rest.length === 1 && rest[0] === "rotate") {
9384
10395
  await manager.rotateGatewayKey();
9385
- return writeJson4(res, 200, { ok: true, integrations: await manager.listStatus() });
10396
+ return writeJson5(res, 200, { ok: true, integrations: await manager.listStatus() });
9386
10397
  }
9387
10398
  const client = rest[0];
9388
10399
  if (!isIntegrationClient(client)) {
9389
- return writeJsonError(res, 400, `unknown integration client '${client ?? ""}'`);
10400
+ return writeJsonError2(res, 400, `unknown integration client '${client ?? ""}'`);
9390
10401
  }
9391
10402
  if (method === "POST" && rest[1] === "key") {
9392
- const body = await readJsonBody4(req);
10403
+ const body = await readJsonBody5(req);
9393
10404
  if (Object.keys(body).length !== 1 || typeof body.keyId !== "string" || !body.keyId.trim()) {
9394
- return writeJsonError(res, 400, "body must contain a non-empty keyId string");
10405
+ return writeJsonError2(res, 400, "body must contain a non-empty keyId string");
9395
10406
  }
9396
10407
  const status = await manager.bindIntegrationKey(client, body.keyId.trim());
9397
- return writeJson4(res, 200, { integration: status });
10408
+ return writeJson5(res, 200, { integration: status });
9398
10409
  }
9399
10410
  if (method === "POST" && rest[1] === "plan") {
9400
- const body = await readJsonBody4(req);
10411
+ const body = await readJsonBody5(req);
9401
10412
  const configPath = body.configPath;
9402
10413
  if (configPath !== void 0 && typeof configPath !== "string") {
9403
- return writeJsonError(res, 400, "configPath must be a string");
10414
+ return writeJsonError2(res, 400, "configPath must be a string");
9404
10415
  }
9405
10416
  const plan = await manager.plan(client, configPath);
9406
- return writeJson4(res, 200, { plan });
10417
+ return writeJson5(res, 200, { plan });
9407
10418
  }
9408
10419
  if (method === "POST" && (rest[1] === "install" || rest[1] === "apply")) {
9409
- const body = await readJsonBody4(req);
10420
+ const body = await readJsonBody5(req);
9410
10421
  const configPath = body.configPath;
9411
10422
  if (configPath !== void 0 && typeof configPath !== "string") {
9412
- return writeJsonError(res, 400, "configPath must be a string");
10423
+ return writeJsonError2(res, 400, "configPath must be a string");
9413
10424
  }
9414
10425
  const status = await manager.install(client, configPath);
9415
- return writeJson4(res, 200, { integration: status });
10426
+ return writeJson5(res, 200, { integration: status });
9416
10427
  }
9417
10428
  if (method === "POST" && rest[1] === "repair") {
9418
10429
  const status = await manager.repair(client);
9419
- return writeJson4(res, 200, { integration: status });
10430
+ return writeJson5(res, 200, { integration: status });
9420
10431
  }
9421
10432
  if (method === "DELETE" && rest.length === 1 || method === "POST" && rest[1] === "remove") {
9422
10433
  const status = await manager.remove(client);
9423
- return writeJson4(res, 200, { integration: status });
10434
+ return writeJson5(res, 200, { integration: status });
9424
10435
  }
9425
- return writeJsonError(res, 405, `method ${method} not allowed on integrations`);
10436
+ return writeJsonError2(res, 405, `method ${method} not allowed on integrations`);
9426
10437
  } catch (error) {
9427
10438
  if (error instanceof IntegrationConflictError) {
9428
- return writeJsonError(res, 409, error.message);
10439
+ return writeJsonError2(res, 409, error.message);
9429
10440
  }
9430
10441
  throw error;
9431
10442
  }
@@ -9568,7 +10579,7 @@ function imageProviderEvidence(images, capabilities) {
9568
10579
  async function handleImagesVerifyLive(req, res, deps) {
9569
10580
  const verifier = deps.imageLiveVerifier;
9570
10581
  if (!verifier) {
9571
- return writeJsonError(res, 501, "Images live verification is not available");
10582
+ return writeJsonError2(res, 501, "Images live verification is not available");
9572
10583
  }
9573
10584
  const serverConfig = await loadServerConfig3(deps.settingsStore);
9574
10585
  const images = serverConfig.images ?? DEFAULT_IMAGES_SERVER_CONFIG;
@@ -9577,7 +10588,7 @@ async function handleImagesVerifyLive(req, res, deps) {
9577
10588
  req.on("close", () => controller.abort());
9578
10589
  const result = await verifier.verifyLive(images, controller.signal);
9579
10590
  const antigravityRouted = Object.values(images.models).includes("antigravity-subscription");
9580
- return writeJson4(res, 200, {
10591
+ return writeJson5(res, 200, {
9581
10592
  ...result,
9582
10593
  ...antigravityRouted ? { antigravityDeferred: true } : {}
9583
10594
  });
@@ -9585,18 +10596,18 @@ async function handleImagesVerifyLive(req, res, deps) {
9585
10596
  async function handleImages(req, res, method, rest, deps) {
9586
10597
  if (rest.length === 1 && rest[0] === "verify-live") {
9587
10598
  if (method !== "POST") {
9588
- return writeJsonError(res, 405, `method ${method} not allowed on Images verify-live`);
10599
+ return writeJsonError2(res, 405, `method ${method} not allowed on Images verify-live`);
9589
10600
  }
9590
10601
  return handleImagesVerifyLive(req, res, deps);
9591
10602
  }
9592
10603
  if (rest.length !== 1 || rest[0] !== "capabilities") {
9593
- return writeJsonError(res, 404, "unknown Images admin resource");
10604
+ return writeJsonError2(res, 404, "unknown Images admin resource");
9594
10605
  }
9595
10606
  if (method !== "GET") {
9596
- return writeJsonError(res, 405, `method ${method} not allowed on Images capabilities`);
10607
+ return writeJsonError2(res, 405, `method ${method} not allowed on Images capabilities`);
9597
10608
  }
9598
10609
  const reader = deps.imageRuntimeStatus;
9599
- if (!reader) return writeJsonError(res, 501, "Images runtime status is not available");
10610
+ if (!reader) return writeJsonError2(res, 501, "Images runtime status is not available");
9600
10611
  const serverConfig = await loadServerConfig3(deps.settingsStore);
9601
10612
  const images = serverConfig.images ?? DEFAULT_IMAGES_SERVER_CONFIG;
9602
10613
  const lifecycle = reader.status();
@@ -9617,7 +10628,7 @@ async function handleImages(req, res, method, rest, deps) {
9617
10628
  httpLeases: safeStatusCount(generation.httpLeases),
9618
10629
  hostedLeases: safeStatusCount(generation.hostedLeases)
9619
10630
  }));
9620
- return writeJson4(res, 200, {
10631
+ return writeJson5(res, 200, {
9621
10632
  configured: {
9622
10633
  enabled: images.enabled,
9623
10634
  provider: images.models[images.defaultModel] ?? "codex-subscription",
@@ -9644,7 +10655,7 @@ async function handleImages(req, res, method, rest, deps) {
9644
10655
  });
9645
10656
  }
9646
10657
  async function handleStatus(res, method, deps) {
9647
- if (method !== "GET") return writeJsonError(res, 405, `method ${method} not allowed on status`);
10658
+ if (method !== "GET") return writeJsonError2(res, 405, `method ${method} not allowed on status`);
9648
10659
  const status = deps.outboundApiServer.getStatus();
9649
10660
  const serverConfig = await loadServerConfig3(deps.settingsStore);
9650
10661
  const endpoints = ["chat", "responses", "messages", "gemini"].map((endpoint) => {
@@ -9684,14 +10695,14 @@ async function handleStatus(res, method, deps) {
9684
10695
  })() : void 0;
9685
10696
  if (status.running) {
9686
10697
  const queueStatus = deps.outboundApiServer.getQueueStatus();
9687
- return writeJson4(res, 200, {
10698
+ return writeJson5(res, 200, {
9688
10699
  ...status,
9689
10700
  endpoints,
9690
10701
  queueStatus,
9691
10702
  ...imageRuntime ? { imageRuntime } : {}
9692
10703
  });
9693
10704
  }
9694
- return writeJson4(res, 200, {
10705
+ return writeJson5(res, 200, {
9695
10706
  ...status,
9696
10707
  endpoints,
9697
10708
  ...imageRuntime ? { imageRuntime } : {}
@@ -9714,23 +10725,23 @@ function resolvePlaygroundPath(endpoint, body) {
9714
10725
  }
9715
10726
  }
9716
10727
  async function handlePlayground(req, res, method, deps) {
9717
- if (method !== "POST") return writeJsonError(res, 405, `method ${method} not allowed on playground`);
9718
- const body = await readJsonBody4(req);
10728
+ if (method !== "POST") return writeJsonError2(res, 405, `method ${method} not allowed on playground`);
10729
+ const body = await readJsonBody5(req);
9719
10730
  const endpoint = typeof body["endpoint"] === "string" ? body["endpoint"] : "";
9720
10731
  const key = typeof body["key"] === "string" ? body["key"] : "";
9721
10732
  const payload = body["body"];
9722
10733
  const status = deps.outboundApiServer.getStatus();
9723
- if (!status.running || !status.port) return writeJsonError(res, 503, "outbound server not running");
9724
- const path2 = resolvePlaygroundPath(endpoint, isRecord9(payload) ? payload : {});
9725
- if (!path2) return writeJsonError(res, 400, `unknown endpoint '${endpoint}'`);
10734
+ if (!status.running || !status.port) return writeJsonError2(res, 503, "outbound server not running");
10735
+ const path2 = resolvePlaygroundPath(endpoint, isRecord11(payload) ? payload : {});
10736
+ if (!path2) return writeJsonError2(res, 400, `unknown endpoint '${endpoint}'`);
9726
10737
  const upstreamBody = typeof payload === "string" ? payload : JSON.stringify(payload ?? {});
9727
10738
  await proxyToOutbound(res, status.port, path2, key, upstreamBody);
9728
10739
  }
9729
- function isRecord9(v) {
10740
+ function isRecord11(v) {
9730
10741
  return !!v && typeof v === "object" && !Array.isArray(v);
9731
10742
  }
9732
10743
  function proxyToOutbound(res, outboundPort, path2, key, body) {
9733
- return new Promise((resolve10) => {
10744
+ return new Promise((resolve11) => {
9734
10745
  const upstream = http.request(
9735
10746
  {
9736
10747
  host: "127.0.0.1",
@@ -9751,14 +10762,14 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
9751
10762
  proxRes.on("data", (chunk) => res.write(chunk));
9752
10763
  proxRes.on("end", () => {
9753
10764
  res.end();
9754
- resolve10();
10765
+ resolve11();
9755
10766
  });
9756
10767
  }
9757
10768
  );
9758
10769
  upstream.on("error", (err9) => {
9759
- if (!res.headersSent) writeJsonError(res, 502, `playground proxy failed: ${err9.message}`);
10770
+ if (!res.headersSent) writeJsonError2(res, 502, `playground proxy failed: ${err9.message}`);
9760
10771
  else res.end();
9761
- resolve10();
10772
+ resolve11();
9762
10773
  });
9763
10774
  upstream.write(body);
9764
10775
  upstream.end();
@@ -9766,8 +10777,8 @@ function proxyToOutbound(res, outboundPort, path2, key, body) {
9766
10777
  }
9767
10778
 
9768
10779
  // src/admin/uiStatic.ts
9769
- import { existsSync as existsSync7, statSync as statSync3 } from "fs";
9770
- import { readFile } from "fs/promises";
10780
+ import { existsSync as existsSync8, statSync as statSync3 } from "fs";
10781
+ import { readFile as readFile2 } from "fs/promises";
9771
10782
  import { createRequire } from "module";
9772
10783
  import path from "path";
9773
10784
  var CONTENT_TYPES = {
@@ -9789,13 +10800,13 @@ var CONTENT_TYPES = {
9789
10800
  function resolveUiDist() {
9790
10801
  const fromEnv = process.env["OMNICROSS_UI_DIST"];
9791
10802
  if (fromEnv) {
9792
- return existsSync7(path.join(fromEnv, "index.html")) ? path.resolve(fromEnv) : null;
10803
+ return existsSync8(path.join(fromEnv, "index.html")) ? path.resolve(fromEnv) : null;
9793
10804
  }
9794
10805
  try {
9795
10806
  const req = createRequire(typeof __filename !== "undefined" ? __filename : import.meta.url);
9796
10807
  const pkgJson = req.resolve("@omnicross/ui/package.json");
9797
10808
  const dist = path.join(path.dirname(pkgJson), "dist");
9798
- return existsSync7(path.join(dist, "index.html")) ? dist : null;
10809
+ return existsSync8(path.join(dist, "index.html")) ? dist : null;
9799
10810
  } catch {
9800
10811
  return null;
9801
10812
  }
@@ -9844,7 +10855,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
9844
10855
  return true;
9845
10856
  }
9846
10857
  let target = filePath;
9847
- if (!existsSync7(target) || statSync3(target).isDirectory()) {
10858
+ if (!existsSync8(target) || statSync3(target).isDirectory()) {
9848
10859
  if (path.extname(rel) === "") {
9849
10860
  target = path.join(uiDist, "index.html");
9850
10861
  } else {
@@ -9853,7 +10864,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
9853
10864
  return true;
9854
10865
  }
9855
10866
  }
9856
- const body = await readFile(target);
10867
+ const body = await readFile2(target);
9857
10868
  const type = CONTENT_TYPES[path.extname(target).toLowerCase()] ?? "application/octet-stream";
9858
10869
  res.writeHead(200, { "Content-Type": type, "Content-Length": body.length });
9859
10870
  res.end(req.method === "HEAD" ? void 0 : body);
@@ -9861,7 +10872,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
9861
10872
  }
9862
10873
 
9863
10874
  // src/admin/version.ts
9864
- var DAEMON_VERSION = true ? "0.4.4" : "0.0.0-dev";
10875
+ var DAEMON_VERSION = true ? "0.4.6" : "0.0.0-dev";
9865
10876
 
9866
10877
  // src/admin/AdminServer.ts
9867
10878
  var LOOPBACK_ADDR = "127.0.0.1";
@@ -9900,14 +10911,14 @@ var AdminServer = class {
9900
10911
  }
9901
10912
  /** Bind once; on EADDRINUSE retry with an ephemeral port (port 0). */
9902
10913
  listen(bindAddr, port) {
9903
- return new Promise((resolve10, reject) => {
10914
+ return new Promise((resolve11, reject) => {
9904
10915
  const server = http2.createServer((req, res) => {
9905
10916
  this.onRequest(req, res);
9906
10917
  });
9907
10918
  const onError = (err9) => {
9908
10919
  if (err9.code === "EADDRINUSE" && port !== 0) {
9909
10920
  server.removeListener("error", onError);
9910
- this.listen(bindAddr, 0).then(resolve10, reject);
10921
+ this.listen(bindAddr, 0).then(resolve11, reject);
9911
10922
  return;
9912
10923
  }
9913
10924
  reject(err9);
@@ -9919,7 +10930,7 @@ var AdminServer = class {
9919
10930
  server.removeListener("error", onError);
9920
10931
  server.on("error", (e) => this.deps.logger.error("[AdminServer] server error", e));
9921
10932
  this.server = server;
9922
- resolve10(addr.port);
10933
+ resolve11(addr.port);
9923
10934
  } else {
9924
10935
  reject(new Error("Failed to get admin server address"));
9925
10936
  }
@@ -9993,6 +11004,10 @@ var AdminServer = class {
9993
11004
  await handleRouteLeaseApi(req, res, path2, this.deps);
9994
11005
  return;
9995
11006
  }
11007
+ if (path2 === "/admin/api/codex-sessions" || path2 === "/admin/api/codex-sessions/preview" || path2 === "/admin/api/codex-sessions/apply") {
11008
+ await handleCodexSessionApi(req, res, path2, this.deps.codexSessionManager);
11009
+ return;
11010
+ }
9996
11011
  if (path2.startsWith("/admin/api/")) {
9997
11012
  await handleAdminApi(req, res, path2, this.deps);
9998
11013
  return;
@@ -10016,8 +11031,8 @@ var AdminServer = class {
10016
11031
  if (!server) return;
10017
11032
  this.server = null;
10018
11033
  this.boundPort = 0;
10019
- return new Promise((resolve10) => {
10020
- server.close(() => resolve10());
11034
+ return new Promise((resolve11) => {
11035
+ server.close(() => resolve11());
10021
11036
  });
10022
11037
  }
10023
11038
  /** A live status snapshot. */
@@ -10156,7 +11171,7 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal
10156
11171
  const port = binding.port ?? LOOPBACK_PORT;
10157
11172
  const callbackPath = binding.path ?? CALLBACK_PATH;
10158
11173
  const label = binding.label ?? "codex";
10159
- return new Promise((resolve10, reject) => {
11174
+ return new Promise((resolve11, reject) => {
10160
11175
  let settled = false;
10161
11176
  const finish = (server2, fn) => {
10162
11177
  if (settled) return;
@@ -10188,7 +11203,7 @@ function awaitLoopbackCode(expectedState, timeoutMs = DEFAULT_TIMEOUT_MS, signal
10188
11203
  }
10189
11204
  res.writeHead(200, HTML_HEADERS);
10190
11205
  res.end(pageHtml("Login complete."));
10191
- finish(server, () => resolve10(code));
11206
+ finish(server, () => resolve11(code));
10192
11207
  });
10193
11208
  const abort = () => finish(server, () => reject(new Error("login: cancelled")));
10194
11209
  if (signal?.aborted) {
@@ -10317,7 +11332,7 @@ function secondsUntil9(instant, now) {
10317
11332
  if (!instant) return void 0;
10318
11333
  return Math.max(0, Math.floor((Date.parse(instant) - now) / 1e3));
10319
11334
  }
10320
- function isRecord10(value) {
11335
+ function isRecord12(value) {
10321
11336
  return !!value && typeof value === "object" && !Array.isArray(value);
10322
11337
  }
10323
11338
  function detectProviderKeyQuotaAdapter(baseUrl) {
@@ -10384,17 +11399,17 @@ function zaiWindowIdLabel(durationMs) {
10384
11399
  return { id: "quota", label: "Quota" };
10385
11400
  }
10386
11401
  function parseZaiQuotaPayload(payload, now) {
10387
- if (!isRecord10(payload)) return null;
10388
- const data = isRecord10(payload["data"]) ? payload["data"] : payload;
11402
+ if (!isRecord12(payload)) return null;
11403
+ const data = isRecord12(payload["data"]) ? payload["data"] : payload;
10389
11404
  if (payload["success"] === false) return null;
10390
11405
  const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
10391
11406
  const byWindow = /* @__PURE__ */ new Map();
10392
11407
  for (const raw of limits) {
10393
- if (!isRecord10(raw)) continue;
11408
+ if (!isRecord12(raw)) continue;
10394
11409
  const item = raw;
10395
11410
  if (item.type === void 0) continue;
10396
11411
  const details = raw["usageDetails"];
10397
- if (Array.isArray(details) && details.some((d) => isRecord10(d) && d["modelCode"] === "zread")) {
11412
+ if (Array.isArray(details) && details.some((d) => isRecord12(d) && d["modelCode"] === "zread")) {
10398
11413
  continue;
10399
11414
  }
10400
11415
  const durationMs = zaiWindowDurationMs(item);
@@ -10427,7 +11442,7 @@ function parseZaiQuotaPayload(payload, now) {
10427
11442
  var MINIMAX_STATUS_EXHAUSTED = 2;
10428
11443
  var MINIMAX_SHARED_BUCKET = "general";
10429
11444
  function parseMiniMaxBucket(value) {
10430
- if (!isRecord10(value)) return null;
11445
+ if (!isRecord12(value)) return null;
10431
11446
  const modelName = typeof value["model_name"] === "string" ? value["model_name"].trim() : "";
10432
11447
  if (!modelName) return null;
10433
11448
  const instant = (v) => {
@@ -10459,9 +11474,9 @@ function minimaxWindow(id, label, windowMinutes, resetsAtMs, remainingPercent, s
10459
11474
  };
10460
11475
  }
10461
11476
  function parseMiniMaxTokenPlanPayload(payload, now) {
10462
- if (!isRecord10(payload)) return null;
11477
+ if (!isRecord12(payload)) return null;
10463
11478
  const baseResp = payload["base_resp"];
10464
- if (!isRecord10(baseResp) || baseResp["status_code"] !== 0) return null;
11479
+ if (!isRecord12(baseResp) || baseResp["status_code"] !== 0) return null;
10465
11480
  const buckets = Array.isArray(payload["model_remains"]) ? payload["model_remains"] : [];
10466
11481
  let general = null;
10467
11482
  for (const raw of buckets) {
@@ -10494,11 +11509,11 @@ function parseMiniMaxTokenPlanPayload(payload, now) {
10494
11509
  ];
10495
11510
  }
10496
11511
  function parseUmansUsagePayload(payload, now) {
10497
- if (!isRecord10(payload)) return null;
10498
- const limits = isRecord10(payload["limits"]) ? payload["limits"] : void 0;
10499
- const requests = limits && isRecord10(limits["requests"]) ? limits["requests"] : void 0;
10500
- const usage = isRecord10(payload["usage"]) ? payload["usage"] : void 0;
10501
- const window = isRecord10(payload["window"]) ? payload["window"] : void 0;
11512
+ if (!isRecord12(payload)) return null;
11513
+ const limits = isRecord12(payload["limits"]) ? payload["limits"] : void 0;
11514
+ const requests = limits && isRecord12(limits["requests"]) ? limits["requests"] : void 0;
11515
+ const usage = isRecord12(payload["usage"]) ? payload["usage"] : void 0;
11516
+ const window = isRecord12(payload["window"]) ? payload["window"] : void 0;
10502
11517
  const hardCap = finiteNumber5(requests?.["hard_cap"]);
10503
11518
  const softLimit = finiteNumber5(requests?.["limit"]);
10504
11519
  const requestsInWindow = finiteNumber5(usage?.["requests_in_window"]);
@@ -10525,9 +11540,9 @@ function parseUmansUsagePayload(payload, now) {
10525
11540
  ];
10526
11541
  }
10527
11542
  function parseSyntheticQuotasPayload(payload, now) {
10528
- if (!isRecord10(payload)) return null;
10529
- const fiveHour = isRecord10(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
10530
- const weekly = isRecord10(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
11543
+ if (!isRecord12(payload)) return null;
11544
+ const fiveHour = isRecord12(payload["rollingFiveHourLimit"]) ? payload["rollingFiveHourLimit"] : void 0;
11545
+ const weekly = isRecord12(payload["weeklyTokenLimit"]) ? payload["weeklyTokenLimit"] : void 0;
10531
11546
  const windows = [];
10532
11547
  if (fiveHour) {
10533
11548
  const max = finiteNumber5(fiveHour["max"]);
@@ -10568,12 +11583,12 @@ var CLINE_WINDOW_CONFIG = {
10568
11583
  monthly: { id: "thirty-day", label: "30 days", minutes: 30 * 24 * 60 }
10569
11584
  };
10570
11585
  function parseClinePassUsageLimitsPayload(payload, now) {
10571
- if (!isRecord10(payload)) return null;
10572
- const data = isRecord10(payload["data"]) ? payload["data"] : payload;
11586
+ if (!isRecord12(payload)) return null;
11587
+ const data = isRecord12(payload["data"]) ? payload["data"] : payload;
10573
11588
  const limits = Array.isArray(data["limits"]) ? data["limits"] : [];
10574
11589
  const windows = [];
10575
11590
  for (const raw of limits) {
10576
- if (!isRecord10(raw)) continue;
11591
+ if (!isRecord12(raw)) continue;
10577
11592
  const config = CLINE_WINDOW_CONFIG[typeof raw["type"] === "string" ? raw["type"] : ""];
10578
11593
  if (!config) continue;
10579
11594
  const usedPercent = finitePercent4(raw["percentUsed"]);
@@ -10726,36 +11741,36 @@ var ProviderKeyQuotaService = class {
10726
11741
  };
10727
11742
 
10728
11743
  // src/commands/paths.ts
10729
- import { dirname as dirname5, join as join5 } from "path";
11744
+ import { dirname as dirname5, join as join6 } from "path";
10730
11745
  function defaultVouchersPath(configPath) {
10731
- return join5(dirname5(configPath), "vouchers.json");
11746
+ return join6(dirname5(configPath), "vouchers.json");
10732
11747
  }
10733
11748
  function defaultIntegrationsPath(configPath) {
10734
- return join5(dirname5(configPath), "integrations.json");
11749
+ return join6(dirname5(configPath), "integrations.json");
10735
11750
  }
10736
11751
  function defaultPricingPath(configPath) {
10737
- return join5(dirname5(configPath), "pricing.json");
11752
+ return join6(dirname5(configPath), "pricing.json");
10738
11753
  }
10739
11754
  function defaultPricingRefreshStatePath(configPath) {
10740
- return join5(dirname5(configPath), "pricing-refresh.json");
11755
+ return join6(dirname5(configPath), "pricing-refresh.json");
10741
11756
  }
10742
11757
  function defaultAccountAllowancePath(configPath) {
10743
- return join5(dirname5(configPath), "allowance-cache.json");
11758
+ return join6(dirname5(configPath), "allowance-cache.json");
10744
11759
  }
10745
11760
  function defaultUsageEventsPath(configPath) {
10746
- return join5(dirname5(configPath), "usage-events.jsonl");
11761
+ return join6(dirname5(configPath), "usage-events.jsonl");
10747
11762
  }
10748
11763
  function defaultLogDir(configPath) {
10749
- return join5(dirname5(configPath), "logs");
11764
+ return join6(dirname5(configPath), "logs");
10750
11765
  }
10751
11766
  function defaultDaemonLogPath(configPath) {
10752
- return join5(defaultLogDir(configPath), "daemon.log");
11767
+ return join6(defaultLogDir(configPath), "daemon.log");
10753
11768
  }
10754
11769
  function defaultAuditDir(configPath) {
10755
- return join5(dirname5(configPath), "audit");
11770
+ return join6(dirname5(configPath), "audit");
10756
11771
  }
10757
11772
  function defaultBillingDir(configPath) {
10758
- return join5(dirname5(configPath), "billing");
11773
+ return join6(dirname5(configPath), "billing");
10759
11774
  }
10760
11775
 
10761
11776
  // src/image-generation/ImageDoctorService.ts
@@ -10775,7 +11790,7 @@ import { createHmac as createHmac2, randomBytes as randomBytes5 } from "crypto";
10775
11790
  import {
10776
11791
  chmodSync as chmodSync6,
10777
11792
  closeSync as closeSync2,
10778
- existsSync as existsSync9,
11793
+ existsSync as existsSync10,
10779
11794
  fsyncSync as fsyncSync2,
10780
11795
  lstatSync as lstatSync3,
10781
11796
  openSync as openSync2,
@@ -10784,7 +11799,7 @@ import {
10784
11799
  unlinkSync as unlinkSync4,
10785
11800
  writeFileSync as writeFileSync7
10786
11801
  } from "fs";
10787
- import { basename as basename2, dirname as dirname6, join as join7, resolve as resolve4 } from "path";
11802
+ import { basename as basename3, dirname as dirname6, join as join8, resolve as resolve5 } from "path";
10788
11803
  import { IMAGE_SERVER_HARD_CEILINGS } from "@omnicross/core/outbound-api";
10789
11804
 
10790
11805
  // src/image-generation/imageTenantHmac.ts
@@ -10793,7 +11808,7 @@ import {
10793
11808
  chmodSync as chmodSync5,
10794
11809
  closeSync,
10795
11810
  constants,
10796
- existsSync as existsSync8,
11811
+ existsSync as existsSync9,
10797
11812
  fstatSync,
10798
11813
  fsyncSync,
10799
11814
  lstatSync as lstatSync2,
@@ -10801,7 +11816,7 @@ import {
10801
11816
  readFileSync as readFileSync6,
10802
11817
  writeFileSync as writeFileSync6
10803
11818
  } from "fs";
10804
- import { join as join6 } from "path";
11819
+ import { join as join7 } from "path";
10805
11820
  var TENANT_SALT_NAME = "tenant-hmac-salt.v1.bin";
10806
11821
  var TENANT_KEY_PATTERN = /^[a-f0-9]{64}$/u;
10807
11822
  var REFERENCE_DOMAIN = Buffer.from("omnicross:image-reference:tenant:v1\0", "utf8");
@@ -10819,8 +11834,8 @@ function deriveImageTenantHmac(salt, purpose, tenantId) {
10819
11834
  }
10820
11835
  function loadOrCreateImageTenantHmacSalt(paths, random) {
10821
11836
  const root = paths.verifiedRoot("mountManifest");
10822
- const path2 = join6(root, TENANT_SALT_NAME);
10823
- if (!existsSync8(path2)) {
11837
+ const path2 = join7(root, TENANT_SALT_NAME);
11838
+ if (!existsSync9(path2)) {
10824
11839
  const salt = random(32);
10825
11840
  if (salt.byteLength !== 32) throw new TypeError("image tenant HMAC salt generator returned invalid bytes");
10826
11841
  let fd2;
@@ -10925,8 +11940,8 @@ function validateObservation(value) {
10925
11940
  }
10926
11941
  }
10927
11942
  function samePath2(left, right) {
10928
- const a = resolve4(left);
10929
- const b = resolve4(right);
11943
+ const a = resolve5(left);
11944
+ const b = resolve5(right);
10930
11945
  return process.platform === "win32" ? a.toLowerCase() === b.toLowerCase() : a === b;
10931
11946
  }
10932
11947
  function capabilityValues(entry) {
@@ -10988,7 +12003,7 @@ var FileCodexImageCapabilityEvidenceManifestOwner = class {
10988
12003
  this.#replaceManifest = options.replaceManifest ?? ((target, contents) => {
10989
12004
  this.#atomicReplace(target, contents);
10990
12005
  });
10991
- if (existsSync9(this.#manifestPath())) this.#load();
12006
+ if (existsSync10(this.#manifestPath())) this.#load();
10992
12007
  }
10993
12008
  createSource(ttlMs) {
10994
12009
  return new FileCodexImageCapabilityEvidenceSource({ owner: this, ttlMs });
@@ -11100,7 +12115,7 @@ var FileCodexImageCapabilityEvidenceManifestOwner = class {
11100
12115
  return Math.min(entry.expiresAt, entry.verifiedAt + ttlMs);
11101
12116
  }
11102
12117
  #manifestPath() {
11103
- return join7(this.#paths.verifiedRoot("evidence"), MANIFEST_NAME);
12118
+ return join8(this.#paths.verifiedRoot("evidence"), MANIFEST_NAME);
11104
12119
  }
11105
12120
  #serialized(entries, revision) {
11106
12121
  const manifest = {
@@ -11145,15 +12160,15 @@ var FileCodexImageCapabilityEvidenceManifestOwner = class {
11145
12160
  this.#entries = entries;
11146
12161
  }
11147
12162
  #refresh() {
11148
- if (!existsSync9(this.#manifestPath())) return;
12163
+ if (!existsSync10(this.#manifestPath())) return;
11149
12164
  this.#load();
11150
12165
  }
11151
12166
  #atomicReplace(targetPath, contents) {
11152
12167
  const root = this.#paths.verifiedRoot("evidence");
11153
- if (!samePath2(dirname6(resolve4(targetPath)), root) || basename2(targetPath) !== MANIFEST_NAME) {
12168
+ if (!samePath2(dirname6(resolve5(targetPath)), root) || basename3(targetPath) !== MANIFEST_NAME) {
11154
12169
  throw new TypeError("Codex image evidence manifest target is invalid");
11155
12170
  }
11156
- const temporaryPath = join7(
12171
+ const temporaryPath = join8(
11157
12172
  root,
11158
12173
  `.codex-image-evidence.${process.pid}.${this.#random(8).toString("hex")}.tmp`
11159
12174
  );
@@ -11173,7 +12188,7 @@ var FileCodexImageCapabilityEvidenceManifestOwner = class {
11173
12188
  } catch {
11174
12189
  }
11175
12190
  }
11176
- if (existsSync9(temporaryPath)) {
12191
+ if (existsSync10(temporaryPath)) {
11177
12192
  try {
11178
12193
  unlinkSync4(temporaryPath);
11179
12194
  } catch {
@@ -11765,11 +12780,11 @@ var DaemonImageExecutionScheduler = class {
11765
12780
  retrySafety: "before_acceptance"
11766
12781
  });
11767
12782
  }
11768
- return new Promise((resolve10, reject) => {
12783
+ return new Promise((resolve11, reject) => {
11769
12784
  const waiter = {
11770
12785
  tenantKey,
11771
12786
  signal: request.signal,
11772
- resolve: resolve10,
12787
+ resolve: resolve11,
11773
12788
  reject,
11774
12789
  onAbort: () => void 0,
11775
12790
  settled: false
@@ -11932,7 +12947,7 @@ import {
11932
12947
  ImageGenerationError as ImageGenerationError3,
11933
12948
  ImageRequestResourceScope
11934
12949
  } from "@omnicross/core/image-generation";
11935
- import { dirname as dirname7, resolve as resolve5 } from "path";
12950
+ import { dirname as dirname7, resolve as resolve6 } from "path";
11936
12951
  function capacityExceeded() {
11937
12952
  throw new ImageGenerationError3("image_too_large");
11938
12953
  }
@@ -12017,10 +13032,10 @@ var DaemonImageActiveScopeRegistry = class {
12017
13032
  #temporaryRoot;
12018
13033
  #active = /* @__PURE__ */ new Set();
12019
13034
  constructor(paths) {
12020
- this.#temporaryRoot = resolve5(paths.paths.temporaryRoot);
13035
+ this.#temporaryRoot = resolve6(paths.paths.temporaryRoot);
12021
13036
  }
12022
13037
  register(privateDirectory) {
12023
- const normalized2 = resolve5(privateDirectory);
13038
+ const normalized2 = resolve6(privateDirectory);
12024
13039
  if (dirname7(normalized2) !== this.#temporaryRoot || this.#active.has(normalized2)) {
12025
13040
  throw new TypeError("image temporary scope directory is invalid or already active");
12026
13041
  }
@@ -12033,7 +13048,7 @@ var DaemonImageActiveScopeRegistry = class {
12033
13048
  };
12034
13049
  }
12035
13050
  isActive(privateDirectory) {
12036
- return this.#active.has(resolve5(privateDirectory));
13051
+ return this.#active.has(resolve6(privateDirectory));
12037
13052
  }
12038
13053
  status() {
12039
13054
  return Object.freeze({ activeDirectories: this.#active.size });
@@ -12327,14 +13342,14 @@ function createImageRuntimeGeneration(options) {
12327
13342
 
12328
13343
  // src/image-generation/ImageStartupReconciler.ts
12329
13344
  import {
12330
- existsSync as existsSync13,
13345
+ existsSync as existsSync14,
12331
13346
  lstatSync as lstatSync7,
12332
13347
  readFileSync as readFileSync11,
12333
13348
  readdirSync as readdirSync3,
12334
13349
  rmdirSync as rmdirSync2,
12335
13350
  unlinkSync as unlinkSync8
12336
13351
  } from "fs";
12337
- import { basename as basename6, dirname as dirname11, isAbsolute as isAbsolute3, relative as relative2, resolve as resolve9 } from "path";
13352
+ import { basename as basename7, dirname as dirname11, isAbsolute as isAbsolute3, relative as relative2, resolve as resolve10 } from "path";
12338
13353
  import {
12339
13354
  IMAGE_REQUEST_DIRECTORY_MARKER_CONTENT,
12340
13355
  IMAGE_REQUEST_DIRECTORY_MARKER_NAME
@@ -12344,7 +13359,7 @@ import {
12344
13359
  import { randomBytes as randomBytes9 } from "crypto";
12345
13360
  import {
12346
13361
  closeSync as closeSync5,
12347
- existsSync as existsSync12,
13362
+ existsSync as existsSync13,
12348
13363
  fsyncSync as fsyncSync5,
12349
13364
  lstatSync as lstatSync6,
12350
13365
  openSync as openSync5,
@@ -12354,7 +13369,7 @@ import {
12354
13369
  unlinkSync as unlinkSync7,
12355
13370
  writeFileSync as writeFileSync10
12356
13371
  } from "fs";
12357
- import { basename as basename5, dirname as dirname10, isAbsolute as isAbsolute2, join as join10, resolve as resolve8 } from "path";
13372
+ import { basename as basename6, dirname as dirname10, isAbsolute as isAbsolute2, join as join11, resolve as resolve9 } from "path";
12358
13373
  import { ImageGenerationError as ImageGenerationError7 } from "@omnicross/core/image-generation";
12359
13374
 
12360
13375
  // src/image-generation/FileImageReferenceStore.ts
@@ -12363,7 +13378,7 @@ import {
12363
13378
  closeSync as closeSync3,
12364
13379
  constants as constants2,
12365
13380
  createReadStream,
12366
- existsSync as existsSync10,
13381
+ existsSync as existsSync11,
12367
13382
  fstatSync as fstatSync2,
12368
13383
  fsyncSync as fsyncSync3,
12369
13384
  lstatSync as lstatSync4,
@@ -12375,8 +13390,8 @@ import {
12375
13390
  unlinkSync as unlinkSync5,
12376
13391
  writeFileSync as writeFileSync8
12377
13392
  } from "fs";
12378
- import { open } from "fs/promises";
12379
- import { basename as basename3, dirname as dirname8, join as join8, resolve as resolve6 } from "path";
13393
+ import { open as open2 } from "fs/promises";
13394
+ import { basename as basename4, dirname as dirname8, join as join9, resolve as resolve7 } from "path";
12380
13395
  import { Readable } from "stream";
12381
13396
  import {
12382
13397
  ImageGenerationError as ImageGenerationError5
@@ -12402,8 +13417,8 @@ function safeInteger(value) {
12402
13417
  return typeof value === "number" && Number.isSafeInteger(value) && value >= 0;
12403
13418
  }
12404
13419
  function samePath3(left, right) {
12405
- const normalizedLeft = resolve6(left);
12406
- const normalizedRight = resolve6(right);
13420
+ const normalizedLeft = resolve7(left);
13421
+ const normalizedRight = resolve7(right);
12407
13422
  return process.platform === "win32" ? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase() : normalizedLeft === normalizedRight;
12408
13423
  }
12409
13424
  function validEntry2(value) {
@@ -12705,7 +13720,7 @@ var FileImageReferenceStore = class {
12705
13720
  const ownedArtifact = ARTIFACT_FILE.test(name);
12706
13721
  const incomplete = /^artifact-[a-f0-9]{32}\.tmp$/u.test(name);
12707
13722
  if ((!ownedArtifact || referenced.has(name)) && !incomplete) continue;
12708
- const path2 = resolve6(root, name);
13723
+ const path2 = resolve7(root, name);
12709
13724
  let info;
12710
13725
  try {
12711
13726
  info = lstatSync4(path2);
@@ -12856,10 +13871,10 @@ var FileImageReferenceStore = class {
12856
13871
  async writeArtifact(asset, limits) {
12857
13872
  const root = this.#paths.verifiedRoot("artifacts");
12858
13873
  const suffix = this.#random(16).toString("hex");
12859
- const tempPath = join8(root, `artifact-${suffix}.tmp`);
13874
+ const tempPath = join9(root, `artifact-${suffix}.tmp`);
12860
13875
  const fileName = `artifact-${suffix}.bin`;
12861
- const finalPath = join8(root, fileName);
12862
- const handle = await open(tempPath, "wx", 384);
13876
+ const finalPath = join9(root, fileName);
13877
+ const handle = await open2(tempPath, "wx", 384);
12863
13878
  let reader;
12864
13879
  let observed = 0;
12865
13880
  let writeFailure;
@@ -12908,8 +13923,8 @@ var FileImageReferenceStore = class {
12908
13923
  artifactPath(fileName) {
12909
13924
  if (!ARTIFACT_FILE.test(fileName)) throw new TypeError("invalid image artifact filename");
12910
13925
  const root = this.#paths.verifiedRoot("artifacts");
12911
- const path2 = resolve6(root, fileName);
12912
- if (!samePath3(dirname8(path2), root) || basename3(path2) !== fileName) {
13926
+ const path2 = resolve7(root, fileName);
13927
+ if (!samePath3(dirname8(path2), root) || basename4(path2) !== fileName) {
12913
13928
  throw new TypeError("image artifact escaped its root");
12914
13929
  }
12915
13930
  return path2;
@@ -12932,12 +13947,12 @@ var FileImageReferenceStore = class {
12932
13947
  }
12933
13948
  safeUnlinkArtifactPath(path2) {
12934
13949
  const root = this.#paths.verifiedRoot("artifacts");
12935
- const target = resolve6(path2);
12936
- const name = basename3(target);
13950
+ const target = resolve7(path2);
13951
+ const name = basename4(target);
12937
13952
  if (!samePath3(dirname8(target), root) || !/^artifact-[a-f0-9]{32}\.(?:bin|tmp)$/u.test(name)) {
12938
13953
  throw new TypeError("refusing to unlink an unverified image artifact");
12939
13954
  }
12940
- if (!existsSync10(target)) return;
13955
+ if (!existsSync11(target)) return;
12941
13956
  const info = lstatSync4(target);
12942
13957
  if (info.isSymbolicLink() || !info.isFile()) throw new TypeError("refusing to unlink an unverified image artifact");
12943
13958
  unlinkSync5(target);
@@ -12959,7 +13974,7 @@ var FileImageReferenceStore = class {
12959
13974
  });
12960
13975
  }
12961
13976
  manifestPath() {
12962
- return join8(this.#paths.verifiedRoot("state"), MANIFEST_NAME2);
13977
+ return join9(this.#paths.verifiedRoot("state"), MANIFEST_NAME2);
12963
13978
  }
12964
13979
  persist(entries, tombstones) {
12965
13980
  const manifest = {
@@ -12975,10 +13990,10 @@ var FileImageReferenceStore = class {
12975
13990
  }
12976
13991
  atomicReplace(targetPath, contents) {
12977
13992
  const root = this.#paths.verifiedRoot("state");
12978
- if (!samePath3(dirname8(resolve6(targetPath)), root) || basename3(targetPath) !== MANIFEST_NAME2) {
13993
+ if (!samePath3(dirname8(resolve7(targetPath)), root) || basename4(targetPath) !== MANIFEST_NAME2) {
12979
13994
  throw new TypeError("invalid image reference manifest target");
12980
13995
  }
12981
- const temporaryPath = join8(root, `.references.${process.pid}.${this.#random(8).toString("hex")}.tmp`);
13996
+ const temporaryPath = join9(root, `.references.${process.pid}.${this.#random(8).toString("hex")}.tmp`);
12982
13997
  let fd;
12983
13998
  try {
12984
13999
  fd = openSync3(temporaryPath, "wx", 384);
@@ -12994,7 +14009,7 @@ var FileImageReferenceStore = class {
12994
14009
  } catch {
12995
14010
  }
12996
14011
  }
12997
- if (existsSync10(temporaryPath)) {
14012
+ if (existsSync11(temporaryPath)) {
12998
14013
  try {
12999
14014
  unlinkSync5(temporaryPath);
13000
14015
  } catch {
@@ -13004,7 +14019,7 @@ var FileImageReferenceStore = class {
13004
14019
  }
13005
14020
  loadManifest() {
13006
14021
  const path2 = this.manifestPath();
13007
- if (!existsSync10(path2)) return;
14022
+ if (!existsSync11(path2)) return;
13008
14023
  const info = lstatSync4(path2);
13009
14024
  if (info.isSymbolicLink() || !info.isFile() || info.size > MAX_MANIFEST_BYTES2) {
13010
14025
  throw new TypeError("image reference manifest is invalid");
@@ -13053,7 +14068,7 @@ var FileImageReferenceStore = class {
13053
14068
  import { randomBytes as randomBytes8 } from "crypto";
13054
14069
  import {
13055
14070
  closeSync as closeSync4,
13056
- existsSync as existsSync11,
14071
+ existsSync as existsSync12,
13057
14072
  fsyncSync as fsyncSync4,
13058
14073
  lstatSync as lstatSync5,
13059
14074
  openSync as openSync4,
@@ -13062,7 +14077,7 @@ import {
13062
14077
  unlinkSync as unlinkSync6,
13063
14078
  writeFileSync as writeFileSync9
13064
14079
  } from "fs";
13065
- import { basename as basename4, dirname as dirname9, join as join9, resolve as resolve7 } from "path";
14080
+ import { basename as basename5, dirname as dirname9, join as join10, resolve as resolve8 } from "path";
13066
14081
  import { ImageGenerationError as ImageGenerationError6 } from "@omnicross/core/image-generation";
13067
14082
  var MANIFEST_VERSION3 = 1;
13068
14083
  var MANIFEST_NAME3 = "responses-image-state.v1.json";
@@ -13115,8 +14130,8 @@ function validPendingReferenceDelete(value) {
13115
14130
  return exactKeys2(row, ["callId", "referenceTenantKey", "referenceId", "expiresAt"]) && typeof row.callId === "string" && CALL_ID_PATTERN.test(row.callId) && isImageTenantHmac(row.referenceTenantKey) && typeof row.referenceId === "string" && REFERENCE_ID_PATTERN.test(row.referenceId) && safeTimestamp2(row.expiresAt);
13116
14131
  }
13117
14132
  function samePath4(left, right) {
13118
- const normalizedLeft = resolve7(left);
13119
- const normalizedRight = resolve7(right);
14133
+ const normalizedLeft = resolve8(left);
14134
+ const normalizedRight = resolve8(right);
13120
14135
  return process.platform === "win32" ? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase() : normalizedLeft === normalizedRight;
13121
14136
  }
13122
14137
  function sameBinding(left, right) {
@@ -13599,7 +14614,7 @@ var FileResponsesImageStateStore = class {
13599
14614
  });
13600
14615
  }
13601
14616
  manifestPath() {
13602
- return join9(this.#paths.verifiedRoot("state"), MANIFEST_NAME3);
14617
+ return join10(this.#paths.verifiedRoot("state"), MANIFEST_NAME3);
13603
14618
  }
13604
14619
  persist(calls, responses, tombstones, pendingReferenceDeletes) {
13605
14620
  const manifest = {
@@ -13619,10 +14634,10 @@ var FileResponsesImageStateStore = class {
13619
14634
  }
13620
14635
  atomicReplace(targetPath, contents) {
13621
14636
  const root = this.#paths.verifiedRoot("state");
13622
- if (!samePath4(dirname9(resolve7(targetPath)), root) || basename4(targetPath) !== MANIFEST_NAME3) {
14637
+ if (!samePath4(dirname9(resolve8(targetPath)), root) || basename5(targetPath) !== MANIFEST_NAME3) {
13623
14638
  throw new TypeError("invalid responses image state manifest target");
13624
14639
  }
13625
- const temporaryPath = join9(
14640
+ const temporaryPath = join10(
13626
14641
  root,
13627
14642
  `.responses-image-state.${process.pid}.${this.#random(8).toString("hex")}.tmp`
13628
14643
  );
@@ -13641,7 +14656,7 @@ var FileResponsesImageStateStore = class {
13641
14656
  } catch {
13642
14657
  }
13643
14658
  }
13644
- if (existsSync11(temporaryPath)) {
14659
+ if (existsSync12(temporaryPath)) {
13645
14660
  try {
13646
14661
  unlinkSync6(temporaryPath);
13647
14662
  } catch {
@@ -13651,7 +14666,7 @@ var FileResponsesImageStateStore = class {
13651
14666
  }
13652
14667
  loadManifest() {
13653
14668
  const path2 = this.manifestPath();
13654
- if (!existsSync11(path2)) return;
14669
+ if (!existsSync12(path2)) return;
13655
14670
  const info = lstatSync5(path2);
13656
14671
  if (info.isSymbolicLink() || !info.isFile() || info.size > MAX_MANIFEST_BYTES3) {
13657
14672
  throw new TypeError("responses image state manifest is invalid");
@@ -13745,8 +14760,8 @@ function validMount(value) {
13745
14760
  return exactKeys3(row, ["id", "durableRoot", "createdAt"]) && typeof row.id === "string" && MOUNT_ID_PATTERN.test(row.id) && typeof row.durableRoot === "string" && isAbsolute2(row.durableRoot) && safeInteger2(row.createdAt);
13746
14761
  }
13747
14762
  function samePath5(left, right) {
13748
- const normalizedLeft = resolve8(left);
13749
- const normalizedRight = resolve8(right);
14763
+ const normalizedLeft = resolve9(left);
14764
+ const normalizedRight = resolve9(right);
13750
14765
  return process.platform === "win32" ? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase() : normalizedLeft === normalizedRight;
13751
14766
  }
13752
14767
  var ImageStorageMountCatalog = class {
@@ -13774,7 +14789,7 @@ var ImageStorageMountCatalog = class {
13774
14789
  this.#catalogResolver = this.createResolver(options.activeStorageRoot);
13775
14790
  this.#reconcileCorruptManifests = options.reconcileCorruptManifests ?? false;
13776
14791
  this.#replaceCatalog = options.replaceCatalog ?? ((target, contents) => this.atomicReplace(target, contents));
13777
- if (existsSync12(this.catalogPath())) {
14792
+ if (existsSync13(this.catalogPath())) {
13778
14793
  try {
13779
14794
  this.loadCatalog();
13780
14795
  } catch (error) {
@@ -14026,15 +15041,15 @@ var ImageStorageMountCatalog = class {
14026
15041
  }
14027
15042
  quarantineManifest(resolver, area, name, label) {
14028
15043
  const root = resolver.verifiedRoot(area);
14029
- const source = join10(root, name);
14030
- if (!existsSync12(source)) throw new TypeError("corrupt image manifest is missing");
15044
+ const source = join11(root, name);
15045
+ if (!existsSync13(source)) throw new TypeError("corrupt image manifest is missing");
14031
15046
  const info = lstatSync6(source);
14032
15047
  if (info.isSymbolicLink() || !info.isFile()) {
14033
15048
  throw new TypeError("refusing to quarantine an unverified image manifest");
14034
15049
  }
14035
15050
  for (let attempt = 0; attempt < 8; attempt += 1) {
14036
- const target = join10(root, `.corrupt-${label}-${this.#random(8).toString("hex")}.json`);
14037
- if (existsSync12(target)) continue;
15051
+ const target = join11(root, `.corrupt-${label}-${this.#random(8).toString("hex")}.json`);
15052
+ if (existsSync13(target)) continue;
14038
15053
  resolver.verifiedRoot(area);
14039
15054
  renameSync6(source, target);
14040
15055
  this.#corruptManifestsQuarantined += 1;
@@ -14079,10 +15094,10 @@ var ImageStorageMountCatalog = class {
14079
15094
  }
14080
15095
  atomicReplace(targetPath, contents) {
14081
15096
  const root = this.#catalogResolver.verifiedRoot("mountManifest");
14082
- if (!samePath5(dirname10(resolve8(targetPath)), root) || basename5(targetPath) !== CATALOG_NAME) {
15097
+ if (!samePath5(dirname10(resolve9(targetPath)), root) || basename6(targetPath) !== CATALOG_NAME) {
14083
15098
  throw new TypeError("invalid image storage mount catalog target");
14084
15099
  }
14085
- const temporaryPath = join10(
15100
+ const temporaryPath = join11(
14086
15101
  root,
14087
15102
  `.catalog.${process.pid}.${this.#random(8).toString("hex")}.tmp`
14088
15103
  );
@@ -14101,7 +15116,7 @@ var ImageStorageMountCatalog = class {
14101
15116
  } catch {
14102
15117
  }
14103
15118
  }
14104
- if (existsSync12(temporaryPath)) {
15119
+ if (existsSync13(temporaryPath)) {
14105
15120
  try {
14106
15121
  unlinkSync7(temporaryPath);
14107
15122
  } catch {
@@ -14323,12 +15338,12 @@ function positiveInteger4(value, name) {
14323
15338
  return value;
14324
15339
  }
14325
15340
  function samePath6(left, right) {
14326
- const normalizedLeft = resolve9(left);
14327
- const normalizedRight = resolve9(right);
15341
+ const normalizedLeft = resolve10(left);
15342
+ const normalizedRight = resolve10(right);
14328
15343
  return process.platform === "win32" ? normalizedLeft.toLowerCase() === normalizedRight.toLowerCase() : normalizedLeft === normalizedRight;
14329
15344
  }
14330
15345
  function isDirectChild(path2, root) {
14331
- const target = resolve9(path2);
15346
+ const target = resolve10(path2);
14332
15347
  const rel = relative2(root, target);
14333
15348
  return !samePath6(target, root) && !isAbsolute3(rel) && !rel.startsWith("..") && samePath6(dirname11(target), root);
14334
15349
  }
@@ -14450,8 +15465,8 @@ var ImageStartupReconciler = class {
14450
15465
  let removed = 0;
14451
15466
  let invalid = 0;
14452
15467
  for (const name of readdirSync3(root).filter((value) => pattern.test(value)).slice(0, limit)) {
14453
- const path2 = resolve9(root, name);
14454
- if (!isDirectChild(path2, root) || basename6(path2) !== name) {
15468
+ const path2 = resolve10(root, name);
15469
+ if (!isDirectChild(path2, root) || basename7(path2) !== name) {
14455
15470
  invalid += 1;
14456
15471
  continue;
14457
15472
  }
@@ -14473,7 +15488,7 @@ var ImageStartupReconciler = class {
14473
15488
  let invalid = 0;
14474
15489
  let active = 0;
14475
15490
  for (const name of readdirSync3(root).slice(0, this.#maxTemporaryDirectoriesPerPass)) {
14476
- const path2 = resolve9(root, name);
15491
+ const path2 = resolve10(root, name);
14477
15492
  if (!OWNED_TEMPORARY_DIRECTORY.test(name) || !isDirectChild(path2, root)) {
14478
15493
  foreign += 1;
14479
15494
  continue;
@@ -14488,8 +15503,8 @@ var ImageStartupReconciler = class {
14488
15503
  active += 1;
14489
15504
  continue;
14490
15505
  }
14491
- const markerPath = resolve9(path2, IMAGE_REQUEST_DIRECTORY_MARKER_NAME);
14492
- if (!isDirectChild(markerPath, path2) || !existsSync13(markerPath)) {
15506
+ const markerPath = resolve10(path2, IMAGE_REQUEST_DIRECTORY_MARKER_NAME);
15507
+ if (!isDirectChild(markerPath, path2) || !existsSync14(markerPath)) {
14493
15508
  foreign += 1;
14494
15509
  continue;
14495
15510
  }
@@ -14521,7 +15536,7 @@ var ImageStartupReconciler = class {
14521
15536
  throw new TypeError("refusing to remove an unsupported temporary descendant");
14522
15537
  }
14523
15538
  for (const name of readdirSync3(path2)) {
14524
- this.removeTreeWithoutFollowingSymlinks(resolve9(path2, name), path2);
15539
+ this.removeTreeWithoutFollowingSymlinks(resolve10(path2, name), path2);
14525
15540
  }
14526
15541
  rmdirSync2(path2);
14527
15542
  }
@@ -14990,8 +16005,8 @@ function createHostedImageContributionFactory(manager) {
14990
16005
  function deferredRecord(generation, phase) {
14991
16006
  let resolveDisposed;
14992
16007
  let rejectDisposed;
14993
- const disposed = new Promise((resolve10, reject) => {
14994
- resolveDisposed = resolve10;
16008
+ const disposed = new Promise((resolve11, reject) => {
16009
+ resolveDisposed = resolve11;
14995
16010
  rejectDisposed = reject;
14996
16011
  });
14997
16012
  void disposed.catch(() => void 0);
@@ -15570,7 +16585,7 @@ function toLLMProvider(row) {
15570
16585
  // src/ports/ConfigurableLogger.ts
15571
16586
  import {
15572
16587
  createWriteStream,
15573
- existsSync as existsSync14,
16588
+ existsSync as existsSync15,
15574
16589
  renameSync as renameSync7,
15575
16590
  statSync as statSync4,
15576
16591
  unlinkSync as unlinkSync9
@@ -15622,7 +16637,7 @@ var ConfigurableLogger = class {
15622
16637
  this.fileStream = null;
15623
16638
  this.rotateQueue = [];
15624
16639
  if (!stream) return Promise.resolve();
15625
- return new Promise((resolve10) => stream.end(() => resolve10()));
16640
+ return new Promise((resolve11) => stream.end(() => resolve11()));
15626
16641
  }
15627
16642
  emit(level, message, error, meta) {
15628
16643
  if (LEVEL_ORDER[level] > this.threshold) return;
@@ -15704,12 +16719,12 @@ var ConfigurableLogger = class {
15704
16719
  /** `<file>.N` unlinked, `<file>.k` → `<file>.k+1`, `<file>` → `<file>.1`. */
15705
16720
  shiftGenerations(path2) {
15706
16721
  const oldest = `${path2}.${this.maxFiles}`;
15707
- if (existsSync14(oldest)) unlinkSync9(oldest);
16722
+ if (existsSync15(oldest)) unlinkSync9(oldest);
15708
16723
  for (let i = this.maxFiles - 1; i >= 1; i--) {
15709
16724
  const from = `${path2}.${i}`;
15710
- if (existsSync14(from)) renameSync7(from, `${path2}.${i + 1}`);
16725
+ if (existsSync15(from)) renameSync7(from, `${path2}.${i + 1}`);
15711
16726
  }
15712
- if (existsSync14(path2)) renameSync7(path2, `${path2}.1`);
16727
+ if (existsSync15(path2)) renameSync7(path2, `${path2}.1`);
15713
16728
  }
15714
16729
  /**
15715
16730
  * Lazily open the append-only file stream; disable the sink on any error. The
@@ -15720,7 +16735,7 @@ var ConfigurableLogger = class {
15720
16735
  if (this.fileDisabled || !this.filePath) return null;
15721
16736
  if (this.fileStream) return this.fileStream;
15722
16737
  try {
15723
- this.fileBytes = existsSync14(this.filePath) ? statSync4(this.filePath).size : 0;
16738
+ this.fileBytes = existsSync15(this.filePath) ? statSync4(this.filePath).size : 0;
15724
16739
  const stream = createWriteStream(this.filePath, { flags: "a" });
15725
16740
  stream.on("error", () => {
15726
16741
  this.fileDisabled = true;
@@ -15793,7 +16808,7 @@ function safeStringify(value) {
15793
16808
  import { randomBytes as randomBytes10 } from "crypto";
15794
16809
  import {
15795
16810
  closeSync as closeSync6,
15796
- existsSync as existsSync15,
16811
+ existsSync as existsSync16,
15797
16812
  fsyncSync as fsyncSync6,
15798
16813
  openSync as openSync6,
15799
16814
  readFileSync as readFileSync12,
@@ -15801,12 +16816,12 @@ import {
15801
16816
  unlinkSync as unlinkSync10,
15802
16817
  writeFileSync as writeFileSync11
15803
16818
  } from "fs";
15804
- import { basename as basename7, dirname as dirname12, join as join11 } from "path";
16819
+ import { basename as basename8, dirname as dirname12, join as join12 } from "path";
15805
16820
  import { OUTBOUND_API_SERVER_CONFIG_KEY } from "@omnicross/core/outbound-api";
15806
16821
  function atomicReplaceDocument(targetPath, contents) {
15807
- const tempPath = join11(
16822
+ const tempPath = join12(
15808
16823
  dirname12(targetPath),
15809
- `.${basename7(targetPath)}.${process.pid}.${randomBytes10(8).toString("hex")}.tmp`
16824
+ `.${basename8(targetPath)}.${process.pid}.${randomBytes10(8).toString("hex")}.tmp`
15810
16825
  );
15811
16826
  let fd;
15812
16827
  try {
@@ -15823,7 +16838,7 @@ function atomicReplaceDocument(targetPath, contents) {
15823
16838
  } catch {
15824
16839
  }
15825
16840
  }
15826
- if (existsSync15(tempPath)) {
16841
+ if (existsSync16(tempPath)) {
15827
16842
  try {
15828
16843
  unlinkSync10(tempPath);
15829
16844
  } catch {
@@ -15866,13 +16881,13 @@ var JsonApiServerSettingsStore = class {
15866
16881
  }
15867
16882
  /** Capture the exact prior document for an admin transaction rollback. */
15868
16883
  captureDocumentSnapshot() {
15869
- if (!existsSync15(this.configPath)) return { existed: false };
16884
+ if (!existsSync16(this.configPath)) return { existed: false };
15870
16885
  return { existed: true, bytes: readFileSync12(this.configPath) };
15871
16886
  }
15872
16887
  /** Restore exact prior bytes (including unrelated fields and encrypted secrets). */
15873
16888
  restoreDocumentSnapshot(snapshot) {
15874
16889
  if (!snapshot.existed) {
15875
- if (existsSync15(this.configPath)) unlinkSync10(this.configPath);
16890
+ if (existsSync16(this.configPath)) unlinkSync10(this.configPath);
15876
16891
  return;
15877
16892
  }
15878
16893
  if (!snapshot.bytes) throw new TypeError("settings snapshot is missing prior bytes");
@@ -15909,13 +16924,13 @@ var JsonApiServerSettingsStore = class {
15909
16924
  };
15910
16925
 
15911
16926
  // src/ports/JsonlUsageEventStore.ts
15912
- import { randomUUID as randomUUID4 } from "crypto";
16927
+ import { randomUUID as randomUUID5 } from "crypto";
15913
16928
  import { appendFileSync, mkdirSync as mkdirSync5 } from "fs";
15914
- import { join as join15 } from "path";
16929
+ import { join as join16 } from "path";
15915
16930
 
15916
16931
  // src/usage/usageFiles.ts
15917
- import { readdir } from "fs/promises";
15918
- import { dirname as dirname13, join as join12 } from "path";
16932
+ import { readdir as readdir2 } from "fs/promises";
16933
+ import { dirname as dirname13, join as join13 } from "path";
15919
16934
  var USAGE_DIR_NAME = "usage";
15920
16935
  var USAGE_SHARD_RE = /^usage-(\d{4})-(\d{2})-(\d{2})\.jsonl$/;
15921
16936
  var USAGE_ROLLUP_RE = /^usage-(\d{4})-(\d{2})-(\d{2})\.rollup\.json$/;
@@ -15932,7 +16947,7 @@ function usageRollupName(dayKey) {
15932
16947
  return `usage-${dayKey}.rollup.json`;
15933
16948
  }
15934
16949
  function usageDirFor(eventsPath) {
15935
- return join12(dirname13(eventsPath), USAGE_DIR_NAME);
16950
+ return join13(dirname13(eventsPath), USAGE_DIR_NAME);
15936
16951
  }
15937
16952
  function dayKeyStartTs(dayKey) {
15938
16953
  const m = /^(\d{4})-(\d{2})-(\d{2})$/.exec(dayKey);
@@ -15953,7 +16968,7 @@ function dayKeyEndTs(dayKey) {
15953
16968
  async function listUsageDays(usageDir) {
15954
16969
  let names;
15955
16970
  try {
15956
- names = await readdir(usageDir);
16971
+ names = await readdir2(usageDir);
15957
16972
  } catch {
15958
16973
  return [];
15959
16974
  }
@@ -16193,12 +17208,12 @@ function isUsageDayRollup(parsed) {
16193
17208
  }
16194
17209
 
16195
17210
  // src/usage/usageRollupStore.ts
16196
- import { mkdir, readFile as readFile2, rename, unlink, writeFile } from "fs/promises";
16197
- import { join as join14 } from "path";
17211
+ import { mkdir, readFile as readFile3, rename as rename2, unlink as unlink2, writeFile as writeFile2 } from "fs/promises";
17212
+ import { join as join15 } from "path";
16198
17213
 
16199
17214
  // src/usage/usageShardCache.ts
16200
- import { open as open2 } from "fs/promises";
16201
- import { join as join13 } from "path";
17215
+ import { open as open3 } from "fs/promises";
17216
+ import { join as join14 } from "path";
16202
17217
 
16203
17218
  // src/usage/usageRow.ts
16204
17219
  var NUMERIC_FIELDS = [
@@ -16258,10 +17273,10 @@ var NEWLINE = 10;
16258
17273
  var READ_CHUNK_BYTES = 8 * 1024 * 1024;
16259
17274
  var DEFAULT_MAX_RESIDENT_DAYS = 3;
16260
17275
  async function streamShardRows(usageDir, dayKey, onRow) {
16261
- const path2 = join13(usageDir, usageShardName(dayKey));
17276
+ const path2 = join14(usageDir, usageShardName(dayKey));
16262
17277
  let handle;
16263
17278
  try {
16264
- handle = await open2(path2, "r");
17279
+ handle = await open3(path2, "r");
16265
17280
  } catch {
16266
17281
  return;
16267
17282
  }
@@ -16291,7 +17306,7 @@ async function streamShardRows(usageDir, dayKey, onRow) {
16291
17306
  async function shardSize(usageDir, dayKey) {
16292
17307
  let handle;
16293
17308
  try {
16294
- handle = await open2(join13(usageDir, usageShardName(dayKey)), "r");
17309
+ handle = await open3(join14(usageDir, usageShardName(dayKey)), "r");
16295
17310
  } catch {
16296
17311
  return null;
16297
17312
  }
@@ -16347,10 +17362,10 @@ var UsageShardCache = class {
16347
17362
  } else {
16348
17363
  this.touch(dayKey);
16349
17364
  }
16350
- const path2 = join13(this.usageDir, usageShardName(dayKey));
17365
+ const path2 = join14(this.usageDir, usageShardName(dayKey));
16351
17366
  let handle;
16352
17367
  try {
16353
- handle = await open2(path2, "r");
17368
+ handle = await open3(path2, "r");
16354
17369
  } catch {
16355
17370
  return entry;
16356
17371
  }
@@ -16469,7 +17484,7 @@ var UsageRollupStore = class {
16469
17484
  }
16470
17485
  async readSidecar(dayKey) {
16471
17486
  try {
16472
- const raw = await readFile2(join14(this.usageDir, usageRollupName(dayKey)), "utf8");
17487
+ const raw = await readFile3(join15(this.usageDir, usageRollupName(dayKey)), "utf8");
16473
17488
  const parsed = JSON.parse(raw);
16474
17489
  return isUsageDayRollup(parsed) && parsed.date === dayKey ? parsed : null;
16475
17490
  } catch {
@@ -16477,14 +17492,14 @@ var UsageRollupStore = class {
16477
17492
  }
16478
17493
  }
16479
17494
  async writeSidecar(dayKey, rollup) {
16480
- const target = join14(this.usageDir, usageRollupName(dayKey));
17495
+ const target = join15(this.usageDir, usageRollupName(dayKey));
16481
17496
  const temp = `${target}.tmp`;
16482
17497
  try {
16483
17498
  await mkdir(this.usageDir, { recursive: true });
16484
- await writeFile(temp, JSON.stringify(rollup), "utf8");
16485
- await rename(temp, target);
17499
+ await writeFile2(temp, JSON.stringify(rollup), "utf8");
17500
+ await rename2(temp, target);
16486
17501
  } catch {
16487
- await unlink(temp).catch(() => {
17502
+ await unlink2(temp).catch(() => {
16488
17503
  });
16489
17504
  }
16490
17505
  }
@@ -16559,13 +17574,13 @@ var JsonlUsageEventStore = class {
16559
17574
  async insert(input) {
16560
17575
  const row = {
16561
17576
  ...input,
16562
- id: randomUUID4(),
17577
+ id: randomUUID5(),
16563
17578
  ts: input.ts ?? Date.now()
16564
17579
  };
16565
17580
  const dayKey = usageDayKey(row.ts);
16566
17581
  this.ensureDir();
16567
17582
  const line = JSON.stringify(row) + "\n";
16568
- appendFileSync(join15(this.usageDir, usageShardName(dayKey)), line, "utf8");
17583
+ appendFileSync(join16(this.usageDir, usageShardName(dayKey)), line, "utf8");
16569
17584
  if (dayKey !== this.lastAppendDay) {
16570
17585
  this.rollups.invalidate(dayKey);
16571
17586
  this.lastAppendDay = dayKey;
@@ -16940,7 +17955,7 @@ function bucketLabel(bucketStartTs, bucket) {
16940
17955
  }
16941
17956
 
16942
17957
  // src/ports/JsonOutboundKeyDb.ts
16943
- import { existsSync as existsSync17, readFileSync as readFileSync13 } from "fs";
17958
+ import { existsSync as existsSync18, readFileSync as readFileSync13 } from "fs";
16944
17959
  import {
16945
17960
  validateOutboundPermissions as validateOutboundPermissions3
16946
17961
  } from "@omnicross/core";
@@ -16949,18 +17964,18 @@ import {
16949
17964
  import { randomBytes as randomBytes11 } from "crypto";
16950
17965
  import {
16951
17966
  closeSync as closeSync7,
16952
- existsSync as existsSync16,
17967
+ existsSync as existsSync17,
16953
17968
  fsyncSync as fsyncSync7,
16954
17969
  openSync as openSync7,
16955
17970
  renameSync as renameSync9,
16956
17971
  unlinkSync as unlinkSync11,
16957
17972
  writeFileSync as writeFileSync12
16958
17973
  } from "fs";
16959
- import { basename as basename8, dirname as dirname14, join as join16 } from "path";
17974
+ import { basename as basename9, dirname as dirname14, join as join17 } from "path";
16960
17975
  function atomicReplaceUtf8(targetPath, contents) {
16961
- const tempPath = join16(
17976
+ const tempPath = join17(
16962
17977
  dirname14(targetPath),
16963
- `.${basename8(targetPath)}.${process.pid}.${randomBytes11(8).toString("hex")}.tmp`
17978
+ `.${basename9(targetPath)}.${process.pid}.${randomBytes11(8).toString("hex")}.tmp`
16964
17979
  );
16965
17980
  let fd;
16966
17981
  try {
@@ -16977,7 +17992,7 @@ function atomicReplaceUtf8(targetPath, contents) {
16977
17992
  } catch {
16978
17993
  }
16979
17994
  }
16980
- if (existsSync16(tempPath)) {
17995
+ if (existsSync17(tempPath)) {
16981
17996
  try {
16982
17997
  unlinkSync11(tempPath);
16983
17998
  } catch {
@@ -17088,6 +18103,19 @@ var JsonOutboundKeyDb = class {
17088
18103
  return true;
17089
18104
  });
17090
18105
  }
18106
+ async outboundApiKeysSetUpstream(id, target) {
18107
+ return this.mutateRow(id, (row) => {
18108
+ if (row.revokedAt !== null) return false;
18109
+ if (target === null) {
18110
+ delete row.boundUpstream;
18111
+ delete row.boundUpstreamProviderId;
18112
+ } else {
18113
+ row.boundUpstream = target;
18114
+ delete row.boundUpstreamProviderId;
18115
+ }
18116
+ return true;
18117
+ });
18118
+ }
17091
18119
  async outboundApiKeysSetPolicy(id, policy) {
17092
18120
  return this.mutateRow(id, (row) => {
17093
18121
  if (row.revokedAt !== null) return false;
@@ -17130,7 +18158,7 @@ var JsonOutboundKeyDb = class {
17130
18158
  }
17131
18159
  /** Read the key rows, tolerating a missing/corrupt file (→ empty list). */
17132
18160
  readRows() {
17133
- if (!existsSync17(this.keysPath)) return [];
18161
+ if (!existsSync18(this.keysPath)) return [];
17134
18162
  try {
17135
18163
  const parsed = JSON.parse(readFileSync13(this.keysPath, "utf8"));
17136
18164
  return Array.isArray(parsed) ? parsed : [];
@@ -17149,8 +18177,8 @@ function applyPolicyField(row, field, value) {
17149
18177
  }
17150
18178
 
17151
18179
  // src/ports/JsonPricingStore.ts
17152
- import { existsSync as existsSync18, readFileSync as readFileSync14, renameSync as renameSync10, rmSync as rmSync3, writeFileSync as writeFileSync13 } from "fs";
17153
- import { randomUUID as randomUUID5 } from "crypto";
18180
+ import { existsSync as existsSync19, readFileSync as readFileSync14, renameSync as renameSync10, rmSync as rmSync3, writeFileSync as writeFileSync13 } from "fs";
18181
+ import { randomUUID as randomUUID6 } from "crypto";
17154
18182
  var JsonPricingStore = class {
17155
18183
  constructor(pricingPath) {
17156
18184
  this.pricingPath = pricingPath;
@@ -17164,7 +18192,7 @@ var JsonPricingStore = class {
17164
18192
  * otherwise unusable pricing table after a crash or manual file edit.
17165
18193
  */
17166
18194
  hasUsableSnapshot() {
17167
- if (!existsSync18(this.pricingPath)) return false;
18195
+ if (!existsSync19(this.pricingPath)) return false;
17168
18196
  try {
17169
18197
  const parsed = JSON.parse(readFileSync14(this.pricingPath, "utf8"));
17170
18198
  return Array.isArray(parsed) && parsed.some(isUsablePricingRow);
@@ -17279,7 +18307,7 @@ var JsonPricingStore = class {
17279
18307
  }
17280
18308
  /** Read the pricing rows, tolerating a missing/corrupt file (→ empty list). */
17281
18309
  readRows() {
17282
- if (!existsSync18(this.pricingPath)) return [];
18310
+ if (!existsSync19(this.pricingPath)) return [];
17283
18311
  try {
17284
18312
  const parsed = JSON.parse(readFileSync14(this.pricingPath, "utf8"));
17285
18313
  return Array.isArray(parsed) ? parsed : [];
@@ -17288,7 +18316,7 @@ var JsonPricingStore = class {
17288
18316
  }
17289
18317
  }
17290
18318
  writeRows(rows) {
17291
- const temporaryPath = `${this.pricingPath}.${process.pid}.${randomUUID5()}.tmp`;
18319
+ const temporaryPath = `${this.pricingPath}.${process.pid}.${randomUUID6()}.tmp`;
17292
18320
  try {
17293
18321
  writeFileSync13(temporaryPath, JSON.stringify(rows, null, 2) + "\n", {
17294
18322
  encoding: "utf8",
@@ -17311,7 +18339,7 @@ function isUsablePricingRow(value) {
17311
18339
  }
17312
18340
 
17313
18341
  // src/pricing/PricingRefreshScheduler.ts
17314
- import { existsSync as existsSync19, readFileSync as readFileSync15, renameSync as renameSync11, writeFileSync as writeFileSync14 } from "fs";
18342
+ import { existsSync as existsSync20, readFileSync as readFileSync15, renameSync as renameSync11, writeFileSync as writeFileSync14 } from "fs";
17315
18343
  var EMPTY_STATE2 = {
17316
18344
  lastAttemptAt: null,
17317
18345
  lastSuccessAt: null,
@@ -17349,7 +18377,7 @@ var PricingRefreshScheduler = class {
17349
18377
  this.timer = null;
17350
18378
  }
17351
18379
  getState() {
17352
- if (!existsSync19(this.statePath)) return { ...EMPTY_STATE2, sources: [] };
18380
+ if (!existsSync20(this.statePath)) return { ...EMPTY_STATE2, sources: [] };
17353
18381
  try {
17354
18382
  const value = JSON.parse(readFileSync15(this.statePath, "utf8"));
17355
18383
  return {
@@ -17414,7 +18442,7 @@ function finiteOrNull(value) {
17414
18442
  }
17415
18443
 
17416
18444
  // src/ports/JsonVoucherDb.ts
17417
- import { existsSync as existsSync20, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
18445
+ import { existsSync as existsSync21, readFileSync as readFileSync16, writeFileSync as writeFileSync15 } from "fs";
17418
18446
  var JsonVoucherDb = class {
17419
18447
  constructor(vouchersPath) {
17420
18448
  this.vouchersPath = vouchersPath;
@@ -17492,7 +18520,7 @@ var JsonVoucherDb = class {
17492
18520
  }
17493
18521
  /** Read the voucher rows, tolerating a missing/corrupt file (→ empty list). */
17494
18522
  readRows() {
17495
- if (!existsSync20(this.vouchersPath)) return [];
18523
+ if (!existsSync21(this.vouchersPath)) return [];
17496
18524
  try {
17497
18525
  const parsed = JSON.parse(readFileSync16(this.vouchersPath, "utf8"));
17498
18526
  return Array.isArray(parsed) ? parsed : [];
@@ -17506,7 +18534,7 @@ var JsonVoucherDb = class {
17506
18534
  };
17507
18535
 
17508
18536
  // src/ports/JsonSubscriptionCredentialStore.ts
17509
- import { existsSync as existsSync22, mkdirSync as mkdirSync6, readFileSync as readFileSync18, renameSync as renameSync12 } from "fs";
18537
+ import { existsSync as existsSync23, mkdirSync as mkdirSync6, readFileSync as readFileSync18, renameSync as renameSync12 } from "fs";
17510
18538
  import { dirname as dirname15 } from "path";
17511
18539
  import { getAntigravityProjectResolver as getAntigravityProjectResolver2 } from "@omnicross/core/auth/GeminiCodeAssistProjectResolver";
17512
18540
  import { getSharedAccountHealth as getSharedAccountHealth2 } from "@omnicross/core/pipeline/SubscriptionAccountHealth";
@@ -17564,11 +18592,11 @@ function findDuplicateCredentialIds(accounts) {
17564
18592
  }
17565
18593
 
17566
18594
  // src/ports/external-cli-credentials.ts
17567
- import { existsSync as existsSync21, readFileSync as readFileSync17 } from "fs";
17568
- import { homedir as homedir4 } from "os";
17569
- import { join as join17 } from "path";
17570
- function externalStorePath(provider, home = homedir4()) {
17571
- return provider === "claude" ? join17(home, ".claude", ".credentials.json") : join17(home, ".codex", "auth.json");
18595
+ import { existsSync as existsSync22, readFileSync as readFileSync17 } from "fs";
18596
+ import { homedir as homedir5 } from "os";
18597
+ import { join as join18 } from "path";
18598
+ function externalStorePath(provider, home = homedir5()) {
18599
+ return provider === "claude" ? join18(home, ".claude", ".credentials.json") : join18(home, ".codex", "auth.json");
17572
18600
  }
17573
18601
  function decodeJwtExpiryMs(token) {
17574
18602
  try {
@@ -17615,9 +18643,9 @@ function parseCodexTokensEnvelope(raw) {
17615
18643
  }
17616
18644
  return parsed;
17617
18645
  }
17618
- function readExternalCliCredentials(provider, home = homedir4()) {
18646
+ function readExternalCliCredentials(provider, home = homedir5()) {
17619
18647
  const path2 = externalStorePath(provider, home);
17620
- if (!existsSync21(path2)) return null;
18648
+ if (!existsSync22(path2)) return null;
17621
18649
  let raw;
17622
18650
  try {
17623
18651
  const parsed = JSON.parse(readFileSync17(path2, "utf8"));
@@ -18424,7 +19452,7 @@ var JsonSubscriptionCredentialStore = class {
18424
19452
  * its parse try.
18425
19453
  */
18426
19454
  readConfig() {
18427
- if (!existsSync22(this.tokensPath)) return { updatedAt: "" };
19455
+ if (!existsSync23(this.tokensPath)) return { updatedAt: "" };
18428
19456
  let parsed;
18429
19457
  try {
18430
19458
  const raw = JSON.parse(readFileSync18(this.tokensPath, "utf8"));
@@ -19001,14 +20029,14 @@ var AccountHealthSweeper = class {
19001
20029
  };
19002
20030
 
19003
20031
  // src/audit/AuditPruneSweeper.ts
19004
- import { createReadStream as createReadStream3, createWriteStream as createWriteStream2, existsSync as existsSync25, readdirSync as readdirSync6, rmSync as rmSync4, unlinkSync as unlinkSync13 } from "fs";
19005
- import { join as join20 } from "path";
20032
+ import { createReadStream as createReadStream3, createWriteStream as createWriteStream2, existsSync as existsSync26, readdirSync as readdirSync6, rmSync as rmSync4, unlinkSync as unlinkSync13 } from "fs";
20033
+ import { join as join21 } from "path";
19006
20034
  import { pipeline } from "stream/promises";
19007
20035
  import { createGzip } from "zlib";
19008
20036
 
19009
20037
  // src/audit/auditDictionary.ts
19010
- import { existsSync as existsSync23, readdirSync as readdirSync4, readFileSync as readFileSync19, renameSync as renameSync13, unlinkSync as unlinkSync12, writeFileSync as writeFileSync16 } from "fs";
19011
- import { join as join18 } from "path";
20038
+ import { existsSync as existsSync24, readdirSync as readdirSync4, readFileSync as readFileSync19, renameSync as renameSync13, unlinkSync as unlinkSync12, writeFileSync as writeFileSync16 } from "fs";
20039
+ import { join as join19 } from "path";
19012
20040
 
19013
20041
  // src/audit/auditBodyStore.ts
19014
20042
  var ANCHOR_EVERY = 64;
@@ -19264,10 +20292,10 @@ function chooseDictionary(anchors) {
19264
20292
  }
19265
20293
  var EMPTY = { shards: 0, anchors: 0, savedBytes: 0 };
19266
20294
  function compactAuditDay(dayPath) {
19267
- const bodiesPath = join18(dayPath, AUDIT_BODIES_DIR);
19268
- if (!existsSync23(bodiesPath)) return EMPTY;
19269
- const dictPath = join18(bodiesPath, AUDIT_DICT_FILE);
19270
- if (existsSync23(dictPath) || existsSync23(`${dictPath}.gz`)) return EMPTY;
20295
+ const bodiesPath = join19(dayPath, AUDIT_BODIES_DIR);
20296
+ if (!existsSync24(bodiesPath)) return EMPTY;
20297
+ const dictPath = join19(bodiesPath, AUDIT_DICT_FILE);
20298
+ if (existsSync24(dictPath) || existsSync24(`${dictPath}.gz`)) return EMPTY;
19271
20299
  const shardFiles = plainShards(bodiesPath);
19272
20300
  if (shardFiles.length < 2) return EMPTY;
19273
20301
  const loaded = /* @__PURE__ */ new Map();
@@ -19275,7 +20303,7 @@ function compactAuditDay(dayPath) {
19275
20303
  for (const file of shardFiles) {
19276
20304
  let entries;
19277
20305
  try {
19278
- entries = parseEntries(readFileSync19(join18(bodiesPath, file), "utf8"));
20306
+ entries = parseEntries(readFileSync19(join19(bodiesPath, file), "utf8"));
19279
20307
  } catch {
19280
20308
  continue;
19281
20309
  }
@@ -19309,14 +20337,14 @@ function compactAuditDay(dayPath) {
19309
20337
  };
19310
20338
  });
19311
20339
  if (!changed) continue;
19312
- const target = join18(bodiesPath, file);
20340
+ const target = join19(bodiesPath, file);
19313
20341
  const temp = `${target}.compacting`;
19314
20342
  try {
19315
20343
  writeFileSync16(temp, rewritten.map((e) => JSON.stringify(e)).join("\n") + "\n", "utf8");
19316
20344
  renameSync13(temp, target);
19317
20345
  } catch {
19318
20346
  try {
19319
- if (existsSync23(temp)) unlinkSync12(temp);
20347
+ if (existsSync24(temp)) unlinkSync12(temp);
19320
20348
  } catch {
19321
20349
  }
19322
20350
  continue;
@@ -19335,7 +20363,7 @@ function compactAuditDay(dayPath) {
19335
20363
  }
19336
20364
  function compactAllClosedAuditDays(auditDir, now = Date.now) {
19337
20365
  const run = { days: 0, shards: 0, savedBytes: 0 };
19338
- if (!existsSync23(auditDir)) return run;
20366
+ if (!existsSync24(auditDir)) return run;
19339
20367
  const today = auditDayDirName(now());
19340
20368
  let names;
19341
20369
  try {
@@ -19346,7 +20374,7 @@ function compactAllClosedAuditDays(auditDir, now = Date.now) {
19346
20374
  for (const name of names) {
19347
20375
  if (name === today) continue;
19348
20376
  try {
19349
- const result = compactAuditDay(join18(auditDir, name));
20377
+ const result = compactAuditDay(join19(auditDir, name));
19350
20378
  if (result.shards === 0) continue;
19351
20379
  run.days += 1;
19352
20380
  run.shards += result.shards;
@@ -19360,13 +20388,13 @@ function compactAllClosedAuditDays(auditDir, now = Date.now) {
19360
20388
  // src/audit/auditStats.ts
19361
20389
  import {
19362
20390
  createReadStream as createReadStream2,
19363
- existsSync as existsSync24,
20391
+ existsSync as existsSync25,
19364
20392
  readFileSync as readFileSync20,
19365
20393
  readdirSync as readdirSync5,
19366
20394
  statSync as statSync5,
19367
20395
  writeFileSync as writeFileSync17
19368
20396
  } from "fs";
19369
- import { basename as basename9, dirname as dirname16, join as join19 } from "path";
20397
+ import { basename as basename10, dirname as dirname16, join as join20 } from "path";
19370
20398
  var SIDECAR_VERSION = 1;
19371
20399
  var META_PREFIX_BYTES = 64 * 1024;
19372
20400
  var READ_CHUNK_BYTES2 = 4 * 1024 * 1024;
@@ -19374,7 +20402,7 @@ function auditStatsFileName(auditFile) {
19374
20402
  return auditFile.replace(/\.jsonl$/, ".stats.json");
19375
20403
  }
19376
20404
  function readPersisted(path2) {
19377
- if (!existsSync24(path2)) return null;
20405
+ if (!existsSync25(path2)) return null;
19378
20406
  try {
19379
20407
  const value = JSON.parse(readFileSync20(path2, "utf8"));
19380
20408
  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)) {
@@ -19386,7 +20414,7 @@ function readPersisted(path2) {
19386
20414
  }
19387
20415
  }
19388
20416
  function updateAuditStatsAfterAppend(auditPath, auditBytesBefore, auditBytesAfter, record) {
19389
- const statsPath = join19(dirname16(auditPath), auditStatsFileName(basename9(auditPath)));
20417
+ const statsPath = join20(dirname16(auditPath), auditStatsFileName(basename10(auditPath)));
19390
20418
  const previous = auditBytesBefore === 0 ? {
19391
20419
  version: SIDECAR_VERSION,
19392
20420
  auditBytes: 0,
@@ -19517,20 +20545,20 @@ function mergePersistedStats(previous, appended) {
19517
20545
  };
19518
20546
  }
19519
20547
  async function readAuditStats(auditDir, query2 = {}) {
19520
- if (!existsSync24(auditDir)) return { requestCount: 0, errorCount: 0, complete: true };
20548
+ if (!existsSync25(auditDir)) return { requestCount: 0, errorCount: 0, complete: true };
19521
20549
  const from = typeof query2.from === "number" ? query2.from : -Infinity;
19522
20550
  const to = typeof query2.to === "number" ? query2.to : Infinity;
19523
20551
  let sources;
19524
20552
  try {
19525
20553
  sources = readdirSync5(auditDir).filter((name) => fileOverlaps(name, from, to)).sort().map(
19526
20554
  (name) => AUDIT_DAY_DIR_RE.test(name) ? {
19527
- auditPath: join19(auditDir, name, AUDIT_META_FILE),
19528
- statsPath: join19(auditDir, name, auditStatsFileName(AUDIT_META_FILE))
20555
+ auditPath: join20(auditDir, name, AUDIT_META_FILE),
20556
+ statsPath: join20(auditDir, name, auditStatsFileName(AUDIT_META_FILE))
19529
20557
  } : {
19530
- auditPath: join19(auditDir, name),
19531
- statsPath: join19(auditDir, auditStatsFileName(name))
20558
+ auditPath: join20(auditDir, name),
20559
+ statsPath: join20(auditDir, auditStatsFileName(name))
19532
20560
  }
19533
- ).filter((source) => existsSync24(source.auditPath));
20561
+ ).filter((source) => existsSync25(source.auditPath));
19534
20562
  } catch {
19535
20563
  return { requestCount: 0, errorCount: 0, complete: false };
19536
20564
  }
@@ -19628,7 +20656,7 @@ var AuditPruneSweeper = class {
19628
20656
  if (!this.config.enabled || this.sweeping) return 0;
19629
20657
  this.sweeping = true;
19630
20658
  try {
19631
- if (!existsSync25(this.auditDir)) return 0;
20659
+ if (!existsSync26(this.auditDir)) return 0;
19632
20660
  const cutoff = this.todayMidnight() - (this.config.retentionDays - 1) * DAY_MS4;
19633
20661
  let removed = 0;
19634
20662
  for (const name of readdirSync6(this.auditDir)) {
@@ -19636,11 +20664,11 @@ var AuditPruneSweeper = class {
19636
20664
  if (dateMs === null || dateMs >= cutoff) continue;
19637
20665
  try {
19638
20666
  if (isAuditDayDir(name)) {
19639
- rmSync4(join20(this.auditDir, name), { recursive: true, force: true });
20667
+ rmSync4(join21(this.auditDir, name), { recursive: true, force: true });
19640
20668
  } else {
19641
- unlinkSync13(join20(this.auditDir, name));
19642
- const statsPath = join20(this.auditDir, auditStatsFileName(name));
19643
- if (existsSync25(statsPath)) unlinkSync13(statsPath);
20669
+ unlinkSync13(join21(this.auditDir, name));
20670
+ const statsPath = join21(this.auditDir, auditStatsFileName(name));
20671
+ if (existsSync26(statsPath)) unlinkSync13(statsPath);
19644
20672
  }
19645
20673
  removed += 1;
19646
20674
  } catch (error) {
@@ -19670,14 +20698,14 @@ var AuditPruneSweeper = class {
19670
20698
  if (!this.config.enabled || this.archiving) return 0;
19671
20699
  this.archiving = true;
19672
20700
  try {
19673
- if (!existsSync25(this.auditDir)) return 0;
20701
+ if (!existsSync26(this.auditDir)) return 0;
19674
20702
  const today = this.todayMidnight();
19675
20703
  let compressed = 0;
19676
20704
  for (const name of readdirSync6(this.auditDir)) {
19677
20705
  if (compressed >= ARCHIVE_BATCH) break;
19678
20706
  const dateMs = auditFileDateMs(name);
19679
20707
  if (dateMs === null || dateMs >= today || !isAuditDayDir(name)) continue;
19680
- const dayPath = join20(this.auditDir, name);
20708
+ const dayPath = join21(this.auditDir, name);
19681
20709
  try {
19682
20710
  const compaction = compactAuditDay(dayPath);
19683
20711
  if (compaction.shards > 0) {
@@ -19695,7 +20723,7 @@ var AuditPruneSweeper = class {
19695
20723
  });
19696
20724
  }
19697
20725
  compressed += await this.archiveDay(
19698
- join20(dayPath, AUDIT_BODIES_DIR),
20726
+ join21(dayPath, AUDIT_BODIES_DIR),
19699
20727
  ARCHIVE_BATCH - compressed
19700
20728
  );
19701
20729
  }
@@ -19721,10 +20749,10 @@ var AuditPruneSweeper = class {
19721
20749
  let compressed = 0;
19722
20750
  for (const shard of shards) {
19723
20751
  if (compressed >= budget) break;
19724
- const source = join20(bodiesPath, shard);
20752
+ const source = join21(bodiesPath, shard);
19725
20753
  const target = `${source}.gz`;
19726
20754
  try {
19727
- if (existsSync25(target)) {
20755
+ if (existsSync26(target)) {
19728
20756
  unlinkSync13(source);
19729
20757
  continue;
19730
20758
  }
@@ -19733,7 +20761,7 @@ var AuditPruneSweeper = class {
19733
20761
  compressed += 1;
19734
20762
  } catch (error) {
19735
20763
  try {
19736
- if (existsSync25(target)) unlinkSync13(target);
20764
+ if (existsSync26(target)) unlinkSync13(target);
19737
20765
  } catch {
19738
20766
  }
19739
20767
  this.logger.warn("[AuditPruneSweeper] failed to archive audit body shard", {
@@ -19748,8 +20776,8 @@ var AuditPruneSweeper = class {
19748
20776
 
19749
20777
  // src/usage/usageMigrate.ts
19750
20778
  import { createReadStream as createReadStream4 } from "fs";
19751
- import { mkdir as mkdir2, open as open3, readdir as readdir2, rename as rename2, rm, stat, unlink as unlink2, writeFile as writeFile2 } from "fs/promises";
19752
- import { join as join21 } from "path";
20779
+ import { mkdir as mkdir2, open as open4, readdir as readdir3, rename as rename3, rm, stat as stat2, unlink as unlink3, writeFile as writeFile3 } from "fs/promises";
20780
+ import { join as join22 } from "path";
19753
20781
  import { createInterface } from "readline";
19754
20782
  var FLUSH_BYTES = 4 * 1024 * 1024;
19755
20783
  async function writeLine(writer2, line) {
@@ -19773,14 +20801,14 @@ var IDLE = {
19773
20801
  };
19774
20802
  async function migrateLegacyUsageEvents(opts) {
19775
20803
  const { eventsPath, usageDir, logger } = opts;
19776
- const legacy = await stat(eventsPath).catch(() => null);
20804
+ const legacy = await stat2(eventsPath).catch(() => null);
19777
20805
  if (!legacy || !legacy.isFile()) return IDLE;
19778
20806
  if (legacy.size === 0) {
19779
- await unlink2(eventsPath).catch(() => {
20807
+ await unlink3(eventsPath).catch(() => {
19780
20808
  });
19781
20809
  return { ...IDLE, migrated: true };
19782
20810
  }
19783
- const scratch = join21(usageDir, USAGE_MIGRATING_DIR);
20811
+ const scratch = join22(usageDir, USAGE_MIGRATING_DIR);
19784
20812
  logger?.info("[usage] migrating legacy usage-events.jsonl into day shards", {
19785
20813
  bytes: legacy.size
19786
20814
  });
@@ -19809,7 +20837,7 @@ async function migrateLegacyUsageEvents(opts) {
19809
20837
  let writer2 = writers.get(dayKey);
19810
20838
  if (!writer2) {
19811
20839
  writer2 = {
19812
- handle: await open3(join21(scratch, usageShardName(dayKey)), "a"),
20840
+ handle: await open4(join22(scratch, usageShardName(dayKey)), "a"),
19813
20841
  buffer: [],
19814
20842
  bytes: 0
19815
20843
  };
@@ -19839,17 +20867,17 @@ async function migrateLegacyUsageEvents(opts) {
19839
20867
  const today = usageDayKey(opts.now ?? Date.now());
19840
20868
  for (const [dayKey, acc] of rollups) {
19841
20869
  if (dayKey === today) continue;
19842
- const size = await stat(join21(scratch, usageShardName(dayKey))).then((s) => s.size).catch(() => null);
20870
+ const size = await stat2(join22(scratch, usageShardName(dayKey))).then((s) => s.size).catch(() => null);
19843
20871
  if (size === null) continue;
19844
- await writeFile2(
19845
- join21(scratch, usageRollupName(dayKey)),
20872
+ await writeFile3(
20873
+ join22(scratch, usageRollupName(dayKey)),
19846
20874
  JSON.stringify(acc.finish(dayKey, size)),
19847
20875
  "utf8"
19848
20876
  );
19849
20877
  }
19850
20878
  await mkdir2(usageDir, { recursive: true });
19851
- const staged = await readdir2(scratch);
19852
- const existing = new Set(await readdir2(usageDir).catch(() => []));
20879
+ const staged = await readdir3(scratch);
20880
+ const existing = new Set(await readdir3(usageDir).catch(() => []));
19853
20881
  const collisions = staged.filter((name) => existing.has(name));
19854
20882
  if (collisions.length > 0) {
19855
20883
  const reason = `refusing to overwrite existing shards in ${usageDir} (${collisions.slice(0, 3).join(", ")}${collisions.length > 3 ? ", \u2026" : ""}); a previous migration may have partially committed \u2014 move or remove them and restart`;
@@ -19859,11 +20887,11 @@ async function migrateLegacyUsageEvents(opts) {
19859
20887
  return { ...IDLE, linesRead, rowsWritten, skipped, reason };
19860
20888
  }
19861
20889
  for (const name of staged) {
19862
- await rename2(join21(scratch, name), join21(usageDir, name));
20890
+ await rename3(join22(scratch, name), join22(usageDir, name));
19863
20891
  }
19864
20892
  await rm(scratch, { recursive: true, force: true }).catch(() => {
19865
20893
  });
19866
- await unlink2(eventsPath);
20894
+ await unlink3(eventsPath);
19867
20895
  const days = rollups.size;
19868
20896
  logger?.info("[usage] migration complete; legacy usage-events.jsonl removed", {
19869
20897
  linesRead,
@@ -19884,8 +20912,8 @@ async function closeAll(writers) {
19884
20912
  }
19885
20913
 
19886
20914
  // src/usage/UsagePruneSweeper.ts
19887
- import { unlink as unlink3 } from "fs/promises";
19888
- import { join as join22 } from "path";
20915
+ import { unlink as unlink4 } from "fs/promises";
20916
+ import { join as join23 } from "path";
19889
20917
  var DAY_MS5 = 24 * 60 * 6e4;
19890
20918
  var SWEEP_INTERVAL_MS3 = 60 * 6e4;
19891
20919
  var DEFAULT_USAGE_RETENTION_DAYS = 90;
@@ -19966,7 +20994,7 @@ var UsagePruneSweeper = class {
19966
20994
  continue;
19967
20995
  }
19968
20996
  try {
19969
- await unlink3(join22(this.usageDir, usageShardName(entry.dayKey)));
20997
+ await unlink4(join23(this.usageDir, usageShardName(entry.dayKey)));
19970
20998
  removed += 1;
19971
20999
  } catch (error) {
19972
21000
  this.logger.warn("[usage] retention: could not remove expired shard", {
@@ -20001,8 +21029,8 @@ var UsagePruneSweeper = class {
20001
21029
  };
20002
21030
 
20003
21031
  // src/audit/auditBodyReader.ts
20004
- import { existsSync as existsSync26, readdirSync as readdirSync7, readFileSync as readFileSync21, statSync as statSync7 } from "fs";
20005
- import { join as join23 } from "path";
21032
+ import { existsSync as existsSync27, readdirSync as readdirSync7, readFileSync as readFileSync21, statSync as statSync7 } from "fs";
21033
+ import { join as join24 } from "path";
20006
21034
  import { gunzipSync } from "zlib";
20007
21035
 
20008
21036
  // src/audit/auditJsonl.ts
@@ -20065,7 +21093,7 @@ function forEachLineFromTail(path2, onLine) {
20065
21093
  function candidateDays(auditDir, ts) {
20066
21094
  if (typeof ts === "number" && Number.isFinite(ts)) {
20067
21095
  const named = auditDayDirName(ts);
20068
- if (existsSync26(join23(auditDir, named))) return [named];
21096
+ if (existsSync27(join24(auditDir, named))) return [named];
20069
21097
  }
20070
21098
  try {
20071
21099
  return readdirSync7(auditDir).filter(isAuditDayDir).sort().reverse();
@@ -20074,11 +21102,11 @@ function candidateDays(auditDir, ts) {
20074
21102
  }
20075
21103
  }
20076
21104
  function readShard(auditDir, day, sessionKey) {
20077
- const base = join23(auditDir, day, AUDIT_BODIES_DIR, auditBodyFileName(sessionKey));
21105
+ const base = join24(auditDir, day, AUDIT_BODIES_DIR, auditBodyFileName(sessionKey));
20078
21106
  try {
20079
- if (existsSync26(base)) return readFileSync21(base, "utf8");
21107
+ if (existsSync27(base)) return readFileSync21(base, "utf8");
20080
21108
  const gz = `${base}.gz`;
20081
- if (existsSync26(gz)) return gunzipSync(readFileSync21(gz)).toString("utf8");
21109
+ if (existsSync27(gz)) return gunzipSync(readFileSync21(gz)).toString("utf8");
20082
21110
  } catch {
20083
21111
  return null;
20084
21112
  }
@@ -20108,11 +21136,11 @@ function withDictionary(auditDir, day, entries) {
20108
21136
  }
20109
21137
  }
20110
21138
  if (!needed) return entries;
20111
- const base = join23(auditDir, day, AUDIT_BODIES_DIR, AUDIT_DICT_FILE);
21139
+ const base = join24(auditDir, day, AUDIT_BODIES_DIR, AUDIT_DICT_FILE);
20112
21140
  let raw = null;
20113
21141
  try {
20114
- if (existsSync26(base)) raw = readFileSync21(base, "utf8");
20115
- else if (existsSync26(`${base}.gz`)) raw = gunzipSync(readFileSync21(`${base}.gz`)).toString("utf8");
21142
+ if (existsSync27(base)) raw = readFileSync21(base, "utf8");
21143
+ else if (existsSync27(`${base}.gz`)) raw = gunzipSync(readFileSync21(`${base}.gz`)).toString("utf8");
20116
21144
  } catch {
20117
21145
  return entries;
20118
21146
  }
@@ -20145,7 +21173,7 @@ function reconstructRequest(entries, entry) {
20145
21173
  }
20146
21174
  function readAuditBody(auditDir, query2) {
20147
21175
  if (!isSafeSessionKey(query2.sessionKey) || !query2.id) return {};
20148
- if (!existsSync26(auditDir)) return {};
21176
+ if (!existsSync27(auditDir)) return {};
20149
21177
  for (const day of candidateDays(auditDir, query2.ts)) {
20150
21178
  const raw = readShard(auditDir, day, query2.sessionKey);
20151
21179
  if (raw === null) continue;
@@ -20170,7 +21198,7 @@ function readLegacyInlineBody(auditDir, id) {
20170
21198
  const needle = JSON.stringify(id);
20171
21199
  let found = {};
20172
21200
  for (const name of names) {
20173
- forEachLineFromTail(join23(auditDir, name), (line) => {
21201
+ forEachLineFromTail(join24(auditDir, name), (line) => {
20174
21202
  if (!line.includes(needle)) return false;
20175
21203
  let parsed;
20176
21204
  try {
@@ -20192,8 +21220,8 @@ function readLegacyInlineBody(auditDir, id) {
20192
21220
  }
20193
21221
 
20194
21222
  // src/audit/auditReader.ts
20195
- import { existsSync as existsSync27, readdirSync as readdirSync8 } from "fs";
20196
- import { join as join24 } from "path";
21223
+ import { existsSync as existsSync28, readdirSync as readdirSync8 } from "fs";
21224
+ import { join as join25 } from "path";
20197
21225
  var DEFAULT_LIMIT = 200;
20198
21226
  var MAX_LIMIT = 2e3;
20199
21227
  var OVERSCAN = 256;
@@ -20209,10 +21237,10 @@ function daySources(auditDir) {
20209
21237
  const dateMs = auditFileDateMs(name);
20210
21238
  if (dateMs === null) continue;
20211
21239
  if (AUDIT_DAY_DIR_RE.test(name)) {
20212
- const path2 = join24(auditDir, name, AUDIT_META_FILE);
20213
- if (existsSync27(path2)) sources.push({ path: path2, dateMs });
21240
+ const path2 = join25(auditDir, name, AUDIT_META_FILE);
21241
+ if (existsSync28(path2)) sources.push({ path: path2, dateMs });
20214
21242
  } else if (AUDIT_FILE_RE.test(name)) {
20215
- sources.push({ path: join24(auditDir, name), dateMs });
21243
+ sources.push({ path: join25(auditDir, name), dateMs });
20216
21244
  }
20217
21245
  }
20218
21246
  return sources.sort((a, b) => b.dateMs - a.dateMs);
@@ -20228,7 +21256,7 @@ function toMetaRecord(record) {
20228
21256
  return { ...meta, hasBody: true };
20229
21257
  }
20230
21258
  function readAuditRecords(auditDir, query2 = {}) {
20231
- if (!existsSync27(auditDir)) return [];
21259
+ if (!existsSync28(auditDir)) return [];
20232
21260
  const from = typeof query2.from === "number" ? query2.from : -Infinity;
20233
21261
  const to = typeof query2.to === "number" ? query2.to : Infinity;
20234
21262
  const limit = Math.min(MAX_LIMIT, Math.max(1, Math.trunc(query2.limit ?? DEFAULT_LIMIT)));
@@ -20256,8 +21284,8 @@ function readAuditRecords(auditDir, query2 = {}) {
20256
21284
  }
20257
21285
 
20258
21286
  // src/audit/AuditWriter.ts
20259
- import { appendFileSync as appendFileSync2, existsSync as existsSync28, mkdirSync as mkdirSync7, statSync as statSync8 } from "fs";
20260
- import { join as join25 } from "path";
21287
+ import { appendFileSync as appendFileSync2, existsSync as existsSync29, mkdirSync as mkdirSync7, statSync as statSync8 } from "fs";
21288
+ import { join as join26 } from "path";
20261
21289
  var AuditWriter = class {
20262
21290
  constructor(auditDir, logger, defer = (fn) => setTimeout(fn, 0)) {
20263
21291
  this.auditDir = auditDir;
@@ -20297,7 +21325,7 @@ var AuditWriter = class {
20297
21325
  */
20298
21326
  appendNow(record) {
20299
21327
  const dayDir = auditDayDirName(record.ts);
20300
- const dayPath = this.ensureDir(join25(this.auditDir, dayDir));
21328
+ const dayPath = this.ensureDir(join26(this.auditDir, dayDir));
20301
21329
  this.appendMeta(dayPath, record);
20302
21330
  this.appendBody(dayPath, dayDir, record);
20303
21331
  }
@@ -20312,9 +21340,9 @@ var AuditWriter = class {
20312
21340
  /** Write the body-free metadata line + refresh the exact-count sidecar. */
20313
21341
  appendMeta(dayPath, record) {
20314
21342
  const { requestBody: _req, responseBody: _res, ...meta } = record;
20315
- const file = join25(dayPath, AUDIT_META_FILE);
21343
+ const file = join26(dayPath, AUDIT_META_FILE);
20316
21344
  const line = JSON.stringify(meta) + "\n";
20317
- const bytesBefore = existsSync28(file) ? statSync8(file).size : 0;
21345
+ const bytesBefore = existsSync29(file) ? statSync8(file).size : 0;
20318
21346
  appendFileSync2(file, line, "utf8");
20319
21347
  try {
20320
21348
  updateAuditStatsAfterAppend(
@@ -20346,8 +21374,8 @@ var AuditWriter = class {
20346
21374
  try {
20347
21375
  const line = encodeBodyEntry(record, sessionKey, dayDir, this.bases);
20348
21376
  if (line === null) return;
20349
- const bodiesPath = this.ensureDir(join25(dayPath, AUDIT_BODIES_DIR));
20350
- appendFileSync2(join25(bodiesPath, auditBodyFileName(sessionKey)), line + "\n", "utf8");
21377
+ const bodiesPath = this.ensureDir(join26(dayPath, AUDIT_BODIES_DIR));
21378
+ appendFileSync2(join26(bodiesPath, auditBodyFileName(sessionKey)), line + "\n", "utf8");
20351
21379
  } catch (error) {
20352
21380
  this.bases.forget(sessionKey);
20353
21381
  this.logger.warn("[AuditWriter] failed to append audit body shard", {
@@ -20361,7 +21389,7 @@ var AuditWriter = class {
20361
21389
  // src/billing/BillingPublisher.ts
20362
21390
  import { appendFileSync as appendFileSync3, mkdirSync as mkdirSync8 } from "fs";
20363
21391
  import { createHmac as createHmac5 } from "crypto";
20364
- import { join as join26 } from "path";
21392
+ import { join as join27 } from "path";
20365
21393
  import { fetchUpstream as fetchUpstream14 } from "@omnicross/core/pipeline/upstreamFetch";
20366
21394
 
20367
21395
  // src/billing/billingFiles.ts
@@ -20432,7 +21460,7 @@ var BillingPublisher = class {
20432
21460
  */
20433
21461
  appendNow(event) {
20434
21462
  this.ensureDir();
20435
- const file = join26(this.billingDir, billingFileName(event.ts));
21463
+ const file = join27(this.billingDir, billingFileName(event.ts));
20436
21464
  appendFileSync3(file, JSON.stringify(event) + "\n", "utf8");
20437
21465
  }
20438
21466
  /**
@@ -20482,7 +21510,7 @@ var BillingPublisher = class {
20482
21510
  markDelivered(event) {
20483
21511
  try {
20484
21512
  this.ensureDir();
20485
- const file = join26(this.billingDir, deliveredFileName(event.ts));
21513
+ const file = join27(this.billingDir, deliveredFileName(event.ts));
20486
21514
  appendFileSync3(file, JSON.stringify({ id: event.id, deliveredAt: this.now() }) + "\n", "utf8");
20487
21515
  } catch (error) {
20488
21516
  this.logger.warn("[BillingPublisher] failed to append delivery marker", {
@@ -20498,11 +21526,11 @@ var BillingPublisher = class {
20498
21526
  };
20499
21527
 
20500
21528
  // src/billing/billingReader.ts
20501
- import { existsSync as existsSync29, readdirSync as readdirSync9, readFileSync as readFileSync22 } from "fs";
20502
- import { join as join27 } from "path";
21529
+ import { existsSync as existsSync30, readdirSync as readdirSync9, readFileSync as readFileSync22 } from "fs";
21530
+ import { join as join28 } from "path";
20503
21531
  function readBillingLedger(billingDir) {
20504
21532
  const view = { events: [], deliveredIds: /* @__PURE__ */ new Set() };
20505
- if (!existsSync29(billingDir)) return view;
21533
+ if (!existsSync30(billingDir)) return view;
20506
21534
  let files;
20507
21535
  try {
20508
21536
  files = readdirSync9(billingDir);
@@ -20536,7 +21564,7 @@ function readBillingStatus(billingDir) {
20536
21564
  function parseLines(dir, file) {
20537
21565
  let raw;
20538
21566
  try {
20539
- raw = readFileSync22(join27(dir, file), "utf8");
21567
+ raw = readFileSync22(join28(dir, file), "utf8");
20540
21568
  } catch {
20541
21569
  return [];
20542
21570
  }
@@ -21348,6 +22376,7 @@ function buildDaemon(config, paths) {
21348
22376
  });
21349
22377
  const auditDir = defaultAuditDir(paths.configPath);
21350
22378
  const billingDir = defaultBillingDir(paths.configPath);
22379
+ const codexSessionManager = new CodexSessionManager();
21351
22380
  const adminServer = new AdminServer({
21352
22381
  configPath: paths.configPath,
21353
22382
  llmConfig,
@@ -21445,6 +22474,10 @@ function buildDaemon(config, paths) {
21445
22474
  cliTerminalOpener: paths.cliTerminalOpener,
21446
22475
  cliPathProbe: paths.cliPathProbe,
21447
22476
  cliCommandRunner: paths.cliCommandRunner,
22477
+ // One helper invocation shared by the integration install and KEY-SCOPED
22478
+ // launches (the latter append `--key-id` per spawn) — same entrypoint, same
22479
+ // config/master-key resolution, so the two paths can never drift.
22480
+ codexAuthHelper: currentProcessCodexAuthHelper(paths.configPath, paths.masterKeyFilePath),
21448
22481
  integrationManagerFactory: () => {
21449
22482
  const live = outboundApiServer.getStatus();
21450
22483
  const port = live.port || decryptedConfig.server?.port || DEFAULT_OUTBOUND_PORT;
@@ -21489,7 +22522,8 @@ function buildDaemon(config, paths) {
21489
22522
  auditCompactor: () => compactAllClosedAuditDays(auditDir),
21490
22523
  // billing-event-stream: the AUTHED `GET /admin/api/billing-status` returns the
21491
22524
  // secret-free total/delivered/pending counts of the durable ledger.
21492
- billingStatusReader: () => readBillingStatus(billingDir)
22525
+ billingStatusReader: () => readBillingStatus(billingDir),
22526
+ codexSessionManager
21493
22527
  });
21494
22528
  const webhookDispatcher = new WebhookDispatcher({
21495
22529
  logger,
@@ -21555,6 +22589,7 @@ function buildDaemon(config, paths) {
21555
22589
  pricingEngine,
21556
22590
  pricingRefreshScheduler,
21557
22591
  usageRecorder,
22592
+ codexSessionManager,
21558
22593
  adminServer,
21559
22594
  tokenRefreshScheduler,
21560
22595
  accountHealthSweeper,
@@ -21590,7 +22625,7 @@ function resetDaemonSingletonsForTests() {
21590
22625
  }
21591
22626
  function isTokensStoreReadable(tokensPath) {
21592
22627
  try {
21593
- if (!existsSync30(tokensPath)) return true;
22628
+ if (!existsSync31(tokensPath)) return true;
21594
22629
  accessSync(tokensPath, fsConstants.R_OK);
21595
22630
  return true;
21596
22631
  } catch {
@@ -21695,6 +22730,8 @@ function mapCcrToOmnicross(ccr) {
21695
22730
  }
21696
22731
  export {
21697
22732
  AdminServer,
22733
+ CodexSessionManager,
22734
+ CodexSessionManagerError,
21698
22735
  ConfigFileProviderConfigSource,
21699
22736
  ConfigurableLogger,
21700
22737
  ConsoleLogger,
@@ -21714,6 +22751,7 @@ export {
21714
22751
  loadConfig,
21715
22752
  mapCcrToOmnicross,
21716
22753
  parseCcrConfig,
22754
+ replaceStructuredProviderFields,
21717
22755
  resetDaemonSingletonsForTests,
21718
22756
  resolveAdminConfig,
21719
22757
  saveConfig,