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
@@ -0,0 +1,32 @@
1
+ import type { AgentPreset } from "../configs/agents/defaults.js";
2
+ export declare const MANAGED_STATE_VERSION = 1;
3
+ export interface ManagedConfigFingerprint {
4
+ fingerprint: string;
5
+ }
6
+ export interface ManagedAgentsFingerprint extends ManagedConfigFingerprint {
7
+ managedEntriesFingerprint: string;
8
+ }
9
+ export interface ManagedOrchestrationFingerprint extends ManagedConfigFingerprint {
10
+ preset: AgentPreset;
11
+ }
12
+ export interface ManagedStateSnapshot {
13
+ version: number;
14
+ configs: {
15
+ agents?: ManagedAgentsFingerprint;
16
+ orchestration?: ManagedOrchestrationFingerprint;
17
+ };
18
+ }
19
+ export interface UpdateManagedStateOptions {
20
+ agentsContent?: string;
21
+ orchestrationContent?: string;
22
+ orchestrationPreset?: AgentPreset;
23
+ }
24
+ export declare function readManagedState(root: string): Promise<ManagedStateSnapshot | undefined>;
25
+ export declare function updateManagedState(root: string, options: UpdateManagedStateOptions): Promise<{
26
+ path: string;
27
+ created: boolean;
28
+ updated: boolean;
29
+ }>;
30
+ export declare function computeManagedFingerprint(content: string): string;
31
+ export declare function isManagedFingerprintMatch(fingerprint: ManagedConfigFingerprint | undefined, content: string): boolean;
32
+ export declare function isManagedAgentsFingerprintMatch(fingerprint: ManagedAgentsFingerprint | undefined, content: string): boolean;
@@ -0,0 +1,104 @@
1
+ import { createHash } from "node:crypto";
2
+ import { readFile, writeFile } from "node:fs/promises";
3
+ import { getAgentDefaultId, getSupportedAgentDefaults, } from "../configs/agents/defaults.js";
4
+ import { readAgentsConfig } from "../configs/agents/loader.js";
5
+ import { isFileSystemError } from "../utils/fs.js";
6
+ import { normalizeConfigText } from "../utils/yaml.js";
7
+ import { VORATIQ_MANAGED_STATE_FILE } from "./constants.js";
8
+ import { resolveWorkspacePath } from "./path-resolvers.js";
9
+ import { serializeAgentsConfigEntries } from "./templates.js";
10
+ export const MANAGED_STATE_VERSION = 1;
11
+ export async function readManagedState(root) {
12
+ const path = resolveWorkspacePath(root, VORATIQ_MANAGED_STATE_FILE);
13
+ try {
14
+ const content = await readFile(path, "utf8");
15
+ return JSON.parse(content);
16
+ }
17
+ catch (error) {
18
+ if (isFileSystemError(error) && error.code === "ENOENT") {
19
+ return undefined;
20
+ }
21
+ throw error;
22
+ }
23
+ }
24
+ export async function updateManagedState(root, options) {
25
+ const path = resolveWorkspacePath(root, VORATIQ_MANAGED_STATE_FILE);
26
+ const existing = await readManagedState(root);
27
+ const next = existing
28
+ ? {
29
+ ...existing,
30
+ version: MANAGED_STATE_VERSION,
31
+ configs: { ...existing.configs },
32
+ }
33
+ : { version: MANAGED_STATE_VERSION, configs: {} };
34
+ if (options.agentsContent !== undefined) {
35
+ next.configs.agents = {
36
+ fingerprint: computeManagedFingerprint(options.agentsContent),
37
+ managedEntriesFingerprint: computeManagedAgentsEntriesFingerprint(options.agentsContent),
38
+ };
39
+ }
40
+ if (options.orchestrationContent !== undefined) {
41
+ next.configs.orchestration = {
42
+ fingerprint: computeManagedFingerprint(options.orchestrationContent),
43
+ preset: options.orchestrationPreset ?? "pro",
44
+ };
45
+ }
46
+ const serialized = serializeManagedState(next);
47
+ const previousSerialized = existing ? serializeManagedState(existing) : "";
48
+ if (serialized === previousSerialized) {
49
+ return { path, created: false, updated: false };
50
+ }
51
+ await writeFile(path, serialized, "utf8");
52
+ return {
53
+ path,
54
+ created: existing === undefined,
55
+ updated: true,
56
+ };
57
+ }
58
+ export function computeManagedFingerprint(content) {
59
+ return createHash("sha256")
60
+ .update(normalizeConfigText(content), "utf8")
61
+ .digest("hex");
62
+ }
63
+ export function isManagedFingerprintMatch(fingerprint, content) {
64
+ if (!fingerprint) {
65
+ return false;
66
+ }
67
+ return fingerprint.fingerprint === computeManagedFingerprint(content);
68
+ }
69
+ export function isManagedAgentsFingerprintMatch(fingerprint, content) {
70
+ if (!fingerprint) {
71
+ return false;
72
+ }
73
+ return (fingerprint.fingerprint === computeManagedFingerprint(content) ||
74
+ fingerprint.managedEntriesFingerprint ===
75
+ computeManagedAgentsEntriesFingerprint(content));
76
+ }
77
+ function serializeManagedState(state) {
78
+ return `${JSON.stringify(state, null, 2)}\n`;
79
+ }
80
+ function computeManagedAgentsEntriesFingerprint(content) {
81
+ const config = readAgentsConfig(content);
82
+ const entriesById = new Map();
83
+ for (const entry of config.agents) {
84
+ entriesById.set(entry.id, normalizeAgentEntry(entry));
85
+ }
86
+ const managedEntries = getSupportedAgentDefaults()
87
+ .map((template) => entriesById.get(getAgentDefaultId(template)))
88
+ .filter((entry) => entry !== undefined);
89
+ return createHash("sha256")
90
+ .update(normalizeConfigText(`agents:\n${serializeAgentsConfigEntries(managedEntries)}`), "utf8")
91
+ .digest("hex");
92
+ }
93
+ function normalizeAgentEntry(entry) {
94
+ return {
95
+ id: entry.id,
96
+ provider: entry.provider,
97
+ model: entry.model,
98
+ enabled: entry.enabled !== false,
99
+ binary: entry.binary ?? "",
100
+ extraArgs: entry.extraArgs && entry.extraArgs.length > 0
101
+ ? [...entry.extraArgs]
102
+ : undefined,
103
+ };
104
+ }
@@ -0,0 +1,9 @@
1
+ export declare function formatWorkspacePath(...segments: string[]): string;
2
+ export declare function assertPathSegment(label: "runId" | "agentId" | "segment" | "domain" | "sessionId", value: string): string;
3
+ export declare function assertDomainSegment(domain: string): string;
4
+ export declare function assertSessionId(sessionId: string): string;
5
+ export declare function formatDomainScopedPath(domain: string, ...segments: string[]): string;
6
+ export declare function formatSessionScopedPath(domain: string, sessionId: string, ...segments: string[]): string;
7
+ export declare function formatAgentSessionScopedPath(domain: string, sessionId: string, agentId: string, ...segments: string[]): string;
8
+ export declare function formatRunScopedPath(runId: string, ...segments: string[]): string;
9
+ export declare function formatAgentScopedPath(runId: string, agentId: string, ...segments: string[]): string;
@@ -0,0 +1,46 @@
1
+ import { agentIdSchema } from "../configs/agents/types.js";
2
+ import { assertRepoRelativePath } from "../utils/path.js";
3
+ import { VORATIQ_DIR, VORATIQ_RUN_DIR, VORATIQ_SESSIONS_DIRNAME, } from "./constants.js";
4
+ export function formatWorkspacePath(...segments) {
5
+ return [VORATIQ_DIR, ...segments].join("/");
6
+ }
7
+ export function assertPathSegment(label, value) {
8
+ if (typeof value !== "string") {
9
+ throw new Error(`${label} must be a string`);
10
+ }
11
+ if (value.length === 0) {
12
+ throw new Error(`${label} must be non-empty`);
13
+ }
14
+ if (value.includes("/") || value.includes("\\") || value.includes("..")) {
15
+ throw new Error(`${label} \`${value}\` must not contain path separators`);
16
+ }
17
+ return value;
18
+ }
19
+ export function assertDomainSegment(domain) {
20
+ return assertPathSegment("domain", domain);
21
+ }
22
+ export function assertSessionId(sessionId) {
23
+ return assertPathSegment("sessionId", sessionId);
24
+ }
25
+ export function formatDomainScopedPath(domain, ...segments) {
26
+ const safeDomain = assertDomainSegment(domain);
27
+ const scoped = formatWorkspacePath(safeDomain, ...segments);
28
+ return assertRepoRelativePath(scoped);
29
+ }
30
+ export function formatSessionScopedPath(domain, sessionId, ...segments) {
31
+ const safeSessionId = assertSessionId(sessionId);
32
+ return formatDomainScopedPath(domain, VORATIQ_SESSIONS_DIRNAME, safeSessionId, ...segments);
33
+ }
34
+ export function formatAgentSessionScopedPath(domain, sessionId, agentId, ...segments) {
35
+ const safeAgentId = agentIdSchema.parse(agentId);
36
+ return formatSessionScopedPath(domain, sessionId, safeAgentId, ...segments);
37
+ }
38
+ export function formatRunScopedPath(runId, ...segments) {
39
+ const safeRunId = assertPathSegment("runId", runId);
40
+ const scoped = formatDomainScopedPath(VORATIQ_RUN_DIR, VORATIQ_SESSIONS_DIRNAME, safeRunId, ...segments);
41
+ return assertRepoRelativePath(scoped);
42
+ }
43
+ export function formatAgentScopedPath(runId, agentId, ...segments) {
44
+ const safeAgentId = agentIdSchema.parse(agentId);
45
+ return formatRunScopedPath(runId, safeAgentId, ...segments);
46
+ }
@@ -0,0 +1 @@
1
+ export declare function resolveWorkspacePath(root: string, ...segments: string[]): string;
@@ -0,0 +1,5 @@
1
+ import { resolvePathWithinRoot } from "../utils/path.js";
2
+ import { VORATIQ_DIR } from "./constants.js";
3
+ export function resolveWorkspacePath(root, ...segments) {
4
+ return resolvePathWithinRoot(root, [VORATIQ_DIR, ...segments]);
5
+ }
@@ -0,0 +1,16 @@
1
+ export declare function getInteractiveIndexPath(): string;
2
+ export declare function getInteractiveHistoryLockPath(): string;
3
+ export declare function getInteractiveSessionsDirectoryPath(): string;
4
+ export declare function getInteractiveSessionDirectoryPath(sessionId: string): string;
5
+ export declare function getInteractiveSessionRecordPath(sessionId: string): string;
6
+ export declare function getInteractiveSessionArtifactsDirectoryPath(sessionId: string): string;
7
+ export declare function getSpecSessionDirectoryPath(sessionId: string): string;
8
+ export declare function getReductionSessionDirectoryPath(sessionId: string): string;
9
+ export declare function getMessageSessionDirectoryPath(sessionId: string): string;
10
+ export declare function getVerificationSessionDirectoryPath(sessionId: string): string;
11
+ export declare function getAgentSessionDirectoryPath(domain: string, sessionId: string, agentId: string): string;
12
+ export declare function getAgentSessionWorkspaceDirectoryPath(domain: string, sessionId: string, agentId: string): string;
13
+ export declare function getAgentSessionContextDirectoryPath(domain: string, sessionId: string, agentId: string): string;
14
+ export declare function getAgentSessionArtifactsDirectoryPath(domain: string, sessionId: string, agentId: string): string;
15
+ export declare function getRunDirectoryPath(runId: string): string;
16
+ export declare function getAgentDirectoryPath(runId: string, agentId: string): string;
@@ -0,0 +1,59 @@
1
+ import { ARTIFACTS_DIRNAME, CONTEXT_DIRNAME, VORATIQ_HISTORY_LOCK_FILENAME, VORATIQ_INDEX_FILENAME, VORATIQ_INTERACTIVE_DIR, VORATIQ_MESSAGE_DIR, VORATIQ_REDUCTION_DIR, VORATIQ_SESSIONS_DIRNAME, VORATIQ_SPEC_DIR, VORATIQ_VERIFICATION_DIR, WORKSPACE_DIRNAME, } from "./constants.js";
2
+ import { formatAgentScopedPath, formatAgentSessionScopedPath, formatDomainScopedPath, formatRunScopedPath, formatSessionScopedPath, } from "./path-formatters.js";
3
+ function getDomainIndexPath(domain) {
4
+ return formatDomainScopedPath(domain, VORATIQ_INDEX_FILENAME);
5
+ }
6
+ export function getInteractiveIndexPath() {
7
+ return getDomainIndexPath(VORATIQ_INTERACTIVE_DIR);
8
+ }
9
+ export function getInteractiveHistoryLockPath() {
10
+ return formatDomainScopedPath(VORATIQ_INTERACTIVE_DIR, VORATIQ_HISTORY_LOCK_FILENAME);
11
+ }
12
+ export function getInteractiveSessionsDirectoryPath() {
13
+ return getDomainSessionsDirectoryPath(VORATIQ_INTERACTIVE_DIR);
14
+ }
15
+ export function getInteractiveSessionDirectoryPath(sessionId) {
16
+ return getSessionDirectoryPath(VORATIQ_INTERACTIVE_DIR, sessionId);
17
+ }
18
+ export function getInteractiveSessionRecordPath(sessionId) {
19
+ return formatSessionScopedPath(VORATIQ_INTERACTIVE_DIR, sessionId, "record.json");
20
+ }
21
+ export function getInteractiveSessionArtifactsDirectoryPath(sessionId) {
22
+ return formatSessionScopedPath(VORATIQ_INTERACTIVE_DIR, sessionId, ARTIFACTS_DIRNAME);
23
+ }
24
+ function getDomainSessionsDirectoryPath(domain) {
25
+ return formatDomainScopedPath(domain, VORATIQ_SESSIONS_DIRNAME);
26
+ }
27
+ function getSessionDirectoryPath(domain, sessionId) {
28
+ return formatSessionScopedPath(domain, sessionId);
29
+ }
30
+ export function getSpecSessionDirectoryPath(sessionId) {
31
+ return getSessionDirectoryPath(VORATIQ_SPEC_DIR, sessionId);
32
+ }
33
+ export function getReductionSessionDirectoryPath(sessionId) {
34
+ return getSessionDirectoryPath(VORATIQ_REDUCTION_DIR, sessionId);
35
+ }
36
+ export function getMessageSessionDirectoryPath(sessionId) {
37
+ return getSessionDirectoryPath(VORATIQ_MESSAGE_DIR, sessionId);
38
+ }
39
+ export function getVerificationSessionDirectoryPath(sessionId) {
40
+ return getSessionDirectoryPath(VORATIQ_VERIFICATION_DIR, sessionId);
41
+ }
42
+ export function getAgentSessionDirectoryPath(domain, sessionId, agentId) {
43
+ return formatAgentSessionScopedPath(domain, sessionId, agentId);
44
+ }
45
+ export function getAgentSessionWorkspaceDirectoryPath(domain, sessionId, agentId) {
46
+ return formatAgentSessionScopedPath(domain, sessionId, agentId, WORKSPACE_DIRNAME);
47
+ }
48
+ export function getAgentSessionContextDirectoryPath(domain, sessionId, agentId) {
49
+ return formatAgentSessionScopedPath(domain, sessionId, agentId, CONTEXT_DIRNAME);
50
+ }
51
+ export function getAgentSessionArtifactsDirectoryPath(domain, sessionId, agentId) {
52
+ return formatAgentSessionScopedPath(domain, sessionId, agentId, ARTIFACTS_DIRNAME);
53
+ }
54
+ export function getRunDirectoryPath(runId) {
55
+ return formatRunScopedPath(runId);
56
+ }
57
+ export function getAgentDirectoryPath(runId, agentId) {
58
+ return formatAgentScopedPath(runId, agentId);
59
+ }
@@ -1,13 +1,15 @@
1
1
  import { mkdir, readFile, writeFile } from "node:fs/promises";
