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.
Files changed (191) hide show
  1. package/.claude/CLAUDE.md +1065 -48
  2. package/.claude/agents/dev-implementer.md +195 -0
  3. package/.claude/commands/{flow-archive.md → flow/archive.md} +46 -11
  4. package/.claude/commands/flow/context.md +150 -0
  5. package/.claude/commands/flow/delta.md +245 -0
  6. package/.claude/commands/{flow-dev.md → flow/dev.md} +112 -11
  7. package/.claude/commands/flow/init.md +45 -0
  8. package/.claude/commands/flow/quality.md +159 -0
  9. package/.claude/commands/flow/spec.md +186 -0
  10. package/.claude/commands/flow/workspace.md +146 -0
  11. package/.claude/commands/{cancel-ralph.md → util/cancel-ralph.md} +1 -0
  12. package/.claude/config/quality-gates.yml +305 -0
  13. package/.claude/docs/guides/TEAM_MODE_GUIDE.md +313 -0
  14. package/.claude/docs/templates/DELTA_SPEC_TEMPLATE.md +91 -0
  15. package/.claude/docs/templates/DESIGN_DECISIONS_TEMPLATE.md +151 -0
  16. package/.claude/docs/templates/JOURNAL_TEMPLATE.md +75 -0
  17. package/.claude/docs/templates/_shared/CLAUDE.md +36 -0
  18. package/.claude/docs/templates/_shared/CONSTITUTION_CHECK.md +125 -0
  19. package/.claude/docs/templates/_shared/VALIDATION_CHECKLIST.md +187 -0
  20. package/.claude/docs/templates/_shared/YAML_FRONTMATTER.md +164 -0
  21. package/.claude/docs/templates/context/dev.jsonl.template +6 -0
  22. package/.claude/docs/templates/context/epic.jsonl.template +5 -0
  23. package/.claude/docs/templates/context/prd.jsonl.template +4 -0
  24. package/.claude/docs/templates/context/research.jsonl.template +4 -0
  25. package/.claude/docs/templates/context/review.jsonl.template +5 -0
  26. package/.claude/docs/templates/context/tech.jsonl.template +5 -0
  27. package/.claude/hooks/CLAUDE.md +342 -0
  28. package/.claude/hooks/inject-agent-context.ts +480 -0
  29. package/.claude/hooks/inject-skill-context.ts +359 -0
  30. package/.claude/hooks/ralph-loop.ts +931 -0
  31. package/.claude/hooks/task-completed-hook.ts +593 -0
  32. package/.claude/hooks/teammate-idle-hook.ts +690 -0
  33. package/.claude/hooks/types/team-types.d.ts +238 -0
  34. package/.claude/rules/devflow-conventions.md +82 -9
  35. package/.claude/scripts/archive-requirement.sh +44 -1
  36. package/.claude/scripts/common.sh +670 -3
  37. package/.claude/scripts/delta-parser.ts +527 -0
  38. package/.claude/scripts/detect-file-conflicts.sh +151 -0
  39. package/.claude/scripts/flow-context-add.sh +134 -0
  40. package/.claude/scripts/flow-context-init.sh +133 -0
  41. package/.claude/scripts/flow-context-validate.sh +144 -0
  42. package/.claude/scripts/flow-delta-apply.sh +297 -0
  43. package/.claude/scripts/flow-delta-archive.sh +71 -0
  44. package/.claude/scripts/flow-delta-create.sh +202 -0
  45. package/.claude/scripts/flow-delta-list.sh +142 -0
  46. package/.claude/scripts/flow-delta-status.sh +235 -0
  47. package/.claude/scripts/flow-quality-full.sh +184 -0
  48. package/.claude/scripts/flow-quality-quick.sh +64 -0
  49. package/.claude/scripts/flow-workspace-init.sh +117 -0
  50. package/.claude/scripts/flow-workspace-record.sh +164 -0
  51. package/.claude/scripts/flow-workspace-start.sh +88 -0
  52. package/.claude/scripts/get-workflow-status.sh +415 -0
  53. package/.claude/scripts/parse-task-dependencies.js +334 -0
  54. package/.claude/scripts/record-quality-error.sh +165 -0
  55. package/.claude/scripts/run-quality-gates.sh +242 -0
  56. package/.claude/scripts/team-dev-init.sh +319 -0
  57. package/.claude/scripts/team-state-recovery.sh +229 -0
  58. package/.claude/scripts/workflow-status.ts +433 -0
  59. package/.claude/settings.json +19 -0
  60. package/.claude/skills/cc-devflow-orchestrator/SKILL.md +85 -200
  61. package/.claude/skills/domain/using-git-worktrees/SKILL.md +252 -0
  62. package/.claude/skills/domain/using-git-worktrees/assets/SHELL_ALIASES.md +133 -0
  63. package/.claude/skills/domain/using-git-worktrees/context.jsonl +4 -0
  64. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh +218 -0
  65. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh +232 -0
  66. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-list.sh +130 -0
  67. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-status.sh +140 -0
  68. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-switch.sh +70 -0
  69. package/.claude/skills/skill-rules.json +72 -1
  70. package/.claude/skills/utility/journey-checker/SKILL.md +199 -0
  71. package/.claude/skills/utility/journey-checker/pressure-scenarios.md +164 -0
  72. package/.claude/skills/utility/skill-creator/LICENSE.txt +202 -0
  73. package/.claude/skills/utility/skill-creator/SKILL.md +356 -0
  74. package/.claude/skills/utility/skill-creator/references/output-patterns.md +82 -0
  75. package/.claude/skills/utility/skill-creator/references/workflows.md +28 -0
  76. package/.claude/skills/utility/skill-creator/scripts/init_skill.py +303 -0
  77. package/.claude/skills/utility/skill-creator/scripts/package_skill.py +110 -0
  78. package/.claude/skills/utility/skill-creator/scripts/quick_validate.py +95 -0
  79. package/.claude/skills/workflow/flow-dev/CLAUDE.md +78 -0
  80. package/.claude/skills/workflow/flow-dev/SKILL.md +96 -0
  81. package/.claude/skills/workflow/flow-dev/assets/IMPLEMENTATION_PLAN_TEMPLATE.md +71 -0
  82. package/.claude/skills/workflow/flow-dev/context.jsonl +8 -0
  83. package/.claude/skills/workflow/flow-dev/dev-implementer.jsonl +8 -0
  84. package/.claude/skills/workflow/flow-dev/scripts/entry-gate.sh +116 -0
  85. package/.claude/skills/workflow/flow-dev/scripts/exit-gate.sh +101 -0
  86. package/.claude/skills/workflow/flow-dev/scripts/task-orchestrator.sh +106 -0
  87. package/.claude/skills/workflow/flow-fix/SKILL.md +105 -0
  88. package/.claude/skills/workflow/flow-fix/context.jsonl +6 -0
  89. package/.claude/skills/workflow/flow-fix/references/bug-analyzer.md +381 -0
  90. package/.claude/skills/workflow/flow-init/SKILL.md +211 -0
  91. package/.claude/skills/workflow/flow-init/assets/BRAINSTORM_TEMPLATE.md +148 -0
  92. package/.claude/skills/workflow/flow-init/assets/INIT_FLOW_TEMPLATE.md +198 -0
  93. package/.claude/skills/workflow/flow-init/assets/RESEARCH_TEMPLATE.md +276 -0
  94. package/.claude/skills/workflow/flow-init/context.jsonl +5 -0
  95. package/.claude/skills/workflow/flow-init/references/flow-researcher.md +132 -0
  96. package/.claude/skills/workflow/flow-init/scripts/check-prerequisites.sh +232 -0
  97. package/.claude/skills/workflow/flow-init/scripts/consolidate-research.sh +182 -0
  98. package/.claude/skills/workflow/flow-init/scripts/create-requirement.sh +515 -0
  99. package/.claude/skills/workflow/flow-init/scripts/generate-research-tasks.sh +157 -0
  100. package/.claude/skills/workflow/flow-init/scripts/populate-research-tasks.sh +284 -0
  101. package/.claude/skills/workflow/flow-init/scripts/validate-research.sh +332 -0
  102. package/.claude/skills/workflow/flow-quality/SKILL.md +94 -0
  103. package/.claude/skills/workflow/flow-quality/context.jsonl +6 -0
  104. package/.claude/skills/workflow/flow-quality/references/code-quality-reviewer.md +205 -0
  105. package/.claude/skills/workflow/flow-quality/references/qa-tester.md +313 -0
  106. package/.claude/skills/workflow/flow-quality/references/security-reviewer.md +314 -0
  107. package/.claude/skills/workflow/flow-quality/references/spec-reviewer.md +221 -0
  108. package/.claude/skills/workflow/flow-release/SKILL.md +126 -0
  109. package/.claude/skills/workflow/flow-release/context.jsonl +7 -0
  110. package/.claude/skills/workflow/flow-release/references/release-manager.md +295 -0
  111. package/.claude/skills/workflow/flow-spec/CLAUDE.md +103 -0
  112. package/.claude/skills/workflow/flow-spec/SKILL.md +545 -0
  113. package/.claude/skills/workflow/flow-spec/context.jsonl +7 -0
  114. package/.claude/skills/workflow/flow-spec/scripts/entry-gate.sh +194 -0
  115. package/.claude/skills/workflow/flow-spec/scripts/exit-gate.sh +244 -0
  116. package/.claude/skills/workflow/flow-spec/scripts/parallel-orchestrator.sh +205 -0
  117. package/.claude/skills/workflow/flow-spec/scripts/team-communication.sh +353 -0
  118. package/.claude/skills/workflow/flow-spec/scripts/team-init.sh +195 -0
  119. package/.claude/skills/workflow/flow-spec/scripts/test-team-mode.sh +496 -0
  120. package/.claude/skills/workflow/flow-spec/team-config.json +165 -0
  121. package/.claude/skills/workflow.yaml +417 -0
  122. package/CHANGELOG.md +254 -0
  123. package/README.md +193 -33
  124. package/README.zh-CN.md +206 -46
  125. package/lib/compiler/CLAUDE.md +77 -46
  126. package/lib/compiler/__tests__/multi-module-emitters.test.js +508 -0
  127. package/lib/compiler/context-expander.js +179 -0
  128. package/lib/compiler/emitters/antigravity-emitter.js +195 -5
  129. package/lib/compiler/emitters/base-emitter.js +217 -2
  130. package/lib/compiler/emitters/codex-emitter.js +200 -4
  131. package/lib/compiler/emitters/cursor-emitter.js +307 -3
  132. package/lib/compiler/emitters/qwen-emitter.js +196 -4
  133. package/lib/compiler/index.js +197 -2
  134. package/lib/compiler/platforms.js +270 -21
  135. package/package.json +1 -1
  136. package/.claude/commands/flow-epic.md +0 -183
  137. package/.claude/commands/flow-init.md +0 -370
  138. package/.claude/commands/flow-prd.md +0 -144
  139. package/.claude/commands/flow-qa.md +0 -93
  140. package/.claude/commands/flow-review.md +0 -257
  141. package/.claude/commands/flow-tech.md +0 -142
  142. package/.claude/commands/flow-ui.md +0 -189
  143. package/.claude/skills/file-header-guardian/SKILL.md +0 -56
  144. package/.claude/skills/skill-developer/ADVANCED.md +0 -197
  145. package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +0 -306
  146. package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +0 -152
  147. package/.claude/skills/skill-developer/SKILL.md +0 -426
  148. package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +0 -315
  149. package/.claude/skills/skill-developer/TRIGGER_TYPES.md +0 -305
  150. package/.claude/skills/skill-developer/TROUBLESHOOTING.md +0 -514
  151. package/.claude/skills/writing-skills/SKILL.md +0 -655
  152. package/.claude/skills/writing-skills/anthropic-best-practices.md +0 -1150
  153. package/.claude/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
  154. package/.claude/skills/writing-skills/graphviz-conventions.dot +0 -172
  155. package/.claude/skills/writing-skills/persuasion-principles.md +0 -187
  156. package/.claude/skills/writing-skills/render-graphs.js +0 -168
  157. package/.claude/skills/writing-skills/testing-skills-with-subagents.md +0 -384
  158. package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/affected-repos.txt +0 -1
  159. package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/affected-repos.txt +0 -1
  160. /package/.claude/commands/{core-architecture.md → core/architecture.md} +0 -0
  161. /package/.claude/commands/{core-guidelines.md → core/guidelines.md} +0 -0
  162. /package/.claude/commands/{core-roadmap.md → core/roadmap.md} +0 -0
  163. /package/.claude/commands/{core-style.md → core/style.md} +0 -0
  164. /package/.claude/commands/{flow-checklist.md → flow/checklist.md} +0 -0
  165. /package/.claude/commands/{flow-clarify.md → flow/clarify.md} +0 -0
  166. /package/.claude/commands/{flow-constitution.md → flow/constitution.md} +0 -0
  167. /package/.claude/commands/{flow-fix.md → flow/fix.md} +0 -0
  168. /package/.claude/commands/{flow-ideate.md → flow/ideate.md} +0 -0
  169. /package/.claude/commands/{flow-new.md → flow/new.md} +0 -0
  170. /package/.claude/commands/{flow-release.md → flow/release.md} +0 -0
  171. /package/.claude/commands/{flow-restart.md → flow/restart.md} +0 -0
  172. /package/.claude/commands/{flow-status.md → flow/status.md} +0 -0
  173. /package/.claude/commands/{flow-update.md → flow/update.md} +0 -0
  174. /package/.claude/commands/{flow-upgrade.md → flow/upgrade.md} +0 -0
  175. /package/.claude/commands/{flow-verify.md → flow/verify.md} +0 -0
  176. /package/.claude/commands/{code-review-high.md → util/code-review.md} +0 -0
  177. /package/.claude/commands/{git-commit.md → util/git-commit.md} +0 -0
  178. /package/.claude/commands/{problem-analyzer.md → util/problem-analyzer.md} +0 -0
  179. /package/.claude/skills/{flow-attention-refresh → domain/attention-refresh}/SKILL.md +0 -0
  180. /package/.claude/skills/{flow-brainstorming → domain/brainstorming}/SKILL.md +0 -0
  181. /package/.claude/skills/{flow-debugging → domain/debugging}/SKILL.md +0 -0
  182. /package/.claude/skills/{flow-finishing-branch → domain/finishing-branch}/SKILL.md +0 -0
  183. /package/.claude/skills/{flow-receiving-review → domain/receiving-review}/SKILL.md +0 -0
  184. /package/.claude/skills/{flow-tdd → domain/tdd}/SKILL.md +0 -0
  185. /package/.claude/skills/{verification-before-completion → domain/verification}/SKILL.md +0 -0
  186. /package/.claude/skills/{constitution-guardian → guardrail/constitution-guardian}/SKILL.md +0 -0
  187. /package/.claude/skills/{devflow-tdd-enforcer → guardrail/tdd-enforcer}/SKILL.md +0 -0
  188. /package/.claude/skills/{devflow-constitution-quick-ref → utility/constitution-quick-ref}/SKILL.md +0 -0
  189. /package/.claude/skills/{devflow-file-standards → utility/file-standards}/SKILL.md +0 -0
  190. /package/.claude/skills/{fractal-docs-generator → utility/fractal-docs}/SKILL.md +0 -0
  191. /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