cc-devflow 2.4.6 → 4.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/CLAUDE.md +1065 -48
- package/.claude/agents/dev-implementer.md +195 -0
- package/.claude/commands/{flow-archive.md → flow/archive.md} +46 -11
- package/.claude/commands/flow/context.md +150 -0
- package/.claude/commands/flow/delta.md +245 -0
- package/.claude/commands/{flow-dev.md → flow/dev.md} +112 -11
- package/.claude/commands/flow/init.md +45 -0
- package/.claude/commands/flow/quality.md +159 -0
- package/.claude/commands/flow/spec.md +186 -0
- package/.claude/commands/flow/workspace.md +146 -0
- package/.claude/commands/{cancel-ralph.md → util/cancel-ralph.md} +1 -0
- package/.claude/config/quality-gates.yml +305 -0
- package/.claude/docs/guides/TEAM_MODE_GUIDE.md +313 -0
- package/.claude/docs/templates/DELTA_SPEC_TEMPLATE.md +91 -0
- package/.claude/docs/templates/DESIGN_DECISIONS_TEMPLATE.md +151 -0
- package/.claude/docs/templates/JOURNAL_TEMPLATE.md +75 -0
- package/.claude/docs/templates/_shared/CLAUDE.md +36 -0
- package/.claude/docs/templates/_shared/CONSTITUTION_CHECK.md +125 -0
- package/.claude/docs/templates/_shared/VALIDATION_CHECKLIST.md +187 -0
- package/.claude/docs/templates/_shared/YAML_FRONTMATTER.md +164 -0
- package/.claude/docs/templates/context/dev.jsonl.template +6 -0
- package/.claude/docs/templates/context/epic.jsonl.template +5 -0
- package/.claude/docs/templates/context/prd.jsonl.template +4 -0
- package/.claude/docs/templates/context/research.jsonl.template +4 -0
- package/.claude/docs/templates/context/review.jsonl.template +5 -0
- package/.claude/docs/templates/context/tech.jsonl.template +5 -0
- package/.claude/hooks/CLAUDE.md +342 -0
- package/.claude/hooks/inject-agent-context.ts +480 -0
- package/.claude/hooks/inject-skill-context.ts +359 -0
- package/.claude/hooks/ralph-loop.ts +931 -0
- package/.claude/hooks/task-completed-hook.ts +593 -0
- package/.claude/hooks/teammate-idle-hook.ts +690 -0
- package/.claude/hooks/types/team-types.d.ts +238 -0
- package/.claude/rules/devflow-conventions.md +82 -9
- package/.claude/scripts/archive-requirement.sh +44 -1
- package/.claude/scripts/common.sh +670 -3
- package/.claude/scripts/delta-parser.ts +527 -0
- package/.claude/scripts/detect-file-conflicts.sh +151 -0
- package/.claude/scripts/flow-context-add.sh +134 -0
- package/.claude/scripts/flow-context-init.sh +133 -0
- package/.claude/scripts/flow-context-validate.sh +144 -0
- package/.claude/scripts/flow-delta-apply.sh +297 -0
- package/.claude/scripts/flow-delta-archive.sh +71 -0
- package/.claude/scripts/flow-delta-create.sh +202 -0
- package/.claude/scripts/flow-delta-list.sh +142 -0
- package/.claude/scripts/flow-delta-status.sh +235 -0
- package/.claude/scripts/flow-quality-full.sh +184 -0
- package/.claude/scripts/flow-quality-quick.sh +64 -0
- package/.claude/scripts/flow-workspace-init.sh +117 -0
- package/.claude/scripts/flow-workspace-record.sh +164 -0
- package/.claude/scripts/flow-workspace-start.sh +88 -0
- package/.claude/scripts/get-workflow-status.sh +415 -0
- package/.claude/scripts/parse-task-dependencies.js +334 -0
- package/.claude/scripts/record-quality-error.sh +165 -0
- package/.claude/scripts/run-quality-gates.sh +242 -0
- package/.claude/scripts/team-dev-init.sh +319 -0
- package/.claude/scripts/team-state-recovery.sh +229 -0
- package/.claude/scripts/workflow-status.ts +433 -0
- package/.claude/settings.json +19 -0
- package/.claude/skills/cc-devflow-orchestrator/SKILL.md +85 -200
- package/.claude/skills/domain/using-git-worktrees/SKILL.md +252 -0
- package/.claude/skills/domain/using-git-worktrees/assets/SHELL_ALIASES.md +133 -0
- package/.claude/skills/domain/using-git-worktrees/context.jsonl +4 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh +218 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh +232 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-list.sh +130 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-status.sh +140 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-switch.sh +70 -0
- package/.claude/skills/skill-rules.json +72 -1
- package/.claude/skills/utility/journey-checker/SKILL.md +199 -0
- package/.claude/skills/utility/journey-checker/pressure-scenarios.md +164 -0
- package/.claude/skills/utility/skill-creator/LICENSE.txt +202 -0
- package/.claude/skills/utility/skill-creator/SKILL.md +356 -0
- package/.claude/skills/utility/skill-creator/references/output-patterns.md +82 -0
- package/.claude/skills/utility/skill-creator/references/workflows.md +28 -0
- package/.claude/skills/utility/skill-creator/scripts/init_skill.py +303 -0
- package/.claude/skills/utility/skill-creator/scripts/package_skill.py +110 -0
- package/.claude/skills/utility/skill-creator/scripts/quick_validate.py +95 -0
- package/.claude/skills/workflow/flow-dev/CLAUDE.md +78 -0
- package/.claude/skills/workflow/flow-dev/SKILL.md +96 -0
- package/.claude/skills/workflow/flow-dev/assets/IMPLEMENTATION_PLAN_TEMPLATE.md +71 -0
- package/.claude/skills/workflow/flow-dev/context.jsonl +8 -0
- package/.claude/skills/workflow/flow-dev/dev-implementer.jsonl +8 -0
- package/.claude/skills/workflow/flow-dev/scripts/entry-gate.sh +116 -0
- package/.claude/skills/workflow/flow-dev/scripts/exit-gate.sh +101 -0
- package/.claude/skills/workflow/flow-dev/scripts/task-orchestrator.sh +106 -0
- package/.claude/skills/workflow/flow-fix/SKILL.md +105 -0
- package/.claude/skills/workflow/flow-fix/context.jsonl +6 -0
- package/.claude/skills/workflow/flow-fix/references/bug-analyzer.md +381 -0
- package/.claude/skills/workflow/flow-init/SKILL.md +211 -0
- package/.claude/skills/workflow/flow-init/assets/BRAINSTORM_TEMPLATE.md +148 -0
- package/.claude/skills/workflow/flow-init/assets/INIT_FLOW_TEMPLATE.md +198 -0
- package/.claude/skills/workflow/flow-init/assets/RESEARCH_TEMPLATE.md +276 -0
- package/.claude/skills/workflow/flow-init/context.jsonl +5 -0
- package/.claude/skills/workflow/flow-init/references/flow-researcher.md +132 -0
- package/.claude/skills/workflow/flow-init/scripts/check-prerequisites.sh +232 -0
- package/.claude/skills/workflow/flow-init/scripts/consolidate-research.sh +182 -0
- package/.claude/skills/workflow/flow-init/scripts/create-requirement.sh +515 -0
- package/.claude/skills/workflow/flow-init/scripts/generate-research-tasks.sh +157 -0
- package/.claude/skills/workflow/flow-init/scripts/populate-research-tasks.sh +284 -0
- package/.claude/skills/workflow/flow-init/scripts/validate-research.sh +332 -0
- package/.claude/skills/workflow/flow-quality/SKILL.md +94 -0
- package/.claude/skills/workflow/flow-quality/context.jsonl +6 -0
- package/.claude/skills/workflow/flow-quality/references/code-quality-reviewer.md +205 -0
- package/.claude/skills/workflow/flow-quality/references/qa-tester.md +313 -0
- package/.claude/skills/workflow/flow-quality/references/security-reviewer.md +314 -0
- package/.claude/skills/workflow/flow-quality/references/spec-reviewer.md +221 -0
- package/.claude/skills/workflow/flow-release/SKILL.md +126 -0
- package/.claude/skills/workflow/flow-release/context.jsonl +7 -0
- package/.claude/skills/workflow/flow-release/references/release-manager.md +295 -0
- package/.claude/skills/workflow/flow-spec/CLAUDE.md +103 -0
- package/.claude/skills/workflow/flow-spec/SKILL.md +545 -0
- package/.claude/skills/workflow/flow-spec/context.jsonl +7 -0
- package/.claude/skills/workflow/flow-spec/scripts/entry-gate.sh +194 -0
- package/.claude/skills/workflow/flow-spec/scripts/exit-gate.sh +244 -0
- package/.claude/skills/workflow/flow-spec/scripts/parallel-orchestrator.sh +205 -0
- package/.claude/skills/workflow/flow-spec/scripts/team-communication.sh +353 -0
- package/.claude/skills/workflow/flow-spec/scripts/team-init.sh +195 -0
- package/.claude/skills/workflow/flow-spec/scripts/test-team-mode.sh +496 -0
- package/.claude/skills/workflow/flow-spec/team-config.json +165 -0
- package/.claude/skills/workflow.yaml +417 -0
- package/CHANGELOG.md +254 -0
- package/README.md +193 -33
- package/README.zh-CN.md +206 -46
- package/lib/compiler/CLAUDE.md +77 -46
- package/lib/compiler/__tests__/multi-module-emitters.test.js +508 -0
- package/lib/compiler/context-expander.js +179 -0
- package/lib/compiler/emitters/antigravity-emitter.js +195 -5
- package/lib/compiler/emitters/base-emitter.js +217 -2
- package/lib/compiler/emitters/codex-emitter.js +200 -4
- package/lib/compiler/emitters/cursor-emitter.js +307 -3
- package/lib/compiler/emitters/qwen-emitter.js +196 -4
- package/lib/compiler/index.js +197 -2
- package/lib/compiler/platforms.js +270 -21
- package/package.json +1 -1
- package/.claude/commands/flow-epic.md +0 -183
- package/.claude/commands/flow-init.md +0 -370
- package/.claude/commands/flow-prd.md +0 -144
- package/.claude/commands/flow-qa.md +0 -93
- package/.claude/commands/flow-review.md +0 -257
- package/.claude/commands/flow-tech.md +0 -142
- package/.claude/commands/flow-ui.md +0 -189
- package/.claude/skills/file-header-guardian/SKILL.md +0 -56
- package/.claude/skills/skill-developer/ADVANCED.md +0 -197
- package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +0 -306
- package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +0 -152
- package/.claude/skills/skill-developer/SKILL.md +0 -426
- package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +0 -315
- package/.claude/skills/skill-developer/TRIGGER_TYPES.md +0 -305
- package/.claude/skills/skill-developer/TROUBLESHOOTING.md +0 -514
- package/.claude/skills/writing-skills/SKILL.md +0 -655
- package/.claude/skills/writing-skills/anthropic-best-practices.md +0 -1150
- package/.claude/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/.claude/skills/writing-skills/graphviz-conventions.dot +0 -172
- package/.claude/skills/writing-skills/persuasion-principles.md +0 -187
- package/.claude/skills/writing-skills/render-graphs.js +0 -168
- package/.claude/skills/writing-skills/testing-skills-with-subagents.md +0 -384
- package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/affected-repos.txt +0 -1
- package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/affected-repos.txt +0 -1
- /package/.claude/commands/{core-architecture.md → core/architecture.md} +0 -0
- /package/.claude/commands/{core-guidelines.md → core/guidelines.md} +0 -0
- /package/.claude/commands/{core-roadmap.md → core/roadmap.md} +0 -0
- /package/.claude/commands/{core-style.md → core/style.md} +0 -0
- /package/.claude/commands/{flow-checklist.md → flow/checklist.md} +0 -0
- /package/.claude/commands/{flow-clarify.md → flow/clarify.md} +0 -0
- /package/.claude/commands/{flow-constitution.md → flow/constitution.md} +0 -0
- /package/.claude/commands/{flow-fix.md → flow/fix.md} +0 -0
- /package/.claude/commands/{flow-ideate.md → flow/ideate.md} +0 -0
- /package/.claude/commands/{flow-new.md → flow/new.md} +0 -0
- /package/.claude/commands/{flow-release.md → flow/release.md} +0 -0
- /package/.claude/commands/{flow-restart.md → flow/restart.md} +0 -0
- /package/.claude/commands/{flow-status.md → flow/status.md} +0 -0
- /package/.claude/commands/{flow-update.md → flow/update.md} +0 -0
- /package/.claude/commands/{flow-upgrade.md → flow/upgrade.md} +0 -0
- /package/.claude/commands/{flow-verify.md → flow/verify.md} +0 -0
- /package/.claude/commands/{code-review-high.md → util/code-review.md} +0 -0
- /package/.claude/commands/{git-commit.md → util/git-commit.md} +0 -0
- /package/.claude/commands/{problem-analyzer.md → util/problem-analyzer.md} +0 -0
- /package/.claude/skills/{flow-attention-refresh → domain/attention-refresh}/SKILL.md +0 -0
- /package/.claude/skills/{flow-brainstorming → domain/brainstorming}/SKILL.md +0 -0
- /package/.claude/skills/{flow-debugging → domain/debugging}/SKILL.md +0 -0
- /package/.claude/skills/{flow-finishing-branch → domain/finishing-branch}/SKILL.md +0 -0
- /package/.claude/skills/{flow-receiving-review → domain/receiving-review}/SKILL.md +0 -0
- /package/.claude/skills/{flow-tdd → domain/tdd}/SKILL.md +0 -0
- /package/.claude/skills/{verification-before-completion → domain/verification}/SKILL.md +0 -0
- /package/.claude/skills/{constitution-guardian → guardrail/constitution-guardian}/SKILL.md +0 -0
- /package/.claude/skills/{devflow-tdd-enforcer → guardrail/tdd-enforcer}/SKILL.md +0 -0
- /package/.claude/skills/{devflow-constitution-quick-ref → utility/constitution-quick-ref}/SKILL.md +0 -0
- /package/.claude/skills/{devflow-file-standards → utility/file-standards}/SKILL.md +0 -0
- /package/.claude/skills/{fractal-docs-generator → utility/fractal-docs}/SKILL.md +0 -0
- /package/.claude/skills/{npm-release → utility/npm-release}/SKILL.md +0 -0
|
@@ -0,0 +1,515 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Create new requirement structure for cc-devflow
|
|
4
|
+
#
|
|
5
|
+
# This script initializes a new requirement or BUG directory structure.
|
|
6
|
+
# Based on spec-kit's create-new-feature.sh design.
|
|
7
|
+
#
|
|
8
|
+
# Usage: ./create-requirement.sh [REQ_ID] [OPTIONS]
|
|
9
|
+
#
|
|
10
|
+
# ARGUMENTS:
|
|
11
|
+
# REQ_ID Requirement ID (REQ-XXX or BUG-XXX format)
|
|
12
|
+
# Optional if --interactive mode is used
|
|
13
|
+
#
|
|
14
|
+
# OPTIONS:
|
|
15
|
+
# --title TITLE Requirement title (docs; branch fallback)
|
|
16
|
+
# --branch-title TITLE Branch title used for git branch naming (optional)
|
|
17
|
+
# --description DESC Brief description (optional)
|
|
18
|
+
# --skip-git Skip git branch/worktree creation
|
|
19
|
+
# --branch-only Use traditional branch mode (no worktree)
|
|
20
|
+
# --worktree Use worktree mode (default)
|
|
21
|
+
# --interactive, -i Interactive mode (prompts for inputs)
|
|
22
|
+
# --json Output in JSON format
|
|
23
|
+
# --help, -h Show help message
|
|
24
|
+
#
|
|
25
|
+
# EXAMPLES:
|
|
26
|
+
# # Create requirement with worktree (default)
|
|
27
|
+
# ./create-requirement.sh REQ-123 --title "User authentication"
|
|
28
|
+
#
|
|
29
|
+
# # Create requirement with traditional branch
|
|
30
|
+
# ./create-requirement.sh REQ-123 --title "User authentication" --branch-only
|
|
31
|
+
#
|
|
32
|
+
# # Interactive mode
|
|
33
|
+
# ./create-requirement.sh --interactive
|
|
34
|
+
#
|
|
35
|
+
# # Create BUG structure
|
|
36
|
+
# ./create-requirement.sh BUG-456 --title "Fix login issue" --skip-git
|
|
37
|
+
#
|
|
38
|
+
# # JSON output for automation
|
|
39
|
+
# ./create-requirement.sh REQ-123 --title "API Gateway" --json
|
|
40
|
+
|
|
41
|
+
set -e
|
|
42
|
+
|
|
43
|
+
# Parse command line arguments
|
|
44
|
+
REQ_ID=""
|
|
45
|
+
TITLE=""
|
|
46
|
+
BRANCH_TITLE=""
|
|
47
|
+
DESCRIPTION=""
|
|
48
|
+
SKIP_GIT=false
|
|
49
|
+
BRANCH_ONLY=false
|
|
50
|
+
USE_WORKTREE=true
|
|
51
|
+
INTERACTIVE=false
|
|
52
|
+
JSON_MODE=false
|
|
53
|
+
AUTO_ID=false
|
|
54
|
+
|
|
55
|
+
while [[ $# -gt 0 ]]; do
|
|
56
|
+
case "$1" in
|
|
57
|
+
--title)
|
|
58
|
+
TITLE="$2"
|
|
59
|
+
shift 2
|
|
60
|
+
;;
|
|
61
|
+
--branch-title)
|
|
62
|
+
BRANCH_TITLE="$2"
|
|
63
|
+
shift 2
|
|
64
|
+
;;
|
|
65
|
+
--description)
|
|
66
|
+
DESCRIPTION="$2"
|
|
67
|
+
shift 2
|
|
68
|
+
;;
|
|
69
|
+
--skip-git)
|
|
70
|
+
SKIP_GIT=true
|
|
71
|
+
shift
|
|
72
|
+
;;
|
|
73
|
+
--branch-only)
|
|
74
|
+
BRANCH_ONLY=true
|
|
75
|
+
USE_WORKTREE=false
|
|
76
|
+
shift
|
|
77
|
+
;;
|
|
78
|
+
--worktree)
|
|
79
|
+
USE_WORKTREE=true
|
|
80
|
+
BRANCH_ONLY=false
|
|
81
|
+
shift
|
|
82
|
+
;;
|
|
83
|
+
--interactive|-i)
|
|
84
|
+
INTERACTIVE=true
|
|
85
|
+
shift
|
|
86
|
+
;;
|
|
87
|
+
--json)
|
|
88
|
+
JSON_MODE=true
|
|
89
|
+
shift
|
|
90
|
+
;;
|
|
91
|
+
--auto-id)
|
|
92
|
+
AUTO_ID=true
|
|
93
|
+
shift
|
|
94
|
+
;;
|
|
95
|
+
--help|-h)
|
|
96
|
+
cat << 'EOF'
|
|
97
|
+
Usage: create-requirement.sh [REQ_ID] [OPTIONS]
|
|
98
|
+
|
|
99
|
+
Create new requirement or BUG structure for cc-devflow.
|
|
100
|
+
|
|
101
|
+
ARGUMENTS:
|
|
102
|
+
REQ_ID Requirement ID (REQ-XXX or BUG-XXX format)
|
|
103
|
+
Optional if --interactive mode is used
|
|
104
|
+
|
|
105
|
+
OPTIONS:
|
|
106
|
+
--title TITLE Requirement title (docs; branch fallback)
|
|
107
|
+
--branch-title TITLE Branch title used for git branch naming (optional)
|
|
108
|
+
--description DESC Brief description (optional)
|
|
109
|
+
--skip-git Skip git branch/worktree creation
|
|
110
|
+
--branch-only Use traditional branch mode (no worktree)
|
|
111
|
+
--worktree Use worktree mode (default)
|
|
112
|
+
--interactive, -i Interactive mode (prompts for inputs)
|
|
113
|
+
--json Output results in JSON format
|
|
114
|
+
--auto-id Auto-select next available REQ-ID when missing or duplicated
|
|
115
|
+
--help, -h Show this help message
|
|
116
|
+
|
|
117
|
+
EXAMPLES:
|
|
118
|
+
# Create requirement with worktree (default)
|
|
119
|
+
./create-requirement.sh REQ-123 --title "User authentication"
|
|
120
|
+
|
|
121
|
+
# Create requirement with traditional branch
|
|
122
|
+
./create-requirement.sh REQ-123 --title "User authentication" --branch-only
|
|
123
|
+
|
|
124
|
+
# Interactive mode
|
|
125
|
+
./create-requirement.sh --interactive
|
|
126
|
+
|
|
127
|
+
# Create BUG structure
|
|
128
|
+
./create-requirement.sh BUG-456 --title "Fix login issue"
|
|
129
|
+
|
|
130
|
+
# JSON output
|
|
131
|
+
./create-requirement.sh REQ-123 --title "API Gateway" --json
|
|
132
|
+
|
|
133
|
+
STRUCTURE CREATED:
|
|
134
|
+
Requirements (REQ-XXX):
|
|
135
|
+
devflow/requirements/REQ-XXX/
|
|
136
|
+
├── research/ # External research materials
|
|
137
|
+
├── EXECUTION_LOG.md # Event log
|
|
138
|
+
└── orchestration_status.json # Status tracking
|
|
139
|
+
|
|
140
|
+
BUG Fixes (BUG-XXX):
|
|
141
|
+
devflow/bugs/BUG-XXX/
|
|
142
|
+
├── EXECUTION_LOG.md
|
|
143
|
+
└── status.json
|
|
144
|
+
|
|
145
|
+
GIT MODES:
|
|
146
|
+
Worktree (default):
|
|
147
|
+
- Creates: ../repo-name-REQ-XXX/
|
|
148
|
+
- Branch: feature/REQ-XXX-title
|
|
149
|
+
- Enables parallel development
|
|
150
|
+
|
|
151
|
+
Branch (--branch-only):
|
|
152
|
+
- Creates: feature/REQ-XXX-title branch
|
|
153
|
+
- Traditional single-workspace mode
|
|
154
|
+
|
|
155
|
+
EOF
|
|
156
|
+
exit 0
|
|
157
|
+
;;
|
|
158
|
+
-*)
|
|
159
|
+
echo "ERROR: Unknown option '$1'. Use --help for usage information." >&2
|
|
160
|
+
exit 1
|
|
161
|
+
;;
|
|
162
|
+
*)
|
|
163
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
164
|
+
REQ_ID="$1"
|
|
165
|
+
else
|
|
166
|
+
echo "ERROR: Too many arguments. Use --help for usage information." >&2
|
|
167
|
+
exit 1
|
|
168
|
+
fi
|
|
169
|
+
shift
|
|
170
|
+
;;
|
|
171
|
+
esac
|
|
172
|
+
done
|
|
173
|
+
|
|
174
|
+
# Source common functions
|
|
175
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
176
|
+
source "$SCRIPT_DIR/common.sh"
|
|
177
|
+
REPO_ROOT=$(get_repo_root)
|
|
178
|
+
|
|
179
|
+
# Interactive mode
|
|
180
|
+
if $INTERACTIVE; then
|
|
181
|
+
if ! $JSON_MODE; then
|
|
182
|
+
echo "=== Create New Requirement ==="
|
|
183
|
+
echo ""
|
|
184
|
+
fi
|
|
185
|
+
|
|
186
|
+
# Prompt for requirement ID if not provided
|
|
187
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
188
|
+
suggested_req_id=$(next_available_req_id "$REPO_ROOT")
|
|
189
|
+
read -p "Requirement ID (REQ-XXX or BUG-XXX) [${suggested_req_id}]: " input_req_id
|
|
190
|
+
input_req_id=$(echo "${input_req_id}" | tr '[:lower:]' '[:upper:]')
|
|
191
|
+
if [[ -z "$input_req_id" ]]; then
|
|
192
|
+
AUTO_ID=true
|
|
193
|
+
REQ_ID="$suggested_req_id"
|
|
194
|
+
else
|
|
195
|
+
REQ_ID="$input_req_id"
|
|
196
|
+
fi
|
|
197
|
+
fi
|
|
198
|
+
|
|
199
|
+
# Prompt for title if not provided
|
|
200
|
+
if [[ -z "$TITLE" ]]; then
|
|
201
|
+
read -p "Requirement Title: " TITLE
|
|
202
|
+
fi
|
|
203
|
+
|
|
204
|
+
# Prompt for description
|
|
205
|
+
if [[ -z "$DESCRIPTION" ]]; then
|
|
206
|
+
read -p "Brief Description (optional): " DESCRIPTION
|
|
207
|
+
fi
|
|
208
|
+
|
|
209
|
+
# Prompt for git branch creation
|
|
210
|
+
if ! $SKIP_GIT && has_git; then
|
|
211
|
+
read -p "Create git branch? (y/n): " create_branch
|
|
212
|
+
if [[ "$create_branch" != "y" && "$create_branch" != "Y" ]]; then
|
|
213
|
+
SKIP_GIT=true
|
|
214
|
+
fi
|
|
215
|
+
fi
|
|
216
|
+
fi
|
|
217
|
+
|
|
218
|
+
# Ensure requirement ID is set, auto-select when allowed
|
|
219
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
220
|
+
AUTO_ID=true
|
|
221
|
+
REQ_ID=$(next_available_req_id "$REPO_ROOT")
|
|
222
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
223
|
+
echo "ERROR: Unable to determine next requirement ID" >&2
|
|
224
|
+
exit 1
|
|
225
|
+
fi
|
|
226
|
+
if ! $JSON_MODE; then
|
|
227
|
+
echo "Auto-selected requirement ID: $REQ_ID" >&2
|
|
228
|
+
fi
|
|
229
|
+
fi
|
|
230
|
+
|
|
231
|
+
# Normalize requirement ID to uppercase
|
|
232
|
+
REQ_ID=$(echo "$REQ_ID" | tr '[:lower:]' '[:upper:]')
|
|
233
|
+
|
|
234
|
+
# Validate requirement ID format
|
|
235
|
+
validate_req_id "$REQ_ID" || exit 1
|
|
236
|
+
|
|
237
|
+
# Resolve conflicts when requirement ID already exists
|
|
238
|
+
if req_id_in_use "$REPO_ROOT" "$REQ_ID"; then
|
|
239
|
+
if $AUTO_ID; then
|
|
240
|
+
original_req_id="$REQ_ID"
|
|
241
|
+
while req_id_in_use "$REPO_ROOT" "$REQ_ID"; do
|
|
242
|
+
next_candidate=$(next_available_req_id "$REPO_ROOT")
|
|
243
|
+
if [[ "$next_candidate" == "$REQ_ID" ]]; then
|
|
244
|
+
next_candidate="REQ-$(date +%Y%m%d%H%M%S)"
|
|
245
|
+
fi
|
|
246
|
+
REQ_ID="$next_candidate"
|
|
247
|
+
done
|
|
248
|
+
if [[ "$REQ_ID" != "$original_req_id" ]] && ! $JSON_MODE; then
|
|
249
|
+
echo "Requirement ID in use; switched to $REQ_ID" >&2
|
|
250
|
+
fi
|
|
251
|
+
else
|
|
252
|
+
suggested_req_id=$(next_available_req_id "$REPO_ROOT")
|
|
253
|
+
conflict_dir=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
|
|
254
|
+
echo "ERROR: Requirement directory already exists: $conflict_dir" >&2
|
|
255
|
+
if [[ "$suggested_req_id" != "$REQ_ID" ]]; then
|
|
256
|
+
echo "Suggested next available ID: $suggested_req_id" >&2
|
|
257
|
+
fi
|
|
258
|
+
exit 1
|
|
259
|
+
fi
|
|
260
|
+
fi
|
|
261
|
+
|
|
262
|
+
# Get requirement type and directory
|
|
263
|
+
REQ_TYPE=$(get_req_type "$REQ_ID")
|
|
264
|
+
REQ_DIR=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
|
|
265
|
+
|
|
266
|
+
# Create directory structure
|
|
267
|
+
if ! $JSON_MODE; then
|
|
268
|
+
echo "Creating requirement structure at $REQ_DIR..." >&2
|
|
269
|
+
fi
|
|
270
|
+
|
|
271
|
+
# Create directories
|
|
272
|
+
mkdir -p "$REQ_DIR/research"
|
|
273
|
+
|
|
274
|
+
# Initialize EXECUTION_LOG.md
|
|
275
|
+
cat > "$REQ_DIR/EXECUTION_LOG.md" <<EOF
|
|
276
|
+
# Execution Log: $REQ_ID
|
|
277
|
+
|
|
278
|
+
**Title**: ${TITLE:-"To be defined"}
|
|
279
|
+
**Type**: $REQ_TYPE
|
|
280
|
+
**Created**: $(get_beijing_time_full)
|
|
281
|
+
|
|
282
|
+
EOF
|
|
283
|
+
|
|
284
|
+
if [[ -n "$DESCRIPTION" ]]; then
|
|
285
|
+
cat >> "$REQ_DIR/EXECUTION_LOG.md" <<EOF
|
|
286
|
+
## Description
|
|
287
|
+
$DESCRIPTION
|
|
288
|
+
|
|
289
|
+
EOF
|
|
290
|
+
fi
|
|
291
|
+
|
|
292
|
+
cat >> "$REQ_DIR/EXECUTION_LOG.md" <<'EOF'
|
|
293
|
+
## Events
|
|
294
|
+
|
|
295
|
+
EOF
|
|
296
|
+
|
|
297
|
+
# Initialize status file
|
|
298
|
+
if [[ "$REQ_TYPE" == "bug" ]]; then
|
|
299
|
+
# BUG-specific status file
|
|
300
|
+
cat > "$REQ_DIR/status.json" <<EOF
|
|
301
|
+
{
|
|
302
|
+
"bugId": "$REQ_ID",
|
|
303
|
+
"title": "${TITLE:-"To be defined"}",
|
|
304
|
+
"status": "initialized",
|
|
305
|
+
"phase": "analysis",
|
|
306
|
+
"severity": "unknown",
|
|
307
|
+
"createdAt": "$(get_beijing_time_iso)",
|
|
308
|
+
"updatedAt": "$(get_beijing_time_iso)"
|
|
309
|
+
}
|
|
310
|
+
EOF
|
|
311
|
+
else
|
|
312
|
+
# Requirement status file
|
|
313
|
+
cat > "$REQ_DIR/orchestration_status.json" <<EOF
|
|
314
|
+
{
|
|
315
|
+
"reqId": "$REQ_ID",
|
|
316
|
+
"title": "${TITLE:-"To be defined"}",
|
|
317
|
+
"status": "initialized",
|
|
318
|
+
"phase": "planning",
|
|
319
|
+
"createdAt": "$(get_beijing_time_iso)",
|
|
320
|
+
"updatedAt": "$(get_beijing_time_iso)"
|
|
321
|
+
}
|
|
322
|
+
EOF
|
|
323
|
+
fi
|
|
324
|
+
|
|
325
|
+
# Create README.md for the requirement
|
|
326
|
+
cat > "$REQ_DIR/README.md" <<EOF
|
|
327
|
+
# $REQ_ID: ${TITLE:-"To be defined"}
|
|
328
|
+
|
|
329
|
+
**Status**: Initialized
|
|
330
|
+
**Type**: $REQ_TYPE
|
|
331
|
+
**Created**: $(get_beijing_time_full)
|
|
332
|
+
|
|
333
|
+
EOF
|
|
334
|
+
|
|
335
|
+
if [[ -n "$DESCRIPTION" ]]; then
|
|
336
|
+
cat >> "$REQ_DIR/README.md" <<EOF
|
|
337
|
+
## Description
|
|
338
|
+
$DESCRIPTION
|
|
339
|
+
|
|
340
|
+
EOF
|
|
341
|
+
fi
|
|
342
|
+
|
|
343
|
+
cat >> "$REQ_DIR/README.md" <<'EOF'
|
|
344
|
+
## Documents
|
|
345
|
+
|
|
346
|
+
### Planning Phase
|
|
347
|
+
- [ ] PRD.md - Product Requirements Document
|
|
348
|
+
- [ ] EPIC.md - Epic Planning
|
|
349
|
+
- [ ] TASKS.md - Task Breakdown
|
|
350
|
+
|
|
351
|
+
### Execution Phase
|
|
352
|
+
- [ ] TEST_PLAN.md - Test Plan
|
|
353
|
+
- [ ] SECURITY_PLAN.md - Security Plan
|
|
354
|
+
- [ ] EXECUTION_LOG.md - Event Log
|
|
355
|
+
|
|
356
|
+
### Review Phase
|
|
357
|
+
- [ ] TEST_REPORT.md - Test Report
|
|
358
|
+
- [ ] SECURITY_REPORT.md - Security Report
|
|
359
|
+
- [ ] RELEASE_PLAN.md - Release Plan
|
|
360
|
+
|
|
361
|
+
## Research Materials
|
|
362
|
+
Place external research materials in `research/` directory:
|
|
363
|
+
- API documentation
|
|
364
|
+
- Design specifications
|
|
365
|
+
- Reference implementations
|
|
366
|
+
- Planning documents
|
|
367
|
+
|
|
368
|
+
## Workflow
|
|
369
|
+
1. **Planning**: Create PRD → Generate EPIC → Break down TASKS
|
|
370
|
+
2. **Development**: Implement tasks following TDD approach
|
|
371
|
+
3. **Quality**: Execute test plan and security review
|
|
372
|
+
4. **Release**: Create release plan and merge to main
|
|
373
|
+
|
|
374
|
+
EOF
|
|
375
|
+
|
|
376
|
+
# Log the creation event
|
|
377
|
+
log_event "$REQ_ID" "Requirement structure initialized"
|
|
378
|
+
|
|
379
|
+
if [[ -n "$TITLE" ]]; then
|
|
380
|
+
log_event "$REQ_ID" "Title: $TITLE"
|
|
381
|
+
fi
|
|
382
|
+
|
|
383
|
+
if [[ -n "$DESCRIPTION" ]]; then
|
|
384
|
+
log_event "$REQ_ID" "Description: $DESCRIPTION"
|
|
385
|
+
fi
|
|
386
|
+
|
|
387
|
+
# Create git branch/worktree if requested and available
|
|
388
|
+
GIT_BRANCH=""
|
|
389
|
+
WORKTREE_DIR=""
|
|
390
|
+
if ! $SKIP_GIT && has_git; then
|
|
391
|
+
# Generate branch name from title
|
|
392
|
+
if [[ -n "$BRANCH_TITLE" ]]; then
|
|
393
|
+
BRANCH_SUFFIX=$(slugify "$BRANCH_TITLE")
|
|
394
|
+
elif [[ -n "$TITLE" ]]; then
|
|
395
|
+
BRANCH_SUFFIX=$(slugify "$TITLE")
|
|
396
|
+
else
|
|
397
|
+
BRANCH_SUFFIX="new-requirement"
|
|
398
|
+
fi
|
|
399
|
+
if [[ -z "$BRANCH_SUFFIX" ]]; then
|
|
400
|
+
BRANCH_SUFFIX="new-requirement"
|
|
401
|
+
fi
|
|
402
|
+
|
|
403
|
+
# Determine branch prefix based on type
|
|
404
|
+
if [[ "$REQ_TYPE" == "bug" ]]; then
|
|
405
|
+
GIT_BRANCH="bugfix/$REQ_ID-$BRANCH_SUFFIX"
|
|
406
|
+
else
|
|
407
|
+
GIT_BRANCH="feature/$REQ_ID-$BRANCH_SUFFIX"
|
|
408
|
+
fi
|
|
409
|
+
|
|
410
|
+
# Check if branch already exists
|
|
411
|
+
if git rev-parse --verify "$GIT_BRANCH" >/dev/null 2>&1; then
|
|
412
|
+
if ! $JSON_MODE; then
|
|
413
|
+
echo "WARNING: Git branch already exists: $GIT_BRANCH" >&2
|
|
414
|
+
fi
|
|
415
|
+
# Branch exists - check if we should use worktree mode
|
|
416
|
+
if $USE_WORKTREE && ! $BRANCH_ONLY; then
|
|
417
|
+
REPO_NAME=$(basename "$REPO_ROOT")
|
|
418
|
+
WORKTREE_DIR="$(dirname "$REPO_ROOT")/${REPO_NAME}-${REQ_ID}"
|
|
419
|
+
if [[ -d "$WORKTREE_DIR" ]]; then
|
|
420
|
+
if ! $JSON_MODE; then
|
|
421
|
+
echo "Worktree already exists at: $WORKTREE_DIR" >&2
|
|
422
|
+
fi
|
|
423
|
+
else
|
|
424
|
+
# Create worktree with existing branch
|
|
425
|
+
git worktree add "$WORKTREE_DIR" "$GIT_BRANCH" >/dev/null 2>&1
|
|
426
|
+
log_event "$REQ_ID" "Created git worktree: $WORKTREE_DIR (existing branch: $GIT_BRANCH)"
|
|
427
|
+
if ! $JSON_MODE; then
|
|
428
|
+
echo "Created worktree at: $WORKTREE_DIR" >&2
|
|
429
|
+
fi
|
|
430
|
+
fi
|
|
431
|
+
fi
|
|
432
|
+
else
|
|
433
|
+
# Branch doesn't exist - create it
|
|
434
|
+
if $USE_WORKTREE && ! $BRANCH_ONLY; then
|
|
435
|
+
# Worktree mode (default)
|
|
436
|
+
REPO_NAME=$(basename "$REPO_ROOT")
|
|
437
|
+
WORKTREE_DIR="$(dirname "$REPO_ROOT")/${REPO_NAME}-${REQ_ID}"
|
|
438
|
+
|
|
439
|
+
if [[ -d "$WORKTREE_DIR" ]]; then
|
|
440
|
+
if ! $JSON_MODE; then
|
|
441
|
+
echo "WARNING: Worktree directory already exists: $WORKTREE_DIR" >&2
|
|
442
|
+
echo "Skipping worktree creation." >&2
|
|
443
|
+
fi
|
|
444
|
+
else
|
|
445
|
+
# Create worktree with new branch
|
|
446
|
+
git worktree add -b "$GIT_BRANCH" "$WORKTREE_DIR" >/dev/null 2>&1
|
|
447
|
+
log_event "$REQ_ID" "Created git worktree: $WORKTREE_DIR (branch: $GIT_BRANCH)"
|
|
448
|
+
|
|
449
|
+
if ! $JSON_MODE; then
|
|
450
|
+
echo "Created worktree at: $WORKTREE_DIR" >&2
|
|
451
|
+
echo "Branch: $GIT_BRANCH" >&2
|
|
452
|
+
fi
|
|
453
|
+
fi
|
|
454
|
+
else
|
|
455
|
+
# Traditional branch mode
|
|
456
|
+
git checkout -b "$GIT_BRANCH" >/dev/null 2>&1
|
|
457
|
+
log_event "$REQ_ID" "Created git branch: $GIT_BRANCH"
|
|
458
|
+
|
|
459
|
+
if ! $JSON_MODE; then
|
|
460
|
+
echo "Created and checked out branch: $GIT_BRANCH" >&2
|
|
461
|
+
fi
|
|
462
|
+
fi
|
|
463
|
+
fi
|
|
464
|
+
|
|
465
|
+
# Set environment variable for non-branch-based workflows
|
|
466
|
+
export DEVFLOW_REQ_ID="$REQ_ID"
|
|
467
|
+
fi
|
|
468
|
+
|
|
469
|
+
# Output results
|
|
470
|
+
if $JSON_MODE; then
|
|
471
|
+
printf '{"req_id":"%s","req_type":"%s","req_dir":"%s","title":"%s","git_branch":"%s","worktree_dir":"%s","mode":"%s","created_at":"%s"}\n' \
|
|
472
|
+
"$REQ_ID" \
|
|
473
|
+
"$REQ_TYPE" \
|
|
474
|
+
"$REQ_DIR" \
|
|
475
|
+
"${TITLE:-""}" \
|
|
476
|
+
"${GIT_BRANCH:-""}" \
|
|
477
|
+
"${WORKTREE_DIR:-""}" \
|
|
478
|
+
"$( $USE_WORKTREE && echo "worktree" || echo "branch" )" \
|
|
479
|
+
"$(get_beijing_time_iso)"
|
|
480
|
+
else
|
|
481
|
+
echo ""
|
|
482
|
+
echo "✅ Requirement structure created successfully!"
|
|
483
|
+
echo ""
|
|
484
|
+
echo "Requirement ID: $REQ_ID"
|
|
485
|
+
echo "Type: $REQ_TYPE"
|
|
486
|
+
echo "Directory: $REQ_DIR"
|
|
487
|
+
if [[ -n "$TITLE" ]]; then
|
|
488
|
+
echo "Title: $TITLE"
|
|
489
|
+
fi
|
|
490
|
+
if [[ -n "$GIT_BRANCH" ]]; then
|
|
491
|
+
echo "Git Branch: $GIT_BRANCH"
|
|
492
|
+
fi
|
|
493
|
+
if [[ -n "$WORKTREE_DIR" ]]; then
|
|
494
|
+
echo "Worktree: $WORKTREE_DIR"
|
|
495
|
+
echo "Mode: worktree (parallel development enabled)"
|
|
496
|
+
elif [[ -n "$GIT_BRANCH" ]]; then
|
|
497
|
+
echo "Mode: branch (traditional)"
|
|
498
|
+
fi
|
|
499
|
+
echo ""
|
|
500
|
+
echo "Next Steps:"
|
|
501
|
+
if [[ -n "$WORKTREE_DIR" && -d "$WORKTREE_DIR" ]]; then
|
|
502
|
+
echo " 1. cd $WORKTREE_DIR"
|
|
503
|
+
echo " 2. claude # Start new Claude Code session"
|
|
504
|
+
echo " 3. Continue with /flow-prd or /flow-spec"
|
|
505
|
+
elif [[ "$REQ_TYPE" == "bug" ]]; then
|
|
506
|
+
echo " 1. Run bug-analyzer agent to analyze the BUG"
|
|
507
|
+
echo " 2. Run /flow-fix to start BUG fix workflow"
|
|
508
|
+
echo " 3. Keep EXECUTION_LOG.md updated during fixes"
|
|
509
|
+
else
|
|
510
|
+
echo " 1. Add research materials to research/ (optional)"
|
|
511
|
+
echo " 2. Run prd-writer agent to create PRD.md"
|
|
512
|
+
echo " 3. Continue with planner and subsequent flow commands"
|
|
513
|
+
fi
|
|
514
|
+
echo ""
|
|
515
|
+
fi
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# shellcheck disable=SC2312
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
usage() {
|
|
7
|
+
cat <<'USAGE'
|
|
8
|
+
Usage: .claude/scripts/generate-research-tasks.sh <requirement-dir>
|
|
9
|
+
|
|
10
|
+
Scans the requirement directory for "NEEDS CLARIFICATION" markers and technology
|
|
11
|
+
choices, then writes research/tasks.json with structured tasks ready for agents.
|
|
12
|
+
USAGE
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
16
|
+
usage
|
|
17
|
+
exit 0
|
|
18
|
+
fi
|
|
19
|
+
|
|
20
|
+
if [[ $# -lt 1 ]]; then
|
|
21
|
+
echo "Error: requirement directory is required." >&2
|
|
22
|
+
usage
|
|
23
|
+
exit 1
|
|
24
|
+
fi
|
|
25
|
+
|
|
26
|
+
REQ_DIR="$1"
|
|
27
|
+
if [[ ! -d "$REQ_DIR" ]]; then
|
|
28
|
+
echo "Error: requirement directory '$REQ_DIR' does not exist." >&2
|
|
29
|
+
exit 1
|
|
30
|
+
fi
|
|
31
|
+
|
|
32
|
+
python3 - "$REQ_DIR" <<'PY'
|
|
33
|
+
from __future__ import annotations
|
|
34
|
+
|
|
35
|
+
import json
|
|
36
|
+
import os
|
|
37
|
+
import re
|
|
38
|
+
import sys
|
|
39
|
+
from datetime import datetime, timezone
|
|
40
|
+
from pathlib import Path
|
|
41
|
+
from typing import List, Dict
|
|
42
|
+
|
|
43
|
+
req_dir = Path(sys.argv[1]).resolve()
|
|
44
|
+
research_dir = req_dir / "research"
|
|
45
|
+
research_dir.mkdir(exist_ok=True, parents=True)
|
|
46
|
+
tasks_path = research_dir / "tasks.json"
|
|
47
|
+
|
|
48
|
+
def to_relative(p: Path) -> str:
|
|
49
|
+
try:
|
|
50
|
+
return str(p.relative_to(req_dir))
|
|
51
|
+
except ValueError:
|
|
52
|
+
return str(p)
|
|
53
|
+
|
|
54
|
+
def detect_feature_name() -> str:
|
|
55
|
+
readme = req_dir / "README.md"
|
|
56
|
+
if readme.exists():
|
|
57
|
+
for line in readme.read_text(encoding="utf-8").splitlines():
|
|
58
|
+
line = line.strip("# ").strip()
|
|
59
|
+
if line:
|
|
60
|
+
return line
|
|
61
|
+
return req_dir.name
|
|
62
|
+
|
|
63
|
+
def collect_unknowns() -> List[Dict[str, str]]:
|
|
64
|
+
pattern = re.compile(r"NEEDS CLARIFICATION", re.IGNORECASE)
|
|
65
|
+
unknowns = []
|
|
66
|
+
for path in req_dir.rglob("*.md"):
|
|
67
|
+
if path.name in {"research.md", "ui_design_strategy.md"}:
|
|
68
|
+
continue
|
|
69
|
+
rel = to_relative(path)
|
|
70
|
+
for idx, line in enumerate(path.read_text(encoding="utf-8", errors="ignore").splitlines(), start=1):
|
|
71
|
+
if pattern.search(line):
|
|
72
|
+
topic = line.split("NEEDS CLARIFICATION", 1)[0]
|
|
73
|
+
topic = topic.replace("-", " ").replace("*", " ").replace("•", " ")
|
|
74
|
+
topic = topic.split(":")[-1].strip()
|
|
75
|
+
if not topic:
|
|
76
|
+
topic = "unspecified topic"
|
|
77
|
+
payload = {
|
|
78
|
+
"topic": re.sub(r"\s+", " ", topic).strip(),
|
|
79
|
+
"source": f"{rel}:{idx}",
|
|
80
|
+
}
|
|
81
|
+
if payload not in unknowns:
|
|
82
|
+
unknowns.append(payload)
|
|
83
|
+
return unknowns
|
|
84
|
+
|
|
85
|
+
def collect_technologies() -> List[Dict[str, str]]:
|
|
86
|
+
tech_entries = []
|
|
87
|
+
bold_line = re.compile(r"^\s*[-*]\s*\*\*(?P<label>[^*]+)\*\*:\s*(?P<value>.+)$")
|
|
88
|
+
for filename in ("plan.md", "PLAN.md", "TECH_DESIGN.md"):
|
|
89
|
+
file_path = req_dir / filename
|
|
90
|
+
if not file_path.exists():
|
|
91
|
+
continue
|
|
92
|
+
for line in file_path.read_text(encoding="utf-8", errors="ignore").splitlines():
|
|
93
|
+
match = bold_line.match(line)
|
|
94
|
+
if match:
|
|
95
|
+
label = match.group("label").strip()
|
|
96
|
+
value = match.group("value").strip()
|
|
97
|
+
entry = {"label": label, "value": value}
|
|
98
|
+
if entry not in tech_entries:
|
|
99
|
+
tech_entries.append(entry)
|
|
100
|
+
return tech_entries
|
|
101
|
+
|
|
102
|
+
feature_name = detect_feature_name()
|
|
103
|
+
unknowns = collect_unknowns()
|
|
104
|
+
technologies = collect_technologies()
|
|
105
|
+
|
|
106
|
+
tasks: List[Dict[str, object]] = []
|
|
107
|
+
|
|
108
|
+
counter = 1
|
|
109
|
+
def next_id() -> str:
|
|
110
|
+
global counter
|
|
111
|
+
ident = f"R{counter:03}"
|
|
112
|
+
counter += 1
|
|
113
|
+
return ident
|
|
114
|
+
|
|
115
|
+
for unknown in unknowns:
|
|
116
|
+
tasks.append(
|
|
117
|
+
{
|
|
118
|
+
"id": next_id(),
|
|
119
|
+
"type": "clarification",
|
|
120
|
+
"prompt": f"Research {unknown['topic']} for {feature_name}",
|
|
121
|
+
"source": unknown["source"],
|
|
122
|
+
"status": "open",
|
|
123
|
+
"decision": "", # 新增: 空字段,等待填充
|
|
124
|
+
"rationale": "", # 新增: 空字段,等待填充
|
|
125
|
+
"alternatives": "", # 新增: 空字段,等待填充
|
|
126
|
+
}
|
|
127
|
+
)
|
|
128
|
+
|
|
129
|
+
for tech in technologies:
|
|
130
|
+
label = tech["label"]
|
|
131
|
+
value = tech["value"]
|
|
132
|
+
# strip trailing notes after parentheses to keep prompt concise
|
|
133
|
+
prompt_value = value.split(";")[0].strip()
|
|
134
|
+
tasks.append(
|
|
135
|
+
{
|
|
136
|
+
"id": next_id(),
|
|
137
|
+
"type": "best_practices",
|
|
138
|
+
"prompt": f"Find best practices for {prompt_value} in the context of {feature_name}",
|
|
139
|
+
"source": f"Tech-Choice:{label}",
|
|
140
|
+
"status": "open",
|
|
141
|
+
"decision": "", # 新增: 空字段,等待填充
|
|
142
|
+
"rationale": "", # 新增: 空字段,等待填充
|
|
143
|
+
"alternatives": "", # 新增: 空字段,等待填充
|
|
144
|
+
}
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
data = {
|
|
148
|
+
"feature": feature_name,
|
|
149
|
+
"generatedAt": datetime.now(timezone.utc).isoformat(),
|
|
150
|
+
"requirementDir": str(req_dir),
|
|
151
|
+
"tasks": tasks,
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
tasks_path.write_text(json.dumps(data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
155
|
+
|
|
156
|
+
print(f"Generated {len(tasks)} research task(s) for {feature_name} → {tasks_path}")
|
|
157
|
+
PY
|