@omnicross/daemon 0.1.7 → 0.1.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +511 -99
- package/dist/cli.js +536 -114
- package/dist/index.cjs +450 -52
- package/dist/index.d.cts +7 -2
- package/dist/index.d.ts +7 -2
- package/dist/index.js +475 -65
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -60,13 +60,14 @@ var import_GeminiCodeAssistProjectResolver = require("@omnicross/core/auth/Gemin
|
|
|
60
60
|
var import_ApiKeyPoolService = require("@omnicross/core/completion/ApiKeyPoolService");
|
|
61
61
|
var import_outbound_api4 = require("@omnicross/core/outbound-api");
|
|
62
62
|
var import_subscriptionRegistryPort = require("@omnicross/core/outbound-api/subscriptionRegistryPort");
|
|
63
|
-
var
|
|
63
|
+
var import_SubscriptionAccountHealth4 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
|
|
64
64
|
var import_AccountAllowanceStore4 = require("@omnicross/core/pipeline/AccountAllowanceStore");
|
|
65
|
-
var
|
|
65
|
+
var import_AccountAllowanceScheduling5 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
|
|
66
66
|
var import_upstreamFetch8 = require("@omnicross/core/pipeline/upstreamFetch");
|
|
67
67
|
var import_SubscriptionIdentityStore3 = require("@omnicross/core/provider-proxy/identity/SubscriptionIdentityStore");
|
|
68
68
|
var import_gemini_code_assist_resolver = require("@omnicross/core/ports/gemini-code-assist-resolver");
|
|
69
|
-
var
|
|
69
|
+
var import_provider_proxy4 = require("@omnicross/core/provider-proxy");
|
|
70
|
+
var import_cli_launcher2 = require("@omnicross/cli-launcher");
|
|
70
71
|
var import_outbound_api5 = require("@omnicross/core/outbound-api");
|
|
71
72
|
var import_usage = require("@omnicross/core/usage");
|
|
72
73
|
var import_subscriptions4 = require("@omnicross/subscriptions");
|
|
@@ -756,6 +757,88 @@ async function handleWebhookTest(req, res) {
|
|
|
756
757
|
res.end(JSON.stringify({ result }));
|
|
757
758
|
}
|
|
758
759
|
|
|
760
|
+
// src/admin/routeLeaseApi.ts
|
|
761
|
+
var import_provider_proxy = require("@omnicross/core/provider-proxy");
|
|
762
|
+
var MAX_BODY_BYTES = 64 * 1024;
|
|
763
|
+
var SAFE_LEASE_ID = /^[A-Za-z0-9-]{1,128}$/u;
|
|
764
|
+
async function readJson(req) {
|
|
765
|
+
const chunks = [];
|
|
766
|
+
let bytes = 0;
|
|
767
|
+
for await (const chunk of req) {
|
|
768
|
+
const buffer = Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk);
|
|
769
|
+
bytes += buffer.length;
|
|
770
|
+
if (bytes > MAX_BODY_BYTES) throw new import_provider_proxy.RouteLeaseError("invalid_request", "request body is too large");
|
|
771
|
+
chunks.push(buffer);
|
|
772
|
+
}
|
|
773
|
+
if (chunks.length === 0) return {};
|
|
774
|
+
try {
|
|
775
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
776
|
+
} catch {
|
|
777
|
+
throw new import_provider_proxy.RouteLeaseError("invalid_request", "request body is not valid JSON");
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function json(res, status, body, noStore = false) {
|
|
781
|
+
res.statusCode = status;
|
|
782
|
+
res.setHeader("Content-Type", "application/json");
|
|
783
|
+
if (noStore) res.setHeader("Cache-Control", "no-store");
|
|
784
|
+
res.end(JSON.stringify(body));
|
|
785
|
+
}
|
|
786
|
+
function leaseId(value) {
|
|
787
|
+
if (!value || !SAFE_LEASE_ID.test(value)) throw new import_provider_proxy.RouteLeaseError("invalid_request", "lease id is invalid");
|
|
788
|
+
return value;
|
|
789
|
+
}
|
|
790
|
+
function header(req, name) {
|
|
791
|
+
const value = req.headers[name.toLowerCase()];
|
|
792
|
+
return Array.isArray(value) ? value[0] : value;
|
|
793
|
+
}
|
|
794
|
+
function writeError(res, error, noStore) {
|
|
795
|
+
const safe = error instanceof import_provider_proxy.RouteLeaseError ? error : new import_provider_proxy.RouteLeaseError("upstream_unavailable", "route lease operation failed safely");
|
|
796
|
+
if (safe.retryAfterSeconds !== void 0) res.setHeader("Retry-After", String(safe.retryAfterSeconds));
|
|
797
|
+
json(res, safe.status, safe.toResponse(), noStore);
|
|
798
|
+
}
|
|
799
|
+
async function handleRouteLeaseApi(req, res, path2, deps) {
|
|
800
|
+
const method = (req.method ?? "GET").toUpperCase();
|
|
801
|
+
const noStore = method === "POST" && (path2 === "/admin/api/route-leases" || path2.endsWith("/renew"));
|
|
802
|
+
try {
|
|
803
|
+
if (!(0, import_provider_proxy.isLoopbackAddress)(req.socket.remoteAddress)) {
|
|
804
|
+
throw new import_provider_proxy.RouteLeaseError("control_unauthorized", "route lease control plane is loopback only");
|
|
805
|
+
}
|
|
806
|
+
const manager = deps.routeLeaseManager;
|
|
807
|
+
if (!manager) throw new import_provider_proxy.RouteLeaseError("daemon_not_ready", "route lease manager is unavailable");
|
|
808
|
+
const base = "/admin/api/route-leases";
|
|
809
|
+
const suffix = path2.slice(base.length).replace(/^\/+|\/+$/gu, "");
|
|
810
|
+
const segments = suffix ? suffix.split("/") : [];
|
|
811
|
+
if (segments.length === 1 && segments[0] === "capabilities") {
|
|
812
|
+
if (method !== "GET" && method !== "HEAD") throw new import_provider_proxy.RouteLeaseError("invalid_request", "method is not allowed");
|
|
813
|
+
return json(res, 200, import_provider_proxy.ROUTE_LEASE_CAPABILITIES);
|
|
814
|
+
}
|
|
815
|
+
if (segments.length === 0) {
|
|
816
|
+
if (method === "GET") return json(res, 200, { leases: manager.list() });
|
|
817
|
+
if (method === "POST") {
|
|
818
|
+
const outcome = await manager.createFromRequest(await readJson(req), header(req, "idempotency-key"));
|
|
819
|
+
return json(res, outcome.created ? 201 : 200, outcome.result, true);
|
|
820
|
+
}
|
|
821
|
+
throw new import_provider_proxy.RouteLeaseError("invalid_request", "method is not allowed");
|
|
822
|
+
}
|
|
823
|
+
const id = leaseId(segments[0]);
|
|
824
|
+
if (segments.length === 1) {
|
|
825
|
+
if (method === "GET") return json(res, 200, manager.get(id));
|
|
826
|
+
if (method === "DELETE") return json(res, 200, manager.release(id));
|
|
827
|
+
throw new import_provider_proxy.RouteLeaseError("invalid_request", "method is not allowed");
|
|
828
|
+
}
|
|
829
|
+
if (segments.length === 2 && segments[1] === "renew" && method === "POST") {
|
|
830
|
+
const body = await readJson(req);
|
|
831
|
+
const ttl = (0, import_provider_proxy.normalizeRouteLeaseTtl)(
|
|
832
|
+
body && typeof body === "object" && !Array.isArray(body) ? body.ttlSeconds : void 0
|
|
833
|
+
);
|
|
834
|
+
return json(res, 200, manager.renew(id, ttl), true);
|
|
835
|
+
}
|
|
836
|
+
throw new import_provider_proxy.RouteLeaseError("lease_not_found", "route lease endpoint was not found");
|
|
837
|
+
} catch (error) {
|
|
838
|
+
writeError(res, error, noStore);
|
|
839
|
+
}
|
|
840
|
+
}
|
|
841
|
+
|
|
759
842
|
// src/admin/adminApi.ts
|
|
760
843
|
var import_node_http = __toESM(require("http"), 1);
|
|
761
844
|
var import_outbound_api2 = require("@omnicross/core/outbound-api");
|
|
@@ -2611,8 +2694,34 @@ async function exchangeGemini(code, codeVerifier, exchangeFetch) {
|
|
|
2611
2694
|
var import_node_child_process = require("child_process");
|
|
2612
2695
|
var import_node_crypto6 = require("crypto");
|
|
2613
2696
|
var import_node_fs6 = require("fs");
|
|
2697
|
+
var import_node_net = require("net");
|
|
2698
|
+
var import_node_os3 = require("os");
|
|
2614
2699
|
var import_node_path5 = require("path");
|
|
2615
2700
|
var import_cli_launcher = require("@omnicross/cli-launcher");
|
|
2701
|
+
var import_provider_proxy2 = require("@omnicross/core/provider-proxy");
|
|
2702
|
+
|
|
2703
|
+
// src/routeLeaseRenewal.ts
|
|
2704
|
+
var TERMINAL_LEASE_TTL_SECONDS = 600;
|
|
2705
|
+
var TERMINAL_LEASE_RENEW_INTERVAL_MS = 5 * 60 * 1e3;
|
|
2706
|
+
var TERMINAL_LEASE_MAX_LIFETIME_MS = 24 * 60 * 60 * 1e3;
|
|
2707
|
+
function startTerminalLeaseRenewal(manager, leaseId2) {
|
|
2708
|
+
const stopAt = Date.now() + TERMINAL_LEASE_MAX_LIFETIME_MS;
|
|
2709
|
+
const timer = setInterval(() => {
|
|
2710
|
+
if (Date.now() >= stopAt) {
|
|
2711
|
+
clearInterval(timer);
|
|
2712
|
+
return;
|
|
2713
|
+
}
|
|
2714
|
+
try {
|
|
2715
|
+
manager.renew(leaseId2, TERMINAL_LEASE_TTL_SECONDS);
|
|
2716
|
+
} catch {
|
|
2717
|
+
clearInterval(timer);
|
|
2718
|
+
}
|
|
2719
|
+
}, TERMINAL_LEASE_RENEW_INTERVAL_MS);
|
|
2720
|
+
timer.unref?.();
|
|
2721
|
+
return () => clearInterval(timer);
|
|
2722
|
+
}
|
|
2723
|
+
|
|
2724
|
+
// src/admin/cliLaunch.ts
|
|
2616
2725
|
var LAUNCHABLE_CLIS = [
|
|
2617
2726
|
{ id: "claude", displayName: "Claude Code", command: "claude" },
|
|
2618
2727
|
{ id: "codex", displayName: "Codex CLI", command: "codex" },
|
|
@@ -2693,34 +2802,183 @@ async function buildLaunchEnv(cli, llmConfig, target) {
|
|
|
2693
2802
|
function shq(s) {
|
|
2694
2803
|
return `'${s.replace(/'/g, `'\\''`)}'`;
|
|
2695
2804
|
}
|
|
2696
|
-
var
|
|
2805
|
+
var MAC_TERMINAL_BOOTSTRAP_SOURCE = `
|
|
2806
|
+
'use strict';
|
|
2807
|
+
const fs = require('node:fs');
|
|
2808
|
+
const net = require('node:net');
|
|
2809
|
+
const { spawn } = require('node:child_process');
|
|
2810
|
+
const [socketPath, launchDir, cwd, command, ...args] = process.argv.slice(2);
|
|
2811
|
+
let payload = '';
|
|
2812
|
+
const socket = net.createConnection(socketPath);
|
|
2813
|
+
socket.setEncoding('utf8');
|
|
2814
|
+
socket.on('data', (chunk) => { payload += chunk; });
|
|
2815
|
+
socket.on('end', () => {
|
|
2816
|
+
const descriptor = JSON.parse(payload);
|
|
2817
|
+
if (!descriptor || Array.isArray(descriptor) || Object.values(descriptor).some((value) => typeof value !== 'string')) {
|
|
2818
|
+
throw new Error('invalid terminal launch descriptor');
|
|
2819
|
+
}
|
|
2820
|
+
try { fs.rmSync(launchDir, { recursive: true, force: true }); } catch {}
|
|
2821
|
+
const child = spawn(command, args, {
|
|
2822
|
+
cwd: cwd || undefined,
|
|
2823
|
+
env: { ...process.env, ...descriptor },
|
|
2824
|
+
stdio: 'inherit',
|
|
2825
|
+
});
|
|
2826
|
+
child.on('error', (error) => { console.error(error.message); process.exitCode = 1; });
|
|
2827
|
+
child.on('exit', (code, signal) => {
|
|
2828
|
+
if (signal) process.kill(process.pid, signal);
|
|
2829
|
+
else process.exitCode = code == null ? 1 : code;
|
|
2830
|
+
});
|
|
2831
|
+
});
|
|
2832
|
+
socket.on('error', (error) => { console.error(error.message); process.exitCode = 1; });
|
|
2833
|
+
`;
|
|
2834
|
+
var MAC_TERMINAL_IPC_TIMEOUT_MS = 12e4;
|
|
2835
|
+
function openTerminal({ cli, command, extraArgs, env, cwd, platform, onFailure }, spawnProcess = import_node_child_process.spawn, macIpc = {}) {
|
|
2697
2836
|
const childEnv = { ...process.env, ...env };
|
|
2698
2837
|
if (platform === "win32") {
|
|
2699
2838
|
const args = ["/c", "start", `"omnicross ${cli}"`];
|
|
2700
2839
|
if (cwd) args.push("/D", `"${cwd}"`);
|
|
2701
2840
|
args.push("cmd", "/k", command, ...extraArgs);
|
|
2702
|
-
(
|
|
2841
|
+
spawnProcess(process.env["ComSpec"] || "cmd.exe", args, {
|
|
2703
2842
|
env: childEnv,
|
|
2704
2843
|
windowsVerbatimArguments: true,
|
|
2705
2844
|
detached: true,
|
|
2706
2845
|
stdio: "ignore"
|
|
2707
2846
|
}).unref();
|
|
2708
|
-
return
|
|
2847
|
+
return () => {
|
|
2848
|
+
};
|
|
2709
2849
|
}
|
|
2710
|
-
const exportLine = Object.entries(env).map(([k, v]) => `export ${k}=${shq(v)}`).join("; ");
|
|
2711
2850
|
const runLine = [command, ...extraArgs].map(shq).join(" ");
|
|
2712
|
-
const script = `${
|
|
2851
|
+
const script = `${cwd ? `cd ${shq(cwd)}; ` : ""}${runLine}`;
|
|
2713
2852
|
if (platform === "darwin") {
|
|
2714
|
-
const
|
|
2715
|
-
(0,
|
|
2716
|
-
|
|
2853
|
+
const launchDir = (0, import_node_fs6.mkdtempSync)((0, import_node_path5.join)((0, import_node_os3.tmpdir)(), "omnicross-terminal-"));
|
|
2854
|
+
const commandFile = (0, import_node_path5.join)(launchDir, "launch.command");
|
|
2855
|
+
const bootstrapFile = (0, import_node_path5.join)(launchDir, "bootstrap.cjs");
|
|
2856
|
+
const socketPath = macIpc.socketPath ?? (0, import_node_path5.join)(launchDir, "descriptor.sock");
|
|
2857
|
+
const openerEnv = { ...process.env };
|
|
2858
|
+
for (const key of Object.keys(env)) delete openerEnv[key];
|
|
2859
|
+
let claimed = false;
|
|
2860
|
+
let cleaned = false;
|
|
2861
|
+
let failureNotified = false;
|
|
2862
|
+
let timer;
|
|
2863
|
+
const notifyFailure = () => {
|
|
2864
|
+
cleanup();
|
|
2865
|
+
if (failureNotified) return;
|
|
2866
|
+
failureNotified = true;
|
|
2867
|
+
try {
|
|
2868
|
+
onFailure?.();
|
|
2869
|
+
} catch {
|
|
2870
|
+
}
|
|
2871
|
+
};
|
|
2872
|
+
const handleLaunchFailure = () => {
|
|
2873
|
+
if (claimed) cleanup();
|
|
2874
|
+
else notifyFailure();
|
|
2875
|
+
};
|
|
2876
|
+
const sockets = /* @__PURE__ */ new Set();
|
|
2877
|
+
const server = (0, import_node_net.createServer)((socket) => {
|
|
2878
|
+
socket.unref();
|
|
2879
|
+
sockets.add(socket);
|
|
2880
|
+
socket.once("close", () => sockets.delete(socket));
|
|
2881
|
+
try {
|
|
2882
|
+
macIpc.onAccepted?.(socket);
|
|
2883
|
+
} catch {
|
|
2884
|
+
cleanup();
|
|
2885
|
+
return;
|
|
2886
|
+
}
|
|
2887
|
+
if (claimed || cleaned) {
|
|
2888
|
+
socket.destroy();
|
|
2889
|
+
return;
|
|
2890
|
+
}
|
|
2891
|
+
claimed = true;
|
|
2892
|
+
try {
|
|
2893
|
+
macIpc.onClaimed?.();
|
|
2894
|
+
if (cleaned) return;
|
|
2895
|
+
socket.end(JSON.stringify(env), cleanup);
|
|
2896
|
+
} catch {
|
|
2897
|
+
cleanup();
|
|
2898
|
+
}
|
|
2899
|
+
});
|
|
2900
|
+
const cleanup = () => {
|
|
2901
|
+
if (!cleaned) {
|
|
2902
|
+
cleaned = true;
|
|
2903
|
+
if (timer) clearTimeout(timer);
|
|
2904
|
+
for (const socket of sockets) socket.destroy();
|
|
2905
|
+
sockets.clear();
|
|
2906
|
+
try {
|
|
2907
|
+
server.close();
|
|
2908
|
+
} catch {
|
|
2909
|
+
}
|
|
2910
|
+
}
|
|
2911
|
+
try {
|
|
2912
|
+
if (macIpc.removeArtifacts) {
|
|
2913
|
+
macIpc.removeArtifacts(launchDir);
|
|
2914
|
+
} else {
|
|
2915
|
+
(0, import_node_fs6.rmSync)(launchDir, {
|
|
2916
|
+
recursive: true,
|
|
2917
|
+
force: true,
|
|
2918
|
+
maxRetries: 3,
|
|
2919
|
+
retryDelay: 20
|
|
2920
|
+
});
|
|
2921
|
+
}
|
|
2922
|
+
} catch {
|
|
2923
|
+
}
|
|
2924
|
+
};
|
|
2925
|
+
try {
|
|
2926
|
+
(0, import_node_fs6.writeFileSync)(bootstrapFile, MAC_TERMINAL_BOOTSTRAP_SOURCE, { encoding: "utf8", mode: 448 });
|
|
2927
|
+
(0, import_node_fs6.writeFileSync)(commandFile, `#!/bin/bash
|
|
2928
|
+
rm -f -- "$0"
|
|
2929
|
+
exec ${shq(process.execPath)} ${shq(bootstrapFile)} ${shq(socketPath)} ${shq(launchDir)} ${shq(cwd ?? "")} ${runLine}
|
|
2930
|
+
`, {
|
|
2931
|
+
encoding: "utf8",
|
|
2932
|
+
mode: 448
|
|
2933
|
+
});
|
|
2934
|
+
(0, import_node_fs6.chmodSync)(commandFile, 448);
|
|
2935
|
+
(0, import_node_fs6.chmodSync)(bootstrapFile, 448);
|
|
2936
|
+
server.once("error", handleLaunchFailure);
|
|
2937
|
+
server.listen(socketPath, () => {
|
|
2938
|
+
if (cleaned) return;
|
|
2939
|
+
try {
|
|
2940
|
+
macIpc.onListening?.();
|
|
2941
|
+
if (cleaned) return;
|
|
2942
|
+
if (process.platform !== "win32") (0, import_node_fs6.chmodSync)(socketPath, 384);
|
|
2943
|
+
const opener = spawnProcess("open", ["-n", "-a", "Terminal", commandFile], {
|
|
2944
|
+
env: openerEnv,
|
|
2945
|
+
detached: true,
|
|
2946
|
+
stdio: "ignore"
|
|
2947
|
+
});
|
|
2948
|
+
opener.once("error", handleLaunchFailure);
|
|
2949
|
+
opener.unref();
|
|
2950
|
+
server.unref();
|
|
2951
|
+
} catch {
|
|
2952
|
+
handleLaunchFailure();
|
|
2953
|
+
}
|
|
2954
|
+
});
|
|
2955
|
+
timer = setTimeout(handleLaunchFailure, macIpc.timeoutMs ?? MAC_TERMINAL_IPC_TIMEOUT_MS);
|
|
2956
|
+
timer.unref?.();
|
|
2957
|
+
return cleanup;
|
|
2958
|
+
} catch (error) {
|
|
2959
|
+
cleanup();
|
|
2960
|
+
throw error;
|
|
2961
|
+
}
|
|
2717
2962
|
}
|
|
2718
|
-
(
|
|
2963
|
+
spawnProcess("x-terminal-emulator", ["-e", "bash", "-lc", `${script}; exec bash`], {
|
|
2964
|
+
env: childEnv,
|
|
2719
2965
|
detached: true,
|
|
2720
2966
|
stdio: "ignore"
|
|
2721
2967
|
}).unref();
|
|
2722
|
-
|
|
2968
|
+
return () => {
|
|
2969
|
+
};
|
|
2970
|
+
}
|
|
2971
|
+
var defaultTerminalOpener = (input) => openTerminal(input);
|
|
2723
2972
|
var sessions = /* @__PURE__ */ new Map();
|
|
2973
|
+
function resetCliSessions() {
|
|
2974
|
+
for (const s of sessions.values()) {
|
|
2975
|
+
try {
|
|
2976
|
+
s.onSessionEnd();
|
|
2977
|
+
} catch {
|
|
2978
|
+
}
|
|
2979
|
+
}
|
|
2980
|
+
sessions.clear();
|
|
2981
|
+
}
|
|
2724
2982
|
function errBody(message) {
|
|
2725
2983
|
return { error: { type: "admin_api_error", message } };
|
|
2726
2984
|
}
|
|
@@ -2775,29 +3033,81 @@ async function handleCliLaunch(cli, body, ctx) {
|
|
|
2775
3033
|
} catch (err5) {
|
|
2776
3034
|
return { status: 400, body: errBody(err5 instanceof Error ? err5.message : "no launch target") };
|
|
2777
3035
|
}
|
|
3036
|
+
const id = (0, import_node_crypto6.randomUUID)();
|
|
3037
|
+
let leaseId2;
|
|
2778
3038
|
let launch;
|
|
2779
3039
|
try {
|
|
2780
|
-
|
|
3040
|
+
if ((cli === "claude" || cli === "codex") && ctx.routeLeaseManager) {
|
|
3041
|
+
const outcome = await ctx.routeLeaseManager.createFromRequest({
|
|
3042
|
+
schemaVersion: import_provider_proxy2.ROUTE_LEASE_REQUEST_SCHEMA,
|
|
3043
|
+
consumer: "omnicross-terminal",
|
|
3044
|
+
runtime: cli,
|
|
3045
|
+
upstream: { kind: "provider", providerId: target.providerId },
|
|
3046
|
+
model: target.model,
|
|
3047
|
+
execution: { sessionId: id }
|
|
3048
|
+
}, `omnicross-terminal:${id}`);
|
|
3049
|
+
leaseId2 = outcome.result.leaseId;
|
|
3050
|
+
const stopRenewal = startTerminalLeaseRenewal(ctx.routeLeaseManager, leaseId2);
|
|
3051
|
+
launch = {
|
|
3052
|
+
env: outcome.result.launch.env,
|
|
3053
|
+
extraArgs: outcome.result.launch.extraArgs,
|
|
3054
|
+
onSessionEnd: () => {
|
|
3055
|
+
stopRenewal();
|
|
3056
|
+
ctx.routeLeaseManager?.release(outcome.result.leaseId);
|
|
3057
|
+
}
|
|
3058
|
+
};
|
|
3059
|
+
} else {
|
|
3060
|
+
launch = await buildLaunchEnv(cli, ctx.llmConfig, target);
|
|
3061
|
+
}
|
|
2781
3062
|
} catch (err5) {
|
|
2782
|
-
|
|
3063
|
+
const status = err5 instanceof import_provider_proxy2.RouteLeaseError ? err5.status : 400;
|
|
3064
|
+
return { status, body: errBody(err5 instanceof Error ? err5.message : "failed to build launch env") };
|
|
2783
3065
|
}
|
|
2784
3066
|
const cwd = typeof body["cwd"] === "string" && body["cwd"].trim() ? body["cwd"].trim() : void 0;
|
|
2785
3067
|
const opener = ctx.opener ?? defaultTerminalOpener;
|
|
3068
|
+
let openerCleanup;
|
|
3069
|
+
let ended = false;
|
|
3070
|
+
let published = false;
|
|
3071
|
+
const onSessionEnd = () => {
|
|
3072
|
+
if (ended) return;
|
|
3073
|
+
ended = true;
|
|
3074
|
+
if (published) sessions.delete(id);
|
|
3075
|
+
try {
|
|
3076
|
+
openerCleanup?.();
|
|
3077
|
+
} finally {
|
|
3078
|
+
launch.onSessionEnd();
|
|
3079
|
+
}
|
|
3080
|
+
};
|
|
2786
3081
|
try {
|
|
2787
|
-
opener({
|
|
3082
|
+
const cleanup = opener({
|
|
3083
|
+
cli,
|
|
3084
|
+
command: meta.command,
|
|
3085
|
+
extraArgs: launch.extraArgs ?? [],
|
|
3086
|
+
env: launch.env,
|
|
3087
|
+
cwd,
|
|
3088
|
+
platform,
|
|
3089
|
+
onFailure: onSessionEnd
|
|
3090
|
+
});
|
|
3091
|
+
if (cleanup) openerCleanup = cleanup;
|
|
2788
3092
|
} catch (err5) {
|
|
2789
|
-
|
|
3093
|
+
onSessionEnd();
|
|
2790
3094
|
return { status: 500, body: errBody(err5 instanceof Error ? err5.message : "failed to open terminal") };
|
|
2791
3095
|
}
|
|
2792
|
-
|
|
3096
|
+
if (ended) {
|
|
3097
|
+
openerCleanup?.();
|
|
3098
|
+
return { status: 500, body: errBody("failed to open terminal") };
|
|
3099
|
+
}
|
|
2793
3100
|
sessions.set(id, {
|
|
2794
3101
|
id,
|
|
2795
3102
|
cli,
|
|
2796
3103
|
providerId: target.providerId,
|
|
2797
3104
|
model: target.model,
|
|
3105
|
+
...leaseId2 ? { leaseId: leaseId2 } : {},
|
|
2798
3106
|
startedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2799
|
-
onSessionEnd
|
|
3107
|
+
onSessionEnd
|
|
2800
3108
|
});
|
|
3109
|
+
published = true;
|
|
3110
|
+
if (ended) sessions.delete(id);
|
|
2801
3111
|
return { status: 200, body: { sessionId: id, providerId: target.providerId, model: target.model } };
|
|
2802
3112
|
}
|
|
2803
3113
|
|
|
@@ -3689,7 +3999,7 @@ function sealPack(bundleJson, passphrase) {
|
|
|
3689
3999
|
cipher.setAAD(aadFor(PACK_MAGIC, PACK_VERSION, KDF_ALGORITHM));
|
|
3690
4000
|
const ciphertext = Buffer.concat([cipher.update(bundleJson, "utf8"), cipher.final()]);
|
|
3691
4001
|
const tag = cipher.getAuthTag();
|
|
3692
|
-
const
|
|
4002
|
+
const header2 = {
|
|
3693
4003
|
magic: PACK_MAGIC,
|
|
3694
4004
|
v: PACK_VERSION,
|
|
3695
4005
|
kdf: KDF_ALGORITHM,
|
|
@@ -3700,7 +4010,7 @@ function sealPack(bundleJson, passphrase) {
|
|
|
3700
4010
|
iv: iv.toString("base64"),
|
|
3701
4011
|
tag: tag.toString("base64")
|
|
3702
4012
|
};
|
|
3703
|
-
return `${PACK_PREFIX}${toB64Url(JSON.stringify(
|
|
4013
|
+
return `${PACK_PREFIX}${toB64Url(JSON.stringify(header2))}.${ciphertext.toString("base64")}`;
|
|
3704
4014
|
}
|
|
3705
4015
|
function parsePack(packString) {
|
|
3706
4016
|
if (typeof packString !== "string" || !packString.startsWith(PACK_PREFIX)) {
|
|
@@ -3711,28 +4021,28 @@ function parsePack(packString) {
|
|
|
3711
4021
|
if (dot < 0) throw new PackAuthError("migration pack is malformed (missing body)");
|
|
3712
4022
|
const headerB64Url = rest.slice(0, dot);
|
|
3713
4023
|
const ctB64 = rest.slice(dot + 1);
|
|
3714
|
-
let
|
|
4024
|
+
let header2;
|
|
3715
4025
|
try {
|
|
3716
|
-
|
|
4026
|
+
header2 = JSON.parse(fromB64Url(headerB64Url));
|
|
3717
4027
|
} catch {
|
|
3718
4028
|
throw new PackAuthError("migration pack is malformed (unreadable header)");
|
|
3719
4029
|
}
|
|
3720
|
-
if (!
|
|
4030
|
+
if (!header2 || header2.magic !== PACK_MAGIC || header2.v !== PACK_VERSION || header2.kdf !== KDF_ALGORITHM || typeof header2.salt !== "string" || typeof header2.iv !== "string" || typeof header2.tag !== "string" || typeof header2.N !== "number" || typeof header2.r !== "number" || typeof header2.p !== "number") {
|
|
3721
4031
|
throw new PackAuthError("migration pack is malformed (unsupported header)");
|
|
3722
4032
|
}
|
|
3723
4033
|
const ciphertext = Buffer.from(ctB64, "base64");
|
|
3724
|
-
return { header, ciphertext };
|
|
4034
|
+
return { header: header2, ciphertext };
|
|
3725
4035
|
}
|
|
3726
4036
|
function openPack(packString, passphrase) {
|
|
3727
4037
|
assertPassphraseStrength(passphrase);
|
|
3728
|
-
const { header, ciphertext } = parsePack(packString);
|
|
3729
|
-
const salt = Buffer.from(
|
|
3730
|
-
const iv = Buffer.from(
|
|
3731
|
-
const tag = Buffer.from(
|
|
4038
|
+
const { header: header2, ciphertext } = parsePack(packString);
|
|
4039
|
+
const salt = Buffer.from(header2.salt, "base64");
|
|
4040
|
+
const iv = Buffer.from(header2.iv, "base64");
|
|
4041
|
+
const tag = Buffer.from(header2.tag, "base64");
|
|
3732
4042
|
if (iv.length !== IV_BYTES2 || tag.length !== TAG_BYTES2) {
|
|
3733
4043
|
throw new PackAuthError("migration pack is malformed (invalid iv/tag length)");
|
|
3734
4044
|
}
|
|
3735
|
-
const key = deriveKey(passphrase, salt,
|
|
4045
|
+
const key = deriveKey(passphrase, salt, header2.N, header2.r, header2.p);
|
|
3736
4046
|
const decipher = (0, import_node_crypto8.createDecipheriv)("aes-256-gcm", key, iv);
|
|
3737
4047
|
decipher.setAAD(aadFor(PACK_MAGIC, PACK_VERSION, KDF_ALGORITHM));
|
|
3738
4048
|
decipher.setAuthTag(tag);
|
|
@@ -4068,10 +4378,10 @@ function writeJson2(res, status, body) {
|
|
|
4068
4378
|
res.writeHead(status, { "Content-Type": "application/json" });
|
|
4069
4379
|
res.end(JSON.stringify(body));
|
|
4070
4380
|
}
|
|
4071
|
-
function
|
|
4381
|
+
function writeError2(res, status, message) {
|
|
4072
4382
|
writeJson2(res, status, { error: { type: "account_allowance_error", message } });
|
|
4073
4383
|
}
|
|
4074
|
-
function
|
|
4384
|
+
function readJson2(req) {
|
|
4075
4385
|
return new Promise((resolve2, reject) => {
|
|
4076
4386
|
const chunks = [];
|
|
4077
4387
|
req.on("data", (chunk) => chunks.push(Buffer.from(chunk)));
|
|
@@ -4097,10 +4407,10 @@ function allowanceProvider(value) {
|
|
|
4097
4407
|
return value === "claude" || value === "codex" ? value : null;
|
|
4098
4408
|
}
|
|
4099
4409
|
async function handleAccountAllowanceApi(req, res, method, rest, service) {
|
|
4100
|
-
if (!service) return
|
|
4410
|
+
if (!service) return writeError2(res, 501, "account allowance service is not available");
|
|
4101
4411
|
if (method === "GET" && rest.length === 1 && rest[0] === "scheduling") {
|
|
4102
4412
|
if (!service.getSchedulingStatus) {
|
|
4103
|
-
return
|
|
4413
|
+
return writeError2(res, 501, "allowance scheduling diagnostics are not available");
|
|
4104
4414
|
}
|
|
4105
4415
|
return writeJson2(res, 200, { scheduling: service.getSchedulingStatus() });
|
|
4106
4416
|
}
|
|
@@ -4108,27 +4418,27 @@ async function handleAccountAllowanceApi(req, res, method, rest, service) {
|
|
|
4108
4418
|
const params = query(req);
|
|
4109
4419
|
const pathProvider = rest.length >= 2 ? rest[0] : null;
|
|
4110
4420
|
const providerId = allowanceProvider(pathProvider ?? params.get("providerId") ?? params.get("provider"));
|
|
4111
|
-
if (providerId === null) return
|
|
4421
|
+
if (providerId === null) return writeError2(res, 400, "providerId must be claude or codex");
|
|
4112
4422
|
const accountId = rest.length >= 2 ? rest[1] : params.get("accountId") ?? void 0;
|
|
4113
4423
|
const allowances = await service.list({ providerId, accountId });
|
|
4114
4424
|
return writeJson2(res, 200, { allowances });
|
|
4115
4425
|
}
|
|
4116
4426
|
if (method === "POST" && rest[0] === "refresh") {
|
|
4117
|
-
const body = await
|
|
4427
|
+
const body = await readJson2(req);
|
|
4118
4428
|
const requestedProvider = allowanceProvider(
|
|
4119
4429
|
typeof body["providerId"] === "string" ? body["providerId"] : "claude"
|
|
4120
4430
|
);
|
|
4121
4431
|
if (requestedProvider !== "claude") {
|
|
4122
|
-
return
|
|
4432
|
+
return writeError2(res, 400, "only Claude allowances support explicit refresh");
|
|
4123
4433
|
}
|
|
4124
4434
|
const accountId = typeof body["accountId"] === "string" && body["accountId"].trim() ? body["accountId"].trim() : void 0;
|
|
4125
4435
|
const allowances = await service.refreshClaude(accountId);
|
|
4126
4436
|
if (accountId && allowances.length === 0) {
|
|
4127
|
-
return
|
|
4437
|
+
return writeError2(res, 404, `Claude account '${accountId}' not found`);
|
|
4128
4438
|
}
|
|
4129
4439
|
return writeJson2(res, 200, { allowances });
|
|
4130
4440
|
}
|
|
4131
|
-
return
|
|
4441
|
+
return writeError2(res, 405, `method ${method} not allowed on account allowances`);
|
|
4132
4442
|
}
|
|
4133
4443
|
|
|
4134
4444
|
// src/admin/adminApi.ts
|
|
@@ -5360,6 +5670,7 @@ async function handleCli(req, res, method, rest, deps) {
|
|
|
5360
5670
|
const result = await handleCliLaunch(cli, body, {
|
|
5361
5671
|
llmConfig: deps.llmConfig,
|
|
5362
5672
|
providers,
|
|
5673
|
+
routeLeaseManager: deps.routeLeaseManager,
|
|
5363
5674
|
opener: deps.cliTerminalOpener,
|
|
5364
5675
|
probe: deps.cliPathProbe
|
|
5365
5676
|
});
|
|
@@ -5623,7 +5934,7 @@ async function handleUiStatic(req, res, urlPath, uiDist) {
|
|
|
5623
5934
|
}
|
|
5624
5935
|
|
|
5625
5936
|
// src/admin/version.ts
|
|
5626
|
-
var DAEMON_VERSION = true ? "0.1.
|
|
5937
|
+
var DAEMON_VERSION = true ? "0.1.8" : "0.0.0-dev";
|
|
5627
5938
|
|
|
5628
5939
|
// src/admin/AdminServer.ts
|
|
5629
5940
|
var LOOPBACK_ADDR = "127.0.0.1";
|
|
@@ -5743,6 +6054,10 @@ var AdminServer = class {
|
|
|
5743
6054
|
await handleWebhookTest(req, res);
|
|
5744
6055
|
return;
|
|
5745
6056
|
}
|
|
6057
|
+
if (path2 === "/admin/api/route-leases" || path2.startsWith("/admin/api/route-leases/")) {
|
|
6058
|
+
await handleRouteLeaseApi(req, res, path2, this.deps);
|
|
6059
|
+
return;
|
|
6060
|
+
}
|
|
5746
6061
|
if (path2.startsWith("/admin/api/")) {
|
|
5747
6062
|
await handleAdminApi(req, res, path2, this.deps);
|
|
5748
6063
|
return;
|
|
@@ -5754,8 +6069,8 @@ var AdminServer = class {
|
|
|
5754
6069
|
}
|
|
5755
6070
|
/** Constant-time bearer/header check against the configured token. */
|
|
5756
6071
|
isAuthorized(req, token) {
|
|
5757
|
-
const
|
|
5758
|
-
const bearer = typeof
|
|
6072
|
+
const header2 = req.headers["authorization"];
|
|
6073
|
+
const bearer = typeof header2 === "string" && header2.startsWith("Bearer ") ? header2.slice("Bearer ".length).trim() : void 0;
|
|
5759
6074
|
const xToken = req.headers["x-admin-token"];
|
|
5760
6075
|
const presented = bearer ?? (typeof xToken === "string" ? xToken.trim() : void 0);
|
|
5761
6076
|
return constantTimeEquals(presented, token);
|
|
@@ -7299,9 +7614,9 @@ function findDuplicateCredentialIds(accounts) {
|
|
|
7299
7614
|
|
|
7300
7615
|
// src/ports/external-cli-credentials.ts
|
|
7301
7616
|
var import_node_fs15 = require("fs");
|
|
7302
|
-
var
|
|
7617
|
+
var import_node_os4 = require("os");
|
|
7303
7618
|
var import_node_path8 = require("path");
|
|
7304
|
-
function externalStorePath(provider, home = (0,
|
|
7619
|
+
function externalStorePath(provider, home = (0, import_node_os4.homedir)()) {
|
|
7305
7620
|
return provider === "claude" ? (0, import_node_path8.join)(home, ".claude", ".credentials.json") : (0, import_node_path8.join)(home, ".codex", "auth.json");
|
|
7306
7621
|
}
|
|
7307
7622
|
function decodeJwtExpiryMs(token) {
|
|
@@ -7349,7 +7664,7 @@ function parseCodexTokensEnvelope(raw) {
|
|
|
7349
7664
|
}
|
|
7350
7665
|
return parsed;
|
|
7351
7666
|
}
|
|
7352
|
-
function readExternalCliCredentials(provider, home = (0,
|
|
7667
|
+
function readExternalCliCredentials(provider, home = (0, import_node_os4.homedir)()) {
|
|
7353
7668
|
const path2 = externalStorePath(provider, home);
|
|
7354
7669
|
if (!(0, import_node_fs15.existsSync)(path2)) return null;
|
|
7355
7670
|
let raw;
|
|
@@ -9234,6 +9549,76 @@ var TokenRefreshScheduler = class {
|
|
|
9234
9549
|
}
|
|
9235
9550
|
};
|
|
9236
9551
|
|
|
9552
|
+
// src/routeLeaseSubscriptionPreflight.ts
|
|
9553
|
+
var import_provider_proxy3 = require("@omnicross/core/provider-proxy");
|
|
9554
|
+
var import_AccountAllowanceScheduling4 = require("@omnicross/core/pipeline/AccountAllowanceScheduling");
|
|
9555
|
+
var import_SubscriptionAccountHealth3 = require("@omnicross/core/pipeline/SubscriptionAccountHealth");
|
|
9556
|
+
var import_accountModelMap = require("@omnicross/subscriptions/scheduler/accountModelMap");
|
|
9557
|
+
var PROVIDERS = /* @__PURE__ */ new Set(["claude", "codex", "gemini", "opencodego"]);
|
|
9558
|
+
function accountArray(config, providerId) {
|
|
9559
|
+
const record = config;
|
|
9560
|
+
const key = `${providerId}Accounts`;
|
|
9561
|
+
const accounts = record[key];
|
|
9562
|
+
if (Array.isArray(accounts)) return accounts;
|
|
9563
|
+
const legacy = record[providerId];
|
|
9564
|
+
if (!legacy || typeof legacy !== "object") return [];
|
|
9565
|
+
const activeKey = `active${providerId[0].toUpperCase()}${providerId.slice(1)}AccountId`;
|
|
9566
|
+
return [{ id: String(record[activeKey] ?? "active"), enabled: true, tokens: legacy }];
|
|
9567
|
+
}
|
|
9568
|
+
function hasCredential(providerId, account) {
|
|
9569
|
+
const tokens = account.tokens;
|
|
9570
|
+
if (providerId === "opencodego") return typeof tokens.apiKey === "string" && tokens.apiKey.length > 0;
|
|
9571
|
+
return typeof tokens.accessToken === "string" && tokens.accessToken.length > 0;
|
|
9572
|
+
}
|
|
9573
|
+
function safeProviderId(value) {
|
|
9574
|
+
if (!PROVIDERS.has(value)) {
|
|
9575
|
+
throw new import_provider_proxy3.RouteLeaseError("upstream_not_found", "subscription provider was not found");
|
|
9576
|
+
}
|
|
9577
|
+
return value;
|
|
9578
|
+
}
|
|
9579
|
+
function createRouteLeaseSubscriptionPreflight(credentials) {
|
|
9580
|
+
return {
|
|
9581
|
+
async assertAvailable(upstream, model) {
|
|
9582
|
+
const providerId = safeProviderId(upstream.providerId);
|
|
9583
|
+
const config = await credentials.getFullConfig();
|
|
9584
|
+
const all = accountArray(config, providerId);
|
|
9585
|
+
if (all.length === 0) {
|
|
9586
|
+
throw new import_provider_proxy3.RouteLeaseError("upstream_unavailable", "subscription provider has no configured account");
|
|
9587
|
+
}
|
|
9588
|
+
let bounded = all;
|
|
9589
|
+
if (upstream.kind === "account") {
|
|
9590
|
+
bounded = all.filter((account) => account.id === upstream.accountId);
|
|
9591
|
+
} else if (upstream.kind === "account-group") {
|
|
9592
|
+
bounded = all.filter((account) => account.group?.trim() === upstream.group);
|
|
9593
|
+
}
|
|
9594
|
+
if (bounded.length === 0) {
|
|
9595
|
+
throw new import_provider_proxy3.RouteLeaseError("upstream_not_found", "the selected subscription resource was not found");
|
|
9596
|
+
}
|
|
9597
|
+
const modelEligible = bounded.filter(
|
|
9598
|
+
(account) => (0, import_accountModelMap.accountSupportsModel)(account.supportedModels, model)
|
|
9599
|
+
);
|
|
9600
|
+
if (modelEligible.length === 0) {
|
|
9601
|
+
throw new import_provider_proxy3.RouteLeaseError("model_not_configured", "model is not supported by the selected subscription resource");
|
|
9602
|
+
}
|
|
9603
|
+
const credentialEligible = modelEligible.filter(
|
|
9604
|
+
(account) => account.enabled !== false && hasCredential(providerId, account)
|
|
9605
|
+
);
|
|
9606
|
+
const health2 = (0, import_SubscriptionAccountHealth3.getSharedAccountHealth)();
|
|
9607
|
+
const allowance = (0, import_AccountAllowanceScheduling4.getSharedAccountAllowanceScheduling)();
|
|
9608
|
+
const candidates = credentialEligible.filter(
|
|
9609
|
+
(account) => health2.isSchedulable(providerId, account.id) && allowance.preview(providerId, account.id, account.priority ?? 50).schedulable
|
|
9610
|
+
);
|
|
9611
|
+
if (candidates.length > 0) return;
|
|
9612
|
+
if (upstream.kind === "account") {
|
|
9613
|
+
throw new import_provider_proxy3.RouteLeaseError("upstream_unavailable", "the selected subscription account is unavailable");
|
|
9614
|
+
}
|
|
9615
|
+
throw new import_provider_proxy3.RouteLeaseError("upstream_exhausted", "the selected subscription pool has no eligible account", {
|
|
9616
|
+
retryAfterSeconds: 30
|
|
9617
|
+
});
|
|
9618
|
+
}
|
|
9619
|
+
};
|
|
9620
|
+
}
|
|
9621
|
+
|
|
9237
9622
|
// src/webhook/WebhookDispatcher.ts
|
|
9238
9623
|
var import_node_crypto14 = require("crypto");
|
|
9239
9624
|
var import_upstreamFetch7 = require("@omnicross/core/pipeline/upstreamFetch");
|
|
@@ -9416,7 +9801,7 @@ function buildDaemon(config, paths) {
|
|
|
9416
9801
|
new JsonAccountAllowancePersistence(defaultAccountAllowancePath(paths.configPath))
|
|
9417
9802
|
);
|
|
9418
9803
|
(0, import_AccountAllowanceStore4.setSharedAccountAllowanceStore)(accountAllowanceStore);
|
|
9419
|
-
(0,
|
|
9804
|
+
(0, import_AccountAllowanceScheduling5.getSharedAccountAllowanceScheduling)().configure(
|
|
9420
9805
|
(0, import_outbound_api4.normalizeServerConfig)(decryptedConfig.server).allowanceScheduling
|
|
9421
9806
|
);
|
|
9422
9807
|
const llmConfig = new ConfigFileProviderConfigSource(decryptedConfig);
|
|
@@ -9483,11 +9868,22 @@ function buildDaemon(config, paths) {
|
|
|
9483
9868
|
const usageRecorder = new import_usage.UsageRecorder(usageEventStore, pricingEngine, logger, {
|
|
9484
9869
|
onRecord: (apiKeyId, costUsd, at) => keySpendTracker.add(apiKeyId, costUsd, at)
|
|
9485
9870
|
});
|
|
9486
|
-
const providerProxy = (0,
|
|
9871
|
+
const providerProxy = (0, import_provider_proxy4.getProviderProxy)({ llmConfig, apiKeyPool, usageRecorder });
|
|
9872
|
+
const routeLeaseManager = new import_provider_proxy4.RouteLeaseManager(
|
|
9873
|
+
providerProxy,
|
|
9874
|
+
new import_provider_proxy4.RouteLeaseTargetResolver(llmConfig, {
|
|
9875
|
+
providerKeys: apiKeyPool,
|
|
9876
|
+
subscriptions: createRouteLeaseSubscriptionPreflight(credentialStore)
|
|
9877
|
+
}),
|
|
9878
|
+
import_cli_launcher2.routeLeaseDescriptorPort,
|
|
9879
|
+
{ logger }
|
|
9880
|
+
);
|
|
9881
|
+
providerProxy.registerBeforeStop(() => routeLeaseManager.shutdown());
|
|
9882
|
+
providerProxy.registerBeforeStop(() => resetCliSessions());
|
|
9487
9883
|
llmConfig.setReloadHook(() => apiKeyPool.invalidateCache());
|
|
9488
9884
|
const accountHealthProbeScheduler = new AccountHealthProbeScheduler(
|
|
9489
9885
|
credentialStore,
|
|
9490
|
-
(0,
|
|
9886
|
+
(0, import_SubscriptionAccountHealth4.getSharedAccountHealth)(),
|
|
9491
9887
|
logger,
|
|
9492
9888
|
import_outbound_api4.DEFAULT_ACCOUNT_PROBE
|
|
9493
9889
|
);
|
|
@@ -9534,6 +9930,7 @@ function buildDaemon(config, paths) {
|
|
|
9534
9930
|
keySpendReader: keySpendTracker,
|
|
9535
9931
|
settingsStore,
|
|
9536
9932
|
outboundApiServer,
|
|
9933
|
+
routeLeaseManager,
|
|
9537
9934
|
subscriptionAccounts,
|
|
9538
9935
|
accountAllowanceService,
|
|
9539
9936
|
allowanceRefreshScheduler: claudeAllowanceRefreshScheduler,
|
|
@@ -9626,7 +10023,7 @@ function buildDaemon(config, paths) {
|
|
|
9626
10023
|
logger,
|
|
9627
10024
|
fetchImpl: (url, init) => (0, import_upstreamFetch8.fetchUpstream)(url, init)
|
|
9628
10025
|
});
|
|
9629
|
-
setWebhookRuntime(webhookDispatcher, (0,
|
|
10026
|
+
setWebhookRuntime(webhookDispatcher, (0, import_SubscriptionAccountHealth4.getSharedAccountHealth)());
|
|
9630
10027
|
const auditWriter = new AuditWriter(auditDir, logger);
|
|
9631
10028
|
const auditPruneSweeper = new AuditPruneSweeper(auditDir, logger, import_audit_types.DEFAULT_AUDIT_CONFIG);
|
|
9632
10029
|
setAuditRuntime(auditWriter, auditPruneSweeper);
|
|
@@ -9641,7 +10038,7 @@ function buildDaemon(config, paths) {
|
|
|
9641
10038
|
const tokenRefreshScheduler = new TokenRefreshScheduler(credentialStore, logger);
|
|
9642
10039
|
const accountHealthSweeper = new AccountHealthSweeper(
|
|
9643
10040
|
credentialStore,
|
|
9644
|
-
(0,
|
|
10041
|
+
(0, import_SubscriptionAccountHealth4.getSharedAccountHealth)(),
|
|
9645
10042
|
logger
|
|
9646
10043
|
);
|
|
9647
10044
|
return {
|
|
@@ -9650,6 +10047,7 @@ function buildDaemon(config, paths) {
|
|
|
9650
10047
|
keyDb,
|
|
9651
10048
|
settingsStore,
|
|
9652
10049
|
providerProxy,
|
|
10050
|
+
routeLeaseManager,
|
|
9653
10051
|
outboundApiServer,
|
|
9654
10052
|
apiKeyPool,
|
|
9655
10053
|
autoDisableStore,
|
|
@@ -9674,7 +10072,7 @@ function buildDaemon(config, paths) {
|
|
|
9674
10072
|
};
|
|
9675
10073
|
}
|
|
9676
10074
|
function resetDaemonSingletonsForTests() {
|
|
9677
|
-
(0,
|
|
10075
|
+
(0, import_provider_proxy4.__resetProviderProxyForTests)();
|
|
9678
10076
|
(0, import_outbound_api4.__resetOutboundApiServerForTests)();
|
|
9679
10077
|
(0, import_subscriptionRegistryPort.setSubscriptionRegistryForOutbound)(null);
|
|
9680
10078
|
(0, import_subscriptions4.setSubscriptionProviderRegistry)(null);
|
|
@@ -9689,7 +10087,7 @@ function resetDaemonSingletonsForTests() {
|
|
|
9689
10087
|
resetBillingRuntimeForTests();
|
|
9690
10088
|
(0, import_SubscriptionIdentityStore3.__resetSharedIdentityStoreForTests)();
|
|
9691
10089
|
(0, import_AccountAllowanceStore4.__resetSharedAccountAllowanceStoreForTests)();
|
|
9692
|
-
(0,
|
|
10090
|
+
(0, import_AccountAllowanceScheduling5.__resetSharedAccountAllowanceSchedulingForTests)();
|
|
9693
10091
|
}
|
|
9694
10092
|
function isTokensStoreReadable(tokensPath) {
|
|
9695
10093
|
try {
|