2
- import { dirname, join } from "node:path";
2
+ import { dirname, join, resolve as resolveAbsolute } from "node:path";
3
3
  import { readAgentsConfig } from "../configs/agents/loader.js";
4
4
  import { loadEnvironmentConfig, } from "../configs/environment/loader.js";
5
5
  import { buildDefaultOrchestrationTemplate } from "../configs/orchestration/bootstrap.js";
6
6
  import { toErrorMessage } from "../utils/errors.js";
7
7
  import { isDirectory, isFile, pathExists } from "../utils/fs.js";
8
8
  import { relativeToRoot } from "../utils/path.js";
9
+ import { VORATIQ_AGENTS_FILE, VORATIQ_ENVIRONMENT_FILE, VORATIQ_INTERACTIVE_DIR, VORATIQ_INTERACTIVE_FILE, VORATIQ_INTERACTIVE_SESSIONS_DIR, VORATIQ_MANAGED_STATE_FILE, VORATIQ_MESSAGE_DIR, VORATIQ_MESSAGE_FILE, VORATIQ_MESSAGE_SESSIONS_DIR, VORATIQ_ORCHESTRATION_FILE, VORATIQ_REDUCTION_DIR, VORATIQ_REDUCTION_FILE, VORATIQ_REDUCTION_SESSIONS_DIR, VORATIQ_RUN_DIR, VORATIQ_RUN_FILE, VORATIQ_RUN_SESSIONS_DIR, VORATIQ_SANDBOX_FILE, VORATIQ_SPEC_DIR, VORATIQ_SPEC_FILE, VORATIQ_SPEC_SESSIONS_DIR, VORATIQ_VERIFICATION_CONFIG_FILE, VORATIQ_VERIFICATION_DIR, VORATIQ_VERIFICATION_FILE, VORATIQ_VERIFICATION_SESSIONS_DIR, VORATIQ_VERIFICATION_TEMPLATES_DIR, } from "./constants.js";
9
10
  import { WorkspaceMissingEntryError, WorkspaceNotInitializedError, WorkspaceSetupError, WorkspaceWrongTypeEntryError, } from "./errors.js";
