claude-mcp-workflow 0.1.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.
- package/.claude-plugin/plugin.json +13 -0
- package/.mcp.json +9 -0
- package/LICENSE +21 -0
- package/README.md +260 -0
- package/build/dashboard.d.ts +4 -0
- package/build/dashboard.d.ts.map +1 -0
- package/build/dashboard.js +91 -0
- package/build/dashboard.js.map +1 -0
- package/build/engine.d.ts +55 -0
- package/build/engine.d.ts.map +1 -0
- package/build/engine.js +486 -0
- package/build/engine.js.map +1 -0
- package/build/index.d.ts +2 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +60 -0
- package/build/index.js.map +1 -0
- package/build/loader.d.ts +29 -0
- package/build/loader.d.ts.map +1 -0
- package/build/loader.js +166 -0
- package/build/loader.js.map +1 -0
- package/build/modifier.d.ts +42 -0
- package/build/modifier.d.ts.map +1 -0
- package/build/modifier.js +96 -0
- package/build/modifier.js.map +1 -0
- package/build/storage.d.ts +12 -0
- package/build/storage.d.ts.map +1 -0
- package/build/storage.js +62 -0
- package/build/storage.js.map +1 -0
- package/build/tools.d.ts +7 -0
- package/build/tools.d.ts.map +1 -0
- package/build/tools.js +316 -0
- package/build/tools.js.map +1 -0
- package/build/types.d.ts +417 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +82 -0
- package/build/types.js.map +1 -0
- package/dashboard/dagre.min.js +801 -0
- package/dashboard/index.html +652 -0
- package/hooks/hooks.json +24 -0
- package/hooks/workflow-cleanup.sh +51 -0
- package/hooks/workflow-start.sh +79 -0
- package/package.json +44 -0
- package/templates/bug-fix.yaml +283 -0
- package/templates/code-review.yaml +164 -0
- package/templates/coding.yaml +176 -0
- package/templates/debugging.yaml +162 -0
- package/templates/explore.yaml +90 -0
- package/templates/file-code.yaml +69 -0
- package/templates/file-review.yaml +164 -0
- package/templates/investigate.yaml +84 -0
- package/templates/master.yaml +202 -0
- package/templates/new-feature.yaml +41 -0
- package/templates/planning.yaml +85 -0
- package/templates/refactoring.yaml +56 -0
- package/templates/reflection.yaml +61 -0
- package/templates/skills/architecture/SKILL.md +55 -0
- package/templates/skills/coding-skill-selector/SKILL.md +25 -0
- package/templates/skills/lang-haxe/SKILL.md +257 -0
- package/templates/skills/lang-python/SKILL.md +16 -0
- package/templates/skills/math/SKILL.md +14 -0
- package/templates/skills/preferences/SKILL.md +25 -0
- package/templates/skills/task-delegation/SKILL.md +53 -0
- package/templates/skills/web-reading/SKILL.md +62 -0
- package/templates/subagent.yaml +67 -0
- package/templates/testing.yaml +120 -0
- package/templates/web-research.yaml +53 -0
package/build/engine.js
ADDED
|
@@ -0,0 +1,486 @@
|
|
|
1
|
+
import { randomBytes } from "node:crypto";
|
|
2
|
+
import { MAX_STACK_DEPTH, DEFAULT_MAX_TRANSITIONS } from "./types.js";
|
|
3
|
+
export class Engine {
|
|
4
|
+
_storage;
|
|
5
|
+
_loader;
|
|
6
|
+
// Snapshot: sessions keep the workflow version they started with
|
|
7
|
+
_snapshots = new Map();
|
|
8
|
+
constructor(storage, loader) {
|
|
9
|
+
this._storage = storage;
|
|
10
|
+
this._loader = loader;
|
|
11
|
+
}
|
|
12
|
+
/** Find the most recently updated active session for the current Claude Code PID. */
|
|
13
|
+
resolveSessionId(sessionId) {
|
|
14
|
+
if (sessionId)
|
|
15
|
+
return sessionId;
|
|
16
|
+
const pid = process.ppid;
|
|
17
|
+
const active = this._storage.readAll().filter(s => s.context.claude_code_pid === pid && s.stack.length > 0);
|
|
18
|
+
if (active.length === 0)
|
|
19
|
+
throw new Error("No active session found. Call start first.");
|
|
20
|
+
active.sort((a, b) => b.updated_at.localeCompare(a.updated_at));
|
|
21
|
+
return active[0].session_id;
|
|
22
|
+
}
|
|
23
|
+
async start(workflowName, actor, parentSessionId) {
|
|
24
|
+
// Guard: prevent duplicate top-level sessions from the same Claude Code process.
|
|
25
|
+
// Sub-agent sessions (with parent_session_id) are exempt — they run alongside the parent.
|
|
26
|
+
if (!parentSessionId) {
|
|
27
|
+
const pid = process.ppid;
|
|
28
|
+
const active = this._storage.readAll().filter(s => s.context.claude_code_pid === pid && !s.parent_session_id && s.stack.length > 0);
|
|
29
|
+
if (active.length > 0) {
|
|
30
|
+
// Auto-redirect to subagent workflow as a child session
|
|
31
|
+
parentSessionId = active[0].session_id;
|
|
32
|
+
workflowName = "subagent";
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
let sessionId;
|
|
36
|
+
do {
|
|
37
|
+
sessionId = randomBytes(4).toString("hex");
|
|
38
|
+
} while (this._storage.read(sessionId));
|
|
39
|
+
const wf = this._loader.get(workflowName);
|
|
40
|
+
if (!wf)
|
|
41
|
+
throw new Error(`Workflow "${workflowName}" not found`);
|
|
42
|
+
// Snapshot all workflows for this session
|
|
43
|
+
this._snapshots.set(sessionId, this._loader.getAll());
|
|
44
|
+
const now = new Date().toISOString();
|
|
45
|
+
const frame = {
|
|
46
|
+
workflow: workflowName,
|
|
47
|
+
current_state: wf.initial,
|
|
48
|
+
state_visits: { [wf.initial]: 1 },
|
|
49
|
+
total_transitions: 0,
|
|
50
|
+
};
|
|
51
|
+
const globalKey = `${workflowName}:${wf.initial}`;
|
|
52
|
+
const session = {
|
|
53
|
+
session_id: sessionId,
|
|
54
|
+
...(parentSessionId ? { parent_session_id: parentSessionId } : {}),
|
|
55
|
+
stack: [frame],
|
|
56
|
+
active_frame: 0,
|
|
57
|
+
started_at: now,
|
|
58
|
+
updated_at: now,
|
|
59
|
+
history: [{ frame: 0, event: "start", workflow: workflowName, at: now, actor }],
|
|
60
|
+
overrides: {},
|
|
61
|
+
context: { claude_code_pid: process.ppid, cwd: process.cwd() },
|
|
62
|
+
global_state_visits: { [globalKey]: 1 },
|
|
63
|
+
};
|
|
64
|
+
await this._storage.write(sessionId, session);
|
|
65
|
+
// Check if initial state is a sub_workflow
|
|
66
|
+
const initialState = this._resolveState(session, workflowName, wf.initial);
|
|
67
|
+
if (initialState?.sub_workflow) {
|
|
68
|
+
return this._pushSubWorkflow(session, initialState, []);
|
|
69
|
+
}
|
|
70
|
+
return this._buildStatus(session, []);
|
|
71
|
+
}
|
|
72
|
+
async transition(sessionId, transitionName, actor) {
|
|
73
|
+
const session = this._storage.read(sessionId);
|
|
74
|
+
if (!session)
|
|
75
|
+
throw new Error(`Session "${sessionId}" not found`);
|
|
76
|
+
if (session.stack.length === 0)
|
|
77
|
+
throw new Error(`Session "${sessionId}" has no active workflow`);
|
|
78
|
+
// Session is waiting for children to complete — try to resolve
|
|
79
|
+
if (session.pending_pop) {
|
|
80
|
+
const result = await this.retryPendingPop(sessionId);
|
|
81
|
+
if (result)
|
|
82
|
+
return result;
|
|
83
|
+
throw new Error(this._formatChildrenBlockError(sessionId));
|
|
84
|
+
}
|
|
85
|
+
const frame = session.stack[session.active_frame];
|
|
86
|
+
const wf = this._getWorkflow(sessionId, frame.workflow);
|
|
87
|
+
const state = this._resolveState(session, frame.workflow, frame.current_state);
|
|
88
|
+
if (!state)
|
|
89
|
+
throw new Error(`State "${frame.current_state}" not found in workflow "${frame.workflow}"`);
|
|
90
|
+
// terminal states without transitions are truly final; with transitions they allow re-entry
|
|
91
|
+
if (state.terminal && (!state.transitions || Object.keys(state.transitions).length === 0)) {
|
|
92
|
+
throw new Error(`Cannot transition from terminal state "${frame.current_state}"`);
|
|
93
|
+
}
|
|
94
|
+
const transitions = state.transitions ?? {};
|
|
95
|
+
const targetStateName = transitions[transitionName];
|
|
96
|
+
if (!targetStateName) {
|
|
97
|
+
const available = Object.keys(transitions).join(", ");
|
|
98
|
+
throw new Error(`Transition "${transitionName}" not available. Available: ${available}`);
|
|
99
|
+
}
|
|
100
|
+
// Check max_transitions
|
|
101
|
+
const maxTransitions = wf.max_transitions ?? DEFAULT_MAX_TRANSITIONS;
|
|
102
|
+
if (frame.total_transitions >= maxTransitions) {
|
|
103
|
+
throw new Error(`Max transitions (${maxTransitions}) reached for workflow "${frame.workflow}"`);
|
|
104
|
+
}
|
|
105
|
+
const now = new Date().toISOString();
|
|
106
|
+
// Update frame
|
|
107
|
+
const targetVisits = (frame.state_visits[targetStateName] ?? 0) + 1;
|
|
108
|
+
const targetState = this._resolveState(session, frame.workflow, targetStateName);
|
|
109
|
+
// Check max_visits
|
|
110
|
+
if (targetState?.max_visits && targetVisits > targetState.max_visits) {
|
|
111
|
+
throw new Error(`State "${targetStateName}" max_visits (${targetState.max_visits}) exceeded`);
|
|
112
|
+
}
|
|
113
|
+
const updatedFrame = {
|
|
114
|
+
...frame,
|
|
115
|
+
current_state: targetStateName,
|
|
116
|
+
state_visits: { ...frame.state_visits, [targetStateName]: targetVisits },
|
|
117
|
+
total_transitions: frame.total_transitions + 1,
|
|
118
|
+
};
|
|
119
|
+
const historyEntry = {
|
|
120
|
+
frame: session.active_frame,
|
|
121
|
+
from: frame.current_state,
|
|
122
|
+
to: targetStateName,
|
|
123
|
+
via: transitionName,
|
|
124
|
+
at: now,
|
|
125
|
+
actor,
|
|
126
|
+
};
|
|
127
|
+
const globalKey = `${frame.workflow}:${targetStateName}`;
|
|
128
|
+
const prevGlobal = session.global_state_visits ?? {};
|
|
129
|
+
let updated = {
|
|
130
|
+
...session,
|
|
131
|
+
stack: session.stack.map((f, i) => i === session.active_frame ? updatedFrame : f),
|
|
132
|
+
updated_at: now,
|
|
133
|
+
history: [...session.history, historyEntry],
|
|
134
|
+
global_state_visits: { ...prevGlobal, [globalKey]: (prevGlobal[globalKey] ?? 0) + 1 },
|
|
135
|
+
};
|
|
136
|
+
await this._storage.write(sessionId, updated);
|
|
137
|
+
const taskOps = [];
|
|
138
|
+
if (state?.task) {
|
|
139
|
+
taskOps.push({ action: "complete", subject: state.task });
|
|
140
|
+
}
|
|
141
|
+
// Check if target is terminal
|
|
142
|
+
if (targetState?.terminal) {
|
|
143
|
+
const hasTransitions = targetState.transitions && Object.keys(targetState.transitions).length > 0;
|
|
144
|
+
if (!hasTransitions) {
|
|
145
|
+
// Hard terminal — pop stack as usual
|
|
146
|
+
const outcome = targetState.outcome === "fail" ? "fail" : "complete";
|
|
147
|
+
return this._popStack(updated, outcome, taskOps);
|
|
148
|
+
}
|
|
149
|
+
// Soft terminal — mark in session, stay in state
|
|
150
|
+
updated = { ...updated, soft_terminal: true };
|
|
151
|
+
await this._storage.write(sessionId, updated);
|
|
152
|
+
return this._buildStatus(updated, taskOps);
|
|
153
|
+
}
|
|
154
|
+
// Clear soft_terminal if leaving a soft-terminal state
|
|
155
|
+
if (updated.soft_terminal) {
|
|
156
|
+
updated = { ...updated, soft_terminal: false };
|
|
157
|
+
await this._storage.write(sessionId, updated);
|
|
158
|
+
}
|
|
159
|
+
// Check if target is sub_workflow → push
|
|
160
|
+
if (targetState?.sub_workflow) {
|
|
161
|
+
return this._pushSubWorkflow(updated, targetState, taskOps);
|
|
162
|
+
}
|
|
163
|
+
return this._buildStatus(updated, taskOps);
|
|
164
|
+
}
|
|
165
|
+
async abort(sessionId) {
|
|
166
|
+
const session = this._storage.read(sessionId);
|
|
167
|
+
if (!session)
|
|
168
|
+
throw new Error(`Session "${sessionId}" not found`);
|
|
169
|
+
const now = new Date().toISOString();
|
|
170
|
+
const updated = {
|
|
171
|
+
...session,
|
|
172
|
+
stack: [],
|
|
173
|
+
active_frame: -1,
|
|
174
|
+
updated_at: now,
|
|
175
|
+
history: [...session.history, { frame: session.active_frame, event: "abort", at: now }],
|
|
176
|
+
outcome: "abandoned",
|
|
177
|
+
};
|
|
178
|
+
await this._storage.write(sessionId, updated);
|
|
179
|
+
this._snapshots.delete(sessionId);
|
|
180
|
+
await this._cascadeAbandonChildren(sessionId);
|
|
181
|
+
// If this was a child session, try to unblock the parent's pending completion
|
|
182
|
+
if (session.parent_session_id)
|
|
183
|
+
await this.retryPendingPop(session.parent_session_id);
|
|
184
|
+
}
|
|
185
|
+
getStatus(sessionId) {
|
|
186
|
+
const session = this._storage.read(sessionId);
|
|
187
|
+
if (!session)
|
|
188
|
+
throw new Error(`Session "${sessionId}" not found`);
|
|
189
|
+
return this._buildStatus(session, []);
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Retry a deferred pop. Called by Modifier after overlays change,
|
|
193
|
+
* in case on_complete/on_fail was added to the parent state.
|
|
194
|
+
* Returns the new status if pop succeeded, or null if still pending.
|
|
195
|
+
*/
|
|
196
|
+
async retryPendingPop(sessionId) {
|
|
197
|
+
const session = this._storage.read(sessionId);
|
|
198
|
+
if (!session?.pending_pop)
|
|
199
|
+
return null;
|
|
200
|
+
// Clear pending_pop before retrying to avoid infinite loops
|
|
201
|
+
const cleared = { ...session, pending_pop: undefined };
|
|
202
|
+
await this._storage.write(sessionId, cleared);
|
|
203
|
+
try {
|
|
204
|
+
const result = await this._popStack(cleared, session.pending_pop.outcome, []);
|
|
205
|
+
// Check if _popStack re-parked (pop still couldn't resolve)
|
|
206
|
+
const afterPop = this._storage.read(sessionId);
|
|
207
|
+
if (afterPop?.pending_pop)
|
|
208
|
+
return null;
|
|
209
|
+
return result;
|
|
210
|
+
}
|
|
211
|
+
catch {
|
|
212
|
+
// Still can't pop — re-park
|
|
213
|
+
const reparked = { ...cleared, pending_pop: session.pending_pop };
|
|
214
|
+
await this._storage.write(sessionId, reparked);
|
|
215
|
+
return null;
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
async setContext(sessionId, key, value, actor) {
|
|
219
|
+
const session = this._storage.read(sessionId);
|
|
220
|
+
if (!session)
|
|
221
|
+
throw new Error(`Session "${sessionId}" not found`);
|
|
222
|
+
const now = new Date().toISOString();
|
|
223
|
+
const updated = {
|
|
224
|
+
...session,
|
|
225
|
+
context: { ...session.context, [key]: value },
|
|
226
|
+
updated_at: now,
|
|
227
|
+
history: [...session.history, { frame: session.active_frame, event: "context_set", at: now, actor }],
|
|
228
|
+
};
|
|
229
|
+
await this._storage.write(sessionId, updated);
|
|
230
|
+
}
|
|
231
|
+
async _pushSubWorkflow(session, state, taskOps) {
|
|
232
|
+
const subName = state.sub_workflow;
|
|
233
|
+
const wf = this._getWorkflow(session.session_id, subName);
|
|
234
|
+
if (session.stack.length >= MAX_STACK_DEPTH) {
|
|
235
|
+
throw new Error(`Max stack depth (${MAX_STACK_DEPTH}) reached — cannot push "${subName}"`);
|
|
236
|
+
}
|
|
237
|
+
const now = new Date().toISOString();
|
|
238
|
+
const newFrame = {
|
|
239
|
+
workflow: subName,
|
|
240
|
+
current_state: wf.initial,
|
|
241
|
+
state_visits: { [wf.initial]: 1 },
|
|
242
|
+
total_transitions: 0,
|
|
243
|
+
};
|
|
244
|
+
const newStack = [...session.stack, newFrame];
|
|
245
|
+
const globalKey = `${subName}:${wf.initial}`;
|
|
246
|
+
const prevGlobal = session.global_state_visits ?? {};
|
|
247
|
+
const updated = {
|
|
248
|
+
...session,
|
|
249
|
+
stack: newStack,
|
|
250
|
+
active_frame: newStack.length - 1,
|
|
251
|
+
updated_at: now,
|
|
252
|
+
history: [...session.history, { frame: newStack.length - 1, event: "push", workflow: subName, at: now }],
|
|
253
|
+
global_state_visits: { ...prevGlobal, [globalKey]: (prevGlobal[globalKey] ?? 0) + 1 },
|
|
254
|
+
};
|
|
255
|
+
await this._storage.write(session.session_id, updated);
|
|
256
|
+
// Check if the initial state of sub_workflow is itself a sub_workflow
|
|
257
|
+
const initialState = this._resolveState(updated, subName, wf.initial);
|
|
258
|
+
if (initialState?.sub_workflow) {
|
|
259
|
+
return this._pushSubWorkflow(updated, initialState, taskOps);
|
|
260
|
+
}
|
|
261
|
+
return this._buildStatus(updated, taskOps);
|
|
262
|
+
}
|
|
263
|
+
async _popStack(session, outcome, taskOps) {
|
|
264
|
+
const now = new Date().toISOString();
|
|
265
|
+
if (session.stack.length <= 1) {
|
|
266
|
+
// Guard: block completion if child sessions are still active
|
|
267
|
+
const activeChildren = this._getActiveChildren(session.session_id);
|
|
268
|
+
if (activeChildren.length > 0) {
|
|
269
|
+
const parked = {
|
|
270
|
+
...session,
|
|
271
|
+
pending_pop: { outcome },
|
|
272
|
+
updated_at: now,
|
|
273
|
+
};
|
|
274
|
+
await this._storage.write(session.session_id, parked);
|
|
275
|
+
throw new Error(this._formatChildrenBlockError(session.session_id, activeChildren));
|
|
276
|
+
}
|
|
277
|
+
// Top-level workflow completed
|
|
278
|
+
const updated = {
|
|
279
|
+
...session,
|
|
280
|
+
stack: [],
|
|
281
|
+
active_frame: -1,
|
|
282
|
+
updated_at: now,
|
|
283
|
+
history: [...session.history, { frame: 0, event: "complete", at: now }],
|
|
284
|
+
outcome: "completed",
|
|
285
|
+
};
|
|
286
|
+
await this._storage.write(session.session_id, updated);
|
|
287
|
+
this._snapshots.delete(session.session_id);
|
|
288
|
+
await this._cascadeAbandonChildren(session.session_id);
|
|
289
|
+
return this._buildStatus(updated, taskOps);
|
|
290
|
+
}
|
|
291
|
+
// Pop current frame, return to parent
|
|
292
|
+
const newStack = session.stack.slice(0, -1);
|
|
293
|
+
const parentIdx = newStack.length - 1;
|
|
294
|
+
const parentFrame = newStack[parentIdx];
|
|
295
|
+
const parentWf = this._getWorkflow(session.session_id, parentFrame.workflow);
|
|
296
|
+
const parentState = this._resolveState(session, parentFrame.workflow, parentFrame.current_state);
|
|
297
|
+
// Determine next state in parent
|
|
298
|
+
const nextStateName = outcome === "complete" ? parentState?.on_complete : parentState?.on_fail;
|
|
299
|
+
if (!nextStateName) {
|
|
300
|
+
// Parent doesn't have on_complete/on_fail yet — park as pending_pop.
|
|
301
|
+
// modify can add it later, which will retry the pop.
|
|
302
|
+
const parked = {
|
|
303
|
+
...session,
|
|
304
|
+
pending_pop: { outcome },
|
|
305
|
+
updated_at: now,
|
|
306
|
+
};
|
|
307
|
+
await this._storage.write(session.session_id, parked);
|
|
308
|
+
return this._buildStatus(parked, taskOps);
|
|
309
|
+
}
|
|
310
|
+
const nextVisits = (parentFrame.state_visits[nextStateName] ?? 0) + 1;
|
|
311
|
+
const updatedParent = {
|
|
312
|
+
...parentFrame,
|
|
313
|
+
current_state: nextStateName,
|
|
314
|
+
state_visits: { ...parentFrame.state_visits, [nextStateName]: nextVisits },
|
|
315
|
+
total_transitions: parentFrame.total_transitions + 1,
|
|
316
|
+
};
|
|
317
|
+
newStack[parentIdx] = updatedParent;
|
|
318
|
+
const globalKey = `${parentFrame.workflow}:${nextStateName}`;
|
|
319
|
+
const prevGlobal = session.global_state_visits ?? {};
|
|
320
|
+
const updated = {
|
|
321
|
+
...session,
|
|
322
|
+
stack: newStack,
|
|
323
|
+
active_frame: parentIdx,
|
|
324
|
+
updated_at: now,
|
|
325
|
+
history: [
|
|
326
|
+
...session.history,
|
|
327
|
+
{ frame: session.active_frame, event: "pop", at: now },
|
|
328
|
+
{ frame: parentIdx, from: parentFrame.current_state, to: nextStateName, via: `on_${outcome}`, at: now },
|
|
329
|
+
],
|
|
330
|
+
global_state_visits: { ...prevGlobal, [globalKey]: (prevGlobal[globalKey] ?? 0) + 1 },
|
|
331
|
+
};
|
|
332
|
+
await this._storage.write(session.session_id, updated);
|
|
333
|
+
// Check if the new parent state is also a sub_workflow or terminal
|
|
334
|
+
const nextState = this._resolveState(updated, parentFrame.workflow, nextStateName);
|
|
335
|
+
if (nextState?.terminal) {
|
|
336
|
+
const hasTransitions = nextState.transitions && Object.keys(nextState.transitions).length > 0;
|
|
337
|
+
if (!hasTransitions) {
|
|
338
|
+
// Pre-check: if recursive pop would reach top-level, guard children
|
|
339
|
+
if (updated.stack.length === 1) {
|
|
340
|
+
const activeChildren = this._getActiveChildren(session.session_id);
|
|
341
|
+
if (activeChildren.length > 0) {
|
|
342
|
+
const nextOutcome = nextState.outcome === "fail" ? "fail" : "complete";
|
|
343
|
+
const parked = {
|
|
344
|
+
...updated,
|
|
345
|
+
pending_pop: { outcome: nextOutcome },
|
|
346
|
+
updated_at: now,
|
|
347
|
+
};
|
|
348
|
+
await this._storage.write(session.session_id, parked);
|
|
349
|
+
throw new Error(this._formatChildrenBlockError(session.session_id, activeChildren));
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
const nextOutcome = nextState.outcome === "fail" ? "fail" : "complete";
|
|
353
|
+
return this._popStack(updated, nextOutcome, taskOps);
|
|
354
|
+
}
|
|
355
|
+
// Soft terminal in parent after pop
|
|
356
|
+
const softUpdated = { ...updated, soft_terminal: true };
|
|
357
|
+
await this._storage.write(session.session_id, softUpdated);
|
|
358
|
+
return this._buildStatus(softUpdated, taskOps);
|
|
359
|
+
}
|
|
360
|
+
if (nextState?.sub_workflow) {
|
|
361
|
+
return this._pushSubWorkflow(updated, nextState, taskOps);
|
|
362
|
+
}
|
|
363
|
+
return this._buildStatus(updated, taskOps);
|
|
364
|
+
}
|
|
365
|
+
_formatChildrenBlockError(parentSessionId, activeChildren) {
|
|
366
|
+
const children = activeChildren ?? this._getActiveChildren(parentSessionId);
|
|
367
|
+
const details = children.map(c => {
|
|
368
|
+
const f = c.stack[c.active_frame];
|
|
369
|
+
return ` - ${c.session_id}: ${f.workflow} @ ${f.current_state} (${f.total_transitions} transitions)`;
|
|
370
|
+
}).join("\n");
|
|
371
|
+
return (`Cannot complete: ${children.length} child session(s) still active:\n${details}\n` +
|
|
372
|
+
`Abort them via abort or investigate why they didn't finish.`);
|
|
373
|
+
}
|
|
374
|
+
_getActiveChildren(parentSessionId) {
|
|
375
|
+
return this._storage.readAll().filter(s => s.parent_session_id === parentSessionId && s.stack.length > 0);
|
|
376
|
+
}
|
|
377
|
+
async _cascadeAbandonChildren(parentSessionId) {
|
|
378
|
+
const now = new Date().toISOString();
|
|
379
|
+
const children = this._getActiveChildren(parentSessionId);
|
|
380
|
+
for (const child of children) {
|
|
381
|
+
const updated = {
|
|
382
|
+
...child,
|
|
383
|
+
stack: [],
|
|
384
|
+
active_frame: -1,
|
|
385
|
+
updated_at: now,
|
|
386
|
+
history: [...child.history, { frame: child.active_frame, event: "cascade_abandon", at: now }],
|
|
387
|
+
outcome: "abandoned",
|
|
388
|
+
};
|
|
389
|
+
await this._storage.write(child.session_id, updated);
|
|
390
|
+
this._snapshots.delete(child.session_id);
|
|
391
|
+
await this._cascadeAbandonChildren(child.session_id);
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
_getWorkflow(sessionId, name) {
|
|
395
|
+
// Try snapshot first, fallback to loader
|
|
396
|
+
const snapshot = this._snapshots.get(sessionId);
|
|
397
|
+
const wf = snapshot?.get(name) ?? this._loader.get(name);
|
|
398
|
+
if (!wf)
|
|
399
|
+
throw new Error(`Workflow "${name}" not found`);
|
|
400
|
+
return wf;
|
|
401
|
+
}
|
|
402
|
+
_resolveState(session, workflowName, stateName) {
|
|
403
|
+
// Check added states first (they may not exist in base YAML)
|
|
404
|
+
const overrides = session.overrides[workflowName];
|
|
405
|
+
if (overrides?.add_states?.[stateName]) {
|
|
406
|
+
return overrides.add_states[stateName];
|
|
407
|
+
}
|
|
408
|
+
const wf = this._getWorkflow(session.session_id, workflowName);
|
|
409
|
+
const base = wf.states[stateName];
|
|
410
|
+
if (!base)
|
|
411
|
+
return undefined;
|
|
412
|
+
// Apply overrides
|
|
413
|
+
if (!overrides)
|
|
414
|
+
return base;
|
|
415
|
+
// Check modified states
|
|
416
|
+
const mods = overrides.modify_states?.[stateName];
|
|
417
|
+
if (!mods) {
|
|
418
|
+
// Apply transition overrides
|
|
419
|
+
return this._applyTransitionOverrides(base, workflowName, stateName, overrides);
|
|
420
|
+
}
|
|
421
|
+
const merged = { ...base, ...mods };
|
|
422
|
+
return this._applyTransitionOverrides(merged, workflowName, stateName, overrides);
|
|
423
|
+
}
|
|
424
|
+
_applyTransitionOverrides(state, _workflowName, stateName, overrides) {
|
|
425
|
+
let transitions = { ...(state.transitions ?? {}) };
|
|
426
|
+
// Add transitions
|
|
427
|
+
if (overrides.add_transitions) {
|
|
428
|
+
for (const t of overrides.add_transitions) {
|
|
429
|
+
if (t.from === stateName)
|
|
430
|
+
transitions[t.name] = t.to;
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
// Remove transitions
|
|
434
|
+
if (overrides.remove_transitions) {
|
|
435
|
+
for (const t of overrides.remove_transitions) {
|
|
436
|
+
if (t.from === stateName)
|
|
437
|
+
delete transitions[t.name];
|
|
438
|
+
}
|
|
439
|
+
}
|
|
440
|
+
return { ...state, transitions };
|
|
441
|
+
}
|
|
442
|
+
_buildStatus(session, taskOps) {
|
|
443
|
+
if (session.stack.length === 0) {
|
|
444
|
+
const isAbandoned = session.outcome === "abandoned";
|
|
445
|
+
const msg = isAbandoned ? "Workflow abandoned." : "Workflow completed.";
|
|
446
|
+
const stateName = isAbandoned ? "(abandoned)" : "(completed)";
|
|
447
|
+
return {
|
|
448
|
+
sessionId: session.session_id,
|
|
449
|
+
stack: [],
|
|
450
|
+
activeFrame: -1,
|
|
451
|
+
currentState: { prompt: msg, terminal: true },
|
|
452
|
+
currentStateName: stateName,
|
|
453
|
+
currentWorkflow: "(none)",
|
|
454
|
+
availableTransitions: {},
|
|
455
|
+
prompt: msg,
|
|
456
|
+
history: session.history,
|
|
457
|
+
context: session.context,
|
|
458
|
+
taskOps: taskOps ?? [],
|
|
459
|
+
visitCount: 0,
|
|
460
|
+
};
|
|
461
|
+
}
|
|
462
|
+
const frame = session.stack[session.active_frame];
|
|
463
|
+
const state = this._resolveState(session, frame.workflow, frame.current_state);
|
|
464
|
+
const prompt = state?.prompt ?? `[sub_workflow: ${state?.sub_workflow ?? "unknown"}]`;
|
|
465
|
+
const currentTaskOps = [...(taskOps ?? [])];
|
|
466
|
+
if (state?.task) {
|
|
467
|
+
currentTaskOps.push({ action: "create", subject: state.task });
|
|
468
|
+
}
|
|
469
|
+
return {
|
|
470
|
+
sessionId: session.session_id,
|
|
471
|
+
stack: session.stack,
|
|
472
|
+
activeFrame: session.active_frame,
|
|
473
|
+
currentState: state ?? { prompt: "Unknown state" },
|
|
474
|
+
currentStateName: frame.current_state,
|
|
475
|
+
currentWorkflow: frame.workflow,
|
|
476
|
+
availableTransitions: state?.transitions ?? {},
|
|
477
|
+
prompt,
|
|
478
|
+
history: session.history,
|
|
479
|
+
context: session.context,
|
|
480
|
+
taskOps: currentTaskOps,
|
|
481
|
+
visitCount: session.global_state_visits?.[`${frame.workflow}:${frame.current_state}`]
|
|
482
|
+
?? frame.state_visits[frame.current_state] ?? 0,
|
|
483
|
+
};
|
|
484
|
+
}
|
|
485
|
+
}
|
|
486
|
+
//# sourceMappingURL=engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"engine.js","sourceRoot":"","sources":["../src/engine.ts"],"names":[],"mappings":"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"}
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/build/index.js
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import os from "node:os";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { fileURLToPath } from "node:url";
|
|
4
|
+
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
|
+
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
|
+
import { Storage } from "./storage.js";
|
|
7
|
+
import { Loader } from "./loader.js";
|
|
8
|
+
import { Engine } from "./engine.js";
|
|
9
|
+
import { Modifier } from "./modifier.js";
|
|
10
|
+
import { registerTools } from "./tools.js";
|
|
11
|
+
import { createDashboard } from "./dashboard.js";
|
|
12
|
+
// Resolve dir: env override → absolute default under ~/.claude/
|
|
13
|
+
function resolveDir(envVar, defaultAbs) {
|
|
14
|
+
const val = process.env[envVar];
|
|
15
|
+
if (!val)
|
|
16
|
+
return defaultAbs;
|
|
17
|
+
return path.isAbsolute(val) ? val : path.resolve(process.cwd(), val);
|
|
18
|
+
}
|
|
19
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
20
|
+
const BUNDLED_DIR = path.resolve(__dirname, "..", "templates");
|
|
21
|
+
const home = os.homedir();
|
|
22
|
+
const GLOBAL_WORKFLOW_DIR = resolveDir("WORKFLOW_DIR", path.join(home, ".claude", "workflows"));
|
|
23
|
+
const STATE_DIR = resolveDir("STATE_DIR", path.join(home, ".claude", "workflow-state"));
|
|
24
|
+
const DASHBOARD_PORT = parseInt(process.env["DASHBOARD_PORT"] ?? "3100", 10);
|
|
25
|
+
// Project-level workflows: .claude/workflows/ relative to CWD (if different from global)
|
|
26
|
+
const projectDir = path.resolve(process.cwd(), ".claude", "workflows");
|
|
27
|
+
const PROJECT_WORKFLOW_DIR = projectDir !== GLOBAL_WORKFLOW_DIR ? projectDir : null;
|
|
28
|
+
// Initialize components
|
|
29
|
+
const storage = new Storage(STATE_DIR);
|
|
30
|
+
const loader = new Loader(BUNDLED_DIR, GLOBAL_WORKFLOW_DIR, PROJECT_WORKFLOW_DIR);
|
|
31
|
+
// Validate cross-references
|
|
32
|
+
const refErrors = loader.validateReferences();
|
|
33
|
+
if (refErrors.length > 0) {
|
|
34
|
+
console.error("Workflow reference warnings:", refErrors.join("; "));
|
|
35
|
+
}
|
|
36
|
+
// Start hot-reload
|
|
37
|
+
loader.startWatching();
|
|
38
|
+
const engine = new Engine(storage, loader);
|
|
39
|
+
const modifier = new Modifier(storage, loader);
|
|
40
|
+
modifier.setEngine(engine);
|
|
41
|
+
// Create MCP server
|
|
42
|
+
const server = new McpServer({
|
|
43
|
+
name: "workflow-engine",
|
|
44
|
+
version: "1.0.0",
|
|
45
|
+
});
|
|
46
|
+
// Register all tools
|
|
47
|
+
registerTools(server, engine, modifier, loader, storage);
|
|
48
|
+
// Start dashboard
|
|
49
|
+
createDashboard(storage, loader, DASHBOARD_PORT);
|
|
50
|
+
// Connect via stdio
|
|
51
|
+
async function main() {
|
|
52
|
+
const transport = new StdioServerTransport();
|
|
53
|
+
await server.connect(transport);
|
|
54
|
+
console.error("MCP Workflow Engine running on stdio");
|
|
55
|
+
}
|
|
56
|
+
main().catch((err) => {
|
|
57
|
+
console.error("Fatal error:", err);
|
|
58
|
+
process.exit(1);
|
|
59
|
+
});
|
|
60
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import type { WorkflowDefinition } from "./types.js";
|
|
2
|
+
export declare class Loader {
|
|
3
|
+
private readonly _bundledDir;
|
|
4
|
+
private readonly _globalDir;
|
|
5
|
+
private readonly _projectDir;
|
|
6
|
+
private _workflows;
|
|
7
|
+
private _globalWatcher;
|
|
8
|
+
private _projectWatcher;
|
|
9
|
+
constructor(bundledDir: string | null, globalDir: string, projectDir: string | null);
|
|
10
|
+
get(name: string): WorkflowDefinition | undefined;
|
|
11
|
+
getAll(): Map<string, WorkflowDefinition>;
|
|
12
|
+
names(): string[];
|
|
13
|
+
/** Directory where create saves new YAML files */
|
|
14
|
+
getWriteDir(scope?: "project" | "global"): string;
|
|
15
|
+
/** @deprecated Use getWriteDir() */
|
|
16
|
+
get writeDir(): string;
|
|
17
|
+
startWatching(): void;
|
|
18
|
+
stopWatching(): void;
|
|
19
|
+
reload(): void;
|
|
20
|
+
/** Delete a workflow YAML file. */
|
|
21
|
+
delete(name: string, scope?: "project" | "global"): string;
|
|
22
|
+
private _findFile;
|
|
23
|
+
private _watchDir;
|
|
24
|
+
private _loadAll;
|
|
25
|
+
private _loadDir;
|
|
26
|
+
private _validate;
|
|
27
|
+
validateReferences(): string[];
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=loader.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loader.d.ts","sourceRoot":"","sources":["../src/loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAGrD,qBAAa,MAAM;IACjB,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgB;IAC5C,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;IACpC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAgB;IAC5C,OAAO,CAAC,UAAU,CAA8C;IAChE,OAAO,CAAC,cAAc,CAA6B;IACnD,OAAO,CAAC,eAAe,CAA6B;gBAExC,UAAU,EAAE,MAAM,GAAG,IAAI,EAAE,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,IAAI;IAS5E,GAAG,CAAC,IAAI,EAAE,MAAM,GAAG,kBAAkB,GAAG,SAAS;IAIjD,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,kBAAkB,CAAC;IAIzC,KAAK,IAAI,MAAM,EAAE;IAIxB,kDAAkD;IAC3C,WAAW,CAAC,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM;IAUxD,oCAAoC;IACpC,IAAW,QAAQ,IAAI,MAAM,CAE5B;IAEM,aAAa,IAAI,IAAI;IAKrB,YAAY,IAAI,IAAI;IAOpB,MAAM,IAAI,IAAI;IAIrB,mCAAmC;IAC5B,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,SAAS,GAAG,QAAQ,GAAG,MAAM;IAcjE,OAAO,CAAC,SAAS;IAQjB,OAAO,CAAC,SAAS;IAWjB,OAAO,CAAC,QAAQ;IAehB,OAAO,CAAC,QAAQ;IAwBhB,OAAO,CAAC,SAAS;IAgCV,kBAAkB,IAAI,MAAM,EAAE;CAUtC"}
|