oxe-cc 1.2.1 → 1.3.0

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 (276) hide show
  1. package/.cursor/commands/oxe-ask.md +2 -2
  2. package/.cursor/commands/oxe-capabilities.md +2 -2
  3. package/.cursor/commands/oxe-checkpoint.md +2 -2
  4. package/.cursor/commands/oxe-compact.md +2 -2
  5. package/.cursor/commands/oxe-dashboard.md +2 -2
  6. package/.cursor/commands/oxe-debug.md +2 -2
  7. package/.cursor/commands/oxe-discuss.md +2 -2
  8. package/.cursor/commands/oxe-execute.md +5 -2
  9. package/.cursor/commands/oxe-forensics.md +2 -2
  10. package/.cursor/commands/oxe-help.md +2 -2
  11. package/.cursor/commands/oxe-loop.md +2 -2
  12. package/.cursor/commands/oxe-milestone.md +2 -2
  13. package/.cursor/commands/oxe-next.md +2 -2
  14. package/.cursor/commands/oxe-obs.md +2 -2
  15. package/.cursor/commands/oxe-plan-agent.md +2 -2
  16. package/.cursor/commands/oxe-plan.md +2 -2
  17. package/.cursor/commands/oxe-project.md +2 -2
  18. package/.cursor/commands/oxe-quick.md +2 -2
  19. package/.cursor/commands/oxe-research.md +2 -2
  20. package/.cursor/commands/oxe-retro.md +2 -2
  21. package/.cursor/commands/oxe-review-pr.md +2 -2
  22. package/.cursor/commands/oxe-route.md +2 -2
  23. package/.cursor/commands/oxe-scan.md +2 -2
  24. package/.cursor/commands/oxe-security.md +2 -2
  25. package/.cursor/commands/oxe-session.md +2 -2
  26. package/.cursor/commands/oxe-ship.md +2 -2
  27. package/.cursor/commands/oxe-skill.md +2 -2
  28. package/.cursor/commands/oxe-spec.md +2 -2
  29. package/.cursor/commands/oxe-ui-review.md +2 -2
  30. package/.cursor/commands/oxe-ui-spec.md +2 -2
  31. package/.cursor/commands/oxe-update.md +2 -2
  32. package/.cursor/commands/oxe-validate-gaps.md +2 -2
  33. package/.cursor/commands/oxe-verify.md +5 -2
  34. package/.cursor/commands/oxe-workstream.md +2 -2
  35. package/.cursor/commands/oxe.md +2 -2
  36. package/.github/copilot-instructions.md +13 -13
  37. package/.github/prompts/oxe-ask.prompt.md +2 -2
  38. package/.github/prompts/oxe-capabilities.prompt.md +2 -2
  39. package/.github/prompts/oxe-checkpoint.prompt.md +2 -2
  40. package/.github/prompts/oxe-compact.prompt.md +2 -2
  41. package/.github/prompts/oxe-dashboard.prompt.md +2 -2
  42. package/.github/prompts/oxe-debug.prompt.md +2 -2
  43. package/.github/prompts/oxe-discuss.prompt.md +2 -2
  44. package/.github/prompts/oxe-execute.prompt.md +5 -2
  45. package/.github/prompts/oxe-forensics.prompt.md +2 -2
  46. package/.github/prompts/oxe-help.prompt.md +2 -2
  47. package/.github/prompts/oxe-loop.prompt.md +2 -2
  48. package/.github/prompts/oxe-milestone.prompt.md +2 -2
  49. package/.github/prompts/oxe-next.prompt.md +2 -2
  50. package/.github/prompts/oxe-obs.prompt.md +2 -2
  51. package/.github/prompts/oxe-plan-agent.prompt.md +2 -2
  52. package/.github/prompts/oxe-plan.prompt.md +2 -2
  53. package/.github/prompts/oxe-project.prompt.md +2 -2
  54. package/.github/prompts/oxe-quick.prompt.md +2 -2
  55. package/.github/prompts/oxe-research.prompt.md +2 -2
  56. package/.github/prompts/oxe-retro.prompt.md +2 -2
  57. package/.github/prompts/oxe-review-pr.prompt.md +2 -2
  58. package/.github/prompts/oxe-route.prompt.md +2 -2
  59. package/.github/prompts/oxe-scan.prompt.md +2 -2
  60. package/.github/prompts/oxe-security.prompt.md +2 -2
  61. package/.github/prompts/oxe-session.prompt.md +2 -2
  62. package/.github/prompts/oxe-ship.prompt.md +2 -2
  63. package/.github/prompts/oxe-skill.prompt.md +2 -2
  64. package/.github/prompts/oxe-spec.prompt.md +2 -2
  65. package/.github/prompts/oxe-ui-review.prompt.md +2 -2
  66. package/.github/prompts/oxe-ui-spec.prompt.md +2 -2
  67. package/.github/prompts/oxe-update.prompt.md +2 -2
  68. package/.github/prompts/oxe-validate-gaps.prompt.md +2 -2
  69. package/.github/prompts/oxe-verify.prompt.md +5 -2
  70. package/.github/prompts/oxe-workstream.prompt.md +2 -2
  71. package/.github/prompts/oxe.prompt.md +2 -2
  72. package/CHANGELOG.md +52 -17
  73. package/README.md +610 -551
  74. package/bin/banner.txt +1 -1
  75. package/bin/lib/oxe-agent-install.cjs +69 -69
  76. package/bin/lib/oxe-azure.cjs +1445 -1445
  77. package/bin/lib/oxe-context-engine.cjs +867 -867
  78. package/bin/lib/oxe-dashboard.cjs +76 -28
  79. package/bin/lib/oxe-operational.cjs +2144 -1340
  80. package/bin/lib/oxe-project-health.cjs +483 -1
  81. package/bin/lib/oxe-runtime-semantics.cjs +12 -0
  82. package/bin/oxe-cc.js +554 -152
  83. package/commands/oxe/ask.md +2 -2
  84. package/commands/oxe/capabilities.md +2 -2
  85. package/commands/oxe/checkpoint.md +2 -2
  86. package/commands/oxe/compact.md +2 -2
  87. package/commands/oxe/dashboard.md +2 -2
  88. package/commands/oxe/debug.md +2 -2
  89. package/commands/oxe/discuss.md +2 -2
  90. package/commands/oxe/execute.md +5 -2
  91. package/commands/oxe/forensics.md +2 -2
  92. package/commands/oxe/help.md +2 -2
  93. package/commands/oxe/loop.md +2 -2
  94. package/commands/oxe/milestone.md +2 -2
  95. package/commands/oxe/next.md +2 -2
  96. package/commands/oxe/obs.md +2 -2
  97. package/commands/oxe/oxe.md +2 -2
  98. package/commands/oxe/plan-agent.md +2 -2
  99. package/commands/oxe/plan.md +2 -2
  100. package/commands/oxe/project.md +2 -2
  101. package/commands/oxe/quick.md +2 -2
  102. package/commands/oxe/research.md +2 -2
  103. package/commands/oxe/retro.md +2 -2
  104. package/commands/oxe/review-pr.md +2 -2
  105. package/commands/oxe/route.md +2 -2
  106. package/commands/oxe/scan.md +2 -2
  107. package/commands/oxe/security.md +2 -2
  108. package/commands/oxe/session.md +2 -2
  109. package/commands/oxe/ship.md +2 -2
  110. package/commands/oxe/skill.md +2 -2
  111. package/commands/oxe/spec.md +2 -2
  112. package/commands/oxe/ui-review.md +2 -2
  113. package/commands/oxe/ui-spec.md +2 -2
  114. package/commands/oxe/update.md +2 -2
  115. package/commands/oxe/validate-gaps.md +2 -2
  116. package/commands/oxe/verify.md +5 -2
  117. package/commands/oxe/workstream.md +2 -2
  118. package/lib/runtime/delivery/branch-manager.d.ts +1 -0
  119. package/lib/runtime/delivery/branch-manager.js +7 -0
  120. package/lib/runtime/delivery/ci-checks.js +34 -1
  121. package/lib/runtime/delivery/delivery-records.d.ts +34 -0
  122. package/lib/runtime/delivery/delivery-records.js +48 -0
  123. package/lib/runtime/delivery/index.d.ts +1 -0
  124. package/lib/runtime/delivery/index.js +1 -0
  125. package/lib/runtime/delivery/promotion-pipeline.d.ts +26 -2
  126. package/lib/runtime/delivery/promotion-pipeline.js +111 -14
  127. package/lib/runtime/gate/gate-manager.d.ts +41 -0
  128. package/lib/runtime/gate/gate-manager.js +108 -1
  129. package/lib/runtime/index.d.ts +2 -2
  130. package/lib/runtime/index.js +3 -1
  131. package/lib/runtime/models/gate-decision.d.ts +4 -1
  132. package/lib/runtime/models/workspace.d.ts +3 -0
  133. package/lib/runtime/plugins/capability-adapter.d.ts +12 -0
  134. package/lib/runtime/plugins/capability-adapter.js +204 -0
  135. package/lib/runtime/plugins/capability-matrix.d.ts +5 -0
  136. package/lib/runtime/plugins/capability-matrix.js +48 -17
  137. package/lib/runtime/plugins/index.d.ts +1 -0
  138. package/lib/runtime/plugins/index.js +1 -0
  139. package/lib/runtime/plugins/plugin-abi.d.ts +2 -0
  140. package/lib/runtime/plugins/plugin-manifest.d.ts +1 -1
  141. package/lib/runtime/plugins/plugin-manifest.js +6 -2
  142. package/lib/runtime/plugins/plugin-registry.d.ts +46 -0
  143. package/lib/runtime/plugins/plugin-registry.js +79 -2
  144. package/lib/runtime/policy/policy-engine.d.ts +19 -0
  145. package/lib/runtime/policy/policy-engine.js +76 -4
  146. package/lib/runtime/projection/projection-engine.d.ts +9 -1
  147. package/lib/runtime/projection/projection-engine.js +73 -3
  148. package/lib/runtime/scheduler/multi-agent-coordinator.d.ts +43 -1
  149. package/lib/runtime/scheduler/multi-agent-coordinator.js +151 -39
  150. package/lib/runtime/scheduler/run-journal.d.ts +1 -1
  151. package/lib/runtime/scheduler/scheduler.d.ts +19 -1
  152. package/lib/runtime/scheduler/scheduler.js +258 -13
  153. package/lib/runtime/verification/verification-compiler.d.ts +43 -0
  154. package/lib/runtime/verification/verification-compiler.js +137 -0
  155. package/lib/runtime/verification/verification-manifest.d.ts +9 -0
  156. package/lib/runtime/verification/verification-manifest.js +56 -6
  157. package/lib/runtime/workspace/strategies/ephemeral-container.d.ts +1 -0
  158. package/lib/runtime/workspace/strategies/ephemeral-container.js +4 -0
  159. package/lib/runtime/workspace/strategies/git-worktree.d.ts +1 -0
  160. package/lib/runtime/workspace/strategies/git-worktree.js +2 -0
  161. package/lib/runtime/workspace/strategies/inplace.d.ts +1 -0
  162. package/lib/runtime/workspace/strategies/inplace.js +2 -0
  163. package/lib/runtime/workspace/workspace-manager.d.ts +2 -1
  164. package/lib/sdk/README.md +9 -9
  165. package/lib/sdk/index.cjs +33 -24
  166. package/lib/sdk/index.d.ts +149 -14
  167. package/oxe/templates/ACTIVE-RUN.template.json +32 -32
  168. package/oxe/templates/CAPABILITIES.template.md +7 -7
  169. package/oxe/templates/CAPABILITY.template.md +45 -45
  170. package/oxe/templates/CHECKPOINTS.template.md +7 -7
  171. package/oxe/templates/EXECUTION-RUNTIME.template.md +68 -68
  172. package/oxe/templates/HYPOTHESES.template.md +33 -33
  173. package/oxe/templates/LESSONS-METRICS.template.json +13 -13
  174. package/oxe/templates/NOTES.template.md +16 -16
  175. package/oxe/templates/PLAN-REVIEW.template.md +31 -31
  176. package/oxe/templates/SESSION.template.md +34 -34
  177. package/oxe/templates/SKILL.template.md +26 -26
  178. package/oxe/templates/STATE.md +55 -55
  179. package/oxe/templates/WORKFLOW_AUTHORING.md +18 -18
  180. package/oxe/workflows/ask.md +96 -96
  181. package/oxe/workflows/capabilities.md +25 -25
  182. package/oxe/workflows/dashboard.md +33 -33
  183. package/oxe/workflows/discuss.md +12 -12
  184. package/oxe/workflows/execute.md +14 -0
  185. package/oxe/workflows/help.md +352 -352
  186. package/oxe/workflows/next.md +22 -22
  187. package/oxe/workflows/oxe.md +6 -6
  188. package/oxe/workflows/plan-agent.md +9 -9
  189. package/oxe/workflows/quick.md +10 -10
  190. package/oxe/workflows/references/reasoning-discovery.md +28 -28
  191. package/oxe/workflows/references/reasoning-execution.md +29 -29
  192. package/oxe/workflows/references/reasoning-planning.md +32 -32
  193. package/oxe/workflows/references/reasoning-review.md +29 -29
  194. package/oxe/workflows/references/reasoning-status.md +24 -24
  195. package/oxe/workflows/references/robustness-elevation.md +295 -295
  196. package/oxe/workflows/references/workflow-runtime-contracts.json +952 -930
  197. package/oxe/workflows/route.md +16 -16
  198. package/oxe/workflows/session.md +213 -213
  199. package/oxe/workflows/ship.md +142 -142
  200. package/oxe/workflows/skill.md +44 -44
  201. package/oxe/workflows/ui-review.md +36 -36
  202. package/oxe/workflows/verify-audit.md +73 -73
  203. package/oxe/workflows/verify.md +10 -0
  204. package/package.json +92 -92
  205. package/packages/runtime/package.json +17 -17
  206. package/packages/runtime/src/audit/audit-trail.ts +243 -243
  207. package/packages/runtime/src/audit/index.ts +2 -2
  208. package/packages/runtime/src/audit/policy-pack.ts +62 -62
  209. package/packages/runtime/src/compiler/graph-compiler.ts +245 -245
  210. package/packages/runtime/src/compiler/index.ts +1 -1
  211. package/packages/runtime/src/context/context-pack-builder.ts +259 -259
  212. package/packages/runtime/src/context/context-pack-store.ts +197 -197
  213. package/packages/runtime/src/context/context-profiles.ts +60 -60
  214. package/packages/runtime/src/context/index.ts +3 -3
  215. package/packages/runtime/src/decision/decision-engine.ts +174 -174
  216. package/packages/runtime/src/decision/decision-memo.ts +211 -211
  217. package/packages/runtime/src/decision/index.ts +2 -2
  218. package/packages/runtime/src/delivery/branch-manager.ts +91 -84
  219. package/packages/runtime/src/delivery/ci-checks.ts +285 -252
  220. package/packages/runtime/src/delivery/delivery-records.ts +75 -0
  221. package/packages/runtime/src/delivery/index.ts +5 -4
  222. package/packages/runtime/src/delivery/pr-manager.ts +112 -112
  223. package/packages/runtime/src/delivery/promotion-pipeline.ts +334 -180
  224. package/packages/runtime/src/events/bus.ts +92 -92
  225. package/packages/runtime/src/events/catalog.ts +29 -29
  226. package/packages/runtime/src/events/envelope.ts +14 -14
  227. package/packages/runtime/src/events/index.ts +3 -3
  228. package/packages/runtime/src/evidence/evidence-store.ts +130 -130
  229. package/packages/runtime/src/evidence/index.ts +1 -1
  230. package/packages/runtime/src/gate/gate-manager.ts +289 -137
  231. package/packages/runtime/src/gate/index.ts +1 -1
  232. package/packages/runtime/src/index.ts +41 -37
  233. package/packages/runtime/src/models/attempt.ts +19 -19
  234. package/packages/runtime/src/models/evidence.ts +21 -21
  235. package/packages/runtime/src/models/gate-decision.ts +25 -21
  236. package/packages/runtime/src/models/index.ts +8 -8
  237. package/packages/runtime/src/models/run.ts +24 -24
  238. package/packages/runtime/src/models/session.ts +11 -11
  239. package/packages/runtime/src/models/verification-result.ts +10 -10
  240. package/packages/runtime/src/models/work-item.ts +25 -25
  241. package/packages/runtime/src/models/workspace.ts +31 -28
  242. package/packages/runtime/src/plugins/capability-adapter.ts +206 -0
  243. package/packages/runtime/src/plugins/capability-matrix.ts +126 -83
  244. package/packages/runtime/src/plugins/index.ts +5 -4
  245. package/packages/runtime/src/plugins/plugin-abi.ts +97 -95
  246. package/packages/runtime/src/plugins/plugin-manifest.ts +118 -113
  247. package/packages/runtime/src/plugins/plugin-registry.ts +232 -124
  248. package/packages/runtime/src/policy/index.ts +1 -1
  249. package/packages/runtime/src/policy/policy-engine.ts +330 -244
  250. package/packages/runtime/src/projection/index.ts +1 -1
  251. package/packages/runtime/src/projection/projection-engine.ts +328 -249
  252. package/packages/runtime/src/reducers/debug-reducer.ts +36 -36
  253. package/packages/runtime/src/reducers/index.ts +2 -2
  254. package/packages/runtime/src/reducers/run-state-reducer.ts +269 -269
  255. package/packages/runtime/src/scheduler/agent-registry.ts +132 -132
  256. package/packages/runtime/src/scheduler/agent-roles.ts +109 -109
  257. package/packages/runtime/src/scheduler/index.ts +4 -4
  258. package/packages/runtime/src/scheduler/multi-agent-coordinator.ts +521 -333
  259. package/packages/runtime/src/scheduler/run-journal.ts +62 -62
  260. package/packages/runtime/src/scheduler/scheduler.ts +722 -441
  261. package/packages/runtime/src/verification/index.ts +2 -2
  262. package/packages/runtime/src/verification/verification-compiler.ts +436 -225
  263. package/packages/runtime/src/verification/verification-manifest.ts +252 -192
  264. package/packages/runtime/src/workspace/index.ts +5 -5
  265. package/packages/runtime/src/workspace/strategies/ephemeral-container.ts +126 -121
  266. package/packages/runtime/src/workspace/strategies/git-worktree.ts +79 -77
  267. package/packages/runtime/src/workspace/strategies/inplace.ts +38 -35
  268. package/packages/runtime/src/workspace/workspace-manager.ts +16 -15
  269. package/packages/runtime/tsconfig.json +17 -17
  270. package/vscode-extension/.vscodeignore +7 -7
  271. package/vscode-extension/oxe-agents-1.0.0.vsix +0 -0
  272. package/vscode-extension/package.json +185 -185
  273. package/vscode-extension/src/extension.js +310 -310
  274. package/vscode-extension/src/shared/contextLoader.js +137 -137
  275. package/vscode-extension/src/shared/contractBuilder.js +159 -159
  276. package/vscode-extension/src/shared/stateReader.js +101 -101
