feat: Add interactive pre-flight checklists for ccw-loop and workflow-plan, including validation and task transformation steps

- Implemented `prep-loop.md` for ccw-loop, detailing source discovery, validation, task transformation, and auto-loop configuration.
- Created `prep-plan.md` for workflow planning, covering environment checks, task quality assessment, execution preferences, and final confirmation.
- Defined schemas and integration points for `prep-package.json` in both ccw-loop and workflow-plan skills, ensuring proper validation and task handling.
- Added error handling mechanisms for various scenarios during the preparation phases.
This commit is contained in:
catlog22
2026-02-09 15:02:38 +08:00
parent ef7382ecf5
commit c62d26183b
25 changed files with 1596 additions and 2896 deletions

View File

@@ -44,6 +44,17 @@ When `--yes` or `-y`: Auto-continue all phases (skip confirmations), use recomme
When `--with-commit`: Auto-commit after each task completion in Phase 4.
## Prep Package Integration
When `plan-prep-package.json` exists at `{projectRoot}/.workflow/.prep/plan-prep-package.json`, the skill consumes it with 6-point validation:
1. **Phase 1**: Use `task.structured` (GOAL/SCOPE/CONTEXT) for session creation, enrich planning-notes.md with source_refs and quality dimensions
2. **Phase 2**: Feed verified source_refs as supplementary docs for exploration agents
3. **Phase 3**: Auto-populate Phase 0 User Configuration (execution_method, preferred_cli_tool, supplementary_materials) — skip interactive questions
4. **Phase 4**: Apply `execution.with_commit` flag
Prep packages are generated by the interactive prompt `/prompts:prep-plan`. See [phases/00-prep-checklist.md](phases/00-prep-checklist.md) for schema and validation rules.
## Execution Flow
```

View File

@@ -0,0 +1,181 @@
# Prep Package Schema & Integration Spec
Schema definition for `plan-prep-package.json` and integration points with the workflow-plan-execute skill.
## File Location
```
{projectRoot}/.workflow/.prep/plan-prep-package.json
```
Generated by: `/prompts:prep-plan` (interactive prompt)
Consumed by: Phase 1 (Session Discovery) → feeds into Phase 2, 3, 4
## JSON Schema
```json
{
"version": "1.0.0",
"generated_at": "ISO8601",
"prep_status": "ready | needs_refinement | blocked",
"target_skill": "workflow-plan-execute",
"environment": {
"project_root": "/path/to/project",
"prerequisites": {
"required_passed": true,
"recommended_passed": true,
"warnings": ["string"]
},
"tech_stack": "string",
"test_framework": "string",
"has_project_tech": true,
"has_project_guidelines": true
},
"task": {
"original": "raw user input",
"structured": {
"goal": "GOAL string (objective + success criteria)",
"scope": "SCOPE string (boundaries)",
"context": "CONTEXT string (constraints + tech context)"
},
"quality_score": 8,
"dimensions": {
"objective": { "score": 2, "value": "..." },
"success_criteria": { "score": 2, "value": "..." },
"scope": { "score": 2, "value": "..." },
"constraints": { "score": 1, "value": "..." },
"context": { "score": 1, "value": "..." }
},
"source_refs": [
{
"path": "docs/prd.md",
"type": "local_file | url | auto_detected",
"status": "verified | linked | not_found",
"preview": "first ~20 lines (local_file only)"
}
]
},
"execution": {
"auto_yes": true,
"with_commit": true,
"execution_method": "agent | cli | hybrid",
"preferred_cli_tool": "codex | gemini | qwen | auto",
"supplementary_materials": {
"type": "none | paths | inline",
"content": []
}
}
}
```
## Validation Rules (6 checks)
Phase 1 对 plan-prep-package.json 执行 **6 项验证**,全部通过才加载:
| # | 检查项 | 条件 | 失败处理 |
|---|--------|------|----------|
| 1 | prep_status | `=== "ready"` | 跳过 prep |
| 2 | target_skill | `=== "workflow-plan-execute"` | 跳过 prep防错误 skill |
| 3 | project_root | 与当前 projectRoot 一致 | 跳过 prep防错误项目 |
| 4 | quality_score | `>= 6` | 跳过 prep任务质量不达标 |
| 5 | 时效性 | generated_at 在 24h 以内 | 跳过 prep可能过期 |
| 6 | 必需字段 | task.structured.goal, execution 全部存在 | 跳过 prep |
## Phase 1 Integration (Session Discovery)
After session creation, enrich planning-notes.md with prep data:
```javascript
const prepPath = `${projectRoot}/.workflow/.prep/plan-prep-package.json`
let prepPackage = null
if (fs.existsSync(prepPath)) {
const raw = JSON.parse(Read(prepPath))
const checks = validatePlanPrepPackage(raw, projectRoot)
if (checks.valid) {
prepPackage = raw
// Use structured task for session creation
structuredDescription = {
goal: prepPackage.task.structured.goal,
scope: prepPackage.task.structured.scope,
context: prepPackage.task.structured.context
}
console.log(`✓ Prep package loaded: score=${prepPackage.task.quality_score}/10`)
} else {
console.warn(`⚠ Prep package validation failed, using defaults`)
}
}
// After session created, enrich planning-notes.md:
if (prepPackage) {
// 1. Add source refs section
const sourceRefsSection = prepPackage.task.source_refs
?.filter(r => r.status === 'verified' || r.status === 'linked')
.map(r => `- **${r.type}**: ${r.path}`)
.join('\n') || 'None'
// 2. Add quality dimensions
const dimensionsSection = Object.entries(prepPackage.task.dimensions)
.map(([k, v]) => `- **${k}**: ${v.value} (score: ${v.score}/2)`)
.join('\n')
// Append to planning-notes.md under User Intent
Edit(planningNotesPath, {
old: `- **KEY_CONSTRAINTS**: ${userConstraints}`,
new: `- **KEY_CONSTRAINTS**: ${userConstraints}
### Requirement Sources (from prep)
${sourceRefsSection}
### Quality Dimensions (from prep)
${dimensionsSection}`
})
}
```
## Phase 3 Integration (Task Generation - Phase 0 User Config)
Prep package auto-populates Phase 0 user configuration:
```javascript
// In Phase 3, Phase 0 (User Configuration):
if (prepPackage) {
// Auto-answer all Phase 0 questions from prep
userConfig = {
supplementaryMaterials: prepPackage.execution.supplementary_materials,
executionMethod: prepPackage.execution.execution_method,
preferredCliTool: prepPackage.execution.preferred_cli_tool,
enableResume: true
}
console.log(`✓ Phase 0 auto-configured from prep: ${userConfig.executionMethod} (${userConfig.preferredCliTool})`)
// Skip interactive questions, proceed to Phase 1 (Context Prep)
}
```
## Phase 2 Integration (Context Gathering)
Source refs from prep feed into exploration context:
```javascript
// In Phase 2, Step 2 (spawn explore agents):
// Add source_refs as supplementary context for exploration
if (prepPackage?.task?.source_refs?.length > 0) {
const verifiedRefs = prepPackage.task.source_refs.filter(r => r.status === 'verified')
// Include verified local docs in exploration agent prompt
explorationAgentPrompt += `\n## SUPPLEMENTARY REQUIREMENT DOCUMENTS\n`
explorationAgentPrompt += verifiedRefs.map(r => `Read and analyze: ${r.path}`).join('\n')
}
```
## Phase 4 Integration (Execution)
Commit flag from prep:
```javascript
// In Phase 4:
const withCommit = prepPackage?.execution?.with_commit || $ARGUMENTS.includes('--with-commit')
```

View File

@@ -9,6 +9,79 @@ Discover existing sessions or start new workflow session with intelligent sessio
- Generate unique session ID (WFS-xxx format)
- Initialize session directory structure
## Step 0.0: Load Prep Package (if exists)
```javascript
// Load plan-prep-package.json (generated by /prompts:prep-plan)
let prepPackage = null
const prepPath = `${projectRoot}/.workflow/.prep/plan-prep-package.json`
if (fs.existsSync(prepPath)) {
const raw = JSON.parse(Read(prepPath))
const checks = validatePlanPrepPackage(raw, projectRoot)
if (checks.valid) {
prepPackage = raw
console.log(`✓ Prep package loaded: score=${prepPackage.task.quality_score}/10, exec=${prepPackage.execution.execution_method}`)
console.log(` Checks passed: ${checks.passed.join(', ')}`)
} else {
console.warn(`⚠ Prep package found but failed validation:`)
checks.failures.forEach(f => console.warn(`${f}`))
console.warn(` → Falling back to default behavior (prep-package ignored)`)
prepPackage = null
}
}
/**
* Validate plan-prep-package.json integrity before consumption.
*/
function validatePlanPrepPackage(prep, projectRoot) {
const passed = []
const failures = []
// Check 1: prep_status
if (prep.prep_status === 'ready') passed.push('status=ready')
else failures.push(`prep_status is "${prep.prep_status}", expected "ready"`)
// Check 2: target_skill
if (prep.target_skill === 'workflow-plan-execute') passed.push('target_skill match')
else failures.push(`target_skill is "${prep.target_skill}", expected "workflow-plan-execute"`)
// Check 3: project_root
if (prep.environment?.project_root === projectRoot) passed.push('project_root match')
else failures.push(`project_root mismatch: "${prep.environment?.project_root}" vs "${projectRoot}"`)
// Check 4: quality_score >= 6
if ((prep.task?.quality_score || 0) >= 6) passed.push(`quality=${prep.task.quality_score}/10`)
else failures.push(`quality_score ${prep.task?.quality_score || 0} < 6`)
// Check 5: generated_at within 24h
const hoursSince = (Date.now() - new Date(prep.generated_at).getTime()) / 3600000
if (hoursSince <= 24) passed.push(`age=${Math.round(hoursSince)}h`)
else failures.push(`prep-package is ${Math.round(hoursSince)}h old (max 24h)`)
// Check 6: required fields
const required = ['task.structured.goal', 'task.structured.scope', 'execution.execution_method']
const missing = required.filter(p => !p.split('.').reduce((o, k) => o?.[k], prep))
if (missing.length === 0) passed.push('fields complete')
else failures.push(`missing: ${missing.join(', ')}`)
return { valid: failures.length === 0, passed, failures }
}
// Build structured description from prep or raw input
let structuredDescription
if (prepPackage) {
structuredDescription = {
goal: prepPackage.task.structured.goal,
scope: prepPackage.task.structured.scope,
context: prepPackage.task.structured.context
}
} else {
structuredDescription = null // Will be parsed from user input later
}
```
## Step 0: Initialize Project State (First-time Only)
**Executed before all modes** - Ensures project-level state files exist by calling `workflow:init`.
@@ -73,23 +146,47 @@ CONTEXT: Existing user database schema, REST API endpoints
### Step 1.4: Initialize Planning Notes
Create `planning-notes.md` with N+1 context support:
Create `planning-notes.md` with N+1 context support, enriched with prep data:
```javascript
const planningNotesPath = `${projectRoot}/.workflow/active/${sessionId}/planning-notes.md`
const userGoal = structuredDescription.goal
const userConstraints = structuredDescription.context || "None specified"
const userGoal = structuredDescription?.goal || taskDescription
const userScope = structuredDescription?.scope || "Not specified"
const userConstraints = structuredDescription?.context || "None specified"
// Build source refs section from prep
const sourceRefsSection = (prepPackage?.task?.source_refs?.length > 0)
? prepPackage.task.source_refs
.filter(r => r.status === 'verified' || r.status === 'linked')
.map(r => `- **${r.type}**: ${r.path}`)
.join('\n')
: 'None'
// Build quality dimensions section from prep
const dimensionsSection = prepPackage?.task?.dimensions
? Object.entries(prepPackage.task.dimensions)
.map(([k, v]) => `- **${k}**: ${v.value} (${v.score}/2)`)
.join('\n')
: ''
Write(planningNotesPath, `# Planning Notes
**Session**: ${sessionId}
**Created**: ${new Date().toISOString()}
${prepPackage ? `**Prep Package**: plan-prep-package.json (score: ${prepPackage.task.quality_score}/10)` : ''}
## User Intent (Phase 1)
- **GOAL**: ${userGoal}
- **SCOPE**: ${userScope}
- **KEY_CONSTRAINTS**: ${userConstraints}
${sourceRefsSection !== 'None' ? `
### Requirement Sources (from prep)
${sourceRefsSection}
` : ''}${dimensionsSection ? `
### Quality Dimensions (from prep)
${dimensionsSection}
` : ''}
---
## Context Findings (Phase 2)

View File

@@ -127,6 +127,15 @@ const sessionFolder = `${projectRoot}/.workflow/active/${session_id}/.process`;
// 2.2 Launch Parallel Explore Agents (with conflict detection)
const explorationAgents = [];
// Load source_refs from prep-package for supplementary context
const prepPath = `${projectRoot}/.workflow/.prep/plan-prep-package.json`
const prepSourceRefs = fs.existsSync(prepPath)
? (JSON.parse(Read(prepPath))?.task?.source_refs || []).filter(r => r.status === 'verified')
: []
const sourceRefsDirective = prepSourceRefs.length > 0
? `\n## SUPPLEMENTARY REQUIREMENT DOCUMENTS (from prep)\nRead these before exploration:\n${prepSourceRefs.map((r, i) => `${i + 1}. Read: ${r.path} (${r.type})`).join('\n')}\nCross-reference findings against these source documents.\n`
: ''
// Spawn all agents in parallel
selectedAngles.forEach((angle, index) => {
const agentId = spawn_agent({
@@ -144,6 +153,7 @@ selectedAngles.forEach((angle, index) => {
Execute **${angle}** exploration for task planning context. Analyze codebase from this specific angle to discover relevant structure, patterns, and constraints.
**CONFLICT DETECTION**: Additionally detect conflict indicators including module overlaps, breaking changes, incompatible patterns, and scenario boundary ambiguities.
${sourceRefsDirective}
## Assigned Context
- **Exploration Angle**: ${angle}

View File

@@ -78,12 +78,17 @@ Phase 3: Integration (+1 Coordinator, Multi-Module Only)
```javascript
const autoYes = $ARGUMENTS.includes('--yes') || $ARGUMENTS.includes('-y')
if (autoYes) {
console.log(`[--yes] Using defaults: No materials, Agent executor, Codex CLI`)
// Check for prep-package auto-configuration (from /prompts:prep-plan)
const prepPath = `${projectRoot}/.workflow/.prep/plan-prep-package.json`
const prepExec = fs.existsSync(prepPath) ? JSON.parse(Read(prepPath))?.execution : null
if (autoYes || prepExec) {
const source = prepExec ? 'prep-package' : '--yes flag'
console.log(`[${source}] Using defaults: ${prepExec?.execution_method || 'agent'} executor, ${prepExec?.preferred_cli_tool || 'codex'} CLI`)
userConfig = {
supplementaryMaterials: { type: "none", content: [] },
executionMethod: "agent",
preferredCliTool: "codex",
supplementaryMaterials: prepExec?.supplementary_materials || { type: "none", content: [] },
executionMethod: prepExec?.execution_method || "agent",
preferredCliTool: prepExec?.preferred_cli_tool || "codex",
enableResume: true
}
// Skip to Phase 1