@sudocode-ai/local-server 0.1.9 → 0.1.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (146) hide show
  1. package/dist/execution/executors/agent-executor-wrapper.d.ts.map +1 -1
  2. package/dist/execution/executors/agent-executor-wrapper.js +57 -2
  3. package/dist/execution/executors/agent-executor-wrapper.js.map +1 -1
  4. package/dist/execution/process/builders/claude.d.ts.map +1 -1
  5. package/dist/execution/process/builders/claude.js +32 -1
  6. package/dist/execution/process/builders/claude.js.map +1 -1
  7. package/dist/execution/worktree/config.js +1 -1
  8. package/dist/execution/worktree/config.js.map +1 -1
  9. package/dist/execution/worktree/git-cli.d.ts +48 -0
  10. package/dist/execution/worktree/git-cli.d.ts.map +1 -1
  11. package/dist/execution/worktree/git-cli.js +81 -0
  12. package/dist/execution/worktree/git-cli.js.map +1 -1
  13. package/dist/execution/worktree/types.d.ts.map +1 -1
  14. package/dist/execution/worktree/types.js.map +1 -1
  15. package/dist/index.d.ts.map +1 -1
  16. package/dist/index.js +17 -4
  17. package/dist/index.js.map +1 -1
  18. package/dist/public/assets/index-Nz4IjDwB.css +1 -0
  19. package/dist/public/assets/index-Z8yftXvD.js +824 -0
  20. package/dist/public/assets/index-Z8yftXvD.js.map +1 -0
  21. package/dist/public/assets/{react-vendor-DiL5hC7l.js → react-vendor-5f1Wq1qs.js} +5 -5
  22. package/dist/public/assets/{react-vendor-DiL5hC7l.js.map → react-vendor-5f1Wq1qs.js.map} +1 -1
  23. package/dist/public/assets/{ui-vendor-B4WMPEfa.js → ui-vendor-BDDPoYki.js} +2 -2
  24. package/dist/public/assets/{ui-vendor-B4WMPEfa.js.map → ui-vendor-BDDPoYki.js.map} +1 -1
  25. package/dist/public/index.html +4 -4
  26. package/dist/routes/executions.d.ts.map +1 -1
  27. package/dist/routes/executions.js +3 -1
  28. package/dist/routes/executions.js.map +1 -1
  29. package/dist/routes/issues.d.ts.map +1 -1
  30. package/dist/routes/issues.js +13 -0
  31. package/dist/routes/issues.js.map +1 -1
  32. package/dist/routes/specs.d.ts.map +1 -1
  33. package/dist/routes/specs.js +14 -0
  34. package/dist/routes/specs.js.map +1 -1
  35. package/dist/routes/workflows.d.ts +8 -0
  36. package/dist/routes/workflows.d.ts.map +1 -0
  37. package/dist/routes/workflows.js +1729 -0
  38. package/dist/routes/workflows.js.map +1 -0
  39. package/dist/services/execution-event-callbacks.d.ts +73 -0
  40. package/dist/services/execution-event-callbacks.d.ts.map +1 -0
  41. package/dist/services/execution-event-callbacks.js +82 -0
  42. package/dist/services/execution-event-callbacks.js.map +1 -0
  43. package/dist/services/execution-lifecycle.d.ts +38 -2
  44. package/dist/services/execution-lifecycle.d.ts.map +1 -1
  45. package/dist/services/execution-lifecycle.js +94 -23
  46. package/dist/services/execution-lifecycle.js.map +1 -1
  47. package/dist/services/execution-service.d.ts +31 -3
  48. package/dist/services/execution-service.d.ts.map +1 -1
  49. package/dist/services/execution-service.js +161 -34
  50. package/dist/services/execution-service.js.map +1 -1
  51. package/dist/services/executions.d.ts +1 -0
  52. package/dist/services/executions.d.ts.map +1 -1
  53. package/dist/services/executions.js +4 -0
  54. package/dist/services/executions.js.map +1 -1
  55. package/dist/services/project-context.d.ts +25 -0
  56. package/dist/services/project-context.d.ts.map +1 -1
  57. package/dist/services/project-context.js +53 -3
  58. package/dist/services/project-context.js.map +1 -1
  59. package/dist/services/project-manager.d.ts +7 -0
  60. package/dist/services/project-manager.d.ts.map +1 -1
  61. package/dist/services/project-manager.js +108 -13
  62. package/dist/services/project-manager.js.map +1 -1
  63. package/dist/services/websocket.d.ts +10 -2
  64. package/dist/services/websocket.d.ts.map +1 -1
  65. package/dist/services/websocket.js +18 -0
  66. package/dist/services/websocket.js.map +1 -1
  67. package/dist/services/workflow-broadcast-service.d.ts +43 -0
  68. package/dist/services/workflow-broadcast-service.d.ts.map +1 -0
  69. package/dist/services/workflow-broadcast-service.js +145 -0
  70. package/dist/services/workflow-broadcast-service.js.map +1 -0
  71. package/dist/services/worktree-sync-service.d.ts +76 -4
  72. package/dist/services/worktree-sync-service.d.ts.map +1 -1
  73. package/dist/services/worktree-sync-service.js +264 -23
  74. package/dist/services/worktree-sync-service.js.map +1 -1
  75. package/dist/workflow/base-workflow-engine.d.ts +186 -0
  76. package/dist/workflow/base-workflow-engine.d.ts.map +1 -0
  77. package/dist/workflow/base-workflow-engine.js +549 -0
  78. package/dist/workflow/base-workflow-engine.js.map +1 -0
  79. package/dist/workflow/dependency-analyzer.d.ts +78 -0
  80. package/dist/workflow/dependency-analyzer.d.ts.map +1 -0
  81. package/dist/workflow/dependency-analyzer.js +264 -0
  82. package/dist/workflow/dependency-analyzer.js.map +1 -0
  83. package/dist/workflow/engines/orchestrator-engine.d.ts +237 -0
  84. package/dist/workflow/engines/orchestrator-engine.d.ts.map +1 -0
  85. package/dist/workflow/engines/orchestrator-engine.js +749 -0
  86. package/dist/workflow/engines/orchestrator-engine.js.map +1 -0
  87. package/dist/workflow/engines/sequential-engine.d.ts +276 -0
  88. package/dist/workflow/engines/sequential-engine.d.ts.map +1 -0
  89. package/dist/workflow/engines/sequential-engine.js +1110 -0
  90. package/dist/workflow/engines/sequential-engine.js.map +1 -0
  91. package/dist/workflow/index.d.ts +15 -0
  92. package/dist/workflow/index.d.ts.map +1 -0
  93. package/dist/workflow/index.js +22 -0
  94. package/dist/workflow/index.js.map +1 -0
  95. package/dist/workflow/mcp/api-client.d.ts +103 -0
  96. package/dist/workflow/mcp/api-client.d.ts.map +1 -0
  97. package/dist/workflow/mcp/api-client.js +193 -0
  98. package/dist/workflow/mcp/api-client.js.map +1 -0
  99. package/dist/workflow/mcp/index.d.ts +16 -0
  100. package/dist/workflow/mcp/index.d.ts.map +1 -0
  101. package/dist/workflow/mcp/index.js +114 -0
  102. package/dist/workflow/mcp/index.js.map +1 -0
  103. package/dist/workflow/mcp/server.d.ts +85 -0
  104. package/dist/workflow/mcp/server.d.ts.map +1 -0
  105. package/dist/workflow/mcp/server.js +520 -0
  106. package/dist/workflow/mcp/server.js.map +1 -0
  107. package/dist/workflow/mcp/tools/escalation.d.ts +36 -0
  108. package/dist/workflow/mcp/tools/escalation.d.ts.map +1 -0
  109. package/dist/workflow/mcp/tools/escalation.js +47 -0
  110. package/dist/workflow/mcp/tools/escalation.js.map +1 -0
  111. package/dist/workflow/mcp/tools/execution.d.ts +59 -0
  112. package/dist/workflow/mcp/tools/execution.d.ts.map +1 -0
  113. package/dist/workflow/mcp/tools/execution.js +67 -0
  114. package/dist/workflow/mcp/tools/execution.js.map +1 -0
  115. package/dist/workflow/mcp/tools/inspection.d.ts +82 -0
  116. package/dist/workflow/mcp/tools/inspection.d.ts.map +1 -0
  117. package/dist/workflow/mcp/tools/inspection.js +57 -0
  118. package/dist/workflow/mcp/tools/inspection.js.map +1 -0
  119. package/dist/workflow/mcp/tools/workflow.d.ts +59 -0
  120. package/dist/workflow/mcp/tools/workflow.d.ts.map +1 -0
  121. package/dist/workflow/mcp/tools/workflow.js +40 -0
  122. package/dist/workflow/mcp/tools/workflow.js.map +1 -0
  123. package/dist/workflow/mcp/types.d.ts +345 -0
  124. package/dist/workflow/mcp/types.d.ts.map +1 -0
  125. package/dist/workflow/mcp/types.js +7 -0
  126. package/dist/workflow/mcp/types.js.map +1 -0
  127. package/dist/workflow/services/prompt-builder.d.ts +36 -0
  128. package/dist/workflow/services/prompt-builder.d.ts.map +1 -0
  129. package/dist/workflow/services/prompt-builder.js +329 -0
  130. package/dist/workflow/services/prompt-builder.js.map +1 -0
  131. package/dist/workflow/services/wakeup-service.d.ts +262 -0
  132. package/dist/workflow/services/wakeup-service.d.ts.map +1 -0
  133. package/dist/workflow/services/wakeup-service.js +809 -0
  134. package/dist/workflow/services/wakeup-service.js.map +1 -0
  135. package/dist/workflow/workflow-engine.d.ts +221 -0
  136. package/dist/workflow/workflow-engine.d.ts.map +1 -0
  137. package/dist/workflow/workflow-engine.js +94 -0
  138. package/dist/workflow/workflow-engine.js.map +1 -0
  139. package/dist/workflow/workflow-event-emitter.d.ts +278 -0
  140. package/dist/workflow/workflow-event-emitter.d.ts.map +1 -0
  141. package/dist/workflow/workflow-event-emitter.js +259 -0
  142. package/dist/workflow/workflow-event-emitter.js.map +1 -0
  143. package/package.json +8 -6
  144. package/dist/public/assets/index-DV9Tbujb.css +0 -1
  145. package/dist/public/assets/index-DcDX9-Ad.js +0 -740
  146. package/dist/public/assets/index-DcDX9-Ad.js.map +0 -1
