@leclabs/agent-flow-navigator-mcp 1.0.0 → 1.2.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/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  A workflow state machine MCP server that navigates agents through DAG-based workflows.
6
6
 
7
- Navigator tracks task state and evaluates graph edges - it tells the orchestrator _where to go next_, but doesn't drive. Think of it like a GPS: you tell it where you are and what happened, it tells you where to go.
7
+ Navigator tracks task state and evaluates graph edges -- it tells the orchestrator _where to go next_, but doesn't drive. Think of it like a GPS: you tell it where you are and what happened, it tells you where to go.
8
8
 
9
9
  ## Installation
10
10
 
@@ -39,104 +39,119 @@ Add to your `.mcp.json`:
39
39
 
40
40
  Navigator works with the [flow plugin](https://github.com/leclabs/agent-toolkit/tree/main/plugins/flow) to provide structured workflow execution:
41
41
 
42
- 1. **Initialize workflows** - Copy workflow templates to your project with `CopyWorkflows`
43
- 2. **Start a task** - Use `Navigate` with a workflow type and description
44
- 3. **Follow the flow** - Navigator tells you the current step and what to do
45
- 4. **Advance on completion** - Report `passed` or `failed` to move to the next step
42
+ 1. **Initialize workflows** -- Copy workflow templates to your project with `CopyWorkflows`
43
+ 2. **Start a task** -- Use `Navigate` with a workflow type and description
44
+ 3. **Follow the flow** -- Navigator tells you the current step and what to do
45
+ 4. **Advance on completion** -- Report `passed` or `failed` to move to the next step
46
46
 
47
47
  ```
48
48
  User: "Add dark mode support"
49
49
 
50
50
  Navigate(workflowType: "feature-development", description: "Add dark mode support")
51
51
 
52
- Navigator returns: Step 1 of 8 - "Create implementation plan"
52
+ Navigator returns: currentStep: "parse_requirements", stage: "planning"
53
53
 
54
- Agent executes step, then calls Navigate(result: "passed")
54
+ Agent executes step, then calls Navigate(taskFilePath: "...", result: "passed")
55
55
 
56
- Navigator returns: Step 2 of 8 - "Implement changes"
56
+ Navigator returns: currentStep: "explore_codebase", stage: "planning"
57
57
 
58
58
  ... continues through workflow ...
59
59
  ```
60
60
 
61
61
  ## MCP Tools Reference
62
62
 
63
- | Tool | Description |
64
- | ---- | ----------- |
65
- | `Navigate` | Start a workflow, get current state, or advance to next step |
66
- | `Diagram` | Generate a mermaid flowchart for a workflow |
67
- | `ListWorkflows` | List all available workflows |
68
- | `SelectWorkflow` | Get workflow selection dialog for user interaction |
69
- | `CopyWorkflows` | Copy workflows from catalog to project |
70
- | `ListCatalog` | List workflows available in the catalog |
63
+ | Tool | Description |
64
+ | ---------------- | ------------------------------------------------------------ |
65
+ | `Navigate` | Start a workflow, get current state, or advance to next step |
66
+ | `Diagram` | Generate a mermaid flowchart for a workflow |
67
+ | `ListWorkflows` | List all available workflows |
68
+ | `SelectWorkflow` | Get workflow selection dialog for user interaction |
69
+ | `CopyWorkflows` | Copy workflows from catalog to project |
70
+ | `ListCatalog` | List workflows available in the catalog |
71
71
 
72
72
  ### Navigate
73
73
 
74
- The primary tool for workflow navigation.
74
+ The primary tool. Operates in 3 modes:
75
75
 
76
- | Parameter | Type | Description |
77
- | --------- | ---- | ----------- |
78
- | `workflowType` | string | Workflow ID (for start only, e.g., "feature-development") |
79
- | `description` | string | User's task description (for start) |
80
- | `taskFilePath` | string | Path to task file (for advance/current) |
81
- | `result` | "passed" \| "failed" | Step result (for advance) |
76
+ - **Start**: Pass `workflowType` + `description` to begin a workflow
77
+ - **Current**: Pass `taskFilePath` to get current step state
78
+ - **Advance**: Pass `taskFilePath` + `result` to move to the next step
79
+
80
+ | Parameter | Type | Description |
81
+ | -------------- | -------------------- | --------------------------------------------------------- |
82
+ | `workflowType` | string | Workflow ID (for start only, e.g., "feature-development") |
83
+ | `description` | string | User's task description (for start) |
84
+ | `taskFilePath` | string | Path to task file (for advance/current) |
85
+ | `result` | "passed" \| "failed" | Step result (for advance) |
82
86
 
83
87
  ### Diagram
84
88
 
85
89
  Generates a mermaid diagram for visualizing workflow structure.
86
90
 
87
- | Parameter | Type | Description |
88
- | --------- | ---- | ----------- |
91
+ | Parameter | Type | Description |
92
+ | -------------- | ------ | ----------------------------------- |
89
93
  | `workflowType` | string | Workflow ID to visualize (required) |
90
- | `currentStep` | string | Optional step to highlight |
94
+ | `currentStep` | string | Optional step to highlight |
95
+
96
+ ### ListWorkflows
97
+
98
+ Lists available workflows, filterable by source.
99
+
100
+ | Parameter | Type | Description |
101
+ | --------- | ------ | --------------------------------------------------------------------------- |
102
+ | `source` | string | Filter: `"project"`, `"catalog"`, or `"all"`. Defaults to project if exists |
103
+
104
+ ### SelectWorkflow
105
+
106
+ Returns a workflow selection dialog for user interaction. No parameters.
107
+
108
+ ### CopyWorkflows
109
+
110
+ Copies workflows from catalog to the project's `.flow/workflows/` directory.
111
+
112
+ | Parameter | Type | Description |
113
+ | ------------- | -------- | -------------------------------------- |
114
+ | `workflowIds` | string[] | Workflow IDs to copy. Empty = copy all |
91
115
 
92
- ## Architecture Overview
116
+ ### ListCatalog
117
+
118
+ Lists workflows available in the built-in catalog. No parameters.
119
+
120
+ ## Architecture
93
121
 
94
122
  ```
95
- ┌─────────────────────────────────────────────────────────────────────┐
96
- ORCHESTRATOR
97
- │ (Source of Truth: GitHub Issues, External DB, etc.)
98
- │ (Executes tasks, makes decisions, drives the workflow) │
99
- └─────────────────────────┬───────────────────────────────────────────┘
100
-
101
- ┌───────────────┼───────────────┐
102
- load_workflow │ load_task_tree│
103
- │ │
104
- ▼ ▼ │
105
- ┌─────────────────────────────────────────┴───────────────────────────┐
106
- NAVIGATOR
107
- (Workflow State Machine MCP Server)
108
-
109
- ┌──────────────────┐ ┌──────────────────┐
110
- │ │ Workflow Store │Task Tree
111
- │ (Graph Defs) │ │ (State Tracker)
112
- └──────────────────┘ └──────────────────┘
113
-
114
- ┌──────────────────┐ ┌──────────────────┐
115
- │ │ Edge Evaluator │ │ Sync Tracker │ │
116
- │ │ (Next Step?) │ │ (Pending Syncs) │ │
117
- │ └──────────────────┘ └──────────────────┘ │
118
- │ │
119
- └─────────────────────────┬───────────────────────────────────────────┘
120
-
121
- ┌───────────────┼───────────────┐
122
- │ get_next_tasks│ advance_task │
123
- │ "What's next?"│ "I got X" │
124
- ▼ ▼ │
125
- ┌─────────────────────────────────────────┴───────────────────────────┐
126
- │ ORCHESTRATOR │
127
- │ (Receives directions, executes, persists, confirms syncs) │
128
- └─────────────────────────────────────────────────────────────────────┘
123
+ ┌─────────────────────────────────────────────────┐
124
+ ORCHESTRATOR
125
+ │ (Executes tasks, delegates to subagents)
126
+ └──────────────────────┬──────────────────────────┘
127
+
128
+ Navigate ───────┼─────── Diagram
129
+ ListWorkflows ──┤ CopyWorkflows
130
+ SelectWorkflow ─┤ ListCatalog
131
+
132
+ ┌──────────────────────┴──────────────────────────┐
133
+ │ NAVIGATOR │
134
+ (Workflow State Machine MCP)
135
+
136
+ ┌──────────────────┐ ┌──────────────────┐
137
+ │ │ Workflow Store │ │ Edge Evaluator │ │
138
+ │ │ (Graph Defs) │ (Next Step?)
139
+ └──────────────────┘ └──────────────────┘
140
+
141
+ Write-through: state transitions persist
142
+ atomically to the task file on disk
143
+ └─────────────────────────────────────────────────┘
129
144
  ```
130
145
 
131
146
  ### Key Concepts
132
147
 
133
- | Concept | Description |
134
- | ----------------------- | ------------------------------------------------------------------------------------ |
135
- | **Workflow Definition** | A DAG blueprint describing how to execute a type of work (nodes + conditional edges) |
136
- | **Task Tree** | A runtime priority queue of actual work items across multiple workflow types |
137
- | **Sync Tracking** | Mutations are tracked; orchestrator is reminded to persist to primary store |
138
- | **Conditional Edges** | Edges with `on` condition (passed/failed) - retry logic is on nodes via `maxRetries` |
139
- | **HITL Escalation** | When retries are exhausted, tasks route to end nodes with `escalation: "hitl"` |
148
+ | Concept | Description |
149
+ | ----------------------- | ------------------------------------------------------------------------------------- |
150
+ | **Workflow Definition** | A DAG blueprint describing how to execute a type of work (nodes + conditional edges) |
151
+ | **Navigate 3-Mode API** | Start a workflow, get current state, or advance -- one tool, three calling patterns |
152
+ | **Write-Through** | State transitions are persisted to the task file atomically on every advance |
153
+ | **Conditional Edges** | Edges with `on` condition (passed/failed) -- retry logic is on nodes via `maxRetries` |
154
+ | **HITL Escalation** | When retries are exhausted, tasks route to end nodes with `escalation: "hitl"` |
140
155
 
141
156
  ## Workflow Definition Schema
142
157
 
@@ -159,89 +174,24 @@ Generates a mermaid diagram for visualizing workflow structure.
159
174
 
160
175
  ### Task/Gate Node Properties
161
176
 
162
- | Property | Description |
163
- | ------------ | ---------------------------------------------------------- |
164
- | `name` | Human-readable name (required) |
165
- | `outputs` | Possible outcomes (default: `["passed", "failed"]`) |
166
- | `maxRetries` | Retry count on failure before following "failed" edge |
167
- | `agent` | Agent type to perform this task |
168
- | `stage` | Workflow phase: planning/development/verification/delivery |
177
+ | Property | Description |
178
+ | ------------ | -------------------------------------------------------------------- |
179
+ | `name` | Human-readable name (required) |
180
+ | `outputs` | Possible outcomes (default: `["passed", "failed"]`) |
181
+ | `maxRetries` | Retry count on failure before following "failed" edge |
182
+ | `agent` | Agent type to perform this task |
183
+ | `stage` | Workflow phase (e.g., planning, development, verification, delivery) |
184
+ | `metadata` | Arbitrary key-value data for workflow tooling and extensions |
169
185
 
170
186
  ### Edge Properties
171
187
 
172
- | Property | Description |
173
- | -------- | -------------------------------------------------------------- |
174
- | `from` | Source node ID |
175
- | `to` | Target node ID |
176
- | `on` | Output value that triggers this edge (for conditional routing) |
177
- | `label` | Human-readable edge description |
178
-
179
- ## Advanced Usage
180
-
181
- ### Loading Workflow Definitions
182
-
183
- ```json
184
- {
185
- "tool": "load_workflow",
186
- "arguments": {
187
- "id": "ui-reconstruction",
188
- "definition": {
189
- "nodes": {
190
- "start": { "type": "start" },
191
- "analyze": { "type": "task", "name": "Analyze Components" },
192
- "review": { "type": "gate", "name": "Review Analysis", "maxRetries": 3 },
193
- "end": { "type": "end", "result": "success" },
194
- "hitl": { "type": "end", "result": "blocked", "escalation": "hitl" }
195
- },
196
- "edges": [
197
- { "from": "start", "to": "analyze" },
198
- { "from": "analyze", "to": "review" },
199
- { "from": "review", "to": "analyze", "on": "failed", "label": "Retry on failure" },
200
- { "from": "review", "to": "hitl", "on": "max_retries_exceeded", "label": "Escalate after 3 failures" },
201
- { "from": "review", "to": "end", "on": "passed" }
202
- ]
203
- }
204
- }
205
- }
206
- ```
207
-
208
- ### Task Tree Management
209
-
210
- Load a priority queue of tasks:
211
-
212
- ```json
213
- {
214
- "tool": "load_task_tree",
215
- "arguments": {
216
- "tasks": [
217
- {
218
- "id": "task-001",
219
- "issueId": "ISSUE-042",
220
- "workflowType": "ui-reconstruction",
221
- "currentStep": "start",
222
- "priority": 100,
223
- "status": "PENDING",
224
- "context": { "targetUrl": "https://example.com" }
225
- }
226
- ]
227
- }
228
- }
229
- ```
230
-
231
- ### Advancing Tasks
232
-
233
- After executing a task step:
234
-
235
- ```json
236
- {
237
- "tool": "advance_task",
238
- "arguments": {
239
- "taskId": "task-001",
240
- "result": "passed",
241
- "output": "Analysis complete, found 5 components"
242
- }
243
- }
244
- ```
188
+ | Property | Description |
189
+ | ----------- | -------------------------------------------------------------- |
190
+ | `from` | Source node ID |
191
+ | `to` | Target node ID |
192
+ | `on` | Output value that triggers this edge (for conditional routing) |
193
+ | `label` | Human-readable edge description |
194
+ | `condition` | Expression for future conditional routing (informational) |
245
195
 
246
196
  ## Testing
247
197
 
@@ -253,8 +203,7 @@ npm test
253
203
 
254
204
  - [GitHub Repository](https://github.com/leclabs/agent-toolkit)
255
205
  - [Flow Plugin](https://github.com/leclabs/agent-toolkit/tree/main/plugins/flow)
256
- - [Full Documentation](https://github.com/leclabs/agent-toolkit/tree/main/packages/agent-flow-navigator-mcp)
257
206
 
258
207
  ## License
259
208
 
260
- MIT
209
+ ISC
@@ -0,0 +1,110 @@
1
+ {
2
+ "id": "build-review-murder-board",
3
+ "name": "Build-Review Murder Board",
4
+ "description": "High-scrutiny iterative build-review loop. A fresh reviewer agent tears apart each build attempt with maximum rigor. Ideal for critical changes requiring independent verification.",
5
+ "nodes": {
6
+ "start": {
7
+ "type": "start",
8
+ "name": "Start",
9
+ "description": "Build-review cycle begins"
10
+ },
11
+ "build": {
12
+ "type": "task",
13
+ "name": "Build",
14
+ "description": "Implement or revise the changes based on requirements or review feedback",
15
+ "agent": "Developer",
16
+ "stage": "development"
17
+ },
18
+ "review": {
19
+ "type": "gate",
20
+ "name": "Murder Board Review",
21
+ "description": "Independent high-scrutiny review. Reviewer must be a fresh agent with no prior context of this build. Approval requires confidence score >= 80.",
22
+ "agent": "Reviewer",
23
+ "stage": "verification",
24
+ "maxRetries": 3,
25
+ "config": {
26
+ "scrutinyLevel": 5,
27
+ "blindShot": true,
28
+ "approvalThreshold": 80
29
+ }
30
+ },
31
+ "lint_format": {
32
+ "type": "gate",
33
+ "name": "Lint & Format",
34
+ "description": "Run lint and format checks. Auto-fix issues where possible.",
35
+ "agent": "Developer",
36
+ "stage": "delivery",
37
+ "maxRetries": 3
38
+ },
39
+ "commit": {
40
+ "type": "task",
41
+ "name": "Commit Changes",
42
+ "description": "Commit all changes with a descriptive message summarizing the work done",
43
+ "agent": "Developer",
44
+ "stage": "delivery"
45
+ },
46
+ "end_success": {
47
+ "type": "end",
48
+ "result": "success",
49
+ "name": "Approved",
50
+ "description": "Build passed murder board review and delivered"
51
+ },
52
+ "hitl_blocked": {
53
+ "type": "end",
54
+ "result": "blocked",
55
+ "escalation": "hitl",
56
+ "name": "Review Blocked",
57
+ "description": "Build failed murder board review after all retries - needs human intervention"
58
+ }
59
+ },
60
+ "edges": [
61
+ {
62
+ "from": "start",
63
+ "to": "build"
64
+ },
65
+ {
66
+ "from": "build",
67
+ "to": "review"
68
+ },
69
+ {
70
+ "from": "review",
71
+ "to": "build",
72
+ "on": "failed",
73
+ "label": "Revise build based on review feedback"
74
+ },
75
+ {
76
+ "from": "review",
77
+ "to": "hitl_blocked",
78
+ "on": "failed",
79
+ "label": "Review failures exhausted retries"
80
+ },
81
+ {
82
+ "from": "review",
83
+ "to": "lint_format",
84
+ "on": "passed",
85
+ "label": "Review passed, run lint checks"
86
+ },
87
+ {
88
+ "from": "lint_format",
89
+ "to": "commit",
90
+ "on": "passed",
91
+ "label": "Lint passes, commit changes"
92
+ },
93
+ {
94
+ "from": "lint_format",
95
+ "to": "build",
96
+ "on": "failed",
97
+ "label": "Fix lint/format issues"
98
+ },
99
+ {
100
+ "from": "lint_format",
101
+ "to": "hitl_blocked",
102
+ "on": "failed",
103
+ "label": "Lint issues persist"
104
+ },
105
+ {
106
+ "from": "commit",
107
+ "to": "end_success"
108
+ }
109
+ ]
110
+ }
@@ -0,0 +1,108 @@
1
+ {
2
+ "id": "build-review-quick",
3
+ "name": "Build-Review Quick",
4
+ "description": "Low-scrutiny iterative build-review loop. A lightweight review pass ensures basic correctness before delivery. Suited for low-risk or well-understood changes.",
5
+ "nodes": {
6
+ "start": {
7
+ "type": "start",
8
+ "name": "Start",
9
+ "description": "Build-review cycle begins"
10
+ },
11
+ "build": {
12
+ "type": "task",
13
+ "name": "Build",
14
+ "description": "Implement or revise the changes based on requirements or review feedback",
15
+ "agent": "Developer",
16
+ "stage": "development"
17
+ },
18
+ "review": {
19
+ "type": "gate",
20
+ "name": "Quick Review",
21
+ "description": "Lightweight review checking basic correctness and completeness",
22
+ "agent": "Reviewer",
23
+ "stage": "verification",
24
+ "maxRetries": 2,
25
+ "config": {
26
+ "scrutinyLevel": 1
27
+ }
28
+ },
29
+ "lint_format": {
30
+ "type": "gate",
31
+ "name": "Lint & Format",
32
+ "description": "Run lint and format checks. Auto-fix issues where possible.",
33
+ "agent": "Developer",
34
+ "stage": "delivery",
35
+ "maxRetries": 3
36
+ },
37
+ "commit": {
38
+ "type": "task",
39
+ "name": "Commit Changes",
40
+ "description": "Commit all changes with a descriptive message summarizing the work done",
41
+ "agent": "Developer",
42
+ "stage": "delivery"
43
+ },
44
+ "end_success": {
45
+ "type": "end",
46
+ "result": "success",
47
+ "name": "Complete",
48
+ "description": "Build passed review and delivered"
49
+ },
50
+ "hitl_blocked": {
51
+ "type": "end",
52
+ "result": "blocked",
53
+ "escalation": "hitl",
54
+ "name": "Blocked",
55
+ "description": "Build failed review after all retries - needs human intervention"
56
+ }
57
+ },
58
+ "edges": [
59
+ {
60
+ "from": "start",
61
+ "to": "build"
62
+ },
63
+ {
64
+ "from": "build",
65
+ "to": "review"
66
+ },
67
+ {
68
+ "from": "review",
69
+ "to": "build",
70
+ "on": "failed",
71
+ "label": "Revise build based on review feedback"
72
+ },
73
+ {
74
+ "from": "review",
75
+ "to": "hitl_blocked",
76
+ "on": "failed",
77
+ "label": "Review failures exhausted retries"
78
+ },
79
+ {
80
+ "from": "review",
81
+ "to": "lint_format",
82
+ "on": "passed",
83
+ "label": "Review passed, run lint checks"
84
+ },
85
+ {
86
+ "from": "lint_format",
87
+ "to": "commit",
88
+ "on": "passed",
89
+ "label": "Lint passes, commit changes"
90
+ },
91
+ {
92
+ "from": "lint_format",
93
+ "to": "build",
94
+ "on": "failed",
95
+ "label": "Fix lint/format issues"
96
+ },
97
+ {
98
+ "from": "lint_format",
99
+ "to": "hitl_blocked",
100
+ "on": "failed",
101
+ "label": "Lint issues persist"
102
+ },
103
+ {
104
+ "from": "commit",
105
+ "to": "end_success"
106
+ }
107
+ ]
108
+ }
@@ -0,0 +1,236 @@
1
+ {
2
+ "id": "refactor",
3
+ "name": "Refactor",
4
+ "description": "Transform outdated codebases into modern equivalents using Functional Core / Imperative Shell architecture. Separates pure business logic from side effects.",
5
+ "nodes": {
6
+ "start": {
7
+ "type": "start",
8
+ "name": "Start",
9
+ "description": "Refactoring workflow begins"
10
+ },
11
+ "analyze_structure": {
12
+ "type": "task",
13
+ "name": "Analyze Structure",
14
+ "description": "Map current architecture: modules, dependencies, entry points. Identify coupling and cohesion issues.",
15
+ "agent": "Planner",
16
+ "stage": "analysis"
17
+ },
18
+ "identify_debt": {
19
+ "type": "task",
20
+ "name": "Identify Technical Debt",
21
+ "description": "Find code smells, anti-patterns, outdated practices. Document violations of SOLID, DRY, and separation of concerns.",
22
+ "agent": "Planner",
23
+ "stage": "analysis"
24
+ },
25
+ "classify_components": {
26
+ "type": "task",
27
+ "name": "Classify Components",
28
+ "description": "Categorize code into Functional Core (pure logic, no side effects) vs Imperative Shell (I/O, state, external calls).",
29
+ "agent": "Planner",
30
+ "stage": "analysis"
31
+ },
32
+ "design_refactor": {
33
+ "type": "task",
34
+ "name": "Design Refactor Plan",
35
+ "description": "Create transformation plan: define functional core boundaries, shell interfaces, and migration sequence.",
36
+ "agent": "Planner",
37
+ "stage": "planning"
38
+ },
39
+ "plan_review": {
40
+ "type": "gate",
41
+ "name": "Review Plan",
42
+ "description": "Verify refactor plan maintains behavioral equivalence while achieving architectural goals.",
43
+ "agent": "Reviewer",
44
+ "stage": "planning",
45
+ "maxRetries": 2,
46
+ "config": {
47
+ "scrutinyLevel": 3
48
+ }
49
+ },
50
+ "extract_core": {
51
+ "type": "task",
52
+ "name": "Extract Functional Core",
53
+ "description": "Refactor pure business logic into functional core: no side effects, deterministic, testable in isolation.",
54
+ "agent": "Developer",
55
+ "stage": "development"
56
+ },
57
+ "isolate_shell": {
58
+ "type": "task",
59
+ "name": "Isolate Imperative Shell",
60
+ "description": "Wrap side effects (I/O, state, external services) in thin imperative shell that coordinates functional core.",
61
+ "agent": "Developer",
62
+ "stage": "development"
63
+ },
64
+ "write_tests": {
65
+ "type": "task",
66
+ "name": "Write Tests",
67
+ "description": "Add tests verifying behavioral equivalence. Unit tests for functional core, integration tests for shell.",
68
+ "agent": "Tester",
69
+ "stage": "development"
70
+ },
71
+ "run_tests": {
72
+ "type": "gate",
73
+ "name": "Run Tests",
74
+ "description": "Execute test suite. Verify refactored code produces identical behavior to original.",
75
+ "agent": "Tester",
76
+ "stage": "verification",
77
+ "maxRetries": 3
78
+ },
79
+ "code_review": {
80
+ "type": "gate",
81
+ "name": "Code Review",
82
+ "description": "Review architecture: clean functional/shell separation, no hidden side effects in core, shell is minimal.",
83
+ "agent": "Reviewer",
84
+ "stage": "verification",
85
+ "maxRetries": 2,
86
+ "config": {
87
+ "scrutinyLevel": 3
88
+ }
89
+ },
90
+ "lint_format": {
91
+ "type": "gate",
92
+ "name": "Lint & Format",
93
+ "description": "Run lint and format checks. Auto-fix issues where possible.",
94
+ "agent": "Developer",
95
+ "stage": "delivery",
96
+ "maxRetries": 3
97
+ },
98
+ "commit": {
99
+ "type": "task",
100
+ "name": "Commit Changes",
101
+ "description": "Commit all changes with a descriptive message summarizing the refactoring",
102
+ "agent": "Developer",
103
+ "stage": "delivery"
104
+ },
105
+ "end_success": {
106
+ "type": "end",
107
+ "result": "success",
108
+ "name": "Complete",
109
+ "description": "Refactoring completed successfully"
110
+ },
111
+ "hitl_analysis_failed": {
112
+ "type": "end",
113
+ "result": "blocked",
114
+ "escalation": "hitl",
115
+ "name": "Analysis Blocked",
116
+ "description": "Analysis or planning needs human guidance"
117
+ },
118
+ "hitl_dev_failed": {
119
+ "type": "end",
120
+ "result": "blocked",
121
+ "escalation": "hitl",
122
+ "name": "Development Blocked",
123
+ "description": "Development or verification needs human intervention"
124
+ }
125
+ },
126
+ "edges": [
127
+ {
128
+ "from": "start",
129
+ "to": "analyze_structure"
130
+ },
131
+ {
132
+ "from": "analyze_structure",
133
+ "to": "identify_debt"
134
+ },
135
+ {
136
+ "from": "identify_debt",
137
+ "to": "classify_components"
138
+ },
139
+ {
140
+ "from": "classify_components",
141
+ "to": "design_refactor"
142
+ },
143
+ {
144
+ "from": "design_refactor",
145
+ "to": "plan_review"
146
+ },
147
+ {
148
+ "from": "plan_review",
149
+ "to": "design_refactor",
150
+ "on": "failed",
151
+ "label": "Revise plan based on feedback"
152
+ },
153
+ {
154
+ "from": "plan_review",
155
+ "to": "hitl_analysis_failed",
156
+ "on": "failed",
157
+ "label": "Planning exhausted retries"
158
+ },
159
+ {
160
+ "from": "plan_review",
161
+ "to": "extract_core",
162
+ "on": "passed",
163
+ "label": "Plan approved, begin refactoring"
164
+ },
165
+ {
166
+ "from": "extract_core",
167
+ "to": "isolate_shell"
168
+ },
169
+ {
170
+ "from": "isolate_shell",
171
+ "to": "write_tests"
172
+ },
173
+ {
174
+ "from": "write_tests",
175
+ "to": "run_tests"
176
+ },
177
+ {
178
+ "from": "run_tests",
179
+ "to": "extract_core",
180
+ "on": "failed",
181
+ "label": "Fix failing tests"
182
+ },
183
+ {
184
+ "from": "run_tests",
185
+ "to": "hitl_dev_failed",
186
+ "on": "failed",
187
+ "label": "Tests keep failing"
188
+ },
189
+ {
190
+ "from": "run_tests",
191
+ "to": "code_review",
192
+ "on": "passed",
193
+ "label": "Tests pass, ready for review"
194
+ },
195
+ {
196
+ "from": "code_review",
197
+ "to": "extract_core",
198
+ "on": "failed",
199
+ "label": "Address review feedback"
200
+ },
201
+ {
202
+ "from": "code_review",
203
+ "to": "hitl_dev_failed",
204
+ "on": "failed",
205
+ "label": "Review issues persist"
206
+ },
207
+ {
208
+ "from": "code_review",
209
+ "to": "lint_format",
210
+ "on": "passed",
211
+ "label": "Code approved, run lint checks"
212
+ },
213
+ {
214
+ "from": "lint_format",
215
+ "to": "commit",
216
+ "on": "passed",
217
+ "label": "Lint passes, commit changes"
218
+ },
219
+ {
220
+ "from": "lint_format",
221
+ "to": "extract_core",
222
+ "on": "failed",
223
+ "label": "Fix lint/format issues"
224
+ },
225
+ {
226
+ "from": "lint_format",
227
+ "to": "hitl_dev_failed",
228
+ "on": "failed",
229
+ "label": "Lint issues persist"
230
+ },
231
+ {
232
+ "from": "commit",
233
+ "to": "end_success"
234
+ }
235
+ ]
236
+ }
package/copier.js CHANGED
@@ -12,78 +12,41 @@
12
12
  export function generateFlowReadme() {
13
13
  return `# Flow Plugin
14
14
 
15
- DAG-based workflow orchestration for Claude Code.
16
-
17
- ## Overview
18
-
19
- Flow provides structured workflows that guide tasks through defined stages (planning → development → verification → delivery). Each step can be delegated to specialized subagents.
15
+ DAG-based workflow orchestration for AI agents.
20
16
 
21
17
  ## Quick Start
22
18
 
23
- Workflows work immediately from the built-in catalog - no setup required:
24
-
25
19
  \`\`\`bash
26
- # Create a task with workflow tracking
27
- /flow:task-create "Add user authentication" [workflow] feature-development
20
+ # Load the orchestrator at session start
21
+ /flow:prime
28
22
 
29
- # Or use prefix shortcuts
30
- feat: Add user authentication # → feature-development workflow
31
- bug: Fix login error # → bug-fix workflow
32
- task: Update config file # → quick-task workflow
23
+ # Create a task using a command
24
+ /flow:feat "add user authentication"
33
25
 
34
- # Run the task autonomously
35
- /flow:run
26
+ # Execute all pending tasks
27
+ /flow:go
36
28
  \`\`\`
37
29
 
38
30
  ## Commands
39
31
 
40
- | Command | Description |
41
- |---------|-------------|
42
- | \`/flow:prime\` | Load Orchestrator context (invoke at session start) |
43
- | \`/flow:task-create\` | Create a new task with workflow tracking |
44
- | \`/flow:task-list\` | List all flow tasks with current status |
45
- | \`/flow:task-get\` | Get detailed task info including workflow diagram |
46
- | \`/flow:task-advance\` | Advance task: \`<taskId> <passed|failed> [summary]\` |
47
- | \`/flow:run\` | Execute flow tasks autonomously |
48
- | \`/flow:list\` | List available workflows |
49
- | \`/flow:diagram\` | Generate mermaid diagram for a workflow |
50
- | \`/flow:init\` | Copy workflows to .flow/workflows/ for customization |
51
- | \`/flow:load\` | Reload workflows after editing .flow/workflows/ |
52
-
53
- ## Available Workflows
54
-
55
- - **quick-task** - Minimal: understand → execute → verify (best for simple tasks)
56
- - **agile-task** - Simple: analyze → implement → test → review
57
- - **feature-development** - Full lifecycle: requirements → planning → implementation → testing → PR
58
- - **bug-fix** - Bug workflow: reproduce → investigate → fix → verify → PR
59
- - **test-coverage** - Analyze coverage gaps and write tests
60
- - **context-optimization** - Optimize agent context and instructions
61
- - **ui-reconstruction** - Reconstruct UI components from screenshots or designs
32
+ | Command | Workflow | Description |
33
+ | --- | --- | --- |
34
+ | \`/flow:feat\` | feature-development | New feature with planning + review |
35
+ | \`/flow:bug\` | bug-fix | Bug investigation and fix |
36
+ | \`/flow:task\` | agile-task | General development task |
37
+ | \`/flow:fix\` | quick-task | Quick fix, minimal ceremony |
38
+ | \`/flow:spec\` | test-coverage | Analyze and improve test coverage |
39
+ | \`/flow:ctx\` | context-optimization | Optimize agent context and prompts |
40
+ | \`/flow:ui\` | ui-reconstruction | Reconstruct UI from reference |
41
+ | \`/flow:go\` | _(runs queue)_ | Execute all pending tasks |
62
42
 
63
- ## Customization (Optional)
43
+ Use \`/flow:task-create "description" <workflow-id>\` for workflows without command shortcuts.
64
44
 
65
- Flow's workflows work directly from the catalog in the flow->navigator mcp. If you want to create custom workflows you can run \`/flow:init\` to select a workflow from the catalog to customize for your project, your agents, and your tools.
66
-
67
- \`\`\`bash
68
- # Copy catalog workflows to .flow/workflows/ for editing
69
- /flow:init
70
-
71
- # Edit .flow/workflows/{workflow}/workflow.json
72
- # Then reload
73
- /flow:load
74
- \`\`\`
75
-
76
- **Customization options:**
77
- - Modify step definitions in workflow.json
78
- - Add custom \`instructions\` to steps for project-specific guidance
79
- - Create new workflows by adding new directories
45
+ ## Available Workflows
80
46
 
81
- ## How It Works
47
+ Workflows are defined in \`.flow/workflows/\`. Edit \`workflow.json\` to customize, then run \`/flow:load\` to reload.
82
48
 
83
- 1. **Navigate API** - Stateless MCP server computes next step based on workflow DAG
84
- 2. **Task Metadata** - Workflow state stored in Claude Code task metadata
85
- 3. **Subagent Delegation** - Steps delegated to specialized agents (planner, developer, tester, reviewer)
86
- 4. **Retry Logic** - Failed steps retry with configurable limits, escalate to HITL if exceeded
49
+ See [Flow Plugin docs](https://github.com/leclabs/agent-toolkit/tree/main/plugins/flow) for the full workflow catalog.
87
50
  `;
88
51
  }
89
52
 
package/engine.js CHANGED
@@ -13,7 +13,7 @@
13
13
  * - Edge to end node = escalation (taken if retries exhausted)
14
14
  */
15
15
 
16
- import { existsSync, readFileSync } from "fs";
16
+ import { existsSync, readFileSync, writeFileSync } from "fs";
17
17
 
18
18
  /**
19
19
  * Read and parse a task file
@@ -58,6 +58,9 @@ export function getTerminalType(node) {
58
58
  export function toSubagentRef(agentId) {
59
59
  if (!agentId) return null;
60
60
  if (agentId.startsWith("@")) return agentId;
61
+ // Namespaced: "org:developer" -> "@org:developer"
62
+ if (agentId.includes(":")) return `@${agentId}`;
63
+ // Simple: "developer" -> "@flow:developer"
61
64
  return `@flow:${agentId}`;
62
65
  }
63
66
 
@@ -454,7 +457,7 @@ export class WorkflowEngine {
454
457
  action = "advance";
455
458
  }
456
459
 
457
- return buildNavigateResponse(
460
+ const response = buildNavigateResponse(
458
461
  workflowType,
459
462
  evaluation.nextStep,
460
463
  nextStepDef,
@@ -463,5 +466,16 @@ export class WorkflowEngine {
463
466
  retryCount,
464
467
  description
465
468
  );
469
+
470
+ // Write-through: persist state transition to task file
471
+ if (taskFilePath) {
472
+ const task = readTaskFile(taskFilePath);
473
+ if (task) {
474
+ task.metadata = { ...task.metadata, ...response.metadata };
475
+ writeFileSync(taskFilePath, JSON.stringify(task, null, 2));
476
+ }
477
+ }
478
+
479
+ return response;
466
480
  }
467
481
  }
package/index.js CHANGED
@@ -64,7 +64,7 @@ function loadProjectWorkflows(dirPath) {
64
64
  try {
65
65
  const content = JSON.parse(readFileSync(workflowFile, "utf-8"));
66
66
  if (validateWorkflow(id, content)) {
67
- store.loadDefinition(id, content);
67
+ store.loadDefinition(id, content, "project");
68
68
  loaded.push(id);
69
69
  }
70
70
  } catch (e) {
@@ -90,7 +90,7 @@ function loadCatalogWorkflows(dirPath) {
90
90
  try {
91
91
  const content = JSON.parse(readFileSync(join(dirPath, file), "utf-8"));
92
92
  if (validateWorkflow(id, content)) {
93
- store.loadDefinition(id, content);
93
+ store.loadDefinition(id, content, "catalog");
94
94
  loaded.push(id);
95
95
  }
96
96
  } catch (e) {
@@ -157,10 +157,16 @@ server.setRequestHandler(ListToolsRequestSchema, async () => {
157
157
  },
158
158
  {
159
159
  name: "ListWorkflows",
160
- description: "List all available workflows. Returns data only, no dialog.",
160
+ description: "List available workflows. Filters by source when project workflows exist.",
161
161
  inputSchema: {
162
162
  type: "object",
163
- properties: {},
163
+ properties: {
164
+ source: {
165
+ type: "string",
166
+ enum: ["all", "project", "catalog"],
167
+ description: "Filter by source. Default: 'project' if project workflows exist, else 'all'.",
168
+ },
169
+ },
164
170
  },
165
171
  },
166
172
  {
@@ -228,9 +234,19 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
228
234
  }
229
235
 
230
236
  case "ListWorkflows": {
237
+ // Default to project-only if project workflows exist
238
+ const hasProject = store.hasProjectWorkflows();
239
+ const filter = args.source || (hasProject ? "project" : "all");
240
+ const workflows = store.listWorkflows(filter);
231
241
  return jsonResponse({
232
242
  schemaVersion: 2,
233
- workflows: store.listWorkflows(),
243
+ workflows,
244
+ filter,
245
+ hasProjectWorkflows: hasProject,
246
+ hint:
247
+ hasProject && filter === "project"
248
+ ? "Showing project workflows. Use source='all' to include catalog."
249
+ : undefined,
234
250
  });
235
251
  }
236
252
 
@@ -245,6 +261,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
245
261
  throw new Error(`Workflow '${args.workflowType}' not found`);
246
262
  }
247
263
 
264
+ const source = store.getSource(args.workflowType);
248
265
  const markdown = generateDiagram(wfDef, args.currentStep);
249
266
 
250
267
  // Save diagram to file
@@ -254,7 +271,7 @@ server.setRequestHandler(CallToolRequestSchema, async (request) => {
254
271
  const filePath = join(DIAGRAMS_PATH, `${args.workflowType}.md`);
255
272
  writeFileSync(filePath, markdown);
256
273
 
257
- return jsonResponse({ savedTo: filePath });
274
+ return jsonResponse({ savedTo: filePath, source });
258
275
  }
259
276
 
260
277
  case "CopyWorkflows": {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leclabs/agent-flow-navigator-mcp",
3
- "version": "1.0.0",
3
+ "version": "1.2.0",
4
4
  "description": "MCP server that navigates agents through DAG-based workflows",
5
5
  "license": "MIT",
6
6
  "author": "leclabs",
@@ -15,7 +15,7 @@
15
15
  "type": "module",
16
16
  "scripts": {
17
17
  "start": "node index.js",
18
- "test": "node --test engine.test.js diagram.test.js store.test.js dialog.test.js copier.test.js catalog.test.js"
18
+ "test": "node --test engine.test.js diagram.test.js store.test.js dialog.test.js copier.test.js catalog.test.js refactor-workflow.test.js build-review-workflow.test.js"
19
19
  },
20
20
  "keywords": [
21
21
  "mcp",
package/store.js CHANGED
@@ -29,16 +29,19 @@ export function validateWorkflow(id, content) {
29
29
  export class WorkflowStore {
30
30
  constructor() {
31
31
  this.workflows = new Map();
32
+ this.sources = new Map(); // Track source: "catalog" | "project"
32
33
  }
33
34
 
34
35
  /**
35
36
  * Load a workflow definition into the store
36
37
  * @param {string} id - Workflow identifier
37
38
  * @param {Object} workflow - Workflow definition
39
+ * @param {string} source - Source: "catalog" | "project"
38
40
  * @returns {string} The workflow id
39
41
  */
40
- loadDefinition(id, workflow) {
42
+ loadDefinition(id, workflow, source = "catalog") {
41
43
  this.workflows.set(id, workflow);
44
+ this.sources.set(id, source);
42
45
  return id;
43
46
  }
44
47
 
@@ -53,15 +56,43 @@ export class WorkflowStore {
53
56
 
54
57
  /**
55
58
  * List all loaded workflows with metadata
59
+ * @param {string} filter - Filter by source: "all" | "project" | "catalog"
56
60
  * @returns {Array} Array of workflow summaries
57
61
  */
58
- listWorkflows() {
59
- return Array.from(this.workflows.entries()).map(([id, wf]) => ({
60
- id,
61
- name: wf.name || id,
62
- description: wf.description || "",
63
- stepCount: Object.keys(wf.nodes || {}).length,
64
- }));
62
+ listWorkflows(filter = "all") {
63
+ const results = [];
64
+ for (const [id, wf] of this.workflows.entries()) {
65
+ const source = this.sources.get(id) || "catalog";
66
+ if (filter !== "all" && source !== filter) continue;
67
+ results.push({
68
+ id,
69
+ name: wf.name || id,
70
+ description: wf.description || "",
71
+ stepCount: Object.keys(wf.nodes || {}).length,
72
+ source,
73
+ });
74
+ }
75
+ return results;
76
+ }
77
+
78
+ /**
79
+ * Check if any project workflows exist
80
+ * @returns {boolean}
81
+ */
82
+ hasProjectWorkflows() {
83
+ for (const source of this.sources.values()) {
84
+ if (source === "project") return true;
85
+ }
86
+ return false;
87
+ }
88
+
89
+ /**
90
+ * Get the source of a workflow
91
+ * @param {string} id - Workflow identifier
92
+ * @returns {string|undefined} Source or undefined
93
+ */
94
+ getSource(id) {
95
+ return this.sources.get(id);
65
96
  }
66
97
 
67
98
  /**
@@ -78,6 +109,7 @@ export class WorkflowStore {
78
109
  */
79
110
  clear() {
80
111
  this.workflows.clear();
112
+ this.sources.clear();
81
113
  }
82
114
 
83
115
  /**