voratiq 0.1.0-beta.21 → 0.1.0-beta.23

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.
Files changed (222) hide show
  1. package/README.md +19 -23
  2. package/dist/agents/launch/chat.d.ts +3 -1
  3. package/dist/agents/launch/chat.js +2 -0
  4. package/dist/agents/runtime/policy.js +2 -1
  5. package/dist/auth/providers/utils.js +1 -1
  6. package/dist/bin.js +28 -7
  7. package/dist/cli/auto.js +4 -16
  8. package/dist/cli/contract.d.ts +26 -17
  9. package/dist/cli/contract.js +3 -1
  10. package/dist/cli/doctor.d.ts +12 -0
  11. package/dist/cli/doctor.js +115 -0
  12. package/dist/cli/list.js +5 -1
  13. package/dist/cli/message.js +16 -11
  14. package/dist/cli/operator-envelope.d.ts +27 -7
  15. package/dist/cli/operator-envelope.js +95 -3
  16. package/dist/cli/option-parsers.d.ts +2 -0
  17. package/dist/cli/option-parsers.js +7 -0
  18. package/dist/cli/output.d.ts +1 -5
  19. package/dist/cli/reduce.js +5 -13
  20. package/dist/cli/run.js +5 -12
  21. package/dist/cli/spec.js +4 -10
  22. package/dist/cli/verify.d.ts +1 -1
  23. package/dist/cli/verify.js +51 -22
  24. package/dist/commands/auto/command.d.ts +1 -0
  25. package/dist/commands/auto/command.js +22 -15
  26. package/dist/commands/auto/errors.js +1 -1
  27. package/dist/commands/auto/validation.js +3 -1
  28. package/dist/commands/doctor/agents.d.ts +5 -0
  29. package/dist/commands/{init → doctor}/agents.js +40 -20
  30. package/dist/commands/doctor/command.d.ts +22 -0
  31. package/dist/commands/doctor/command.js +100 -0
  32. package/dist/commands/doctor/environment.d.ts +2 -0
  33. package/dist/commands/{init → doctor}/environment.js +41 -7
  34. package/dist/commands/{init/types.d.ts → doctor/fix-types.d.ts} +30 -9
  35. package/dist/commands/doctor/fix.d.ts +2 -0
  36. package/dist/commands/{init/command.js → doctor/fix.js} +109 -11
  37. package/dist/commands/doctor/reconcile.d.ts +2 -0
  38. package/dist/commands/doctor/reconcile.js +103 -0
  39. package/dist/commands/interactive/lifecycle.d.ts +2 -0
  40. package/dist/commands/interactive/lifecycle.js +16 -0
  41. package/dist/commands/list/command.d.ts +1 -0
  42. package/dist/commands/list/command.js +241 -361
  43. package/dist/commands/list/normalization.d.ts +51 -0
  44. package/dist/commands/list/normalization.js +309 -0
  45. package/dist/commands/list/records.d.ts +9 -0
  46. package/dist/commands/list/records.js +6 -0
  47. package/dist/commands/message/command.d.ts +2 -2
  48. package/dist/commands/message/command.js +29 -16
  49. package/dist/commands/message/errors.d.ts +12 -3
  50. package/dist/commands/message/errors.js +19 -3
  51. package/dist/commands/prune/command.js +4 -1
  52. package/dist/commands/reduce/command.js +16 -17
  53. package/dist/commands/reduce/errors.d.ts +2 -2
  54. package/dist/commands/reduce/errors.js +3 -3
  55. package/dist/commands/reduce/targets.js +12 -3
  56. package/dist/commands/root-launcher/command.js +12 -6
  57. package/dist/commands/run/command.d.ts +1 -0
  58. package/dist/commands/run/command.js +4 -1
  59. package/dist/commands/run/record-init.d.ts +2 -0
  60. package/dist/commands/run/record-init.js +8 -1
  61. package/dist/commands/run/spec-provenance.d.ts +37 -0
  62. package/dist/commands/run/spec-provenance.js +384 -0
  63. package/dist/commands/run/validation.d.ts +4 -0
  64. package/dist/commands/run/validation.js +25 -62
  65. package/dist/commands/shared/resolve-stage-competitors.js +2 -1
  66. package/dist/commands/spec/command.js +64 -138
  67. package/dist/commands/spec/errors.d.ts +5 -0
  68. package/dist/commands/spec/errors.js +9 -0
  69. package/dist/commands/verify/agents.d.ts +4 -2
  70. package/dist/commands/verify/agents.js +4 -11
  71. package/dist/commands/verify/command.js +23 -6
  72. package/dist/commands/verify/errors.d.ts +12 -0
  73. package/dist/commands/verify/errors.js +22 -0
  74. package/dist/commands/verify/lifecycle.js +1 -1
  75. package/dist/commands/verify/targets.js +108 -12
  76. package/dist/competition/shared/preflight.d.ts +1 -1
  77. package/dist/competition/shared/preflight.js +15 -2
  78. package/dist/competition/shared/teardown.d.ts +7 -0
  79. package/dist/competition/shared/teardown.js +6 -0
  80. package/dist/configs/agents/defaults.js +13 -44
  81. package/dist/configs/agents/loader.js +1 -1
  82. package/dist/configs/environment/loader.js +2 -1
  83. package/dist/configs/orchestration/loader.js +2 -1
  84. package/dist/configs/sandbox/loader.js +2 -1
  85. package/dist/configs/settings/loader.js +1 -1
  86. package/dist/configs/verification/loader.js +2 -1
  87. package/dist/contracts/list.d.ts +129 -149
  88. package/dist/contracts/list.js +47 -99
  89. package/dist/domain/interactive/model/types.d.ts +2 -0
  90. package/dist/domain/interactive/model/types.js +16 -1
  91. package/dist/domain/interactive/persistence/adapter.d.ts +23 -0
  92. package/dist/domain/interactive/persistence/adapter.js +67 -5
  93. package/dist/domain/interactive/prompt.d.ts +1 -1
  94. package/dist/domain/interactive/prompt.js +1 -1
  95. package/dist/domain/interactive/session-env.d.ts +10 -0
  96. package/dist/domain/interactive/session-env.js +25 -0
  97. package/dist/domain/message/competition/adapter.js +3 -9
  98. package/dist/domain/message/model/types.d.ts +32 -1
  99. package/dist/domain/message/model/types.js +25 -1
  100. package/dist/domain/reduce/competition/adapter.js +30 -16
  101. package/dist/domain/reduce/competition/finalize.d.ts +7 -0
  102. package/dist/domain/reduce/competition/finalize.js +19 -0
  103. package/dist/domain/reduce/model/types.d.ts +3 -3
  104. package/dist/domain/run/competition/agents/artifacts.js +4 -2
  105. package/dist/domain/run/competition/agents/lifecycle.js +1 -1
  106. package/dist/domain/run/competition/agents/workspace.js +2 -1
  107. package/dist/domain/run/competition/errors.d.ts +1 -1
  108. package/dist/domain/run/competition/errors.js +4 -7
  109. package/dist/domain/run/competition/reports.js +2 -1
  110. package/dist/domain/run/model/enhanced.d.ts +1 -1
  111. package/dist/domain/run/model/enhanced.js +2 -1
  112. package/dist/domain/run/model/types.d.ts +384 -0
  113. package/dist/domain/run/model/types.js +87 -0
  114. package/dist/domain/spec/competition/adapter.d.ts +1 -0
  115. package/dist/domain/spec/competition/adapter.js +9 -10
  116. package/dist/domain/spec/model/mutators.d.ts +20 -0
  117. package/dist/domain/spec/model/mutators.js +146 -0
  118. package/dist/domain/spec/model/types.d.ts +3 -0
  119. package/dist/domain/spec/model/types.js +5 -0
  120. package/dist/domain/spec/persistence/adapter.d.ts +1 -0
  121. package/dist/domain/spec/persistence/adapter.js +7 -2
  122. package/dist/domain/verify/competition/adapter.d.ts +1 -1
  123. package/dist/domain/verify/competition/adapter.js +4 -9
  124. package/dist/domain/verify/competition/finalize.d.ts +9 -0
  125. package/dist/domain/verify/competition/finalize.js +22 -3
  126. package/dist/domain/verify/competition/programmatic.js +2 -1
  127. package/dist/domain/verify/competition/prompt.js +1 -1
  128. package/dist/domain/verify/competition/shared-layout.js +1 -1
  129. package/dist/domain/verify/model/types.d.ts +2 -2
  130. package/dist/interactive/providers/launch.d.ts +2 -0
  131. package/dist/interactive/providers/launch.js +19 -2
  132. package/dist/interactive/providers/mcp.d.ts +1 -0
  133. package/dist/interactive/providers/mcp.js +45 -7
  134. package/dist/interactive/substrate.js +32 -5
  135. package/dist/mcp/server.d.ts +1 -0
  136. package/dist/mcp/server.js +337 -44
  137. package/dist/policy/auto.d.ts +0 -1
  138. package/dist/policy/auto.js +3 -14
  139. package/dist/policy/verification.js +18 -1
  140. package/dist/preflight/agents.d.ts +24 -0
  141. package/dist/preflight/agents.js +71 -0
  142. package/dist/preflight/environment.d.ts +6 -0
  143. package/dist/preflight/environment.js +17 -0
  144. package/dist/preflight/formatting.d.ts +5 -0
  145. package/dist/preflight/formatting.js +20 -0
  146. package/dist/preflight/index.d.ts +2 -0
  147. package/dist/preflight/index.js +6 -9
  148. package/dist/preflight/operator.d.ts +32 -0
  149. package/dist/preflight/operator.js +40 -0
  150. package/dist/preflight/settings.d.ts +2 -0
  151. package/dist/preflight/settings.js +17 -0
  152. package/dist/render/transcripts/apply.js +2 -1
  153. package/dist/render/transcripts/interactive.d.ts +16 -0
  154. package/dist/render/transcripts/interactive.js +42 -0
  155. package/dist/render/transcripts/list.d.ts +41 -0
  156. package/dist/render/transcripts/list.js +152 -3
  157. package/dist/render/transcripts/message.d.ts +3 -5
  158. package/dist/render/transcripts/message.js +29 -74
  159. package/dist/render/transcripts/reduce.d.ts +2 -4
  160. package/dist/render/transcripts/reduce.js +31 -75
  161. package/dist/render/transcripts/root-launcher.js +2 -12
  162. package/dist/render/transcripts/run.d.ts +4 -4
  163. package/dist/render/transcripts/run.js +36 -47
  164. package/dist/render/transcripts/spec.d.ts +1 -4
  165. package/dist/render/transcripts/spec.js +15 -62
  166. package/dist/render/transcripts/verify.d.ts +6 -7
  167. package/dist/render/transcripts/verify.js +54 -85
  168. package/dist/render/utils/cli-writer.d.ts +4 -0
  169. package/dist/render/utils/cli-writer.js +1 -0
  170. package/dist/render/utils/duration.d.ts +5 -0
  171. package/dist/render/utils/duration.js +6 -0
  172. package/dist/render/utils/progressive-render.d.ts +3 -0
  173. package/dist/render/utils/progressive-render.js +44 -0
  174. package/dist/render/utils/runs.d.ts +1 -0
  175. package/dist/render/utils/runs.js +1 -0
  176. package/dist/render/utils/transcript-shell.d.ts +2 -1
  177. package/dist/render/utils/transcript-shell.js +19 -6
  178. package/dist/utils/diff.d.ts +2 -0
  179. package/dist/utils/diff.js +1 -0
  180. package/dist/utils/errors.d.ts +2 -1
  181. package/dist/utils/errors.js +3 -1
  182. package/dist/utils/git.d.ts +1 -1
  183. package/dist/utils/git.js +25 -2
  184. package/dist/utils/list-target.d.ts +4 -0
  185. package/dist/utils/list-target.js +35 -0
  186. package/dist/utils/swarm-session-ack.d.ts +9 -0
  187. package/dist/utils/swarm-session-ack.js +17 -0
  188. package/dist/utils/terminal.d.ts +1 -0
  189. package/dist/utils/terminal.js +11 -0
  190. package/dist/workspace/artifact-paths.d.ts +55 -0
  191. package/dist/workspace/artifact-paths.js +106 -0
  192. package/dist/workspace/chat/artifacts.d.ts +7 -0
  193. package/dist/workspace/chat/artifacts.js +95 -4
  194. package/dist/workspace/chat/native-usage.js +1 -1
  195. package/dist/workspace/chat/sources.d.ts +2 -5
  196. package/dist/workspace/chat/sources.js +4 -4
  197. package/dist/workspace/constants.d.ts +47 -0
  198. package/dist/workspace/constants.js +47 -0
  199. package/dist/workspace/errors.js +2 -2
  200. package/dist/workspace/layout.js +3 -1
  201. package/dist/workspace/managed-state.d.ts +32 -0
  202. package/dist/workspace/managed-state.js +104 -0
  203. package/dist/workspace/path-formatters.d.ts +9 -0
  204. package/dist/workspace/path-formatters.js +46 -0
  205. package/dist/workspace/path-resolvers.d.ts +1 -0
  206. package/dist/workspace/path-resolvers.js +5 -0
  207. package/dist/workspace/session-paths.d.ts +16 -0
  208. package/dist/workspace/session-paths.js +59 -0
  209. package/dist/workspace/setup.js +67 -2
  210. package/dist/workspace/shim.d.ts +1 -0
  211. package/dist/workspace/shim.js +3 -3
  212. package/package.json +2 -2
  213. package/dist/cli/init.d.ts +0 -15
  214. package/dist/cli/init.js +0 -70
  215. package/dist/commands/init/agents.d.ts +0 -4
  216. package/dist/commands/init/command.d.ts +0 -2
  217. package/dist/commands/init/environment.d.ts +0 -2
  218. package/dist/render/transcripts/init.d.ts +0 -7
  219. package/dist/render/transcripts/init.js +0 -83
  220. package/dist/workspace/structure.d.ts +0 -143
  221. package/dist/workspace/structure.js +0 -319
  222. /package/dist/commands/{init/types.js → doctor/fix-types.js} +0 -0
