feat: add Feature Dev workflow and improve default workflow prompts (#481)

This commit is contained in:
Carlos Florêncio
2026-03-29 11:36:07 +01:00
committed by GitHub
parent 663919a52b
commit dfa4a3369f
6 changed files with 464 additions and 33 deletions
+21 -9
View File
@@ -20,24 +20,36 @@ steps:
allow_manual_move: true
prompt: |
[ARCHITECTURE PHASE]
Analyze and design the architecture for this task.
Analyze and design the architecture for this task. Do NOT write any code.
Before creating the design, ask the user clarifying questions if anything is unclear or ambiguous about the requirements. Use the ask_user_question_kandev tool to get answers before proceeding.
{{task_prompt}}
When including diagrams in your design (architecture, sequence, flowcharts, etc.), always use mermaid syntax in code blocks.
STEP 1: UNDERSTAND THE REQUIREMENTS
If anything is unclear or ambiguous, ask the user clarifying questions using the ask_user_question_kandev tool before proceeding.
STEP 2: EXPLORE THE CODEBASE
- Find similar features and understand how they are architected.
- Identify existing patterns, abstractions, and conventions.
- Map integration points, data flow, and system boundaries.
STEP 3: DESIGN THE ARCHITECTURE
Create a design that includes:
1. Component overview — what each component does and how they interact
2. Interfaces and contracts — how components communicate (APIs, events, shared types)
3. Data flow — how data moves through the system from input to output
4. File structure — which files will be created or modified
5. Trade-offs — alternative approaches considered and why the recommended one was chosen
6. Risks and open questions — what could go wrong, what needs further investigation
When including diagrams (architecture, sequence, flowcharts, etc.), always use mermaid syntax in code blocks.
IMPORTANT: Save your design using the create_task_plan_kandev MCP tool with the task_id provided in the session context.
After saving the plan, STOP and wait for user review. The user will review your design in the UI and may edit it.
Do not create any other files during this phase - only use the MCP tool to save the plan.
{{task_prompt}}
Do not create any other files during this phase — only use the MCP tool to save the plan.
events:
on_enter:
- type: enable_plan_mode
- type: auto_start_agent
on_turn_complete:
- type: disable_plan_mode
- type: move_to_next
- id: review
name: Review
@@ -0,0 +1,266 @@
id: feature-dev
name: Feature Dev
description: >-
Full development lifecycle: spec with user review, implementation with TDD,
automated code review, QA verification, draft PR, and CI fixup. Ideal for
features that need quality gates between phases.
steps:
- id: todo
name: Todo
position: 0
color: bg-neutral-400
allow_manual_move: true
- id: spec
name: Spec
position: 1
color: bg-purple-500
is_start_step: true
show_in_command_panel: true
allow_manual_move: true
prompt: |
[SPEC PHASE]
Analyze this task and create a detailed implementation plan. Do NOT write any code yet.
{{task_prompt}}
STEP 1: UNDERSTAND THE PROBLEM
- If anything is unclear or ambiguous, ask the user clarifying questions using the ask_user_question_kandev tool before proceeding.
- Identify: what problem is being solved, who benefits, what are the constraints.
STEP 2: EXPLORE THE CODEBASE
- Find similar features and understand how they are implemented.
- Identify the architecture and patterns in the relevant area.
- Map integration points, data flow, and extension points.
- Check if the repo has a decision log (e.g. docs/decisions/) and read relevant decisions.
STEP 3: DESIGN THE SOLUTION
- Propose 2-3 approaches with trade-offs and your recommendation.
- Map which files will be created or modified and what each is responsible for.
- When including diagrams (architecture, sequence, flowcharts), use mermaid syntax in code blocks.
IMPORTANT: Save your plan using the create_task_plan_kandev MCP tool with the task_id provided in the session context.
After saving the plan, STOP and wait for user review. The user will review your plan in the UI and may edit it.
Do not create any other files during this phase — only use the MCP tool to save the plan.
events:
on_enter:
- type: enable_plan_mode
- type: auto_start_agent
on_exit:
- type: disable_plan_mode
- id: work
name: Work
position: 2
color: bg-blue-500
show_in_command_panel: true
allow_manual_move: true
prompt: |
[WORK PHASE]
Implement the task following the approved plan.
{{task_prompt}}
STEP 1: RETRIEVE THE PLAN
Before starting, retrieve the task plan using get_task_plan_kandev with the task_id from the session context.
Review the plan carefully, including any edits the user may have made.
Acknowledge the plan and any user modifications before proceeding.
STEP 2: IMPLEMENT
Use a TDD strategy — for each behavior:
1. Write a failing test that asserts the expected behavior
2. Run the test — confirm it fails with the expected assertion error (not a compile error)
3. Write the minimum code to make it pass
4. Run the test — confirm it passes
5. Refactor while keeping tests green
6. Commit the change
Build incrementally — one behavior at a time, tests passing at every step.
Follow existing codebase conventions (naming, patterns, file organization).
You can update the plan during implementation using update_task_plan_kandev if needed.
STEP 3: STOP CONDITIONS
- If you hit a blocker (missing dependency, unclear requirement, test fails repeatedly): stop and ask the user.
- If a fix requires an architectural change (new DB table, new service layer, switching libraries): stop and ask.
- After 3 failed fix attempts on the same issue: stop, question the approach, ask the user.
events:
on_enter:
- type: auto_start_agent
- id: review
name: Review
position: 3
color: bg-yellow-500
show_in_command_panel: true
allow_manual_move: true
prompt: |
[REVIEW PHASE]
Review the changes made in the Work phase for quality, security, and correctness.
{{task_prompt}}
STEP 1: DETERMINE WHAT TO REVIEW
Determine the default branch (e.g. main, master) and diff against it:
- Run: git remote show origin | grep 'HEAD branch' to find the default branch name
- Run: git diff origin/<default_branch>...HEAD --name-only to get the list of changed files
Read each changed file in full — understand the surrounding code, not just the diff.
STEP 2: REVIEW THE CHANGES
Review across these layers (skip layers that don't apply):
Security (blockers if found):
- No secrets, tokens, or credentials in code
- Input validation at system boundaries
- No SQL injection, XSS, command injection, or path traversal
- Auth and authorization checks on new endpoints
Logic & correctness:
- Edge cases handled (empty input, nil/null, zero, max values)
- Error paths covered and not silently swallowed
- Race conditions in concurrent code
Performance:
- No N+1 queries (loop with individual DB calls)
- No memory leaks (unclosed connections, streams, listeners)
Code quality:
- No dead code, unused imports, or commented-out code
- No speculative code (unused flags, one-off abstractions with single call site)
- Deep nesting (>3 levels) — suggest early returns
STEP 3: FIX OR REPORT
- Fix directly any issues you can resolve confidently (dead code, unused imports, missing early returns).
- For issues needing the author's input, report with file:line, why it matters, and how to fix.
- Only report findings you're >=80% confident about.
Do NOT report issues on code that was not modified in this branch.
events:
on_enter:
- type: reset_agent_context
- type: auto_start_agent
- id: qa
name: QA
position: 4
color: bg-orange-500
show_in_command_panel: true
allow_manual_move: true
prompt: |
[QA PHASE]
Verify the feature works end-to-end. Your goal is to find bugs, not confirm it works.
{{task_prompt}}
STEP 1: UNDERSTAND WHAT WAS BUILT
Read the task description and recent commits to understand what the feature should do.
Retrieve the task plan using get_task_plan_kandev if available.
STEP 2: TRACE THE WIRING
Before testing behavior, verify the feature is actually connected:
- Exports are imported and used (not just defined)
- API routes have consumers
- Data flows end-to-end: input -> handler -> storage -> response -> display
STEP 3: TEST THE HAPPY PATH
Run the feature as intended. For backend changes, call the API. For frontend changes, trace the UI flow.
STEP 4: TRY TO BREAK IT
Systematically test:
- Boundary values: empty input, nil/null, zero, negative, max values, very long strings
- Error paths: what happens when dependencies fail?
- Concurrency: simultaneous requests to the same resource
- Authorization: can the feature be accessed without proper auth?
STEP 5: VERIFY TEST COVERAGE
Check that the implementation has tests covering the behaviors you verified.
If tests are missing for critical paths, write them.
STEP 6: REPORT
Summarize: what was verified working, what issues were found (with file:line and how to reproduce), and what test coverage is missing.
events:
on_enter:
- type: auto_start_agent
- id: pr
name: PR
position: 5
color: bg-indigo-500
show_in_command_panel: true
allow_manual_move: true
prompt: |
[PR PHASE]
Create a draft pull request for the changes.
{{task_prompt}}
STEP 1: PREPARE
- Run formatters and linters to ensure code is clean.
- Stage and commit any remaining changes.
- Push the branch to origin.
STEP 2: CHECK FOR PR TEMPLATE
Look for a pull request template in the repo:
- .github/pull_request_template.md
- .github/PULL_REQUEST_TEMPLATE.md
- docs/pull_request_template.md
If found, read it and follow its structure for the PR body.
STEP 3: CREATE DRAFT PR
Create the PR as a draft:
```bash
gh pr create --draft --title "<type>: <description>" --body "<body following template or default>"
```
- Title should follow Conventional Commits format if the repo uses it.
- If no PR template was found, the body should include: summary of what was built and why, validation steps, and a checklist.
STEP 4: REPORT
Return the PR URL.
events:
on_enter:
- type: auto_start_agent
- id: ci-fixup
name: CI Fixup
position: 6
color: bg-amber-500
show_in_command_panel: true
allow_manual_move: true
prompt: |
[CI FIXUP PHASE]
Wait for CI checks to complete and fix any failures.
{{task_prompt}}
STEP 1: FIND THE PR
Run gh pr list --head $(git branch --show-current) to find the PR number.
STEP 2: WAIT FOR CI
Poll CI checks until they all resolve:
```bash
gh pr checks <number>
```
- Poll every 30 seconds, cap at 10 minutes.
- Once done, note which checks passed and which failed.
STEP 3: FIX FAILURES
If any CI checks failed:
1. Identify the failed run from gh pr checks output.
2. Fetch failed logs: gh run view <run-id> --log-failed
3. Read the relevant source files at the failing lines.
4. Fix the issues (lint errors, test failures, type errors).
5. Commit and push the fix.
6. Go back to STEP 2 and verify the fix passes.
STEP 4: REPORT
When all checks pass, report the CI status and the PR URL.
events:
on_enter:
- type: auto_start_agent
- id: done
name: Done
position: 7
color: bg-green-500
allow_manual_move: true
@@ -0,0 +1,135 @@
package workflows
import (
"fmt"
"testing"
)
func TestLoadTemplates_AllValid(t *testing.T) {
templates, err := LoadTemplates()
if err != nil {
t.Fatalf("LoadTemplates() returned error: %v", err)
}
if len(templates) == 0 {
t.Fatal("LoadTemplates() returned no templates")
}
for _, tmpl := range templates {
if tmpl.ID == "" {
t.Error("template has empty ID")
}
if tmpl.Name == "" {
t.Errorf("template %q has empty name", tmpl.ID)
}
if len(tmpl.Steps) == 0 {
t.Errorf("template %q has no steps", tmpl.ID)
}
}
}
func TestLoadTemplates_EachHasStartStep(t *testing.T) {
templates, err := LoadTemplates()
if err != nil {
t.Fatalf("LoadTemplates() returned error: %v", err)
}
for _, tmpl := range templates {
startCount := 0
for _, step := range tmpl.Steps {
if step.IsStartStep {
startCount++
}
}
if startCount == 0 {
t.Errorf("template %q has no step with is_start_step: true", tmpl.ID)
}
if startCount > 1 {
t.Errorf("template %q has %d start steps (expected 1)", tmpl.ID, startCount)
}
}
}
func TestLoadTemplates_MoveToStepReferencesExist(t *testing.T) {
templates, err := LoadTemplates()
if err != nil {
t.Fatalf("LoadTemplates() returned error: %v", err)
}
for _, tmpl := range templates {
stepIDs := make(map[string]bool)
for _, step := range tmpl.Steps {
stepIDs[step.ID] = true
}
for _, step := range tmpl.Steps {
// Collect all move_to_step configs from all event types
var configs []map[string]interface{}
for _, a := range step.Events.OnTurnStart {
if a.Config != nil {
configs = append(configs, a.Config)
}
}
for _, a := range step.Events.OnTurnComplete {
if a.Config != nil {
configs = append(configs, a.Config)
}
}
for _, cfg := range configs {
stepID, ok := cfg["step_id"]
if !ok {
continue
}
ref := fmt.Sprintf("%v", stepID)
if !stepIDs[ref] {
t.Errorf("template %q, step %q: move_to_step references %q which does not exist",
tmpl.ID, step.ID, ref)
}
}
}
}
}
func TestLoadTemplates_StepPositionsUnique(t *testing.T) {
templates, err := LoadTemplates()
if err != nil {
t.Fatalf("LoadTemplates() returned error: %v", err)
}
for _, tmpl := range templates {
positions := make(map[int]string)
for _, step := range tmpl.Steps {
if existing, ok := positions[step.Position]; ok {
t.Errorf("template %q: steps %q and %q share position %d",
tmpl.ID, existing, step.ID, step.Position)
}
positions[step.Position] = step.ID
}
}
}
func TestLoadTemplates_ExpectedTemplateIDs(t *testing.T) {
templates, err := LoadTemplates()
if err != nil {
t.Fatalf("LoadTemplates() returned error: %v", err)
}
expected := map[string]bool{
"simple": false,
"standard": false,
"architecture": false,
"pr-review": false,
"feature-dev": false,
}
for _, tmpl := range templates {
if _, ok := expected[tmpl.ID]; ok {
expected[tmpl.ID] = true
}
}
for id, found := range expected {
if !found {
t.Errorf("expected template %q not found", id)
}
}
}
@@ -21,23 +21,31 @@ steps:
prompt: |
[PLANNING PHASE]
Analyze this task and create a detailed implementation plan.
Do NOT make any code changes yet - only analyze and plan.
Do NOT make any code changes yet — only analyze and plan.
Before creating the plan, ask the user clarifying questions if anything is unclear or ambiguous about the requirements. Use the ask_user_question_kandev tool to get answers before proceeding.
{{task_prompt}}
STEP 1: UNDERSTAND THE REQUIREMENTS
If anything is unclear or ambiguous, ask the user clarifying questions using the ask_user_question_kandev tool before proceeding.
STEP 2: EXPLORE THE CODEBASE
- Find similar features and understand how they are implemented.
- Identify the architecture and patterns in the relevant area.
- Map integration points and data flow.
STEP 3: CREATE THE PLAN
Create a plan that includes:
1. Understanding of the requirements
2. Files that need to be modified or created
2. Files that need to be modified or created, and what each is responsible for
3. Step-by-step implementation approach
4. Potential risks or considerations
5. Alternative approaches considered and why the recommended one was chosen
When including diagrams in your plan (architecture, sequence, flowcharts, etc.), always use mermaid syntax in code blocks.
When including diagrams (architecture, sequence, flowcharts, etc.), always use mermaid syntax in code blocks.
IMPORTANT: Save your plan using the create_task_plan_kandev MCP tool with the task_id provided in the session context.
After saving the plan, STOP and wait for user review. The user will review your plan in the UI and may edit it.
Do not create any other files during this phase - only use the MCP tool to save the plan.
{{task_prompt}}
Do not create any other files during this phase — only use the MCP tool to save the plan.
events:
on_enter:
- type: enable_plan_mode
@@ -51,19 +59,35 @@ steps:
allow_manual_move: true
prompt: |
[IMPLEMENTATION PHASE]
Before starting implementation, retrieve the task plan using get_task_plan_kandev with the task_id from the session context.
Implement the task following the approved plan.
{{task_prompt}}
STEP 1: RETRIEVE THE PLAN
Before starting, retrieve the task plan using get_task_plan_kandev with the task_id from the session context.
Review the plan carefully, including any edits the user may have made.
Acknowledge the plan and any user modifications before proceeding.
Then implement the task following the plan step-by-step.
STEP 2: IMPLEMENT
Use a TDD strategy — for each behavior:
1. Write a failing test that asserts the expected behavior
2. Run the test — confirm it fails with the expected assertion error
3. Write the minimum code to make it pass
4. Run the test — confirm it passes
5. Refactor while keeping tests green
6. Commit the change
Build incrementally — one behavior at a time, tests passing at every step.
Follow existing codebase conventions (naming, patterns, file organization).
You can update the plan during implementation using update_task_plan_kandev if needed.
{{task_prompt}}
STEP 3: STOP CONDITIONS
- If you hit a blocker (missing dependency, unclear requirement, test fails repeatedly): stop and ask the user.
- If a fix requires an architectural change (new DB table, new service layer, switching libraries): stop and ask.
- After 3 failed fix attempts on the same issue: stop, question the approach, ask the user.
events:
on_enter:
- type: auto_start_agent
on_turn_complete:
- type: move_to_next
- id: done
name: Done
+1 -10
View File
@@ -39,11 +39,7 @@ steps:
STEP 2: REVIEW THE CHANGES
Check if any code review skill is available (e.g. /code-review, /review, or similar).
If one exists, invoke it — it has project-specific rules.
Otherwise, use the fallback review below.
FALLBACK REVIEW (skip layers that don't apply):
Review across these layers (skip layers that don't apply):
Security (blockers if found):
- No secrets, tokens, or credentials in code
@@ -100,14 +96,9 @@ steps:
events:
on_enter:
- type: auto_start_agent
on_turn_complete:
- type: move_to_next
- id: done
name: Done
position: 2
color: bg-green-500
allow_manual_move: true
events:
on_turn_start:
- type: move_to_previous
@@ -138,11 +138,14 @@ export function CreateWorkflowDialog({
}: CreateWorkflowDialogProps) {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="sm:w-[900px] sm:max-w-none" data-testid="create-workflow-dialog">
<DialogContent
className="sm:w-[900px] sm:max-w-none max-h-[90vh] flex flex-col"
data-testid="create-workflow-dialog"
>
<DialogHeader>
<DialogTitle>Add Workflow</DialogTitle>
</DialogHeader>
<div className="space-y-6">
<div className="space-y-6 overflow-y-auto">
<div className="space-y-2">
<Label htmlFor="workflowName">Name</Label>
<Input