@@ -0,0 +1,549 @@
1
+ /**
2
+ * Base Workflow Engine
3
+ *
4
+ * Abstract base class with shared logic for workflow engine implementations.
5
+ * Both SequentialWorkflowEngine and OrchestratorWorkflowEngine extend this class.
6
+ */
7
+ import { randomUUID } from "crypto";
8
+ import { execSync } from "child_process";
9
+ import { getIncomingRelationships } from "@sudocode-ai/cli/dist/operations/relationships.js";
10
+ import { WorkflowNotFoundError, WorkflowStepNotFoundError, DEFAULT_WORKFLOW_CONFIG, } from "./workflow-engine.js";
11
+ import { WorkflowEventEmitter, createEscalationRequestedEvent, createEscalationResolvedEvent, createStepStartedEvent, createStepCompletedEvent, createStepFailedEvent, createWorkflowCompletedEvent, createWorkflowFailedEvent, } from "./workflow-event-emitter.js";
12
+ import { analyzeDependencies } from "./dependency-analyzer.js";
13
+ // =============================================================================
14
+ // Helper Functions
15
+ // =============================================================================
16
+ /**
17
+ * Generate a unique workflow ID.
18
+ */
19
+ function generateWorkflowId() {
20
+ return `wf-${randomUUID().slice(0, 8)}`;
21
+ }
22
+ /**
23
+ * Generate a unique step ID.
24
+ */
25
+ function generateStepId() {
26
+ return `step-${randomUUID().slice(0, 8)}`;
27
+ }
28
+ /**
29
+ * Convert a database row to a Workflow object.
30
+ */
31
+ function rowToWorkflow(row) {
32
+ return {
33
+ id: row.id,
34
+ title: row.title,
35
+ source: JSON.parse(row.source),
36
+ status: row.status,
37
+ steps: JSON.parse(row.steps),
38
+ worktreePath: row.worktree_path ?? undefined,
39
+ branchName: row.branch_name ?? undefined,
40
+ baseBranch: row.base_branch,
41
+ currentStepIndex: row.current_step_index,
42
+ orchestratorExecutionId: row.orchestrator_execution_id ?? undefined,
43
+ orchestratorSessionId: row.orchestrator_session_id ?? undefined,
44
+ config: JSON.parse(row.config),
45
+ createdAt: row.created_at,
46
+ updatedAt: row.updated_at,
47
+ startedAt: row.started_at ?? undefined,
48
+ completedAt: row.completed_at ?? undefined,
49
+ };
50
+ }
51
+ /**
52
+ * Merge partial config with defaults.
53
+ */
54
+ function mergeConfig(partial) {
55
+ return {
56
+ ...DEFAULT_WORKFLOW_CONFIG,
57
+ ...partial,
58
+ };
59
+ }
60
+ // =============================================================================
61
+ // Base Workflow Engine
62
+ // =============================================================================
63
+ /**
64
+ * Abstract base class for workflow engine implementations.
65
+ *
66
+ * Provides shared functionality for:
67
+ * - Database CRUD operations
68
+ * - Source resolution (spec, issues, root_issue, goal)
69
+ * - Step creation from dependency graph
70
+ * - Ready step detection
71
+ * - Event subscription
72
+ *
73
+ * Subclasses must implement:
74
+ * - createWorkflow()
75
+ * - startWorkflow()
76
+ * - pauseWorkflow()
77
+ * - resumeWorkflow()
78
+ * - cancelWorkflow()
79
+ * - retryStep()
80
+ * - skipStep()
81
+ */
82
+ export class BaseWorkflowEngine {
83
+ db;
84
+ eventEmitter;
85
+ constructor(db, eventEmitter) {
86
+ this.db = db;
87
+ this.eventEmitter = eventEmitter ?? new WorkflowEventEmitter();
88
+ }
89
+ /**
90
+ * Generate a title from the workflow source.
91
+ */
92
+ generateTitle(source) {
93
+ switch (source.type) {
94
+ case "spec":
95
+ return `Workflow for spec ${source.specId}`;
96
+ case "issues":
97
+ return `Workflow for ${source.issueIds.length} issues`;
98
+ case "root_issue":
99
+ return `Workflow for issue ${source.issueId}`;
100
+ case "goal":
101
+ return source.goal.slice(0, 100);
102
+ default:
103
+ return "Workflow";
104
+ }
105
+ }
106
+ // ===========================================================================
107
+ // Query Methods (public)
108
+ // ===========================================================================
109
+ /**
110
+ * Get a workflow by ID.
111
+ */
112
+ async getWorkflow(workflowId) {
113
+ const row = this.db
114
+ .prepare("SELECT * FROM workflows WHERE id = ?")
115
+ .get(workflowId);
116
+ if (!row) {
117
+ return null;
118
+ }
119
+ return rowToWorkflow(row);
120
+ }
121
+ /**
122
+ * Get a workflow by ID, throwing if not found.
123
+ */
124
+ async getWorkflowOrThrow(workflowId) {
125
+ const workflow = await this.getWorkflow(workflowId);
126
+ if (!workflow) {
127
+ throw new WorkflowNotFoundError(workflowId);
128
+ }
129
+ return workflow;
130
+ }
131
+ /**
132
+ * Get steps that are ready to execute.
133
+ * A step is ready if:
134
+ * - Its status is "pending" or "ready"
135
+ * - All its dependencies are "completed"
136
+ */
137
+ async getReadySteps(workflowId) {
138
+ const workflow = await this.getWorkflowOrThrow(workflowId);
139
+ // Build a map of step ID to status for quick lookup
140
+ const stepStatusMap = new Map();
141
+ for (const step of workflow.steps) {
142
+ stepStatusMap.set(step.id, step.status);
143
+ }
144
+ // Find steps that are ready
145
+ const readySteps = [];
146
+ for (const step of workflow.steps) {
147
+ // Only consider pending or ready steps
148
+ if (step.status !== "pending" && step.status !== "ready") {
149
+ continue;
150
+ }
151
+ // Check if all dependencies are completed
152
+ const allDepsCompleted = step.dependencies.every((depId) => {
153
+ const depStatus = stepStatusMap.get(depId);
154
+ return depStatus === "completed";
155
+ });
156
+ if (allDepsCompleted) {
157
+ readySteps.push(step);
158
+ }
159
+ }
160
+ return readySteps;
161
+ }
162
+ /**
163
+ * List all workflows with optional filtering.
164
+ */
165
+ async listWorkflows(options) {
166
+ const limit = options?.limit ?? 50;
167
+ const offset = options?.offset ?? 0;
168
+ let query = "SELECT * FROM workflows";
169
+ const params = [];
170
+ if (options?.status) {
171
+ query += " WHERE status = ?";
172
+ params.push(options.status);
173
+ }
174
+ query += " ORDER BY created_at DESC LIMIT ? OFFSET ?";
175
+ params.push(limit, offset);
176
+ const rows = this.db.prepare(query).all(...params);
177
+ return rows.map(rowToWorkflow);
178
+ }
179
+ // ===========================================================================
180
+ // Event Methods (public)
181
+ // ===========================================================================
182
+ /**
183
+ * Subscribe to workflow events.
184
+ */
185
+ onWorkflowEvent(listener) {
186
+ return this.eventEmitter.on(listener);
187
+ }
188
+ /**
189
+ * Emit an escalation requested event.
190
+ */
191
+ emitEscalationRequested(workflowId, escalationId, message, options, context) {
192
+ this.eventEmitter.emit(createEscalationRequestedEvent(workflowId, escalationId, message, options, context));
193
+ }
194
+ /**
195
+ * Emit an escalation resolved event.
196
+ */
197
+ emitEscalationResolved(workflowId, escalationId, action, message) {
198
+ this.eventEmitter.emit(createEscalationResolvedEvent(workflowId, escalationId, action, message));
199
+ }
200
+ /**
201
+ * Emit a step started event.
202
+ */
203
+ emitStepStarted(workflowId, step) {
204
+ this.eventEmitter.emit(createStepStartedEvent(workflowId, step));
205
+ }
206
+ /**
207
+ * Emit a step completed event.
208
+ */
209
+ emitStepCompleted(workflowId, step, executionId) {
210
+ this.eventEmitter.emit(createStepCompletedEvent(workflowId, step, executionId));
211
+ }
212
+ /**
213
+ * Emit a step failed event.
214
+ */
215
+ emitStepFailed(workflowId, step, error) {
216
+ this.eventEmitter.emit(createStepFailedEvent(workflowId, step, error));
217
+ }
218
+ /**
219
+ * Emit a workflow completed event.
220
+ */
221
+ emitWorkflowCompleted(workflowId, workflow) {
222
+ this.eventEmitter.emit(createWorkflowCompletedEvent(workflowId, workflow));
223
+ }
224
+ /**
225
+ * Emit a workflow failed event.
226
+ */
227
+ emitWorkflowFailed(workflowId, error) {
228
+ this.eventEmitter.emit(createWorkflowFailedEvent(workflowId, error));
229
+ }
230
+ // ===========================================================================
231
+ // Database Operations (protected)
232
+ // ===========================================================================
233
+ /**
234
+ * Save a new workflow to the database.
235
+ */
236
+ saveWorkflow(workflow) {
237
+ const now = new Date().toISOString();
238
+ this.db
239
+ .prepare(`
240
+ INSERT INTO workflows (
241
+ id, title, source, status, steps,
242
+ worktree_path, branch_name, base_branch,
243
+ current_step_index, orchestrator_execution_id, orchestrator_session_id,
244
+ config, created_at, updated_at, started_at, completed_at
245
+ ) VALUES (
246
+ ?, ?, ?, ?, ?,
247
+ ?, ?, ?,
248
+ ?, ?, ?,
249
+ ?, ?, ?, ?, ?
250
+ )
251
+ `)
252
+ .run(workflow.id, workflow.title, JSON.stringify(workflow.source), workflow.status, JSON.stringify(workflow.steps), workflow.worktreePath ?? null, workflow.branchName ?? null, workflow.baseBranch, workflow.currentStepIndex, workflow.orchestratorExecutionId ?? null, workflow.orchestratorSessionId ?? null, JSON.stringify(workflow.config), workflow.createdAt ?? now, workflow.updatedAt ?? now, workflow.startedAt ?? null, workflow.completedAt ?? null);
253
+ }
254
+ /**
255
+ * Update a workflow in the database.
256
+ * Uses dynamic field builder for partial updates.
257
+ */
258
+ updateWorkflow(workflowId, updates) {
259
+ const setClauses = [];
260
+ const values = [];
261
+ if (updates.title !== undefined) {
262
+ setClauses.push("title = ?");
263
+ values.push(updates.title);
264
+ }
265
+ if (updates.status !== undefined) {
266
+ setClauses.push("status = ?");
267
+ values.push(updates.status);
268
+ }
269
+ if (updates.steps !== undefined) {
270
+ setClauses.push("steps = ?");
271
+ values.push(JSON.stringify(updates.steps));
272
+ }
273
+ if (updates.worktreePath !== undefined) {
274
+ setClauses.push("worktree_path = ?");
275
+ values.push(updates.worktreePath);
276
+ }
277
+ if (updates.branchName !== undefined) {
278
+ setClauses.push("branch_name = ?");
279
+ values.push(updates.branchName);
280
+ }
281
+ if (updates.currentStepIndex !== undefined) {
282
+ setClauses.push("current_step_index = ?");
283
+ values.push(updates.currentStepIndex);
284
+ }
285
+ if (updates.orchestratorExecutionId !== undefined) {
286
+ setClauses.push("orchestrator_execution_id = ?");
287
+ values.push(updates.orchestratorExecutionId);
288
+ }
289
+ if (updates.orchestratorSessionId !== undefined) {
290
+ setClauses.push("orchestrator_session_id = ?");
291
+ values.push(updates.orchestratorSessionId);
292
+ }
293
+ if (updates.config !== undefined) {
294
+ setClauses.push("config = ?");
295
+ values.push(JSON.stringify(updates.config));
296
+ }
297
+ if (updates.startedAt !== undefined) {
298
+ setClauses.push("started_at = ?");
299
+ values.push(updates.startedAt);
300
+ }
301
+ if (updates.completedAt !== undefined) {
302
+ setClauses.push("completed_at = ?");
303
+ values.push(updates.completedAt);
304
+ }
305
+ // Always update updated_at
306
+ setClauses.push("updated_at = ?");
307
+ values.push(new Date().toISOString());
308
+ // Add workflowId for WHERE clause
309
+ values.push(workflowId);
310
+ this.db
311
+ .prepare(`UPDATE workflows SET ${setClauses.join(", ")} WHERE id = ?`)
312
+ .run(...values);
313
+ // Return the updated workflow
314
+ const workflow = this.db
315
+ .prepare("SELECT * FROM workflows WHERE id = ?")
316
+ .get(workflowId);
317
+ return rowToWorkflow(workflow);
318
+ }
319
+ /**
320
+ * Update a specific step within a workflow.
321
+ */
322
+ updateStep(workflowId, stepId, updates) {
323
+ const workflow = this.db
324
+ .prepare("SELECT steps FROM workflows WHERE id = ?")
325
+ .get(workflowId);
326
+ if (!workflow) {
327
+ throw new WorkflowNotFoundError(workflowId);
328
+ }
329
+ const steps = JSON.parse(workflow.steps);
330
+ const stepIndex = steps.findIndex((s) => s.id === stepId);
331
+ if (stepIndex === -1) {
332
+ throw new WorkflowStepNotFoundError(workflowId, stepId);
333
+ }
334
+ // Merge updates into the step
335
+ steps[stepIndex] = { ...steps[stepIndex], ...updates };
336
+ // Update the steps array
337
+ this.db
338
+ .prepare("UPDATE workflows SET steps = ?, updated_at = ? WHERE id = ?")
339
+ .run(JSON.stringify(steps), new Date().toISOString(), workflowId);
340
+ }
341
+ /**
342
+ * Delete a workflow from the database.
343
+ */
344
+ deleteWorkflow(workflowId) {
345
+ this.db.prepare("DELETE FROM workflows WHERE id = ?").run(workflowId);
346
+ }
347
+ // ===========================================================================
348
+ // Source Resolution (protected)
349
+ // ===========================================================================
350
+ /**
351
+ * Resolve a WorkflowSource to a list of issue IDs.
352
+ *
353
+ * @param source - The workflow source definition
354
+ * @returns Array of issue IDs
355
+ */
356
+ async resolveSource(source) {
357
+ switch (source.type) {
358
+ case "spec":
359
+ return this.resolveSpecSource(source.specId);
360
+ case "issues":
361
+ return source.issueIds;
362
+ case "root_issue":
363
+ return this.resolveRootIssueSource(source.issueId);
364
+ case "goal":
365
+ // Goal-based workflows start with no issues
366
+ // The orchestrator creates them dynamically
367
+ return [];
368
+ default:
369
+ // TypeScript exhaustiveness check
370
+ const _exhaustive = source;
371
+ throw new Error(`Unknown source type: ${_exhaustive.type}`);
372
+ }
373
+ }
374
+ /**
375
+ * Resolve a spec source to issue IDs.
376
+ * Finds all issues that implement the spec.
377
+ */
378
+ resolveSpecSource(specId) {
379
+ // Find issues that have "implements" relationship to this spec
380
+ const relationships = getIncomingRelationships(this.db, specId, "spec", "implements");
381
+ // Filter to only issue sources
382
+ return relationships
383
+ .filter((rel) => rel.from_type === "issue")
384
+ .map((rel) => rel.from_id);
385
+ }
386
+ /**
387
+ * Resolve a root issue source to issue IDs.
388
+ * Returns the root issue plus all issues that block it (recursively).
389
+ */
390
+ resolveRootIssueSource(rootIssueId) {
391
+ const issueIds = new Set();
392
+ const queue = [rootIssueId];
393
+ while (queue.length > 0) {
394
+ const issueId = queue.shift();
395
+ if (issueIds.has(issueId)) {
396
+ continue;
397
+ }
398
+ issueIds.add(issueId);
399
+ // Find issues that block this issue
400
+ // "blocks" relationship: from_id blocks to_id
401
+ const blocksRels = getIncomingRelationships(this.db, issueId, "issue", "blocks");
402
+ for (const rel of blocksRels) {
403
+ if (rel.from_type === "issue" && !issueIds.has(rel.from_id)) {
404
+ queue.push(rel.from_id);
405
+ }
406
+ }
407
+ // Find issues this issue depends on
408
+ // "depends-on" relationship: from_id depends on to_id
409
+ // We need outgoing depends-on relationships
410
+ const dependsOnRels = this.db
411
+ .prepare(`
412
+ SELECT * FROM relationships
413
+ WHERE from_id = ? AND from_type = 'issue' AND relationship_type = 'depends-on'
414
+ `)
415
+ .all(issueId);
416
+ for (const rel of dependsOnRels) {
417
+ if (rel.to_type === "issue" && !issueIds.has(rel.to_id)) {
418
+ queue.push(rel.to_id);
419
+ }
420
+ }
421
+ }
422
+ return Array.from(issueIds);
423
+ }
424
+ // ===========================================================================
425
+ // Step Creation (protected)
426
+ // ===========================================================================
427
+ /**
428
+ * Create workflow steps from a dependency graph.
429
+ *
430
+ * @param graph - The analyzed dependency graph
431
+ * @returns Array of WorkflowStep objects
432
+ */
433
+ createStepsFromGraph(graph) {
434
+ // Create a map from issue ID to step ID
435
+ const issueToStepId = new Map();
436
+ for (const issueId of graph.issueIds) {
437
+ issueToStepId.set(issueId, generateStepId());
438
+ }
439
+ // Build steps based on topological order
440
+ const steps = [];
441
+ for (let i = 0; i < graph.topologicalOrder.length; i++) {
442
+ const issueId = graph.topologicalOrder[i];
443
+ const stepId = issueToStepId.get(issueId);
444
+ // Find dependencies for this step
445
+ // Dependencies are issues that block this one (edges ending at this issue)
446
+ const dependencies = [];
447
+ for (const [fromId, toId] of graph.edges) {
448
+ if (toId === issueId) {
449
+ const depStepId = issueToStepId.get(fromId);
450
+ if (depStepId) {
451
+ dependencies.push(depStepId);
452
+ }
453
+ }
454
+ }
455
+ const step = {
456
+ id: stepId,
457
+ issueId,
458
+ index: i,
459
+ dependencies,
460
+ status: dependencies.length === 0 ? "ready" : "pending",
461
+ };
462
+ steps.push(step);
463
+ }
464
+ return steps;
465
+ }
466
+ // ===========================================================================
467
+ // Workflow Creation Helpers (protected)
468
+ // ===========================================================================
469
+ /**
470
+ * Create a workflow object (without saving to database).
471
+ * Used by subclasses to build the workflow before saving.
472
+ */
473
+ buildWorkflow(options) {
474
+ const now = new Date().toISOString();
475
+ // Get title from config, or generate from source
476
+ const title = options.config.title || this.generateTitle(options.source);
477
+ // Get baseBranch from config, or default to current branch
478
+ let baseBranch = options.config.baseBranch;
479
+ if (!baseBranch && options.repoPath) {
480
+ try {
481
+ baseBranch = execSync("git rev-parse --abbrev-ref HEAD", {
482
+ cwd: options.repoPath,
483
+ encoding: "utf-8",
484
+ }).trim();
485
+ }
486
+ catch {
487
+ // Fall back to "main" if we can't determine current branch
488
+ }
489
+ }
490
+ baseBranch = baseBranch || "main";
491
+ return {
492
+ id: generateWorkflowId(),
493
+ title,
494
+ source: options.source,
495
+ status: "pending",
496
+ steps: options.steps,
497
+ baseBranch,
498
+ currentStepIndex: 0,
499
+ config: mergeConfig(options.config),
500
+ createdAt: now,
501
+ updatedAt: now,
502
+ };
503
+ }
504
+ // ===========================================================================
505
+ // Dependency Analysis (protected)
506
+ // ===========================================================================
507
+ /**
508
+ * Analyze dependencies for a set of issues.
509
+ * Convenience wrapper around analyzeDependencies().
510
+ */
511
+ analyzeDependencies(issueIds) {
512
+ return analyzeDependencies(this.db, issueIds);
513
+ }
514
+ // ===========================================================================
515
+ // Worktree Management (protected)
516
+ // ===========================================================================
517
+ /**
518
+ * Create a workflow-level worktree.
519
+ *
520
+ * Creates a worktree that will be shared across all executions in the workflow.
521
+ * This ensures the orchestrator and all step executions run in the same isolated
522
+ * environment and can see each other's changes.
523
+ *
524
+ * @param workflow - The workflow to create the worktree for
525
+ * @param repoPath - Path to the git repository
526
+ * @param lifecycleService - Execution lifecycle service for worktree creation
527
+ * @returns Object with worktreePath and branchName
528
+ */
529
+ async createWorkflowWorktreeHelper(workflow, repoPath, lifecycleService) {
530
+ // Check if reuseWorktreePath is specified in config
531
+ const reuseWorktreePath = workflow.config.reuseWorktreePath;
532
+ // Create the workflow worktree
533
+ const result = await lifecycleService.createWorkflowWorktree({
534
+ workflowId: workflow.id,
535
+ workflowTitle: workflow.title,
536
+ baseBranch: workflow.baseBranch,
537
+ repoPath,
538
+ reuseWorktreePath,
539
+ });
540
+ // Update workflow with worktree info
541
+ this.updateWorkflow(workflow.id, {
542
+ worktreePath: result.worktreePath,
543
+ branchName: result.branchName,
544
+ });
545
+ console.log(`[BaseWorkflowEngine] Created workflow worktree for ${workflow.id}: ${result.worktreePath} (branch: ${result.branchName})`);
546
+ return result;
547
+ }
548
+ }
549
+ //# sourceMappingURL=base-workflow-engine.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"base-workflow-engine.js","sourceRoot":"","sources":["../../src/workflow/base-workflow-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,78 @@
1
+ /**
2
+ * Dependency Graph Analyzer for Workflow System
3
+ *
4
+ * Analyzes issue dependencies using blocks/depends-on relationships
5
+ * to determine execution order and detect cycles.
6
+ */
7
+ import type Database from "better-sqlite3";
8
+ import type { DependencyGraph } from "@sudocode-ai/types";
9
+ /**
10
+ * Internal graph representation for analysis
11
+ */
12
+ interface InternalGraph {
13
+ /** All issue IDs in the graph */
14
+ issueIds: string[];
15
+ /** Edges as [from, to] tuples (from blocks to) */
16
+ edges: Array<[string, string]>;
17
+ /** Adjacency list: issueId -> issues it blocks */
18
+ adjacencyList: Map<string, string[]>;
19
+ /** In-degree: issueId -> number of issues blocking it */
20
+ inDegree: Map<string, number>;
21
+ }
22
+ /**
23
+ * Result of topological sort
24
+ */
25
+ interface TopologicalSortResult {
26
+ /** Issue IDs in valid execution order */
27
+ sorted: string[];
28
+ /** Detected cycles, or null if none */
29
+ cycles: string[][] | null;
30
+ /** True if graph has no cycles */
31
+ valid: boolean;
32
+ }
33
+ /**
34
+ * Build a dependency graph from issue relationships.
35
+ *
36
+ * Examines `blocks` and `depends-on` relationships between issues
37
+ * to create an adjacency list representation.
38
+ *
39
+ * @param db - Database connection
40
+ * @param issueIds - Issue IDs to include in the graph
41
+ * @returns Internal graph representation
42
+ */
43
+ export declare function buildDependencyGraph(db: Database.Database, issueIds: string[]): InternalGraph;
44
+ /**
45
+ * Perform topological sort using Kahn's algorithm.
46
+ *
47
+ * Returns issues in a valid execution order where all dependencies
48
+ * come before dependents. Detects cycles if present.
49
+ *
50
+ * @param adjacencyList - Map of issueId -> issues it blocks
51
+ * @param inDegree - Map of issueId -> number of blockers
52
+ * @returns Sorted order and cycle information
53
+ */
54
+ export declare function topologicalSort(adjacencyList: Map<string, string[]>, inDegree: Map<string, number>): TopologicalSortResult;
55
+ /**
56
+ * Group issues by topological level for parallel execution.
57
+ *
58
+ * Issues at the same level have no dependencies between them
59
+ * and can be executed concurrently.
60
+ *
61
+ * @param sortedIds - Issue IDs in topological order
62
+ * @param adjacencyList - Map of issueId -> issues it blocks
63
+ * @param inDegree - Original in-degrees
64
+ * @returns Array of groups, each group can run in parallel
65
+ */
66
+ export declare function findParallelGroups(sortedIds: string[], adjacencyList: Map<string, string[]>, inDegree: Map<string, number>): string[][];
67
+ /**
68
+ * Analyze dependencies between issues and return a complete dependency graph.
69
+ *
70
+ * This is the main entry point for workflow dependency analysis.
71
+ *
72
+ * @param db - Database connection
73
+ * @param issueIds - Issue IDs to analyze
74
+ * @returns Complete dependency graph with topological order and parallel groups
75
+ */
76
+ export declare function analyzeDependencies(db: Database.Database, issueIds: string[]): DependencyGraph;
77
+ export {};
78
+ //# sourceMappingURL=dependency-analyzer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"dependency-analyzer.d.ts","sourceRoot":"","sources":["../../src/workflow/dependency-analyzer.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,QAAQ,MAAM,gBAAgB,CAAC;AAC3C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAO1D;;GAEG;AACH,UAAU,aAAa;IACrB,iCAAiC;IACjC,QAAQ,EAAE,MAAM,EAAE,CAAC;IACnB,kDAAkD;IAClD,KAAK,EAAE,KAAK,CAAC,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;IAC/B,kDAAkD;IAClD,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACrC,yDAAyD;IACzD,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED;;GAEG;AACH,UAAU,qBAAqB;IAC7B,yCAAyC;IACzC,MAAM,EAAE,MAAM,EAAE,CAAC;IACjB,uCAAuC;IACvC,MAAM,EAAE,MAAM,EAAE,EAAE,GAAG,IAAI,CAAC;IAC1B,kCAAkC;IAClC,KAAK,EAAE,OAAO,CAAC;CAChB;AAMD;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAAE,GACjB,aAAa,CA2Df;AAMD;;;;;;;;;GASG;AACH,wBAAgB,eAAe,CAC7B,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACpC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,qBAAqB,CAyCvB;AAoFD;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAChC,SAAS,EAAE,MAAM,EAAE,EACnB,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,EACpC,QAAQ,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,MAAM,EAAE,EAAE,CA6CZ;AAMD;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,EAAE,EAAE,QAAQ,CAAC,QAAQ,EACrB,QAAQ,EAAE,MAAM,EAAE,GACjB,eAAe,CAuBjB"}