@@ -1,21 +1,42 @@
1
+ import { readFile } from "node:fs/promises";
1
2
  import { getAgentDefaultId, getAgentDefaultsForPreset, getSupportedAgentDefaults, } from "../../configs/agents/defaults.js";
2
3
  import { readAgentsConfig } from "../../configs/agents/loader.js";
4
+ import { loadEnvironmentConfig } from "../../configs/environment/loader.js";
3
5
  import { buildDefaultOrchestrationTemplate } from "../../configs/orchestration/bootstrap.js";
4
- import { renderPresetPromptPreface } from "../../render/transcripts/init.js";
6
+ import { pathExists } from "../../utils/fs.js";
5
7
  import { normalizeConfigText, readConfigSnapshot, writeConfigIfChanged, } from "../../utils/yaml.js";
8
+ import { VORATIQ_AGENTS_FILE, VORATIQ_ORCHESTRATION_FILE, VORATIQ_SANDBOX_FILE, } from "../../workspace/constants.js";
9
+ import { updateManagedState } from "../../workspace/managed-state.js";
10
+ import { formatWorkspacePath } from "../../workspace/path-formatters.js";
11
+ import { resolveWorkspacePath } from "../../workspace/path-resolvers.js";
6
12
  import { createWorkspace } from "../../workspace/setup.js";
