@spencer-kit/coder-studio 0.3.9 → 0.3.11
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/CHANGELOG.md +12 -0
- package/dist/esm/bin.mjs +1157 -211
- package/dist/esm/bin.mjs.map +4 -4
- package/dist/esm/server-runner.mjs +1141 -195
- package/dist/esm/server-runner.mjs.map +4 -4
- package/dist/web/assets/index-3VcBsCCu.js +111 -0
- package/dist/web/assets/index-3VcBsCCu.js.map +1 -0
- package/dist/web/assets/index-BfhlsaFt.css +1 -0
- package/dist/web/index.html +2 -2
- package/package.json +1 -1
- package/dist/web/assets/index-BwryTUQ9.css +0 -1
- package/dist/web/assets/index-Z64V-v_U.js +0 -111
- package/dist/web/assets/index-Z64V-v_U.js.map +0 -1
|
@@ -996,7 +996,14 @@ var init_image = __esm({
|
|
|
996
996
|
|
|
997
997
|
// packages/server/src/fs/file-io.ts
|
|
998
998
|
import { createHash } from "crypto";
|
|
999
|
-
import {
|
|
999
|
+
import {
|
|
1000
|
+
readFile as fsReadFile,
|
|
1001
|
+
rename as fsRename,
|
|
1002
|
+
writeFile as fsWriteFile,
|
|
1003
|
+
mkdir,
|
|
1004
|
+
rm,
|
|
1005
|
+
stat
|
|
1006
|
+
} from "fs/promises";
|
|
1000
1007
|
import { dirname as dirname2, isAbsolute, relative, resolve as resolve2 } from "path";
|
|
1001
1008
|
async function statSafe(path10) {
|
|
1002
1009
|
try {
|
|
@@ -1030,6 +1037,27 @@ async function deleteEntry(rootPath, relPath) {
|
|
|
1030
1037
|
}
|
|
1031
1038
|
await rm(abs, { recursive: true });
|
|
1032
1039
|
}
|
|
1040
|
+
async function renameEntry(rootPath, fromPath, toPath) {
|
|
1041
|
+
const fromAbs = resolveSafe(rootPath, fromPath);
|
|
1042
|
+
const toAbs = resolveSafe(rootPath, toPath);
|
|
1043
|
+
const source = await statSafe(fromAbs);
|
|
1044
|
+
const target = await statSafe(toAbs);
|
|
1045
|
+
const fromParent = dirname2(fromAbs);
|
|
1046
|
+
const toParent = dirname2(toAbs);
|
|
1047
|
+
if (!source) {
|
|
1048
|
+
throw { code: "not_found", message: "Source not found" };
|
|
1049
|
+
}
|
|
1050
|
+
if (fromParent !== toParent) {
|
|
1051
|
+
throw {
|
|
1052
|
+
code: "rename_across_directories_not_supported",
|
|
1053
|
+
message: "Rename must stay within the current directory"
|
|
1054
|
+
};
|
|
1055
|
+
}
|
|
1056
|
+
if (target) {
|
|
1057
|
+
throw { code: "already_exists", message: "Target already exists" };
|
|
1058
|
+
}
|
|
1059
|
+
await fsRename(fromAbs, toAbs);
|
|
1060
|
+
}
|
|
1033
1061
|
function resolveSafe(root, relPath) {
|
|
1034
1062
|
const absRoot = resolve2(root);
|
|
1035
1063
|
const abs = resolve2(absRoot, relPath);
|
|
@@ -1043,7 +1071,7 @@ async function readFile(workspaceId, rootPath, relPath) {
|
|
|
1043
1071
|
const abs = resolveSafe(rootPath, relPath);
|
|
1044
1072
|
const imageType = getImageTypeInfo(relPath);
|
|
1045
1073
|
if (imageType) {
|
|
1046
|
-
const
|
|
1074
|
+
const bytes = await fsReadFile(abs);
|
|
1047
1075
|
const params = new URLSearchParams({
|
|
1048
1076
|
workspaceId,
|
|
1049
1077
|
path: relPath
|
|
@@ -1052,8 +1080,9 @@ async function readFile(workspaceId, rootPath, relPath) {
|
|
|
1052
1080
|
kind: "image",
|
|
1053
1081
|
mime: imageType.mime,
|
|
1054
1082
|
url: `/api/file?${params.toString()}`,
|
|
1055
|
-
size:
|
|
1056
|
-
isTextBacked: imageType.isTextBacked
|
|
1083
|
+
size: bytes.byteLength,
|
|
1084
|
+
isTextBacked: imageType.isTextBacked,
|
|
1085
|
+
version: createHash("sha256").update(bytes).digest("hex")
|
|
1057
1086
|
};
|
|
1058
1087
|
}
|
|
1059
1088
|
const content = await fsReadFile(abs, "utf-8");
|
|
@@ -2009,12 +2038,12 @@ var init_auto_fetch = __esm({
|
|
|
2009
2038
|
}
|
|
2010
2039
|
acquireWorkspaceOperation(workspaceId) {
|
|
2011
2040
|
const state = this.getOrCreateState(workspaceId);
|
|
2012
|
-
return new Promise((
|
|
2041
|
+
return new Promise((resolve5) => {
|
|
2013
2042
|
const grant = () => {
|
|
2014
2043
|
state.inFlight = true;
|
|
2015
2044
|
state.nextFetchAt = void 0;
|
|
2016
2045
|
let released = false;
|
|
2017
|
-
|
|
2046
|
+
resolve5(() => {
|
|
2018
2047
|
if (released) {
|
|
2019
2048
|
return;
|
|
2020
2049
|
}
|
|
@@ -2042,7 +2071,7 @@ var init_auto_fetch = __esm({
|
|
|
2042
2071
|
// packages/server/src/provider-runtime/command-runner.ts
|
|
2043
2072
|
import { spawn } from "node:child_process";
|
|
2044
2073
|
async function runCommandAsString(file, args, options) {
|
|
2045
|
-
return new Promise((
|
|
2074
|
+
return new Promise((resolve5, reject) => {
|
|
2046
2075
|
const child = spawn(file, args, {
|
|
2047
2076
|
shell: shouldUseShellForCommand(file, process.platform),
|
|
2048
2077
|
windowsHide: options?.windowsHide ?? true
|
|
@@ -2067,7 +2096,7 @@ async function runCommandAsString(file, args, options) {
|
|
|
2067
2096
|
const stdout = Buffer.concat(stdoutChunks).toString("utf8");
|
|
2068
2097
|
const stderr = Buffer.concat(stderrChunks).toString("utf8");
|
|
2069
2098
|
if (code === 0) {
|
|
2070
|
-
|
|
2099
|
+
resolve5({ stdout, stderr });
|
|
2071
2100
|
return;
|
|
2072
2101
|
}
|
|
2073
2102
|
reject(
|
|
@@ -2676,6 +2705,13 @@ ${details.stdout}`.toLowerCase();
|
|
|
2676
2705
|
}
|
|
2677
2706
|
});
|
|
2678
2707
|
|
|
2708
|
+
// packages/core/src/domain/diagnostics.ts
|
|
2709
|
+
var init_diagnostics = __esm({
|
|
2710
|
+
"packages/core/src/domain/diagnostics.ts"() {
|
|
2711
|
+
"use strict";
|
|
2712
|
+
}
|
|
2713
|
+
});
|
|
2714
|
+
|
|
2679
2715
|
// packages/core/src/domain/events.ts
|
|
2680
2716
|
var init_events = __esm({
|
|
2681
2717
|
"packages/core/src/domain/events.ts"() {
|
|
@@ -2926,6 +2962,7 @@ var init_idle_heuristics2 = __esm({
|
|
|
2926
2962
|
var init_src3 = __esm({
|
|
2927
2963
|
"packages/core/src/index.ts"() {
|
|
2928
2964
|
"use strict";
|
|
2965
|
+
init_diagnostics();
|
|
2929
2966
|
init_events();
|
|
2930
2967
|
init_mcp();
|
|
2931
2968
|
init_provider_install();
|
|
@@ -5009,13 +5046,13 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
|
|
|
5009
5046
|
return;
|
|
5010
5047
|
}
|
|
5011
5048
|
const arch = deps.arch ?? process.arch;
|
|
5012
|
-
const
|
|
5049
|
+
const resolve5 = deps.resolve ?? ((id) => require2.resolve(id));
|
|
5013
5050
|
const fileExists = deps.existsSync ?? existsSync4;
|
|
5014
|
-
const
|
|
5051
|
+
const stat8 = deps.statSync ?? statSync;
|
|
5015
5052
|
const chmod = deps.chmodSync ?? chmodSync2;
|
|
5016
5053
|
let packageJsonPath;
|
|
5017
5054
|
try {
|
|
5018
|
-
packageJsonPath =
|
|
5055
|
+
packageJsonPath = resolve5(NODE_PTY_PKG);
|
|
5019
5056
|
} catch {
|
|
5020
5057
|
return;
|
|
5021
5058
|
}
|
|
@@ -5029,7 +5066,7 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
|
|
|
5029
5066
|
if (!fileExists(helperPath)) {
|
|
5030
5067
|
return;
|
|
5031
5068
|
}
|
|
5032
|
-
const currentMode =
|
|
5069
|
+
const currentMode = stat8(helperPath).mode;
|
|
5033
5070
|
const executableMode = currentMode | 73;
|
|
5034
5071
|
if (executableMode === currentMode) {
|
|
5035
5072
|
return;
|
|
@@ -5080,7 +5117,7 @@ async function escalateKillWithPolling(pid, signal, options) {
|
|
|
5080
5117
|
const startTime = Date.now();
|
|
5081
5118
|
const deadline = startTime + timeoutMs;
|
|
5082
5119
|
while (Date.now() < deadline) {
|
|
5083
|
-
await new Promise((
|
|
5120
|
+
await new Promise((resolve5) => setTimeout(resolve5, pollIntervalMs));
|
|
5084
5121
|
if (!isProcessAlive(pid)) {
|
|
5085
5122
|
return true;
|
|
5086
5123
|
}
|
|
@@ -5232,38 +5269,107 @@ var init_settings = __esm({
|
|
|
5232
5269
|
|
|
5233
5270
|
// packages/server/src/supervisor/evaluator.ts
|
|
5234
5271
|
import { spawn as spawn2 } from "node:child_process";
|
|
5235
|
-
function buildPrompt(context) {
|
|
5272
|
+
function buildPrompt(context, mode) {
|
|
5273
|
+
if (mode === "decompose") {
|
|
5274
|
+
return [
|
|
5275
|
+
"You are an autonomous supervisor for a target-scoped software task.",
|
|
5276
|
+
"Your first job is to decompose the target into a supervision structure before evaluation begins.",
|
|
5277
|
+
"",
|
|
5278
|
+
"Return JSON only.",
|
|
5279
|
+
"No prose before or after the JSON.",
|
|
5280
|
+
"",
|
|
5281
|
+
"Decomposition policy:",
|
|
5282
|
+
"- Do not ask the user any questions.",
|
|
5283
|
+
"- Do not ask for clarification, confirmation, or approval.",
|
|
5284
|
+
"- Do not propose options for the user to choose from.",
|
|
5285
|
+
"- If information is incomplete, make the most conservative reasonable assumptions and decide the decomposition yourself.",
|
|
5286
|
+
"- Your job is to return the best useful decomposition now, not to begin a discussion or planning workflow.",
|
|
5287
|
+
"- Keep the user-visible target as the top-level supervision owner.",
|
|
5288
|
+
'- Choose "stage" by default.',
|
|
5289
|
+
'- Choose "subtarget" only when the work clearly breaks into independently deliverable and independently verifiable workstreams.',
|
|
5290
|
+
"- If the distinction is unclear, choose stage.",
|
|
5291
|
+
"- Produce 1 to 7 decomposition items.",
|
|
5292
|
+
"- Each item must be concrete, milestone-sized, and useful for subsequent evaluation.",
|
|
5293
|
+
"- Do not leave the structure empty.",
|
|
5294
|
+
"",
|
|
5295
|
+
"Item requirements:",
|
|
5296
|
+
'- Each item must include "id", "kind", "title", "objective", "deliverable", "acceptanceCriteria", and "status".',
|
|
5297
|
+
'- "kind" must match the selected decompositionMode: all "stage" or all "subtarget".',
|
|
5298
|
+
'- "acceptanceCriteria" must be a non-empty string array.',
|
|
5299
|
+
'- Use statuses "pending", "in_progress", or "done".',
|
|
5300
|
+
"- Usually mark the first active item as in_progress and the rest as pending.",
|
|
5301
|
+
"",
|
|
5302
|
+
"Output schema:",
|
|
5303
|
+
"{",
|
|
5304
|
+
' "mode": "decompose",',
|
|
5305
|
+
' "decompositionMode": "stage" | "subtarget",',
|
|
5306
|
+
' "items": [',
|
|
5307
|
+
' { "id": string, "kind": "stage" | "subtarget", "title": string, "objective": string, "deliverable": string, "acceptanceCriteria": string[], "status": "pending" | "in_progress" | "done" }',
|
|
5308
|
+
" ],",
|
|
5309
|
+
' "activeItemId": optional string,',
|
|
5310
|
+
' "progressSummary": optional brief summary',
|
|
5311
|
+
"}",
|
|
5312
|
+
"",
|
|
5313
|
+
"Current objective:",
|
|
5314
|
+
context.objective,
|
|
5315
|
+
"",
|
|
5316
|
+
"Current target memory:",
|
|
5317
|
+
JSON.stringify(context.targetMemory, null, 2),
|
|
5318
|
+
"",
|
|
5319
|
+
"Latest user input:",
|
|
5320
|
+
context.latestUserInput?.trim() || "(none)",
|
|
5321
|
+
"",
|
|
5322
|
+
"Current terminal snapshot:",
|
|
5323
|
+
context.terminalExcerpt || "(no output yet)"
|
|
5324
|
+
].join("\n");
|
|
5325
|
+
}
|
|
5236
5326
|
const lines = [
|
|
5237
5327
|
"You are an autonomous supervisor for a target-scoped software task.",
|
|
5238
5328
|
"Your job is to keep the agent moving toward the objective until the objective is complete.",
|
|
5239
5329
|
"",
|
|
5240
5330
|
"Return JSON only.",
|
|
5331
|
+
"No prose before or after the JSON.",
|
|
5241
5332
|
"",
|
|
5242
5333
|
"Decision policy:",
|
|
5243
|
-
'- Prefer "continue" whenever there is a
|
|
5334
|
+
'- Prefer "continue" over "stop" whenever the objective is not yet verified complete and there is a concrete next action.',
|
|
5335
|
+
'- "continue" may mean continuing the current item, verifying the current item, unblocking the current item, or advancing to the next item only after the current item is verified done.',
|
|
5244
5336
|
"- Do not ask the user to decide, clarify, or choose among implementation options.",
|
|
5337
|
+
"- Do not tell the agent to ask the user to decide, clarify, or choose among implementation options unless continuing would likely be unsafe or clearly unsupported.",
|
|
5338
|
+
"- If the agent asks a question or presents multiple options, choose the most conservative reasonable option yourself and direct the next action.",
|
|
5339
|
+
"- If multiple reasonable paths exist, pick one and move forward unless doing so would be unsafe or clearly unsupported.",
|
|
5245
5340
|
"- When information is incomplete, choose a conservative next action based on the objective, target memory, latest user input, and terminal snapshot.",
|
|
5341
|
+
"- Do not treat the agent's claims, summaries, or self-reports as sufficient evidence of completion.",
|
|
5246
5342
|
"- Stop only when the objective is complete, or when continuing would likely push the agent in an unsafe or clearly unsupported direction.",
|
|
5247
5343
|
"",
|
|
5248
5344
|
"Stage decision policy:",
|
|
5249
5345
|
"- Use the target memory as the current supervision state.",
|
|
5250
|
-
"- Base your decision on the objective, current
|
|
5251
|
-
"- Identify which
|
|
5252
|
-
"-
|
|
5253
|
-
"-
|
|
5254
|
-
|
|
5346
|
+
"- Base your decision on the objective, current decompositionMode, items, activeItemId, progressSummary, lastGuidance, stalledCount, latest user input, and terminal snapshot.",
|
|
5347
|
+
"- Identify which decomposition item is currently active.",
|
|
5348
|
+
"- Keep the current active item unless there is evidence that it is done, blocked, or obsolete.",
|
|
5349
|
+
"- Decide whether the active item is done, still in progress, blocked, or obsolete based on observable evidence.",
|
|
5350
|
+
'- Treat statements like "done", "fixed", "implemented", or "should pass" as unverified unless supported by observable evidence.',
|
|
5351
|
+
'- Mark an item as "done" only when there is observable evidence that its deliverable or acceptanceCriteria were satisfied.',
|
|
5352
|
+
"- Prefer evidence from terminal output, test results, build results, explicit verification output, or other observable artifacts in the terminal snapshot.",
|
|
5353
|
+
"- If evidence is missing or ambiguous, keep the item in_progress and direct the agent to gather or produce the missing verification evidence.",
|
|
5354
|
+
"- If the current item appears nearly complete but is not yet verified, keep the same active item and direct targeted verification.",
|
|
5355
|
+
"- Advance to the next item only after the current item's deliverable or acceptanceCriteria are supported by observable evidence.",
|
|
5356
|
+
'- When advancing to the next item, mark the previous item as "done" and set activeItemId to the next item explicitly.',
|
|
5357
|
+
"- If the active item is blocked, give guidance that is most likely to unblock it.",
|
|
5358
|
+
"- If the active item is obsolete, explain the reason briefly and move to the next useful item.",
|
|
5255
5359
|
"- If the agent appears stuck or repeated the same action, give a different concrete next action.",
|
|
5256
|
-
"-
|
|
5360
|
+
"- Do not rewrite the decomposition structure during normal evaluation cycles.",
|
|
5257
5361
|
"",
|
|
5258
5362
|
"Allowed statuses:",
|
|
5259
|
-
'- "continue":
|
|
5363
|
+
'- "continue": supervision should continue; include "reason" and "guidance".',
|
|
5260
5364
|
'- "stop": supervision should stop; include "stopReason" and "reason".',
|
|
5261
5365
|
"",
|
|
5262
5366
|
"Allowed stop reasons:",
|
|
5263
5367
|
'- "objective_complete"',
|
|
5264
5368
|
'- "supervisor_uncertain"',
|
|
5265
5369
|
"",
|
|
5266
|
-
'Use "objective_complete" only when the objective
|
|
5370
|
+
'Use "objective_complete" only when there is evidence that the objective and relevant acceptanceCriteria have been satisfied.',
|
|
5371
|
+
"- Do not stop only because the agent says the work is complete or because code changes exist without verification evidence.",
|
|
5372
|
+
"- If completion looks plausible but remains unverified, continue and require targeted verification.",
|
|
5267
5373
|
'Use "supervisor_uncertain" only as a last resort when no useful next action can be inferred and additional guidance would likely be misleading.',
|
|
5268
5374
|
"",
|
|
5269
5375
|
'Guidance requirements for "continue":',
|
|
@@ -5271,30 +5377,32 @@ function buildPrompt(context) {
|
|
|
5271
5377
|
"- Focus on the highest-value step toward completing the objective.",
|
|
5272
5378
|
"- Be specific enough for the supervised agent to act without asking the user.",
|
|
5273
5379
|
"- Avoid generic reminders, encouragement, or restating the objective.",
|
|
5274
|
-
"- If verification is needed, tell the agent exactly what to verify next.",
|
|
5380
|
+
"- If verification is needed, tell the agent exactly what command, file, behavior, or artifact to verify next.",
|
|
5275
5381
|
"- If implementation is needed, point to the likely area, behavior, or file/module based on available evidence.",
|
|
5382
|
+
"- If the agent asked a question, answer it directly in the guidance and continue with a concrete next action.",
|
|
5276
5383
|
"",
|
|
5277
|
-
"
|
|
5278
|
-
"-
|
|
5279
|
-
"-
|
|
5280
|
-
"-
|
|
5281
|
-
"-
|
|
5282
|
-
"-
|
|
5384
|
+
"Evaluation policy:",
|
|
5385
|
+
"- Update progress incrementally against the existing decomposition.",
|
|
5386
|
+
"- Use itemUpdates to reflect evidence-backed status changes only.",
|
|
5387
|
+
"- Keep activeItemId on the current item by default.",
|
|
5388
|
+
"- Change activeItemId only when there is a clear reason to switch items.",
|
|
5389
|
+
"- If evidence is missing or ambiguous, prefer verification over further implementation.",
|
|
5283
5390
|
"",
|
|
5284
5391
|
"Output schema:",
|
|
5285
5392
|
"For continue:",
|
|
5286
5393
|
"{",
|
|
5394
|
+
' "mode": "evaluate",',
|
|
5287
5395
|
' "status": "continue",',
|
|
5288
5396
|
' "reason": "brief explanation of why more work is needed",',
|
|
5289
5397
|
' "guidance": "specific next action for the supervised agent",',
|
|
5290
|
-
' "
|
|
5291
|
-
' "activeStepId": optional step id,',
|
|
5398
|
+
' "activeItemId": optional item id,',
|
|
5292
5399
|
' "progressSummary": optional brief progress summary,',
|
|
5293
|
-
' "
|
|
5400
|
+
' "itemUpdates": optional array of { "id": string, "status": "pending" | "in_progress" | "done" }',
|
|
5294
5401
|
"}",
|
|
5295
5402
|
"",
|
|
5296
5403
|
"For stop:",
|
|
5297
5404
|
"{",
|
|
5405
|
+
' "mode": "evaluate",',
|
|
5298
5406
|
' "status": "stop",',
|
|
5299
5407
|
' "stopReason": "objective_complete" | "supervisor_uncertain",',
|
|
5300
5408
|
' "reason": "brief explanation"',
|
|
@@ -5318,7 +5426,7 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
5318
5426
|
if (options.signal?.aborted) {
|
|
5319
5427
|
throw createSupervisorEvalAbortedError();
|
|
5320
5428
|
}
|
|
5321
|
-
return await new Promise((
|
|
5429
|
+
return await new Promise((resolve5, reject) => {
|
|
5322
5430
|
const child = spawn2(command.argv[0], command.argv.slice(1), {
|
|
5323
5431
|
cwd: command.cwd,
|
|
5324
5432
|
detached: process.platform !== "win32",
|
|
@@ -5348,7 +5456,7 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
5348
5456
|
}
|
|
5349
5457
|
settled = true;
|
|
5350
5458
|
cleanup();
|
|
5351
|
-
|
|
5459
|
+
resolve5(value);
|
|
5352
5460
|
};
|
|
5353
5461
|
const terminate = (error) => {
|
|
5354
5462
|
if (terminationError) {
|
|
@@ -5379,7 +5487,10 @@ async function runCommand(command, timeoutMs, options = {}) {
|
|
|
5379
5487
|
settleReject(terminationError);
|
|
5380
5488
|
return;
|
|
5381
5489
|
}
|
|
5382
|
-
settleReject(
|
|
5490
|
+
settleReject({
|
|
5491
|
+
code: "supervisor_eval_failed",
|
|
5492
|
+
message: error instanceof Error ? error.message : "Evaluator process failed to start"
|
|
5493
|
+
});
|
|
5383
5494
|
});
|
|
5384
5495
|
child.on("exit", (code) => {
|
|
5385
5496
|
if (terminationError) {
|
|
@@ -5557,7 +5668,7 @@ function extractSupervisorPayload(output, providerId) {
|
|
|
5557
5668
|
}
|
|
5558
5669
|
throw new Error("Supervisor did not return a recognizable message");
|
|
5559
5670
|
}
|
|
5560
|
-
function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
|
|
5671
|
+
function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars, requestedMode) {
|
|
5561
5672
|
let parsed;
|
|
5562
5673
|
try {
|
|
5563
5674
|
parsed = JSON.parse(stripCodeFence(payloadText));
|
|
@@ -5570,9 +5681,49 @@ function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
|
|
|
5570
5681
|
throw new Error("Supervisor returned invalid evaluation payload");
|
|
5571
5682
|
}
|
|
5572
5683
|
const record = parsed;
|
|
5684
|
+
const payloadMode = record.mode;
|
|
5685
|
+
if (requestedMode === "decompose") {
|
|
5686
|
+
if (payloadMode !== "decompose") {
|
|
5687
|
+
throw new Error("Supervisor returned invalid decompose payload");
|
|
5688
|
+
}
|
|
5689
|
+
const decompositionMode = record.decompositionMode;
|
|
5690
|
+
if (decompositionMode !== "stage" && decompositionMode !== "subtarget") {
|
|
5691
|
+
throw new Error("Supervisor decompose result is missing a valid decompositionMode");
|
|
5692
|
+
}
|
|
5693
|
+
const items = Array.isArray(record.items) ? record.items.flatMap((value) => {
|
|
5694
|
+
if (!value || typeof value !== "object") {
|
|
5695
|
+
return [];
|
|
5696
|
+
}
|
|
5697
|
+
const item = value;
|
|
5698
|
+
if (typeof item.id !== "string" || item.kind !== "stage" && item.kind !== "subtarget" || item.kind !== decompositionMode || typeof item.title !== "string" || typeof item.objective !== "string" || typeof item.deliverable !== "string" || !Array.isArray(item.acceptanceCriteria) || item.acceptanceCriteria.length === 0 || item.acceptanceCriteria.some((entry) => typeof entry !== "string") || item.status !== "pending" && item.status !== "in_progress" && item.status !== "done") {
|
|
5699
|
+
return [];
|
|
5700
|
+
}
|
|
5701
|
+
return [
|
|
5702
|
+
{
|
|
5703
|
+
id: item.id,
|
|
5704
|
+
kind: item.kind,
|
|
5705
|
+
title: item.title,
|
|
5706
|
+
objective: item.objective,
|
|
5707
|
+
deliverable: item.deliverable,
|
|
5708
|
+
acceptanceCriteria: item.acceptanceCriteria,
|
|
5709
|
+
status: item.status
|
|
5710
|
+
}
|
|
5711
|
+
];
|
|
5712
|
+
}) : [];
|
|
5713
|
+
if (items.length === 0) {
|
|
5714
|
+
throw new Error("Supervisor decompose result must include at least one valid item");
|
|
5715
|
+
}
|
|
5716
|
+
return {
|
|
5717
|
+
mode: "decompose",
|
|
5718
|
+
decompositionMode,
|
|
5719
|
+
items,
|
|
5720
|
+
activeItemId: typeof record.activeItemId === "string" && record.activeItemId.trim() ? record.activeItemId : void 0,
|
|
5721
|
+
progressSummary: typeof record.progressSummary === "string" && record.progressSummary.trim() ? record.progressSummary.trim() : void 0
|
|
5722
|
+
};
|
|
5723
|
+
}
|
|
5573
5724
|
const status = record.status;
|
|
5574
5725
|
const reason = record.reason;
|
|
5575
|
-
if (status !== "continue" && status !== "stop" || typeof reason !== "string" || !reason.trim()) {
|
|
5726
|
+
if (payloadMode !== void 0 && payloadMode !== "evaluate" || status !== "continue" && status !== "stop" || typeof reason !== "string" || !reason.trim()) {
|
|
5576
5727
|
throw new Error("Supervisor returned invalid evaluation payload");
|
|
5577
5728
|
}
|
|
5578
5729
|
if (status === "stop") {
|
|
@@ -5581,23 +5732,14 @@ function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
|
|
|
5581
5732
|
throw new Error("Supervisor stop result is missing a valid stopReason");
|
|
5582
5733
|
}
|
|
5583
5734
|
return {
|
|
5735
|
+
mode: "evaluate",
|
|
5584
5736
|
status,
|
|
5585
5737
|
stopReason,
|
|
5586
5738
|
reason: reason.trim()
|
|
5587
5739
|
};
|
|
5588
5740
|
}
|
|
5589
5741
|
const guidance = typeof record.guidance === "string" && record.guidance.trim() ? record.guidance.trim().slice(0, guidanceMaxChars) : void 0;
|
|
5590
|
-
const
|
|
5591
|
-
if (!value || typeof value !== "object") {
|
|
5592
|
-
return [];
|
|
5593
|
-
}
|
|
5594
|
-
const step = value;
|
|
5595
|
-
if (typeof step.id !== "string" || typeof step.title !== "string" || step.status !== "pending" && step.status !== "in_progress" && step.status !== "done") {
|
|
5596
|
-
return [];
|
|
5597
|
-
}
|
|
5598
|
-
return [{ id: step.id, title: step.title, status: step.status }];
|
|
5599
|
-
}) : void 0;
|
|
5600
|
-
const stepUpdates = Array.isArray(record.stepUpdates) ? record.stepUpdates.flatMap((value) => {
|
|
5742
|
+
const itemUpdates = Array.isArray(record.itemUpdates) ? record.itemUpdates.flatMap((value) => {
|
|
5601
5743
|
if (!value || typeof value !== "object") {
|
|
5602
5744
|
return [];
|
|
5603
5745
|
}
|
|
@@ -5608,13 +5750,13 @@ function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
|
|
|
5608
5750
|
return [{ id: update.id, status: update.status }];
|
|
5609
5751
|
}) : void 0;
|
|
5610
5752
|
return {
|
|
5753
|
+
mode: "evaluate",
|
|
5611
5754
|
status,
|
|
5612
5755
|
reason: reason.trim(),
|
|
5613
5756
|
guidance,
|
|
5614
|
-
|
|
5615
|
-
activeStepId: typeof record.activeStepId === "string" && record.activeStepId.trim() ? record.activeStepId : void 0,
|
|
5757
|
+
activeItemId: typeof record.activeItemId === "string" && record.activeItemId.trim() ? record.activeItemId : void 0,
|
|
5616
5758
|
progressSummary: typeof record.progressSummary === "string" && record.progressSummary.trim() ? record.progressSummary.trim() : void 0,
|
|
5617
|
-
|
|
5759
|
+
itemUpdates
|
|
5618
5760
|
};
|
|
5619
5761
|
}
|
|
5620
5762
|
var NOOP_LOGGER2, SupervisorEvaluator;
|
|
@@ -5666,7 +5808,8 @@ var init_evaluator = __esm({
|
|
|
5666
5808
|
provider,
|
|
5667
5809
|
this.deps.providerConfigRepo.get(provider.id)
|
|
5668
5810
|
);
|
|
5669
|
-
const
|
|
5811
|
+
const mode = options.mode ?? "evaluate";
|
|
5812
|
+
const prompt = buildPrompt(context, mode);
|
|
5670
5813
|
const command = provider.buildSupervisorEvalCommand(config, {
|
|
5671
5814
|
prompt,
|
|
5672
5815
|
sessionId: supervisor.sessionId,
|
|
@@ -5700,7 +5843,7 @@ var init_evaluator = __esm({
|
|
|
5700
5843
|
);
|
|
5701
5844
|
throw error;
|
|
5702
5845
|
}
|
|
5703
|
-
return parseSupervisorEvaluationResult(payloadText, this.config.guidanceMaxChars);
|
|
5846
|
+
return parseSupervisorEvaluationResult(payloadText, this.config.guidanceMaxChars, mode);
|
|
5704
5847
|
}
|
|
5705
5848
|
};
|
|
5706
5849
|
}
|
|
@@ -5871,12 +6014,12 @@ var init_scheduler = __esm({
|
|
|
5871
6014
|
|
|
5872
6015
|
// packages/server/src/supervisor/manager.ts
|
|
5873
6016
|
function createDeferredCompletion() {
|
|
5874
|
-
let
|
|
6017
|
+
let resolve5 = () => {
|
|
5875
6018
|
};
|
|
5876
6019
|
const promise = new Promise((innerResolve) => {
|
|
5877
|
-
|
|
6020
|
+
resolve5 = innerResolve;
|
|
5878
6021
|
});
|
|
5879
|
-
return { promise, resolve:
|
|
6022
|
+
return { promise, resolve: resolve5 };
|
|
5880
6023
|
}
|
|
5881
6024
|
function generateSupervisorId() {
|
|
5882
6025
|
return `sup_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
|
|
@@ -5902,6 +6045,12 @@ function messageOf(error, fallback) {
|
|
|
5902
6045
|
function logFailure(logger, error, context, message) {
|
|
5903
6046
|
logger.error({ ...context, err: error }, message);
|
|
5904
6047
|
}
|
|
6048
|
+
function isDecomposeResult(result) {
|
|
6049
|
+
return result.mode === "decompose";
|
|
6050
|
+
}
|
|
6051
|
+
function isEvaluateStopResult(result) {
|
|
6052
|
+
return "status" in result && result.status === "stop";
|
|
6053
|
+
}
|
|
5905
6054
|
function isSupervisorEvalAborted(error) {
|
|
5906
6055
|
return !!error && typeof error === "object" && error.code === "supervisor_eval_aborted";
|
|
5907
6056
|
}
|
|
@@ -6405,7 +6554,12 @@ var init_manager2 = __esm({
|
|
|
6405
6554
|
turnId: context.lastTurnId,
|
|
6406
6555
|
createdAt: Date.now()
|
|
6407
6556
|
});
|
|
6408
|
-
this.broadcastCycle(evaluatingSupervisor, activeCycle, "created"
|
|
6557
|
+
this.broadcastCycle(evaluatingSupervisor, activeCycle, "created", {
|
|
6558
|
+
phase: "waiting_evaluator",
|
|
6559
|
+
currentAttemptIndex: 0,
|
|
6560
|
+
attemptCount: 1,
|
|
6561
|
+
maxAttempts: 1 + retrySettings.retryMaxCount
|
|
6562
|
+
});
|
|
6409
6563
|
return {
|
|
6410
6564
|
cycle: activeCycle,
|
|
6411
6565
|
supervisor: hydratedSupervisor,
|
|
@@ -6603,6 +6757,8 @@ var init_manager2 = __esm({
|
|
|
6603
6757
|
}
|
|
6604
6758
|
async executeCycleWithRetry(started, signal) {
|
|
6605
6759
|
const supervisor = started.supervisor;
|
|
6760
|
+
let context = started.context;
|
|
6761
|
+
let currentMemory = context.targetMemory;
|
|
6606
6762
|
for (let attemptIndex = 0; ; attemptIndex += 1) {
|
|
6607
6763
|
const attempt = this.deps.cycleAttemptRepo.create({
|
|
6608
6764
|
id: generateAttemptId(),
|
|
@@ -6611,23 +6767,79 @@ var init_manager2 = __esm({
|
|
|
6611
6767
|
status: "evaluating",
|
|
6612
6768
|
startedAt: Date.now()
|
|
6613
6769
|
});
|
|
6770
|
+
this.broadcastCycle(started.supervisor, started.cycle, "updated", {
|
|
6771
|
+
phase: "waiting_evaluator",
|
|
6772
|
+
currentAttemptIndex: attemptIndex,
|
|
6773
|
+
attemptCount: attemptIndex + 1,
|
|
6774
|
+
maxAttempts: 1 + started.retry.retryMaxCount
|
|
6775
|
+
});
|
|
6614
6776
|
try {
|
|
6615
|
-
|
|
6777
|
+
if (!currentMemory.decompositionGenerated || currentMemory.items.length === 0) {
|
|
6778
|
+
const decomposition = await this.evaluator.evaluate(supervisor, context, {
|
|
6779
|
+
signal,
|
|
6780
|
+
mode: "decompose"
|
|
6781
|
+
});
|
|
6782
|
+
if (!isDecomposeResult(decomposition)) {
|
|
6783
|
+
throw new Error("Supervisor decompose pass did not return a decomposition result");
|
|
6784
|
+
}
|
|
6785
|
+
currentMemory = {
|
|
6786
|
+
...currentMemory,
|
|
6787
|
+
decompositionGenerated: true,
|
|
6788
|
+
decompositionMode: decomposition.decompositionMode,
|
|
6789
|
+
items: decomposition.items,
|
|
6790
|
+
activeItemId: decomposition.activeItemId,
|
|
6791
|
+
progressSummary: decomposition.progressSummary ?? currentMemory.progressSummary,
|
|
6792
|
+
updatedAt: Date.now()
|
|
6793
|
+
};
|
|
6794
|
+
const workspace = this.requireWorkspace(context.workspaceId);
|
|
6795
|
+
await this.deps.targetStore.saveTargetMemory(
|
|
6796
|
+
workspace.path,
|
|
6797
|
+
started.targetId,
|
|
6798
|
+
currentMemory
|
|
6799
|
+
);
|
|
6800
|
+
const currentSupervisor2 = this.supervisors.get(supervisor.id) ?? this.requireSupervisor(supervisor.id);
|
|
6801
|
+
if (currentSupervisor2.targetId === started.targetId) {
|
|
6802
|
+
const refreshed = this.attachCycles({
|
|
6803
|
+
...currentSupervisor2,
|
|
6804
|
+
currentTargetMemory: currentMemory
|
|
6805
|
+
});
|
|
6806
|
+
this.storeSnapshot(refreshed);
|
|
6807
|
+
}
|
|
6808
|
+
context = {
|
|
6809
|
+
...context,
|
|
6810
|
+
targetMemory: currentMemory
|
|
6811
|
+
};
|
|
6812
|
+
}
|
|
6813
|
+
const evaluation = await this.evaluator.evaluate(supervisor, context, {
|
|
6814
|
+
signal,
|
|
6815
|
+
mode: "evaluate"
|
|
6816
|
+
});
|
|
6616
6817
|
this.deps.cycleAttemptRepo.update(attempt.id, {
|
|
6617
6818
|
status: "completed",
|
|
6618
6819
|
completedAt: Date.now(),
|
|
6619
6820
|
providerModel: supervisor.evaluatorModel ?? null
|
|
6620
6821
|
});
|
|
6621
|
-
if (evaluation
|
|
6822
|
+
if (isDecomposeResult(evaluation)) {
|
|
6823
|
+
throw new Error("Supervisor evaluate pass returned a decompose result");
|
|
6824
|
+
}
|
|
6825
|
+
const nextTargetMemory = this.applyEvaluationToTargetMemory(
|
|
6826
|
+
currentMemory,
|
|
6827
|
+
evaluation,
|
|
6828
|
+
void 0,
|
|
6829
|
+
Date.now()
|
|
6830
|
+
);
|
|
6831
|
+
if (isEvaluateStopResult(evaluation)) {
|
|
6622
6832
|
return {
|
|
6623
6833
|
evaluation,
|
|
6624
|
-
injected: false
|
|
6834
|
+
injected: false,
|
|
6835
|
+
targetMemory: nextTargetMemory
|
|
6625
6836
|
};
|
|
6626
6837
|
}
|
|
6627
6838
|
if (!evaluation.guidance?.trim()) {
|
|
6628
6839
|
return {
|
|
6629
6840
|
evaluation,
|
|
6630
|
-
injected: false
|
|
6841
|
+
injected: false,
|
|
6842
|
+
targetMemory: nextTargetMemory
|
|
6631
6843
|
};
|
|
6632
6844
|
}
|
|
6633
6845
|
if (signal?.aborted || this.pendingPauses.has(supervisor.id)) {
|
|
@@ -6637,7 +6849,8 @@ var init_manager2 = __esm({
|
|
|
6637
6849
|
if (currentSupervisor.targetId !== started.targetId) {
|
|
6638
6850
|
return {
|
|
6639
6851
|
evaluation,
|
|
6640
|
-
injected: false
|
|
6852
|
+
injected: false,
|
|
6853
|
+
targetMemory: nextTargetMemory
|
|
6641
6854
|
};
|
|
6642
6855
|
}
|
|
6643
6856
|
const injectingSupervisor = this.attachCycles(
|
|
@@ -6650,6 +6863,12 @@ var init_manager2 = __esm({
|
|
|
6650
6863
|
);
|
|
6651
6864
|
this.storeSnapshot(injectingSupervisor);
|
|
6652
6865
|
this.broadcastState(injectingSupervisor, "state_changed");
|
|
6866
|
+
this.broadcastCycle(injectingSupervisor, started.cycle, "updated", {
|
|
6867
|
+
phase: "injecting",
|
|
6868
|
+
currentAttemptIndex: attemptIndex,
|
|
6869
|
+
attemptCount: attemptIndex + 1,
|
|
6870
|
+
maxAttempts: 1 + started.retry.retryMaxCount
|
|
6871
|
+
});
|
|
6653
6872
|
const recentCycles = this.deps.cycleRepo.listRecentForSupervisor(supervisor.id, this.config.guidanceDedupeWindow + 1).filter((cycle) => cycle.id !== started.cycle.id);
|
|
6654
6873
|
const injection = await this.injector.inject(
|
|
6655
6874
|
injectingSupervisor,
|
|
@@ -6662,7 +6881,13 @@ var init_manager2 = __esm({
|
|
|
6662
6881
|
return {
|
|
6663
6882
|
evaluation,
|
|
6664
6883
|
injected: injection.injected,
|
|
6665
|
-
injectedText: injection.injected ? injection.text : void 0
|
|
6884
|
+
injectedText: injection.injected ? injection.text : void 0,
|
|
6885
|
+
targetMemory: this.applyEvaluationToTargetMemory(
|
|
6886
|
+
currentMemory,
|
|
6887
|
+
evaluation,
|
|
6888
|
+
injection.injected ? injection.text : void 0,
|
|
6889
|
+
Date.now()
|
|
6890
|
+
)
|
|
6666
6891
|
};
|
|
6667
6892
|
} catch (error) {
|
|
6668
6893
|
if (isSupervisorEvalAborted(error)) {
|
|
@@ -6683,6 +6908,15 @@ var init_manager2 = __esm({
|
|
|
6683
6908
|
if (!this.shouldRetryAttempt(error, attemptIndex, started.retry)) {
|
|
6684
6909
|
throw error;
|
|
6685
6910
|
}
|
|
6911
|
+
const nextRetryAt = Date.now() + started.retry.retryDelayMs;
|
|
6912
|
+
this.broadcastCycle(supervisor, started.cycle, "updated", {
|
|
6913
|
+
phase: "retry_wait",
|
|
6914
|
+
currentAttemptIndex: attemptIndex,
|
|
6915
|
+
attemptCount: attemptIndex + 1,
|
|
6916
|
+
maxAttempts: 1 + started.retry.retryMaxCount,
|
|
6917
|
+
lastAttemptError: reason,
|
|
6918
|
+
nextRetryAt
|
|
6919
|
+
});
|
|
6686
6920
|
await this.sleep(started.retry.retryDelayMs, signal);
|
|
6687
6921
|
const evaluatingSupervisor = this.attachCycles(
|
|
6688
6922
|
this.withCurrentTargetState(
|
|
@@ -6700,9 +6934,9 @@ var init_manager2 = __esm({
|
|
|
6700
6934
|
async finalizeSuccessfulCycle(activeCycle, context, result, targetId) {
|
|
6701
6935
|
const workspace = this.requireWorkspace(context.workspaceId);
|
|
6702
6936
|
const currentSupervisor = this.supervisors.get(activeCycle.supervisorId) ?? this.requireSupervisor(activeCycle.supervisorId);
|
|
6703
|
-
const
|
|
6937
|
+
const evaluation = result.evaluation;
|
|
6704
6938
|
const finalStatus = result.injected ? "injected" : "completed";
|
|
6705
|
-
const cycleReason =
|
|
6939
|
+
const cycleReason = isEvaluateStopResult(evaluation) ? evaluation.reason : result.injected ? result.injectedText : evaluation.guidance ? `Skipped duplicate: ${evaluation.guidance}` : void 0;
|
|
6706
6940
|
const finishedCycle = this.deps.cycleRepo.update(activeCycle.id, {
|
|
6707
6941
|
status: finalStatus,
|
|
6708
6942
|
result: cycleReason ?? null,
|
|
@@ -6710,24 +6944,22 @@ var init_manager2 = __esm({
|
|
|
6710
6944
|
errorReason: null,
|
|
6711
6945
|
completedAt: Date.now()
|
|
6712
6946
|
});
|
|
6713
|
-
const nextTargetMemory =
|
|
6714
|
-
targetMemory,
|
|
6715
|
-
|
|
6716
|
-
|
|
6717
|
-
finishedCycle.completedAt ?? Date.now()
|
|
6718
|
-
);
|
|
6947
|
+
const nextTargetMemory = {
|
|
6948
|
+
...result.targetMemory,
|
|
6949
|
+
updatedAt: finishedCycle.completedAt ?? Date.now()
|
|
6950
|
+
};
|
|
6719
6951
|
await this.deps.targetStore.saveTargetMemory(workspace.path, targetId, nextTargetMemory);
|
|
6720
|
-
const cycleRecord =
|
|
6952
|
+
const cycleRecord = isEvaluateStopResult(evaluation) ? {
|
|
6721
6953
|
cycleId: activeCycle.id,
|
|
6722
6954
|
targetId,
|
|
6723
6955
|
startedAt: activeCycle.createdAt,
|
|
6724
6956
|
completedAt: finishedCycle.completedAt ?? Date.now(),
|
|
6725
6957
|
result: "stop",
|
|
6726
|
-
stopReason:
|
|
6727
|
-
reason:
|
|
6728
|
-
progressSummary:
|
|
6729
|
-
|
|
6730
|
-
|
|
6958
|
+
stopReason: evaluation.stopReason,
|
|
6959
|
+
reason: evaluation.reason,
|
|
6960
|
+
progressSummary: nextTargetMemory.progressSummary,
|
|
6961
|
+
decompositionMode: nextTargetMemory.decompositionMode,
|
|
6962
|
+
activeItemId: nextTargetMemory.activeItemId,
|
|
6731
6963
|
injected: false,
|
|
6732
6964
|
attemptCount: this.deps.cycleAttemptRepo.listForCycle(activeCycle.id).length
|
|
6733
6965
|
} : {
|
|
@@ -6736,18 +6968,19 @@ var init_manager2 = __esm({
|
|
|
6736
6968
|
startedAt: activeCycle.createdAt,
|
|
6737
6969
|
completedAt: finishedCycle.completedAt ?? Date.now(),
|
|
6738
6970
|
result: "continue",
|
|
6739
|
-
reason:
|
|
6740
|
-
guidance: result.injected ? result.injectedText :
|
|
6971
|
+
reason: evaluation.reason,
|
|
6972
|
+
guidance: result.injected ? result.injectedText : evaluation.guidance,
|
|
6741
6973
|
progressSummary: nextTargetMemory.progressSummary,
|
|
6742
|
-
|
|
6743
|
-
|
|
6974
|
+
decompositionMode: nextTargetMemory.decompositionMode,
|
|
6975
|
+
activeItemId: nextTargetMemory.activeItemId,
|
|
6976
|
+
itemUpdates: evaluation.itemUpdates,
|
|
6744
6977
|
injected: result.injected,
|
|
6745
6978
|
attemptCount: this.deps.cycleAttemptRepo.listForCycle(activeCycle.id).length
|
|
6746
6979
|
};
|
|
6747
6980
|
await this.deps.targetStore.appendTargetCycleRecord(workspace.path, targetId, cycleRecord);
|
|
6748
|
-
if (
|
|
6981
|
+
if (isEvaluateStopResult(evaluation)) {
|
|
6749
6982
|
await this.updateTargetMetaStatus(workspace.path, targetId, {
|
|
6750
|
-
status:
|
|
6983
|
+
status: evaluation.stopReason === "objective_complete" ? "completed" : "cancelled",
|
|
6751
6984
|
completedAt: finishedCycle.completedAt ?? Date.now()
|
|
6752
6985
|
});
|
|
6753
6986
|
}
|
|
@@ -6764,9 +6997,9 @@ var init_manager2 = __esm({
|
|
|
6764
6997
|
const finishedSupervisor = this.attachCycles(
|
|
6765
6998
|
this.withCurrentTargetState(
|
|
6766
6999
|
this.deps.supervisorRepo.update(activeCycle.supervisorId, {
|
|
6767
|
-
state: result.evaluation
|
|
7000
|
+
state: isEvaluateStopResult(result.evaluation) ? "stopped" : "idle",
|
|
6768
7001
|
completedSupervisionCount: (this.supervisors.get(activeCycle.supervisorId)?.completedSupervisionCount ?? 0) + 1,
|
|
6769
|
-
stopReason:
|
|
7002
|
+
stopReason: isEvaluateStopResult(evaluation) ? evaluation.stopReason : null,
|
|
6770
7003
|
lastCycleAt: finishedCycle.completedAt,
|
|
6771
7004
|
lastEvaluatedTurnId: context.lastTurnId ?? void 0,
|
|
6772
7005
|
errorReason: null,
|
|
@@ -6920,23 +7153,46 @@ var init_manager2 = __esm({
|
|
|
6920
7153
|
};
|
|
6921
7154
|
}
|
|
6922
7155
|
applyEvaluationToTargetMemory(memory, evaluation, injectedText, updatedAt) {
|
|
6923
|
-
|
|
6924
|
-
|
|
6925
|
-
|
|
6926
|
-
|
|
6927
|
-
|
|
6928
|
-
|
|
6929
|
-
|
|
7156
|
+
if (isDecomposeResult(evaluation)) {
|
|
7157
|
+
return {
|
|
7158
|
+
...memory,
|
|
7159
|
+
decompositionGenerated: true,
|
|
7160
|
+
decompositionMode: evaluation.decompositionMode,
|
|
7161
|
+
items: evaluation.items,
|
|
7162
|
+
activeItemId: evaluation.activeItemId,
|
|
7163
|
+
progressSummary: evaluation.progressSummary ?? memory.progressSummary,
|
|
7164
|
+
updatedAt
|
|
7165
|
+
};
|
|
7166
|
+
}
|
|
7167
|
+
if (isEvaluateStopResult(evaluation)) {
|
|
7168
|
+
return {
|
|
7169
|
+
...memory,
|
|
7170
|
+
decompositionGenerated: memory.decompositionGenerated,
|
|
7171
|
+
decompositionMode: memory.decompositionMode,
|
|
7172
|
+
items: memory.items,
|
|
7173
|
+
activeItemId: memory.activeItemId,
|
|
7174
|
+
progressSummary: memory.progressSummary,
|
|
7175
|
+
lastGuidance: memory.lastGuidance,
|
|
7176
|
+
stalledCount: 0,
|
|
7177
|
+
updatedAt
|
|
7178
|
+
};
|
|
7179
|
+
}
|
|
7180
|
+
let items = memory.items;
|
|
7181
|
+
if (evaluation.itemUpdates?.length) {
|
|
7182
|
+
const updates = new Map(evaluation.itemUpdates.map((item) => [item.id, item.status]));
|
|
7183
|
+
items = memory.items.map(
|
|
7184
|
+
(item) => updates.has(item.id) ? { ...item, status: updates.get(item.id) } : item
|
|
6930
7185
|
);
|
|
6931
7186
|
}
|
|
6932
7187
|
const progressSummary = evaluation.progressSummary ?? memory.progressSummary;
|
|
6933
|
-
const lastGuidance =
|
|
6934
|
-
const stalledCount =
|
|
7188
|
+
const lastGuidance = injectedText ?? evaluation.guidance ?? memory.lastGuidance;
|
|
7189
|
+
const stalledCount = !evaluation.progressSummary && !evaluation.itemUpdates?.length ? memory.stalledCount + 1 : 0;
|
|
6935
7190
|
return {
|
|
6936
7191
|
...memory,
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
7192
|
+
decompositionGenerated: memory.decompositionGenerated,
|
|
7193
|
+
decompositionMode: memory.decompositionMode,
|
|
7194
|
+
items,
|
|
7195
|
+
activeItemId: evaluation.activeItemId ?? memory.activeItemId,
|
|
6940
7196
|
progressSummary,
|
|
6941
7197
|
lastGuidance,
|
|
6942
7198
|
stalledCount,
|
|
@@ -7059,10 +7315,10 @@ var init_manager2 = __esm({
|
|
|
7059
7315
|
{ supervisor, event }
|
|
7060
7316
|
);
|
|
7061
7317
|
}
|
|
7062
|
-
broadcastCycle(supervisor, cycle, event) {
|
|
7318
|
+
broadcastCycle(supervisor, cycle, event, runtime) {
|
|
7063
7319
|
this.deps.broadcaster.broadcast(
|
|
7064
7320
|
Topics.supervisorCycle(supervisor.workspaceId, supervisor.sessionId),
|
|
7065
|
-
{ cycle, event }
|
|
7321
|
+
{ cycle: runtime ? { ...cycle, runtime } : cycle, event }
|
|
7066
7322
|
);
|
|
7067
7323
|
}
|
|
7068
7324
|
shouldRetryAttempt(error, attemptIndex, retry) {
|
|
@@ -7088,10 +7344,10 @@ var init_manager2 = __esm({
|
|
|
7088
7344
|
if (signal?.aborted) {
|
|
7089
7345
|
throw { code: "supervisor_eval_aborted", message: "Supervisor evaluator aborted" };
|
|
7090
7346
|
}
|
|
7091
|
-
await new Promise((
|
|
7347
|
+
await new Promise((resolve5, reject) => {
|
|
7092
7348
|
const timer = setTimeout(() => {
|
|
7093
7349
|
signal?.removeEventListener("abort", onAbort);
|
|
7094
|
-
|
|
7350
|
+
resolve5();
|
|
7095
7351
|
}, delayMs);
|
|
7096
7352
|
timer.unref?.();
|
|
7097
7353
|
const onAbort = () => {
|
|
@@ -7159,6 +7415,119 @@ function errorMessage(error, fallback) {
|
|
|
7159
7415
|
}
|
|
7160
7416
|
return fallback;
|
|
7161
7417
|
}
|
|
7418
|
+
function isRecord(value) {
|
|
7419
|
+
return Boolean(value) && typeof value === "object";
|
|
7420
|
+
}
|
|
7421
|
+
function readNonEmptyString(value) {
|
|
7422
|
+
if (typeof value !== "string") {
|
|
7423
|
+
return void 0;
|
|
7424
|
+
}
|
|
7425
|
+
const next = value.trim();
|
|
7426
|
+
return next ? next : void 0;
|
|
7427
|
+
}
|
|
7428
|
+
function readStatus(value) {
|
|
7429
|
+
return value === "in_progress" || value === "done" || value === "pending" ? value : "pending";
|
|
7430
|
+
}
|
|
7431
|
+
function readDecompositionMode(value) {
|
|
7432
|
+
return value === "stage" || value === "subtarget" ? value : void 0;
|
|
7433
|
+
}
|
|
7434
|
+
function readNonNegativeInteger(value, fallback) {
|
|
7435
|
+
if (!Number.isSafeInteger(value) || typeof value !== "number" || value < 0) {
|
|
7436
|
+
return fallback;
|
|
7437
|
+
}
|
|
7438
|
+
return value;
|
|
7439
|
+
}
|
|
7440
|
+
function readTimestamp(value, fallback) {
|
|
7441
|
+
if (!Number.isSafeInteger(value) || typeof value !== "number") {
|
|
7442
|
+
return fallback;
|
|
7443
|
+
}
|
|
7444
|
+
return value;
|
|
7445
|
+
}
|
|
7446
|
+
function fallbackAcceptanceCriteria(title) {
|
|
7447
|
+
return [`${title} is complete`];
|
|
7448
|
+
}
|
|
7449
|
+
function normalizeItem(value, fallbackKind) {
|
|
7450
|
+
if (!isRecord(value)) {
|
|
7451
|
+
return null;
|
|
7452
|
+
}
|
|
7453
|
+
const id = readNonEmptyString(value.id);
|
|
7454
|
+
const title = readNonEmptyString(value.title);
|
|
7455
|
+
if (!id || !title) {
|
|
7456
|
+
return null;
|
|
7457
|
+
}
|
|
7458
|
+
const kind = readDecompositionMode(value.kind) ?? fallbackKind ?? "stage";
|
|
7459
|
+
const objective = readNonEmptyString(value.objective) ?? title;
|
|
7460
|
+
const deliverable = readNonEmptyString(value.deliverable) ?? `${title} completed`;
|
|
7461
|
+
const acceptanceCriteria = Array.isArray(value.acceptanceCriteria) ? value.acceptanceCriteria.flatMap((entry) => {
|
|
7462
|
+
const next = readNonEmptyString(entry);
|
|
7463
|
+
return next ? [next] : [];
|
|
7464
|
+
}) : [];
|
|
7465
|
+
return {
|
|
7466
|
+
id,
|
|
7467
|
+
kind,
|
|
7468
|
+
title,
|
|
7469
|
+
objective,
|
|
7470
|
+
deliverable,
|
|
7471
|
+
acceptanceCriteria: acceptanceCriteria.length > 0 ? acceptanceCriteria : fallbackAcceptanceCriteria(title),
|
|
7472
|
+
status: readStatus(value.status)
|
|
7473
|
+
};
|
|
7474
|
+
}
|
|
7475
|
+
function normalizeLegacyPlanItems(plan) {
|
|
7476
|
+
if (!Array.isArray(plan)) {
|
|
7477
|
+
return [];
|
|
7478
|
+
}
|
|
7479
|
+
return plan.flatMap((value) => {
|
|
7480
|
+
const item = normalizeItem(
|
|
7481
|
+
isRecord(value) ? {
|
|
7482
|
+
id: value.id,
|
|
7483
|
+
kind: "stage",
|
|
7484
|
+
title: value.title,
|
|
7485
|
+
objective: value.title,
|
|
7486
|
+
deliverable: `${readNonEmptyString(value.title) ?? "Legacy step"} completed`,
|
|
7487
|
+
acceptanceCriteria: fallbackAcceptanceCriteria(
|
|
7488
|
+
readNonEmptyString(value.title) ?? "Legacy step"
|
|
7489
|
+
),
|
|
7490
|
+
status: value.status
|
|
7491
|
+
} : value,
|
|
7492
|
+
"stage"
|
|
7493
|
+
);
|
|
7494
|
+
return item ? [item] : [];
|
|
7495
|
+
});
|
|
7496
|
+
}
|
|
7497
|
+
function resolveActiveItemId(items, candidate) {
|
|
7498
|
+
const next = readNonEmptyString(candidate);
|
|
7499
|
+
if (next && items.some((item) => item.id === next)) {
|
|
7500
|
+
return next;
|
|
7501
|
+
}
|
|
7502
|
+
return items.find((item) => item.status === "in_progress")?.id ?? items.find((item) => item.status === "pending")?.id ?? items[0]?.id;
|
|
7503
|
+
}
|
|
7504
|
+
function normalizeTargetMemory(raw, targetId) {
|
|
7505
|
+
if (!isRecord(raw)) {
|
|
7506
|
+
return buildTargetMemory(targetId, 0);
|
|
7507
|
+
}
|
|
7508
|
+
const updatedAt = readTimestamp(raw.updatedAt, 0);
|
|
7509
|
+
const declaredMode = readDecompositionMode(raw.decompositionMode);
|
|
7510
|
+
let items = Array.isArray(raw.items) ? raw.items.flatMap((value) => {
|
|
7511
|
+
const item = normalizeItem(value, declaredMode);
|
|
7512
|
+
return item ? [item] : [];
|
|
7513
|
+
}) : [];
|
|
7514
|
+
let decompositionMode = declaredMode ?? items[0]?.kind;
|
|
7515
|
+
if (items.length === 0) {
|
|
7516
|
+
items = normalizeLegacyPlanItems(raw.plan);
|
|
7517
|
+
decompositionMode = items.length > 0 ? "stage" : void 0;
|
|
7518
|
+
}
|
|
7519
|
+
return {
|
|
7520
|
+
targetId: readNonEmptyString(raw.targetId) ?? targetId,
|
|
7521
|
+
decompositionGenerated: items.length > 0,
|
|
7522
|
+
decompositionMode,
|
|
7523
|
+
items,
|
|
7524
|
+
activeItemId: resolveActiveItemId(items, raw.activeItemId ?? raw.activeStepId),
|
|
7525
|
+
progressSummary: readNonEmptyString(raw.progressSummary),
|
|
7526
|
+
lastGuidance: readNonEmptyString(raw.lastGuidance),
|
|
7527
|
+
stalledCount: readNonNegativeInteger(raw.stalledCount, 0),
|
|
7528
|
+
updatedAt
|
|
7529
|
+
};
|
|
7530
|
+
}
|
|
7162
7531
|
async function writeJsonIfMissing(path10, value) {
|
|
7163
7532
|
try {
|
|
7164
7533
|
await writeFile3(path10, JSON.stringify(value, null, 2) + "\n", {
|
|
@@ -7187,8 +7556,12 @@ function buildTargetMeta(input) {
|
|
|
7187
7556
|
function buildTargetMemory(targetId, createdAt) {
|
|
7188
7557
|
return {
|
|
7189
7558
|
targetId,
|
|
7190
|
-
|
|
7191
|
-
|
|
7559
|
+
decompositionGenerated: false,
|
|
7560
|
+
decompositionMode: void 0,
|
|
7561
|
+
items: [],
|
|
7562
|
+
activeItemId: void 0,
|
|
7563
|
+
progressSummary: void 0,
|
|
7564
|
+
lastGuidance: void 0,
|
|
7192
7565
|
stalledCount: 0,
|
|
7193
7566
|
updatedAt: createdAt
|
|
7194
7567
|
};
|
|
@@ -7277,8 +7650,9 @@ async function readTargetMeta(workspacePath, targetId) {
|
|
|
7277
7650
|
);
|
|
7278
7651
|
}
|
|
7279
7652
|
async function loadTargetMemory(workspacePath, targetId) {
|
|
7280
|
-
return
|
|
7281
|
-
await readFile2(memoryPath(workspacePath, targetId), "utf-8")
|
|
7653
|
+
return normalizeTargetMemory(
|
|
7654
|
+
JSON.parse(await readFile2(memoryPath(workspacePath, targetId), "utf-8")),
|
|
7655
|
+
targetId
|
|
7282
7656
|
);
|
|
7283
7657
|
}
|
|
7284
7658
|
async function saveTargetMemory(workspacePath, targetId, memory) {
|
|
@@ -7615,8 +7989,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
7615
7989
|
if (this.pendingWriteCount === 0) {
|
|
7616
7990
|
return Promise.resolve();
|
|
7617
7991
|
}
|
|
7618
|
-
return new Promise((
|
|
7619
|
-
this.drainResolvers.push(
|
|
7992
|
+
return new Promise((resolve5) => {
|
|
7993
|
+
this.drainResolvers.push(resolve5);
|
|
7620
7994
|
});
|
|
7621
7995
|
}
|
|
7622
7996
|
resolveDrainIfIdle() {
|
|
@@ -7625,8 +7999,8 @@ var init_terminal_snapshot_buffer = __esm({
|
|
|
7625
7999
|
}
|
|
7626
8000
|
const resolvers = this.drainResolvers;
|
|
7627
8001
|
this.drainResolvers = [];
|
|
7628
|
-
for (const
|
|
7629
|
-
|
|
8002
|
+
for (const resolve5 of resolvers) {
|
|
8003
|
+
resolve5();
|
|
7630
8004
|
}
|
|
7631
8005
|
}
|
|
7632
8006
|
requireTerminal() {
|
|
@@ -7945,10 +8319,10 @@ var init_manager3 = __esm({
|
|
|
7945
8319
|
}
|
|
7946
8320
|
return existing.promise;
|
|
7947
8321
|
}
|
|
7948
|
-
let
|
|
8322
|
+
let resolve5 = () => {
|
|
7949
8323
|
};
|
|
7950
8324
|
const promise = new Promise((innerResolve) => {
|
|
7951
|
-
|
|
8325
|
+
resolve5 = innerResolve;
|
|
7952
8326
|
});
|
|
7953
8327
|
let markKillCompleted = () => {
|
|
7954
8328
|
};
|
|
@@ -7961,7 +8335,7 @@ var init_manager3 = __esm({
|
|
|
7961
8335
|
markKillCompleted,
|
|
7962
8336
|
finalized: false,
|
|
7963
8337
|
promise,
|
|
7964
|
-
resolve:
|
|
8338
|
+
resolve: resolve5
|
|
7965
8339
|
});
|
|
7966
8340
|
void terminal.pty.kill(signal).finally(() => {
|
|
7967
8341
|
const waiter = this.explicitCloseWaiters.get(terminalId);
|
|
@@ -8168,20 +8542,8 @@ function createTreeVisibilityFilter() {
|
|
|
8168
8542
|
return (name) => !isTreeHidden(name);
|
|
8169
8543
|
}
|
|
8170
8544
|
function createWatcherIgnoreFilter(rootPath) {
|
|
8171
|
-
|
|
8172
|
-
|
|
8173
|
-
return (path10) => DEFAULT_WATCHER_IGNORED_PATTERNS.some((p) => p.test(normalizePath(path10)));
|
|
8174
|
-
}
|
|
8175
|
-
const gitignoreContent = readFileSync5(gitignorePath, "utf-8");
|
|
8176
|
-
const ig = ignore().add(gitignoreContent);
|
|
8177
|
-
return (path10) => {
|
|
8178
|
-
const normalizedPath = normalizePath(path10);
|
|
8179
|
-
if (DEFAULT_WATCHER_IGNORED_PATTERNS.some((p) => p.test(normalizedPath))) {
|
|
8180
|
-
return true;
|
|
8181
|
-
}
|
|
8182
|
-
const relativePath = relativeToRoot(rootPath, path10);
|
|
8183
|
-
return isIgnoredByGitignore(ig, relativePath);
|
|
8184
|
-
};
|
|
8545
|
+
void rootPath;
|
|
8546
|
+
return (path10) => DEFAULT_WATCHER_IGNORED_PATTERNS.some((p) => p.test(normalizePath(path10)));
|
|
8185
8547
|
}
|
|
8186
8548
|
var DEFAULT_WATCHER_IGNORED_PATTERNS;
|
|
8187
8549
|
var init_gitignore = __esm({
|
|
@@ -8246,11 +8608,11 @@ var init_watcher = __esm({
|
|
|
8246
8608
|
this.pendingReason = "fs_change";
|
|
8247
8609
|
}
|
|
8248
8610
|
const elapsed = now - this.firstDirtyTime;
|
|
8249
|
-
const
|
|
8611
|
+
const delay2 = Math.min(this.DEBOUNCE_MS, Math.max(0, this.MAX_WAIT_MS - elapsed));
|
|
8250
8612
|
if (this.dirtyTimer) {
|
|
8251
8613
|
clearTimeout(this.dirtyTimer);
|
|
8252
8614
|
}
|
|
8253
|
-
this.dirtyTimer = setTimeout(() => this.flushDirty(),
|
|
8615
|
+
this.dirtyTimer = setTimeout(() => this.flushDirty(), delay2);
|
|
8254
8616
|
}
|
|
8255
8617
|
flushDirty() {
|
|
8256
8618
|
this.broadcaster?.broadcast(Topics.workspaceFsDirty(this.workspaceId), {
|
|
@@ -8848,7 +9210,8 @@ var init_fencing = __esm({
|
|
|
8848
9210
|
});
|
|
8849
9211
|
|
|
8850
9212
|
// packages/server/src/commands/terminal.ts
|
|
8851
|
-
import {
|
|
9213
|
+
import { stat as stat6 } from "node:fs/promises";
|
|
9214
|
+
import { basename, isAbsolute as isAbsolute3 } from "node:path";
|
|
8852
9215
|
import { z as z5 } from "zod";
|
|
8853
9216
|
function decodeTerminalInput(args) {
|
|
8854
9217
|
if ("bytes" in args) {
|
|
@@ -8919,6 +9282,7 @@ var init_terminal = __esm({
|
|
|
8919
9282
|
"packages/server/src/commands/terminal.ts"() {
|
|
8920
9283
|
"use strict";
|
|
8921
9284
|
init_src3();
|
|
9285
|
+
init_file_io();
|
|
8922
9286
|
init_dispatch();
|
|
8923
9287
|
TerminalInputActivitySchema = z5.enum(TERMINAL_INPUT_ACTIVITIES).optional();
|
|
8924
9288
|
TerminalInputSchema = z5.union([
|
|
@@ -8953,20 +9317,44 @@ var init_terminal = __esm({
|
|
|
8953
9317
|
z5.object({
|
|
8954
9318
|
workspaceId: z5.string(),
|
|
8955
9319
|
cols: z5.number().int().positive().optional(),
|
|
8956
|
-
rows: z5.number().int().positive().optional()
|
|
9320
|
+
rows: z5.number().int().positive().optional(),
|
|
9321
|
+
cwdPath: z5.string().optional()
|
|
8957
9322
|
}),
|
|
8958
9323
|
async (args, ctx) => {
|
|
8959
9324
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
8960
9325
|
if (!workspace) {
|
|
8961
9326
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
8962
9327
|
}
|
|
9328
|
+
let cwd = workspace.path;
|
|
9329
|
+
if (args.cwdPath && args.cwdPath !== ".") {
|
|
9330
|
+
if (isAbsolute3(args.cwdPath)) {
|
|
9331
|
+
throw { code: "invalid_cwd_path", message: "cwdPath must be workspace-relative" };
|
|
9332
|
+
}
|
|
9333
|
+
let resolvedCwd;
|
|
9334
|
+
try {
|
|
9335
|
+
resolvedCwd = resolveSafe(workspace.path, args.cwdPath);
|
|
9336
|
+
} catch (error) {
|
|
9337
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "path_escape") {
|
|
9338
|
+
throw { code: "invalid_cwd_path", message: "cwdPath must be workspace-relative" };
|
|
9339
|
+
}
|
|
9340
|
+
throw error;
|
|
9341
|
+
}
|
|
9342
|
+
const cwdStats = await stat6(resolvedCwd).catch(() => null);
|
|
9343
|
+
if (!cwdStats) {
|
|
9344
|
+
throw { code: "cwd_not_found", message: `Directory not found: ${args.cwdPath}` };
|
|
9345
|
+
}
|
|
9346
|
+
if (!cwdStats.isDirectory()) {
|
|
9347
|
+
throw { code: "cwd_not_directory", message: `Not a directory: ${args.cwdPath}` };
|
|
9348
|
+
}
|
|
9349
|
+
cwd = resolvedCwd;
|
|
9350
|
+
}
|
|
8963
9351
|
const shell = resolveShellCommand();
|
|
8964
9352
|
const terminal = ctx.terminalMgr.create({
|
|
8965
9353
|
workspaceId: args.workspaceId,
|
|
8966
9354
|
kind: "shell",
|
|
8967
9355
|
argv: shell.argv,
|
|
8968
9356
|
title: shell.title,
|
|
8969
|
-
cwd
|
|
9357
|
+
cwd,
|
|
8970
9358
|
cols: args.cols ?? 120,
|
|
8971
9359
|
rows: args.rows ?? 30
|
|
8972
9360
|
});
|
|
@@ -9652,7 +10040,7 @@ var init_hub = __esm({
|
|
|
9652
10040
|
}
|
|
9653
10041
|
}
|
|
9654
10042
|
awaitBinaryPayload(clientId) {
|
|
9655
|
-
return new Promise((
|
|
10043
|
+
return new Promise((resolve5, reject) => {
|
|
9656
10044
|
const timer = setTimeout(() => {
|
|
9657
10045
|
const waiters = this.pendingBinaryWaiters.get(clientId);
|
|
9658
10046
|
if (!waiters) return;
|
|
@@ -9664,7 +10052,7 @@ var init_hub = __esm({
|
|
|
9664
10052
|
}
|
|
9665
10053
|
reject(new Error("Timeout waiting for terminal input binary payload"));
|
|
9666
10054
|
}, BINARY_PAYLOAD_TIMEOUT_MS);
|
|
9667
|
-
const waiter = { resolve:
|
|
10055
|
+
const waiter = { resolve: resolve5, reject, timer };
|
|
9668
10056
|
const queue = this.pendingBinaryWaiters.get(clientId);
|
|
9669
10057
|
if (queue) {
|
|
9670
10058
|
queue.push(waiter);
|
|
@@ -9942,10 +10330,34 @@ var init_hub = __esm({
|
|
|
9942
10330
|
});
|
|
9943
10331
|
|
|
9944
10332
|
// packages/server/src/commands/workspace.ts
|
|
9945
|
-
import { readdir as readdir2 } from "node:fs/promises";
|
|
10333
|
+
import { readdir as readdir2, realpath as realpath2 } from "node:fs/promises";
|
|
9946
10334
|
import { homedir as homedir2 } from "node:os";
|
|
9947
|
-
import { join as join6 } from "node:path";
|
|
10335
|
+
import { isAbsolute as isAbsolute4, join as join6, resolve as resolve3 } from "node:path";
|
|
9948
10336
|
import { z as z6 } from "zod";
|
|
10337
|
+
function resolveBrowsePath(path10) {
|
|
10338
|
+
const home = homedir2();
|
|
10339
|
+
if (!path10 || path10 === "~") {
|
|
10340
|
+
return home;
|
|
10341
|
+
}
|
|
10342
|
+
if (path10.startsWith("~/")) {
|
|
10343
|
+
return join6(home, path10.slice(2));
|
|
10344
|
+
}
|
|
10345
|
+
return isAbsolute4(path10) ? path10 : resolve3(home, path10);
|
|
10346
|
+
}
|
|
10347
|
+
async function buildRootPaths(currentPath) {
|
|
10348
|
+
const roots = /* @__PURE__ */ new Set(["/"]);
|
|
10349
|
+
const home = homedir2();
|
|
10350
|
+
roots.add(home);
|
|
10351
|
+
try {
|
|
10352
|
+
roots.add(await realpath2(home));
|
|
10353
|
+
} catch {
|
|
10354
|
+
}
|
|
10355
|
+
const currentSegments = currentPath.split("/").filter(Boolean);
|
|
10356
|
+
if (currentSegments.length > 0) {
|
|
10357
|
+
roots.add(`/${currentSegments[0]}`);
|
|
10358
|
+
}
|
|
10359
|
+
return Array.from(roots);
|
|
10360
|
+
}
|
|
9949
10361
|
var init_workspace = __esm({
|
|
9950
10362
|
"packages/server/src/commands/workspace.ts"() {
|
|
9951
10363
|
"use strict";
|
|
@@ -9959,7 +10371,7 @@ var init_workspace = __esm({
|
|
|
9959
10371
|
path: z6.string().optional()
|
|
9960
10372
|
}),
|
|
9961
10373
|
async (args) => {
|
|
9962
|
-
const basePath = args.path
|
|
10374
|
+
const basePath = resolveBrowsePath(args.path);
|
|
9963
10375
|
const entries = await readdir2(basePath, { withFileTypes: true });
|
|
9964
10376
|
const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
|
|
9965
10377
|
name: entry.name,
|
|
@@ -9968,7 +10380,8 @@ var init_workspace = __esm({
|
|
|
9968
10380
|
return {
|
|
9969
10381
|
currentPath: basePath,
|
|
9970
10382
|
parentPath: basePath !== "/" ? join6(basePath, "..") : null,
|
|
9971
|
-
directories
|
|
10383
|
+
directories,
|
|
10384
|
+
rootPaths: await buildRootPaths(basePath)
|
|
9972
10385
|
};
|
|
9973
10386
|
}
|
|
9974
10387
|
);
|
|
@@ -10001,6 +10414,7 @@ var init_workspace = __esm({
|
|
|
10001
10414
|
bottomPanelHeight: z6.number(),
|
|
10002
10415
|
focusMode: z6.boolean(),
|
|
10003
10416
|
activeSessionId: z6.string().optional(),
|
|
10417
|
+
fileTreeExpandedDirs: z6.array(z6.string()).optional(),
|
|
10004
10418
|
paneLayout: z6.object({
|
|
10005
10419
|
id: z6.string(),
|
|
10006
10420
|
type: z6.enum(["leaf", "split"]),
|
|
@@ -10264,16 +10678,105 @@ var init_runtime_status = __esm({
|
|
|
10264
10678
|
}
|
|
10265
10679
|
});
|
|
10266
10680
|
|
|
10681
|
+
// packages/server/src/workspace/pane-layout.ts
|
|
10682
|
+
function applyPaneDisposition(layout, sessionId, disposition) {
|
|
10683
|
+
if (!layout) {
|
|
10684
|
+
return layout;
|
|
10685
|
+
}
|
|
10686
|
+
return disposition === "remove" ? removePaneBySessionId(layout, sessionId) : closePaneBySessionId(layout, sessionId);
|
|
10687
|
+
}
|
|
10688
|
+
function closePaneBySessionId(node, sessionId) {
|
|
10689
|
+
return replaceSessionWithDraft(node, sessionId);
|
|
10690
|
+
}
|
|
10691
|
+
function replaceSessionWithDraft(node, sessionId) {
|
|
10692
|
+
if (node.type === "leaf") {
|
|
10693
|
+
if (node.sessionId === sessionId) {
|
|
10694
|
+
return {
|
|
10695
|
+
id: node.id,
|
|
10696
|
+
type: "leaf"
|
|
10697
|
+
};
|
|
10698
|
+
}
|
|
10699
|
+
return node;
|
|
10700
|
+
}
|
|
10701
|
+
const children = node.children ?? [];
|
|
10702
|
+
let changed = false;
|
|
10703
|
+
const nextChildren = children.map((child) => {
|
|
10704
|
+
const nextChild = replaceSessionWithDraft(child, sessionId);
|
|
10705
|
+
if (nextChild !== child) {
|
|
10706
|
+
changed = true;
|
|
10707
|
+
}
|
|
10708
|
+
return nextChild;
|
|
10709
|
+
});
|
|
10710
|
+
if (!changed) {
|
|
10711
|
+
return node;
|
|
10712
|
+
}
|
|
10713
|
+
return {
|
|
10714
|
+
...node,
|
|
10715
|
+
children: nextChildren
|
|
10716
|
+
};
|
|
10717
|
+
}
|
|
10718
|
+
function removePaneBySessionId(node, sessionId) {
|
|
10719
|
+
return removeSessionPane(node, sessionId) ?? { id: node.id, type: "leaf" };
|
|
10720
|
+
}
|
|
10721
|
+
function removeSessionPane(node, sessionId) {
|
|
10722
|
+
if (node.type === "leaf") {
|
|
10723
|
+
if (node.sessionId === sessionId) {
|
|
10724
|
+
return null;
|
|
10725
|
+
}
|
|
10726
|
+
return node;
|
|
10727
|
+
}
|
|
10728
|
+
const children = node.children ?? [];
|
|
10729
|
+
let changed = false;
|
|
10730
|
+
const nextChildren = [];
|
|
10731
|
+
for (const child of children) {
|
|
10732
|
+
const nextChild = removeSessionPane(child, sessionId);
|
|
10733
|
+
if (nextChild !== child) {
|
|
10734
|
+
changed = true;
|
|
10735
|
+
}
|
|
10736
|
+
if (nextChild !== null) {
|
|
10737
|
+
nextChildren.push(nextChild);
|
|
10738
|
+
}
|
|
10739
|
+
}
|
|
10740
|
+
if (!changed) {
|
|
10741
|
+
return node;
|
|
10742
|
+
}
|
|
10743
|
+
if (nextChildren.length === 1) {
|
|
10744
|
+
return nextChildren[0];
|
|
10745
|
+
}
|
|
10746
|
+
if (nextChildren.length === 0) {
|
|
10747
|
+
return null;
|
|
10748
|
+
}
|
|
10749
|
+
return {
|
|
10750
|
+
...node,
|
|
10751
|
+
children: nextChildren
|
|
10752
|
+
};
|
|
10753
|
+
}
|
|
10754
|
+
var init_pane_layout = __esm({
|
|
10755
|
+
"packages/server/src/workspace/pane-layout.ts"() {
|
|
10756
|
+
"use strict";
|
|
10757
|
+
}
|
|
10758
|
+
});
|
|
10759
|
+
|
|
10267
10760
|
// packages/server/src/commands/session.ts
|
|
10268
10761
|
import { z as z10 } from "zod";
|
|
10762
|
+
function delay(ms) {
|
|
10763
|
+
return new Promise((resolve5) => {
|
|
10764
|
+
setTimeout(resolve5, ms);
|
|
10765
|
+
});
|
|
10766
|
+
}
|
|
10269
10767
|
function getProviderFromRegistry(providerId, registry) {
|
|
10270
10768
|
return registry.find((provider) => provider.id === providerId);
|
|
10271
10769
|
}
|
|
10770
|
+
var SESSION_CLOSE_POLL_INTERVAL_MS, SESSION_CLOSE_TIMEOUT_MS;
|
|
10272
10771
|
var init_session = __esm({
|
|
10273
10772
|
"packages/server/src/commands/session.ts"() {
|
|
10274
10773
|
"use strict";
|
|
10275
10774
|
init_runtime_status();
|
|
10775
|
+
init_database();
|
|
10776
|
+
init_pane_layout();
|
|
10276
10777
|
init_dispatch();
|
|
10778
|
+
SESSION_CLOSE_POLL_INTERVAL_MS = 100;
|
|
10779
|
+
SESSION_CLOSE_TIMEOUT_MS = 5e3;
|
|
10277
10780
|
registerCommand(
|
|
10278
10781
|
"session.list",
|
|
10279
10782
|
z10.object({
|
|
@@ -10345,11 +10848,75 @@ var init_session = __esm({
|
|
|
10345
10848
|
ctx.sessionMgr.delete(args.sessionId);
|
|
10346
10849
|
}
|
|
10347
10850
|
);
|
|
10851
|
+
registerCommand(
|
|
10852
|
+
"session.close",
|
|
10853
|
+
z10.object({
|
|
10854
|
+
sessionId: z10.string(),
|
|
10855
|
+
paneDisposition: z10.enum(["draft", "remove"]).default("draft")
|
|
10856
|
+
}),
|
|
10857
|
+
async (args, ctx) => {
|
|
10858
|
+
let session = ctx.sessionMgr.get(args.sessionId);
|
|
10859
|
+
if (!session) {
|
|
10860
|
+
throw { code: "session_not_found", message: `Session not found: ${args.sessionId}` };
|
|
10861
|
+
}
|
|
10862
|
+
if (session.state !== "ended") {
|
|
10863
|
+
try {
|
|
10864
|
+
await ctx.sessionMgr.stop(args.sessionId);
|
|
10865
|
+
} catch (error) {
|
|
10866
|
+
const candidate = error;
|
|
10867
|
+
throw {
|
|
10868
|
+
code: "session_close_failed",
|
|
10869
|
+
message: candidate.message ?? `Failed to stop session: ${args.sessionId}`
|
|
10870
|
+
};
|
|
10871
|
+
}
|
|
10872
|
+
const deadline = Date.now() + SESSION_CLOSE_TIMEOUT_MS;
|
|
10873
|
+
while (Date.now() < deadline) {
|
|
10874
|
+
session = ctx.sessionMgr.get(args.sessionId);
|
|
10875
|
+
if (!session) {
|
|
10876
|
+
return;
|
|
10877
|
+
}
|
|
10878
|
+
if (session.state === "ended") {
|
|
10879
|
+
break;
|
|
10880
|
+
}
|
|
10881
|
+
await delay(SESSION_CLOSE_POLL_INTERVAL_MS);
|
|
10882
|
+
}
|
|
10883
|
+
session = ctx.sessionMgr.get(args.sessionId);
|
|
10884
|
+
if (!session) {
|
|
10885
|
+
return;
|
|
10886
|
+
}
|
|
10887
|
+
if (session.state !== "ended") {
|
|
10888
|
+
throw {
|
|
10889
|
+
code: "session_close_timeout",
|
|
10890
|
+
message: `Timed out waiting for session to end before closing: ${args.sessionId}`
|
|
10891
|
+
};
|
|
10892
|
+
}
|
|
10893
|
+
}
|
|
10894
|
+
const workspace = ctx.workspaceMgr.get(session.workspaceId);
|
|
10895
|
+
if (!workspace) {
|
|
10896
|
+
throw {
|
|
10897
|
+
code: "workspace_not_found",
|
|
10898
|
+
message: `Workspace not found: ${session.workspaceId}`
|
|
10899
|
+
};
|
|
10900
|
+
}
|
|
10901
|
+
const nextUiState = {
|
|
10902
|
+
...workspace.uiState,
|
|
10903
|
+
paneLayout: applyPaneDisposition(
|
|
10904
|
+
workspace.uiState.paneLayout,
|
|
10905
|
+
args.sessionId,
|
|
10906
|
+
args.paneDisposition
|
|
10907
|
+
)
|
|
10908
|
+
};
|
|
10909
|
+
withTransaction(ctx.db, () => {
|
|
10910
|
+
ctx.workspaceMgr.updateUiState(session.workspaceId, nextUiState);
|
|
10911
|
+
ctx.sessionMgr.delete(args.sessionId);
|
|
10912
|
+
});
|
|
10913
|
+
}
|
|
10914
|
+
);
|
|
10348
10915
|
}
|
|
10349
10916
|
});
|
|
10350
10917
|
|
|
10351
10918
|
// packages/server/src/fs/tree.ts
|
|
10352
|
-
import { readdir as readdir3, stat as
|
|
10919
|
+
import { readdir as readdir3, stat as stat7 } from "fs/promises";
|
|
10353
10920
|
import { join as join7, relative as relative4 } from "path";
|
|
10354
10921
|
async function readTree(rootPath, subdir) {
|
|
10355
10922
|
const targetPath = subdir ? join7(rootPath, subdir) : rootPath;
|
|
@@ -10371,7 +10938,7 @@ async function readTree(rootPath, subdir) {
|
|
|
10371
10938
|
// Not loaded yet - client will request on expand
|
|
10372
10939
|
});
|
|
10373
10940
|
} else if (entry.isFile()) {
|
|
10374
|
-
const stats = await
|
|
10941
|
+
const stats = await stat7(fullPath);
|
|
10375
10942
|
nodes.push({
|
|
10376
10943
|
name: entry.name,
|
|
10377
10944
|
path: relPath,
|
|
@@ -10440,7 +11007,7 @@ async function searchFiles(rootPath, query, limit = 10) {
|
|
|
10440
11007
|
}
|
|
10441
11008
|
return a.path.toLowerCase().localeCompare(b.path.toLowerCase());
|
|
10442
11009
|
}).slice(0, limit)) {
|
|
10443
|
-
const stats = await
|
|
11010
|
+
const stats = await stat7(match.fullPath);
|
|
10444
11011
|
files.push({
|
|
10445
11012
|
name: match.name,
|
|
10446
11013
|
path: match.path,
|
|
@@ -10607,6 +11174,27 @@ var init_file = __esm({
|
|
|
10607
11174
|
return { ok: true };
|
|
10608
11175
|
}
|
|
10609
11176
|
);
|
|
11177
|
+
registerCommand(
|
|
11178
|
+
"file.rename",
|
|
11179
|
+
z11.object({
|
|
11180
|
+
workspaceId: z11.string(),
|
|
11181
|
+
fromPath: z11.string(),
|
|
11182
|
+
toPath: z11.string()
|
|
11183
|
+
}),
|
|
11184
|
+
async (args, ctx) => {
|
|
11185
|
+
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
11186
|
+
if (!workspace) {
|
|
11187
|
+
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
11188
|
+
}
|
|
11189
|
+
await renameEntry(workspace.path, args.fromPath, args.toPath);
|
|
11190
|
+
ctx.eventBus.emit({
|
|
11191
|
+
type: "fs.dirty",
|
|
11192
|
+
workspaceId: args.workspaceId,
|
|
11193
|
+
reason: "fs_change"
|
|
11194
|
+
});
|
|
11195
|
+
return { ok: true };
|
|
11196
|
+
}
|
|
11197
|
+
);
|
|
10610
11198
|
registerCommand(
|
|
10611
11199
|
"file.write",
|
|
10612
11200
|
z11.object({
|
|
@@ -10788,7 +11376,7 @@ import { mkdir as mkdir4, mkdtemp as mkdtemp2, rm as rm5, writeFile as writeFile
|
|
|
10788
11376
|
import os2 from "os";
|
|
10789
11377
|
import path6 from "path";
|
|
10790
11378
|
async function runGit(cwd, args, options = {}) {
|
|
10791
|
-
return new Promise((
|
|
11379
|
+
return new Promise((resolve5, reject) => {
|
|
10792
11380
|
const gitArgs = [
|
|
10793
11381
|
...options.config?.flatMap(([key, value]) => ["-c", `${key}=${value}`]) ?? [],
|
|
10794
11382
|
...args
|
|
@@ -10815,7 +11403,7 @@ async function runGit(cwd, args, options = {}) {
|
|
|
10815
11403
|
if (err) {
|
|
10816
11404
|
reject(new GitError(err.message, stderr));
|
|
10817
11405
|
} else {
|
|
10818
|
-
|
|
11406
|
+
resolve5({ stdout, stderr });
|
|
10819
11407
|
}
|
|
10820
11408
|
}
|
|
10821
11409
|
);
|
|
@@ -12016,6 +12604,9 @@ var init_settings2 = __esm({
|
|
|
12016
12604
|
themeId: z13.string().optional(),
|
|
12017
12605
|
terminalRenderer: z13.enum(["standard", "compatibility"]).optional(),
|
|
12018
12606
|
terminalCopyOnSelect: z13.boolean().optional(),
|
|
12607
|
+
terminalFontSize: z13.number().int().min(10).max(18).optional(),
|
|
12608
|
+
desktopTerminalFontSize: z13.number().int().min(10).max(18).optional(),
|
|
12609
|
+
mobileTerminalFontSize: z13.number().int().min(10).max(18).optional(),
|
|
12019
12610
|
locale: z13.enum(["zh", "en"]).optional()
|
|
12020
12611
|
}).optional(),
|
|
12021
12612
|
providers: ProviderSettingsSchema.optional()
|
|
@@ -12156,20 +12747,373 @@ var init_settings2 = __esm({
|
|
|
12156
12747
|
}
|
|
12157
12748
|
});
|
|
12158
12749
|
|
|
12159
|
-
// packages/server/src/commands/
|
|
12750
|
+
// packages/server/src/commands/diagnostics.ts
|
|
12160
12751
|
import { z as z14 } from "zod";
|
|
12752
|
+
function isLoopbackHost(host) {
|
|
12753
|
+
return host === void 0 || host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "0.0.0.0";
|
|
12754
|
+
}
|
|
12755
|
+
async function resolveWorkspacePathCheck(workspacePath) {
|
|
12756
|
+
if (!workspacePath) {
|
|
12757
|
+
return {
|
|
12758
|
+
canContinue: false,
|
|
12759
|
+
checks: [
|
|
12760
|
+
{
|
|
12761
|
+
id: "workspace-selection",
|
|
12762
|
+
code: "workspace_selection_missing",
|
|
12763
|
+
status: "needs_attention"
|
|
12764
|
+
}
|
|
12765
|
+
]
|
|
12766
|
+
};
|
|
12767
|
+
}
|
|
12768
|
+
const validation = await validatePath(workspacePath);
|
|
12769
|
+
if (validation.valid) {
|
|
12770
|
+
return {
|
|
12771
|
+
canContinue: true,
|
|
12772
|
+
checks: [
|
|
12773
|
+
{
|
|
12774
|
+
id: "workspace-path",
|
|
12775
|
+
code: "workspace_path_ready",
|
|
12776
|
+
status: "ready",
|
|
12777
|
+
workspacePath
|
|
12778
|
+
}
|
|
12779
|
+
]
|
|
12780
|
+
};
|
|
12781
|
+
}
|
|
12782
|
+
return {
|
|
12783
|
+
canContinue: false,
|
|
12784
|
+
checks: [
|
|
12785
|
+
{
|
|
12786
|
+
id: "workspace-path",
|
|
12787
|
+
code: validation.error === "Path does not exist" ? "workspace_path_not_found" : "workspace_path_unreadable",
|
|
12788
|
+
status: "needs_attention",
|
|
12789
|
+
workspacePath
|
|
12790
|
+
}
|
|
12791
|
+
]
|
|
12792
|
+
};
|
|
12793
|
+
}
|
|
12794
|
+
function buildProviderCheck(providerStatus, providerId) {
|
|
12795
|
+
if (providerStatus.available) {
|
|
12796
|
+
return {
|
|
12797
|
+
canContinue: true,
|
|
12798
|
+
checks: [
|
|
12799
|
+
{
|
|
12800
|
+
id: `provider:${providerId}`,
|
|
12801
|
+
code: "provider_runtime_ready",
|
|
12802
|
+
status: "ready",
|
|
12803
|
+
providerId,
|
|
12804
|
+
autoInstallSupported: providerStatus.autoInstallSupported,
|
|
12805
|
+
installReadiness: providerStatus.installReadiness
|
|
12806
|
+
}
|
|
12807
|
+
]
|
|
12808
|
+
};
|
|
12809
|
+
}
|
|
12810
|
+
if (providerStatus.missingPrerequisites.length > 0) {
|
|
12811
|
+
return {
|
|
12812
|
+
canContinue: false,
|
|
12813
|
+
checks: [
|
|
12814
|
+
{
|
|
12815
|
+
id: `provider:${providerId}`,
|
|
12816
|
+
code: "provider_prerequisite_missing",
|
|
12817
|
+
status: "needs_attention",
|
|
12818
|
+
providerId,
|
|
12819
|
+
autoInstallSupported: providerStatus.autoInstallSupported,
|
|
12820
|
+
installReadiness: providerStatus.installReadiness,
|
|
12821
|
+
missingCommands: providerStatus.missingCommands,
|
|
12822
|
+
missingPrerequisites: providerStatus.missingPrerequisites,
|
|
12823
|
+
manualGuideKeys: providerStatus.manualGuideKeys,
|
|
12824
|
+
docUrl: providerStatus.docUrls.provider
|
|
12825
|
+
}
|
|
12826
|
+
]
|
|
12827
|
+
};
|
|
12828
|
+
}
|
|
12829
|
+
return {
|
|
12830
|
+
canContinue: false,
|
|
12831
|
+
checks: [
|
|
12832
|
+
{
|
|
12833
|
+
id: `provider:${providerId}`,
|
|
12834
|
+
code: "provider_cli_missing",
|
|
12835
|
+
status: "needs_attention",
|
|
12836
|
+
providerId,
|
|
12837
|
+
autoInstallSupported: providerStatus.autoInstallSupported,
|
|
12838
|
+
installReadiness: providerStatus.installReadiness,
|
|
12839
|
+
missingCommands: providerStatus.missingCommands,
|
|
12840
|
+
missingPrerequisites: providerStatus.missingPrerequisites,
|
|
12841
|
+
manualGuideKeys: providerStatus.manualGuideKeys,
|
|
12842
|
+
docUrl: providerStatus.docUrls.provider
|
|
12843
|
+
}
|
|
12844
|
+
]
|
|
12845
|
+
};
|
|
12846
|
+
}
|
|
12847
|
+
async function buildWorkspaceSelectionChecks(args, ctx) {
|
|
12848
|
+
if (args.workspacePath) {
|
|
12849
|
+
const workspaceResult = await resolveWorkspacePathCheck(args.workspacePath);
|
|
12850
|
+
return {
|
|
12851
|
+
canContinue: workspaceResult.canContinue,
|
|
12852
|
+
checks: workspaceResult.checks,
|
|
12853
|
+
workspacePath: args.workspacePath
|
|
12854
|
+
};
|
|
12855
|
+
}
|
|
12856
|
+
const workspace = args.workspaceId ? ctx.workspaceMgr.get(args.workspaceId) : void 0;
|
|
12857
|
+
if (!args.workspaceId) {
|
|
12858
|
+
return {
|
|
12859
|
+
canContinue: true,
|
|
12860
|
+
checks: []
|
|
12861
|
+
};
|
|
12862
|
+
}
|
|
12863
|
+
if (!workspace) {
|
|
12864
|
+
return {
|
|
12865
|
+
canContinue: false,
|
|
12866
|
+
checks: [
|
|
12867
|
+
{
|
|
12868
|
+
id: "session-workspace",
|
|
12869
|
+
code: "session_workspace_missing",
|
|
12870
|
+
status: "needs_attention",
|
|
12871
|
+
workspaceId: args.workspaceId
|
|
12872
|
+
}
|
|
12873
|
+
]
|
|
12874
|
+
};
|
|
12875
|
+
}
|
|
12876
|
+
const pathCheck = await resolveWorkspacePathCheck(workspace.path);
|
|
12877
|
+
return {
|
|
12878
|
+
canContinue: pathCheck.canContinue,
|
|
12879
|
+
checks: [
|
|
12880
|
+
{
|
|
12881
|
+
id: "session-workspace",
|
|
12882
|
+
code: "session_workspace_ready",
|
|
12883
|
+
status: "ready",
|
|
12884
|
+
workspaceId: workspace.id,
|
|
12885
|
+
workspacePath: workspace.path
|
|
12886
|
+
},
|
|
12887
|
+
...pathCheck.checks.map(
|
|
12888
|
+
(check) => check.id === "workspace-path" ? {
|
|
12889
|
+
...check,
|
|
12890
|
+
id: `workspace-path:${workspace.id}`
|
|
12891
|
+
} : check
|
|
12892
|
+
)
|
|
12893
|
+
],
|
|
12894
|
+
workspacePath: workspace.path
|
|
12895
|
+
};
|
|
12896
|
+
}
|
|
12897
|
+
async function buildAllProviderChecks(ctx, preferredProviderId) {
|
|
12898
|
+
const checks = [];
|
|
12899
|
+
let canContinueForPreferredProvider = preferredProviderId ? false : true;
|
|
12900
|
+
const runtimeStatus = await buildProviderRuntimeStatus(
|
|
12901
|
+
ctx.providerRegistry,
|
|
12902
|
+
ctx.providerRuntimeDeps
|
|
12903
|
+
);
|
|
12904
|
+
for (const provider of ctx.providerRegistry) {
|
|
12905
|
+
const providerStatus = runtimeStatus.providers[provider.id];
|
|
12906
|
+
if (!providerStatus) {
|
|
12907
|
+
checks.push({
|
|
12908
|
+
id: `provider:${provider.id}`,
|
|
12909
|
+
code: "provider_unknown",
|
|
12910
|
+
status: "needs_attention",
|
|
12911
|
+
providerId: provider.id
|
|
12912
|
+
});
|
|
12913
|
+
if (provider.id === preferredProviderId) {
|
|
12914
|
+
canContinueForPreferredProvider = false;
|
|
12915
|
+
}
|
|
12916
|
+
continue;
|
|
12917
|
+
}
|
|
12918
|
+
const providerCheck = buildProviderCheck(providerStatus, provider.id);
|
|
12919
|
+
checks.push(...providerCheck.checks);
|
|
12920
|
+
if (provider.id === preferredProviderId) {
|
|
12921
|
+
canContinueForPreferredProvider = providerCheck.canContinue;
|
|
12922
|
+
}
|
|
12923
|
+
}
|
|
12924
|
+
if (preferredProviderId && !ctx.providerRegistry.find((provider) => provider.id === preferredProviderId)) {
|
|
12925
|
+
checks.unshift({
|
|
12926
|
+
id: "session-provider",
|
|
12927
|
+
code: "provider_unknown",
|
|
12928
|
+
status: "needs_attention",
|
|
12929
|
+
providerId: preferredProviderId
|
|
12930
|
+
});
|
|
12931
|
+
canContinueForPreferredProvider = false;
|
|
12932
|
+
}
|
|
12933
|
+
return { checks, canContinueForPreferredProvider };
|
|
12934
|
+
}
|
|
12935
|
+
function buildServerAuthCheck(ctx) {
|
|
12936
|
+
return {
|
|
12937
|
+
id: "server-auth",
|
|
12938
|
+
code: ctx.config?.auth.enabled ? "server_auth_ready" : "server_auth_not_required",
|
|
12939
|
+
status: "ready"
|
|
12940
|
+
};
|
|
12941
|
+
}
|
|
12942
|
+
function buildMobileHostCheck(ctx) {
|
|
12943
|
+
if (isLoopbackHost(ctx.config?.host)) {
|
|
12944
|
+
return {
|
|
12945
|
+
canContinue: false,
|
|
12946
|
+
check: {
|
|
12947
|
+
id: "mobile-host",
|
|
12948
|
+
code: "mobile_host_local_only",
|
|
12949
|
+
status: "needs_attention"
|
|
12950
|
+
}
|
|
12951
|
+
};
|
|
12952
|
+
}
|
|
12953
|
+
return {
|
|
12954
|
+
canContinue: true,
|
|
12955
|
+
check: {
|
|
12956
|
+
id: "mobile-host",
|
|
12957
|
+
code: "mobile_host_ready",
|
|
12958
|
+
status: "ready"
|
|
12959
|
+
}
|
|
12960
|
+
};
|
|
12961
|
+
}
|
|
12962
|
+
async function buildSessionStartDiagnostics(args, ctx) {
|
|
12963
|
+
const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
|
|
12964
|
+
const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
|
|
12965
|
+
const mobileHost = buildMobileHostCheck(ctx);
|
|
12966
|
+
const checks = [
|
|
12967
|
+
...workspaceSelection.checks,
|
|
12968
|
+
...providerChecks.checks,
|
|
12969
|
+
buildServerAuthCheck(ctx),
|
|
12970
|
+
mobileHost.check
|
|
12971
|
+
];
|
|
12972
|
+
const canContinue = workspaceSelection.canContinue && providerChecks.canContinueForPreferredProvider;
|
|
12973
|
+
return {
|
|
12974
|
+
context: "session_start",
|
|
12975
|
+
canContinue,
|
|
12976
|
+
checks,
|
|
12977
|
+
metadata: {
|
|
12978
|
+
providerId: args.providerId,
|
|
12979
|
+
workspaceId: args.workspaceId,
|
|
12980
|
+
workspacePath: workspaceSelection.workspacePath,
|
|
12981
|
+
authEnabled: ctx.config?.auth.enabled ?? false,
|
|
12982
|
+
host: ctx.config?.host
|
|
12983
|
+
}
|
|
12984
|
+
};
|
|
12985
|
+
}
|
|
12986
|
+
async function buildManualDiagnostics(args, ctx) {
|
|
12987
|
+
const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
|
|
12988
|
+
const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
|
|
12989
|
+
const mobileHost = buildMobileHostCheck(ctx);
|
|
12990
|
+
const checks = [
|
|
12991
|
+
...workspaceSelection.checks,
|
|
12992
|
+
...providerChecks.checks,
|
|
12993
|
+
buildServerAuthCheck(ctx),
|
|
12994
|
+
mobileHost.check
|
|
12995
|
+
];
|
|
12996
|
+
return {
|
|
12997
|
+
context: "manual_check",
|
|
12998
|
+
canContinue: checks.every((check) => check.status !== "needs_attention"),
|
|
12999
|
+
checks,
|
|
13000
|
+
metadata: {
|
|
13001
|
+
authEnabled: ctx.config?.auth.enabled ?? false,
|
|
13002
|
+
host: ctx.config?.host,
|
|
13003
|
+
providerId: args.providerId,
|
|
13004
|
+
workspaceId: args.workspaceId,
|
|
13005
|
+
workspacePath: workspaceSelection.workspacePath ?? args.workspacePath
|
|
13006
|
+
}
|
|
13007
|
+
};
|
|
13008
|
+
}
|
|
13009
|
+
async function buildMobileDiagnostics(args, ctx) {
|
|
13010
|
+
const host = ctx.config?.host;
|
|
13011
|
+
const authEnabled = ctx.config?.auth.enabled ?? false;
|
|
13012
|
+
const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
|
|
13013
|
+
const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
|
|
13014
|
+
const mobileHost = buildMobileHostCheck(ctx);
|
|
13015
|
+
const checks = [
|
|
13016
|
+
...workspaceSelection.checks,
|
|
13017
|
+
...providerChecks.checks,
|
|
13018
|
+
buildServerAuthCheck(ctx),
|
|
13019
|
+
mobileHost.check
|
|
13020
|
+
];
|
|
13021
|
+
let canContinue = mobileHost.canContinue;
|
|
13022
|
+
if (!authEnabled) {
|
|
13023
|
+
canContinue = false;
|
|
13024
|
+
checks.push({
|
|
13025
|
+
id: "mobile-auth",
|
|
13026
|
+
code: "mobile_auth_disabled",
|
|
13027
|
+
status: "needs_attention"
|
|
13028
|
+
});
|
|
13029
|
+
} else {
|
|
13030
|
+
checks.push({
|
|
13031
|
+
id: "mobile-auth",
|
|
13032
|
+
code: "server_auth_ready",
|
|
13033
|
+
status: "ready"
|
|
13034
|
+
});
|
|
13035
|
+
}
|
|
13036
|
+
return {
|
|
13037
|
+
context: "mobile_continue",
|
|
13038
|
+
canContinue,
|
|
13039
|
+
checks,
|
|
13040
|
+
metadata: {
|
|
13041
|
+
authEnabled,
|
|
13042
|
+
host,
|
|
13043
|
+
workspaceId: args.workspaceId,
|
|
13044
|
+
workspacePath: workspaceSelection.workspacePath,
|
|
13045
|
+
providerId: args.providerId
|
|
13046
|
+
}
|
|
13047
|
+
};
|
|
13048
|
+
}
|
|
13049
|
+
async function buildDiagnostics(args, ctx) {
|
|
13050
|
+
switch (args.context) {
|
|
13051
|
+
case "workspace_open": {
|
|
13052
|
+
const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
|
|
13053
|
+
const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
|
|
13054
|
+
const mobileHost = buildMobileHostCheck(ctx);
|
|
13055
|
+
return {
|
|
13056
|
+
context: "workspace_open",
|
|
13057
|
+
canContinue: workspaceSelection.canContinue,
|
|
13058
|
+
checks: [
|
|
13059
|
+
...workspaceSelection.checks,
|
|
13060
|
+
...providerChecks.checks,
|
|
13061
|
+
buildServerAuthCheck(ctx),
|
|
13062
|
+
mobileHost.check
|
|
13063
|
+
],
|
|
13064
|
+
metadata: {
|
|
13065
|
+
workspacePath: workspaceSelection.workspacePath ?? args.workspacePath,
|
|
13066
|
+
authEnabled: ctx.config?.auth.enabled ?? false,
|
|
13067
|
+
host: ctx.config?.host,
|
|
13068
|
+
providerId: args.providerId,
|
|
13069
|
+
workspaceId: args.workspaceId
|
|
13070
|
+
}
|
|
13071
|
+
};
|
|
13072
|
+
}
|
|
13073
|
+
case "session_start":
|
|
13074
|
+
return buildSessionStartDiagnostics(args, ctx);
|
|
13075
|
+
case "mobile_continue":
|
|
13076
|
+
return buildMobileDiagnostics(args, ctx);
|
|
13077
|
+
case "manual_check":
|
|
13078
|
+
return buildManualDiagnostics(args, ctx);
|
|
13079
|
+
}
|
|
13080
|
+
}
|
|
13081
|
+
var DiagnosticsRequestSchema;
|
|
13082
|
+
var init_diagnostics2 = __esm({
|
|
13083
|
+
"packages/server/src/commands/diagnostics.ts"() {
|
|
13084
|
+
"use strict";
|
|
13085
|
+
init_runtime_status();
|
|
13086
|
+
init_validator();
|
|
13087
|
+
init_dispatch();
|
|
13088
|
+
DiagnosticsRequestSchema = z14.object({
|
|
13089
|
+
context: z14.enum(["workspace_open", "session_start", "mobile_continue", "manual_check"]),
|
|
13090
|
+
workspaceId: z14.string().optional(),
|
|
13091
|
+
workspacePath: z14.string().optional(),
|
|
13092
|
+
providerId: z14.string().optional()
|
|
13093
|
+
});
|
|
13094
|
+
registerCommand("diagnostics.get", DiagnosticsRequestSchema, async (args, ctx) => {
|
|
13095
|
+
return buildDiagnostics(args, ctx);
|
|
13096
|
+
});
|
|
13097
|
+
registerCommand("diagnostics.recheck", DiagnosticsRequestSchema, async (args, ctx) => {
|
|
13098
|
+
return buildDiagnostics(args, ctx);
|
|
13099
|
+
});
|
|
13100
|
+
}
|
|
13101
|
+
});
|
|
13102
|
+
|
|
13103
|
+
// packages/server/src/commands/provider.ts
|
|
13104
|
+
import { z as z15 } from "zod";
|
|
12161
13105
|
var init_provider = __esm({
|
|
12162
13106
|
"packages/server/src/commands/provider.ts"() {
|
|
12163
13107
|
"use strict";
|
|
12164
13108
|
init_runtime_status();
|
|
12165
13109
|
init_dispatch();
|
|
12166
|
-
registerCommand("provider.runtimeStatus",
|
|
13110
|
+
registerCommand("provider.runtimeStatus", z15.object({}), async (_args, ctx) => {
|
|
12167
13111
|
return buildProviderRuntimeStatus(ctx.providerRegistry, ctx.providerRuntimeDeps);
|
|
12168
13112
|
});
|
|
12169
13113
|
registerCommand(
|
|
12170
13114
|
"provider.install.start",
|
|
12171
|
-
|
|
12172
|
-
providerId:
|
|
13115
|
+
z15.object({
|
|
13116
|
+
providerId: z15.string()
|
|
12173
13117
|
}),
|
|
12174
13118
|
async (args, ctx) => {
|
|
12175
13119
|
if (!ctx.providerInstallMgr) {
|
|
@@ -12183,8 +13127,8 @@ var init_provider = __esm({
|
|
|
12183
13127
|
);
|
|
12184
13128
|
registerCommand(
|
|
12185
13129
|
"provider.install.get",
|
|
12186
|
-
|
|
12187
|
-
jobId:
|
|
13130
|
+
z15.object({
|
|
13131
|
+
jobId: z15.string()
|
|
12188
13132
|
}),
|
|
12189
13133
|
async (args, ctx) => {
|
|
12190
13134
|
if (!ctx.providerInstallMgr) {
|
|
@@ -12207,35 +13151,35 @@ var init_provider = __esm({
|
|
|
12207
13151
|
});
|
|
12208
13152
|
|
|
12209
13153
|
// packages/server/src/commands/supervisor.ts
|
|
12210
|
-
import { z as
|
|
13154
|
+
import { z as z16 } from "zod";
|
|
12211
13155
|
var supervisorObjectiveSchema, createSupervisorSchema, updateSupervisorSchema, sessionIdSchema, supervisorIdSchema;
|
|
12212
13156
|
var init_supervisor2 = __esm({
|
|
12213
13157
|
"packages/server/src/commands/supervisor.ts"() {
|
|
12214
13158
|
"use strict";
|
|
12215
13159
|
init_dispatch();
|
|
12216
|
-
supervisorObjectiveSchema =
|
|
12217
|
-
createSupervisorSchema =
|
|
12218
|
-
sessionId:
|
|
12219
|
-
workspaceId:
|
|
13160
|
+
supervisorObjectiveSchema = z16.string().trim().min(1).max(4e3);
|
|
13161
|
+
createSupervisorSchema = z16.object({
|
|
13162
|
+
sessionId: z16.string(),
|
|
13163
|
+
workspaceId: z16.string(),
|
|
12220
13164
|
objective: supervisorObjectiveSchema,
|
|
12221
|
-
evaluatorProviderId:
|
|
12222
|
-
evaluatorModel:
|
|
12223
|
-
maxSupervisionCount:
|
|
12224
|
-
scheduledAt:
|
|
13165
|
+
evaluatorProviderId: z16.string(),
|
|
13166
|
+
evaluatorModel: z16.string().trim().min(1).max(200).optional(),
|
|
13167
|
+
maxSupervisionCount: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
13168
|
+
scheduledAt: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
|
|
12225
13169
|
}).strict();
|
|
12226
|
-
updateSupervisorSchema =
|
|
12227
|
-
id:
|
|
13170
|
+
updateSupervisorSchema = z16.object({
|
|
13171
|
+
id: z16.string(),
|
|
12228
13172
|
objective: supervisorObjectiveSchema.optional(),
|
|
12229
|
-
evaluatorProviderId:
|
|
12230
|
-
evaluatorModel:
|
|
12231
|
-
maxSupervisionCount:
|
|
12232
|
-
scheduledAt:
|
|
13173
|
+
evaluatorProviderId: z16.string().optional(),
|
|
13174
|
+
evaluatorModel: z16.string().trim().min(1).max(200).nullable().optional(),
|
|
13175
|
+
maxSupervisionCount: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
|
|
13176
|
+
scheduledAt: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable().optional()
|
|
12233
13177
|
}).strict().refine(
|
|
12234
13178
|
(input) => input.objective !== void 0 || input.evaluatorProviderId !== void 0 || input.evaluatorModel !== void 0 || input.maxSupervisionCount !== void 0 || input.scheduledAt !== void 0,
|
|
12235
13179
|
"at least one supervisor field is required"
|
|
12236
13180
|
);
|
|
12237
|
-
sessionIdSchema =
|
|
12238
|
-
supervisorIdSchema =
|
|
13181
|
+
sessionIdSchema = z16.object({ sessionId: z16.string() });
|
|
13182
|
+
supervisorIdSchema = z16.object({ id: z16.string() });
|
|
12239
13183
|
registerCommand("supervisor.create", createSupervisorSchema, async (args, ctx) => {
|
|
12240
13184
|
return {
|
|
12241
13185
|
supervisor: await ctx.supervisorMgr.create({
|
|
@@ -12419,7 +13363,7 @@ var init_worktree = __esm({
|
|
|
12419
13363
|
|
|
12420
13364
|
// packages/server/src/commands/worktree.ts
|
|
12421
13365
|
import path9 from "node:path";
|
|
12422
|
-
import { z as
|
|
13366
|
+
import { z as z17 } from "zod";
|
|
12423
13367
|
async function findRelatedWorkspaceIds(ctx, workspacePath) {
|
|
12424
13368
|
const targetCommonDir = await getGitCommonDirPath(workspacePath);
|
|
12425
13369
|
const relatedWorkspaceIds = await Promise.all(
|
|
@@ -12452,7 +13396,7 @@ var init_worktree2 = __esm({
|
|
|
12452
13396
|
init_worktree();
|
|
12453
13397
|
init_dispatch();
|
|
12454
13398
|
init_git_events();
|
|
12455
|
-
registerCommand("worktree.list",
|
|
13399
|
+
registerCommand("worktree.list", z17.object({ workspaceId: z17.string() }), async (args, ctx) => {
|
|
12456
13400
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
12457
13401
|
if (!workspace) {
|
|
12458
13402
|
throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
|
|
@@ -12461,7 +13405,7 @@ var init_worktree2 = __esm({
|
|
|
12461
13405
|
});
|
|
12462
13406
|
registerCommand(
|
|
12463
13407
|
"worktree.status",
|
|
12464
|
-
|
|
13408
|
+
z17.object({ workspaceId: z17.string(), worktreePath: z17.string() }),
|
|
12465
13409
|
async (args, ctx) => {
|
|
12466
13410
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
12467
13411
|
if (!workspace) {
|
|
@@ -12473,10 +13417,10 @@ var init_worktree2 = __esm({
|
|
|
12473
13417
|
);
|
|
12474
13418
|
registerCommand(
|
|
12475
13419
|
"worktree.diff",
|
|
12476
|
-
|
|
12477
|
-
workspaceId:
|
|
12478
|
-
worktreePath:
|
|
12479
|
-
staged:
|
|
13420
|
+
z17.object({
|
|
13421
|
+
workspaceId: z17.string(),
|
|
13422
|
+
worktreePath: z17.string(),
|
|
13423
|
+
staged: z17.boolean().optional().default(false)
|
|
12480
13424
|
}),
|
|
12481
13425
|
async (args, ctx) => {
|
|
12482
13426
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -12489,7 +13433,7 @@ var init_worktree2 = __esm({
|
|
|
12489
13433
|
);
|
|
12490
13434
|
registerCommand(
|
|
12491
13435
|
"worktree.tree",
|
|
12492
|
-
|
|
13436
|
+
z17.object({ workspaceId: z17.string(), worktreePath: z17.string() }),
|
|
12493
13437
|
async (args, ctx) => {
|
|
12494
13438
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
12495
13439
|
if (!workspace) {
|
|
@@ -12501,10 +13445,10 @@ var init_worktree2 = __esm({
|
|
|
12501
13445
|
);
|
|
12502
13446
|
registerCommand(
|
|
12503
13447
|
"worktree.create",
|
|
12504
|
-
|
|
12505
|
-
workspaceId:
|
|
12506
|
-
branch:
|
|
12507
|
-
path:
|
|
13448
|
+
z17.object({
|
|
13449
|
+
workspaceId: z17.string(),
|
|
13450
|
+
branch: z17.string(),
|
|
13451
|
+
path: z17.string()
|
|
12508
13452
|
}),
|
|
12509
13453
|
async (args, ctx) => {
|
|
12510
13454
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -12519,10 +13463,10 @@ var init_worktree2 = __esm({
|
|
|
12519
13463
|
);
|
|
12520
13464
|
registerCommand(
|
|
12521
13465
|
"worktree.remove",
|
|
12522
|
-
|
|
12523
|
-
workspaceId:
|
|
12524
|
-
worktreePath:
|
|
12525
|
-
force:
|
|
13466
|
+
z17.object({
|
|
13467
|
+
workspaceId: z17.string(),
|
|
13468
|
+
worktreePath: z17.string(),
|
|
13469
|
+
force: z17.boolean().optional().default(false)
|
|
12526
13470
|
}),
|
|
12527
13471
|
async (args, ctx) => {
|
|
12528
13472
|
const workspace = ctx.workspaceMgr.get(args.workspaceId);
|
|
@@ -12546,7 +13490,7 @@ var init_worktree2 = __esm({
|
|
|
12546
13490
|
});
|
|
12547
13491
|
|
|
12548
13492
|
// packages/server/src/commands/fencing.ts
|
|
12549
|
-
import { z as
|
|
13493
|
+
import { z as z18 } from "zod";
|
|
12550
13494
|
function createMockFencingRequest() {
|
|
12551
13495
|
return {
|
|
12552
13496
|
ip: "127.0.0.1",
|
|
@@ -12559,9 +13503,9 @@ var init_fencing2 = __esm({
|
|
|
12559
13503
|
init_dispatch();
|
|
12560
13504
|
registerCommand(
|
|
12561
13505
|
"fencing.request",
|
|
12562
|
-
|
|
12563
|
-
workspaceId:
|
|
12564
|
-
tabId:
|
|
13506
|
+
z18.object({
|
|
13507
|
+
workspaceId: z18.string(),
|
|
13508
|
+
tabId: z18.string()
|
|
12565
13509
|
}),
|
|
12566
13510
|
async (args, ctx, clientId) => {
|
|
12567
13511
|
return ctx.fencingMgr.requestControl(
|
|
@@ -12574,7 +13518,7 @@ var init_fencing2 = __esm({
|
|
|
12574
13518
|
);
|
|
12575
13519
|
registerCommand(
|
|
12576
13520
|
"fencing.heartbeat",
|
|
12577
|
-
|
|
13521
|
+
z18.object({ workspaceId: z18.string() }),
|
|
12578
13522
|
async (args, ctx, clientId) => {
|
|
12579
13523
|
const success = ctx.fencingMgr.heartbeat(args.workspaceId, clientId);
|
|
12580
13524
|
return { success };
|
|
@@ -12582,13 +13526,13 @@ var init_fencing2 = __esm({
|
|
|
12582
13526
|
);
|
|
12583
13527
|
registerCommand(
|
|
12584
13528
|
"fencing.release",
|
|
12585
|
-
|
|
13529
|
+
z18.object({ workspaceId: z18.string() }),
|
|
12586
13530
|
async (args, ctx, clientId) => {
|
|
12587
13531
|
ctx.fencingMgr.release(args.workspaceId, clientId);
|
|
12588
13532
|
return {};
|
|
12589
13533
|
}
|
|
12590
13534
|
);
|
|
12591
|
-
registerCommand("fencing.status",
|
|
13535
|
+
registerCommand("fencing.status", z18.object({ workspaceId: z18.string() }), async (args, ctx) => {
|
|
12592
13536
|
const controller = ctx.fencingMgr.getController(args.workspaceId);
|
|
12593
13537
|
const isUnresponsive = ctx.fencingMgr.isControllerUnresponsive(args.workspaceId);
|
|
12594
13538
|
return {
|
|
@@ -12599,9 +13543,9 @@ var init_fencing2 = __esm({
|
|
|
12599
13543
|
});
|
|
12600
13544
|
registerCommand(
|
|
12601
13545
|
"fencing.takeover",
|
|
12602
|
-
|
|
12603
|
-
workspaceId:
|
|
12604
|
-
tabId:
|
|
13546
|
+
z18.object({
|
|
13547
|
+
workspaceId: z18.string(),
|
|
13548
|
+
tabId: z18.string()
|
|
12605
13549
|
}),
|
|
12606
13550
|
async (args, ctx, clientId) => {
|
|
12607
13551
|
return ctx.fencingMgr.forceTakeover(
|
|
@@ -12628,6 +13572,7 @@ var init_commands = __esm({
|
|
|
12628
13572
|
init_file();
|
|
12629
13573
|
init_git2();
|
|
12630
13574
|
init_settings2();
|
|
13575
|
+
init_diagnostics2();
|
|
12631
13576
|
init_provider();
|
|
12632
13577
|
init_supervisor2();
|
|
12633
13578
|
init_worktree2();
|
|
@@ -12771,7 +13716,8 @@ async function createServer(configOverrides) {
|
|
|
12771
13716
|
autoFetch,
|
|
12772
13717
|
providerRuntimeDeps,
|
|
12773
13718
|
providerInstallMgr,
|
|
12774
|
-
activationMgr
|
|
13719
|
+
activationMgr,
|
|
13720
|
+
config
|
|
12775
13721
|
};
|
|
12776
13722
|
wsHub.setCommandContext(commandContext);
|
|
12777
13723
|
await app.listen({
|
|
@@ -13276,11 +14222,11 @@ function readCliConfig() {
|
|
|
13276
14222
|
|
|
13277
14223
|
// packages/cli/src/embed.ts
|
|
13278
14224
|
import { existsSync as existsSync8 } from "fs";
|
|
13279
|
-
import { dirname as dirname6, resolve as
|
|
14225
|
+
import { dirname as dirname6, resolve as resolve4 } from "path";
|
|
13280
14226
|
import { fileURLToPath } from "url";
|
|
13281
14227
|
var __filename = fileURLToPath(import.meta.url);
|
|
13282
14228
|
var __dirname = dirname6(__filename);
|
|
13283
|
-
var WEB_ASSETS_DIR =
|
|
14229
|
+
var WEB_ASSETS_DIR = resolve4(__dirname, "../web");
|
|
13284
14230
|
function getStaticAssetsDir() {
|
|
13285
14231
|
return WEB_ASSETS_DIR;
|
|
13286
14232
|
}
|