10
- import { resolveWorkspacePath, VORATIQ_AGENTS_FILE, VORATIQ_ENVIRONMENT_FILE, VORATIQ_INTERACTIVE_DIR, VORATIQ_INTERACTIVE_FILE, VORATIQ_INTERACTIVE_SESSIONS_DIR, VORATIQ_MESSAGE_DIR, VORATIQ_MESSAGE_FILE, VORATIQ_MESSAGE_SESSIONS_DIR, VORATIQ_ORCHESTRATION_FILE, VORATIQ_REDUCTION_DIR, VORATIQ_REDUCTION_FILE, VORATIQ_REDUCTION_SESSIONS_DIR, VORATIQ_RUN_DIR, VORATIQ_RUN_FILE, VORATIQ_RUN_SESSIONS_DIR, VORATIQ_SANDBOX_FILE, VORATIQ_SPEC_DIR, VORATIQ_SPEC_FILE, VORATIQ_SPEC_SESSIONS_DIR, VORATIQ_VERIFICATION_CONFIG_FILE, VORATIQ_VERIFICATION_DIR, VORATIQ_VERIFICATION_FILE, VORATIQ_VERIFICATION_SESSIONS_DIR, VORATIQ_VERIFICATION_TEMPLATES_DIR, } from "./structure.js";
11
+ import { updateManagedState } from "./managed-state.js";
12
+ import { resolveWorkspacePath } from "./path-resolvers.js";
11
13
  import { buildDefaultAgentsTemplate, buildDefaultEnvironmentTemplate, buildDefaultSandboxTemplate, } from "./templates.js";