7
- import { formatWorkspacePath, resolveWorkspacePath, VORATIQ_AGENTS_FILE, VORATIQ_ORCHESTRATION_FILE, VORATIQ_SANDBOX_FILE, } from "../../workspace/structure.js";
8
13
  import { listAgentPresetTemplates, serializeAgentsConfigEntries, } from "../../workspace/templates.js";
9
- import { configureAgents } from "./agents.js";
10
- import { configureEnvironment } from "./environment.js";
11
- export async function executeInitCommand(input) {
14
+ import { bootstrapDoctorAgents } from "./agents.js";
15
+ import { reconcileDoctorEnvironment } from "./environment.js";
16
+ export async function executeDoctorBootstrap(input) {
12
17
  const { root, preset, presetProvided, onPresetResolved, assumeYes, interactive, confirm, prompt, } = input;
18
+ const workspaceExistsBeforeInit = await pathExists(resolveWorkspacePath(root));
13
19
  const agentsConfigPath = resolveWorkspacePath(root, VORATIQ_AGENTS_FILE);
14
20
  const agentsSnapshotBeforeInit = await readConfigSnapshot(agentsConfigPath);
15
21
  const agentsConfigMissing = !agentsSnapshotBeforeInit.exists;
16
22
  const orchestrationConfigPath = resolveWorkspacePath(root, VORATIQ_ORCHESTRATION_FILE);
17
23
  const orchestrationSnapshotBeforeInit = await readConfigSnapshot(orchestrationConfigPath);
18
24
  const orchestrationConfigMissing = !orchestrationSnapshotBeforeInit.exists;
25
+ const workspaceResult = await createWorkspace(root);
26
+ if (workspaceExistsBeforeInit) {
27
+ const repairedOrchestrationSummary = await repairExistingWorkspaceOrchestration(root, {
28
+ orchestrationConfigMissing,
29
+ preset,
30
+ });
31
+ const repairOnly = await buildRepairOnlySummaries(root, workspaceResult);
32
+ return {
33
+ mode: "repair",
34
+ preset,
35
+ workspaceResult,
36
+ ...repairOnly,
37
+ orchestrationSummary: repairedOrchestrationSummary ?? repairOnly.orchestrationSummary,
38
+ };
39
+ }
19
40
  const resolvedPreset = await resolveAgentPreset({
20
41
  preset,
21
42
  presetProvided,
@@ -24,12 +45,11 @@ export async function executeInitCommand(input) {
24
45
  agentsConfigMissing,
25
46
  });
26
47
  onPresetResolved?.(resolvedPreset);
27
- const workspaceResult = await createWorkspace(root);
28
48
  await applyAgentPresetTemplate(root, resolvedPreset, {
29
49
  presetProvided: Boolean(presetProvided),
30
50
  agentsConfigMissing,
31
51
  });
32
- const agentSummary = await configureAgents(root, resolvedPreset, {
52
+ const agentSummary = await bootstrapDoctorAgents(root, resolvedPreset, {
33
53
  interactive,
34
54
  assumeYes,
35
55
  confirm,
@@ -38,11 +58,13 @@ export async function executeInitCommand(input) {
38
58
  orchestrationConfigMissing,
39
59
  preset: resolvedPreset,
40
60
  });
41
- const environmentSummary = await configureEnvironment(root, {
61
+ const environmentSummary = await reconcileDoctorEnvironment(root, {
42
62
  interactive: false,
43
63
  });
44
64
  const sandboxSummary = buildSandboxSummary(workspaceResult);
65
+ await refreshManagedState(root, resolvedPreset);
45
66
  return {
67
+ mode: "bootstrap",
46
68
  preset: resolvedPreset,
47
69
  workspaceResult,
48
70
  agentSummary,
@@ -51,6 +73,56 @@ export async function executeInitCommand(input) {
51
73
  sandboxSummary,
52
74
  };
53
75
  }
76
+ async function buildRepairOnlySummaries(root, workspaceResult) {
77
+ const createdFiles = new Set(workspaceResult.createdFiles.map((value) => value.replace(/\\/g, "/")));
78
+ const agentsConfig = readAgentsConfig(await readFile(resolveWorkspacePath(root, VORATIQ_AGENTS_FILE), "utf8"));
79
+ const environmentConfig = loadEnvironmentConfig({ root, optional: true });
80
+ return {
81
+ agentSummary: {
82
+ configPath: formatWorkspacePath(VORATIQ_AGENTS_FILE),
83
+ enabledAgents: agentsConfig.agents
84
+ .filter((entry) => entry.enabled !== false)
85
+ .map((entry) => entry.id),
86
+ agentCount: agentsConfig.agents.length,
87
+ zeroDetections: agentsConfig.agents.every((entry) => (entry.binary ?? "").trim().length === 0),
88
+ detectedProviders: collectDetectedProvidersFromConfig(agentsConfig),
89
+ providerEnablementPrompted: false,
90
+ configCreated: createdFiles.has(formatWorkspacePath(VORATIQ_AGENTS_FILE)),
91
+ configUpdated: false,
92
+ managed: false,
93
+ },
94
+ orchestrationSummary: {
95
+ configPath: formatWorkspacePath(VORATIQ_ORCHESTRATION_FILE),
96
+ configCreated: createdFiles.has(formatWorkspacePath(VORATIQ_ORCHESTRATION_FILE)),
97
+ configUpdated: false,
98
+ },
99
+ environmentSummary: {
100
+ configPath: formatWorkspacePath("environment.yaml"),
101
+ detectedEntries: Object.keys(environmentConfig),
102
+ configCreated: createdFiles.has(formatWorkspacePath("environment.yaml")),
103
+ configUpdated: false,
104
+ config: environmentConfig,
105
+ },
106
+ sandboxSummary: buildSandboxSummary(workspaceResult),
107
+ };
108
+ }
109
+ async function repairExistingWorkspaceOrchestration(root, options) {
110
+ if (!options.orchestrationConfigMissing) {
111
+ return undefined;
112
+ }
113
+ return reconcileOrchestrationConfig(root, options);
114
+ }
115
+ async function refreshManagedState(root, preset) {
116
+ const [agentsContent, orchestrationContent] = await Promise.all([
117
+ readFile(resolveWorkspacePath(root, VORATIQ_AGENTS_FILE), "utf8"),
118
+ readFile(resolveWorkspacePath(root, VORATIQ_ORCHESTRATION_FILE), "utf8"),
119
+ ]);
120
+ await updateManagedState(root, {
121
+ agentsContent,
122
+ orchestrationContent,
123
+ orchestrationPreset: preset,
124
+ });
125
+ }
54
126
  function buildSandboxSummary(workspaceResult) {
55
127
  const configPath = formatWorkspacePath(VORATIQ_SANDBOX_FILE);
56
128
  const normalizedCreated = workspaceResult.createdFiles.map((file) => file.replace(/\\/g, "/"));
@@ -72,8 +144,12 @@ async function reconcileOrchestrationConfig(root, options) {
72
144
  const baseline = orchestrationSnapshot.exists
73
145
  ? orchestrationSnapshot.normalized
74
146
  : "__missing__";
75
- await writeConfigIfChanged(orchestrationConfigPath, nextContent, baseline);
76
- return { configPath, configCreated: true };
147
+ const updated = await writeConfigIfChanged(orchestrationConfigPath, nextContent, baseline);
148
+ await updateManagedState(root, {
149
+ orchestrationContent: nextContent,
150
+ orchestrationPreset: preset,
151
+ });
152
+ return { configPath, configCreated: true, configUpdated: updated };
77
153
  }
78
154
  async function applyAgentPresetTemplate(root, preset, options) {
79
155
  const { presetProvided, agentsConfigMissing } = options;
@@ -149,7 +225,7 @@ async function promptForPresetSelection(prompt) {
149
225
  for (;;) {
150
226
  const response = await prompt({
151
227
  message: "[1]",
152
- prefaceLines: renderPresetPromptPreface(firstPrompt),
228
+ prefaceLines: buildPresetPromptPreface(firstPrompt),
153
229
  });
154
230
  const trimmed = response.trim();
155
231
  const normalized = trimmed.length === 0 ? "1" : trimmed;
@@ -161,6 +237,19 @@ async function promptForPresetSelection(prompt) {
161
237
  firstPrompt = false;
162
238
  }
163
239
  }
240
+ function collectDetectedProvidersFromConfig(config) {
241
+ const detected = [];
242
+ const seenProviders = new Set();
243
+ for (const entry of config.agents) {
244
+ const binary = entry.binary?.trim();
245
+ if (!binary || seenProviders.has(entry.provider)) {
246
+ continue;
247
+ }
248
+ seenProviders.add(entry.provider);
249
+ detected.push({ provider: entry.provider, binary });
250
+ }
251
+ return detected;
252
+ }
164
253
  function tryReadAgentsConfig(content) {
165
254
  try {
166
255
  return readAgentsConfig(content);
@@ -242,6 +331,15 @@ function detectManagedAgentsPreset(config) {
242
331
  }
243
332
  return undefined;
244
333
  }
334
+ function buildPresetPromptPreface(firstPrompt) {
335
+ const lines = [
336
+ "Which workspace preset would you like?",
337
+ " [1] Pro (flagship)",
338
+ " [2] Lite (faster/cheaper)",
339
+ " [3] Manual (configure yourself)",
340
+ ];
341
+ return firstPrompt ? ["", ...lines] : lines;
342
+ }
245
343
  function retargetManagedAgentEntries(config, fromPreset) {
246
344
  const fromRoster = buildPresetRoster(fromPreset);
247
345
  const fromIds = new Set(fromRoster.map((entry) => entry.id));
@@ -0,0 +1,2 @@
1
+ import type { DoctorReconcileInput, DoctorReconcileResult } from "./fix-types.js";
2
+ export declare function executeDoctorReconcile(input: DoctorReconcileInput): Promise<DoctorReconcileResult>;
@@ -0,0 +1,103 @@
1
+ import { readFile } from "node:fs/promises";
2
+ import { readAgentsConfig } from "../../configs/agents/loader.js";
3
+ import { buildDefaultOrchestrationTemplate } from "../../configs/orchestration/bootstrap.js";
4
+ import { pathExists } from "../../utils/fs.js";
5
+ import { readConfigSnapshot, writeConfigIfChanged } from "../../utils/yaml.js";
6
+ import { VORATIQ_ORCHESTRATION_FILE } from "../../workspace/constants.js";
7
+ import { computeManagedFingerprint, isManagedFingerprintMatch, readManagedState, updateManagedState, } from "../../workspace/managed-state.js";
8
+ import { formatWorkspacePath } from "../../workspace/path-formatters.js";
9
+ import { resolveWorkspacePath } from "../../workspace/path-resolvers.js";
10
+ import { createWorkspace } from "../../workspace/setup.js";
11
+ import { reconcileManagedDoctorAgents } from "./agents.js";
12
+ import { reconcileDoctorEnvironment } from "./environment.js";
13
+ export async function executeDoctorReconcile(input) {
14
+ const { root } = input;
15
+ const workspaceDirExists = await pathExists(resolveWorkspacePath(root));
16
+ const workspaceResult = workspaceDirExists
17
+ ? undefined
18
+ : await createWorkspace(root);
19
+ const agentSummary = await reconcileManagedDoctorAgents(root);
20
+ const environmentSummary = await reconcileDoctorEnvironment(root, {
21
+ interactive: false,
22
+ });
23
+ const orchestrationSummary = await reconcileManagedOrchestration(root);
24
+ const [agentsContent, orchestrationContent] = await Promise.all([
25
+ readFile(resolveWorkspacePath(root, "agents.yaml"), "utf8"),
26
+ readFile(resolveWorkspacePath(root, "orchestration.yaml"), "utf8"),
27
+ ]);
28
+ await updateManagedState(root, {
29
+ ...(agentSummary.managed ? { agentsContent } : {}),
30
+ ...(orchestrationSummary.managed
31
+ ? {
32
+ orchestrationContent,
33
+ orchestrationPreset: orchestrationSummary.preset,
34
+ }
35
+ : {}),
36
+ });
37
+ return {
38
+ workspaceBootstrapped: !workspaceDirExists,
39
+ workspaceResult,
40
+ agentSummary,
41
+ environmentSummary,
42
+ orchestrationSummary,
43
+ };
44
+ }
45
+ async function reconcileManagedOrchestration(root) {
46
+ const configPath = formatWorkspacePath(VORATIQ_ORCHESTRATION_FILE);
47
+ const filePath = resolveWorkspacePath(root, VORATIQ_ORCHESTRATION_FILE);
48
+ const agentsPath = resolveWorkspacePath(root, "agents.yaml");
49
+ const [snapshot, agentsContent, managedState] = await Promise.all([
50
+ readConfigSnapshot(filePath),
51
+ readFile(agentsPath, "utf8"),
52
+ readManagedState(root),
53
+ ]);
54
+ const agentsConfig = readAgentsConfig(agentsContent);
55
+ const preset = managedState?.configs.orchestration?.preset ??
56
+ inferManagedPreset(snapshot.content, agentsConfig) ??
57
+ "pro";
58
+ const desired = buildDefaultOrchestrationTemplate(agentsConfig, preset);
59
+ const managed = !snapshot.exists ||
60
+ isManagedFingerprintMatch(managedState?.configs.orchestration, snapshot.content) ||
61
+ computeManagedFingerprint(snapshot.content) ===
62
+ computeManagedFingerprint(desired);
63
+ if (!snapshot.exists) {
64
+ await writeConfigIfChanged(filePath, desired, "__missing__");
65
+ return {
66
+ configPath,
67
+ configCreated: true,
68
+ configUpdated: true,
69
+ skippedCustomized: false,
70
+ managed: true,
71
+ preset,
72
+ };
73
+ }
74
+ if (!managed) {
75
+ return {
76
+ configPath,
77
+ configCreated: false,
78
+ configUpdated: false,
79
+ skippedCustomized: true,
80
+ managed: false,
81
+ preset,
82
+ };
83
+ }
84
+ const updated = await writeConfigIfChanged(filePath, desired, snapshot.normalized);
85
+ return {
86
+ configPath,
87
+ configCreated: false,
88
+ configUpdated: updated,
89
+ skippedCustomized: false,
90
+ managed: true,
91
+ preset,
92
+ };
93
+ }
94
+ function inferManagedPreset(content, agentsConfig) {
95
+ const normalized = computeManagedFingerprint(content);
96
+ for (const preset of ["pro", "lite", "manual"]) {
97
+ const candidate = buildDefaultOrchestrationTemplate(agentsConfig, preset);
98
+ if (computeManagedFingerprint(candidate) === normalized) {
99
+ return preset;
100
+ }
101
+ }
102
+ return undefined;
103
+ }
@@ -7,9 +7,11 @@ interface ActiveInteractiveContext {
7
7
  process?: ChildProcess;
8
8
  completion?: Promise<InteractiveSessionRecord>;
9
9
  teardown?: TeardownController;
10
+ terminationStatus?: "failed" | "aborted";
10
11
  }
11
12
  export declare function registerActiveInteractive(context: ActiveInteractiveContext): void;
12
13
  export declare function clearActiveInteractive(sessionId: string): void;
14
+ export declare function getActiveInteractiveTerminationStatus(sessionId: string): "failed" | "aborted" | undefined;
13
15
  export declare function terminateActiveInteractive(status: "failed" | "aborted", reason?: string): Promise<void>;
14
16
  export declare function finalizeActiveInteractive(sessionId: string): Promise<void>;
15
17
  export {};
@@ -1,5 +1,6 @@
1
1
  import { runTeardown } from "../../competition/shared/teardown.js";
2
2
  import { disposeInteractiveSessionBuffer, getInteractiveSessionRecordSnapshot, rewriteInteractiveSessionRecord, } from "../../domain/interactive/persistence/adapter.js";
3
+ import { buildRecordLifecycleCompleteFields } from "../../domain/shared/lifecycle.js";
3
4
  import { toErrorMessage } from "../../utils/errors.js";
4
5
  const INTERACTIVE_TERMINATION_WAIT_MS = 1_000;
5
6
  let activeInteractive;
@@ -15,12 +16,19 @@ export function clearActiveInteractive(sessionId) {
15
16
  activeInteractive = undefined;
16
17
  }
17
18
  }
19
+ export function getActiveInteractiveTerminationStatus(sessionId) {
20
+ if (activeInteractive?.sessionId !== sessionId) {
21
+ return undefined;
22
+ }
23
+ return activeInteractive.terminationStatus;
24
+ }
18
25
  export async function terminateActiveInteractive(status, reason) {
19
26
  if (!activeInteractive || terminationInFlight) {
20
27
  return;
21
28
  }
22
29
  terminationInFlight = true;
23
30
  const context = activeInteractive;
31
+ context.terminationStatus = status;
24
32
  let persistenceError;
25
33
  try {
26
34
  terminateInteractiveProcess(context.process);
@@ -57,6 +65,7 @@ export async function terminateActiveInteractive(status, reason) {
57
65
  await runTeardown(context.teardown);
58
66
  }
59
67
  finally {
68
+ context.terminationStatus = undefined;
60
69
  terminationInFlight = false;
61
70
  activeInteractive = undefined;
62
71
  }
@@ -114,15 +123,22 @@ async function waitForInteractiveCompletion(completion) {
114
123
  ]);
115
124
  }
116
125
  function buildTerminatedRecord(record, status, reason) {
126
+ const lifecycle = buildRecordLifecycleCompleteFields({
127
+ existing: record,
128
+ startedAt: record.startedAt ?? record.createdAt,
129
+ completedAt: new Date().toISOString(),
130
+ });
117
131
  if (status === "aborted") {
118
132
  return {
119
133
  ...record,
120
134
  status: "succeeded",
135
+ ...lifecycle,
121
136
  };
122
137
  }
123
138
  return {
124
139
  ...record,
125
140
  status: "failed",
141
+ ...lifecycle,
126
142
  error: {
127
143
  code: "provider_launch_failed",
128
144
  message: buildTerminationMessage(status, reason),
@@ -6,6 +6,7 @@ export interface ListCommandInput {
6
6
  reductionsFilePath: string;
7
7
  messagesFilePath: string;
8
8
  verificationsFilePath: string;
9
+ interactiveFilePath: string;
9
10
  operator: ListOperator;
10
11
  sessionId?: string;
11
12
  limit?: number;