@sudocode-ai/local-server 0.1.10 → 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.
- package/dist/execution/executors/agent-executor-wrapper.d.ts.map +1 -1
- package/dist/execution/executors/agent-executor-wrapper.js +57 -2
- package/dist/execution/executors/agent-executor-wrapper.js.map +1 -1
- package/dist/execution/process/builders/claude.d.ts.map +1 -1
- package/dist/execution/process/builders/claude.js +32 -1
- package/dist/execution/process/builders/claude.js.map +1 -1
- package/dist/execution/worktree/git-cli.d.ts +48 -0
- package/dist/execution/worktree/git-cli.d.ts.map +1 -1
- package/dist/execution/worktree/git-cli.js +81 -0
- package/dist/execution/worktree/git-cli.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +17 -4
- package/dist/index.js.map +1 -1
- package/dist/public/assets/index-Nz4IjDwB.css +1 -0
- package/dist/public/assets/index-Z8yftXvD.js +824 -0
- package/dist/public/assets/index-Z8yftXvD.js.map +1 -0
- package/dist/public/assets/{react-vendor-DiL5hC7l.js → react-vendor-5f1Wq1qs.js} +5 -5
- package/dist/public/assets/{react-vendor-DiL5hC7l.js.map → react-vendor-5f1Wq1qs.js.map} +1 -1
- package/dist/public/assets/{ui-vendor-B4WMPEfa.js → ui-vendor-BDDPoYki.js} +2 -2
- package/dist/public/assets/{ui-vendor-B4WMPEfa.js.map → ui-vendor-BDDPoYki.js.map} +1 -1
- package/dist/public/index.html +4 -4
- package/dist/routes/workflows.d.ts +8 -0
- package/dist/routes/workflows.d.ts.map +1 -0
- package/dist/routes/workflows.js +1729 -0
- package/dist/routes/workflows.js.map +1 -0
- package/dist/services/execution-event-callbacks.d.ts +73 -0
- package/dist/services/execution-event-callbacks.d.ts.map +1 -0
- package/dist/services/execution-event-callbacks.js +82 -0
- package/dist/services/execution-event-callbacks.js.map +1 -0
- package/dist/services/execution-lifecycle.d.ts +36 -0
- package/dist/services/execution-lifecycle.d.ts.map +1 -1
- package/dist/services/execution-lifecycle.js +87 -0
- package/dist/services/execution-lifecycle.js.map +1 -1
- package/dist/services/execution-service.d.ts +31 -3
- package/dist/services/execution-service.d.ts.map +1 -1
- package/dist/services/execution-service.js +161 -34
- package/dist/services/execution-service.js.map +1 -1
- package/dist/services/executions.d.ts +1 -0
- package/dist/services/executions.d.ts.map +1 -1
- package/dist/services/executions.js +4 -0
- package/dist/services/executions.js.map +1 -1
- package/dist/services/project-context.d.ts +25 -0
- package/dist/services/project-context.d.ts.map +1 -1
- package/dist/services/project-context.js +53 -3
- package/dist/services/project-context.js.map +1 -1
- package/dist/services/project-manager.d.ts +7 -0
- package/dist/services/project-manager.d.ts.map +1 -1
- package/dist/services/project-manager.js +90 -1
- package/dist/services/project-manager.js.map +1 -1
- package/dist/services/websocket.d.ts +10 -2
- package/dist/services/websocket.d.ts.map +1 -1
- package/dist/services/websocket.js +18 -0
- package/dist/services/websocket.js.map +1 -1
- package/dist/services/workflow-broadcast-service.d.ts +43 -0
- package/dist/services/workflow-broadcast-service.d.ts.map +1 -0
- package/dist/services/workflow-broadcast-service.js +145 -0
- package/dist/services/workflow-broadcast-service.js.map +1 -0
- package/dist/workflow/base-workflow-engine.d.ts +186 -0
- package/dist/workflow/base-workflow-engine.d.ts.map +1 -0
- package/dist/workflow/base-workflow-engine.js +549 -0
- package/dist/workflow/base-workflow-engine.js.map +1 -0
- package/dist/workflow/dependency-analyzer.d.ts +78 -0
- package/dist/workflow/dependency-analyzer.d.ts.map +1 -0
- package/dist/workflow/dependency-analyzer.js +264 -0
- package/dist/workflow/dependency-analyzer.js.map +1 -0
- package/dist/workflow/engines/orchestrator-engine.d.ts +237 -0
- package/dist/workflow/engines/orchestrator-engine.d.ts.map +1 -0
- package/dist/workflow/engines/orchestrator-engine.js +749 -0
- package/dist/workflow/engines/orchestrator-engine.js.map +1 -0
- package/dist/workflow/engines/sequential-engine.d.ts +276 -0
- package/dist/workflow/engines/sequential-engine.d.ts.map +1 -0
- package/dist/workflow/engines/sequential-engine.js +1110 -0
- package/dist/workflow/engines/sequential-engine.js.map +1 -0
- package/dist/workflow/index.d.ts +15 -0
- package/dist/workflow/index.d.ts.map +1 -0
- package/dist/workflow/index.js +22 -0
- package/dist/workflow/index.js.map +1 -0
- package/dist/workflow/mcp/api-client.d.ts +103 -0
- package/dist/workflow/mcp/api-client.d.ts.map +1 -0
- package/dist/workflow/mcp/api-client.js +193 -0
- package/dist/workflow/mcp/api-client.js.map +1 -0
- package/dist/workflow/mcp/index.d.ts +16 -0
- package/dist/workflow/mcp/index.d.ts.map +1 -0
- package/dist/workflow/mcp/index.js +114 -0
- package/dist/workflow/mcp/index.js.map +1 -0
- package/dist/workflow/mcp/server.d.ts +85 -0
- package/dist/workflow/mcp/server.d.ts.map +1 -0
- package/dist/workflow/mcp/server.js +520 -0
- package/dist/workflow/mcp/server.js.map +1 -0
- package/dist/workflow/mcp/tools/escalation.d.ts +36 -0
- package/dist/workflow/mcp/tools/escalation.d.ts.map +1 -0
- package/dist/workflow/mcp/tools/escalation.js +47 -0
- package/dist/workflow/mcp/tools/escalation.js.map +1 -0
- package/dist/workflow/mcp/tools/execution.d.ts +59 -0
- package/dist/workflow/mcp/tools/execution.d.ts.map +1 -0
- package/dist/workflow/mcp/tools/execution.js +67 -0
- package/dist/workflow/mcp/tools/execution.js.map +1 -0
- package/dist/workflow/mcp/tools/inspection.d.ts +82 -0
- package/dist/workflow/mcp/tools/inspection.d.ts.map +1 -0
- package/dist/workflow/mcp/tools/inspection.js +57 -0
- package/dist/workflow/mcp/tools/inspection.js.map +1 -0
- package/dist/workflow/mcp/tools/workflow.d.ts +59 -0
- package/dist/workflow/mcp/tools/workflow.d.ts.map +1 -0
- package/dist/workflow/mcp/tools/workflow.js +40 -0
- package/dist/workflow/mcp/tools/workflow.js.map +1 -0
- package/dist/workflow/mcp/types.d.ts +345 -0
- package/dist/workflow/mcp/types.d.ts.map +1 -0
- package/dist/workflow/mcp/types.js +7 -0
- package/dist/workflow/mcp/types.js.map +1 -0
- package/dist/workflow/services/prompt-builder.d.ts +36 -0
- package/dist/workflow/services/prompt-builder.d.ts.map +1 -0
- package/dist/workflow/services/prompt-builder.js +329 -0
- package/dist/workflow/services/prompt-builder.js.map +1 -0
- package/dist/workflow/services/wakeup-service.d.ts +262 -0
- package/dist/workflow/services/wakeup-service.d.ts.map +1 -0
- package/dist/workflow/services/wakeup-service.js +809 -0
- package/dist/workflow/services/wakeup-service.js.map +1 -0
- package/dist/workflow/workflow-engine.d.ts +221 -0
- package/dist/workflow/workflow-engine.d.ts.map +1 -0
- package/dist/workflow/workflow-engine.js +94 -0
- package/dist/workflow/workflow-engine.js.map +1 -0
- package/dist/workflow/workflow-event-emitter.d.ts +278 -0
- package/dist/workflow/workflow-event-emitter.d.ts.map +1 -0
- package/dist/workflow/workflow-event-emitter.js +259 -0
- package/dist/workflow/workflow-event-emitter.js.map +1 -0
- package/package.json +8 -6
- package/dist/public/assets/index-CQoCSnhl.css +0 -1
- package/dist/public/assets/index-iWE3gSYw.js +0 -758
- package/dist/public/assets/index-iWE3gSYw.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"}
|