12
14
  import { buildDefaultVerificationConfigYaml, SHIPPED_VERIFICATION_TEMPLATES, } from "./verification-defaults.js";
13
15
  async function seedVerificationSurface(root, options = {}) {
@@ -99,6 +101,12 @@ const WORKSPACE_CONFIG_SEGMENTS = [
99
101
  VORATIQ_SANDBOX_FILE,
100
102
  VORATIQ_ORCHESTRATION_FILE,
101
103
  ];
104
+ const VOLATILE_WORKSPACE_EXCLUDE_PATTERNS = [
105
+ "/.voratiq/*/index.json",
106
+ "/.voratiq/*/sessions/",
107
+ "/.voratiq/*/history.lock",
108
+ ];
109
+ const VOLATILE_WORKSPACE_EXCLUDE_HEADER = "# voratiq runtime state (auto-managed)";
102
110
  export async function createWorkspace(root) {
103
111
  const createdDirectories = [];
104
112
  const createdFiles = [];
@@ -109,6 +117,7 @@ export async function createWorkspace(root) {
109
117
  const sandboxConfigPath = resolveWorkspacePath(root, VORATIQ_SANDBOX_FILE);
110
118
  const orchestrationConfigPath = resolveWorkspacePath(root, VORATIQ_ORCHESTRATION_FILE);
111
119
  const verificationConfigPath = resolveWorkspacePath(root, VORATIQ_VERIFICATION_CONFIG_FILE);
120
+ const managedStatePath = resolveWorkspacePath(root, VORATIQ_MANAGED_STATE_FILE);
112
121
  const workspaceExists = await pathExists(workspaceDir);
113
122
  const [agentsConfigExists, environmentConfigExists] = await Promise.all([
114
123
  pathExists(agentsConfigPath),
@@ -123,6 +132,7 @@ export async function createWorkspace(root) {
123
132
  await mkdir(workspaceDir, { recursive: true });
124
133
  createdDirectories.push(relativeToRoot(root, workspaceDir));
125
134
  }
135
+ await ensureWorkspaceGitExclude(root);
126
136
  for (const domain of domainStructures) {
127
137
  if (!(await pathExists(domain.directoryPath))) {
128
138
  await mkdir(domain.directoryPath, { recursive: true });
@@ -165,6 +175,20 @@ export async function createWorkspace(root) {
165
175
  });
166
176
  createdFiles.push(relativeToRoot(root, orchestrationConfigPath));
167
177
  }
178
+ if (!agentsConfigExists || !orchestrationConfigExists) {
179
+ const [agentsContent, orchestrationContent] = await Promise.all([
180
+ readFile(agentsConfigPath, "utf8"),
181
+ readFile(orchestrationConfigPath, "utf8"),
182
+ ]);
183
+ const managedStateResult = await updateManagedState(root, {
184
+ agentsContent,
185
+ orchestrationContent,
186
+ orchestrationPreset: "pro",
187
+ });
188
+ if (managedStateResult.created) {
189
+ createdFiles.push(relativeToRoot(root, managedStatePath));
190
+ }
191
+ }
168
192
  const seededVerification = await seedVerificationSurface(root, {
169
193
  verificationConfigPath,
170
194
  configExists: verificationExists,
@@ -178,6 +202,7 @@ export async function repairWorkspaceStructure(root, options = {}) {
178
202
  const createdFiles = [];
179
203
  const workspaceDir = resolveWorkspacePath(root);
180
204
  await ensureWorkspaceDirectoryEntry(root, workspaceDir);
205
+ await ensureWorkspaceGitExclude(root);
181
206
  // Additive repair must not mutate config semantics.
182
207
  for (const configPath of resolveWorkspaceConfigPaths(root)) {
183
208
  const kind = await detectPathKind(configPath);
@@ -359,6 +384,46 @@ async function detectPathKind(path) {
359
384
  }
360
385
  return "other";
361
386
  }
387
+ async function ensureWorkspaceGitExclude(root) {
388
+ const excludePath = await resolveGitExcludePath(root);
389
+ if (!excludePath) {
390
+ return;
391
+ }
392
+ const existing = (await pathExists(excludePath))
393
+ ? await readFile(excludePath, "utf8")
394
+ : "";
395
+ const lines = existing.split(/\r?\n/u);
396
+ const missingPatterns = VOLATILE_WORKSPACE_EXCLUDE_PATTERNS.filter((pattern) => !lines.includes(pattern));
397
+ if (missingPatterns.length === 0) {
398
+ return;
399
+ }
400
+ const nextLines = existing.length > 0 && !existing.endsWith("\n")
401
+ ? [...lines, VOLATILE_WORKSPACE_EXCLUDE_HEADER, ...missingPatterns]
402
+ : [
403
+ ...lines.filter((line, index, all) => !(index === all.length - 1 && line === "")),
404
+ VOLATILE_WORKSPACE_EXCLUDE_HEADER,
405
+ ...missingPatterns,
406
+ ];
407
+ await mkdir(dirname(excludePath), { recursive: true });
408
+ await writeFile(excludePath, `${nextLines.join("\n")}\n`, "utf8");
409
+ }
410
+ async function resolveGitExcludePath(root) {
411
+ const gitEntryPath = join(root, ".git");
412
+ const kind = await detectPathKind(gitEntryPath);
413
+ if (kind === "directory") {
414
+ return join(gitEntryPath, "info", "exclude");
415
+ }
416
+ if (kind !== "file") {
417
+ return undefined;
418
+ }
419
+ const raw = await readFile(gitEntryPath, "utf8");
420
+ const match = raw.match(/^gitdir:\s*(.+)\s*$/mu);
421
+ if (!match) {
422
+ return undefined;
423
+ }
424
+ const gitDir = resolveAbsolute(root, match[1]);
425
+ return join(gitDir, "info", "exclude");
426
+ }
362
427
  async function validateWorkspaceIndexFile(root, domain) {
363
428
  const displayPath = relativeToRoot(root, domain.indexPath);
364
429
  let raw;
@@ -1,3 +1,4 @@
1
+ export declare const WORKSPACE_SHIM_RELATIVE_PATH: readonly ["dist", "commands", "run", "shim", "run-agent-shim.mjs"];
1
2
  export declare function ensureWorkspaceShim(options: {
2
3
  workspacePath: string;
3
4
  cliInstallRoot?: string;
@@ -4,7 +4,7 @@ import { fileURLToPath } from "node:url";
4
4
  import { isFileSystemError } from "../utils/fs.js";
5
5
  import { resolvePath } from "../utils/path.js";
6
6
  import { WorkspaceSetupError } from "./errors.js";
7
- const SHIM_RELATIVE_PATH = [
7
+ export const WORKSPACE_SHIM_RELATIVE_PATH = [
8
8
  "dist",
9
9
  "commands",
10
10
  "run",
@@ -16,8 +16,8 @@ function resolveCliInstallRoot() {
16
16
  }
17
17
  export async function ensureWorkspaceShim(options) {
18
18
  const { workspacePath, cliInstallRoot = resolveCliInstallRoot() } = options;
19
- const sourcePath = resolvePath(cliInstallRoot, ...SHIM_RELATIVE_PATH);
20
- const targetPath = resolvePath(workspacePath, ...SHIM_RELATIVE_PATH);
19
+ const sourcePath = resolvePath(cliInstallRoot, ...WORKSPACE_SHIM_RELATIVE_PATH);
20
+ const targetPath = resolvePath(workspacePath, ...WORKSPACE_SHIM_RELATIVE_PATH);
21
21
  try {
22
22
  await access(sourcePath);
23
23
  await mkdir(dirname(targetPath), { recursive: true });
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "voratiq",
3
- "version": "0.1.0-beta.21",
4
- "description": "Agent ensembles to design, generate, and select the best code for every task.",
3
+ "version": "0.1.0-beta.23",
4
+ "description": "Run workflows, delegate to swarms, and verify outputs before you apply them.",
5
5
  "keywords": [
6
6
  "agent-ensembles",
7
7
  "agent-orchestration",
@@ -1,15 +0,0 @@
1
- import { Command } from "commander";
2
- import type { InitCommandResult } from "../commands/init/types.js";
3
- import type { AgentPreset } from "../workspace/templates.js";
4
- import { type CommandOutputWriter } from "./output.js";
5
- export interface RunInitCommandResult extends InitCommandResult {
6
- body: string;
7
- }
8
- export interface InitCommandOptions {
9
- yes?: boolean;
10
- preset?: AgentPreset;
11
- presetProvided?: boolean;
12
- writeOutput?: CommandOutputWriter;
13
- }
14
- export declare function runInitCommand(options?: InitCommandOptions): Promise<RunInitCommandResult>;
15
- export declare function createInitCommand(): Command;
package/dist/cli/init.js DELETED
@@ -1,70 +0,0 @@
1
- import { Command, Option } from "commander";
2
- import { executeInitCommand } from "../commands/init/command.js";
3
- import { resolveCliContext } from "../preflight/index.js";
4
- import { renderInitTranscript } from "../render/transcripts/init.js";
5
- import { AGENT_PRESET_CHOICES } from "../workspace/templates.js";
6
- import { createConfirmationWorkflow } from "./confirmation.js";
7
- import { NonInteractiveShellError } from "./errors.js";
8
- import { writeCommandOutput } from "./output.js";
9
- export async function runInitCommand(options = {}) {
10
- const { writeOutput = writeCommandOutput } = options;
11
- writeOutput({
12
- alerts: [{ severity: "info", message: "Initializing Voratiq…" }],
13
- });
14
- const { root } = await resolveCliContext({ requireWorkspace: false });
15
- const assumeYes = Boolean(options.yes);
16
- const preset = options.preset ?? "pro";
17
- const presetProvided = Boolean(options.presetProvided);
18
- const confirmation = createConfirmationWorkflow({
19
- assumeYes,
20
- onUnavailable: () => {
21
- throw new NonInteractiveShellError();
22
- },
23
- });
24
- let wroteConfiguringPreface = false;
25
- try {
26
- const initResult = await executeInitCommand({
27
- root,
28
- preset,
29
- presetProvided,
30
- onPresetResolved: () => {
31
- writeOutput({
32
- alerts: [{ severity: "info", message: "Configuring workspace…" }],
33
- });
34
- wroteConfiguringPreface = true;
35
- },
36
- assumeYes,
37
- interactive: confirmation.interactive,
38
- confirm: confirmation.confirm,
39
- prompt: confirmation.prompt,
40
- });
41
- const body = renderInitTranscript(initResult, {
42
- includeConfigurationHeading: !wroteConfiguringPreface,
43
- });
44
- return { ...initResult, body };
45
- }
46
- finally {
47
- confirmation.close();
48
- }
49
- }
50
- export function createInitCommand() {
51
- const presetOption = new Option("--preset <preset>", "Select a preset")
52
- .choices(AGENT_PRESET_CHOICES)
53
- .default("pro");
54
- return new Command("init")
55
- .description("Initialize the Voratiq workspace")
56
- .addOption(presetOption)
57
- .option("-y, --yes", "Assume yes and accept defaults")
58
- .allowExcessArguments(false)
59
- .action(async (commandOptions, command) => {
60
- const presetSource = command.getOptionValueSource("preset");
61
- const presetProvided = typeof presetSource === "string" && presetSource !== "default";
62
- const result = await runInitCommand({
63
- ...commandOptions,
64
- presetProvided,
65
- });
66
- writeCommandOutput({
67
- body: result.body,
68
- });
69
- });
70
- }
@@ -1,4 +0,0 @@
1
- import { type AgentPreset } from "../../workspace/templates.js";
2
- import type { AgentInitSummary, InitConfigureOptions } from "./types.js";
3
- export declare const AGENTS_CONFIG_DISPLAY_PATH: string;
4
- export declare function configureAgents(root: string, preset: AgentPreset, options: InitConfigureOptions): Promise<AgentInitSummary>;
@@ -1,2 +0,0 @@
1
- import type { InitCommandInput, InitCommandResult } from "./types.js";
2
- export declare function executeInitCommand(input: InitCommandInput): Promise<InitCommandResult>;
@@ -1,2 +0,0 @@
1
- import type { EnvironmentInitSummary, InitConfigureOptions } from "./types.js";
2
- export declare function configureEnvironment(root: string, options: InitConfigureOptions): Promise<EnvironmentInitSummary>;
@@ -1,7 +0,0 @@
1
- import type { InitCommandResult } from "../../commands/init/types.js";
2
- export declare function renderPresetPromptPreface(firstPrompt: boolean): string[];
3
- interface RenderInitTranscriptOptions {
4
- includeConfigurationHeading?: boolean;
5
- }
6
- export declare function renderInitTranscript({ preset, agentSummary, orchestrationSummary, environmentSummary, sandboxSummary, }: InitCommandResult, options?: RenderInitTranscriptOptions): string;
7
- export {};
@@ -1,83 +0,0 @@
1
- import { getAgentDefaultsForPreset } from "../../configs/agents/defaults.js";
2
- import { colorize } from "../../utils/colors.js";
3
- import { formatWorkspacePath, VORATIQ_VERIFICATION_CONFIG_FILE, } from "../../workspace/structure.js";
4
- import { renderTable } from "../utils/table.js";
5
- import { renderBlocks, renderTranscript } from "../utils/transcript.js";
6
- import { wrapWords } from "../utils/wrap.js";
7
- const INIT_NOTE_MAX_WIDTH = 79;
8
- export function renderPresetPromptPreface(firstPrompt) {
9
- const sections = [
10
- [
11
- "Which workspace preset would you like?",
12
- " [1] Pro (flagship)",
13
- " [2] Lite (faster/cheaper)",
14
- " [3] Manual (configure yourself)",
15
- ],
16
- ];
17
- return renderBlocks({
18
- sections,
19
- leadingBlankLine: firstPrompt,
20
- });
21
- }
22
- export function renderInitTranscript({ preset, agentSummary, orchestrationSummary, environmentSummary, sandboxSummary, }, options = {}) {
23
- const { includeConfigurationHeading = true } = options;
24
- const sections = [];
25
- if (includeConfigurationHeading) {
26
- sections.push(["Configuring workspace…"]);
27
- }
28
- sections.push(buildConfigurationSummaryTable({
29
- orchestrationPath: orchestrationSummary.configPath,
30
- agentsPath: agentSummary.configPath,
31
- verificationPath: formatWorkspacePath(VORATIQ_VERIFICATION_CONFIG_FILE),
32
- environmentPath: environmentSummary.configPath,
33
- sandboxPath: sandboxSummary.configPath,
34
- }));
35
- const conditionalNote = resolveConditionalInitNote({
36
- preset,
37
- agentSummary,
38
- });
39
- if (conditionalNote) {
40
- sections.push(wrapWords(conditionalNote, INIT_NOTE_MAX_WIDTH).map((line) => colorize(line, "yellow")));
41
- }
42
- sections.push([
43
- "Configuration docs:",
44
- " https://github.com/voratiq/voratiq/tree/main/docs/configs",
45
- ]);
46
- sections.push([buildWorkspaceInitializedSection()]);
47
- sections.push(["Run end-to-end:", ' voratiq auto --description "<task>"']);
48
- return renderTranscript({ sections });
49
- }
50
- function buildConfigurationSummaryTable(paths) {
51
- return renderTable({
52
- columns: [
53
- { header: "CONFIGURATION", accessor: (row) => row.configuration },
54
- { header: "FILE", accessor: (row) => row.path },
55
- ],
56
- rows: [
57
- { configuration: "agents", path: paths.agentsPath },
58
- { configuration: "orchestration", path: paths.orchestrationPath },
59
- { configuration: "verification", path: paths.verificationPath },
60
- { configuration: "environment", path: paths.environmentPath },
61
- { configuration: "sandbox", path: paths.sandboxPath },
62
- ],
63
- });
64
- }
65
- function buildWorkspaceInitializedSection() {
66
- return colorize("Voratiq initialized.", "green");
67
- }
68
- function resolveConditionalInitNote({ preset, agentSummary, }) {
69
- if (agentSummary.zeroDetections) {
70
- return "No agent CLIs detected on PATH. Install providers, then update `agents.yaml`.";
71
- }
72
- if (preset === "manual") {
73
- return "Manual preset leaves stages empty. Add agents to `orchestration.yaml`.";
74
- }
75
- const presetProviders = new Set(getAgentDefaultsForPreset(preset).map((agentDefault) => agentDefault.provider));
76
- const detectedProviders = new Set(agentSummary.detectedProviders.map((summary) => summary.provider));
77
- for (const presetProvider of presetProviders) {
78
- if (!detectedProviders.has(presetProvider)) {
79
- return "Some providers not found on PATH. Only detected providers were configured. Install missing ones, then update `agents.yaml`.";
80
- }
81
- }
82
- return undefined;
83
- }