@dotobokuri/fleet-cli 1.9.0 → 1.10.0
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 +619 -365
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -29321,6 +29321,7 @@ __export(typebox_exports, {
|
|
|
29321
29321
|
|
|
29322
29322
|
// ../../packages/fleet-carriers/dist/index.js
|
|
29323
29323
|
init_dist2();
|
|
29324
|
+
import path23 from "path";
|
|
29324
29325
|
init_dist2();
|
|
29325
29326
|
init_dist();
|
|
29326
29327
|
var __defProp2 = Object.defineProperty;
|
|
@@ -29515,11 +29516,11 @@ function sanitizeCarriersMap(value) {
|
|
|
29515
29516
|
return result;
|
|
29516
29517
|
}
|
|
29517
29518
|
var TASK_FORCE_POOL_KEY_PATTERN = /(?:^|:)taskforce:[^:]+:([^:]+)$/;
|
|
29518
|
-
function buildCarrierExecutorPoolKey(carrierId, originSessionId) {
|
|
29519
|
-
return namespacePoolKey(carrierId, originSessionId);
|
|
29519
|
+
function buildCarrierExecutorPoolKey(carrierId, originSessionId, cwd) {
|
|
29520
|
+
return namespacePoolKey(carrierId, joinSessionCwdNamespace(originSessionId, cwd));
|
|
29520
29521
|
}
|
|
29521
|
-
function buildTaskForceExecutorPoolKey(carrierId, cliType, originSessionId) {
|
|
29522
|
-
return namespacePoolKey(buildTaskForceRunId(carrierId, cliType), originSessionId);
|
|
29522
|
+
function buildTaskForceExecutorPoolKey(carrierId, cliType, originSessionId, cwd) {
|
|
29523
|
+
return namespacePoolKey(buildTaskForceRunId(carrierId, cliType), joinSessionCwdNamespace(originSessionId, cwd));
|
|
29523
29524
|
}
|
|
29524
29525
|
function buildTaskForceRunId(carrierId, cliType) {
|
|
29525
29526
|
const encodedCarrierId = Buffer.from(carrierId, "utf-8").toString("base64url");
|
|
@@ -29534,6 +29535,11 @@ function matchesCarrierPoolKey(poolKey, carrierId) {
|
|
|
29534
29535
|
function namespacePoolKey(baseKey, originSessionId) {
|
|
29535
29536
|
return originSessionId ? `${originSessionId}:${baseKey}` : baseKey;
|
|
29536
29537
|
}
|
|
29538
|
+
function joinSessionCwdNamespace(originSessionId, cwd) {
|
|
29539
|
+
const cwdNamespace = cwd ? `cwd-${Buffer.from(cwd, "utf-8").toString("base64url")}` : void 0;
|
|
29540
|
+
if (originSessionId && cwdNamespace) return `${originSessionId}:${cwdNamespace}`;
|
|
29541
|
+
return originSessionId ?? cwdNamespace;
|
|
29542
|
+
}
|
|
29537
29543
|
async function disconnectCarrierExecutorPools(carrierId) {
|
|
29538
29544
|
const poolKeys = new Set(listActivePoolKeys().filter((poolKey) => matchesCarrierPoolKey(poolKey, carrierId)));
|
|
29539
29545
|
poolKeys.add(carrierId);
|
|
@@ -32338,7 +32344,7 @@ function escapeRegExp(str) {
|
|
|
32338
32344
|
}
|
|
32339
32345
|
var taskForceStateStore = /* @__PURE__ */ new Map();
|
|
32340
32346
|
function launchTaskForceJob(options2) {
|
|
32341
|
-
const { registry: registry4, carrierId, request, label, startedAt, toolName, ctx, deps } = options2;
|
|
32347
|
+
const { registry: registry4, carrierId, request, label, startedAt, toolName, ctx, cwd, deps } = options2;
|
|
32342
32348
|
const requestKey = buildTaskForceRequestKey(carrierId, request);
|
|
32343
32349
|
const backendIds = getConfiguredTaskForceBackends(carrierId);
|
|
32344
32350
|
assertRegisteredCarrier(registry4, carrierId);
|
|
@@ -32391,7 +32397,7 @@ function launchTaskForceJob(options2) {
|
|
|
32391
32397
|
request,
|
|
32392
32398
|
state,
|
|
32393
32399
|
signal: launch.signal,
|
|
32394
|
-
cwd
|
|
32400
|
+
cwd,
|
|
32395
32401
|
permit: launch.permit,
|
|
32396
32402
|
startedAt,
|
|
32397
32403
|
toolName,
|
|
@@ -32483,7 +32489,7 @@ function getRequiredTaskForceModelConfig(carrierId, cliType) {
|
|
|
32483
32489
|
async function runTaskForceBackend(registry4, cliType, carrierId, originSessionId, requestKey, request, state, signal, cwd, jobId, trackModelInfoByCli, deps) {
|
|
32484
32490
|
const execStartedAt = Date.now();
|
|
32485
32491
|
const progress = state.backends.get(cliType);
|
|
32486
|
-
const poolKey = buildTaskForceExecutorPoolKey(carrierId, cliType, originSessionId);
|
|
32492
|
+
const poolKey = buildTaskForceExecutorPoolKey(carrierId, cliType, originSessionId, cwd);
|
|
32487
32493
|
const streamKey = buildTaskForceScopedRunId(requestKey, cliType);
|
|
32488
32494
|
const modelInfo = trackModelInfoByCli.get(cliType);
|
|
32489
32495
|
if (!modelInfo) throw new Error(`Task Force config missing for ${cliType} on carrier "${carrierId}".`);
|
|
@@ -32688,7 +32694,8 @@ function buildCarrierDispatchToolSpec(registry4, deps) {
|
|
|
32688
32694
|
CARRIER_REQUEST_BREVITY_GUIDELINE
|
|
32689
32695
|
],
|
|
32690
32696
|
guardrails: [
|
|
32691
|
-
`Multiple agents may be working on this codebase at the same time on a single filesystem and branch. Only touch changes you made \u2014 never revert or overwrite modifications made by others. Prefer precise edits (edit) over full-file writes (write). Always re-read a file before modifying it, as it may have changed since your last read
|
|
32697
|
+
`Multiple agents may be working on this codebase at the same time on a single filesystem and branch. Only touch changes you made \u2014 never revert or overwrite modifications made by others. Prefer precise edits (edit) over full-file writes (write). Always re-read a file before modifying it, as it may have changed since your last read.`,
|
|
32698
|
+
`When the carrier must work in a directory other than the host session cwd (e.g. a git worktree checkout), pass cwd as an absolute path so the carrier's CLI spawns there; never pass a relative path. Omit cwd to use the host session cwd.`
|
|
32692
32699
|
],
|
|
32693
32700
|
get parameters() {
|
|
32694
32701
|
const carrierIds = getRegisteredOrder(registry4);
|
|
@@ -32702,12 +32709,14 @@ function buildCarrierDispatchToolSpec(registry4, deps) {
|
|
|
32702
32709
|
}),
|
|
32703
32710
|
request: typebox_exports.String({
|
|
32704
32711
|
description: `The task/prompt to send to the carrier. Required blocks per carrier -- see <fleet section="roster">. Missing blocks cause hard-error rejection.`
|
|
32705
|
-
})
|
|
32712
|
+
}),
|
|
32713
|
+
cwd: typebox_exports.Optional(typebox_exports.String({
|
|
32714
|
+
description: `Optional absolute working directory for the carrier's CLI spawn. MUST be an absolute path. Provide it when delegating work to a directory other than the host session cwd (e.g. a git worktree checkout) so the carrier spawns deterministically at that path. Omit to default to the host session cwd.`
|
|
32715
|
+
}))
|
|
32706
32716
|
});
|
|
32707
32717
|
},
|
|
32708
32718
|
async execute(args, ctx) {
|
|
32709
32719
|
const t0 = Date.now();
|
|
32710
|
-
const cwd = ctx.cwd;
|
|
32711
32720
|
const toolCallId = ctx.toolCallId ?? "";
|
|
32712
32721
|
const jobId = buildCarrierJobId("carrier", toolCallId);
|
|
32713
32722
|
const toolName = "carrier_dispatch";
|
|
@@ -32718,6 +32727,11 @@ function buildCarrierDispatchToolSpec(registry4, deps) {
|
|
|
32718
32727
|
error: "Invalid arguments: carrier_id, label, and request must be non-empty strings."
|
|
32719
32728
|
});
|
|
32720
32729
|
}
|
|
32730
|
+
const cwdResolution = resolveDispatchCwd(args.cwd, ctx.cwd);
|
|
32731
|
+
if (!cwdResolution.ok) {
|
|
32732
|
+
return launchResponseResult({ job_id: jobId, accepted: false, error: cwdResolution.error });
|
|
32733
|
+
}
|
|
32734
|
+
const cwd = cwdResolution.cwd;
|
|
32721
32735
|
const carrierId = args.carrier_id.trim();
|
|
32722
32736
|
const label = args.label.trim();
|
|
32723
32737
|
const request = args.request;
|
|
@@ -32750,6 +32764,7 @@ function buildCarrierDispatchToolSpec(registry4, deps) {
|
|
|
32750
32764
|
startedAt: t0,
|
|
32751
32765
|
toolName,
|
|
32752
32766
|
ctx,
|
|
32767
|
+
cwd,
|
|
32753
32768
|
deps
|
|
32754
32769
|
});
|
|
32755
32770
|
}
|
|
@@ -32862,7 +32877,7 @@ async function runSingleCarrier(opts) {
|
|
|
32862
32877
|
});
|
|
32863
32878
|
try {
|
|
32864
32879
|
const execResult = await executeWithPool({
|
|
32865
|
-
poolKey: buildCarrierExecutorPoolKey(opts.carrierId, opts.originSessionId),
|
|
32880
|
+
poolKey: buildCarrierExecutorPoolKey(opts.carrierId, opts.originSessionId, opts.cwd),
|
|
32866
32881
|
scopeId: opts.carrierId,
|
|
32867
32882
|
authEnvResolver: opts.deps.authEnvResolver,
|
|
32868
32883
|
reservedExternalMcpServerIds: opts.deps.reservedExternalMcpServerIds,
|
|
@@ -32992,7 +33007,19 @@ function buildCarrierDispatchRunId(jobId, carrierId) {
|
|
|
32992
33007
|
function isDispatchArgs(v) {
|
|
32993
33008
|
if (typeof v !== "object" || v === null) return false;
|
|
32994
33009
|
const obj = v;
|
|
32995
|
-
return typeof obj.carrier_id === "string" && obj.carrier_id.trim().length > 0 && typeof obj.label === "string" && obj.label.trim().length > 0 && typeof obj.request === "string" && obj.request.trim().length > 0;
|
|
33010
|
+
return typeof obj.carrier_id === "string" && obj.carrier_id.trim().length > 0 && typeof obj.label === "string" && obj.label.trim().length > 0 && typeof obj.request === "string" && obj.request.trim().length > 0 && (obj.cwd === void 0 || typeof obj.cwd === "string");
|
|
33011
|
+
}
|
|
33012
|
+
function resolveDispatchCwd(rawCwd, fallbackCwd) {
|
|
33013
|
+
if (rawCwd === void 0) return { ok: true, cwd: fallbackCwd };
|
|
33014
|
+
const trimmed = rawCwd.trim();
|
|
33015
|
+
if (trimmed.length === 0) return { ok: true, cwd: fallbackCwd };
|
|
33016
|
+
if (!path23.isAbsolute(trimmed)) {
|
|
33017
|
+
return {
|
|
33018
|
+
ok: false,
|
|
33019
|
+
error: `Invalid cwd "${rawCwd}": must be an absolute path. Provide an absolute directory or omit cwd to use the host session cwd.`
|
|
33020
|
+
};
|
|
33021
|
+
}
|
|
33022
|
+
return { ok: true, cwd: trimmed };
|
|
32996
33023
|
}
|
|
32997
33024
|
function buildCarrierRoster(registry4, carrierIds, options2) {
|
|
32998
33025
|
const { excludeCarrierIds, heading, preambleLines, extraLines } = options2 ?? {};
|
|
@@ -33185,7 +33212,7 @@ init_dist2();
|
|
|
33185
33212
|
import crypto4 from "crypto";
|
|
33186
33213
|
import { existsSync as existsSync32, lstatSync as lstatSync22, mkdtempSync, readFileSync as readFileSync32, readdirSync as readdirSync3, realpathSync as realpathSync4, renameSync as renameSync22, statSync as statSync2 } from "fs";
|
|
33187
33214
|
import path52 from "path";
|
|
33188
|
-
import
|
|
33215
|
+
import path24 from "path";
|
|
33189
33216
|
import { chmodSync as chmodSync3, closeSync as closeSync6, constants as constants7, lstatSync as lstatSync6, mkdirSync as mkdirSync5, openSync as openSync6, realpathSync as realpathSync2, rmSync as rmSync3, symlinkSync, writeFileSync as writeFileSync4 } from "fs";
|
|
33190
33217
|
import path10 from "path";
|
|
33191
33218
|
import { existsSync as existsSync22, readFileSync as readFileSync22, realpathSync as realpathSync3 } from "fs";
|
|
@@ -34031,11 +34058,11 @@ function renderAssetPluginRoot(pluginRoot, bundle, options2) {
|
|
|
34031
34058
|
if (bundle.includeClaudeAgents) {
|
|
34032
34059
|
for (const subagent of options2.claudeDefinitions) {
|
|
34033
34060
|
const fileStem = parseClaudeAgentFileStem(subagent.name);
|
|
34034
|
-
writePrivateFile(
|
|
34061
|
+
writePrivateFile(path24.join(pluginRoot, "agents", `${fileStem}.md`), claudeAgentFile(subagent), pluginRoot);
|
|
34035
34062
|
}
|
|
34036
34063
|
}
|
|
34037
34064
|
if (options2.cliId === "claude" || options2.cliId === "claude-kimi" || options2.cliId === "claude-glm") {
|
|
34038
|
-
writePrivateJson(
|
|
34065
|
+
writePrivateJson(path24.join(pluginRoot, "hooks", "hooks.json"), claudeHooks(options2), pluginRoot);
|
|
34039
34066
|
}
|
|
34040
34067
|
}
|
|
34041
34068
|
function validateClaudeAgentFileStems(subagents) {
|
|
@@ -34044,7 +34071,7 @@ function validateClaudeAgentFileStems(subagents) {
|
|
|
34044
34071
|
}
|
|
34045
34072
|
}
|
|
34046
34073
|
function parseClaudeAgentFileStem(name) {
|
|
34047
|
-
if (CLAUDE_AGENT_FILE_STEM_ALLOWLIST.test(name) &&
|
|
34074
|
+
if (CLAUDE_AGENT_FILE_STEM_ALLOWLIST.test(name) && path24.basename(name) === name) return name;
|
|
34048
34075
|
throw new Error(`Invalid Claude agent file name: ${name}`);
|
|
34049
34076
|
}
|
|
34050
34077
|
function claudeHooks(options2) {
|
|
@@ -34114,7 +34141,7 @@ function yamlScalar(value) {
|
|
|
34114
34141
|
}
|
|
34115
34142
|
function renderEmbeddedSkillAssets(pluginRoot) {
|
|
34116
34143
|
for (const asset of EMBEDDED_AGENT_CLI_SKILL_ASSETS) {
|
|
34117
|
-
writePrivateFile(
|
|
34144
|
+
writePrivateFile(path24.join(pluginRoot, "skills", asset.relativePath), asset.content, pluginRoot);
|
|
34118
34145
|
}
|
|
34119
34146
|
}
|
|
34120
34147
|
var CONFIG_FILE_NAME = "config.toml";
|
|
@@ -40974,10 +41001,10 @@ function mergeDefs2(...defs) {
|
|
|
40974
41001
|
function cloneDef2(schema) {
|
|
40975
41002
|
return mergeDefs2(schema._zod.def);
|
|
40976
41003
|
}
|
|
40977
|
-
function getElementAtPath2(obj,
|
|
40978
|
-
if (!
|
|
41004
|
+
function getElementAtPath2(obj, path37) {
|
|
41005
|
+
if (!path37)
|
|
40979
41006
|
return obj;
|
|
40980
|
-
return
|
|
41007
|
+
return path37.reduce((acc, key) => acc?.[key], obj);
|
|
40981
41008
|
}
|
|
40982
41009
|
function promiseAllObject2(promisesObj) {
|
|
40983
41010
|
const keys = Object.keys(promisesObj);
|
|
@@ -41386,11 +41413,11 @@ function explicitlyAborted2(x, startIndex = 0) {
|
|
|
41386
41413
|
}
|
|
41387
41414
|
return false;
|
|
41388
41415
|
}
|
|
41389
|
-
function prefixIssues2(
|
|
41416
|
+
function prefixIssues2(path37, issues) {
|
|
41390
41417
|
return issues.map((iss) => {
|
|
41391
41418
|
var _a32;
|
|
41392
41419
|
(_a32 = iss).path ?? (_a32.path = []);
|
|
41393
|
-
iss.path.unshift(
|
|
41420
|
+
iss.path.unshift(path37);
|
|
41394
41421
|
return iss;
|
|
41395
41422
|
});
|
|
41396
41423
|
}
|
|
@@ -41535,16 +41562,16 @@ function flattenError2(error512, mapper = (issue32) => issue32.message) {
|
|
|
41535
41562
|
}
|
|
41536
41563
|
function formatError4(error512, mapper = (issue32) => issue32.message) {
|
|
41537
41564
|
const fieldErrors = { _errors: [] };
|
|
41538
|
-
const processError = (error522,
|
|
41565
|
+
const processError = (error522, path37 = []) => {
|
|
41539
41566
|
for (const issue32 of error522.issues) {
|
|
41540
41567
|
if (issue32.code === "invalid_union" && issue32.errors.length) {
|
|
41541
|
-
issue32.errors.map((issues) => processError({ issues }, [...
|
|
41568
|
+
issue32.errors.map((issues) => processError({ issues }, [...path37, ...issue32.path]));
|
|
41542
41569
|
} else if (issue32.code === "invalid_key") {
|
|
41543
|
-
processError({ issues: issue32.issues }, [...
|
|
41570
|
+
processError({ issues: issue32.issues }, [...path37, ...issue32.path]);
|
|
41544
41571
|
} else if (issue32.code === "invalid_element") {
|
|
41545
|
-
processError({ issues: issue32.issues }, [...
|
|
41572
|
+
processError({ issues: issue32.issues }, [...path37, ...issue32.path]);
|
|
41546
41573
|
} else {
|
|
41547
|
-
const fullpath = [...
|
|
41574
|
+
const fullpath = [...path37, ...issue32.path];
|
|
41548
41575
|
if (fullpath.length === 0) {
|
|
41549
41576
|
fieldErrors._errors.push(mapper(issue32));
|
|
41550
41577
|
} else {
|
|
@@ -41571,17 +41598,17 @@ function formatError4(error512, mapper = (issue32) => issue32.message) {
|
|
|
41571
41598
|
}
|
|
41572
41599
|
function treeifyError2(error512, mapper = (issue32) => issue32.message) {
|
|
41573
41600
|
const result = { errors: [] };
|
|
41574
|
-
const processError = (error522,
|
|
41601
|
+
const processError = (error522, path37 = []) => {
|
|
41575
41602
|
var _a32, _b;
|
|
41576
41603
|
for (const issue32 of error522.issues) {
|
|
41577
41604
|
if (issue32.code === "invalid_union" && issue32.errors.length) {
|
|
41578
|
-
issue32.errors.map((issues) => processError({ issues }, [...
|
|
41605
|
+
issue32.errors.map((issues) => processError({ issues }, [...path37, ...issue32.path]));
|
|
41579
41606
|
} else if (issue32.code === "invalid_key") {
|
|
41580
|
-
processError({ issues: issue32.issues }, [...
|
|
41607
|
+
processError({ issues: issue32.issues }, [...path37, ...issue32.path]);
|
|
41581
41608
|
} else if (issue32.code === "invalid_element") {
|
|
41582
|
-
processError({ issues: issue32.issues }, [...
|
|
41609
|
+
processError({ issues: issue32.issues }, [...path37, ...issue32.path]);
|
|
41583
41610
|
} else {
|
|
41584
|
-
const fullpath = [...
|
|
41611
|
+
const fullpath = [...path37, ...issue32.path];
|
|
41585
41612
|
if (fullpath.length === 0) {
|
|
41586
41613
|
result.errors.push(mapper(issue32));
|
|
41587
41614
|
continue;
|
|
@@ -41613,8 +41640,8 @@ function treeifyError2(error512, mapper = (issue32) => issue32.message) {
|
|
|
41613
41640
|
}
|
|
41614
41641
|
function toDotPath2(_path) {
|
|
41615
41642
|
const segs = [];
|
|
41616
|
-
const
|
|
41617
|
-
for (const seg of
|
|
41643
|
+
const path37 = _path.map((seg) => typeof seg === "object" ? seg.key : seg);
|
|
41644
|
+
for (const seg of path37) {
|
|
41618
41645
|
if (typeof seg === "number")
|
|
41619
41646
|
segs.push(`[${seg}]`);
|
|
41620
41647
|
else if (typeof seg === "symbol")
|
|
@@ -54135,13 +54162,13 @@ function resolveRef2(ref, ctx) {
|
|
|
54135
54162
|
if (!ref.startsWith("#")) {
|
|
54136
54163
|
throw new Error("External $ref is not supported, only local refs (#/...) are allowed");
|
|
54137
54164
|
}
|
|
54138
|
-
const
|
|
54139
|
-
if (
|
|
54165
|
+
const path37 = ref.slice(1).split("/").filter(Boolean);
|
|
54166
|
+
if (path37.length === 0) {
|
|
54140
54167
|
return ctx.rootSchema;
|
|
54141
54168
|
}
|
|
54142
54169
|
const defsKey = ctx.version === "draft-2020-12" ? "$defs" : "definitions";
|
|
54143
|
-
if (
|
|
54144
|
-
const key =
|
|
54170
|
+
if (path37[0] === defsKey) {
|
|
54171
|
+
const key = path37[1];
|
|
54145
54172
|
if (!key || !ctx.defs[key]) {
|
|
54146
54173
|
throw new Error(`Reference not found: ${ref}`);
|
|
54147
54174
|
}
|
|
@@ -67593,11 +67620,11 @@ function sanitizeCarriersMap2(value) {
|
|
|
67593
67620
|
return result;
|
|
67594
67621
|
}
|
|
67595
67622
|
var TASK_FORCE_POOL_KEY_PATTERN2 = /(?:^|:)taskforce:[^:]+:([^:]+)$/;
|
|
67596
|
-
function buildCarrierExecutorPoolKey2(carrierId, originSessionId) {
|
|
67597
|
-
return namespacePoolKey2(carrierId, originSessionId);
|
|
67623
|
+
function buildCarrierExecutorPoolKey2(carrierId, originSessionId, cwd) {
|
|
67624
|
+
return namespacePoolKey2(carrierId, joinSessionCwdNamespace2(originSessionId, cwd));
|
|
67598
67625
|
}
|
|
67599
|
-
function buildTaskForceExecutorPoolKey2(carrierId, cliType, originSessionId) {
|
|
67600
|
-
return namespacePoolKey2(buildTaskForceRunId2(carrierId, cliType), originSessionId);
|
|
67626
|
+
function buildTaskForceExecutorPoolKey2(carrierId, cliType, originSessionId, cwd) {
|
|
67627
|
+
return namespacePoolKey2(buildTaskForceRunId2(carrierId, cliType), joinSessionCwdNamespace2(originSessionId, cwd));
|
|
67601
67628
|
}
|
|
67602
67629
|
function buildTaskForceRunId2(carrierId, cliType) {
|
|
67603
67630
|
const encodedCarrierId = Buffer.from(carrierId, "utf-8").toString("base64url");
|
|
@@ -67612,6 +67639,11 @@ function matchesCarrierPoolKey2(poolKey, carrierId) {
|
|
|
67612
67639
|
function namespacePoolKey2(baseKey, originSessionId) {
|
|
67613
67640
|
return originSessionId ? `${originSessionId}:${baseKey}` : baseKey;
|
|
67614
67641
|
}
|
|
67642
|
+
function joinSessionCwdNamespace2(originSessionId, cwd) {
|
|
67643
|
+
const cwdNamespace = cwd ? `cwd-${Buffer.from(cwd, "utf-8").toString("base64url")}` : void 0;
|
|
67644
|
+
if (originSessionId && cwdNamespace) return `${originSessionId}:${cwdNamespace}`;
|
|
67645
|
+
return originSessionId ?? cwdNamespace;
|
|
67646
|
+
}
|
|
67615
67647
|
async function disconnectCarrierExecutorPools2(carrierId) {
|
|
67616
67648
|
const poolKeys = new Set(listActivePoolKeys2().filter((poolKey) => matchesCarrierPoolKey2(poolKey, carrierId)));
|
|
67617
67649
|
poolKeys.add(carrierId);
|
|
@@ -70415,7 +70447,7 @@ function escapeRegExp2(str) {
|
|
|
70415
70447
|
}
|
|
70416
70448
|
var taskForceStateStore2 = /* @__PURE__ */ new Map();
|
|
70417
70449
|
function launchTaskForceJob2(options2) {
|
|
70418
|
-
const { registry: registry32, carrierId, request, label, startedAt, toolName, ctx, deps } = options2;
|
|
70450
|
+
const { registry: registry32, carrierId, request, label, startedAt, toolName, ctx, cwd, deps } = options2;
|
|
70419
70451
|
const requestKey = buildTaskForceRequestKey2(carrierId, request);
|
|
70420
70452
|
getConfiguredTaskForceBackends2(carrierId);
|
|
70421
70453
|
assertRegisteredCarrier2(registry32, carrierId);
|
|
@@ -70468,7 +70500,7 @@ function launchTaskForceJob2(options2) {
|
|
|
70468
70500
|
request,
|
|
70469
70501
|
state,
|
|
70470
70502
|
signal: launch.signal,
|
|
70471
|
-
cwd
|
|
70503
|
+
cwd,
|
|
70472
70504
|
permit: launch.permit,
|
|
70473
70505
|
startedAt,
|
|
70474
70506
|
toolName,
|
|
@@ -70560,7 +70592,7 @@ function getRequiredTaskForceModelConfig2(carrierId, cliType) {
|
|
|
70560
70592
|
async function runTaskForceBackend2(registry32, cliType, carrierId, originSessionId, requestKey, request, state, signal, cwd, jobId, trackModelInfoByCli, deps) {
|
|
70561
70593
|
const execStartedAt = Date.now();
|
|
70562
70594
|
const progress = state.backends.get(cliType);
|
|
70563
|
-
const poolKey = buildTaskForceExecutorPoolKey2(carrierId, cliType, originSessionId);
|
|
70595
|
+
const poolKey = buildTaskForceExecutorPoolKey2(carrierId, cliType, originSessionId, cwd);
|
|
70564
70596
|
buildTaskForceScopedRunId2(requestKey, cliType);
|
|
70565
70597
|
const modelInfo = trackModelInfoByCli.get(cliType);
|
|
70566
70598
|
if (!modelInfo) throw new Error(`Task Force config missing for ${cliType} on carrier "${carrierId}".`);
|
|
@@ -70765,7 +70797,8 @@ function buildCarrierDispatchToolSpec2(registry32, deps) {
|
|
|
70765
70797
|
CARRIER_REQUEST_BREVITY_GUIDELINE2
|
|
70766
70798
|
],
|
|
70767
70799
|
guardrails: [
|
|
70768
|
-
`Multiple agents may be working on this codebase at the same time on a single filesystem and branch. Only touch changes you made \u2014 never revert or overwrite modifications made by others. Prefer precise edits (edit) over full-file writes (write). Always re-read a file before modifying it, as it may have changed since your last read
|
|
70800
|
+
`Multiple agents may be working on this codebase at the same time on a single filesystem and branch. Only touch changes you made \u2014 never revert or overwrite modifications made by others. Prefer precise edits (edit) over full-file writes (write). Always re-read a file before modifying it, as it may have changed since your last read.`,
|
|
70801
|
+
`When the carrier must work in a directory other than the host session cwd (e.g. a git worktree checkout), pass cwd as an absolute path so the carrier's CLI spawns there; never pass a relative path. Omit cwd to use the host session cwd.`
|
|
70769
70802
|
],
|
|
70770
70803
|
get parameters() {
|
|
70771
70804
|
const carrierIds = getRegisteredOrder2(registry32);
|
|
@@ -70779,12 +70812,14 @@ function buildCarrierDispatchToolSpec2(registry32, deps) {
|
|
|
70779
70812
|
}),
|
|
70780
70813
|
request: typebox_exports2.String({
|
|
70781
70814
|
description: `The task/prompt to send to the carrier. Required blocks per carrier -- see <fleet section="roster">. Missing blocks cause hard-error rejection.`
|
|
70782
|
-
})
|
|
70815
|
+
}),
|
|
70816
|
+
cwd: typebox_exports2.Optional(typebox_exports2.String({
|
|
70817
|
+
description: `Optional absolute working directory for the carrier's CLI spawn. MUST be an absolute path. Provide it when delegating work to a directory other than the host session cwd (e.g. a git worktree checkout) so the carrier spawns deterministically at that path. Omit to default to the host session cwd.`
|
|
70818
|
+
}))
|
|
70783
70819
|
});
|
|
70784
70820
|
},
|
|
70785
70821
|
async execute(args, ctx) {
|
|
70786
70822
|
const t0 = Date.now();
|
|
70787
|
-
const cwd = ctx.cwd;
|
|
70788
70823
|
const toolCallId = ctx.toolCallId ?? "";
|
|
70789
70824
|
const jobId = buildCarrierJobId2("carrier", toolCallId);
|
|
70790
70825
|
const toolName = "carrier_dispatch";
|
|
@@ -70795,6 +70830,11 @@ function buildCarrierDispatchToolSpec2(registry32, deps) {
|
|
|
70795
70830
|
error: "Invalid arguments: carrier_id, label, and request must be non-empty strings."
|
|
70796
70831
|
});
|
|
70797
70832
|
}
|
|
70833
|
+
const cwdResolution = resolveDispatchCwd2(args.cwd, ctx.cwd);
|
|
70834
|
+
if (!cwdResolution.ok) {
|
|
70835
|
+
return launchResponseResult2({ job_id: jobId, accepted: false, error: cwdResolution.error });
|
|
70836
|
+
}
|
|
70837
|
+
const cwd = cwdResolution.cwd;
|
|
70798
70838
|
const carrierId = args.carrier_id.trim();
|
|
70799
70839
|
const label = args.label.trim();
|
|
70800
70840
|
const request = args.request;
|
|
@@ -70827,6 +70867,7 @@ function buildCarrierDispatchToolSpec2(registry32, deps) {
|
|
|
70827
70867
|
startedAt: t0,
|
|
70828
70868
|
toolName,
|
|
70829
70869
|
ctx,
|
|
70870
|
+
cwd,
|
|
70830
70871
|
deps
|
|
70831
70872
|
});
|
|
70832
70873
|
}
|
|
@@ -70939,7 +70980,7 @@ async function runSingleCarrier2(opts) {
|
|
|
70939
70980
|
});
|
|
70940
70981
|
try {
|
|
70941
70982
|
const execResult = await executeWithPool2({
|
|
70942
|
-
poolKey: buildCarrierExecutorPoolKey2(opts.carrierId, opts.originSessionId),
|
|
70983
|
+
poolKey: buildCarrierExecutorPoolKey2(opts.carrierId, opts.originSessionId, opts.cwd),
|
|
70943
70984
|
scopeId: opts.carrierId,
|
|
70944
70985
|
authEnvResolver: opts.deps.authEnvResolver,
|
|
70945
70986
|
reservedExternalMcpServerIds: opts.deps.reservedExternalMcpServerIds,
|
|
@@ -71069,7 +71110,19 @@ function buildCarrierDispatchRunId2(jobId, carrierId) {
|
|
|
71069
71110
|
function isDispatchArgs2(v) {
|
|
71070
71111
|
if (typeof v !== "object" || v === null) return false;
|
|
71071
71112
|
const obj = v;
|
|
71072
|
-
return typeof obj.carrier_id === "string" && obj.carrier_id.trim().length > 0 && typeof obj.label === "string" && obj.label.trim().length > 0 && typeof obj.request === "string" && obj.request.trim().length > 0;
|
|
71113
|
+
return typeof obj.carrier_id === "string" && obj.carrier_id.trim().length > 0 && typeof obj.label === "string" && obj.label.trim().length > 0 && typeof obj.request === "string" && obj.request.trim().length > 0 && (obj.cwd === void 0 || typeof obj.cwd === "string");
|
|
71114
|
+
}
|
|
71115
|
+
function resolveDispatchCwd2(rawCwd, fallbackCwd) {
|
|
71116
|
+
if (rawCwd === void 0) return { ok: true, cwd: fallbackCwd };
|
|
71117
|
+
const trimmed = rawCwd.trim();
|
|
71118
|
+
if (trimmed.length === 0) return { ok: true, cwd: fallbackCwd };
|
|
71119
|
+
if (!path92__default.isAbsolute(trimmed)) {
|
|
71120
|
+
return {
|
|
71121
|
+
ok: false,
|
|
71122
|
+
error: `Invalid cwd "${rawCwd}": must be an absolute path. Provide an absolute directory or omit cwd to use the host session cwd.`
|
|
71123
|
+
};
|
|
71124
|
+
}
|
|
71125
|
+
return { ok: true, cwd: trimmed };
|
|
71073
71126
|
}
|
|
71074
71127
|
function buildCarrierRoster2(registry32, carrierIds, options2) {
|
|
71075
71128
|
const { excludeCarrierIds, heading, preambleLines, extraLines } = options2 ?? {};
|
|
@@ -71186,68 +71239,6 @@ function getClaudeModel2(config22) {
|
|
|
71186
71239
|
function clampClaudeEffort2(effort) {
|
|
71187
71240
|
return effort === "max" ? CLAUDE_MAX_EFFORT2 : effort;
|
|
71188
71241
|
}
|
|
71189
|
-
var ROLE_DESCRIPTION_SEPARATOR2 = " - ";
|
|
71190
|
-
function readCarrierStatusEntries(registry32) {
|
|
71191
|
-
const carrierDefaults = buildCarrierDefaultsByCarrier(registry32);
|
|
71192
|
-
return buildCarrierStatusEntriesFromSnapshot(registry32, readFileBackedCarriersSnapshot2(carrierDefaults));
|
|
71193
|
-
}
|
|
71194
|
-
function buildCarrierStatusEntriesFromSnapshot(registry32, snapshot) {
|
|
71195
|
-
const entries = [];
|
|
71196
|
-
for (const carrierId of getRegisteredOrder2(registry32)) {
|
|
71197
|
-
const config22 = getRegisteredCarrierConfig2(registry32, carrierId);
|
|
71198
|
-
if (!config22) continue;
|
|
71199
|
-
const state = snapshot.carriers[carrierId];
|
|
71200
|
-
const cliType = snapshot.carriers[carrierId]?.agentCliType ?? config22.defaultCliType;
|
|
71201
|
-
const selection = snapshot.carriers[carrierId]?.agentCli[cliType];
|
|
71202
|
-
const provider = getProviderModels2(cliType);
|
|
71203
|
-
const role = sanitizeCarrierMetadataText2(config22.carrierMetadata?.title);
|
|
71204
|
-
const roleSummary = sanitizeCarrierMetadataText2(config22.carrierMetadata?.summary);
|
|
71205
|
-
entries.push({
|
|
71206
|
-
carrierId,
|
|
71207
|
-
category: config22.carrierMetadata?.category,
|
|
71208
|
-
cliType,
|
|
71209
|
-
defaultCliType: config22.defaultCliType,
|
|
71210
|
-
displayName: state?.displayName ?? getCarrierSourceDisplayName2(registry32, carrierId),
|
|
71211
|
-
effort: selection?.effort ?? null,
|
|
71212
|
-
isDefault: !selection?.model,
|
|
71213
|
-
model: selection?.model || provider.defaultModel,
|
|
71214
|
-
role,
|
|
71215
|
-
roleDescription: buildRoleDescription2(role, roleSummary),
|
|
71216
|
-
slot: config22.slot,
|
|
71217
|
-
subagentMode: state?.agentMode === "subagent",
|
|
71218
|
-
taskForceBackendCount: getConfiguredTaskForceBackendsFromSnapshot2(snapshot, carrierId).length
|
|
71219
|
-
});
|
|
71220
|
-
}
|
|
71221
|
-
return entries;
|
|
71222
|
-
}
|
|
71223
|
-
function buildCarrierDefaultsByCarrier(registry32) {
|
|
71224
|
-
return Object.fromEntries(
|
|
71225
|
-
getRegisteredOrder2(registry32).map((carrierId) => {
|
|
71226
|
-
const config22 = getRegisteredCarrierConfig2(registry32, carrierId);
|
|
71227
|
-
if (!config22) return null;
|
|
71228
|
-
return [carrierId, buildCarrierDefaults(config22)];
|
|
71229
|
-
}).filter((entry) => entry !== null)
|
|
71230
|
-
);
|
|
71231
|
-
}
|
|
71232
|
-
function buildCarrierDefaults(config22) {
|
|
71233
|
-
const cliType = resolveAgentCliType22(config22.id, config22.defaultCliType);
|
|
71234
|
-
const cliDefaults = buildCarrierModelDefaults2(config22, cliType);
|
|
71235
|
-
return {
|
|
71236
|
-
cliType,
|
|
71237
|
-
...config22.defaultAgentMode ? { defaultAgentMode: config22.defaultAgentMode } : {},
|
|
71238
|
-
...cliDefaults.defaultEffort ? { defaultEffort: cliDefaults.defaultEffort } : {},
|
|
71239
|
-
...cliDefaults.defaultModel ? { defaultModel: cliDefaults.defaultModel } : {}
|
|
71240
|
-
};
|
|
71241
|
-
}
|
|
71242
|
-
function buildRoleDescription2(role, summary) {
|
|
71243
|
-
if (role && summary) return `${role}${ROLE_DESCRIPTION_SEPARATOR2}${summary}`;
|
|
71244
|
-
return role ?? summary;
|
|
71245
|
-
}
|
|
71246
|
-
function sanitizeCarrierMetadataText2(value) {
|
|
71247
|
-
if (typeof value !== "string") return null;
|
|
71248
|
-
const sanitized = sanitizeToolBlockLabel2(value).trim();
|
|
71249
|
-
return sanitized.length > 0 ? sanitized : null;
|
|
71250
|
-
}
|
|
71251
71242
|
var dispatch2 = {
|
|
71252
71243
|
...framework_exports2,
|
|
71253
71244
|
framework: framework_exports2,
|
|
@@ -79375,8 +79366,98 @@ function buildWikiToolSpec(config22, usage) {
|
|
|
79375
79366
|
}
|
|
79376
79367
|
};
|
|
79377
79368
|
}
|
|
79369
|
+
var AGENT_CLI_API_CATALOG = [
|
|
79370
|
+
{
|
|
79371
|
+
method: "GET",
|
|
79372
|
+
path: "/agent-cli/state",
|
|
79373
|
+
summary: "\uC124\uCE58\uB41C Agent CLI \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
79374
|
+
category: "Agent CLI",
|
|
79375
|
+
gate: "loopback"
|
|
79376
|
+
}
|
|
79377
|
+
];
|
|
79378
|
+
function createAgentCliRouter(deps) {
|
|
79379
|
+
return async function handleAgentCliRoute(context) {
|
|
79380
|
+
const { req, res, pathname } = context;
|
|
79381
|
+
if (pathname === "/agent-cli/state") {
|
|
79382
|
+
if (req.method !== "GET") {
|
|
79383
|
+
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
79384
|
+
return true;
|
|
79385
|
+
}
|
|
79386
|
+
const clis = await deps.detect();
|
|
79387
|
+
const body = { clis };
|
|
79388
|
+
deps.writeJson(res, 200, body);
|
|
79389
|
+
return true;
|
|
79390
|
+
}
|
|
79391
|
+
return false;
|
|
79392
|
+
};
|
|
79393
|
+
}
|
|
79378
79394
|
var SUBAGENT_CLI_TYPES = /* @__PURE__ */ new Set(["claude", "claude-zai", "claude-kimi", "claude-glm"]);
|
|
79379
79395
|
var TASKFORCE_MIN_BACKENDS = 2;
|
|
79396
|
+
var CARRIER_SETTINGS_API_CATALOG = [
|
|
79397
|
+
{
|
|
79398
|
+
method: "GET",
|
|
79399
|
+
path: "/carrier-settings/state",
|
|
79400
|
+
summary: "\uCE90\uB9AC\uC5B4 \uC124\uC815 \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
79401
|
+
category: "Carrier Settings",
|
|
79402
|
+
gate: "loopback"
|
|
79403
|
+
},
|
|
79404
|
+
{
|
|
79405
|
+
method: "GET",
|
|
79406
|
+
path: "/carrier-settings/options",
|
|
79407
|
+
summary: "\uCE90\uB9AC\uC5B4 \uC124\uC815 \uC120\uD0DD\uC9C0\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
79408
|
+
category: "Carrier Settings",
|
|
79409
|
+
gate: "loopback"
|
|
79410
|
+
},
|
|
79411
|
+
{
|
|
79412
|
+
method: "PUT",
|
|
79413
|
+
path: "/carrier-settings/carriers/:id/cli",
|
|
79414
|
+
summary: "\uCE90\uB9AC\uC5B4 Agent CLI\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4.",
|
|
79415
|
+
category: "Carrier Settings",
|
|
79416
|
+
gate: "terminal-origin"
|
|
79417
|
+
},
|
|
79418
|
+
{
|
|
79419
|
+
method: "PUT",
|
|
79420
|
+
path: "/carrier-settings/carriers/:id/model",
|
|
79421
|
+
summary: "\uCE90\uB9AC\uC5B4 \uBAA8\uB378 \uC120\uD0DD\uC744 \uBCC0\uACBD\uD569\uB2C8\uB2E4.",
|
|
79422
|
+
category: "Carrier Settings",
|
|
79423
|
+
gate: "terminal-origin"
|
|
79424
|
+
},
|
|
79425
|
+
{
|
|
79426
|
+
method: "PATCH",
|
|
79427
|
+
path: "/carrier-settings/carriers/:id/display-name",
|
|
79428
|
+
summary: "\uCE90\uB9AC\uC5B4 \uD45C\uC2DC \uC774\uB984\uC744 \uBCC0\uACBD\uD569\uB2C8\uB2E4.",
|
|
79429
|
+
category: "Carrier Settings",
|
|
79430
|
+
gate: "terminal-origin"
|
|
79431
|
+
},
|
|
79432
|
+
{
|
|
79433
|
+
method: "PUT",
|
|
79434
|
+
path: "/carrier-settings/carriers/:id/agent-mode",
|
|
79435
|
+
summary: "\uCE90\uB9AC\uC5B4 \uC2E4\uD589 \uBAA8\uB4DC\uB97C \uBCC0\uACBD\uD569\uB2C8\uB2E4.",
|
|
79436
|
+
category: "Carrier Settings",
|
|
79437
|
+
gate: "terminal-origin"
|
|
79438
|
+
},
|
|
79439
|
+
{
|
|
79440
|
+
method: "PUT",
|
|
79441
|
+
path: "/carrier-settings/carriers/:id/taskforce/:cliType",
|
|
79442
|
+
summary: "Task Force \uBC31\uC5D4\uB4DC \uBAA8\uB378\uC744 \uC124\uC815\uD569\uB2C8\uB2E4.",
|
|
79443
|
+
category: "Carrier Settings",
|
|
79444
|
+
gate: "terminal-origin"
|
|
79445
|
+
},
|
|
79446
|
+
{
|
|
79447
|
+
method: "DELETE",
|
|
79448
|
+
path: "/carrier-settings/carriers/:id/taskforce/:cliType",
|
|
79449
|
+
summary: "Task Force \uBC31\uC5D4\uB4DC \uBAA8\uB378 \uC124\uC815\uC744 \uD574\uC81C\uD569\uB2C8\uB2E4.",
|
|
79450
|
+
category: "Carrier Settings",
|
|
79451
|
+
gate: "terminal-origin"
|
|
79452
|
+
},
|
|
79453
|
+
{
|
|
79454
|
+
method: "DELETE",
|
|
79455
|
+
path: "/carrier-settings/carriers/:id/taskforce",
|
|
79456
|
+
summary: "\uCE90\uB9AC\uC5B4 Task Force \uC124\uC815\uC744 \uCD08\uAE30\uD654\uD569\uB2C8\uB2E4.",
|
|
79457
|
+
category: "Carrier Settings",
|
|
79458
|
+
gate: "terminal-origin"
|
|
79459
|
+
}
|
|
79460
|
+
];
|
|
79380
79461
|
function createCarrierSettingsRouter(deps) {
|
|
79381
79462
|
const controller = createStatusOverlayController(deps.registry);
|
|
79382
79463
|
return async function handleCarrierSettingsRoute(context) {
|
|
@@ -79787,6 +79868,255 @@ function requireCarrierConfig(registry32, carrierId) {
|
|
|
79787
79868
|
if (!config22) throw new Error(`Carrier not found: ${carrierId}`);
|
|
79788
79869
|
return config22;
|
|
79789
79870
|
}
|
|
79871
|
+
var GLOBAL_SETTINGS_API_CATALOG = [
|
|
79872
|
+
{
|
|
79873
|
+
method: "GET",
|
|
79874
|
+
path: "/global-settings/state",
|
|
79875
|
+
summary: "\uC804\uC5ED \uCF58\uC194 \uC124\uC815 \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
79876
|
+
category: "Global Settings",
|
|
79877
|
+
gate: "loopback"
|
|
79878
|
+
},
|
|
79879
|
+
{
|
|
79880
|
+
method: "PUT",
|
|
79881
|
+
path: "/global-settings",
|
|
79882
|
+
summary: "\uC804\uC5ED \uCF58\uC194 \uC124\uC815\uC744 \uC800\uC7A5\uD569\uB2C8\uB2E4.",
|
|
79883
|
+
category: "Global Settings",
|
|
79884
|
+
gate: "terminal-origin"
|
|
79885
|
+
}
|
|
79886
|
+
];
|
|
79887
|
+
function createGlobalSettingsRouter(deps) {
|
|
79888
|
+
return async function handleGlobalSettingsRoute(context) {
|
|
79889
|
+
const { req, res, pathname } = context;
|
|
79890
|
+
if (pathname === "/global-settings/state") {
|
|
79891
|
+
if (req.method !== "GET") {
|
|
79892
|
+
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
79893
|
+
return true;
|
|
79894
|
+
}
|
|
79895
|
+
deps.writeJson(res, 200, buildGlobalSettingsState(deps.globalOptionsService));
|
|
79896
|
+
return true;
|
|
79897
|
+
}
|
|
79898
|
+
if (pathname === "/global-settings") {
|
|
79899
|
+
if (req.method !== "PUT") {
|
|
79900
|
+
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
79901
|
+
return true;
|
|
79902
|
+
}
|
|
79903
|
+
await mutateGlobalSettings(req, res, deps);
|
|
79904
|
+
return true;
|
|
79905
|
+
}
|
|
79906
|
+
return false;
|
|
79907
|
+
};
|
|
79908
|
+
}
|
|
79909
|
+
function buildGlobalSettingsState(service) {
|
|
79910
|
+
return toGlobalSettingsState(service.load());
|
|
79911
|
+
}
|
|
79912
|
+
async function mutateGlobalSettings(req, res, deps) {
|
|
79913
|
+
if (!deps.isAuthorized(req)) {
|
|
79914
|
+
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
79915
|
+
return;
|
|
79916
|
+
}
|
|
79917
|
+
if (!isJsonRequest2(req)) {
|
|
79918
|
+
deps.writeJson(res, 415, { error: "unsupported_media_type" });
|
|
79919
|
+
return;
|
|
79920
|
+
}
|
|
79921
|
+
const body = await deps.readJsonBody(req);
|
|
79922
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
79923
|
+
deps.writeJson(res, 400, { error: "invalid_json" });
|
|
79924
|
+
return;
|
|
79925
|
+
}
|
|
79926
|
+
if (body.replaceSystemPrompt !== void 0 && typeof body.replaceSystemPrompt !== "boolean") {
|
|
79927
|
+
deps.writeJson(res, 400, { error: "invalid_replace_system_prompt" });
|
|
79928
|
+
return;
|
|
79929
|
+
}
|
|
79930
|
+
if (body.enableMetaphor !== void 0 && typeof body.enableMetaphor !== "boolean") {
|
|
79931
|
+
deps.writeJson(res, 400, { error: "invalid_enable_metaphor" });
|
|
79932
|
+
return;
|
|
79933
|
+
}
|
|
79934
|
+
const updated = deps.globalOptionsService.update((current) => ({
|
|
79935
|
+
...current,
|
|
79936
|
+
...typeof body.replaceSystemPrompt === "boolean" ? { replaceSystemPrompt: body.replaceSystemPrompt } : {},
|
|
79937
|
+
...typeof body.enableMetaphor === "boolean" ? { enableMetaphor: body.enableMetaphor } : {}
|
|
79938
|
+
}));
|
|
79939
|
+
const response = { state: toGlobalSettingsState(updated) };
|
|
79940
|
+
deps.writeJson(res, 200, response);
|
|
79941
|
+
}
|
|
79942
|
+
function toGlobalSettingsState(data) {
|
|
79943
|
+
return {
|
|
79944
|
+
replaceSystemPrompt: data.replaceSystemPrompt ?? false,
|
|
79945
|
+
enableMetaphor: data.enableMetaphor ?? false
|
|
79946
|
+
};
|
|
79947
|
+
}
|
|
79948
|
+
function isJsonRequest2(req) {
|
|
79949
|
+
const contentType = req.headers["content-type"];
|
|
79950
|
+
return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
|
|
79951
|
+
}
|
|
79952
|
+
var MODEL_AUTH_PROVIDERS = [
|
|
79953
|
+
{ cli: "claude-kimi", displayName: "Moonshot Kimi" },
|
|
79954
|
+
{ cli: "claude-glm", displayName: "ZhipuAI GLM" }
|
|
79955
|
+
];
|
|
79956
|
+
var UPSTREAM_FAILURE_STATUSES = /* @__PURE__ */ new Set(["timeout", "network", "server"]);
|
|
79957
|
+
var MODEL_AUTH_API_CATALOG = [
|
|
79958
|
+
{
|
|
79959
|
+
method: "GET",
|
|
79960
|
+
path: "/model-auth/state",
|
|
79961
|
+
summary: "\uBAA8\uB378 \uB85C\uADF8\uC778 \uC0C1\uD0DC\uB97C \uC870\uD68C\uD569\uB2C8\uB2E4.",
|
|
79962
|
+
category: "Model Auth",
|
|
79963
|
+
gate: "loopback"
|
|
79964
|
+
},
|
|
79965
|
+
{
|
|
79966
|
+
method: "PUT",
|
|
79967
|
+
path: "/model-auth/providers/:cli",
|
|
79968
|
+
summary: "\uBAA8\uB378 \uC81C\uACF5\uC790 API \uD0A4\uB97C \uB4F1\uB85D\uD569\uB2C8\uB2E4.",
|
|
79969
|
+
category: "Model Auth",
|
|
79970
|
+
gate: "terminal-origin"
|
|
79971
|
+
},
|
|
79972
|
+
{
|
|
79973
|
+
method: "DELETE",
|
|
79974
|
+
path: "/model-auth/providers/:cli",
|
|
79975
|
+
summary: "\uBAA8\uB378 \uC81C\uACF5\uC790 API \uD0A4\uB97C \uC0AD\uC81C\uD569\uB2C8\uB2E4.",
|
|
79976
|
+
category: "Model Auth",
|
|
79977
|
+
gate: "terminal-origin"
|
|
79978
|
+
}
|
|
79979
|
+
];
|
|
79980
|
+
function createModelAuthRouter(deps) {
|
|
79981
|
+
return async function handleModelAuthRoute(context) {
|
|
79982
|
+
const { req, res, pathname } = context;
|
|
79983
|
+
if (pathname === "/model-auth/state") {
|
|
79984
|
+
if (req.method !== "GET") {
|
|
79985
|
+
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
79986
|
+
return true;
|
|
79987
|
+
}
|
|
79988
|
+
deps.writeJson(res, 200, await buildModelAuthState(deps.authService));
|
|
79989
|
+
return true;
|
|
79990
|
+
}
|
|
79991
|
+
const cli = parseProviderPath(pathname);
|
|
79992
|
+
if (!cli) return false;
|
|
79993
|
+
const provider = MODEL_AUTH_PROVIDERS.find((entry) => entry.cli === cli);
|
|
79994
|
+
if (!provider) {
|
|
79995
|
+
deps.writeJson(res, 404, { error: "provider_not_found" });
|
|
79996
|
+
return true;
|
|
79997
|
+
}
|
|
79998
|
+
if (req.method === "PUT") {
|
|
79999
|
+
await signInProvider(req, res, deps, provider);
|
|
80000
|
+
return true;
|
|
80001
|
+
}
|
|
80002
|
+
if (req.method === "DELETE") {
|
|
80003
|
+
await signOutProvider(req, res, deps, provider);
|
|
80004
|
+
return true;
|
|
80005
|
+
}
|
|
80006
|
+
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
80007
|
+
return true;
|
|
80008
|
+
};
|
|
80009
|
+
}
|
|
80010
|
+
async function buildModelAuthState(authService) {
|
|
80011
|
+
const signedInIds = new Set(await authService.listProviderIds());
|
|
80012
|
+
return {
|
|
80013
|
+
providers: MODEL_AUTH_PROVIDERS.map((provider) => toProviderState(provider, signedInIds))
|
|
80014
|
+
};
|
|
80015
|
+
}
|
|
80016
|
+
async function signInProvider(req, res, deps, provider) {
|
|
80017
|
+
if (!deps.isAuthorized(req)) {
|
|
80018
|
+
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
80019
|
+
return;
|
|
80020
|
+
}
|
|
80021
|
+
if (!isJsonRequest3(req)) {
|
|
80022
|
+
deps.writeJson(res, 415, { error: "unsupported_media_type" });
|
|
80023
|
+
return;
|
|
80024
|
+
}
|
|
80025
|
+
const body = await deps.readJsonBody(req);
|
|
80026
|
+
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
80027
|
+
deps.writeJson(res, 400, { error: "invalid_json" });
|
|
80028
|
+
return;
|
|
80029
|
+
}
|
|
80030
|
+
const apiKey = typeof body.apiKey === "string" ? body.apiKey.trim() : "";
|
|
80031
|
+
if (apiKey.length === 0) {
|
|
80032
|
+
deps.writeJson(res, 400, { error: "invalid_api_key" });
|
|
80033
|
+
return;
|
|
80034
|
+
}
|
|
80035
|
+
const providerId = CLI_TO_AUTH_PROVIDER_ID2[provider.cli];
|
|
80036
|
+
if (!providerId) {
|
|
80037
|
+
deps.writeJson(res, 500, { error: "provider_unavailable" });
|
|
80038
|
+
return;
|
|
80039
|
+
}
|
|
80040
|
+
const validation = await deps.validateApiKey(provider.cli, apiKey);
|
|
80041
|
+
if (validation.status !== "success") {
|
|
80042
|
+
const status = UPSTREAM_FAILURE_STATUSES.has(validation.status) ? 502 : 400;
|
|
80043
|
+
deps.writeJson(res, status, {
|
|
80044
|
+
error: formatSignInFailureMessage(provider.displayName, validation.status),
|
|
80045
|
+
status: validation.status
|
|
80046
|
+
});
|
|
80047
|
+
return;
|
|
80048
|
+
}
|
|
80049
|
+
await deps.authService.setApiKey(providerId, apiKey);
|
|
80050
|
+
await writeMutationState2(res, deps);
|
|
80051
|
+
}
|
|
80052
|
+
async function signOutProvider(req, res, deps, provider) {
|
|
80053
|
+
if (!deps.isAuthorized(req)) {
|
|
80054
|
+
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
80055
|
+
return;
|
|
80056
|
+
}
|
|
80057
|
+
const providerId = CLI_TO_AUTH_PROVIDER_ID2[provider.cli];
|
|
80058
|
+
if (!providerId) {
|
|
80059
|
+
deps.writeJson(res, 500, { error: "provider_unavailable" });
|
|
80060
|
+
return;
|
|
80061
|
+
}
|
|
80062
|
+
await deps.authService.deleteApiKey(providerId);
|
|
80063
|
+
await writeMutationState2(res, deps);
|
|
80064
|
+
}
|
|
80065
|
+
async function writeMutationState2(res, deps) {
|
|
80066
|
+
const response = { state: await buildModelAuthState(deps.authService) };
|
|
80067
|
+
deps.writeJson(res, 200, response);
|
|
80068
|
+
}
|
|
80069
|
+
function toProviderState(provider, signedInIds) {
|
|
80070
|
+
const providerId = CLI_TO_AUTH_PROVIDER_ID2[provider.cli] ?? provider.cli;
|
|
80071
|
+
return {
|
|
80072
|
+
cli: provider.cli,
|
|
80073
|
+
displayName: provider.displayName,
|
|
80074
|
+
signedIn: signedInIds.has(providerId)
|
|
80075
|
+
};
|
|
80076
|
+
}
|
|
80077
|
+
function parseProviderPath(pathname) {
|
|
80078
|
+
const parts = pathname.split("/").filter(Boolean);
|
|
80079
|
+
if (parts.length !== 3 || parts[0] !== "model-auth" || parts[1] !== "providers") return null;
|
|
80080
|
+
const cli = safeDecodeURIComponent2(parts[2] ?? "");
|
|
80081
|
+
return cli ? cli : null;
|
|
80082
|
+
}
|
|
80083
|
+
function safeDecodeURIComponent2(value) {
|
|
80084
|
+
try {
|
|
80085
|
+
return decodeURIComponent(value);
|
|
80086
|
+
} catch {
|
|
80087
|
+
return null;
|
|
80088
|
+
}
|
|
80089
|
+
}
|
|
80090
|
+
function isJsonRequest3(req) {
|
|
80091
|
+
const contentType = req.headers["content-type"];
|
|
80092
|
+
return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
|
|
80093
|
+
}
|
|
80094
|
+
function formatSignInFailureMessage(displayName, status) {
|
|
80095
|
+
switch (status) {
|
|
80096
|
+
case "unauthorized":
|
|
80097
|
+
return `${displayName} rejected the API key. Check the key and try again.`;
|
|
80098
|
+
case "forbidden":
|
|
80099
|
+
return `The API key is not allowed for ${displayName}. Check its permissions.`;
|
|
80100
|
+
case "timeout":
|
|
80101
|
+
return `Validating the ${displayName} API key timed out. Check your connection and try again.`;
|
|
80102
|
+
case "network":
|
|
80103
|
+
return `Could not reach ${displayName} to validate the API key. Check your connection and try again.`;
|
|
80104
|
+
case "server":
|
|
80105
|
+
return `${displayName} returned an error while validating the API key. Try again later.`;
|
|
80106
|
+
default:
|
|
80107
|
+
return `Could not validate the ${displayName} API key. Check the key and try again.`;
|
|
80108
|
+
}
|
|
80109
|
+
}
|
|
80110
|
+
var compareApiCatalogEntries = (left, right) => left.category.localeCompare(right.category) || left.path.localeCompare(right.path) || left.method.localeCompare(right.method);
|
|
80111
|
+
function buildApiCatalog() {
|
|
80112
|
+
return [
|
|
80113
|
+
...SERVER_API_CATALOG,
|
|
80114
|
+
...CARRIER_SETTINGS_API_CATALOG,
|
|
80115
|
+
...GLOBAL_SETTINGS_API_CATALOG,
|
|
80116
|
+
...AGENT_CLI_API_CATALOG,
|
|
80117
|
+
...MODEL_AUTH_API_CATALOG
|
|
80118
|
+
].slice().sort(compareApiCatalogEntries);
|
|
80119
|
+
}
|
|
79790
80120
|
var CONTENT_SECURITY_POLICY = "default-src 'self'; script-src 'self'; style-src 'self' 'unsafe-inline'; img-src 'self' data:; connect-src 'self'; object-src 'none'; base-uri 'none'";
|
|
79791
80121
|
var SECURITY_HEADERS = {
|
|
79792
80122
|
"content-security-policy": CONTENT_SECURITY_POLICY,
|
|
@@ -80693,7 +81023,7 @@ function createCodexGateway(deps) {
|
|
|
80693
81023
|
return true;
|
|
80694
81024
|
}
|
|
80695
81025
|
if (selected.kind === "no-workspace") {
|
|
80696
|
-
if (
|
|
81026
|
+
if (isJsonRequest4(request)) {
|
|
80697
81027
|
sendJson2(response, 404, { error: "no_workspace_registered" });
|
|
80698
81028
|
return true;
|
|
80699
81029
|
}
|
|
@@ -80814,7 +81144,7 @@ function legacyWorkspacePath(url22) {
|
|
|
80814
81144
|
}
|
|
80815
81145
|
return null;
|
|
80816
81146
|
}
|
|
80817
|
-
function
|
|
81147
|
+
function isJsonRequest4(request) {
|
|
80818
81148
|
const accept = Array.isArray(request.headers.accept) ? request.headers.accept.join(",") : request.headers.accept ?? "";
|
|
80819
81149
|
const requestedWith = Array.isArray(request.headers["x-requested-with"]) ? request.headers["x-requested-with"].join(",") : request.headers["x-requested-with"] ?? "";
|
|
80820
81150
|
return accept.includes("application/json") || requestedWith.toLowerCase() === "xmlhttprequest";
|
|
@@ -81107,71 +81437,6 @@ function looksSecretToken(rawToken) {
|
|
|
81107
81437
|
if (SECRET_PREFIX_PATTERN.test(token)) return true;
|
|
81108
81438
|
return token.length >= SECRET_MIN_TOKEN_LENGTH && SECRET_CHARSET_PATTERN.test(token) && /[0-9]/.test(token) && /[A-Za-z]/.test(token);
|
|
81109
81439
|
}
|
|
81110
|
-
function createGlobalSettingsRouter(deps) {
|
|
81111
|
-
return async function handleGlobalSettingsRoute(context) {
|
|
81112
|
-
const { req, res, pathname } = context;
|
|
81113
|
-
if (pathname === "/global-settings/state") {
|
|
81114
|
-
if (req.method !== "GET") {
|
|
81115
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
81116
|
-
return true;
|
|
81117
|
-
}
|
|
81118
|
-
deps.writeJson(res, 200, buildGlobalSettingsState(deps.globalOptionsService));
|
|
81119
|
-
return true;
|
|
81120
|
-
}
|
|
81121
|
-
if (pathname === "/global-settings") {
|
|
81122
|
-
if (req.method !== "PUT") {
|
|
81123
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
81124
|
-
return true;
|
|
81125
|
-
}
|
|
81126
|
-
await mutateGlobalSettings(req, res, deps);
|
|
81127
|
-
return true;
|
|
81128
|
-
}
|
|
81129
|
-
return false;
|
|
81130
|
-
};
|
|
81131
|
-
}
|
|
81132
|
-
function buildGlobalSettingsState(service) {
|
|
81133
|
-
return toGlobalSettingsState(service.load());
|
|
81134
|
-
}
|
|
81135
|
-
async function mutateGlobalSettings(req, res, deps) {
|
|
81136
|
-
if (!deps.isAuthorized(req)) {
|
|
81137
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
81138
|
-
return;
|
|
81139
|
-
}
|
|
81140
|
-
if (!isJsonRequest3(req)) {
|
|
81141
|
-
deps.writeJson(res, 415, { error: "unsupported_media_type" });
|
|
81142
|
-
return;
|
|
81143
|
-
}
|
|
81144
|
-
const body = await deps.readJsonBody(req);
|
|
81145
|
-
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
81146
|
-
deps.writeJson(res, 400, { error: "invalid_json" });
|
|
81147
|
-
return;
|
|
81148
|
-
}
|
|
81149
|
-
if (body.replaceSystemPrompt !== void 0 && typeof body.replaceSystemPrompt !== "boolean") {
|
|
81150
|
-
deps.writeJson(res, 400, { error: "invalid_replace_system_prompt" });
|
|
81151
|
-
return;
|
|
81152
|
-
}
|
|
81153
|
-
if (body.enableMetaphor !== void 0 && typeof body.enableMetaphor !== "boolean") {
|
|
81154
|
-
deps.writeJson(res, 400, { error: "invalid_enable_metaphor" });
|
|
81155
|
-
return;
|
|
81156
|
-
}
|
|
81157
|
-
const updated = deps.globalOptionsService.update((current) => ({
|
|
81158
|
-
...current,
|
|
81159
|
-
...typeof body.replaceSystemPrompt === "boolean" ? { replaceSystemPrompt: body.replaceSystemPrompt } : {},
|
|
81160
|
-
...typeof body.enableMetaphor === "boolean" ? { enableMetaphor: body.enableMetaphor } : {}
|
|
81161
|
-
}));
|
|
81162
|
-
const response = { state: toGlobalSettingsState(updated) };
|
|
81163
|
-
deps.writeJson(res, 200, response);
|
|
81164
|
-
}
|
|
81165
|
-
function toGlobalSettingsState(data) {
|
|
81166
|
-
return {
|
|
81167
|
-
replaceSystemPrompt: data.replaceSystemPrompt ?? false,
|
|
81168
|
-
enableMetaphor: data.enableMetaphor ?? false
|
|
81169
|
-
};
|
|
81170
|
-
}
|
|
81171
|
-
function isJsonRequest3(req) {
|
|
81172
|
-
const contentType = req.headers["content-type"];
|
|
81173
|
-
return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
|
|
81174
|
-
}
|
|
81175
81440
|
var BINARY_DISPLAY_NAMES = {
|
|
81176
81441
|
claude: "Claude Code",
|
|
81177
81442
|
codex: "Codex CLI",
|
|
@@ -81268,157 +81533,6 @@ function combineAgentCliLaunchMetadata(metadata, installStatuses, authStatuses)
|
|
|
81268
81533
|
signedIn: signedInByCli.has(meta32.id) ? signedInByCli.get(meta32.id) ?? false : true
|
|
81269
81534
|
}));
|
|
81270
81535
|
}
|
|
81271
|
-
function createAgentCliRouter(deps) {
|
|
81272
|
-
return async function handleAgentCliRoute(context) {
|
|
81273
|
-
const { req, res, pathname } = context;
|
|
81274
|
-
if (pathname === "/agent-cli/state") {
|
|
81275
|
-
if (req.method !== "GET") {
|
|
81276
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
81277
|
-
return true;
|
|
81278
|
-
}
|
|
81279
|
-
const clis = await deps.detect();
|
|
81280
|
-
const body = { clis };
|
|
81281
|
-
deps.writeJson(res, 200, body);
|
|
81282
|
-
return true;
|
|
81283
|
-
}
|
|
81284
|
-
return false;
|
|
81285
|
-
};
|
|
81286
|
-
}
|
|
81287
|
-
var MODEL_AUTH_PROVIDERS = [
|
|
81288
|
-
{ cli: "claude-kimi", displayName: "Moonshot Kimi" },
|
|
81289
|
-
{ cli: "claude-glm", displayName: "ZhipuAI GLM" }
|
|
81290
|
-
];
|
|
81291
|
-
var UPSTREAM_FAILURE_STATUSES = /* @__PURE__ */ new Set(["timeout", "network", "server"]);
|
|
81292
|
-
function createModelAuthRouter(deps) {
|
|
81293
|
-
return async function handleModelAuthRoute(context) {
|
|
81294
|
-
const { req, res, pathname } = context;
|
|
81295
|
-
if (pathname === "/model-auth/state") {
|
|
81296
|
-
if (req.method !== "GET") {
|
|
81297
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
81298
|
-
return true;
|
|
81299
|
-
}
|
|
81300
|
-
deps.writeJson(res, 200, await buildModelAuthState(deps.authService));
|
|
81301
|
-
return true;
|
|
81302
|
-
}
|
|
81303
|
-
const cli = parseProviderPath(pathname);
|
|
81304
|
-
if (!cli) return false;
|
|
81305
|
-
const provider = MODEL_AUTH_PROVIDERS.find((entry) => entry.cli === cli);
|
|
81306
|
-
if (!provider) {
|
|
81307
|
-
deps.writeJson(res, 404, { error: "provider_not_found" });
|
|
81308
|
-
return true;
|
|
81309
|
-
}
|
|
81310
|
-
if (req.method === "PUT") {
|
|
81311
|
-
await signInProvider(req, res, deps, provider);
|
|
81312
|
-
return true;
|
|
81313
|
-
}
|
|
81314
|
-
if (req.method === "DELETE") {
|
|
81315
|
-
await signOutProvider(req, res, deps, provider);
|
|
81316
|
-
return true;
|
|
81317
|
-
}
|
|
81318
|
-
deps.writeJson(res, 405, { error: "Method not allowed" });
|
|
81319
|
-
return true;
|
|
81320
|
-
};
|
|
81321
|
-
}
|
|
81322
|
-
async function buildModelAuthState(authService) {
|
|
81323
|
-
const signedInIds = new Set(await authService.listProviderIds());
|
|
81324
|
-
return {
|
|
81325
|
-
providers: MODEL_AUTH_PROVIDERS.map((provider) => toProviderState(provider, signedInIds))
|
|
81326
|
-
};
|
|
81327
|
-
}
|
|
81328
|
-
async function signInProvider(req, res, deps, provider) {
|
|
81329
|
-
if (!deps.isAuthorized(req)) {
|
|
81330
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
81331
|
-
return;
|
|
81332
|
-
}
|
|
81333
|
-
if (!isJsonRequest4(req)) {
|
|
81334
|
-
deps.writeJson(res, 415, { error: "unsupported_media_type" });
|
|
81335
|
-
return;
|
|
81336
|
-
}
|
|
81337
|
-
const body = await deps.readJsonBody(req);
|
|
81338
|
-
if (!body || typeof body !== "object" || Array.isArray(body)) {
|
|
81339
|
-
deps.writeJson(res, 400, { error: "invalid_json" });
|
|
81340
|
-
return;
|
|
81341
|
-
}
|
|
81342
|
-
const apiKey = typeof body.apiKey === "string" ? body.apiKey.trim() : "";
|
|
81343
|
-
if (apiKey.length === 0) {
|
|
81344
|
-
deps.writeJson(res, 400, { error: "invalid_api_key" });
|
|
81345
|
-
return;
|
|
81346
|
-
}
|
|
81347
|
-
const providerId = CLI_TO_AUTH_PROVIDER_ID2[provider.cli];
|
|
81348
|
-
if (!providerId) {
|
|
81349
|
-
deps.writeJson(res, 500, { error: "provider_unavailable" });
|
|
81350
|
-
return;
|
|
81351
|
-
}
|
|
81352
|
-
const validation = await deps.validateApiKey(provider.cli, apiKey);
|
|
81353
|
-
if (validation.status !== "success") {
|
|
81354
|
-
const status = UPSTREAM_FAILURE_STATUSES.has(validation.status) ? 502 : 400;
|
|
81355
|
-
deps.writeJson(res, status, {
|
|
81356
|
-
error: formatSignInFailureMessage(provider.displayName, validation.status),
|
|
81357
|
-
status: validation.status
|
|
81358
|
-
});
|
|
81359
|
-
return;
|
|
81360
|
-
}
|
|
81361
|
-
await deps.authService.setApiKey(providerId, apiKey);
|
|
81362
|
-
await writeMutationState2(res, deps);
|
|
81363
|
-
}
|
|
81364
|
-
async function signOutProvider(req, res, deps, provider) {
|
|
81365
|
-
if (!deps.isAuthorized(req)) {
|
|
81366
|
-
deps.writeJson(res, 401, { error: "unauthorized" });
|
|
81367
|
-
return;
|
|
81368
|
-
}
|
|
81369
|
-
const providerId = CLI_TO_AUTH_PROVIDER_ID2[provider.cli];
|
|
81370
|
-
if (!providerId) {
|
|
81371
|
-
deps.writeJson(res, 500, { error: "provider_unavailable" });
|
|
81372
|
-
return;
|
|
81373
|
-
}
|
|
81374
|
-
await deps.authService.deleteApiKey(providerId);
|
|
81375
|
-
await writeMutationState2(res, deps);
|
|
81376
|
-
}
|
|
81377
|
-
async function writeMutationState2(res, deps) {
|
|
81378
|
-
const response = { state: await buildModelAuthState(deps.authService) };
|
|
81379
|
-
deps.writeJson(res, 200, response);
|
|
81380
|
-
}
|
|
81381
|
-
function toProviderState(provider, signedInIds) {
|
|
81382
|
-
const providerId = CLI_TO_AUTH_PROVIDER_ID2[provider.cli] ?? provider.cli;
|
|
81383
|
-
return {
|
|
81384
|
-
cli: provider.cli,
|
|
81385
|
-
displayName: provider.displayName,
|
|
81386
|
-
signedIn: signedInIds.has(providerId)
|
|
81387
|
-
};
|
|
81388
|
-
}
|
|
81389
|
-
function parseProviderPath(pathname) {
|
|
81390
|
-
const parts = pathname.split("/").filter(Boolean);
|
|
81391
|
-
if (parts.length !== 3 || parts[0] !== "model-auth" || parts[1] !== "providers") return null;
|
|
81392
|
-
const cli = safeDecodeURIComponent2(parts[2] ?? "");
|
|
81393
|
-
return cli ? cli : null;
|
|
81394
|
-
}
|
|
81395
|
-
function safeDecodeURIComponent2(value) {
|
|
81396
|
-
try {
|
|
81397
|
-
return decodeURIComponent(value);
|
|
81398
|
-
} catch {
|
|
81399
|
-
return null;
|
|
81400
|
-
}
|
|
81401
|
-
}
|
|
81402
|
-
function isJsonRequest4(req) {
|
|
81403
|
-
const contentType = req.headers["content-type"];
|
|
81404
|
-
return typeof contentType === "string" && contentType.toLowerCase().split(";")[0]?.trim() === "application/json";
|
|
81405
|
-
}
|
|
81406
|
-
function formatSignInFailureMessage(displayName, status) {
|
|
81407
|
-
switch (status) {
|
|
81408
|
-
case "unauthorized":
|
|
81409
|
-
return `${displayName} rejected the API key. Check the key and try again.`;
|
|
81410
|
-
case "forbidden":
|
|
81411
|
-
return `The API key is not allowed for ${displayName}. Check its permissions.`;
|
|
81412
|
-
case "timeout":
|
|
81413
|
-
return `Validating the ${displayName} API key timed out. Check your connection and try again.`;
|
|
81414
|
-
case "network":
|
|
81415
|
-
return `Could not reach ${displayName} to validate the API key. Check your connection and try again.`;
|
|
81416
|
-
case "server":
|
|
81417
|
-
return `${displayName} returned an error while validating the API key. Try again later.`;
|
|
81418
|
-
default:
|
|
81419
|
-
return `Could not validate the ${displayName} API key. Check the key and try again.`;
|
|
81420
|
-
}
|
|
81421
|
-
}
|
|
81422
81536
|
function writeObserverEvents(req, res, workspace, store22) {
|
|
81423
81537
|
res.writeHead(200, withSecurityHeaders2({
|
|
81424
81538
|
"Content-Type": "text/event-stream",
|
|
@@ -83411,6 +83525,162 @@ var THEATER_SHELL_SESSION_PREFIX2 = "shell:";
|
|
|
83411
83525
|
var SERVER_TIMEOUT_MS = 30 * 60 * 1e3;
|
|
83412
83526
|
var MAX_BODY_BYTES = 1024 * 1024;
|
|
83413
83527
|
var UPDATE_APPLY_FORBIDDEN_BODY_KEYS = /* @__PURE__ */ new Set(["channel", "package", "packageName", "packageVersion", "packages", "targetVersion", "version"]);
|
|
83528
|
+
var SERVER_API_CATALOG = [
|
|
83529
|
+
{
|
|
83530
|
+
method: "GET",
|
|
83531
|
+
path: "/observer/status",
|
|
83532
|
+
summary: "Get the console observation status.",
|
|
83533
|
+
category: "Observer",
|
|
83534
|
+
gate: "loopback"
|
|
83535
|
+
},
|
|
83536
|
+
{
|
|
83537
|
+
method: "GET",
|
|
83538
|
+
path: "/observer/api-catalog",
|
|
83539
|
+
summary: "Get the backend API catalog.",
|
|
83540
|
+
category: "Observer",
|
|
83541
|
+
gate: "loopback"
|
|
83542
|
+
},
|
|
83543
|
+
{
|
|
83544
|
+
method: "GET",
|
|
83545
|
+
path: "/observer/tenants",
|
|
83546
|
+
summary: "List observed terminal workspaces.",
|
|
83547
|
+
category: "Observer",
|
|
83548
|
+
gate: "loopback"
|
|
83549
|
+
},
|
|
83550
|
+
{
|
|
83551
|
+
method: "GET",
|
|
83552
|
+
path: "/observer/jobs",
|
|
83553
|
+
summary: "List observed carrier jobs.",
|
|
83554
|
+
category: "Observer",
|
|
83555
|
+
gate: "loopback"
|
|
83556
|
+
},
|
|
83557
|
+
{
|
|
83558
|
+
method: "GET",
|
|
83559
|
+
path: "/observer/events",
|
|
83560
|
+
summary: "Open the observation event stream.",
|
|
83561
|
+
category: "Observer",
|
|
83562
|
+
gate: "loopback"
|
|
83563
|
+
},
|
|
83564
|
+
{
|
|
83565
|
+
method: "GET",
|
|
83566
|
+
path: "/observer/theaters",
|
|
83567
|
+
summary: "List Theaters.",
|
|
83568
|
+
category: "Observer",
|
|
83569
|
+
gate: "loopback"
|
|
83570
|
+
},
|
|
83571
|
+
{
|
|
83572
|
+
method: "POST",
|
|
83573
|
+
path: "/observer/theaters",
|
|
83574
|
+
summary: "Register a new Theater.",
|
|
83575
|
+
category: "Observer",
|
|
83576
|
+
gate: "terminal-origin"
|
|
83577
|
+
},
|
|
83578
|
+
{
|
|
83579
|
+
method: "DELETE",
|
|
83580
|
+
path: "/observer/theaters/:theaterId",
|
|
83581
|
+
summary: "Remove a Theater and its Operations.",
|
|
83582
|
+
category: "Observer",
|
|
83583
|
+
gate: "terminal-origin"
|
|
83584
|
+
},
|
|
83585
|
+
{
|
|
83586
|
+
method: "POST",
|
|
83587
|
+
path: "/observer/theaters/:theaterId/sessions",
|
|
83588
|
+
summary: "Create a new Operation in a Theater.",
|
|
83589
|
+
category: "Observer",
|
|
83590
|
+
gate: "terminal-origin"
|
|
83591
|
+
},
|
|
83592
|
+
{
|
|
83593
|
+
method: "POST",
|
|
83594
|
+
path: "/terminal/ticket",
|
|
83595
|
+
summary: "Issue a terminal WebSocket connection ticket.",
|
|
83596
|
+
category: "Terminal",
|
|
83597
|
+
gate: "terminal-origin"
|
|
83598
|
+
},
|
|
83599
|
+
{
|
|
83600
|
+
method: "POST",
|
|
83601
|
+
path: "/terminal/folders/list",
|
|
83602
|
+
summary: "List terminal folder selection entries.",
|
|
83603
|
+
category: "Terminal",
|
|
83604
|
+
gate: "terminal-origin"
|
|
83605
|
+
},
|
|
83606
|
+
{
|
|
83607
|
+
method: "POST",
|
|
83608
|
+
path: "/terminal/folders/grants",
|
|
83609
|
+
summary: "Issue a terminal folder access grant.",
|
|
83610
|
+
category: "Terminal",
|
|
83611
|
+
gate: "terminal-origin"
|
|
83612
|
+
},
|
|
83613
|
+
{
|
|
83614
|
+
method: "GET",
|
|
83615
|
+
path: "/terminal/sessions",
|
|
83616
|
+
summary: "List terminal Operations.",
|
|
83617
|
+
category: "Terminal",
|
|
83618
|
+
gate: "terminal-origin"
|
|
83619
|
+
},
|
|
83620
|
+
{
|
|
83621
|
+
method: "POST",
|
|
83622
|
+
path: "/terminal/sessions",
|
|
83623
|
+
summary: "Create a new terminal Operation.",
|
|
83624
|
+
category: "Terminal",
|
|
83625
|
+
gate: "terminal-origin"
|
|
83626
|
+
},
|
|
83627
|
+
{
|
|
83628
|
+
method: "POST",
|
|
83629
|
+
path: "/terminal/sessions/:sessionId/resume",
|
|
83630
|
+
summary: "Resume a dormant Operation.",
|
|
83631
|
+
category: "Terminal",
|
|
83632
|
+
gate: "terminal-origin"
|
|
83633
|
+
},
|
|
83634
|
+
{
|
|
83635
|
+
method: "POST",
|
|
83636
|
+
path: "/terminal/sessions/:sessionId/turn",
|
|
83637
|
+
summary: "Receive an Agent CLI turn state hook.",
|
|
83638
|
+
category: "Terminal",
|
|
83639
|
+
gate: "lock-token"
|
|
83640
|
+
},
|
|
83641
|
+
{
|
|
83642
|
+
method: "POST",
|
|
83643
|
+
path: "/terminal/sessions/:sessionId/attention",
|
|
83644
|
+
summary: "Receive an input-waiting attention hook.",
|
|
83645
|
+
category: "Terminal",
|
|
83646
|
+
gate: "lock-token"
|
|
83647
|
+
},
|
|
83648
|
+
{
|
|
83649
|
+
method: "POST",
|
|
83650
|
+
path: "/terminal/sessions/:sessionId/auto-name",
|
|
83651
|
+
summary: "Receive an Operation auto-name hook.",
|
|
83652
|
+
category: "Terminal",
|
|
83653
|
+
gate: "lock-token"
|
|
83654
|
+
},
|
|
83655
|
+
{
|
|
83656
|
+
method: "DELETE",
|
|
83657
|
+
path: "/terminal/sessions/:sessionId",
|
|
83658
|
+
summary: "Remove a terminal Operation.",
|
|
83659
|
+
category: "Terminal",
|
|
83660
|
+
gate: "terminal-origin"
|
|
83661
|
+
},
|
|
83662
|
+
{
|
|
83663
|
+
method: "PATCH",
|
|
83664
|
+
path: "/terminal/sessions/:sessionId",
|
|
83665
|
+
summary: "Rename a terminal Operation.",
|
|
83666
|
+
category: "Terminal",
|
|
83667
|
+
gate: "terminal-origin"
|
|
83668
|
+
},
|
|
83669
|
+
{
|
|
83670
|
+
method: "POST",
|
|
83671
|
+
path: "/update/apply",
|
|
83672
|
+
summary: "Request console update application.",
|
|
83673
|
+
category: "Update",
|
|
83674
|
+
gate: "console-origin"
|
|
83675
|
+
},
|
|
83676
|
+
{
|
|
83677
|
+
method: "GET",
|
|
83678
|
+
path: "/health",
|
|
83679
|
+
summary: "Check console status with the lock token.",
|
|
83680
|
+
category: "Health",
|
|
83681
|
+
gate: "lock-token"
|
|
83682
|
+
}
|
|
83683
|
+
];
|
|
83414
83684
|
function createConsoleServer(deps = {}) {
|
|
83415
83685
|
const host = deps.host ?? DEFAULT_HOST22;
|
|
83416
83686
|
const port = deps.port ?? DEFAULT_PORT22;
|
|
@@ -83611,12 +83881,12 @@ function createConsoleServer(deps = {}) {
|
|
|
83611
83881
|
handleObserverStatus(req, res);
|
|
83612
83882
|
return;
|
|
83613
83883
|
}
|
|
83614
|
-
if (pathname === "/
|
|
83615
|
-
|
|
83884
|
+
if (pathname === "/observer/api-catalog") {
|
|
83885
|
+
handleObserverApiCatalog(req, res);
|
|
83616
83886
|
return;
|
|
83617
83887
|
}
|
|
83618
|
-
if (pathname === "/
|
|
83619
|
-
|
|
83888
|
+
if (pathname === "/update/apply") {
|
|
83889
|
+
runAsyncHandler(handleUpdateApply(req, res), res);
|
|
83620
83890
|
return;
|
|
83621
83891
|
}
|
|
83622
83892
|
if (pathname === "/carrier-settings" || pathname.startsWith("/carrier-settings/")) {
|
|
@@ -84062,6 +84332,9 @@ function createConsoleServer(deps = {}) {
|
|
|
84062
84332
|
};
|
|
84063
84333
|
writeJson(res, 200, payload);
|
|
84064
84334
|
}
|
|
84335
|
+
function handleObserverApiCatalog(_req, res) {
|
|
84336
|
+
writeJson(res, 200, { version: version22, routes: buildApiCatalog() });
|
|
84337
|
+
}
|
|
84065
84338
|
async function handleUpdateApply(req, res) {
|
|
84066
84339
|
if (req.method !== "POST") {
|
|
84067
84340
|
writeJson(res, 405, { error: "Method not allowed" });
|
|
@@ -84125,11 +84398,6 @@ function createConsoleServer(deps = {}) {
|
|
|
84125
84398
|
const payload = { status: "accepted" };
|
|
84126
84399
|
writeJson(res, 202, payload);
|
|
84127
84400
|
}
|
|
84128
|
-
function handleObserverCarriers(_req, res) {
|
|
84129
|
-
writeJson(res, 200, {
|
|
84130
|
-
carriers: readCarrierStatusEntries(carrierRegistry).map(toCarrierReadinessEntry)
|
|
84131
|
-
});
|
|
84132
|
-
}
|
|
84133
84401
|
function handleObserverWorkspaces(_req, res) {
|
|
84134
84402
|
writeJson(res, 200, { tenants: observability.listWorkspaces() });
|
|
84135
84403
|
}
|
|
@@ -84199,20 +84467,6 @@ function createConsoleServer(deps = {}) {
|
|
|
84199
84467
|
activeAdmiralCount: observability.listWorkspaces().filter((workspace) => workspace.theaterId === theater.id).length
|
|
84200
84468
|
};
|
|
84201
84469
|
}
|
|
84202
|
-
function toCarrierReadinessEntry(entry) {
|
|
84203
|
-
return {
|
|
84204
|
-
carrierId: entry.carrierId,
|
|
84205
|
-
displayName: entry.displayName,
|
|
84206
|
-
role: entry.role,
|
|
84207
|
-
model: entry.model,
|
|
84208
|
-
effort: entry.effort,
|
|
84209
|
-
taskForceBackendCount: entry.taskForceBackendCount,
|
|
84210
|
-
subagentMode: entry.subagentMode,
|
|
84211
|
-
...entry.category ? { category: entry.category } : {},
|
|
84212
|
-
slot: entry.slot,
|
|
84213
|
-
cliType: entry.cliType
|
|
84214
|
-
};
|
|
84215
|
-
}
|
|
84216
84470
|
function resolveWikiServerStatus(theaterId) {
|
|
84217
84471
|
if (!theaterId) return "unknown";
|
|
84218
84472
|
if (!theaters.get(theaterId)) return "unknown";
|
|
@@ -85902,7 +86156,7 @@ import { appendFile as appendFile2, mkdir as mkdir3, readFile as readFile22 } fr
|
|
|
85902
86156
|
import { mkdir as mkdir22 } from "fs/promises";
|
|
85903
86157
|
import path33 from "path";
|
|
85904
86158
|
import { mkdir as mkdir5, readdir as readdir3, readFile as readFile4, writeFile as writeFile3 } from "fs/promises";
|
|
85905
|
-
import
|
|
86159
|
+
import path25 from "path";
|
|
85906
86160
|
import path102 from "path";
|
|
85907
86161
|
import { mkdir as mkdir52 } from "fs/promises";
|
|
85908
86162
|
import path72 from "path";
|
|
@@ -86384,18 +86638,18 @@ Always read \`schema/wiki-schema.md\` directly before composing or revising entr
|
|
|
86384
86638
|
`;
|
|
86385
86639
|
async function ensureWorkspaceSchema2(paths) {
|
|
86386
86640
|
await mkdir5(paths.schemaDir, { recursive: true });
|
|
86387
|
-
await writeDefaultFileIfMissing2(
|
|
86388
|
-
await writeDefaultFileIfMissing2(
|
|
86641
|
+
await writeDefaultFileIfMissing2(path25.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME2), DEFAULT_WORKSPACE_SCHEMA_AGENTS2);
|
|
86642
|
+
await writeDefaultFileIfMissing2(path25.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME2), DEFAULT_WORKSPACE_WIKI_SCHEMA2);
|
|
86389
86643
|
await writeDefaultFileIfMissing2(buildTemplatePath2(paths, "prd"), DEFAULT_TEMPLATE_PRD2);
|
|
86390
86644
|
return readWorkspaceSchemaSummary2(paths);
|
|
86391
86645
|
}
|
|
86392
86646
|
async function ensureWorkspaceDoctrine2(paths) {
|
|
86393
86647
|
await mkdir5(paths.root, { recursive: true });
|
|
86394
|
-
await writeDefaultFileIfMissing2(
|
|
86648
|
+
await writeDefaultFileIfMissing2(path25.join(paths.root, WORKSPACE_KNOWLEDGE_AGENTS_FILENAME2), DEFAULT_WORKSPACE_KNOWLEDGE_AGENTS2);
|
|
86395
86649
|
}
|
|
86396
86650
|
async function readWorkspaceSchemaSummary2(paths) {
|
|
86397
|
-
const agentsPath =
|
|
86398
|
-
const wikiSchemaPath =
|
|
86651
|
+
const agentsPath = path25.join(paths.schemaDir, WORKSPACE_SCHEMA_AGENTS_FILENAME2);
|
|
86652
|
+
const wikiSchemaPath = path25.join(paths.schemaDir, WORKSPACE_SCHEMA_FILENAME2);
|
|
86399
86653
|
const wikiSchemaContent = await tryReadFile2(wikiSchemaPath);
|
|
86400
86654
|
const templates = await scanTemplates2(paths);
|
|
86401
86655
|
if (wikiSchemaContent === null) {
|
|
@@ -86434,7 +86688,7 @@ async function scanTemplates2(paths) {
|
|
|
86434
86688
|
if (!entry.name.startsWith(WORKSPACE_TEMPLATE_PREFIX2) || !entry.name.endsWith(WORKSPACE_TEMPLATE_SUFFIX2)) continue;
|
|
86435
86689
|
const id = entry.name.slice(WORKSPACE_TEMPLATE_PREFIX2.length, -WORKSPACE_TEMPLATE_SUFFIX2.length);
|
|
86436
86690
|
if (!id) continue;
|
|
86437
|
-
const filePath =
|
|
86691
|
+
const filePath = path25.join(paths.schemaDir, entry.name);
|
|
86438
86692
|
try {
|
|
86439
86693
|
const parsed = parseTemplateMarkdown2(await readFile4(filePath, "utf8"));
|
|
86440
86694
|
templates.push({
|
|
@@ -86468,7 +86722,7 @@ async function validateTemplateCompliance2(paths, templateId, body) {
|
|
|
86468
86722
|
}
|
|
86469
86723
|
}
|
|
86470
86724
|
function inferTemplateIdFromTarget2(target, knownTemplateIds) {
|
|
86471
|
-
const basename =
|
|
86725
|
+
const basename = path25.basename(target, ".md");
|
|
86472
86726
|
const ids = knownTemplateIds ?? DEFAULT_TEMPLATE_IDS2;
|
|
86473
86727
|
const sorted = [...ids].sort((a, b) => b.length - a.length);
|
|
86474
86728
|
for (const id of sorted) {
|
|
@@ -86497,7 +86751,7 @@ function extractSchemaSummary2(content) {
|
|
|
86497
86751
|
return lines.find((line) => line.length > 0 && !line.startsWith("#")) ?? "Workspace schema is present.";
|
|
86498
86752
|
}
|
|
86499
86753
|
function buildTemplatePath2(paths, id) {
|
|
86500
|
-
return
|
|
86754
|
+
return path25.join(paths.schemaDir, `${WORKSPACE_TEMPLATE_PREFIX2}${id}${WORKSPACE_TEMPLATE_SUFFIX2}`);
|
|
86501
86755
|
}
|
|
86502
86756
|
function parseTemplateMarkdown2(content) {
|
|
86503
86757
|
const normalized = content.replace(/\r\n/g, "\n");
|
|
@@ -92314,7 +92568,7 @@ function renderCarrierHudStrip(width, carriers, frame, theme) {
|
|
|
92314
92568
|
return [line];
|
|
92315
92569
|
}
|
|
92316
92570
|
function appendWidgetJobSummary(carrierRuntime, lines, width, jobs3, frame, theme, now) {
|
|
92317
|
-
const subagentModes = readCarrierAgentModeSnapshot(
|
|
92571
|
+
const subagentModes = readCarrierAgentModeSnapshot(buildCarrierDefaults(carrierRuntime)).agentModes;
|
|
92318
92572
|
const groups = buildCarrierJobGroups(
|
|
92319
92573
|
jobs3,
|
|
92320
92574
|
getRegisteredOrder(carrierRuntime.registry),
|
|
@@ -92365,7 +92619,7 @@ function appendTrackRows(carrierRuntime, lines, width, job, jobColor, frame, the
|
|
|
92365
92619
|
}
|
|
92366
92620
|
function buildCarrierTiles(carrierRuntime, activeJobs) {
|
|
92367
92621
|
const snapshot = readCarriersSnapshot();
|
|
92368
|
-
const subagentModes = readCarrierAgentModeSnapshot(
|
|
92622
|
+
const subagentModes = readCarrierAgentModeSnapshot(buildCarrierDefaults(carrierRuntime)).agentModes;
|
|
92369
92623
|
return getRegisteredOrder(carrierRuntime.registry).map((carrierId) => {
|
|
92370
92624
|
const activeCarrierJobs = activeJobs.filter((job) => job.ownerCarrierId === carrierId);
|
|
92371
92625
|
const taskForceBackendCount = getConfiguredTaskForceBackendsFromSnapshot(snapshot, carrierId).length;
|
|
@@ -92450,7 +92704,7 @@ function groupTrackModelEffortLabel(group) {
|
|
|
92450
92704
|
const track = carrierJobs[0]?.tracks[0];
|
|
92451
92705
|
return track ? trackModelEffortLabel(track) : "";
|
|
92452
92706
|
}
|
|
92453
|
-
function
|
|
92707
|
+
function buildCarrierDefaults(carrierRuntime) {
|
|
92454
92708
|
return Object.fromEntries(
|
|
92455
92709
|
getRegisteredOrder(carrierRuntime.registry).map((carrierId) => {
|
|
92456
92710
|
const config3 = getCarrierConfig(carrierRuntime.registry, carrierId);
|