@zhuk/spego 0.8.0 → 0.10.1

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 (105) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +57 -2
  3. package/dist/cli/body-input.d.ts +12 -0
  4. package/dist/cli/body-input.js +27 -0
  5. package/dist/cli/body-input.js.map +1 -0
  6. package/dist/cli/commands/artifact.d.ts +8 -0
  7. package/dist/cli/commands/artifact.js +171 -0
  8. package/dist/cli/commands/artifact.js.map +1 -0
  9. package/dist/cli/commands/delivery.d.ts +7 -0
  10. package/dist/cli/commands/delivery.js +99 -0
  11. package/dist/cli/commands/delivery.js.map +1 -0
  12. package/dist/cli/commands/index-rebuild.d.ts +5 -0
  13. package/dist/cli/commands/index-rebuild.js +31 -0
  14. package/dist/cli/commands/index-rebuild.js.map +1 -0
  15. package/dist/cli/commands/meta.d.ts +6 -0
  16. package/dist/cli/commands/meta.js +60 -0
  17. package/dist/cli/commands/meta.js.map +1 -0
  18. package/dist/cli/commands/orchestrate.d.ts +6 -0
  19. package/dist/cli/commands/orchestrate.js +51 -0
  20. package/dist/cli/commands/orchestrate.js.map +1 -0
  21. package/dist/cli/commands/skills.d.ts +5 -0
  22. package/dist/cli/commands/skills.js +49 -0
  23. package/dist/cli/commands/skills.js.map +1 -0
  24. package/dist/cli/commands/view.d.ts +8 -0
  25. package/dist/cli/commands/view.js +59 -0
  26. package/dist/cli/commands/view.js.map +1 -0
  27. package/dist/cli/commands/workspace.d.ts +5 -0
  28. package/dist/cli/commands/workspace.js +61 -0
  29. package/dist/cli/commands/workspace.js.map +1 -0
  30. package/dist/cli/errors.d.ts +20 -0
  31. package/dist/cli/errors.js +55 -0
  32. package/dist/cli/errors.js.map +1 -0
  33. package/dist/cli/output.d.ts +12 -0
  34. package/dist/cli/output.js +28 -0
  35. package/dist/cli/output.js.map +1 -0
  36. package/dist/cli/render.d.ts +7 -0
  37. package/dist/cli/render.js +22 -0
  38. package/dist/cli/render.js.map +1 -1
  39. package/dist/cli/runtime.d.ts +26 -0
  40. package/dist/cli/runtime.js +48 -0
  41. package/dist/cli/runtime.js.map +1 -0
  42. package/dist/cli.d.ts +8 -0
  43. package/dist/cli.js +65 -582
  44. package/dist/cli.js.map +1 -1
  45. package/dist/commands/registry.js +12 -0
  46. package/dist/commands/registry.js.map +1 -1
  47. package/dist/errors.d.ts +1 -1
  48. package/dist/errors.js.map +1 -1
  49. package/dist/index.d.ts +2 -0
  50. package/dist/index.js +1 -0
  51. package/dist/index.js.map +1 -1
  52. package/dist/orchestration/agents.d.ts +15 -0
  53. package/dist/orchestration/agents.js +156 -0
  54. package/dist/orchestration/agents.js.map +1 -0
  55. package/dist/orchestration/artifacts.d.ts +8 -0
  56. package/dist/orchestration/artifacts.js +20 -0
  57. package/dist/orchestration/artifacts.js.map +1 -0
  58. package/dist/orchestration/client.d.ts +59 -0
  59. package/dist/orchestration/client.js +107 -0
  60. package/dist/orchestration/client.js.map +1 -0
  61. package/dist/orchestration/config.d.ts +14 -0
  62. package/dist/orchestration/config.js +45 -0
  63. package/dist/orchestration/config.js.map +1 -0
  64. package/dist/orchestration/emit.d.ts +7 -0
  65. package/dist/orchestration/emit.js +19 -0
  66. package/dist/orchestration/emit.js.map +1 -0
  67. package/dist/orchestration/engine.d.ts +23 -0
  68. package/dist/orchestration/engine.js +136 -0
  69. package/dist/orchestration/engine.js.map +1 -0
  70. package/dist/orchestration/file-gate.d.ts +19 -0
  71. package/dist/orchestration/file-gate.js +25 -0
  72. package/dist/orchestration/file-gate.js.map +1 -0
  73. package/dist/orchestration/index.d.ts +18 -0
  74. package/dist/orchestration/index.js +12 -0
  75. package/dist/orchestration/index.js.map +1 -0
  76. package/dist/orchestration/manager.d.ts +13 -0
  77. package/dist/orchestration/manager.js +26 -0
  78. package/dist/orchestration/manager.js.map +1 -0
  79. package/dist/orchestration/prompts.d.ts +10 -0
  80. package/dist/orchestration/prompts.js +71 -0
  81. package/dist/orchestration/prompts.js.map +1 -0
  82. package/dist/orchestration/scheduler.d.ts +18 -0
  83. package/dist/orchestration/scheduler.js +49 -0
  84. package/dist/orchestration/scheduler.js.map +1 -0
  85. package/dist/orchestration/schema.d.ts +12 -0
  86. package/dist/orchestration/schema.js +78 -0
  87. package/dist/orchestration/schema.js.map +1 -0
  88. package/dist/orchestration/tiers.d.ts +14 -0
  89. package/dist/orchestration/tiers.js +57 -0
  90. package/dist/orchestration/tiers.js.map +1 -0
  91. package/dist/orchestration/types.d.ts +74 -0
  92. package/dist/orchestration/types.js +8 -0
  93. package/dist/orchestration/types.js.map +1 -0
  94. package/dist/orchestration/verifier.d.ts +14 -0
  95. package/dist/orchestration/verifier.js +66 -0
  96. package/dist/orchestration/verifier.js.map +1 -0
  97. package/dist/orchestration/worker.d.ts +16 -0
  98. package/dist/orchestration/worker.js +80 -0
  99. package/dist/orchestration/worker.js.map +1 -0
  100. package/dist/workspace/config.d.ts +69 -2
  101. package/dist/workspace/config.js +20 -0
  102. package/dist/workspace/config.js.map +1 -1
  103. package/dist/workspace/init.js +2 -0
  104. package/dist/workspace/init.js.map +1 -1
  105. package/package.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"emit.js","sourceRoot":"","sources":["../../src/orchestration/emit.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,IAAI,MAAM,WAAW,CAAC;AAC7B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE1D,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC;AAEzD,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,WAAmB;IAC/D,MAAM,KAAK,GAAoB,EAAE,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,0BAA0B,EAAE,CAAC;QAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACtD,MAAM,MAAM,GAAG,MAAM,kBAAkB,CAAC,OAAO,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QAChE,KAAK,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,EAAE,CAAC,CAAC;IACxC,CAAC;IACD,OAAO,EAAE,MAAM,EAAE,wBAAwB,EAAE,KAAK,EAAE,OAAO,EAAE,iBAAiB,EAAE,CAAC;AACjF,CAAC"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Top-level orchestration entrypoint.
3
+ *
4
+ * Reads a named OpenSpec change read-only, then runs the manager → swarm →
5
+ * verifier pipeline through the OpenCode REST API and returns a structured
6
+ * outcome. OpenSpec lifecycle state (apply/verify/sync/archive) is never
7
+ * mutated; only the working tree may change as workers implement sub-tasks.
8
+ */
9
+ import type { OpenCodeApi } from './client.js';
10
+ import type { ExecutionMode, OrchestrationOutcome } from './types.js';
11
+ export declare const AGENT_MANAGER = "ultramanager";
12
+ export declare const AGENT_WORKER = "ultraworker";
13
+ export declare const AGENT_VERIFIER = "ultraverifier";
14
+ export interface OrchestrateOptions {
15
+ projectRoot: string;
16
+ changeName: string;
17
+ mode?: ExecutionMode;
18
+ skipVerify?: boolean;
19
+ /** Inject a backend for testing; defaults to a real {@link OpenCodeClient}. */
20
+ client?: OpenCodeApi;
21
+ env?: Record<string, string | undefined>;
22
+ }
23
+ export declare function orchestrateChange(opts: OrchestrateOptions): Promise<OrchestrationOutcome>;
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Top-level orchestration entrypoint.
3
+ *
4
+ * Reads a named OpenSpec change read-only, then runs the manager → swarm →
5
+ * verifier pipeline through the OpenCode REST API and returns a structured
6
+ * outcome. OpenSpec lifecycle state (apply/verify/sync/archive) is never
7
+ * mutated; only the working tree may change as workers implement sub-tasks.
8
+ */
9
+ import fs from 'node:fs/promises';
10
+ import path from 'node:path';
11
+ import { resolveWorkspacePaths } from '../workspace/paths.js';
12
+ import { readConfig } from '../workspace/config.js';
13
+ import { discoverChanges } from '../delivery/openspec-discover.js';
14
+ import { SpegoError } from '../errors.js';
15
+ import { OpenCodeClient } from './client.js';
16
+ import { resolveOrchestrationConfig, assertModelsConfigured } from './config.js';
17
+ import { ensureWorkDir, saveArtifact, appendLog } from './artifacts.js';
18
+ import { runManager } from './manager.js';
19
+ import { runWorker } from './worker.js';
20
+ import { runVerifier } from './verifier.js';
21
+ import { runSwarm } from './scheduler.js';
22
+ export const AGENT_MANAGER = 'ultramanager';
23
+ export const AGENT_WORKER = 'ultraworker';
24
+ export const AGENT_VERIFIER = 'ultraverifier';
25
+ async function readMaybe(filePath) {
26
+ try {
27
+ return await fs.readFile(filePath, 'utf8');
28
+ }
29
+ catch {
30
+ return '';
31
+ }
32
+ }
33
+ async function buildRequirement(projectRoot, relPath) {
34
+ const dir = path.join(projectRoot, relPath);
35
+ const proposal = await readMaybe(path.join(dir, 'proposal.md'));
36
+ const design = await readMaybe(path.join(dir, 'design.md'));
37
+ const tasks = await readMaybe(path.join(dir, 'tasks.md'));
38
+ let specSections = '';
39
+ try {
40
+ const specsDir = path.join(dir, 'specs');
41
+ const entries = await fs.readdir(specsDir, { recursive: true });
42
+ const mdFiles = entries.filter((e) => e.endsWith('.md')).sort();
43
+ if (mdFiles.length > 0) {
44
+ const parts = await Promise.all(mdFiles.map(async (f) => {
45
+ const content = await readMaybe(path.join(specsDir, f));
46
+ return content.trim()
47
+ ? `### ${path.basename(f, '.md')}\n\n${content.trim()}`
48
+ : '';
49
+ }));
50
+ specSections = parts.filter(Boolean).join('\n\n');
51
+ }
52
+ }
53
+ catch {
54
+ // specs dir may not exist
55
+ }
56
+ return [
57
+ '# Change requirement',
58
+ proposal.trim(),
59
+ design.trim() ? `## Design\n\n${design.trim()}` : '',
60
+ specSections ? `## Specs\n\n${specSections}` : '',
61
+ tasks.trim() ? `## Planned tasks\n\n${tasks.trim()}` : '',
62
+ ]
63
+ .filter(Boolean)
64
+ .join('\n\n');
65
+ }
66
+ export async function orchestrateChange(opts) {
67
+ const projectRoot = path.resolve(opts.projectRoot);
68
+ const wsPaths = resolveWorkspacePaths(projectRoot);
69
+ const config = await readConfig(wsPaths.configPath);
70
+ const rc = resolveOrchestrationConfig(config, opts.env);
71
+ const changes = await discoverChanges(projectRoot);
72
+ const change = changes.find((c) => c.name === opts.changeName && !c.archived);
73
+ if (!change) {
74
+ throw new SpegoError('CHANGE_NOT_FOUND', `OpenSpec change "${opts.changeName}" not found`, {
75
+ changeName: opts.changeName,
76
+ });
77
+ }
78
+ assertModelsConfigured(rc);
79
+ const requirement = await buildRequirement(projectRoot, change.relPath);
80
+ const workDirAbs = await ensureWorkDir(projectRoot, path.join(rc.workDir, change.name));
81
+ await saveArtifact(workDirAbs, 'requirement.md', requirement);
82
+ const client = opts.client ??
83
+ new OpenCodeClient({ baseUrl: rc.serverUrl, username: rc.username, password: rc.password });
84
+ await client.health();
85
+ const breakdown = await runManager(client, {
86
+ requirement,
87
+ model: rc.models.manager,
88
+ agentName: AGENT_MANAGER,
89
+ workDirAbs,
90
+ });
91
+ await appendLog(workDirAbs, `manager: ${breakdown.subtasks.length} sub-tasks (mode=${breakdown.executionMode})`);
92
+ const swarm = await runSwarm(breakdown, {
93
+ mode: opts.mode,
94
+ maxParallel: rc.maxParallel,
95
+ runTask: (task) => runWorker(client, task, breakdown, {
96
+ model: rc.models.worker,
97
+ agentName: AGENT_WORKER,
98
+ projectRoot,
99
+ workDirAbs,
100
+ }),
101
+ });
102
+ for (const warning of swarm.warnings)
103
+ await appendLog(workDirAbs, `warning: ${warning}`);
104
+ let verdict;
105
+ if (opts.skipVerify) {
106
+ verdict = {
107
+ passed: swarm.results.every((r) => r.success),
108
+ testOutput: '',
109
+ failingCriteria: [],
110
+ regressions: [],
111
+ notes: 'Verification skipped.',
112
+ skipped: true,
113
+ };
114
+ await saveArtifact(workDirAbs, 'verdict.json', verdict);
115
+ }
116
+ else {
117
+ verdict = await runVerifier(client, breakdown, swarm.results, {
118
+ model: rc.models.verifier,
119
+ agentName: AGENT_VERIFIER,
120
+ workDirAbs,
121
+ });
122
+ }
123
+ const tasksSucceeded = swarm.results.filter((r) => r.success).length;
124
+ await appendLog(workDirAbs, `done: ${tasksSucceeded}/${swarm.results.length} succeeded; verdict=${verdict.passed ? 'PASS' : 'FAIL'}`);
125
+ return {
126
+ changeName: change.name,
127
+ goal: breakdown.goal,
128
+ executionMode: opts.mode ?? breakdown.executionMode,
129
+ tasksTotal: swarm.results.length,
130
+ tasksSucceeded,
131
+ results: swarm.results,
132
+ verdict,
133
+ warnings: swarm.warnings,
134
+ };
135
+ }
136
+ //# sourceMappingURL=engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"engine.js","sourceRoot":"","sources":["../../src/orchestration/engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Per-task file gate.
3
+ *
4
+ * Each worker may persist edits only to the files listed in its sub-task
5
+ * allow-list. Anything outside the list is reverted and the sub-task is
6
+ * marked failed. Detection is pure (and unit-tested); reverting is delegated
7
+ * to an injected callback so the policy stays decoupled from git/fs IO.
8
+ */
9
+ /** Return the changed paths that fall outside the allow-list. */
10
+ export declare function detectFileGateViolations(changedPaths: string[], allowed: string[]): string[];
11
+ export interface FileGateResult {
12
+ violations: string[];
13
+ }
14
+ /** Detect violations, revert each one through the supplied callback, and report them. */
15
+ export declare function enforceFileGate(opts: {
16
+ changedPaths: string[];
17
+ allowed: string[];
18
+ revert: (path: string) => Promise<void> | void;
19
+ }): Promise<FileGateResult>;
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Per-task file gate.
3
+ *
4
+ * Each worker may persist edits only to the files listed in its sub-task
5
+ * allow-list. Anything outside the list is reverted and the sub-task is
6
+ * marked failed. Detection is pure (and unit-tested); reverting is delegated
7
+ * to an injected callback so the policy stays decoupled from git/fs IO.
8
+ */
9
+ function normalizePath(p) {
10
+ return p.replace(/^\.\//, '').replace(/\\/g, '/').replace(/^\/+/, '');
11
+ }
12
+ /** Return the changed paths that fall outside the allow-list. */
13
+ export function detectFileGateViolations(changedPaths, allowed) {
14
+ const allow = new Set(allowed.map(normalizePath));
15
+ return changedPaths.filter((p) => !allow.has(normalizePath(p)));
16
+ }
17
+ /** Detect violations, revert each one through the supplied callback, and report them. */
18
+ export async function enforceFileGate(opts) {
19
+ const violations = detectFileGateViolations(opts.changedPaths, opts.allowed);
20
+ for (const violation of violations) {
21
+ await opts.revert(violation);
22
+ }
23
+ return { violations };
24
+ }
25
+ //# sourceMappingURL=file-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-gate.js","sourceRoot":"","sources":["../../src/orchestration/file-gate.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,SAAS,aAAa,CAAC,CAAS;IAC9B,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;AACxE,CAAC;AAED,iEAAiE;AACjE,MAAM,UAAU,wBAAwB,CAAC,YAAsB,EAAE,OAAiB;IAChF,MAAM,KAAK,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC;IAClD,OAAO,YAAY,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAClE,CAAC;AAMD,yFAAyF;AACzF,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAIrC;IACC,MAAM,UAAU,GAAG,wBAAwB,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IAC7E,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;QACnC,MAAM,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,EAAE,UAAU,EAAE,CAAC;AACxB,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Public surface for the ultracode multi-agent orchestration capability.
3
+ */
4
+ export { orchestrateChange, AGENT_MANAGER, AGENT_WORKER, AGENT_VERIFIER } from './engine.js';
5
+ export type { OrchestrateOptions } from './engine.js';
6
+ export { OpenCodeClient, extractText } from './client.js';
7
+ export type { OpenCodeApi, OpenCodeClientOptions, SendMessageInput, OpenCodeMessageResponse } from './client.js';
8
+ export { resolveOrchestrationConfig, assertModelsConfigured } from './config.js';
9
+ export { parseBreakdown, stripJsonFences } from './schema.js';
10
+ export { buildDependencyTiers } from './tiers.js';
11
+ export type { DependencyTiers } from './tiers.js';
12
+ export { runSwarm } from './scheduler.js';
13
+ export type { SwarmOptions, SwarmOutcome } from './scheduler.js';
14
+ export { detectFileGateViolations, enforceFileGate } from './file-gate.js';
15
+ export type { FileGateResult } from './file-gate.js';
16
+ export { ORCHESTRATION_AGENT_ASSETS } from './agents.js';
17
+ export type { OrchestrationAsset } from './agents.js';
18
+ export type { ExecutionMode, SubTask, TaskBreakdown, SubtaskResult, Verdict, OrchestrationModels, OrchestrationRuntimeConfig, OrchestrationOutcome, } from './types.js';
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Public surface for the ultracode multi-agent orchestration capability.
3
+ */
4
+ export { orchestrateChange, AGENT_MANAGER, AGENT_WORKER, AGENT_VERIFIER } from './engine.js';
5
+ export { OpenCodeClient, extractText } from './client.js';
6
+ export { resolveOrchestrationConfig, assertModelsConfigured } from './config.js';
7
+ export { parseBreakdown, stripJsonFences } from './schema.js';
8
+ export { buildDependencyTiers } from './tiers.js';
9
+ export { runSwarm } from './scheduler.js';
10
+ export { detectFileGateViolations, enforceFileGate } from './file-gate.js';
11
+ export { ORCHESTRATION_AGENT_ASSETS } from './agents.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/orchestration/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,iBAAiB,EAAE,aAAa,EAAE,YAAY,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAE7F,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1D,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AACjF,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAC9D,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAElD,OAAO,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAE,wBAAwB,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AAE3E,OAAO,EAAE,0BAA0B,EAAE,MAAM,aAAa,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Manager step: send the requirement to the manager agent, validate the
3
+ * returned breakdown against the schema, persist it, and return the model.
4
+ */
5
+ import type { OpenCodeApi } from './client.js';
6
+ import type { TaskBreakdown } from './types.js';
7
+ export interface ManagerOptions {
8
+ requirement: string;
9
+ model: string;
10
+ agentName: string;
11
+ workDirAbs: string;
12
+ }
13
+ export declare function runManager(api: OpenCodeApi, opts: ManagerOptions): Promise<TaskBreakdown>;
@@ -0,0 +1,26 @@
1
+ /**
2
+ * Manager step: send the requirement to the manager agent, validate the
3
+ * returned breakdown against the schema, persist it, and return the model.
4
+ */
5
+ import { extractText } from './client.js';
6
+ import { parseBreakdown } from './schema.js';
7
+ import { MANAGER_SYSTEM_PROMPT } from './prompts.js';
8
+ import { saveArtifact } from './artifacts.js';
9
+ export async function runManager(api, opts) {
10
+ const session = await api.createSession('spego-orchestrate-manager');
11
+ try {
12
+ const response = await api.sendMessage(session.id, {
13
+ text: opts.requirement,
14
+ model: opts.model,
15
+ agent: opts.agentName,
16
+ system: MANAGER_SYSTEM_PROMPT,
17
+ });
18
+ const breakdown = parseBreakdown(extractText(response));
19
+ await saveArtifact(opts.workDirAbs, 'breakdown.json', breakdown);
20
+ return breakdown;
21
+ }
22
+ finally {
23
+ await api.deleteSession(session.id).catch(() => undefined);
24
+ }
25
+ }
26
+ //# sourceMappingURL=manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../src/orchestration/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAE1C,OAAO,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,OAAO,EAAE,YAAY,EAAE,MAAM,gBAAgB,CAAC;AAU9C,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAgB,EAAE,IAAoB;IACrE,MAAM,OAAO,GAAG,MAAM,GAAG,CAAC,aAAa,CAAC,2BAA2B,CAAC,CAAC;IACrE,IAAI,CAAC;QACH,MAAM,QAAQ,GAAG,MAAM,GAAG,CAAC,WAAW,CAAC,OAAO,CAAC,EAAE,EAAE;YACjD,IAAI,EAAE,IAAI,CAAC,WAAW;YACtB,KAAK,EAAE,IAAI,CAAC,KAAK;YACjB,KAAK,EAAE,IAAI,CAAC,SAAS;YACrB,MAAM,EAAE,qBAAqB;SAC9B,CAAC,CAAC;QACH,MAAM,SAAS,GAAG,cAAc,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC,CAAC;QACxD,MAAM,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,gBAAgB,EAAE,SAAS,CAAC,CAAC;QACjE,OAAO,SAAS,CAAC;IACnB,CAAC;YAAS,CAAC;QACT,MAAM,GAAG,CAAC,aAAa,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,SAAS,CAAC,CAAC;IAC7D,CAAC;AACH,CAAC"}
@@ -0,0 +1,10 @@
1
+ /**
2
+ * System prompts for the orchestration agents, ported from the ultracode
3
+ * reference implementation. The manager emits a strict snake_case JSON
4
+ * contract; the worker reports a status marker; the verifier emits a verdict.
5
+ */
6
+ import type { SubTask, TaskBreakdown } from './types.js';
7
+ export declare const MANAGER_SYSTEM_PROMPT = "You are UltraManager, a senior software architect responsible for decomposing a coding task into precise, parallelisable sub-tasks.\n\nOutput ONLY valid JSON matching this schema \u2014 no prose, no markdown fences:\n{\n \"goal\": \"<one sentence>\",\n \"context_summary\": \"<=200 words summarising relevant codebase context>\",\n \"execution_mode\": \"sequential\" | \"parallel\" | \"adaptive\",\n \"test_command\": \"<shell command to run the full test suite>\",\n \"language\": \"<primary language>\",\n \"subtasks\": [\n {\n \"id\": \"<snake_case unique id>\",\n \"title\": \"<=60 chars>\",\n \"description\": \"<clear implementation instructions>\",\n \"files\": [\"<relative paths the worker may modify>\"],\n \"acceptance_criteria\": [\"<verifiable criterion>\"],\n \"depends_on\": [\"<other subtask id>\"],\n \"priority\": 0\n }\n ]\n}\n\nRules:\n- Each subtask must be self-contained enough to be implemented in one agent session.\n- Minimise cross-task file overlap to allow safe parallel execution.\n- If tasks share files, list them as depends_on (sequential chain).\n- acceptance_criteria must be executable assertions, not vague goals.\n- Do NOT include any text outside the JSON object.";
8
+ export declare const VERIFIER_SYSTEM_PROMPT = "You are UltraVerifier, a QA agent responsible for final validation.\nYou will receive a JSON summary of all completed sub-tasks and their changed files.\nYour job:\n1. Run the full test suite using the provided test command.\n2. Check that every acceptance criterion is satisfied.\n3. Report any regressions or missing criteria.\n4. Output ONLY a structured JSON verdict (no prose, no fences):\n{\n \"passed\": true | false,\n \"test_output\": \"<truncated stdout>\",\n \"failing_criteria\": [\"<criterion text>\"],\n \"regressions\": [\"<regression description>\"],\n \"notes\": \"<optional free text>\"\n}";
9
+ export declare function renderWorkerPrompt(task: SubTask, breakdown: TaskBreakdown): string;
10
+ export declare function renderVerifierPrompt(payload: unknown): string;
@@ -0,0 +1,71 @@
1
+ /**
2
+ * System prompts for the orchestration agents, ported from the ultracode
3
+ * reference implementation. The manager emits a strict snake_case JSON
4
+ * contract; the worker reports a status marker; the verifier emits a verdict.
5
+ */
6
+ export const MANAGER_SYSTEM_PROMPT = `You are UltraManager, a senior software architect responsible for decomposing a coding task into precise, parallelisable sub-tasks.
7
+
8
+ Output ONLY valid JSON matching this schema — no prose, no markdown fences:
9
+ {
10
+ "goal": "<one sentence>",
11
+ "context_summary": "<=200 words summarising relevant codebase context>",
12
+ "execution_mode": "sequential" | "parallel" | "adaptive",
13
+ "test_command": "<shell command to run the full test suite>",
14
+ "language": "<primary language>",
15
+ "subtasks": [
16
+ {
17
+ "id": "<snake_case unique id>",
18
+ "title": "<=60 chars>",
19
+ "description": "<clear implementation instructions>",
20
+ "files": ["<relative paths the worker may modify>"],
21
+ "acceptance_criteria": ["<verifiable criterion>"],
22
+ "depends_on": ["<other subtask id>"],
23
+ "priority": 0
24
+ }
25
+ ]
26
+ }
27
+
28
+ Rules:
29
+ - Each subtask must be self-contained enough to be implemented in one agent session.
30
+ - Minimise cross-task file overlap to allow safe parallel execution.
31
+ - If tasks share files, list them as depends_on (sequential chain).
32
+ - acceptance_criteria must be executable assertions, not vague goals.
33
+ - Do NOT include any text outside the JSON object.`;
34
+ export const VERIFIER_SYSTEM_PROMPT = `You are UltraVerifier, a QA agent responsible for final validation.
35
+ You will receive a JSON summary of all completed sub-tasks and their changed files.
36
+ Your job:
37
+ 1. Run the full test suite using the provided test command.
38
+ 2. Check that every acceptance criterion is satisfied.
39
+ 3. Report any regressions or missing criteria.
40
+ 4. Output ONLY a structured JSON verdict (no prose, no fences):
41
+ {
42
+ "passed": true | false,
43
+ "test_output": "<truncated stdout>",
44
+ "failing_criteria": ["<criterion text>"],
45
+ "regressions": ["<regression description>"],
46
+ "notes": "<optional free text>"
47
+ }`;
48
+ export function renderWorkerPrompt(task, breakdown) {
49
+ return `You are UltraWorker, a focused implementation agent.
50
+ You will implement a single sub-task precisely.
51
+
52
+ Codebase context:
53
+ ${breakdown.contextSummary}
54
+
55
+ Task spec (JSON):
56
+ ${JSON.stringify(task, null, 2)}
57
+
58
+ Rules:
59
+ - Modify ONLY the files listed in the \`files\` array.
60
+ - After implementing, run the test command to verify your changes:
61
+ ${breakdown.testCommand || '(no test command provided)'}
62
+ - If tests fail, fix them (max 3 attempts) before reporting done.
63
+ - End your final message with exactly:
64
+ ULTRAWORKER_STATUS: SUCCESS
65
+ or
66
+ ULTRAWORKER_STATUS: FAILED - <reason>`;
67
+ }
68
+ export function renderVerifierPrompt(payload) {
69
+ return `Here is the multi-agent execution summary. Run the test suite and emit your verdict JSON.\n\n${JSON.stringify(payload, null, 2)}`;
70
+ }
71
+ //# sourceMappingURL=prompts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompts.js","sourceRoot":"","sources":["../../src/orchestration/prompts.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,CAAC,MAAM,qBAAqB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;mDA2Bc,CAAC;AAEpD,MAAM,CAAC,MAAM,sBAAsB,GAAG;;;;;;;;;;;;;EAapC,CAAC;AAEH,MAAM,UAAU,kBAAkB,CAAC,IAAa,EAAE,SAAwB;IACxE,OAAO;;;;EAIP,SAAS,CAAC,cAAc;;;EAGxB,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;;;;;MAKzB,SAAS,CAAC,WAAW,IAAI,4BAA4B;;;;;0CAKjB,CAAC;AAC3C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,OAAgB;IACnD,OAAO,gGAAgG,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,CAAC;AAC5I,CAAC"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Swarm scheduler. Executes sub-tasks in `sequential`, `parallel`, or
3
+ * `adaptive` mode, honoring `dependsOn` edges and bounding concurrency.
4
+ *
5
+ * The actual per-task work is injected via `runTask`, keeping the scheduler
6
+ * free of any OpenCode/IO coupling and trivially unit-testable.
7
+ */
8
+ import type { ExecutionMode, SubTask, SubtaskResult, TaskBreakdown } from './types.js';
9
+ export interface SwarmOptions {
10
+ mode?: ExecutionMode;
11
+ maxParallel: number;
12
+ runTask: (task: SubTask) => Promise<SubtaskResult>;
13
+ }
14
+ export interface SwarmOutcome {
15
+ results: SubtaskResult[];
16
+ warnings: string[];
17
+ }
18
+ export declare function runSwarm(breakdown: TaskBreakdown, opts: SwarmOptions): Promise<SwarmOutcome>;
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Swarm scheduler. Executes sub-tasks in `sequential`, `parallel`, or
3
+ * `adaptive` mode, honoring `dependsOn` edges and bounding concurrency.
4
+ *
5
+ * The actual per-task work is injected via `runTask`, keeping the scheduler
6
+ * free of any OpenCode/IO coupling and trivially unit-testable.
7
+ */
8
+ import { buildDependencyTiers } from './tiers.js';
9
+ async function mapWithConcurrency(items, limit, fn) {
10
+ const results = new Array(items.length);
11
+ let cursor = 0;
12
+ const workerCount = Math.max(1, Math.min(limit, items.length));
13
+ const workers = Array.from({ length: workerCount }, async () => {
14
+ while (cursor < items.length) {
15
+ const index = cursor++;
16
+ const item = items[index];
17
+ if (item === undefined)
18
+ continue;
19
+ results[index] = await fn(item);
20
+ }
21
+ });
22
+ await Promise.all(workers);
23
+ return results;
24
+ }
25
+ export async function runSwarm(breakdown, opts) {
26
+ const mode = opts.mode ?? breakdown.executionMode;
27
+ const tasks = [...breakdown.subtasks].sort((a, b) => a.priority - b.priority);
28
+ const warnings = [];
29
+ const { tiers, hadCycle } = buildDependencyTiers(tasks);
30
+ if (hadCycle) {
31
+ warnings.push('Dependency cycle detected — affected sub-tasks ran sequentially');
32
+ }
33
+ if (mode === 'sequential') {
34
+ const ordered = tiers.flat();
35
+ const results = [];
36
+ for (const task of ordered) {
37
+ results.push(await opts.runTask(task));
38
+ }
39
+ return { results, warnings };
40
+ }
41
+ // parallel + adaptive: run dependency tiers sequentially, parallel within each tier.
42
+ const results = [];
43
+ for (const tier of tiers) {
44
+ const tierResults = await mapWithConcurrency(tier, opts.maxParallel, opts.runTask);
45
+ results.push(...tierResults);
46
+ }
47
+ return { results, warnings };
48
+ }
49
+ //# sourceMappingURL=scheduler.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scheduler.js","sourceRoot":"","sources":["../../src/orchestration/scheduler.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAclD,KAAK,UAAU,kBAAkB,CAC/B,KAAU,EACV,KAAa,EACb,EAA2B;IAE3B,MAAM,OAAO,GAAQ,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC7C,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC;IAC/D,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,WAAW,EAAE,EAAE,KAAK,IAAI,EAAE;QAC7D,OAAO,MAAM,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;YAC7B,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC;YACvB,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;YAC1B,IAAI,IAAI,KAAK,SAAS;gBAAE,SAAS;YACjC,OAAO,CAAC,KAAK,CAAC,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,CAAC;QAClC,CAAC;IACH,CAAC,CAAC,CAAC;IACH,MAAM,OAAO,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;IAC3B,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,SAAwB,EAAE,IAAkB;IACzE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,IAAI,SAAS,CAAC,aAAa,CAAC;IAClD,MAAM,KAAK,GAAG,CAAC,GAAG,SAAS,CAAC,QAAQ,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,GAAG,CAAC,CAAC,QAAQ,CAAC,CAAC;IAC9E,MAAM,QAAQ,GAAa,EAAE,CAAC;IAE9B,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAC;IACxD,IAAI,QAAQ,EAAE,CAAC;QACb,QAAQ,CAAC,IAAI,CAAC,iEAAiE,CAAC,CAAC;IACnF,CAAC;IAED,IAAI,IAAI,KAAK,YAAY,EAAE,CAAC;QAC1B,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,EAAE,CAAC;QAC7B,MAAM,OAAO,GAAoB,EAAE,CAAC;QACpC,KAAK,MAAM,IAAI,IAAI,OAAO,EAAE,CAAC;YAC3B,OAAO,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;QACzC,CAAC;QACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;IAC/B,CAAC;IAED,qFAAqF;IACrF,MAAM,OAAO,GAAoB,EAAE,CAAC;IACpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACnF,OAAO,CAAC,IAAI,CAAC,GAAG,WAAW,CAAC,CAAC;IAC/B,CAAC;IACD,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Schema validation and parsing for the manager's TaskBreakdown contract.
3
+ *
4
+ * The manager is instructed to emit snake_case JSON. This module strips any
5
+ * markdown code fences, parses the JSON, validates it against a zod schema,
6
+ * and normalizes it into the camelCase {@link TaskBreakdown} model.
7
+ */
8
+ import type { TaskBreakdown } from './types.js';
9
+ /** Remove a leading/trailing ```json … ``` markdown fence if present. */
10
+ export declare function stripJsonFences(text: string): string;
11
+ /** Parse and validate raw manager output into a {@link TaskBreakdown}. */
12
+ export declare function parseBreakdown(raw: string): TaskBreakdown;
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Schema validation and parsing for the manager's TaskBreakdown contract.
3
+ *
4
+ * The manager is instructed to emit snake_case JSON. This module strips any
5
+ * markdown code fences, parses the JSON, validates it against a zod schema,
6
+ * and normalizes it into the camelCase {@link TaskBreakdown} model.
7
+ */
8
+ import { z } from 'zod';
9
+ import { SpegoError } from '../errors.js';
10
+ const subTaskSchema = z
11
+ .object({
12
+ id: z.string().min(1),
13
+ title: z.string().default(''),
14
+ description: z.string().default(''),
15
+ files: z.array(z.string()).default([]),
16
+ acceptance_criteria: z.array(z.string()).default([]),
17
+ depends_on: z.array(z.string()).default([]),
18
+ priority: z.number().int().default(0),
19
+ model_override: z.string().optional(),
20
+ })
21
+ .transform((s) => ({
22
+ id: s.id,
23
+ title: s.title,
24
+ description: s.description,
25
+ files: s.files,
26
+ acceptanceCriteria: s.acceptance_criteria,
27
+ dependsOn: s.depends_on,
28
+ priority: s.priority,
29
+ modelOverride: s.model_override,
30
+ }));
31
+ const breakdownSchema = z
32
+ .object({
33
+ goal: z.string().min(1),
34
+ context_summary: z.string().default(''),
35
+ execution_mode: z.enum(['sequential', 'parallel', 'adaptive']).default('adaptive'),
36
+ test_command: z.string().default(''),
37
+ language: z.string().default('unknown'),
38
+ subtasks: z.array(subTaskSchema).min(1),
39
+ })
40
+ .transform((b) => ({
41
+ goal: b.goal,
42
+ contextSummary: b.context_summary,
43
+ executionMode: b.execution_mode,
44
+ testCommand: b.test_command,
45
+ language: b.language,
46
+ subtasks: b.subtasks,
47
+ }));
48
+ /** Remove a leading/trailing ```json … ``` markdown fence if present. */
49
+ export function stripJsonFences(text) {
50
+ const trimmed = text.trim();
51
+ if (!trimmed.startsWith('```'))
52
+ return trimmed;
53
+ const lines = trimmed.split('\n');
54
+ const inner = lines[lines.length - 1]?.startsWith('```') ? lines.slice(1, -1) : lines.slice(1);
55
+ return inner.join('\n').trim();
56
+ }
57
+ /** Parse and validate raw manager output into a {@link TaskBreakdown}. */
58
+ export function parseBreakdown(raw) {
59
+ const stripped = stripJsonFences(raw);
60
+ let data;
61
+ try {
62
+ data = JSON.parse(stripped);
63
+ }
64
+ catch (err) {
65
+ throw new SpegoError('ORCHESTRATION_INVALID_BREAKDOWN', 'Manager returned non-JSON output', {
66
+ cause: err.message,
67
+ raw: raw.slice(0, 500),
68
+ });
69
+ }
70
+ const parsed = breakdownSchema.safeParse(data);
71
+ if (!parsed.success) {
72
+ throw new SpegoError('ORCHESTRATION_INVALID_BREAKDOWN', 'Manager breakdown failed schema validation', {
73
+ issues: parsed.error.issues,
74
+ });
75
+ }
76
+ return parsed.data;
77
+ }
78
+ //# sourceMappingURL=schema.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/orchestration/schema.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * Dependency-tier construction for the swarm scheduler.
3
+ *
4
+ * Uses Kahn's algorithm to group sub-tasks into tiers: tasks within a tier
5
+ * have no dependency on one another and can run in parallel. When a cycle is
6
+ * detected, the remaining tasks are emitted as single-task tiers so they run
7
+ * sequentially rather than concurrently.
8
+ */
9
+ import type { SubTask } from './types.js';
10
+ export interface DependencyTiers {
11
+ tiers: SubTask[][];
12
+ hadCycle: boolean;
13
+ }
14
+ export declare function buildDependencyTiers(tasks: SubTask[]): DependencyTiers;