feat: add MCP server for semantic code search with FastMCP integration

This commit is contained in:
catlog22
2026-03-17 23:03:20 +08:00
parent ef2c5a58e1
commit ad9d3f94e0
80 changed files with 3427 additions and 21329 deletions

View File

@@ -0,0 +1,93 @@
# Phase 1: Parse — Semantic Intent Extraction
## Objective
Extract structured semantic steps and context variables from the user's natural language workflow description.
## Workflow
### Step 1.1 — Read Input
Parse `$ARGUMENTS` as the workflow description. If empty or ambiguous, AskUserQuestion:
- "Describe the workflow you want to automate. Include: what steps to run, in what order, and what varies each time (inputs)."
### Step 1.2 — Extract Steps
Scan the description for sequential actions. Each action becomes a candidate node.
**Signal patterns** (not exhaustive — apply NL understanding):
| Signal | Candidate Node Type |
|--------|---------------------|
| "analyze", "review", "explore" | analysis step (cli --mode analysis) |
| "plan", "design", "spec" | planning step (skill: workflow-lite-plan / workflow-plan) |
| "implement", "build", "code", "fix", "refactor" | execution step (skill: workflow-execute) |
| "test", "validate", "verify" | testing step (skill: workflow-test-fix) |
| "brainstorm", "ideate" | brainstorm step (skill: brainstorm / brainstorm-with-file) |
| "review code", "code review" | review step (skill: review-cycle) |
| "save", "checkpoint", "pause" | explicit checkpoint node |
| "spawn agent", "delegate", "subagent" | agent node |
| "then", "next", "after", "finally" | sequential edge signal |
| "parallel", "simultaneously", "at the same time" | parallel edge signal |
### Step 1.3 — Extract Variables
Identify inputs that vary per run. These become `context_schema` entries.
**Variable detection**:
- Direct mentions: "the goal", "the target", "my task", "user-provided X"
- Parameterized slots: `{goal}`, `[feature]`, `<scope>` patterns in the description
- Implicit from task type: any "feature/bugfix/topic" is `goal`
For each variable: assign name, type (string|path|boolean), required flag, description.
### Step 1.4 — Detect Task Type
Use ccw-coordinator task detection logic to classify the overall workflow:
```
bugfix | feature | tdd | review | brainstorm | spec-driven | roadmap |
refactor | integration-test | greenfield | quick-task | custom
```
`custom` = user describes a non-standard combination.
### Step 1.5 — Complexity Assessment
Count nodes, detect parallel tracks, identify dependencies:
- `simple` = 1-3 nodes, linear
- `medium` = 4-7 nodes, at most 1 parallel track
- `complex` = 8+ nodes or multiple parallel tracks
### Step 1.6 — Write Output
Create session dir: `.workflow/templates/design-drafts/WFD-<slug>-<date>/`
Write `intent.json`:
```json
{
"session_id": "WFD-<slug>-<date>",
"raw_description": "<original user input>",
"task_type": "<detected type>",
"complexity": "simple|medium|complex",
"steps": [
{
"seq": 1,
"description": "<extracted step description>",
"type_hint": "analysis|planning|execution|testing|review|checkpoint|agent|cli",
"parallel_with": null,
"variables": ["goal"]
}
],
"variables": {
"goal": { "type": "string", "required": true, "description": "<inferred description>" }
},
"created_at": "<ISO timestamp>"
}
```
## Success Criteria
- `intent.json` exists with at least 1 step
- All referenced variables extracted to `variables` map
- task_type and complexity assigned

View File