@@ -1,245 +1,245 @@
1
- import crypto from 'crypto';
2
- import type { WorkspaceStrategy } from '../models/workspace';
3
-
4
- // Mirror of SDK ParsedTask / ParsedSpec / ParsedPlan interfaces
5
- // (avoids a hard dependency on the CJS SDK from TypeScript source)
6
- export interface ParsedTask {
7
- id: string;
8
- title: string;
9
- wave: number | null;
10
- dependsOn: string[];
11
- files: string[];
12
- verifyCommand: string | null;
13
- aceite: string[];
14
- done: boolean;
15
- meta?: Record<string, unknown> | null;
16
- }
17
-
18
- export interface ParsedSpecCriterion {
19
- id: string;
20
- criterion: string;
21
- howToVerify: string;
22
- }
23
-
24
- export interface ParsedSpec {
25
- objective: string | null;
26
- criteria: ParsedSpecCriterion[];
27
- }
28
-
29
- export interface ParsedPlan {
30
- tasks: ParsedTask[];
31
- waves: Record<number, string[]>;
32
- totalTasks: number;
33
- }
34
-
35
- export interface Action {
36
- type: 'read_code' | 'generate_patch' | 'run_tests' | 'run_lint' | 'collect_evidence' | 'custom';
37
- command?: string;
38
- targets?: string[];
39
- }
40
-
41
- export interface VerifyContract {
42
- must_pass: string[];
43
- acceptance_refs: string[];
44
- command: string | null;
45
- }
46
-
47
- export interface NodePolicy {
48
- requires_human_approval: boolean;
49
- max_retries: number;
50
- }
51
-
52
- export interface GraphNode {
53
- id: string;
54
- title: string;
55
- wave: number;
56
- depends_on: string[];
57
- workspace_strategy: WorkspaceStrategy;
58
- mutation_scope: string[];
59
- actions: Action[];
60
- verify: VerifyContract;
61
- policy: NodePolicy;
62
- }
63
-
64
- export interface GraphEdge {
65
- from: string;
66
- to: string;
67
- type: 'dependency' | 'wave_sequence';
68
- }
69
-
70
- export interface Wave {
71
- wave_number: number;
72
- node_ids: string[];
73
- }
74
-
75
- export interface ExecutionGraphMetadata {
76
- compiled_at: string;
77
- plan_hash: string;
78
- spec_hash: string;
79
- node_count: number;
80
- wave_count: number;
81
- }
82
-
83
- export interface ExecutionGraph {
84
- nodes: Map<string, GraphNode>;
85
- edges: GraphEdge[];
86
- waves: Wave[];
87
- metadata: ExecutionGraphMetadata;
88
- }
89
-
90
- export interface CompilerOptions {
91
- default_workspace_strategy?: WorkspaceStrategy;
92
- default_max_retries?: number;
93
- require_approval_for_all?: boolean;
94
- skip_done_tasks?: boolean;
95
- }
96
-
97
- export function compile(
98
- plan: ParsedPlan,
99
- spec: ParsedSpec,
100
- options: CompilerOptions = {}
101
- ): ExecutionGraph {
102
- const {
103
- default_workspace_strategy = 'git_worktree',
104
- default_max_retries = 2,
105
- require_approval_for_all = false,
106
- skip_done_tasks = false,
107
- } = options;
108
-
109
- const nodes = new Map<string, GraphNode>();
110
- const edges: GraphEdge[] = [];
111
- const waveMap = new Map<number, string[]>();
112
-
113
- for (const task of plan.tasks) {
114
- if (skip_done_tasks && task.done) continue;
115
-
116
- const waveNumber = task.wave ?? 1;
117
- const node: GraphNode = {
118
- id: task.id,
119
- title: task.title,
120
- wave: waveNumber,
121
- depends_on: task.dependsOn,
122
- workspace_strategy: default_workspace_strategy,
123
- mutation_scope: task.files,
124
- actions: buildActions(task),
125
- verify: {
126
- must_pass: task.verifyCommand ? ['tests'] : [],
127
- acceptance_refs: task.aceite,
128
- command: task.verifyCommand,
129
- },
130
- policy: {
131
- requires_human_approval: require_approval_for_all,
132
- max_retries: default_max_retries,
133
- },
134
- };
135
-
136
- nodes.set(task.id, node);
137
-
138
- for (const dep of task.dependsOn) {
139
- edges.push({ from: dep, to: task.id, type: 'dependency' });
140
- }
141
-
142
- if (!waveMap.has(waveNumber)) waveMap.set(waveNumber, []);
143
- waveMap.get(waveNumber)!.push(task.id);
144
- }
145
-
146
- const waves: Wave[] = Array.from(waveMap.entries())
147
- .sort(([a], [b]) => a - b)
148
- .map(([wave_number, node_ids]) => ({ wave_number, node_ids }));
149
-
150
- return {
151
- nodes,
152
- edges,
153
- waves,
154
- metadata: {
155
- compiled_at: new Date().toISOString(),
156
- plan_hash: hashObject(plan),
157
- spec_hash: hashObject(spec),
158
- node_count: nodes.size,
159
- wave_count: waves.length,
160
- },
161
- };
162
- }
163
-
164
- export function validateGraph(graph: ExecutionGraph): string[] {
165
- const errors: string[] = [];
166
- const nodeIds = new Set(graph.nodes.keys());
167
-
168
- for (const [id, node] of graph.nodes) {
169
- for (const dep of node.depends_on) {
170
- if (!nodeIds.has(dep)) {
171
- errors.push(`Node ${id} depends on unknown node ${dep}`);
172
- }
173
- }
174
- }
175
-
176
- // Detect cycles using DFS
177
- const visited = new Set<string>();
178
- const inStack = new Set<string>();
179
-
180
- function hasCycle(nodeId: string): boolean {
181
- if (inStack.has(nodeId)) return true;
182
- if (visited.has(nodeId)) return false;
183
- visited.add(nodeId);
184
- inStack.add(nodeId);
185
- const node = graph.nodes.get(nodeId);
186
- if (node) {
187
- for (const dep of node.depends_on) {
188
- if (hasCycle(dep)) return true;
189
- }
190
- }
191
- inStack.delete(nodeId);
192
- return false;
193
- }
194
-
195
- for (const id of nodeIds) {
196
- if (hasCycle(id)) {
197
- errors.push(`Cycle detected involving node ${id}`);
198
- break;
199
- }
200
- }
201
-
202
- return errors;
203
- }
204
-
205
- export function toSerializable(graph: ExecutionGraph): Record<string, unknown> {
206
- return {
207
- nodes: Object.fromEntries(graph.nodes),
208
- edges: graph.edges,
209
- waves: graph.waves,
210
- metadata: graph.metadata,
211
- };
212
- }
213
-
214
- export function fromSerializable(raw: Record<string, unknown>): ExecutionGraph {
215
- const nodes = new Map<string, GraphNode>(
216
- Object.entries(raw.nodes as Record<string, GraphNode>)
217
- );
218
- return {
219
- nodes,
220
- edges: raw.edges as GraphEdge[],
221
- waves: raw.waves as Wave[],
222
- metadata: raw.metadata as ExecutionGraphMetadata,
223
- };
224
- }
225
-
226
- function buildActions(task: ParsedTask): Action[] {
227
- const actions: Action[] = [];
228
- if (task.files.length > 0) {
229
- actions.push({ type: 'read_code', targets: task.files });
230
- }
231
- actions.push({ type: 'generate_patch' });
232
- if (task.verifyCommand) {
233
- actions.push({ type: 'run_tests', command: task.verifyCommand });
234
- }
235
- actions.push({ type: 'collect_evidence' });
236
- return actions;
237
- }
238
-
239
- function hashObject(obj: unknown): string {
240
- return crypto
241
- .createHash('sha256')
242
- .update(JSON.stringify(obj))
243
- .digest('hex')
244
- .slice(0, 12);
245
- }
1
+ import crypto from 'crypto';
2
+ import type { WorkspaceStrategy } from '../models/workspace';
3
+
4
+ // Mirror of SDK ParsedTask / ParsedSpec / ParsedPlan interfaces
5
+ // (avoids a hard dependency on the CJS SDK from TypeScript source)
6
+ export interface ParsedTask {
7
+ id: string;
8
+ title: string;
9
+ wave: number | null;
10
+ dependsOn: string[];
11
+ files: string[];
12
+ verifyCommand: string | null;
13
+ aceite: string[];
14
+ done: boolean;
15
+ meta?: Record<string, unknown> | null;
16
+ }
17
+
18
+ export interface ParsedSpecCriterion {
19
+ id: string;
20
+ criterion: string;
21
+ howToVerify: string;
22
+ }
23
+
24
+ export interface ParsedSpec {
25
+ objective: string | null;
26
+ criteria: ParsedSpecCriterion[];
27
+ }
28
+
29
+ export interface ParsedPlan {
30
+ tasks: ParsedTask[];
31
+ waves: Record<number, string[]>;
32
+ totalTasks: number;
33
+ }
34
+
35
+ export interface Action {
36
+ type: 'read_code' | 'generate_patch' | 'run_tests' | 'run_lint' | 'collect_evidence' | 'custom';
37
+ command?: string;
38
+ targets?: string[];
39
+ }
40
+
41
+ export interface VerifyContract {
42
+ must_pass: string[];
43
+ acceptance_refs: string[];
44
+ command: string | null;
45
+ }
46
+
47
+ export interface NodePolicy {
48
+ requires_human_approval: boolean;
49
+ max_retries: number;
50
+ }
51
+
52
+ export interface GraphNode {
53
+ id: string;
54
+ title: string;
55
+ wave: number;
56
+ depends_on: string[];
57
+ workspace_strategy: WorkspaceStrategy;
58
+ mutation_scope: string[];
59
+ actions: Action[];
60
+ verify: VerifyContract;
61
+ policy: NodePolicy;
62
+ }
63
+
64
+ export interface GraphEdge {
65
+ from: string;
66
+ to: string;
67
+ type: 'dependency' | 'wave_sequence';
68
+ }
69
+
70
+ export interface Wave {
71
+ wave_number: number;
72
+ node_ids: string[];
73
+ }
74
+
75
+ export interface ExecutionGraphMetadata {
76
+ compiled_at: string;
77
+ plan_hash: string;
78
+ spec_hash: string;
79
+ node_count: number;
80
+ wave_count: number;
81
+ }
82
+
83
+ export interface ExecutionGraph {
84
+ nodes: Map<string, GraphNode>;
85
+ edges: GraphEdge[];
86
+ waves: Wave[];
87
+ metadata: ExecutionGraphMetadata;
88
+ }
89
+
90
+ export interface CompilerOptions {
91
+ default_workspace_strategy?: WorkspaceStrategy;
92
+ default_max_retries?: number;
93
+ require_approval_for_all?: boolean;
94
+ skip_done_tasks?: boolean;
95
+ }
96
+
97
+ export function compile(
98
+ plan: ParsedPlan,
99
+ spec: ParsedSpec,
100
+ options: CompilerOptions = {}
101
+ ): ExecutionGraph {
102
+ const {
103
+ default_workspace_strategy = 'git_worktree',
104
+ default_max_retries = 2,
105
+ require_approval_for_all = false,
106
+ skip_done_tasks = false,
107
+ } = options;
108
+
109
+ const nodes = new Map<string, GraphNode>();
110
+ const edges: GraphEdge[] = [];
111
+ const waveMap = new Map<number, string[]>();
112
+
113
+ for (const task of plan.tasks) {
114
+ if (skip_done_tasks && task.done) continue;
115
+
116
+ const waveNumber = task.wave ?? 1;
117
+ const node: GraphNode = {
118
+ id: task.id,
119
+ title: task.title,
120
+ wave: waveNumber,
121
+ depends_on: task.dependsOn,
122
+ workspace_strategy: default_workspace_strategy,
123
+ mutation_scope: task.files,
124
+ actions: buildActions(task),
125
+ verify: {
126
+ must_pass: task.verifyCommand ? ['tests'] : [],
127
+ acceptance_refs: task.aceite,
128
+ command: task.verifyCommand,
129
+ },
130
+ policy: {
131
+ requires_human_approval: require_approval_for_all,
132
+ max_retries: default_max_retries,
133
+ },
134
+ };
135
+
136
+ nodes.set(task.id, node);
137
+
138
+ for (const dep of task.dependsOn) {
139
+ edges.push({ from: dep, to: task.id, type: 'dependency' });
140
+ }
141
+
142
+ if (!waveMap.has(waveNumber)) waveMap.set(waveNumber, []);
143
+ waveMap.get(waveNumber)!.push(task.id);
144
+ }
145
+
146
+ const waves: Wave[] = Array.from(waveMap.entries())
147
+ .sort(([a], [b]) => a - b)
148
+ .map(([wave_number, node_ids]) => ({ wave_number, node_ids }));
149
+
150
+ return {
151
+ nodes,
152
+ edges,
153
+ waves,
154
+ metadata: {
155
+ compiled_at: new Date().toISOString(),
156
+ plan_hash: hashObject(plan),
157
+ spec_hash: hashObject(spec),
158
+ node_count: nodes.size,
159
+ wave_count: waves.length,
160
+ },
161
+ };
162
+ }
163
+
164
+ export function validateGraph(graph: ExecutionGraph): string[] {
165
+ const errors: string[] = [];
166
+ const nodeIds = new Set(graph.nodes.keys());
167
+
168
+ for (const [id, node] of graph.nodes) {
169
+ for (const dep of node.depends_on) {
170
+ if (!nodeIds.has(dep)) {
171
+ errors.push(`Node ${id} depends on unknown node ${dep}`);
172
+ }
173
+ }
174
+ }
175
+
176
+ // Detect cycles using DFS
177
+ const visited = new Set<string>();
178
+ const inStack = new Set<string>();
179
+
180
+ function hasCycle(nodeId: string): boolean {
181
+ if (inStack.has(nodeId)) return true;
182
+ if (visited.has(nodeId)) return false;
183
+ visited.add(nodeId);
184
+ inStack.add(nodeId);
185
+ const node = graph.nodes.get(nodeId);
186
+ if (node) {
187
+ for (const dep of node.depends_on) {
188
+ if (hasCycle(dep)) return true;
189
+ }
190
+ }
191
+ inStack.delete(nodeId);
192
+ return false;
193
+ }
194
+
195
+ for (const id of nodeIds) {
196
+ if (hasCycle(id)) {
197
+ errors.push(`Cycle detected involving node ${id}`);
198
+ break;
199
+ }
200
+ }
201
+
202
+ return errors;
203
+ }
204
+
205
+ export function toSerializable(graph: ExecutionGraph): Record<string, unknown> {
206
+ return {
207
+ nodes: Object.fromEntries(graph.nodes),
208
+ edges: graph.edges,
209
+ waves: graph.waves,
210
+ metadata: graph.metadata,
211
+ };
212
+ }
213
+
214
+ export function fromSerializable(raw: Record<string, unknown>): ExecutionGraph {
215
+ const nodes = new Map<string, GraphNode>(
216
+ Object.entries(raw.nodes as Record<string, GraphNode>)
217
+ );
218
+ return {
219
+ nodes,
220
+ edges: raw.edges as GraphEdge[],
221
+ waves: raw.waves as Wave[],
222
+ metadata: raw.metadata as ExecutionGraphMetadata,
223
+ };
224
+ }
225
+
226
+ function buildActions(task: ParsedTask): Action[] {
227
+ const actions: Action[] = [];
228
+ if (task.files.length > 0) {
229
+ actions.push({ type: 'read_code', targets: task.files });
230
+ }
231
+ actions.push({ type: 'generate_patch' });
232
+ if (task.verifyCommand) {
233
+ actions.push({ type: 'run_tests', command: task.verifyCommand });
234
+ }
235
+ actions.push({ type: 'collect_evidence' });
236
+ return actions;
237
+ }
238
+
239
+ function hashObject(obj: unknown): string {
240
+ return crypto
241
+ .createHash('sha256')
242
+ .update(JSON.stringify(obj))
243
+ .digest('hex')
244
+ .slice(0, 12);
245
+ }
@@ -1 +1 @@
1
- export * from './graph-compiler';
1
+ export * from './graph-compiler';