@spencer-kit/coder-studio 0.3.10 → 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/dist/esm/bin.mjs CHANGED
@@ -1018,7 +1018,14 @@ var init_image = __esm({
1018
1018
 
1019
1019
  // packages/server/src/fs/file-io.ts
1020
1020
  import { createHash } from "crypto";
1021
- import { readFile as fsReadFile, writeFile as fsWriteFile, mkdir, rm, stat } from "fs/promises";
1021
+ import {
1022
+ readFile as fsReadFile,
1023
+ rename as fsRename,
1024
+ writeFile as fsWriteFile,
1025
+ mkdir,
1026
+ rm,
1027
+ stat
1028
+ } from "fs/promises";
1022
1029
  import { dirname as dirname2, isAbsolute, relative, resolve as resolve2 } from "path";
1023
1030
  async function statSafe(path10) {
1024
1031
  try {
@@ -1052,6 +1059,27 @@ async function deleteEntry(rootPath, relPath) {
1052
1059
  }
1053
1060
  await rm(abs, { recursive: true });
1054
1061
  }
1062
+ async function renameEntry(rootPath, fromPath, toPath) {
1063
+ const fromAbs = resolveSafe(rootPath, fromPath);
1064
+ const toAbs = resolveSafe(rootPath, toPath);
1065
+ const source = await statSafe(fromAbs);
1066
+ const target = await statSafe(toAbs);
1067
+ const fromParent = dirname2(fromAbs);
1068
+ const toParent = dirname2(toAbs);
1069
+ if (!source) {
1070
+ throw { code: "not_found", message: "Source not found" };
1071
+ }
1072
+ if (fromParent !== toParent) {
1073
+ throw {
1074
+ code: "rename_across_directories_not_supported",
1075
+ message: "Rename must stay within the current directory"
1076
+ };
1077
+ }
1078
+ if (target) {
1079
+ throw { code: "already_exists", message: "Target already exists" };
1080
+ }
1081
+ await fsRename(fromAbs, toAbs);
1082
+ }
1055
1083
  function resolveSafe(root, relPath) {
1056
1084
  const absRoot = resolve2(root);
1057
1085
  const abs = resolve2(absRoot, relPath);
@@ -2032,12 +2060,12 @@ var init_auto_fetch = __esm({
2032
2060
  }
2033
2061
  acquireWorkspaceOperation(workspaceId) {
2034
2062
  const state = this.getOrCreateState(workspaceId);
2035
- return new Promise((resolve4) => {
2063
+ return new Promise((resolve5) => {
2036
2064
  const grant = () => {
2037
2065
  state.inFlight = true;
2038
2066
  state.nextFetchAt = void 0;
2039
2067
  let released = false;
2040
- resolve4(() => {
2068
+ resolve5(() => {
2041
2069
  if (released) {
2042
2070
  return;
2043
2071
  }
@@ -2065,7 +2093,7 @@ var init_auto_fetch = __esm({
2065
2093
  // packages/server/src/provider-runtime/command-runner.ts
2066
2094
  import { spawn } from "node:child_process";
2067
2095
  async function runCommandAsString(file, args, options) {
2068
- return new Promise((resolve4, reject) => {
2096
+ return new Promise((resolve5, reject) => {
2069
2097
  const child = spawn(file, args, {
2070
2098
  shell: shouldUseShellForCommand(file, process.platform),
2071
2099
  windowsHide: options?.windowsHide ?? true
@@ -2090,7 +2118,7 @@ async function runCommandAsString(file, args, options) {
2090
2118
  const stdout = Buffer.concat(stdoutChunks).toString("utf8");
2091
2119
  const stderr = Buffer.concat(stderrChunks).toString("utf8");
2092
2120
  if (code === 0) {
2093
- resolve4({ stdout, stderr });
2121
+ resolve5({ stdout, stderr });
2094
2122
  return;
2095
2123
  }
2096
2124
  reject(
@@ -2699,6 +2727,13 @@ ${details.stdout}`.toLowerCase();
2699
2727
  }
2700
2728
  });
2701
2729
 
2730
+ // packages/core/src/domain/diagnostics.ts
2731
+ var init_diagnostics = __esm({
2732
+ "packages/core/src/domain/diagnostics.ts"() {
2733
+ "use strict";
2734
+ }
2735
+ });
2736
+
2702
2737
  // packages/core/src/domain/events.ts
2703
2738
  var init_events = __esm({
2704
2739
  "packages/core/src/domain/events.ts"() {
@@ -2949,6 +2984,7 @@ var init_idle_heuristics2 = __esm({
2949
2984
  var init_src3 = __esm({
2950
2985
  "packages/core/src/index.ts"() {
2951
2986
  "use strict";
2987
+ init_diagnostics();
2952
2988
  init_events();
2953
2989
  init_mcp();
2954
2990
  init_provider_install();
@@ -5032,13 +5068,13 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
5032
5068
  return;
5033
5069
  }
5034
5070
  const arch = deps.arch ?? process.arch;
5035
- const resolve4 = deps.resolve ?? ((id) => require2.resolve(id));
5071
+ const resolve5 = deps.resolve ?? ((id) => require2.resolve(id));
5036
5072
  const fileExists = deps.existsSync ?? existsSync4;
5037
- const stat7 = deps.statSync ?? statSync;
5073
+ const stat8 = deps.statSync ?? statSync;
5038
5074
  const chmod = deps.chmodSync ?? chmodSync2;
5039
5075
  let packageJsonPath;
5040
5076
  try {
5041
- packageJsonPath = resolve4(NODE_PTY_PKG);
5077
+ packageJsonPath = resolve5(NODE_PTY_PKG);
5042
5078
  } catch {
5043
5079
  return;
5044
5080
  }
@@ -5052,7 +5088,7 @@ function ensureNodePtySpawnHelperExecutable(deps = {}) {
5052
5088
  if (!fileExists(helperPath)) {
5053
5089
  return;
5054
5090
  }
5055
- const currentMode = stat7(helperPath).mode;
5091
+ const currentMode = stat8(helperPath).mode;
5056
5092
  const executableMode = currentMode | 73;
5057
5093
  if (executableMode === currentMode) {
5058
5094
  return;
@@ -5103,7 +5139,7 @@ async function escalateKillWithPolling(pid, signal, options) {
5103
5139
  const startTime = Date.now();
5104
5140
  const deadline = startTime + timeoutMs;
5105
5141
  while (Date.now() < deadline) {
5106
- await new Promise((resolve4) => setTimeout(resolve4, pollIntervalMs));
5142
+ await new Promise((resolve5) => setTimeout(resolve5, pollIntervalMs));
5107
5143
  if (!isProcessAlive(pid)) {
5108
5144
  return true;
5109
5145
  }
@@ -5255,38 +5291,107 @@ var init_settings = __esm({
5255
5291
 
5256
5292
  // packages/server/src/supervisor/evaluator.ts
5257
5293
  import { spawn as spawn2 } from "node:child_process";
5258
- function buildPrompt(context) {
5294
+ function buildPrompt(context, mode) {
5295
+ if (mode === "decompose") {
5296
+ return [
5297
+ "You are an autonomous supervisor for a target-scoped software task.",
5298
+ "Your first job is to decompose the target into a supervision structure before evaluation begins.",
5299
+ "",
5300
+ "Return JSON only.",
5301
+ "No prose before or after the JSON.",
5302
+ "",
5303
+ "Decomposition policy:",
5304
+ "- Do not ask the user any questions.",
5305
+ "- Do not ask for clarification, confirmation, or approval.",
5306
+ "- Do not propose options for the user to choose from.",
5307
+ "- If information is incomplete, make the most conservative reasonable assumptions and decide the decomposition yourself.",
5308
+ "- Your job is to return the best useful decomposition now, not to begin a discussion or planning workflow.",
5309
+ "- Keep the user-visible target as the top-level supervision owner.",
5310
+ '- Choose "stage" by default.',
5311
+ '- Choose "subtarget" only when the work clearly breaks into independently deliverable and independently verifiable workstreams.',
5312
+ "- If the distinction is unclear, choose stage.",
5313
+ "- Produce 1 to 7 decomposition items.",
5314
+ "- Each item must be concrete, milestone-sized, and useful for subsequent evaluation.",
5315
+ "- Do not leave the structure empty.",
5316
+ "",
5317
+ "Item requirements:",
5318
+ '- Each item must include "id", "kind", "title", "objective", "deliverable", "acceptanceCriteria", and "status".',
5319
+ '- "kind" must match the selected decompositionMode: all "stage" or all "subtarget".',
5320
+ '- "acceptanceCriteria" must be a non-empty string array.',
5321
+ '- Use statuses "pending", "in_progress", or "done".',
5322
+ "- Usually mark the first active item as in_progress and the rest as pending.",
5323
+ "",
5324
+ "Output schema:",
5325
+ "{",
5326
+ ' "mode": "decompose",',
5327
+ ' "decompositionMode": "stage" | "subtarget",',
5328
+ ' "items": [',
5329
+ ' { "id": string, "kind": "stage" | "subtarget", "title": string, "objective": string, "deliverable": string, "acceptanceCriteria": string[], "status": "pending" | "in_progress" | "done" }',
5330
+ " ],",
5331
+ ' "activeItemId": optional string,',
5332
+ ' "progressSummary": optional brief summary',
5333
+ "}",
5334
+ "",
5335
+ "Current objective:",
5336
+ context.objective,
5337
+ "",
5338
+ "Current target memory:",
5339
+ JSON.stringify(context.targetMemory, null, 2),
5340
+ "",
5341
+ "Latest user input:",
5342
+ context.latestUserInput?.trim() || "(none)",
5343
+ "",
5344
+ "Current terminal snapshot:",
5345
+ context.terminalExcerpt || "(no output yet)"
5346
+ ].join("\n");
5347
+ }
5259
5348
  const lines = [
5260
5349
  "You are an autonomous supervisor for a target-scoped software task.",
5261
5350
  "Your job is to keep the agent moving toward the objective until the objective is complete.",
5262
5351
  "",
5263
5352
  "Return JSON only.",
5353
+ "No prose before or after the JSON.",
5264
5354
  "",
5265
5355
  "Decision policy:",
5266
- '- Prefer "continue" whenever there is a reasonable next action.',
5356
+ '- Prefer "continue" over "stop" whenever the objective is not yet verified complete and there is a concrete next action.',
5357
+ '- "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.',
5267
5358
  "- Do not ask the user to decide, clarify, or choose among implementation options.",
5359
+ "- 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.",
5360
+ "- If the agent asks a question or presents multiple options, choose the most conservative reasonable option yourself and direct the next action.",
5361
+ "- If multiple reasonable paths exist, pick one and move forward unless doing so would be unsafe or clearly unsupported.",
5268
5362
  "- When information is incomplete, choose a conservative next action based on the objective, target memory, latest user input, and terminal snapshot.",
5363
+ "- Do not treat the agent's claims, summaries, or self-reports as sufficient evidence of completion.",
5269
5364
  "- Stop only when the objective is complete, or when continuing would likely push the agent in an unsafe or clearly unsupported direction.",
5270
5365
  "",
5271
5366
  "Stage decision policy:",
5272
5367
  "- Use the target memory as the current supervision state.",
5273
- "- Base your decision on the objective, current plan, activeStepId, progressSummary, lastGuidance, stalledCount, latest user input, and terminal snapshot.",
5274
- "- Identify which plan step is currently active.",
5275
- "- Decide whether the active step is done, still in progress, blocked, or obsolete.",
5276
- "- If the active step is done, advance to the next useful step.",
5277
- "- If the active step is still in progress, give guidance that moves it forward.",
5368
+ "- Base your decision on the objective, current decompositionMode, items, activeItemId, progressSummary, lastGuidance, stalledCount, latest user input, and terminal snapshot.",
5369
+ "- Identify which decomposition item is currently active.",
5370
+ "- Keep the current active item unless there is evidence that it is done, blocked, or obsolete.",
5371
+ "- Decide whether the active item is done, still in progress, blocked, or obsolete based on observable evidence.",
5372
+ '- Treat statements like "done", "fixed", "implemented", or "should pass" as unverified unless supported by observable evidence.',
5373
+ '- Mark an item as "done" only when there is observable evidence that its deliverable or acceptanceCriteria were satisfied.',
5374
+ "- Prefer evidence from terminal output, test results, build results, explicit verification output, or other observable artifacts in the terminal snapshot.",
5375
+ "- If evidence is missing or ambiguous, keep the item in_progress and direct the agent to gather or produce the missing verification evidence.",
5376
+ "- If the current item appears nearly complete but is not yet verified, keep the same active item and direct targeted verification.",
5377
+ "- Advance to the next item only after the current item's deliverable or acceptanceCriteria are supported by observable evidence.",
5378
+ '- When advancing to the next item, mark the previous item as "done" and set activeItemId to the next item explicitly.',
5379
+ "- If the active item is blocked, give guidance that is most likely to unblock it.",
5380
+ "- If the active item is obsolete, explain the reason briefly and move to the next useful item.",
5278
5381
  "- If the agent appears stuck or repeated the same action, give a different concrete next action.",
5279
- "- If the plan is obsolete, update only the affected steps unless a full replacement is necessary.",
5382
+ "- Do not rewrite the decomposition structure during normal evaluation cycles.",
5280
5383
  "",
5281
5384
  "Allowed statuses:",
5282
- '- "continue": more work is needed; include "reason" and "guidance".',
5385
+ '- "continue": supervision should continue; include "reason" and "guidance".',
5283
5386
  '- "stop": supervision should stop; include "stopReason" and "reason".',
5284
5387
  "",
5285
5388
  "Allowed stop reasons:",
5286
5389
  '- "objective_complete"',
5287
5390
  '- "supervisor_uncertain"',
5288
5391
  "",
5289
- 'Use "objective_complete" only when the objective has been satisfied.',
5392
+ 'Use "objective_complete" only when there is evidence that the objective and relevant acceptanceCriteria have been satisfied.',
5393
+ "- Do not stop only because the agent says the work is complete or because code changes exist without verification evidence.",
5394
+ "- If completion looks plausible but remains unverified, continue and require targeted verification.",
5290
5395
  'Use "supervisor_uncertain" only as a last resort when no useful next action can be inferred and additional guidance would likely be misleading.',
5291
5396
  "",
5292
5397
  'Guidance requirements for "continue":',
@@ -5294,30 +5399,32 @@ function buildPrompt(context) {
5294
5399
  "- Focus on the highest-value step toward completing the objective.",
5295
5400
  "- Be specific enough for the supervised agent to act without asking the user.",
5296
5401
  "- Avoid generic reminders, encouragement, or restating the objective.",
5297
- "- If verification is needed, tell the agent exactly what to verify next.",
5402
+ "- If verification is needed, tell the agent exactly what command, file, behavior, or artifact to verify next.",
5298
5403
  "- If implementation is needed, point to the likely area, behavior, or file/module based on available evidence.",
5404
+ "- If the agent asked a question, answer it directly in the guidance and continue with a concrete next action.",
5299
5405
  "",
5300
- "Planning policy:",
5301
- "- If planGenerated is false, include a plan with 3 to 7 milestone-sized steps.",
5302
- "- If planGenerated is true, update progress incrementally.",
5303
- "- Do not rewrite the full plan unless the existing plan is clearly wrong or obsolete.",
5304
- "- Use stepUpdates to mark completed or active steps when the terminal snapshot shows progress.",
5305
- "- Keep activeStepId aligned with the next useful step.",
5406
+ "Evaluation policy:",
5407
+ "- Update progress incrementally against the existing decomposition.",
5408
+ "- Use itemUpdates to reflect evidence-backed status changes only.",
5409
+ "- Keep activeItemId on the current item by default.",
5410
+ "- Change activeItemId only when there is a clear reason to switch items.",
5411
+ "- If evidence is missing or ambiguous, prefer verification over further implementation.",
5306
5412
  "",
5307
5413
  "Output schema:",
5308
5414
  "For continue:",
5309
5415
  "{",
5416
+ ' "mode": "evaluate",',
5310
5417
  ' "status": "continue",',
5311
5418
  ' "reason": "brief explanation of why more work is needed",',
5312
5419
  ' "guidance": "specific next action for the supervised agent",',
5313
- ' "plan": optional array of plan steps,',
5314
- ' "activeStepId": optional step id,',
5420
+ ' "activeItemId": optional item id,',
5315
5421
  ' "progressSummary": optional brief progress summary,',
5316
- ' "stepUpdates": optional array of { "id": string, "status": "pending" | "in_progress" | "done" }',
5422
+ ' "itemUpdates": optional array of { "id": string, "status": "pending" | "in_progress" | "done" }',
5317
5423
  "}",
5318
5424
  "",
5319
5425
  "For stop:",
5320
5426
  "{",
5427
+ ' "mode": "evaluate",',
5321
5428
  ' "status": "stop",',
5322
5429
  ' "stopReason": "objective_complete" | "supervisor_uncertain",',
5323
5430
  ' "reason": "brief explanation"',
@@ -5341,7 +5448,7 @@ async function runCommand(command, timeoutMs, options = {}) {
5341
5448
  if (options.signal?.aborted) {
5342
5449
  throw createSupervisorEvalAbortedError();
5343
5450
  }
5344
- return await new Promise((resolve4, reject) => {
5451
+ return await new Promise((resolve5, reject) => {
5345
5452
  const child = spawn2(command.argv[0], command.argv.slice(1), {
5346
5453
  cwd: command.cwd,
5347
5454
  detached: process.platform !== "win32",
@@ -5371,7 +5478,7 @@ async function runCommand(command, timeoutMs, options = {}) {
5371
5478
  }
5372
5479
  settled = true;
5373
5480
  cleanup();
5374
- resolve4(value);
5481
+ resolve5(value);
5375
5482
  };
5376
5483
  const terminate = (error) => {
5377
5484
  if (terminationError) {
@@ -5402,7 +5509,10 @@ async function runCommand(command, timeoutMs, options = {}) {
5402
5509
  settleReject(terminationError);
5403
5510
  return;
5404
5511
  }
5405
- settleReject(error);
5512
+ settleReject({
5513
+ code: "supervisor_eval_failed",
5514
+ message: error instanceof Error ? error.message : "Evaluator process failed to start"
5515
+ });
5406
5516
  });
5407
5517
  child.on("exit", (code) => {
5408
5518
  if (terminationError) {
@@ -5580,7 +5690,7 @@ function extractSupervisorPayload(output2, providerId) {
5580
5690
  }
5581
5691
  throw new Error("Supervisor did not return a recognizable message");
5582
5692
  }
5583
- function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
5693
+ function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars, requestedMode) {
5584
5694
  let parsed;
5585
5695
  try {
5586
5696
  parsed = JSON.parse(stripCodeFence(payloadText));
@@ -5593,9 +5703,49 @@ function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
5593
5703
  throw new Error("Supervisor returned invalid evaluation payload");
5594
5704
  }
5595
5705
  const record = parsed;
5706
+ const payloadMode = record.mode;
5707
+ if (requestedMode === "decompose") {
5708
+ if (payloadMode !== "decompose") {
5709
+ throw new Error("Supervisor returned invalid decompose payload");
5710
+ }
5711
+ const decompositionMode = record.decompositionMode;
5712
+ if (decompositionMode !== "stage" && decompositionMode !== "subtarget") {
5713
+ throw new Error("Supervisor decompose result is missing a valid decompositionMode");
5714
+ }
5715
+ const items = Array.isArray(record.items) ? record.items.flatMap((value) => {
5716
+ if (!value || typeof value !== "object") {
5717
+ return [];
5718
+ }
5719
+ const item = value;
5720
+ 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") {
5721
+ return [];
5722
+ }
5723
+ return [
5724
+ {
5725
+ id: item.id,
5726
+ kind: item.kind,
5727
+ title: item.title,
5728
+ objective: item.objective,
5729
+ deliverable: item.deliverable,
5730
+ acceptanceCriteria: item.acceptanceCriteria,
5731
+ status: item.status
5732
+ }
5733
+ ];
5734
+ }) : [];
5735
+ if (items.length === 0) {
5736
+ throw new Error("Supervisor decompose result must include at least one valid item");
5737
+ }
5738
+ return {
5739
+ mode: "decompose",
5740
+ decompositionMode,
5741
+ items,
5742
+ activeItemId: typeof record.activeItemId === "string" && record.activeItemId.trim() ? record.activeItemId : void 0,
5743
+ progressSummary: typeof record.progressSummary === "string" && record.progressSummary.trim() ? record.progressSummary.trim() : void 0
5744
+ };
5745
+ }
5596
5746
  const status = record.status;
5597
5747
  const reason = record.reason;
5598
- if (status !== "continue" && status !== "stop" || typeof reason !== "string" || !reason.trim()) {
5748
+ if (payloadMode !== void 0 && payloadMode !== "evaluate" || status !== "continue" && status !== "stop" || typeof reason !== "string" || !reason.trim()) {
5599
5749
  throw new Error("Supervisor returned invalid evaluation payload");
5600
5750
  }
5601
5751
  if (status === "stop") {
@@ -5604,23 +5754,14 @@ function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
5604
5754
  throw new Error("Supervisor stop result is missing a valid stopReason");
5605
5755
  }
5606
5756
  return {
5757
+ mode: "evaluate",
5607
5758
  status,
5608
5759
  stopReason,
5609
5760
  reason: reason.trim()
5610
5761
  };
5611
5762
  }
5612
5763
  const guidance = typeof record.guidance === "string" && record.guidance.trim() ? record.guidance.trim().slice(0, guidanceMaxChars) : void 0;
5613
- const plan = Array.isArray(record.plan) ? record.plan.flatMap((value) => {
5614
- if (!value || typeof value !== "object") {
5615
- return [];
5616
- }
5617
- const step = value;
5618
- if (typeof step.id !== "string" || typeof step.title !== "string" || step.status !== "pending" && step.status !== "in_progress" && step.status !== "done") {
5619
- return [];
5620
- }
5621
- return [{ id: step.id, title: step.title, status: step.status }];
5622
- }) : void 0;
5623
- const stepUpdates = Array.isArray(record.stepUpdates) ? record.stepUpdates.flatMap((value) => {
5764
+ const itemUpdates = Array.isArray(record.itemUpdates) ? record.itemUpdates.flatMap((value) => {
5624
5765
  if (!value || typeof value !== "object") {
5625
5766
  return [];
5626
5767
  }
@@ -5631,13 +5772,13 @@ function parseSupervisorEvaluationResult(payloadText, guidanceMaxChars) {
5631
5772
  return [{ id: update.id, status: update.status }];
5632
5773
  }) : void 0;
5633
5774
  return {
5775
+ mode: "evaluate",
5634
5776
  status,
5635
5777
  reason: reason.trim(),
5636
5778
  guidance,
5637
- plan,
5638
- activeStepId: typeof record.activeStepId === "string" && record.activeStepId.trim() ? record.activeStepId : void 0,
5779
+ activeItemId: typeof record.activeItemId === "string" && record.activeItemId.trim() ? record.activeItemId : void 0,
5639
5780
  progressSummary: typeof record.progressSummary === "string" && record.progressSummary.trim() ? record.progressSummary.trim() : void 0,
5640
- stepUpdates
5781
+ itemUpdates
5641
5782
  };
5642
5783
  }
5643
5784
  var NOOP_LOGGER2, SupervisorEvaluator;
@@ -5689,7 +5830,8 @@ var init_evaluator = __esm({
5689
5830
  provider,
5690
5831
  this.deps.providerConfigRepo.get(provider.id)
5691
5832
  );
5692
- const prompt = buildPrompt(context);
5833
+ const mode = options.mode ?? "evaluate";
5834
+ const prompt = buildPrompt(context, mode);
5693
5835
  const command = provider.buildSupervisorEvalCommand(config, {
5694
5836
  prompt,
5695
5837
  sessionId: supervisor.sessionId,
@@ -5723,7 +5865,7 @@ var init_evaluator = __esm({
5723
5865
  );
5724
5866
  throw error;
5725
5867
  }
5726
- return parseSupervisorEvaluationResult(payloadText, this.config.guidanceMaxChars);
5868
+ return parseSupervisorEvaluationResult(payloadText, this.config.guidanceMaxChars, mode);
5727
5869
  }
5728
5870
  };
5729
5871
  }
@@ -5894,12 +6036,12 @@ var init_scheduler = __esm({
5894
6036
 
5895
6037
  // packages/server/src/supervisor/manager.ts
5896
6038
  function createDeferredCompletion() {
5897
- let resolve4 = () => {
6039
+ let resolve5 = () => {
5898
6040
  };
5899
6041
  const promise = new Promise((innerResolve) => {
5900
- resolve4 = innerResolve;
6042
+ resolve5 = innerResolve;
5901
6043
  });
5902
- return { promise, resolve: resolve4 };
6044
+ return { promise, resolve: resolve5 };
5903
6045
  }
5904
6046
  function generateSupervisorId() {
5905
6047
  return `sup_${Date.now()}_${Math.random().toString(36).slice(2, 9)}`;
@@ -5925,6 +6067,12 @@ function messageOf(error, fallback) {
5925
6067
  function logFailure(logger, error, context, message) {
5926
6068
  logger.error({ ...context, err: error }, message);
5927
6069
  }
6070
+ function isDecomposeResult(result) {
6071
+ return result.mode === "decompose";
6072
+ }
6073
+ function isEvaluateStopResult(result) {
6074
+ return "status" in result && result.status === "stop";
6075
+ }
5928
6076
  function isSupervisorEvalAborted(error) {
5929
6077
  return !!error && typeof error === "object" && error.code === "supervisor_eval_aborted";
5930
6078
  }
@@ -6428,7 +6576,12 @@ var init_manager2 = __esm({
6428
6576
  turnId: context.lastTurnId,
6429
6577
  createdAt: Date.now()
6430
6578
  });
6431
- this.broadcastCycle(evaluatingSupervisor, activeCycle, "created");
6579
+ this.broadcastCycle(evaluatingSupervisor, activeCycle, "created", {
6580
+ phase: "waiting_evaluator",
6581
+ currentAttemptIndex: 0,
6582
+ attemptCount: 1,
6583
+ maxAttempts: 1 + retrySettings.retryMaxCount
6584
+ });
6432
6585
  return {
6433
6586
  cycle: activeCycle,
6434
6587
  supervisor: hydratedSupervisor,
@@ -6626,6 +6779,8 @@ var init_manager2 = __esm({
6626
6779
  }
6627
6780
  async executeCycleWithRetry(started, signal) {
6628
6781
  const supervisor = started.supervisor;
6782
+ let context = started.context;
6783
+ let currentMemory = context.targetMemory;
6629
6784
  for (let attemptIndex = 0; ; attemptIndex += 1) {
6630
6785
  const attempt = this.deps.cycleAttemptRepo.create({
6631
6786
  id: generateAttemptId(),
@@ -6634,23 +6789,79 @@ var init_manager2 = __esm({
6634
6789
  status: "evaluating",
6635
6790
  startedAt: Date.now()
6636
6791
  });
6792
+ this.broadcastCycle(started.supervisor, started.cycle, "updated", {
6793
+ phase: "waiting_evaluator",
6794
+ currentAttemptIndex: attemptIndex,
6795
+ attemptCount: attemptIndex + 1,
6796
+ maxAttempts: 1 + started.retry.retryMaxCount
6797
+ });
6637
6798
  try {
6638
- const evaluation = await this.evaluator.evaluate(supervisor, started.context, { signal });
6799
+ if (!currentMemory.decompositionGenerated || currentMemory.items.length === 0) {
6800
+ const decomposition = await this.evaluator.evaluate(supervisor, context, {
6801
+ signal,
6802
+ mode: "decompose"
6803
+ });
6804
+ if (!isDecomposeResult(decomposition)) {
6805
+ throw new Error("Supervisor decompose pass did not return a decomposition result");
6806
+ }
6807
+ currentMemory = {
6808
+ ...currentMemory,
6809
+ decompositionGenerated: true,
6810
+ decompositionMode: decomposition.decompositionMode,
6811
+ items: decomposition.items,
6812
+ activeItemId: decomposition.activeItemId,
6813
+ progressSummary: decomposition.progressSummary ?? currentMemory.progressSummary,
6814
+ updatedAt: Date.now()
6815
+ };
6816
+ const workspace = this.requireWorkspace(context.workspaceId);
6817
+ await this.deps.targetStore.saveTargetMemory(
6818
+ workspace.path,
6819
+ started.targetId,
6820
+ currentMemory
6821
+ );
6822
+ const currentSupervisor2 = this.supervisors.get(supervisor.id) ?? this.requireSupervisor(supervisor.id);
6823
+ if (currentSupervisor2.targetId === started.targetId) {
6824
+ const refreshed = this.attachCycles({
6825
+ ...currentSupervisor2,
6826
+ currentTargetMemory: currentMemory
6827
+ });
6828
+ this.storeSnapshot(refreshed);
6829
+ }
6830
+ context = {
6831
+ ...context,
6832
+ targetMemory: currentMemory
6833
+ };
6834
+ }
6835
+ const evaluation = await this.evaluator.evaluate(supervisor, context, {
6836
+ signal,
6837
+ mode: "evaluate"
6838
+ });
6639
6839
  this.deps.cycleAttemptRepo.update(attempt.id, {
6640
6840
  status: "completed",
6641
6841
  completedAt: Date.now(),
6642
6842
  providerModel: supervisor.evaluatorModel ?? null
6643
6843
  });
6644
- if (evaluation.status === "stop") {
6844
+ if (isDecomposeResult(evaluation)) {
6845
+ throw new Error("Supervisor evaluate pass returned a decompose result");
6846
+ }
6847
+ const nextTargetMemory = this.applyEvaluationToTargetMemory(
6848
+ currentMemory,
6849
+ evaluation,
6850
+ void 0,
6851
+ Date.now()
6852
+ );
6853
+ if (isEvaluateStopResult(evaluation)) {
6645
6854
  return {
6646
6855
  evaluation,
6647
- injected: false
6856
+ injected: false,
6857
+ targetMemory: nextTargetMemory
6648
6858
  };
6649
6859
  }
6650
6860
  if (!evaluation.guidance?.trim()) {
6651
6861
  return {
6652
6862
  evaluation,
6653
- injected: false
6863
+ injected: false,
6864
+ targetMemory: nextTargetMemory
6654
6865
  };
6655
6866
  }
6656
6867
  if (signal?.aborted || this.pendingPauses.has(supervisor.id)) {
@@ -6660,7 +6871,8 @@ var init_manager2 = __esm({
6660
6871
  if (currentSupervisor.targetId !== started.targetId) {
6661
6872
  return {
6662
6873
  evaluation,
6663
- injected: false
6874
+ injected: false,
6875
+ targetMemory: nextTargetMemory
6664
6876
  };
6665
6877
  }
6666
6878
  const injectingSupervisor = this.attachCycles(
@@ -6673,6 +6885,12 @@ var init_manager2 = __esm({
6673
6885
  );
6674
6886
  this.storeSnapshot(injectingSupervisor);
6675
6887
  this.broadcastState(injectingSupervisor, "state_changed");
6888
+ this.broadcastCycle(injectingSupervisor, started.cycle, "updated", {
6889
+ phase: "injecting",
6890
+ currentAttemptIndex: attemptIndex,
6891
+ attemptCount: attemptIndex + 1,
6892
+ maxAttempts: 1 + started.retry.retryMaxCount
6893
+ });
6676
6894
  const recentCycles = this.deps.cycleRepo.listRecentForSupervisor(supervisor.id, this.config.guidanceDedupeWindow + 1).filter((cycle) => cycle.id !== started.cycle.id);
6677
6895
  const injection = await this.injector.inject(
6678
6896
  injectingSupervisor,
@@ -6685,7 +6903,13 @@ var init_manager2 = __esm({
6685
6903
  return {
6686
6904
  evaluation,
6687
6905
  injected: injection.injected,
6688
- injectedText: injection.injected ? injection.text : void 0
6906
+ injectedText: injection.injected ? injection.text : void 0,
6907
+ targetMemory: this.applyEvaluationToTargetMemory(
6908
+ currentMemory,
6909
+ evaluation,
6910
+ injection.injected ? injection.text : void 0,
6911
+ Date.now()
6912
+ )
6689
6913
  };
6690
6914
  } catch (error) {
6691
6915
  if (isSupervisorEvalAborted(error)) {
@@ -6706,6 +6930,15 @@ var init_manager2 = __esm({
6706
6930
  if (!this.shouldRetryAttempt(error, attemptIndex, started.retry)) {
6707
6931
  throw error;
6708
6932
  }
6933
+ const nextRetryAt = Date.now() + started.retry.retryDelayMs;
6934
+ this.broadcastCycle(supervisor, started.cycle, "updated", {
6935
+ phase: "retry_wait",
6936
+ currentAttemptIndex: attemptIndex,
6937
+ attemptCount: attemptIndex + 1,
6938
+ maxAttempts: 1 + started.retry.retryMaxCount,
6939
+ lastAttemptError: reason,
6940
+ nextRetryAt
6941
+ });
6709
6942
  await this.sleep(started.retry.retryDelayMs, signal);
6710
6943
  const evaluatingSupervisor = this.attachCycles(
6711
6944
  this.withCurrentTargetState(
@@ -6723,9 +6956,9 @@ var init_manager2 = __esm({
6723
6956
  async finalizeSuccessfulCycle(activeCycle, context, result, targetId) {
6724
6957
  const workspace = this.requireWorkspace(context.workspaceId);
6725
6958
  const currentSupervisor = this.supervisors.get(activeCycle.supervisorId) ?? this.requireSupervisor(activeCycle.supervisorId);
6726
- const targetMemory = targetId === currentSupervisor.targetId && currentSupervisor.currentTargetMemory ? currentSupervisor.currentTargetMemory : await this.deps.targetStore.loadTargetMemory(workspace.path, targetId);
6959
+ const evaluation = result.evaluation;
6727
6960
  const finalStatus = result.injected ? "injected" : "completed";
6728
- const cycleReason = result.evaluation.status === "stop" ? result.evaluation.reason : result.injected ? result.injectedText : result.evaluation.guidance ? `Skipped duplicate: ${result.evaluation.guidance}` : void 0;
6961
+ const cycleReason = isEvaluateStopResult(evaluation) ? evaluation.reason : result.injected ? result.injectedText : evaluation.guidance ? `Skipped duplicate: ${evaluation.guidance}` : void 0;
6729
6962
  const finishedCycle = this.deps.cycleRepo.update(activeCycle.id, {
6730
6963
  status: finalStatus,
6731
6964
  result: cycleReason ?? null,
@@ -6733,24 +6966,22 @@ var init_manager2 = __esm({
6733
6966
  errorReason: null,
6734
6967
  completedAt: Date.now()
6735
6968
  });
6736
- const nextTargetMemory = this.applyEvaluationToTargetMemory(
6737
- targetMemory,
6738
- result.evaluation,
6739
- result.injectedText,
6740
- finishedCycle.completedAt ?? Date.now()
6741
- );
6969
+ const nextTargetMemory = {
6970
+ ...result.targetMemory,
6971
+ updatedAt: finishedCycle.completedAt ?? Date.now()
6972
+ };
6742
6973
  await this.deps.targetStore.saveTargetMemory(workspace.path, targetId, nextTargetMemory);
6743
- const cycleRecord = result.evaluation.status === "stop" ? {
6974
+ const cycleRecord = isEvaluateStopResult(evaluation) ? {
6744
6975
  cycleId: activeCycle.id,
6745
6976
  targetId,
6746
6977
  startedAt: activeCycle.createdAt,
6747
6978
  completedAt: finishedCycle.completedAt ?? Date.now(),
6748
6979
  result: "stop",
6749
- stopReason: result.evaluation.stopReason,
6750
- reason: result.evaluation.reason,
6751
- progressSummary: result.evaluation.progressSummary ?? nextTargetMemory.progressSummary,
6752
- activeStepId: result.evaluation.activeStepId ?? nextTargetMemory.activeStepId,
6753
- stepUpdates: result.evaluation.stepUpdates,
6980
+ stopReason: evaluation.stopReason,
6981
+ reason: evaluation.reason,
6982
+ progressSummary: nextTargetMemory.progressSummary,
6983
+ decompositionMode: nextTargetMemory.decompositionMode,
6984
+ activeItemId: nextTargetMemory.activeItemId,
6754
6985
  injected: false,
6755
6986
  attemptCount: this.deps.cycleAttemptRepo.listForCycle(activeCycle.id).length
6756
6987
  } : {
@@ -6759,18 +6990,19 @@ var init_manager2 = __esm({
6759
6990
  startedAt: activeCycle.createdAt,
6760
6991
  completedAt: finishedCycle.completedAt ?? Date.now(),
6761
6992
  result: "continue",
6762
- reason: result.evaluation.reason,
6763
- guidance: result.injected ? result.injectedText : result.evaluation.guidance,
6993
+ reason: evaluation.reason,
6994
+ guidance: result.injected ? result.injectedText : evaluation.guidance,
6764
6995
  progressSummary: nextTargetMemory.progressSummary,
6765
- activeStepId: nextTargetMemory.activeStepId,
6766
- stepUpdates: result.evaluation.stepUpdates,
6996
+ decompositionMode: nextTargetMemory.decompositionMode,
6997
+ activeItemId: nextTargetMemory.activeItemId,
6998
+ itemUpdates: evaluation.itemUpdates,
6767
6999
  injected: result.injected,
6768
7000
  attemptCount: this.deps.cycleAttemptRepo.listForCycle(activeCycle.id).length
6769
7001
  };
6770
7002
  await this.deps.targetStore.appendTargetCycleRecord(workspace.path, targetId, cycleRecord);
6771
- if (result.evaluation.status === "stop") {
7003
+ if (isEvaluateStopResult(evaluation)) {
6772
7004
  await this.updateTargetMetaStatus(workspace.path, targetId, {
6773
- status: result.evaluation.stopReason === "objective_complete" ? "completed" : "cancelled",
7005
+ status: evaluation.stopReason === "objective_complete" ? "completed" : "cancelled",
6774
7006
  completedAt: finishedCycle.completedAt ?? Date.now()
6775
7007
  });
6776
7008
  }
@@ -6787,9 +7019,9 @@ var init_manager2 = __esm({
6787
7019
  const finishedSupervisor = this.attachCycles(
6788
7020
  this.withCurrentTargetState(
6789
7021
  this.deps.supervisorRepo.update(activeCycle.supervisorId, {
6790
- state: result.evaluation.status === "stop" ? "stopped" : "idle",
7022
+ state: isEvaluateStopResult(result.evaluation) ? "stopped" : "idle",
6791
7023
  completedSupervisionCount: (this.supervisors.get(activeCycle.supervisorId)?.completedSupervisionCount ?? 0) + 1,
6792
- stopReason: result.evaluation.status === "stop" ? result.evaluation.stopReason : null,
7024
+ stopReason: isEvaluateStopResult(evaluation) ? evaluation.stopReason : null,
6793
7025
  lastCycleAt: finishedCycle.completedAt,
6794
7026
  lastEvaluatedTurnId: context.lastTurnId ?? void 0,
6795
7027
  errorReason: null,
@@ -6943,23 +7175,46 @@ var init_manager2 = __esm({
6943
7175
  };
6944
7176
  }
6945
7177
  applyEvaluationToTargetMemory(memory, evaluation, injectedText, updatedAt) {
6946
- let plan = memory.plan;
6947
- if (evaluation.plan && evaluation.plan.length > 0) {
6948
- plan = evaluation.plan;
6949
- } else if (evaluation.stepUpdates?.length) {
6950
- const updates = new Map(evaluation.stepUpdates.map((step) => [step.id, step.status]));
6951
- plan = memory.plan.map(
6952
- (step) => updates.has(step.id) ? { ...step, status: updates.get(step.id) } : step
7178
+ if (isDecomposeResult(evaluation)) {
7179
+ return {
7180
+ ...memory,
7181
+ decompositionGenerated: true,
7182
+ decompositionMode: evaluation.decompositionMode,
7183
+ items: evaluation.items,
7184
+ activeItemId: evaluation.activeItemId,
7185
+ progressSummary: evaluation.progressSummary ?? memory.progressSummary,
7186
+ updatedAt
7187
+ };
7188
+ }
7189
+ if (isEvaluateStopResult(evaluation)) {
7190
+ return {
7191
+ ...memory,
7192
+ decompositionGenerated: memory.decompositionGenerated,
7193
+ decompositionMode: memory.decompositionMode,
7194
+ items: memory.items,
7195
+ activeItemId: memory.activeItemId,
7196
+ progressSummary: memory.progressSummary,
7197
+ lastGuidance: memory.lastGuidance,
7198
+ stalledCount: 0,
7199
+ updatedAt
7200
+ };
7201
+ }
7202
+ let items = memory.items;
7203
+ if (evaluation.itemUpdates?.length) {
7204
+ const updates = new Map(evaluation.itemUpdates.map((item) => [item.id, item.status]));
7205
+ items = memory.items.map(
7206
+ (item) => updates.has(item.id) ? { ...item, status: updates.get(item.id) } : item
6953
7207
  );
6954
7208
  }
6955
7209
  const progressSummary = evaluation.progressSummary ?? memory.progressSummary;
6956
- const lastGuidance = evaluation.status === "continue" ? injectedText ?? evaluation.guidance ?? memory.lastGuidance : memory.lastGuidance;
6957
- const stalledCount = evaluation.status === "continue" && !evaluation.progressSummary && !evaluation.stepUpdates?.length ? memory.stalledCount + 1 : 0;
7210
+ const lastGuidance = injectedText ?? evaluation.guidance ?? memory.lastGuidance;
7211
+ const stalledCount = !evaluation.progressSummary && !evaluation.itemUpdates?.length ? memory.stalledCount + 1 : 0;
6958
7212
  return {
6959
7213
  ...memory,
6960
- planGenerated: memory.planGenerated || Boolean(evaluation.plan?.length),
6961
- plan,
6962
- activeStepId: evaluation.activeStepId ?? memory.activeStepId,
7214
+ decompositionGenerated: memory.decompositionGenerated,
7215
+ decompositionMode: memory.decompositionMode,
7216
+ items,
7217
+ activeItemId: evaluation.activeItemId ?? memory.activeItemId,
6963
7218
  progressSummary,
6964
7219
  lastGuidance,
6965
7220
  stalledCount,
@@ -7082,10 +7337,10 @@ var init_manager2 = __esm({
7082
7337
  { supervisor, event }
7083
7338
  );
7084
7339
  }
7085
- broadcastCycle(supervisor, cycle, event) {
7340
+ broadcastCycle(supervisor, cycle, event, runtime) {
7086
7341
  this.deps.broadcaster.broadcast(
7087
7342
  Topics.supervisorCycle(supervisor.workspaceId, supervisor.sessionId),
7088
- { cycle, event }
7343
+ { cycle: runtime ? { ...cycle, runtime } : cycle, event }
7089
7344
  );
7090
7345
  }
7091
7346
  shouldRetryAttempt(error, attemptIndex, retry) {
@@ -7111,10 +7366,10 @@ var init_manager2 = __esm({
7111
7366
  if (signal?.aborted) {
7112
7367
  throw { code: "supervisor_eval_aborted", message: "Supervisor evaluator aborted" };
7113
7368
  }
7114
- await new Promise((resolve4, reject) => {
7369
+ await new Promise((resolve5, reject) => {
7115
7370
  const timer = setTimeout(() => {
7116
7371
  signal?.removeEventListener("abort", onAbort);
7117
- resolve4();
7372
+ resolve5();
7118
7373
  }, delayMs);
7119
7374
  timer.unref?.();
7120
7375
  const onAbort = () => {
@@ -7182,6 +7437,119 @@ function errorMessage(error, fallback) {
7182
7437
  }
7183
7438
  return fallback;
7184
7439
  }
7440
+ function isRecord(value) {
7441
+ return Boolean(value) && typeof value === "object";
7442
+ }
7443
+ function readNonEmptyString(value) {
7444
+ if (typeof value !== "string") {
7445
+ return void 0;
7446
+ }
7447
+ const next = value.trim();
7448
+ return next ? next : void 0;
7449
+ }
7450
+ function readStatus(value) {
7451
+ return value === "in_progress" || value === "done" || value === "pending" ? value : "pending";
7452
+ }
7453
+ function readDecompositionMode(value) {
7454
+ return value === "stage" || value === "subtarget" ? value : void 0;
7455
+ }
7456
+ function readNonNegativeInteger(value, fallback) {
7457
+ if (!Number.isSafeInteger(value) || typeof value !== "number" || value < 0) {
7458
+ return fallback;
7459
+ }
7460
+ return value;
7461
+ }
7462
+ function readTimestamp(value, fallback) {
7463
+ if (!Number.isSafeInteger(value) || typeof value !== "number") {
7464
+ return fallback;
7465
+ }
7466
+ return value;
7467
+ }
7468
+ function fallbackAcceptanceCriteria(title) {
7469
+ return [`${title} is complete`];
7470
+ }
7471
+ function normalizeItem(value, fallbackKind) {
7472
+ if (!isRecord(value)) {
7473
+ return null;
7474
+ }
7475
+ const id = readNonEmptyString(value.id);
7476
+ const title = readNonEmptyString(value.title);
7477
+ if (!id || !title) {
7478
+ return null;
7479
+ }
7480
+ const kind = readDecompositionMode(value.kind) ?? fallbackKind ?? "stage";
7481
+ const objective = readNonEmptyString(value.objective) ?? title;
7482
+ const deliverable = readNonEmptyString(value.deliverable) ?? `${title} completed`;
7483
+ const acceptanceCriteria = Array.isArray(value.acceptanceCriteria) ? value.acceptanceCriteria.flatMap((entry) => {
7484
+ const next = readNonEmptyString(entry);
7485
+ return next ? [next] : [];
7486
+ }) : [];
7487
+ return {
7488
+ id,
7489
+ kind,
7490
+ title,
7491
+ objective,
7492
+ deliverable,
7493
+ acceptanceCriteria: acceptanceCriteria.length > 0 ? acceptanceCriteria : fallbackAcceptanceCriteria(title),
7494
+ status: readStatus(value.status)
7495
+ };
7496
+ }
7497
+ function normalizeLegacyPlanItems(plan) {
7498
+ if (!Array.isArray(plan)) {
7499
+ return [];
7500
+ }
7501
+ return plan.flatMap((value) => {
7502
+ const item = normalizeItem(
7503
+ isRecord(value) ? {
7504
+ id: value.id,
7505
+ kind: "stage",
7506
+ title: value.title,
7507
+ objective: value.title,
7508
+ deliverable: `${readNonEmptyString(value.title) ?? "Legacy step"} completed`,
7509
+ acceptanceCriteria: fallbackAcceptanceCriteria(
7510
+ readNonEmptyString(value.title) ?? "Legacy step"
7511
+ ),
7512
+ status: value.status
7513
+ } : value,
7514
+ "stage"
7515
+ );
7516
+ return item ? [item] : [];
7517
+ });
7518
+ }
7519
+ function resolveActiveItemId(items, candidate) {
7520
+ const next = readNonEmptyString(candidate);
7521
+ if (next && items.some((item) => item.id === next)) {
7522
+ return next;
7523
+ }
7524
+ return items.find((item) => item.status === "in_progress")?.id ?? items.find((item) => item.status === "pending")?.id ?? items[0]?.id;
7525
+ }
7526
+ function normalizeTargetMemory(raw, targetId) {
7527
+ if (!isRecord(raw)) {
7528
+ return buildTargetMemory(targetId, 0);
7529
+ }
7530
+ const updatedAt = readTimestamp(raw.updatedAt, 0);
7531
+ const declaredMode = readDecompositionMode(raw.decompositionMode);
7532
+ let items = Array.isArray(raw.items) ? raw.items.flatMap((value) => {
7533
+ const item = normalizeItem(value, declaredMode);
7534
+ return item ? [item] : [];
7535
+ }) : [];
7536
+ let decompositionMode = declaredMode ?? items[0]?.kind;
7537
+ if (items.length === 0) {
7538
+ items = normalizeLegacyPlanItems(raw.plan);
7539
+ decompositionMode = items.length > 0 ? "stage" : void 0;
7540
+ }
7541
+ return {
7542
+ targetId: readNonEmptyString(raw.targetId) ?? targetId,
7543
+ decompositionGenerated: items.length > 0,
7544
+ decompositionMode,
7545
+ items,
7546
+ activeItemId: resolveActiveItemId(items, raw.activeItemId ?? raw.activeStepId),
7547
+ progressSummary: readNonEmptyString(raw.progressSummary),
7548
+ lastGuidance: readNonEmptyString(raw.lastGuidance),
7549
+ stalledCount: readNonNegativeInteger(raw.stalledCount, 0),
7550
+ updatedAt
7551
+ };
7552
+ }
7185
7553
  async function writeJsonIfMissing(path10, value) {
7186
7554
  try {
7187
7555
  await writeFile3(path10, JSON.stringify(value, null, 2) + "\n", {
@@ -7210,8 +7578,12 @@ function buildTargetMeta(input2) {
7210
7578
  function buildTargetMemory(targetId, createdAt) {
7211
7579
  return {
7212
7580
  targetId,
7213
- planGenerated: false,
7214
- plan: [],
7581
+ decompositionGenerated: false,
7582
+ decompositionMode: void 0,
7583
+ items: [],
7584
+ activeItemId: void 0,
7585
+ progressSummary: void 0,
7586
+ lastGuidance: void 0,
7215
7587
  stalledCount: 0,
7216
7588
  updatedAt: createdAt
7217
7589
  };
@@ -7300,8 +7672,9 @@ async function readTargetMeta(workspacePath, targetId) {
7300
7672
  );
7301
7673
  }
7302
7674
  async function loadTargetMemory(workspacePath, targetId) {
7303
- return JSON.parse(
7304
- await readFile2(memoryPath(workspacePath, targetId), "utf-8")
7675
+ return normalizeTargetMemory(
7676
+ JSON.parse(await readFile2(memoryPath(workspacePath, targetId), "utf-8")),
7677
+ targetId
7305
7678
  );
7306
7679
  }
7307
7680
  async function saveTargetMemory(workspacePath, targetId, memory) {
@@ -7638,8 +8011,8 @@ var init_terminal_snapshot_buffer = __esm({
7638
8011
  if (this.pendingWriteCount === 0) {
7639
8012
  return Promise.resolve();
7640
8013
  }
7641
- return new Promise((resolve4) => {
7642
- this.drainResolvers.push(resolve4);
8014
+ return new Promise((resolve5) => {
8015
+ this.drainResolvers.push(resolve5);
7643
8016
  });
7644
8017
  }
7645
8018
  resolveDrainIfIdle() {
@@ -7648,8 +8021,8 @@ var init_terminal_snapshot_buffer = __esm({
7648
8021
  }
7649
8022
  const resolvers = this.drainResolvers;
7650
8023
  this.drainResolvers = [];
7651
- for (const resolve4 of resolvers) {
7652
- resolve4();
8024
+ for (const resolve5 of resolvers) {
8025
+ resolve5();
7653
8026
  }
7654
8027
  }
7655
8028
  requireTerminal() {
@@ -7968,10 +8341,10 @@ var init_manager3 = __esm({
7968
8341
  }
7969
8342
  return existing.promise;
7970
8343
  }
7971
- let resolve4 = () => {
8344
+ let resolve5 = () => {
7972
8345
  };
7973
8346
  const promise = new Promise((innerResolve) => {
7974
- resolve4 = innerResolve;
8347
+ resolve5 = innerResolve;
7975
8348
  });
7976
8349
  let markKillCompleted = () => {
7977
8350
  };
@@ -7984,7 +8357,7 @@ var init_manager3 = __esm({
7984
8357
  markKillCompleted,
7985
8358
  finalized: false,
7986
8359
  promise,
7987
- resolve: resolve4
8360
+ resolve: resolve5
7988
8361
  });
7989
8362
  void terminal.pty.kill(signal).finally(() => {
7990
8363
  const waiter = this.explicitCloseWaiters.get(terminalId);
@@ -8257,11 +8630,11 @@ var init_watcher = __esm({
8257
8630
  this.pendingReason = "fs_change";
8258
8631
  }
8259
8632
  const elapsed = now - this.firstDirtyTime;
8260
- const delay = Math.min(this.DEBOUNCE_MS, Math.max(0, this.MAX_WAIT_MS - elapsed));
8633
+ const delay2 = Math.min(this.DEBOUNCE_MS, Math.max(0, this.MAX_WAIT_MS - elapsed));
8261
8634
  if (this.dirtyTimer) {
8262
8635
  clearTimeout(this.dirtyTimer);
8263
8636
  }
8264
- this.dirtyTimer = setTimeout(() => this.flushDirty(), delay);
8637
+ this.dirtyTimer = setTimeout(() => this.flushDirty(), delay2);
8265
8638
  }
8266
8639
  flushDirty() {
8267
8640
  this.broadcaster?.broadcast(Topics.workspaceFsDirty(this.workspaceId), {
@@ -8859,7 +9232,8 @@ var init_fencing = __esm({
8859
9232
  });
8860
9233
 
8861
9234
  // packages/server/src/commands/terminal.ts
8862
- import { basename } from "node:path";
9235
+ import { stat as stat6 } from "node:fs/promises";
9236
+ import { basename, isAbsolute as isAbsolute3 } from "node:path";
8863
9237
  import { z as z5 } from "zod";
8864
9238
  function decodeTerminalInput(args) {
8865
9239
  if ("bytes" in args) {
@@ -8930,6 +9304,7 @@ var init_terminal = __esm({
8930
9304
  "packages/server/src/commands/terminal.ts"() {
8931
9305
  "use strict";
8932
9306
  init_src3();
9307
+ init_file_io();
8933
9308
  init_dispatch();
8934
9309
  TerminalInputActivitySchema = z5.enum(TERMINAL_INPUT_ACTIVITIES).optional();
8935
9310
  TerminalInputSchema = z5.union([
@@ -8964,20 +9339,44 @@ var init_terminal = __esm({
8964
9339
  z5.object({
8965
9340
  workspaceId: z5.string(),
8966
9341
  cols: z5.number().int().positive().optional(),
8967
- rows: z5.number().int().positive().optional()
9342
+ rows: z5.number().int().positive().optional(),
9343
+ cwdPath: z5.string().optional()
8968
9344
  }),
8969
9345
  async (args, ctx) => {
8970
9346
  const workspace = ctx.workspaceMgr.get(args.workspaceId);
8971
9347
  if (!workspace) {
8972
9348
  throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
8973
9349
  }
9350
+ let cwd = workspace.path;
9351
+ if (args.cwdPath && args.cwdPath !== ".") {
9352
+ if (isAbsolute3(args.cwdPath)) {
9353
+ throw { code: "invalid_cwd_path", message: "cwdPath must be workspace-relative" };
9354
+ }
9355
+ let resolvedCwd;
9356
+ try {
9357
+ resolvedCwd = resolveSafe(workspace.path, args.cwdPath);
9358
+ } catch (error) {
9359
+ if (typeof error === "object" && error !== null && "code" in error && error.code === "path_escape") {
9360
+ throw { code: "invalid_cwd_path", message: "cwdPath must be workspace-relative" };
9361
+ }
9362
+ throw error;
9363
+ }
9364
+ const cwdStats = await stat6(resolvedCwd).catch(() => null);
9365
+ if (!cwdStats) {
9366
+ throw { code: "cwd_not_found", message: `Directory not found: ${args.cwdPath}` };
9367
+ }
9368
+ if (!cwdStats.isDirectory()) {
9369
+ throw { code: "cwd_not_directory", message: `Not a directory: ${args.cwdPath}` };
9370
+ }
9371
+ cwd = resolvedCwd;
9372
+ }
8974
9373
  const shell = resolveShellCommand();
8975
9374
  const terminal = ctx.terminalMgr.create({
8976
9375
  workspaceId: args.workspaceId,
8977
9376
  kind: "shell",
8978
9377
  argv: shell.argv,
8979
9378
  title: shell.title,
8980
- cwd: workspace.path,
9379
+ cwd,
8981
9380
  cols: args.cols ?? 120,
8982
9381
  rows: args.rows ?? 30
8983
9382
  });
@@ -9663,7 +10062,7 @@ var init_hub = __esm({
9663
10062
  }
9664
10063
  }
9665
10064
  awaitBinaryPayload(clientId) {
9666
- return new Promise((resolve4, reject) => {
10065
+ return new Promise((resolve5, reject) => {
9667
10066
  const timer = setTimeout(() => {
9668
10067
  const waiters = this.pendingBinaryWaiters.get(clientId);
9669
10068
  if (!waiters) return;
@@ -9675,7 +10074,7 @@ var init_hub = __esm({
9675
10074
  }
9676
10075
  reject(new Error("Timeout waiting for terminal input binary payload"));
9677
10076
  }, BINARY_PAYLOAD_TIMEOUT_MS);
9678
- const waiter = { resolve: resolve4, reject, timer };
10077
+ const waiter = { resolve: resolve5, reject, timer };
9679
10078
  const queue = this.pendingBinaryWaiters.get(clientId);
9680
10079
  if (queue) {
9681
10080
  queue.push(waiter);
@@ -9953,10 +10352,34 @@ var init_hub = __esm({
9953
10352
  });
9954
10353
 
9955
10354
  // packages/server/src/commands/workspace.ts
9956
- import { readdir as readdir2 } from "node:fs/promises";
10355
+ import { readdir as readdir2, realpath as realpath2 } from "node:fs/promises";
9957
10356
  import { homedir as homedir2 } from "node:os";
9958
- import { join as join6 } from "node:path";
10357
+ import { isAbsolute as isAbsolute4, join as join6, resolve as resolve3 } from "node:path";
9959
10358
  import { z as z6 } from "zod";
10359
+ function resolveBrowsePath(path10) {
10360
+ const home = homedir2();
10361
+ if (!path10 || path10 === "~") {
10362
+ return home;
10363
+ }
10364
+ if (path10.startsWith("~/")) {
10365
+ return join6(home, path10.slice(2));
10366
+ }
10367
+ return isAbsolute4(path10) ? path10 : resolve3(home, path10);
10368
+ }
10369
+ async function buildRootPaths(currentPath) {
10370
+ const roots = /* @__PURE__ */ new Set(["/"]);
10371
+ const home = homedir2();
10372
+ roots.add(home);
10373
+ try {
10374
+ roots.add(await realpath2(home));
10375
+ } catch {
10376
+ }
10377
+ const currentSegments = currentPath.split("/").filter(Boolean);
10378
+ if (currentSegments.length > 0) {
10379
+ roots.add(`/${currentSegments[0]}`);
10380
+ }
10381
+ return Array.from(roots);
10382
+ }
9960
10383
  var init_workspace = __esm({
9961
10384
  "packages/server/src/commands/workspace.ts"() {
9962
10385
  "use strict";
@@ -9970,7 +10393,7 @@ var init_workspace = __esm({
9970
10393
  path: z6.string().optional()
9971
10394
  }),
9972
10395
  async (args) => {
9973
- const basePath = args.path || homedir2();
10396
+ const basePath = resolveBrowsePath(args.path);
9974
10397
  const entries = await readdir2(basePath, { withFileTypes: true });
9975
10398
  const directories = entries.filter((entry) => entry.isDirectory()).map((entry) => ({
9976
10399
  name: entry.name,
@@ -9979,7 +10402,8 @@ var init_workspace = __esm({
9979
10402
  return {
9980
10403
  currentPath: basePath,
9981
10404
  parentPath: basePath !== "/" ? join6(basePath, "..") : null,
9982
- directories
10405
+ directories,
10406
+ rootPaths: await buildRootPaths(basePath)
9983
10407
  };
9984
10408
  }
9985
10409
  );
@@ -10276,16 +10700,105 @@ var init_runtime_status = __esm({
10276
10700
  }
10277
10701
  });
10278
10702
 
10703
+ // packages/server/src/workspace/pane-layout.ts
10704
+ function applyPaneDisposition(layout, sessionId, disposition) {
10705
+ if (!layout) {
10706
+ return layout;
10707
+ }
10708
+ return disposition === "remove" ? removePaneBySessionId(layout, sessionId) : closePaneBySessionId(layout, sessionId);
10709
+ }
10710
+ function closePaneBySessionId(node, sessionId) {
10711
+ return replaceSessionWithDraft(node, sessionId);
10712
+ }
10713
+ function replaceSessionWithDraft(node, sessionId) {
10714
+ if (node.type === "leaf") {
10715
+ if (node.sessionId === sessionId) {
10716
+ return {
10717
+ id: node.id,
10718
+ type: "leaf"
10719
+ };
10720
+ }
10721
+ return node;
10722
+ }
10723
+ const children = node.children ?? [];
10724
+ let changed = false;
10725
+ const nextChildren = children.map((child) => {
10726
+ const nextChild = replaceSessionWithDraft(child, sessionId);
10727
+ if (nextChild !== child) {
10728
+ changed = true;
10729
+ }
10730
+ return nextChild;
10731
+ });
10732
+ if (!changed) {
10733
+ return node;
10734
+ }
10735
+ return {
10736
+ ...node,
10737
+ children: nextChildren
10738
+ };
10739
+ }
10740
+ function removePaneBySessionId(node, sessionId) {
10741
+ return removeSessionPane(node, sessionId) ?? { id: node.id, type: "leaf" };
10742
+ }
10743
+ function removeSessionPane(node, sessionId) {
10744
+ if (node.type === "leaf") {
10745
+ if (node.sessionId === sessionId) {
10746
+ return null;
10747
+ }
10748
+ return node;
10749
+ }
10750
+ const children = node.children ?? [];
10751
+ let changed = false;
10752
+ const nextChildren = [];
10753
+ for (const child of children) {
10754
+ const nextChild = removeSessionPane(child, sessionId);
10755
+ if (nextChild !== child) {
10756
+ changed = true;
10757
+ }
10758
+ if (nextChild !== null) {
10759
+ nextChildren.push(nextChild);
10760
+ }
10761
+ }
10762
+ if (!changed) {
10763
+ return node;
10764
+ }
10765
+ if (nextChildren.length === 1) {
10766
+ return nextChildren[0];
10767
+ }
10768
+ if (nextChildren.length === 0) {
10769
+ return null;
10770
+ }
10771
+ return {
10772
+ ...node,
10773
+ children: nextChildren
10774
+ };
10775
+ }
10776
+ var init_pane_layout = __esm({
10777
+ "packages/server/src/workspace/pane-layout.ts"() {
10778
+ "use strict";
10779
+ }
10780
+ });
10781
+
10279
10782
  // packages/server/src/commands/session.ts
10280
10783
  import { z as z10 } from "zod";
10784
+ function delay(ms) {
10785
+ return new Promise((resolve5) => {
10786
+ setTimeout(resolve5, ms);
10787
+ });
10788
+ }
10281
10789
  function getProviderFromRegistry(providerId, registry) {
10282
10790
  return registry.find((provider) => provider.id === providerId);
10283
10791
  }
10792
+ var SESSION_CLOSE_POLL_INTERVAL_MS, SESSION_CLOSE_TIMEOUT_MS;
10284
10793
  var init_session = __esm({
10285
10794
  "packages/server/src/commands/session.ts"() {
10286
10795
  "use strict";
10287
10796
  init_runtime_status();
10797
+ init_database();
10798
+ init_pane_layout();
10288
10799
  init_dispatch();
10800
+ SESSION_CLOSE_POLL_INTERVAL_MS = 100;
10801
+ SESSION_CLOSE_TIMEOUT_MS = 5e3;
10289
10802
  registerCommand(
10290
10803
  "session.list",
10291
10804
  z10.object({
@@ -10357,11 +10870,75 @@ var init_session = __esm({
10357
10870
  ctx.sessionMgr.delete(args.sessionId);
10358
10871
  }
10359
10872
  );
10873
+ registerCommand(
10874
+ "session.close",
10875
+ z10.object({
10876
+ sessionId: z10.string(),
10877
+ paneDisposition: z10.enum(["draft", "remove"]).default("draft")
10878
+ }),
10879
+ async (args, ctx) => {
10880
+ let session = ctx.sessionMgr.get(args.sessionId);
10881
+ if (!session) {
10882
+ throw { code: "session_not_found", message: `Session not found: ${args.sessionId}` };
10883
+ }
10884
+ if (session.state !== "ended") {
10885
+ try {
10886
+ await ctx.sessionMgr.stop(args.sessionId);
10887
+ } catch (error) {
10888
+ const candidate = error;
10889
+ throw {
10890
+ code: "session_close_failed",
10891
+ message: candidate.message ?? `Failed to stop session: ${args.sessionId}`
10892
+ };
10893
+ }
10894
+ const deadline = Date.now() + SESSION_CLOSE_TIMEOUT_MS;
10895
+ while (Date.now() < deadline) {
10896
+ session = ctx.sessionMgr.get(args.sessionId);
10897
+ if (!session) {
10898
+ return;
10899
+ }
10900
+ if (session.state === "ended") {
10901
+ break;
10902
+ }
10903
+ await delay(SESSION_CLOSE_POLL_INTERVAL_MS);
10904
+ }
10905
+ session = ctx.sessionMgr.get(args.sessionId);
10906
+ if (!session) {
10907
+ return;
10908
+ }
10909
+ if (session.state !== "ended") {
10910
+ throw {
10911
+ code: "session_close_timeout",
10912
+ message: `Timed out waiting for session to end before closing: ${args.sessionId}`
10913
+ };
10914
+ }
10915
+ }
10916
+ const workspace = ctx.workspaceMgr.get(session.workspaceId);
10917
+ if (!workspace) {
10918
+ throw {
10919
+ code: "workspace_not_found",
10920
+ message: `Workspace not found: ${session.workspaceId}`
10921
+ };
10922
+ }
10923
+ const nextUiState = {
10924
+ ...workspace.uiState,
10925
+ paneLayout: applyPaneDisposition(
10926
+ workspace.uiState.paneLayout,
10927
+ args.sessionId,
10928
+ args.paneDisposition
10929
+ )
10930
+ };
10931
+ withTransaction(ctx.db, () => {
10932
+ ctx.workspaceMgr.updateUiState(session.workspaceId, nextUiState);
10933
+ ctx.sessionMgr.delete(args.sessionId);
10934
+ });
10935
+ }
10936
+ );
10360
10937
  }
10361
10938
  });
10362
10939
 
10363
10940
  // packages/server/src/fs/tree.ts
10364
- import { readdir as readdir3, stat as stat6 } from "fs/promises";
10941
+ import { readdir as readdir3, stat as stat7 } from "fs/promises";
10365
10942
  import { join as join7, relative as relative4 } from "path";
10366
10943
  async function readTree(rootPath, subdir) {
10367
10944
  const targetPath = subdir ? join7(rootPath, subdir) : rootPath;
@@ -10383,7 +10960,7 @@ async function readTree(rootPath, subdir) {
10383
10960
  // Not loaded yet - client will request on expand
10384
10961
  });
10385
10962
  } else if (entry.isFile()) {
10386
- const stats = await stat6(fullPath);
10963
+ const stats = await stat7(fullPath);
10387
10964
  nodes.push({
10388
10965
  name: entry.name,
10389
10966
  path: relPath,
@@ -10452,7 +11029,7 @@ async function searchFiles(rootPath, query, limit = 10) {
10452
11029
  }
10453
11030
  return a.path.toLowerCase().localeCompare(b.path.toLowerCase());
10454
11031
  }).slice(0, limit)) {
10455
- const stats = await stat6(match.fullPath);
11032
+ const stats = await stat7(match.fullPath);
10456
11033
  files.push({
10457
11034
  name: match.name,
10458
11035
  path: match.path,
@@ -10619,6 +11196,27 @@ var init_file = __esm({
10619
11196
  return { ok: true };
10620
11197
  }
10621
11198
  );
11199
+ registerCommand(
11200
+ "file.rename",
11201
+ z11.object({
11202
+ workspaceId: z11.string(),
11203
+ fromPath: z11.string(),
11204
+ toPath: z11.string()
11205
+ }),
11206
+ async (args, ctx) => {
11207
+ const workspace = ctx.workspaceMgr.get(args.workspaceId);
11208
+ if (!workspace) {
11209
+ throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
11210
+ }
11211
+ await renameEntry(workspace.path, args.fromPath, args.toPath);
11212
+ ctx.eventBus.emit({
11213
+ type: "fs.dirty",
11214
+ workspaceId: args.workspaceId,
11215
+ reason: "fs_change"
11216
+ });
11217
+ return { ok: true };
11218
+ }
11219
+ );
10622
11220
  registerCommand(
10623
11221
  "file.write",
10624
11222
  z11.object({
@@ -10800,7 +11398,7 @@ import { mkdir as mkdir4, mkdtemp as mkdtemp2, rm as rm5, writeFile as writeFile
10800
11398
  import os2 from "os";
10801
11399
  import path6 from "path";
10802
11400
  async function runGit(cwd, args, options = {}) {
10803
- return new Promise((resolve4, reject) => {
11401
+ return new Promise((resolve5, reject) => {
10804
11402
  const gitArgs = [
10805
11403
  ...options.config?.flatMap(([key, value]) => ["-c", `${key}=${value}`]) ?? [],
10806
11404
  ...args
@@ -10827,7 +11425,7 @@ async function runGit(cwd, args, options = {}) {
10827
11425
  if (err) {
10828
11426
  reject(new GitError(err.message, stderr));
10829
11427
  } else {
10830
- resolve4({ stdout, stderr });
11428
+ resolve5({ stdout, stderr });
10831
11429
  }
10832
11430
  }
10833
11431
  );
@@ -12171,20 +12769,373 @@ var init_settings2 = __esm({
12171
12769
  }
12172
12770
  });
12173
12771
 
12174
- // packages/server/src/commands/provider.ts
12772
+ // packages/server/src/commands/diagnostics.ts
12175
12773
  import { z as z14 } from "zod";
12774
+ function isLoopbackHost(host) {
12775
+ return host === void 0 || host === "localhost" || host === "127.0.0.1" || host === "::1" || host === "0.0.0.0";
12776
+ }
12777
+ async function resolveWorkspacePathCheck(workspacePath) {
12778
+ if (!workspacePath) {
12779
+ return {
12780
+ canContinue: false,
12781
+ checks: [
12782
+ {
12783
+ id: "workspace-selection",
12784
+ code: "workspace_selection_missing",
12785
+ status: "needs_attention"
12786
+ }
12787
+ ]
12788
+ };
12789
+ }
12790
+ const validation = await validatePath(workspacePath);
12791
+ if (validation.valid) {
12792
+ return {
12793
+ canContinue: true,
12794
+ checks: [
12795
+ {
12796
+ id: "workspace-path",
12797
+ code: "workspace_path_ready",
12798
+ status: "ready",
12799
+ workspacePath
12800
+ }
12801
+ ]
12802
+ };
12803
+ }
12804
+ return {
12805
+ canContinue: false,
12806
+ checks: [
12807
+ {
12808
+ id: "workspace-path",
12809
+ code: validation.error === "Path does not exist" ? "workspace_path_not_found" : "workspace_path_unreadable",
12810
+ status: "needs_attention",
12811
+ workspacePath
12812
+ }
12813
+ ]
12814
+ };
12815
+ }
12816
+ function buildProviderCheck(providerStatus, providerId) {
12817
+ if (providerStatus.available) {
12818
+ return {
12819
+ canContinue: true,
12820
+ checks: [
12821
+ {
12822
+ id: `provider:${providerId}`,
12823
+ code: "provider_runtime_ready",
12824
+ status: "ready",
12825
+ providerId,
12826
+ autoInstallSupported: providerStatus.autoInstallSupported,
12827
+ installReadiness: providerStatus.installReadiness
12828
+ }
12829
+ ]
12830
+ };
12831
+ }
12832
+ if (providerStatus.missingPrerequisites.length > 0) {
12833
+ return {
12834
+ canContinue: false,
12835
+ checks: [
12836
+ {
12837
+ id: `provider:${providerId}`,
12838
+ code: "provider_prerequisite_missing",
12839
+ status: "needs_attention",
12840
+ providerId,
12841
+ autoInstallSupported: providerStatus.autoInstallSupported,
12842
+ installReadiness: providerStatus.installReadiness,
12843
+ missingCommands: providerStatus.missingCommands,
12844
+ missingPrerequisites: providerStatus.missingPrerequisites,
12845
+ manualGuideKeys: providerStatus.manualGuideKeys,
12846
+ docUrl: providerStatus.docUrls.provider
12847
+ }
12848
+ ]
12849
+ };
12850
+ }
12851
+ return {
12852
+ canContinue: false,
12853
+ checks: [
12854
+ {
12855
+ id: `provider:${providerId}`,
12856
+ code: "provider_cli_missing",
12857
+ status: "needs_attention",
12858
+ providerId,
12859
+ autoInstallSupported: providerStatus.autoInstallSupported,
12860
+ installReadiness: providerStatus.installReadiness,
12861
+ missingCommands: providerStatus.missingCommands,
12862
+ missingPrerequisites: providerStatus.missingPrerequisites,
12863
+ manualGuideKeys: providerStatus.manualGuideKeys,
12864
+ docUrl: providerStatus.docUrls.provider
12865
+ }
12866
+ ]
12867
+ };
12868
+ }
12869
+ async function buildWorkspaceSelectionChecks(args, ctx) {
12870
+ if (args.workspacePath) {
12871
+ const workspaceResult = await resolveWorkspacePathCheck(args.workspacePath);
12872
+ return {
12873
+ canContinue: workspaceResult.canContinue,
12874
+ checks: workspaceResult.checks,
12875
+ workspacePath: args.workspacePath
12876
+ };
12877
+ }
12878
+ const workspace = args.workspaceId ? ctx.workspaceMgr.get(args.workspaceId) : void 0;
12879
+ if (!args.workspaceId) {
12880
+ return {
12881
+ canContinue: true,
12882
+ checks: []
12883
+ };
12884
+ }
12885
+ if (!workspace) {
12886
+ return {
12887
+ canContinue: false,
12888
+ checks: [
12889
+ {
12890
+ id: "session-workspace",
12891
+ code: "session_workspace_missing",
12892
+ status: "needs_attention",
12893
+ workspaceId: args.workspaceId
12894
+ }
12895
+ ]
12896
+ };
12897
+ }
12898
+ const pathCheck = await resolveWorkspacePathCheck(workspace.path);
12899
+ return {
12900
+ canContinue: pathCheck.canContinue,
12901
+ checks: [
12902
+ {
12903
+ id: "session-workspace",
12904
+ code: "session_workspace_ready",
12905
+ status: "ready",
12906
+ workspaceId: workspace.id,
12907
+ workspacePath: workspace.path
12908
+ },
12909
+ ...pathCheck.checks.map(
12910
+ (check) => check.id === "workspace-path" ? {
12911
+ ...check,
12912
+ id: `workspace-path:${workspace.id}`
12913
+ } : check
12914
+ )
12915
+ ],
12916
+ workspacePath: workspace.path
12917
+ };
12918
+ }
12919
+ async function buildAllProviderChecks(ctx, preferredProviderId) {
12920
+ const checks = [];
12921
+ let canContinueForPreferredProvider = preferredProviderId ? false : true;
12922
+ const runtimeStatus = await buildProviderRuntimeStatus(
12923
+ ctx.providerRegistry,
12924
+ ctx.providerRuntimeDeps
12925
+ );
12926
+ for (const provider of ctx.providerRegistry) {
12927
+ const providerStatus = runtimeStatus.providers[provider.id];
12928
+ if (!providerStatus) {
12929
+ checks.push({
12930
+ id: `provider:${provider.id}`,
12931
+ code: "provider_unknown",
12932
+ status: "needs_attention",
12933
+ providerId: provider.id
12934
+ });
12935
+ if (provider.id === preferredProviderId) {
12936
+ canContinueForPreferredProvider = false;
12937
+ }
12938
+ continue;
12939
+ }
12940
+ const providerCheck = buildProviderCheck(providerStatus, provider.id);
12941
+ checks.push(...providerCheck.checks);
12942
+ if (provider.id === preferredProviderId) {
12943
+ canContinueForPreferredProvider = providerCheck.canContinue;
12944
+ }
12945
+ }
12946
+ if (preferredProviderId && !ctx.providerRegistry.find((provider) => provider.id === preferredProviderId)) {
12947
+ checks.unshift({
12948
+ id: "session-provider",
12949
+ code: "provider_unknown",
12950
+ status: "needs_attention",
12951
+ providerId: preferredProviderId
12952
+ });
12953
+ canContinueForPreferredProvider = false;
12954
+ }
12955
+ return { checks, canContinueForPreferredProvider };
12956
+ }
12957
+ function buildServerAuthCheck(ctx) {
12958
+ return {
12959
+ id: "server-auth",
12960
+ code: ctx.config?.auth.enabled ? "server_auth_ready" : "server_auth_not_required",
12961
+ status: "ready"
12962
+ };
12963
+ }
12964
+ function buildMobileHostCheck(ctx) {
12965
+ if (isLoopbackHost(ctx.config?.host)) {
12966
+ return {
12967
+ canContinue: false,
12968
+ check: {
12969
+ id: "mobile-host",
12970
+ code: "mobile_host_local_only",
12971
+ status: "needs_attention"
12972
+ }
12973
+ };
12974
+ }
12975
+ return {
12976
+ canContinue: true,
12977
+ check: {
12978
+ id: "mobile-host",
12979
+ code: "mobile_host_ready",
12980
+ status: "ready"
12981
+ }
12982
+ };
12983
+ }
12984
+ async function buildSessionStartDiagnostics(args, ctx) {
12985
+ const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
12986
+ const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
12987
+ const mobileHost = buildMobileHostCheck(ctx);
12988
+ const checks = [
12989
+ ...workspaceSelection.checks,
12990
+ ...providerChecks.checks,
12991
+ buildServerAuthCheck(ctx),
12992
+ mobileHost.check
12993
+ ];
12994
+ const canContinue = workspaceSelection.canContinue && providerChecks.canContinueForPreferredProvider;
12995
+ return {
12996
+ context: "session_start",
12997
+ canContinue,
12998
+ checks,
12999
+ metadata: {
13000
+ providerId: args.providerId,
13001
+ workspaceId: args.workspaceId,
13002
+ workspacePath: workspaceSelection.workspacePath,
13003
+ authEnabled: ctx.config?.auth.enabled ?? false,
13004
+ host: ctx.config?.host
13005
+ }
13006
+ };
13007
+ }
13008
+ async function buildManualDiagnostics(args, ctx) {
13009
+ const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
13010
+ const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
13011
+ const mobileHost = buildMobileHostCheck(ctx);
13012
+ const checks = [
13013
+ ...workspaceSelection.checks,
13014
+ ...providerChecks.checks,
13015
+ buildServerAuthCheck(ctx),
13016
+ mobileHost.check
13017
+ ];
13018
+ return {
13019
+ context: "manual_check",
13020
+ canContinue: checks.every((check) => check.status !== "needs_attention"),
13021
+ checks,
13022
+ metadata: {
13023
+ authEnabled: ctx.config?.auth.enabled ?? false,
13024
+ host: ctx.config?.host,
13025
+ providerId: args.providerId,
13026
+ workspaceId: args.workspaceId,
13027
+ workspacePath: workspaceSelection.workspacePath ?? args.workspacePath
13028
+ }
13029
+ };
13030
+ }
13031
+ async function buildMobileDiagnostics(args, ctx) {
13032
+ const host = ctx.config?.host;
13033
+ const authEnabled = ctx.config?.auth.enabled ?? false;
13034
+ const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
13035
+ const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
13036
+ const mobileHost = buildMobileHostCheck(ctx);
13037
+ const checks = [
13038
+ ...workspaceSelection.checks,
13039
+ ...providerChecks.checks,
13040
+ buildServerAuthCheck(ctx),
13041
+ mobileHost.check
13042
+ ];
13043
+ let canContinue = mobileHost.canContinue;
13044
+ if (!authEnabled) {
13045
+ canContinue = false;
13046
+ checks.push({
13047
+ id: "mobile-auth",
13048
+ code: "mobile_auth_disabled",
13049
+ status: "needs_attention"
13050
+ });
13051
+ } else {
13052
+ checks.push({
13053
+ id: "mobile-auth",
13054
+ code: "server_auth_ready",
13055
+ status: "ready"
13056
+ });
13057
+ }
13058
+ return {
13059
+ context: "mobile_continue",
13060
+ canContinue,
13061
+ checks,
13062
+ metadata: {
13063
+ authEnabled,
13064
+ host,
13065
+ workspaceId: args.workspaceId,
13066
+ workspacePath: workspaceSelection.workspacePath,
13067
+ providerId: args.providerId
13068
+ }
13069
+ };
13070
+ }
13071
+ async function buildDiagnostics(args, ctx) {
13072
+ switch (args.context) {
13073
+ case "workspace_open": {
13074
+ const workspaceSelection = await buildWorkspaceSelectionChecks(args, ctx);
13075
+ const providerChecks = await buildAllProviderChecks(ctx, args.providerId);
13076
+ const mobileHost = buildMobileHostCheck(ctx);
13077
+ return {
13078
+ context: "workspace_open",
13079
+ canContinue: workspaceSelection.canContinue,
13080
+ checks: [
13081
+ ...workspaceSelection.checks,
13082
+ ...providerChecks.checks,
13083
+ buildServerAuthCheck(ctx),
13084
+ mobileHost.check
13085
+ ],
13086
+ metadata: {
13087
+ workspacePath: workspaceSelection.workspacePath ?? args.workspacePath,
13088
+ authEnabled: ctx.config?.auth.enabled ?? false,
13089
+ host: ctx.config?.host,
13090
+ providerId: args.providerId,
13091
+ workspaceId: args.workspaceId
13092
+ }
13093
+ };
13094
+ }
13095
+ case "session_start":
13096
+ return buildSessionStartDiagnostics(args, ctx);
13097
+ case "mobile_continue":
13098
+ return buildMobileDiagnostics(args, ctx);
13099
+ case "manual_check":
13100
+ return buildManualDiagnostics(args, ctx);
13101
+ }
13102
+ }
13103
+ var DiagnosticsRequestSchema;
13104
+ var init_diagnostics2 = __esm({
13105
+ "packages/server/src/commands/diagnostics.ts"() {
13106
+ "use strict";
13107
+ init_runtime_status();
13108
+ init_validator();
13109
+ init_dispatch();
13110
+ DiagnosticsRequestSchema = z14.object({
13111
+ context: z14.enum(["workspace_open", "session_start", "mobile_continue", "manual_check"]),
13112
+ workspaceId: z14.string().optional(),
13113
+ workspacePath: z14.string().optional(),
13114
+ providerId: z14.string().optional()
13115
+ });
13116
+ registerCommand("diagnostics.get", DiagnosticsRequestSchema, async (args, ctx) => {
13117
+ return buildDiagnostics(args, ctx);
13118
+ });
13119
+ registerCommand("diagnostics.recheck", DiagnosticsRequestSchema, async (args, ctx) => {
13120
+ return buildDiagnostics(args, ctx);
13121
+ });
13122
+ }
13123
+ });
13124
+
13125
+ // packages/server/src/commands/provider.ts
13126
+ import { z as z15 } from "zod";
12176
13127
  var init_provider = __esm({
12177
13128
  "packages/server/src/commands/provider.ts"() {
12178
13129
  "use strict";
12179
13130
  init_runtime_status();
12180
13131
  init_dispatch();
12181
- registerCommand("provider.runtimeStatus", z14.object({}), async (_args, ctx) => {
13132
+ registerCommand("provider.runtimeStatus", z15.object({}), async (_args, ctx) => {
12182
13133
  return buildProviderRuntimeStatus(ctx.providerRegistry, ctx.providerRuntimeDeps);
12183
13134
  });
12184
13135
  registerCommand(
12185
13136
  "provider.install.start",
12186
- z14.object({
12187
- providerId: z14.string()
13137
+ z15.object({
13138
+ providerId: z15.string()
12188
13139
  }),
12189
13140
  async (args, ctx) => {
12190
13141
  if (!ctx.providerInstallMgr) {
@@ -12198,8 +13149,8 @@ var init_provider = __esm({
12198
13149
  );
12199
13150
  registerCommand(
12200
13151
  "provider.install.get",
12201
- z14.object({
12202
- jobId: z14.string()
13152
+ z15.object({
13153
+ jobId: z15.string()
12203
13154
  }),
12204
13155
  async (args, ctx) => {
12205
13156
  if (!ctx.providerInstallMgr) {
@@ -12222,35 +13173,35 @@ var init_provider = __esm({
12222
13173
  });
12223
13174
 
12224
13175
  // packages/server/src/commands/supervisor.ts
12225
- import { z as z15 } from "zod";
13176
+ import { z as z16 } from "zod";
12226
13177
  var supervisorObjectiveSchema, createSupervisorSchema, updateSupervisorSchema, sessionIdSchema, supervisorIdSchema;
12227
13178
  var init_supervisor2 = __esm({
12228
13179
  "packages/server/src/commands/supervisor.ts"() {
12229
13180
  "use strict";
12230
13181
  init_dispatch();
12231
- supervisorObjectiveSchema = z15.string().trim().min(1).max(4e3);
12232
- createSupervisorSchema = z15.object({
12233
- sessionId: z15.string(),
12234
- workspaceId: z15.string(),
13182
+ supervisorObjectiveSchema = z16.string().trim().min(1).max(4e3);
13183
+ createSupervisorSchema = z16.object({
13184
+ sessionId: z16.string(),
13185
+ workspaceId: z16.string(),
12235
13186
  objective: supervisorObjectiveSchema,
12236
- evaluatorProviderId: z15.string(),
12237
- evaluatorModel: z15.string().trim().min(1).max(200).optional(),
12238
- maxSupervisionCount: z15.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
12239
- scheduledAt: z15.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
13187
+ evaluatorProviderId: z16.string(),
13188
+ evaluatorModel: z16.string().trim().min(1).max(200).optional(),
13189
+ maxSupervisionCount: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
13190
+ scheduledAt: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional()
12240
13191
  }).strict();
12241
- updateSupervisorSchema = z15.object({
12242
- id: z15.string(),
13192
+ updateSupervisorSchema = z16.object({
13193
+ id: z16.string(),
12243
13194
  objective: supervisorObjectiveSchema.optional(),
12244
- evaluatorProviderId: z15.string().optional(),
12245
- evaluatorModel: z15.string().trim().min(1).max(200).nullable().optional(),
12246
- maxSupervisionCount: z15.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
12247
- scheduledAt: z15.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable().optional()
13195
+ evaluatorProviderId: z16.string().optional(),
13196
+ evaluatorModel: z16.string().trim().min(1).max(200).nullable().optional(),
13197
+ maxSupervisionCount: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).optional(),
13198
+ scheduledAt: z16.number().int().min(0).max(Number.MAX_SAFE_INTEGER).nullable().optional()
12248
13199
  }).strict().refine(
12249
13200
  (input2) => input2.objective !== void 0 || input2.evaluatorProviderId !== void 0 || input2.evaluatorModel !== void 0 || input2.maxSupervisionCount !== void 0 || input2.scheduledAt !== void 0,
12250
13201
  "at least one supervisor field is required"
12251
13202
  );
12252
- sessionIdSchema = z15.object({ sessionId: z15.string() });
12253
- supervisorIdSchema = z15.object({ id: z15.string() });
13203
+ sessionIdSchema = z16.object({ sessionId: z16.string() });
13204
+ supervisorIdSchema = z16.object({ id: z16.string() });
12254
13205
  registerCommand("supervisor.create", createSupervisorSchema, async (args, ctx) => {
12255
13206
  return {
12256
13207
  supervisor: await ctx.supervisorMgr.create({
@@ -12434,7 +13385,7 @@ var init_worktree = __esm({
12434
13385
 
12435
13386
  // packages/server/src/commands/worktree.ts
12436
13387
  import path9 from "node:path";
12437
- import { z as z16 } from "zod";
13388
+ import { z as z17 } from "zod";
12438
13389
  async function findRelatedWorkspaceIds(ctx, workspacePath) {
12439
13390
  const targetCommonDir = await getGitCommonDirPath(workspacePath);
12440
13391
  const relatedWorkspaceIds = await Promise.all(
@@ -12467,7 +13418,7 @@ var init_worktree2 = __esm({
12467
13418
  init_worktree();
12468
13419
  init_dispatch();
12469
13420
  init_git_events();
12470
- registerCommand("worktree.list", z16.object({ workspaceId: z16.string() }), async (args, ctx) => {
13421
+ registerCommand("worktree.list", z17.object({ workspaceId: z17.string() }), async (args, ctx) => {
12471
13422
  const workspace = ctx.workspaceMgr.get(args.workspaceId);
12472
13423
  if (!workspace) {
12473
13424
  throw { code: "workspace_not_found", message: `Workspace not found: ${args.workspaceId}` };
@@ -12476,7 +13427,7 @@ var init_worktree2 = __esm({
12476
13427
  });
12477
13428
  registerCommand(
12478
13429
  "worktree.status",
12479
- z16.object({ workspaceId: z16.string(), worktreePath: z16.string() }),
13430
+ z17.object({ workspaceId: z17.string(), worktreePath: z17.string() }),
12480
13431
  async (args, ctx) => {
12481
13432
  const workspace = ctx.workspaceMgr.get(args.workspaceId);
12482
13433
  if (!workspace) {
@@ -12488,10 +13439,10 @@ var init_worktree2 = __esm({
12488
13439
  );
12489
13440
  registerCommand(
12490
13441
  "worktree.diff",
12491
- z16.object({
12492
- workspaceId: z16.string(),
12493
- worktreePath: z16.string(),
12494
- staged: z16.boolean().optional().default(false)
13442
+ z17.object({
13443
+ workspaceId: z17.string(),
13444
+ worktreePath: z17.string(),
13445
+ staged: z17.boolean().optional().default(false)
12495
13446
  }),
12496
13447
  async (args, ctx) => {
12497
13448
  const workspace = ctx.workspaceMgr.get(args.workspaceId);
@@ -12504,7 +13455,7 @@ var init_worktree2 = __esm({
12504
13455
  );
12505
13456
  registerCommand(
12506
13457
  "worktree.tree",
12507
- z16.object({ workspaceId: z16.string(), worktreePath: z16.string() }),
13458
+ z17.object({ workspaceId: z17.string(), worktreePath: z17.string() }),
12508
13459
  async (args, ctx) => {
12509
13460
  const workspace = ctx.workspaceMgr.get(args.workspaceId);
12510
13461
  if (!workspace) {
@@ -12516,10 +13467,10 @@ var init_worktree2 = __esm({
12516
13467
  );
12517
13468
  registerCommand(
12518
13469
  "worktree.create",
12519
- z16.object({
12520
- workspaceId: z16.string(),
12521
- branch: z16.string(),
12522
- path: z16.string()
13470
+ z17.object({
13471
+ workspaceId: z17.string(),
13472
+ branch: z17.string(),
13473
+ path: z17.string()
12523
13474
  }),
12524
13475
  async (args, ctx) => {
12525
13476
  const workspace = ctx.workspaceMgr.get(args.workspaceId);
@@ -12534,10 +13485,10 @@ var init_worktree2 = __esm({
12534
13485
  );
12535
13486
  registerCommand(
12536
13487
  "worktree.remove",
12537
- z16.object({
12538
- workspaceId: z16.string(),
12539
- worktreePath: z16.string(),
12540
- force: z16.boolean().optional().default(false)
13488
+ z17.object({
13489
+ workspaceId: z17.string(),
13490
+ worktreePath: z17.string(),
13491
+ force: z17.boolean().optional().default(false)
12541
13492
  }),
12542
13493
  async (args, ctx) => {
12543
13494
  const workspace = ctx.workspaceMgr.get(args.workspaceId);
@@ -12561,7 +13512,7 @@ var init_worktree2 = __esm({
12561
13512
  });
12562
13513
 
12563
13514
  // packages/server/src/commands/fencing.ts
12564
- import { z as z17 } from "zod";
13515
+ import { z as z18 } from "zod";
12565
13516
  function createMockFencingRequest() {
12566
13517
  return {
12567
13518
  ip: "127.0.0.1",
@@ -12574,9 +13525,9 @@ var init_fencing2 = __esm({
12574
13525
  init_dispatch();
12575
13526
  registerCommand(
12576
13527
  "fencing.request",
12577
- z17.object({
12578
- workspaceId: z17.string(),
12579
- tabId: z17.string()
13528
+ z18.object({
13529
+ workspaceId: z18.string(),
13530
+ tabId: z18.string()
12580
13531
  }),
12581
13532
  async (args, ctx, clientId) => {
12582
13533
  return ctx.fencingMgr.requestControl(
@@ -12589,7 +13540,7 @@ var init_fencing2 = __esm({
12589
13540
  );
12590
13541
  registerCommand(
12591
13542
  "fencing.heartbeat",
12592
- z17.object({ workspaceId: z17.string() }),
13543
+ z18.object({ workspaceId: z18.string() }),
12593
13544
  async (args, ctx, clientId) => {
12594
13545
  const success = ctx.fencingMgr.heartbeat(args.workspaceId, clientId);
12595
13546
  return { success };
@@ -12597,13 +13548,13 @@ var init_fencing2 = __esm({
12597
13548
  );
12598
13549
  registerCommand(
12599
13550
  "fencing.release",
12600
- z17.object({ workspaceId: z17.string() }),
13551
+ z18.object({ workspaceId: z18.string() }),
12601
13552
  async (args, ctx, clientId) => {
12602
13553
  ctx.fencingMgr.release(args.workspaceId, clientId);
12603
13554
  return {};
12604
13555
  }
12605
13556
  );
12606
- registerCommand("fencing.status", z17.object({ workspaceId: z17.string() }), async (args, ctx) => {
13557
+ registerCommand("fencing.status", z18.object({ workspaceId: z18.string() }), async (args, ctx) => {
12607
13558
  const controller = ctx.fencingMgr.getController(args.workspaceId);
12608
13559
  const isUnresponsive = ctx.fencingMgr.isControllerUnresponsive(args.workspaceId);
12609
13560
  return {
@@ -12614,9 +13565,9 @@ var init_fencing2 = __esm({
12614
13565
  });
12615
13566
  registerCommand(
12616
13567
  "fencing.takeover",
12617
- z17.object({
12618
- workspaceId: z17.string(),
12619
- tabId: z17.string()
13568
+ z18.object({
13569
+ workspaceId: z18.string(),
13570
+ tabId: z18.string()
12620
13571
  }),
12621
13572
  async (args, ctx, clientId) => {
12622
13573
  return ctx.fencingMgr.forceTakeover(
@@ -12643,6 +13594,7 @@ var init_commands = __esm({
12643
13594
  init_file();
12644
13595
  init_git2();
12645
13596
  init_settings2();
13597
+ init_diagnostics2();
12646
13598
  init_provider();
12647
13599
  init_supervisor2();
12648
13600
  init_worktree2();
@@ -12786,7 +13738,8 @@ async function createServer(configOverrides) {
12786
13738
  autoFetch,
12787
13739
  providerRuntimeDeps,
12788
13740
  providerInstallMgr,
12789
- activationMgr
13741
+ activationMgr,
13742
+ config
12790
13743
  };
12791
13744
  wsHub.setCommandContext(commandContext);
12792
13745
  await app.listen({
@@ -13361,7 +14314,7 @@ function getOpenCommand(url) {
13361
14314
  }
13362
14315
  async function openBrowser(url) {
13363
14316
  const { command, args } = getOpenCommand(url);
13364
- await new Promise((resolve4, reject) => {
14317
+ await new Promise((resolve5, reject) => {
13365
14318
  const child = spawn3(command, args, {
13366
14319
  detached: true,
13367
14320
  stdio: "ignore",
@@ -13370,7 +14323,7 @@ async function openBrowser(url) {
13370
14323
  child.once("error", reject);
13371
14324
  child.once("spawn", () => {
13372
14325
  child.unref();
13373
- resolve4();
14326
+ resolve5();
13374
14327
  });
13375
14328
  });
13376
14329
  }
@@ -13739,29 +14692,29 @@ async function loadPm2() {
13739
14692
  }
13740
14693
  var connectPm2 = async () => {
13741
14694
  const pm2 = await loadPm2();
13742
- return new Promise((resolve4, reject) => {
14695
+ return new Promise((resolve5, reject) => {
13743
14696
  pm2.connect((error) => {
13744
14697
  if (error) {
13745
14698
  reject(error);
13746
14699
  return;
13747
14700
  }
13748
- resolve4();
14701
+ resolve5();
13749
14702
  });
13750
14703
  });
13751
14704
  };
13752
- var sleep = async (ms) => new Promise((resolve4) => {
13753
- setTimeout(resolve4, ms);
14705
+ var sleep = async (ms) => new Promise((resolve5) => {
14706
+ setTimeout(resolve5, ms);
13754
14707
  });
13755
14708
  var disconnectPm2 = async () => {
13756
14709
  const pm2 = await loadPm2();
13757
- await new Promise((resolve4) => {
14710
+ await new Promise((resolve5) => {
13758
14711
  let settled = false;
13759
14712
  const finish = () => {
13760
14713
  if (settled) {
13761
14714
  return;
13762
14715
  }
13763
14716
  settled = true;
13764
- resolve4();
14717
+ resolve5();
13765
14718
  };
13766
14719
  const timer = setTimeout(finish, PM2_DISCONNECT_WAIT_MS);
13767
14720
  try {
@@ -13775,29 +14728,29 @@ var disconnectPm2 = async () => {
13775
14728
  }
13776
14729
  });
13777
14730
  };
13778
- var describeManagedServer = async (pm2) => new Promise((resolve4, reject) => {
14731
+ var describeManagedServer = async (pm2) => new Promise((resolve5, reject) => {
13779
14732
  pm2.describe(MANAGED_SERVER_NAME, (error, result) => {
13780
14733
  if (error) {
13781
14734
  reject(error);
13782
14735
  return;
13783
14736
  }
13784
- resolve4(result ?? []);
14737
+ resolve5(result ?? []);
13785
14738
  });
13786
14739
  });
13787
- var removeManagedServer = async (pm2) => new Promise((resolve4, reject) => {
14740
+ var removeManagedServer = async (pm2) => new Promise((resolve5, reject) => {
13788
14741
  pm2.delete(MANAGED_SERVER_NAME, (error) => {
13789
14742
  if (error) {
13790
14743
  reject(error);
13791
14744
  return;
13792
14745
  }
13793
- resolve4();
14746
+ resolve5();
13794
14747
  });
13795
14748
  });
13796
14749
  var killPm2Daemon = async () => {
13797
14750
  const pm2 = await loadPm2();
13798
- return new Promise((resolve4) => {
14751
+ return new Promise((resolve5) => {
13799
14752
  pm2.kill(() => {
13800
- resolve4();
14753
+ resolve5();
13801
14754
  });
13802
14755
  });
13803
14756
  };
@@ -13943,7 +14896,7 @@ var startManagedServer = async ({
13943
14896
  ensureLogDirectory();
13944
14897
  const { outFile, errFile } = getLogPaths();
13945
14898
  const logOffsets = captureStartupLogOffsets();
13946
- await new Promise((resolve4, reject) => {
14899
+ await new Promise((resolve5, reject) => {
13947
14900
  pm2.start(
13948
14901
  {
13949
14902
  name: MANAGED_SERVER_NAME,
@@ -13966,7 +14919,7 @@ var startManagedServer = async ({
13966
14919
  reject(error);
13967
14920
  return;
13968
14921
  }
13969
- resolve4();
14922
+ resolve5();
13970
14923
  }
13971
14924
  );
13972
14925
  });
@@ -14084,11 +15037,11 @@ import { fileURLToPath as fileURLToPath2 } from "url";
14084
15037
 
14085
15038
  // packages/cli/src/embed.ts
14086
15039
  import { existsSync as existsSync10 } from "fs";
14087
- import { dirname as dirname6, resolve as resolve3 } from "path";
15040
+ import { dirname as dirname6, resolve as resolve4 } from "path";
14088
15041
  import { fileURLToPath } from "url";
14089
15042
  var __filename = fileURLToPath(import.meta.url);
14090
15043
  var __dirname = dirname6(__filename);
14091
- var WEB_ASSETS_DIR = resolve3(__dirname, "../web");
15044
+ var WEB_ASSETS_DIR = resolve4(__dirname, "../web");
14092
15045
  function getStaticAssetsDir() {
14093
15046
  return WEB_ASSETS_DIR;
14094
15047
  }