@@ -0,0 +1,89 @@
# Phase 2: Resolve — Map Steps to Executor Nodes
## Objective
Map each intent step from `intent.json` into a concrete executor node with assigned type, executor, and arg template.
## Workflow
### Step 2.1 — Load Intent
Read `design-session/intent.json`. Load steps[], variables{}.
### Step 2.2 — Map Each Step to Executor
For each step, determine the executor node using the Node Catalog (`specs/node-catalog.md`).
**Resolution algorithm**:
1. Match `type_hint` to executor candidates in catalog
2. If multiple candidates, select by semantic fit to step description
3. If no catalog match, emit `cli` node with inferred `--rule` and `--mode`
**Node type assignment**:
| Step type_hint | Default executor type | Default executor |
|----------------|----------------------|------------------|
| `planning` | skill | `workflow-lite-plan` (simple/medium) or `workflow-plan` (complex) |
| `execution` | skill | `workflow-execute` |
| `testing` | skill | `workflow-test-fix` |
| `review` | skill | `review-cycle` |
| `brainstorm` | skill | `brainstorm` |
| `analysis` | cli | `ccw cli --tool gemini --mode analysis` |
| `spec` | skill | `spec-generator` |
| `tdd` | skill | `workflow-tdd-plan` |
| `refactor` | command | `workflow:refactor-cycle` |
| `integration-test` | command | `workflow:integration-test-cycle` |
| `agent` | agent | (infer subagent_type from description) |
| `checkpoint` | checkpoint | — |
### Step 2.3 — Build Arg Templates
For each node, build `args_template` by substituting variable references:
```
skill node: args_template = `{goal}` (or `--session {prev_session}`)
cli node: args_template = `PURPOSE: {goal}\nTASK: ...\nMODE: analysis\nCONTEXT: @**/*`
agent node: args_template = `{goal}\nContext: {prev_output}`
```
**Context injection rules**:
- Planning nodes that follow analysis: inject `--context {prev_output_path}`
- Execution nodes that follow planning: inject `--resume-session {prev_session_id}`
- Testing nodes that follow execution: inject `--session {prev_session_id}`
Use `{prev_session_id}` and `{prev_output_path}` as runtime-resolved references — the executor will substitute these from node state at run time.
### Step 2.4 — Assign Parallel Groups
For steps with `parallel_with` set:
- Assign same `parallel_group` string to both nodes
- Parallel nodes share no data dependency (each gets same input)
### Step 2.5 — Write Output
Write `design-session/nodes.json`:
```json
{
"session_id": "<WFD-id>",
"nodes": [
{
"id": "N-001",
"seq": 1,
"name": "<step description shortened>",
"type": "skill|cli|command|agent|checkpoint",
"executor": "<skill name | cli command | agent subagent_type>",
"args_template": "<template string with {variable} placeholders>",
"input_ports": ["<port>"],
"output_ports": ["<port>"],
"parallel_group": null,
"on_fail": "abort"
}
]
}
```
## Success Criteria
- Every intent step has a corresponding node in nodes.json
- Every node has a non-empty executor and args_template
- Parallel groups correctly assigned where step.parallel_with is set

View File

@@ -0,0 +1,104 @@
# Phase 3: Enrich — Inject Checkpoints + Build DAG
## Objective
Build the directed acyclic graph (DAG) with proper edges, auto-inject checkpoint nodes at phase boundaries, and finalize the context_schema.
## Workflow
### Step 3.1 — Load Nodes
Read `design-session/nodes.json`. Get nodes[] list.
### Step 3.2 — Build Sequential Edges
Start with a linear chain: N-001 → N-002 → N-003 → ...
For nodes with the same `parallel_group`:
- Remove edges between them
- Add fan-out from the last non-parallel node to all group members
- Add fan-in from all group members to the next non-parallel node
### Step 3.3 — Auto-Inject Checkpoint Nodes
Scan the edge list and inject a `checkpoint` node between edges that cross a phase boundary.
**Phase boundary detection rules** (inject checkpoint if ANY rule triggers):
| Rule | Condition |
|------|-----------|
| **Artifact boundary** | Source node has output_ports containing `plan`, `spec`, `analysis`, `review-findings` |
| **Execution gate** | Target node type is `skill` with executor containing `execute` |
| **Agent spawn** | Target node type is `agent` |
| **Long-running** | Target node executor is `workflow-plan`, `spec-generator`, `collaborative-plan-with-file` |
| **User-defined** | Intent step had `type_hint: checkpoint` |
| **Post-testing** | Source node executor contains `test-fix` or `integration-test` |
**Checkpoint node template**:
```json
{
"id": "CP-<seq>",
"name": "Checkpoint: <description>",
"type": "checkpoint",
"description": "<what was just completed>",
"auto_continue": true,
"save_fields": ["session_id", "artifacts", "output_path"]
}
```
Set `auto_continue: false` for checkpoints that:
- Precede a user-facing deliverable (spec, plan, review report)
- Are explicitly requested by the user ("pause and show me")
### Step 3.4 — Insert Checkpoint Edges
For each injected checkpoint CP-X between edge (A → B):
- Remove edge A → B
- Add edges: A → CP-X, CP-X → B
### Step 3.5 — Finalize context_schema
Aggregate all `{variable}` references found in nodes' args_template strings.
For each unique variable name found:
- Look up from `intent.json#variables` if already defined
- Otherwise infer: type=string, required=true, description="<variable name>"
Produce final `context_schema{}` map.
### Step 3.6 — Validate DAG
Check:
- No cycles (topological sort must succeed)
- No orphan nodes (every node reachable from start)
- Every non-start node has at least one incoming edge
- Every non-terminal node has at least one outgoing edge
On cycle detection: report error, ask user to resolve.
### Step 3.7 — Write Output
Write `design-session/dag.json`:
```json
{
"session_id": "<WFD-id>",
"nodes": [ /* all nodes including injected checkpoints */ ],
"edges": [
{ "from": "N-001", "to": "CP-01" },
{ "from": "CP-01", "to": "N-002" }
],
"checkpoints": ["CP-01", "CP-02"],
"parallel_groups": { "<group-name>": ["N-003", "N-004"] },
"context_schema": {
"goal": { "type": "string", "required": true, "description": "..." }
},
"topological_order": ["N-001", "CP-01", "N-002"]
}
```
## Success Criteria
- dag.json exists and is valid (no cycles)
- At least one checkpoint exists (or user explicitly opted out)
- context_schema contains all variables referenced in args_templates
- topological_order covers all nodes

View File

@@ -0,0 +1,97 @@
# Phase 4: Confirm — Visualize + User Approval
## Objective
Render the pipeline as an ASCII diagram, present to user for confirmation and optional edits.
## Workflow
### Step 4.1 — Render Pipeline
Load `design-session/dag.json`. Render in topological order:
```
Pipeline: <template-name>
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
N-001 [skill] workflow-lite-plan "{goal}"
|
CP-01 [checkpoint] After Plan auto-continue
|
N-002 [skill] workflow-execute --resume {N-001.session_id}
|
CP-02 [checkpoint] Before Review pause-for-user
|
N-003 [skill] review-cycle --session {N-002.session_id}
|
N-004 [skill] workflow-test-fix --session {N-002.session_id}
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Variables (required): goal
Checkpoints: 2 (1 auto-continue, 1 pause-for-user)
Nodes: 4 work + 2 checkpoints
```
For parallel groups, show fan-out/fan-in:
```
N-003a [skill] review-cycle ─┐
├─ N-004 [skill] workflow-test-fix
N-003b [cli] gemini analysis ─┘
```
### Step 4.2 — Ask User
```
AskUserQuestion({
questions: [{
question: "Review the workflow pipeline above.",
header: "Confirm Pipeline",
options: [
{ label: "Confirm & Save", description: "Save as reusable template" },
{ label: "Edit a node", description: "Modify executor or args of a specific node" },
{ label: "Add a node", description: "Insert a new step at a position" },
{ label: "Remove a node", description: "Delete a step from the pipeline" },
{ label: "Rename template", description: "Change the template name" },
{ label: "Re-run checkpoint injection", description: "Reset and re-inject checkpoints" },
{ label: "Cancel", description: "Discard and exit" }
]
}]
})
```
### Step 4.3 — Handle Edit Actions
**Edit a node**:
- AskUserQuestion: "Which node ID to edit?" → show fields → apply change
- Re-render pipeline and re-ask
**Add a node**:
- AskUserQuestion: "Insert after which node ID?" + "Describe the new step"
- Re-run Phase 2 (resolve) for the new step description
- Insert new node + update edges
- Re-run Phase 3 (enrich) for checkpoint injection
- Re-render and re-ask
**Remove a node**:
- AskUserQuestion: "Which node ID to remove?"
- If node is a checkpoint: also remove it, re-wire edges
- If node is a work node: re-wire edges, re-run checkpoint injection
- Re-render and re-ask
**Rename template**:
- AskUserQuestion: "New template name?"
- Update slug for template_id
### Step 4.4 — Finalize
On "Confirm & Save":
- Freeze dag.json (mark as confirmed)
- Proceed to Phase 5
On "Cancel":
- Save draft to `design-session/dag-draft.json`
- Output: "Draft saved. Resume with: Skill(skill='wf-composer', args='--resume <session-id>')"
- Exit
## Success Criteria
- User selected "Confirm & Save"
- dag.json frozen with all user edits applied

View File

@@ -0,0 +1,107 @@
# Phase 5: Persist — Assemble + Save Template
## Objective
Assemble the final workflow template JSON from design session data, write to template library, output usage instructions.
## Workflow
### Step 5.1 — Load Design Session
Read:
- `design-session/intent.json` → template metadata
- `design-session/dag.json` → nodes, edges, checkpoints, context_schema
### Step 5.2 — Determine Template Name + Path
**Name**: Use user's confirmed name from Phase 4. If not set, derive from intent.task_type + first 3 meaningful words of raw_description.
**Slug**: kebab-case from name (e.g. "Feature TDD with Review" → "feature-tdd-with-review")
**Path**: `.workflow/templates/<slug>.json`
**template_id**: `wft-<slug>-<YYYYMMDD>`
Check for existing file:
- If exists and different content: append `-v2`, `-v3`, etc.
- If exists and identical: skip write, output "Template already exists"
### Step 5.3 — Assemble Template JSON
See `specs/template-schema.md` for full schema. Assemble:
```json
{
"template_id": "wft-<slug>-<date>",
"name": "<human name>",
"description": "<raw_description truncated to 120 chars>",
"version": "1.0",
"created_at": "<ISO timestamp>",
"source_session": "<WFD-id>",
"tags": ["<task_type>", "<complexity>"],
"context_schema": { /* from dag.json */ },
"nodes": [ /* from dag.json, full node objects */ ],
"edges": [ /* from dag.json */ ],
"checkpoints": [ /* checkpoint node IDs */ ],
"atomic_groups": [ /* from intent.json parallel groups */ ],
"execution_mode": "serial",
"metadata": {
"node_count": <n>,
"checkpoint_count": <n>,
"estimated_duration": "<rough estimate based on node types>"
}
}
```
### Step 5.4 — Write Template
Write assembled JSON to `.workflow/templates/<slug>.json`.
Ensure `.workflow/templates/` directory exists (create if not).
### Step 5.5 — Update Template Index
Read/create `.workflow/templates/index.json`:
```json
{
"templates": [
{
"template_id": "wft-<slug>-<date>",
"name": "<name>",
"path": ".workflow/templates/<slug>.json",
"tags": ["<task_type>"],
"created_at": "<ISO>",
"node_count": <n>
}
]
}
```
Append or update entry for this template. Write back.
### Step 5.6 — Output Summary
```
Template saved: .workflow/templates/<slug>.json
ID: wft-<slug>-<date>
Nodes: <n> work nodes + <n> checkpoints
Variables: <comma-separated required vars>
To execute:
Skill(skill="wf-player", args="<slug> --context goal='<your goal>'")
To edit later:
Skill(skill="wf-composer", args="--edit .workflow/templates/<slug>.json")
To list all templates:
Skill(skill="wf-player", args="--list")
```
### Step 5.7 — Clean Up Draft
Delete `design-session/` directory (or move to `.workflow/templates/design-drafts/archive/`).
## Success Criteria
- `.workflow/templates/<slug>.json` exists and is valid JSON
- `index.json` updated with new entry
- Console shows template path + usage command