cc-devflow 2.5.0 → 4.1.1

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 (192) hide show
  1. package/.claude/CLAUDE.md +1065 -53
  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/new.md +279 -0
  9. package/.claude/commands/flow/quality.md +159 -0
  10. package/.claude/commands/flow/spec.md +186 -0
  11. package/.claude/commands/flow/workspace.md +146 -0
  12. package/.claude/commands/{cancel-ralph.md → util/cancel-ralph.md} +1 -0
  13. package/.claude/config/quality-gates.yml +305 -0
  14. package/.claude/docs/guides/TEAM_MODE_GUIDE.md +313 -0
  15. package/.claude/docs/templates/DELTA_SPEC_TEMPLATE.md +91 -0
  16. package/.claude/docs/templates/DESIGN_DECISIONS_TEMPLATE.md +151 -0
  17. package/.claude/docs/templates/JOURNAL_TEMPLATE.md +75 -0
  18. package/.claude/docs/templates/NEW_ORCHESTRATION_TEMPLATE.md +51 -91
  19. package/.claude/docs/templates/_shared/CLAUDE.md +36 -0
  20. package/.claude/docs/templates/_shared/CONSTITUTION_CHECK.md +125 -0
  21. package/.claude/docs/templates/_shared/VALIDATION_CHECKLIST.md +187 -0
  22. package/.claude/docs/templates/_shared/YAML_FRONTMATTER.md +164 -0
  23. package/.claude/docs/templates/context/dev.jsonl.template +6 -0
  24. package/.claude/docs/templates/context/epic.jsonl.template +5 -0
  25. package/.claude/docs/templates/context/prd.jsonl.template +4 -0
  26. package/.claude/docs/templates/context/research.jsonl.template +4 -0
  27. package/.claude/docs/templates/context/review.jsonl.template +5 -0
  28. package/.claude/docs/templates/context/tech.jsonl.template +5 -0
  29. package/.claude/hooks/CLAUDE.md +342 -0
  30. package/.claude/hooks/inject-agent-context.ts +480 -0
  31. package/.claude/hooks/inject-skill-context.ts +359 -0
  32. package/.claude/hooks/ralph-loop.ts +931 -0
  33. package/.claude/hooks/task-completed-hook.ts +593 -0
  34. package/.claude/hooks/teammate-idle-hook.ts +690 -0
  35. package/.claude/hooks/types/team-types.d.ts +238 -0
  36. package/.claude/rules/devflow-conventions.md +82 -9
  37. package/.claude/scripts/archive-requirement.sh +44 -1
  38. package/.claude/scripts/common.sh +670 -3
  39. package/.claude/scripts/delta-parser.ts +527 -0
  40. package/.claude/scripts/detect-file-conflicts.sh +151 -0
  41. package/.claude/scripts/flow-context-add.sh +134 -0
  42. package/.claude/scripts/flow-context-init.sh +133 -0
  43. package/.claude/scripts/flow-context-validate.sh +144 -0
  44. package/.claude/scripts/flow-delta-apply.sh +297 -0
  45. package/.claude/scripts/flow-delta-archive.sh +71 -0
  46. package/.claude/scripts/flow-delta-create.sh +202 -0
  47. package/.claude/scripts/flow-delta-list.sh +142 -0
  48. package/.claude/scripts/flow-delta-status.sh +235 -0
  49. package/.claude/scripts/flow-quality-full.sh +184 -0
  50. package/.claude/scripts/flow-quality-quick.sh +64 -0
  51. package/.claude/scripts/flow-workspace-init.sh +117 -0
  52. package/.claude/scripts/flow-workspace-record.sh +164 -0
  53. package/.claude/scripts/flow-workspace-start.sh +88 -0
  54. package/.claude/scripts/get-workflow-status.sh +415 -0
  55. package/.claude/scripts/parse-task-dependencies.js +334 -0
  56. package/.claude/scripts/record-quality-error.sh +165 -0
  57. package/.claude/scripts/run-quality-gates.sh +242 -0
  58. package/.claude/scripts/team-dev-init.sh +319 -0
  59. package/.claude/scripts/team-state-recovery.sh +229 -0
  60. package/.claude/scripts/workflow-status.ts +433 -0
  61. package/.claude/settings.json +19 -0
  62. package/.claude/skills/cc-devflow-orchestrator/SKILL.md +85 -200
  63. package/.claude/skills/domain/using-git-worktrees/SKILL.md +252 -0
  64. package/.claude/skills/domain/using-git-worktrees/assets/SHELL_ALIASES.md +133 -0
  65. package/.claude/skills/domain/using-git-worktrees/context.jsonl +4 -0
  66. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh +218 -0
  67. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh +232 -0
  68. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-list.sh +130 -0
  69. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-status.sh +140 -0
  70. package/.claude/skills/domain/using-git-worktrees/scripts/worktree-switch.sh +70 -0
  71. package/.claude/skills/utility/skill-creator/LICENSE.txt +202 -0
  72. package/.claude/skills/utility/skill-creator/SKILL.md +356 -0
  73. package/.claude/skills/utility/skill-creator/references/output-patterns.md +82 -0
  74. package/.claude/skills/utility/skill-creator/references/workflows.md +28 -0
  75. package/.claude/skills/utility/skill-creator/scripts/init_skill.py +303 -0
  76. package/.claude/skills/utility/skill-creator/scripts/package_skill.py +110 -0
  77. package/.claude/skills/utility/skill-creator/scripts/quick_validate.py +95 -0
  78. package/.claude/skills/workflow/flow-dev/CLAUDE.md +78 -0
  79. package/.claude/skills/workflow/flow-dev/SKILL.md +96 -0
  80. package/.claude/skills/workflow/flow-dev/assets/IMPLEMENTATION_PLAN_TEMPLATE.md +71 -0
  81. package/.claude/skills/workflow/flow-dev/context.jsonl +8 -0
  82. package/.claude/skills/workflow/flow-dev/dev-implementer.jsonl +8 -0
  83. package/.claude/skills/workflow/flow-dev/scripts/entry-gate.sh +116 -0
  84. package/.claude/skills/workflow/flow-dev/scripts/exit-gate.sh +101 -0
  85. package/.claude/skills/workflow/flow-dev/scripts/task-orchestrator.sh +106 -0
  86. package/.claude/skills/workflow/flow-fix/SKILL.md +105 -0
  87. package/.claude/skills/workflow/flow-fix/context.jsonl +6 -0
  88. package/.claude/skills/workflow/flow-fix/references/bug-analyzer.md +381 -0
  89. package/.claude/skills/workflow/flow-init/SKILL.md +211 -0
  90. package/.claude/skills/workflow/flow-init/assets/BRAINSTORM_TEMPLATE.md +148 -0
  91. package/.claude/skills/workflow/flow-init/assets/INIT_FLOW_TEMPLATE.md +198 -0
  92. package/.claude/skills/workflow/flow-init/assets/RESEARCH_TEMPLATE.md +276 -0
  93. package/.claude/skills/workflow/flow-init/context.jsonl +5 -0
  94. package/.claude/skills/workflow/flow-init/references/flow-researcher.md +132 -0
  95. package/.claude/skills/workflow/flow-init/scripts/check-prerequisites.sh +240 -0
  96. package/.claude/skills/workflow/flow-init/scripts/consolidate-research.sh +182 -0
  97. package/.claude/skills/workflow/flow-init/scripts/create-requirement.sh +523 -0
  98. package/.claude/skills/workflow/flow-init/scripts/generate-research-tasks.sh +157 -0
  99. package/.claude/skills/workflow/flow-init/scripts/populate-research-tasks.sh +284 -0
  100. package/.claude/skills/workflow/flow-init/scripts/validate-research.sh +340 -0
  101. package/.claude/skills/workflow/flow-quality/SKILL.md +94 -0
  102. package/.claude/skills/workflow/flow-quality/context.jsonl +6 -0
  103. package/.claude/skills/workflow/flow-quality/references/code-quality-reviewer.md +205 -0
  104. package/.claude/skills/workflow/flow-quality/references/qa-tester.md +313 -0
  105. package/.claude/skills/workflow/flow-quality/references/security-reviewer.md +314 -0
  106. package/.claude/skills/workflow/flow-quality/references/spec-reviewer.md +221 -0
  107. package/.claude/skills/workflow/flow-release/SKILL.md +126 -0
  108. package/.claude/skills/workflow/flow-release/context.jsonl +7 -0
  109. package/.claude/skills/workflow/flow-release/references/release-manager.md +295 -0
  110. package/.claude/skills/workflow/flow-spec/CLAUDE.md +103 -0
  111. package/.claude/skills/workflow/flow-spec/SKILL.md +545 -0
  112. package/.claude/skills/workflow/flow-spec/context.jsonl +7 -0
  113. package/.claude/skills/workflow/flow-spec/scripts/entry-gate.sh +194 -0
  114. package/.claude/skills/workflow/flow-spec/scripts/exit-gate.sh +244 -0
  115. package/.claude/skills/workflow/flow-spec/scripts/parallel-orchestrator.sh +205 -0
  116. package/.claude/skills/workflow/flow-spec/scripts/team-communication.sh +353 -0
  117. package/.claude/skills/workflow/flow-spec/scripts/team-init.sh +195 -0
  118. package/.claude/skills/workflow/flow-spec/scripts/test-team-mode.sh +496 -0
  119. package/.claude/skills/workflow/flow-spec/team-config.json +165 -0
  120. package/.claude/skills/workflow.yaml +417 -0
  121. package/CHANGELOG.md +268 -0
  122. package/README.md +206 -50
  123. package/README.zh-CN.md +219 -57
  124. package/lib/compiler/CLAUDE.md +77 -46
  125. package/lib/compiler/__tests__/multi-module-emitters.test.js +508 -0
  126. package/lib/compiler/context-expander.js +179 -0
  127. package/lib/compiler/emitters/antigravity-emitter.js +195 -5
  128. package/lib/compiler/emitters/base-emitter.js +217 -2
  129. package/lib/compiler/emitters/codex-emitter.js +200 -4
  130. package/lib/compiler/emitters/cursor-emitter.js +307 -3
  131. package/lib/compiler/emitters/qwen-emitter.js +196 -4
  132. package/lib/compiler/index.js +197 -2
  133. package/lib/compiler/platforms.js +270 -21
  134. package/package.json +2 -2
  135. package/.claude/commands/flow-epic.md +0 -183
  136. package/.claude/commands/flow-init.md +0 -370
  137. package/.claude/commands/flow-new.md +0 -442
  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-release.md → flow/release.md} +0 -0
  170. /package/.claude/commands/{flow-restart.md → flow/restart.md} +0 -0
  171. /package/.claude/commands/{flow-status.md → flow/status.md} +0 -0
  172. /package/.claude/commands/{flow-update.md → flow/update.md} +0 -0
  173. /package/.claude/commands/{flow-upgrade.md → flow/upgrade.md} +0 -0
  174. /package/.claude/commands/{flow-verify.md → flow/verify.md} +0 -0
  175. /package/.claude/commands/{code-review-high.md → util/code-review.md} +0 -0
  176. /package/.claude/commands/{git-commit.md → util/git-commit.md} +0 -0
  177. /package/.claude/commands/{problem-analyzer.md → util/problem-analyzer.md} +0 -0
  178. /package/.claude/skills/{flow-attention-refresh → domain/attention-refresh}/SKILL.md +0 -0
  179. /package/.claude/skills/{flow-brainstorming → domain/brainstorming}/SKILL.md +0 -0
  180. /package/.claude/skills/{flow-debugging → domain/debugging}/SKILL.md +0 -0
  181. /package/.claude/skills/{flow-finishing-branch → domain/finishing-branch}/SKILL.md +0 -0
  182. /package/.claude/skills/{flow-receiving-review → domain/receiving-review}/SKILL.md +0 -0
  183. /package/.claude/skills/{flow-tdd → domain/tdd}/SKILL.md +0 -0
  184. /package/.claude/skills/{verification-before-completion → domain/verification}/SKILL.md +0 -0
  185. /package/.claude/skills/{constitution-guardian → guardrail/constitution-guardian}/SKILL.md +0 -0
  186. /package/.claude/skills/{devflow-tdd-enforcer → guardrail/tdd-enforcer}/SKILL.md +0 -0
  187. /package/.claude/skills/{devflow-constitution-quick-ref → utility/constitution-quick-ref}/SKILL.md +0 -0
  188. /package/.claude/skills/{devflow-file-standards → utility/file-standards}/SKILL.md +0 -0
  189. /package/.claude/skills/{fractal-docs-generator → utility/fractal-docs}/SKILL.md +0 -0
  190. /package/.claude/skills/{journey-coherence-checker → utility/journey-checker}/SKILL.md +0 -0
  191. /package/.claude/skills/{journey-coherence-checker → utility/journey-checker}/pressure-scenarios.md +0 -0
  192. /package/.claude/skills/{npm-release → utility/npm-release}/SKILL.md +0 -0
@@ -0,0 +1,523 @@
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
+ COMMON_SH="$SCRIPT_DIR/common.sh"
177
+ if [[ ! -f "$COMMON_SH" ]]; then
178
+ COMMON_SH="$SCRIPT_DIR/../../../../scripts/common.sh"
179
+ fi
180
+ if [[ ! -f "$COMMON_SH" ]]; then
181
+ echo "ERROR: common.sh not found (checked local + .claude/scripts)" >&2
182
+ exit 1
183
+ fi
184
+ source "$COMMON_SH"
185
+ REPO_ROOT=$(get_repo_root)
186
+
187
+ # Interactive mode
188
+ if $INTERACTIVE; then
189
+ if ! $JSON_MODE; then
190
+ echo "=== Create New Requirement ==="
191
+ echo ""
192
+ fi
193
+
194
+ # Prompt for requirement ID if not provided
195
+ if [[ -z "$REQ_ID" ]]; then
196
+ suggested_req_id=$(next_available_req_id "$REPO_ROOT")
197
+ read -p "Requirement ID (REQ-XXX or BUG-XXX) [${suggested_req_id}]: " input_req_id
198
+ input_req_id=$(echo "${input_req_id}" | tr '[:lower:]' '[:upper:]')
199
+ if [[ -z "$input_req_id" ]]; then
200
+ AUTO_ID=true
201
+ REQ_ID="$suggested_req_id"
202
+ else
203
+ REQ_ID="$input_req_id"
204
+ fi
205
+ fi
206
+
207
+ # Prompt for title if not provided
208
+ if [[ -z "$TITLE" ]]; then
209
+ read -p "Requirement Title: " TITLE
210
+ fi
211
+
212
+ # Prompt for description
213
+ if [[ -z "$DESCRIPTION" ]]; then
214
+ read -p "Brief Description (optional): " DESCRIPTION
215
+ fi
216
+
217
+ # Prompt for git branch creation
218
+ if ! $SKIP_GIT && has_git; then
219
+ read -p "Create git branch? (y/n): " create_branch
220
+ if [[ "$create_branch" != "y" && "$create_branch" != "Y" ]]; then
221
+ SKIP_GIT=true
222
+ fi
223
+ fi
224
+ fi
225
+
226
+ # Ensure requirement ID is set, auto-select when allowed
227
+ if [[ -z "$REQ_ID" ]]; then
228
+ AUTO_ID=true
229
+ REQ_ID=$(next_available_req_id "$REPO_ROOT")
230
+ if [[ -z "$REQ_ID" ]]; then
231
+ echo "ERROR: Unable to determine next requirement ID" >&2
232
+ exit 1
233
+ fi
234
+ if ! $JSON_MODE; then
235
+ echo "Auto-selected requirement ID: $REQ_ID" >&2
236
+ fi
237
+ fi
238
+
239
+ # Normalize requirement ID to uppercase
240
+ REQ_ID=$(echo "$REQ_ID" | tr '[:lower:]' '[:upper:]')
241
+
242
+ # Validate requirement ID format
243
+ validate_req_id "$REQ_ID" || exit 1
244
+
245
+ # Resolve conflicts when requirement ID already exists
246
+ if req_id_in_use "$REPO_ROOT" "$REQ_ID"; then
247
+ if $AUTO_ID; then
248
+ original_req_id="$REQ_ID"
249
+ while req_id_in_use "$REPO_ROOT" "$REQ_ID"; do
250
+ next_candidate=$(next_available_req_id "$REPO_ROOT")
251
+ if [[ "$next_candidate" == "$REQ_ID" ]]; then
252
+ next_candidate="REQ-$(date +%Y%m%d%H%M%S)"
253
+ fi
254
+ REQ_ID="$next_candidate"
255
+ done
256
+ if [[ "$REQ_ID" != "$original_req_id" ]] && ! $JSON_MODE; then
257
+ echo "Requirement ID in use; switched to $REQ_ID" >&2
258
+ fi
259
+ else
260
+ suggested_req_id=$(next_available_req_id "$REPO_ROOT")
261
+ conflict_dir=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
262
+ echo "ERROR: Requirement directory already exists: $conflict_dir" >&2
263
+ if [[ "$suggested_req_id" != "$REQ_ID" ]]; then
264
+ echo "Suggested next available ID: $suggested_req_id" >&2
265
+ fi
266
+ exit 1
267
+ fi
268
+ fi
269
+
270
+ # Get requirement type and directory
271
+ REQ_TYPE=$(get_req_type "$REQ_ID")
272
+ REQ_DIR=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
273
+
274
+ # Create directory structure
275
+ if ! $JSON_MODE; then
276
+ echo "Creating requirement structure at $REQ_DIR..." >&2
277
+ fi
278
+
279
+ # Create directories
280
+ mkdir -p "$REQ_DIR/research"
281
+
282
+ # Initialize EXECUTION_LOG.md
283
+ cat > "$REQ_DIR/EXECUTION_LOG.md" <<EOF
284
+ # Execution Log: $REQ_ID
285
+
286
+ **Title**: ${TITLE:-"To be defined"}
287
+ **Type**: $REQ_TYPE
288
+ **Created**: $(get_beijing_time_full)
289
+
290
+ EOF
291
+
292
+ if [[ -n "$DESCRIPTION" ]]; then
293
+ cat >> "$REQ_DIR/EXECUTION_LOG.md" <<EOF
294
+ ## Description
295
+ $DESCRIPTION
296
+
297
+ EOF
298
+ fi
299
+
300
+ cat >> "$REQ_DIR/EXECUTION_LOG.md" <<'EOF'
301
+ ## Events
302
+
303
+ EOF
304
+
305
+ # Initialize status file
306
+ if [[ "$REQ_TYPE" == "bug" ]]; then
307
+ # BUG-specific status file
308
+ cat > "$REQ_DIR/status.json" <<EOF
309
+ {
310
+ "bugId": "$REQ_ID",
311
+ "title": "${TITLE:-"To be defined"}",
312
+ "status": "initialized",
313
+ "phase": "analysis",
314
+ "severity": "unknown",
315
+ "createdAt": "$(get_beijing_time_iso)",
316
+ "updatedAt": "$(get_beijing_time_iso)"
317
+ }
318
+ EOF
319
+ else
320
+ # Requirement status file
321
+ cat > "$REQ_DIR/orchestration_status.json" <<EOF
322
+ {
323
+ "reqId": "$REQ_ID",
324
+ "title": "${TITLE:-"To be defined"}",
325
+ "status": "initialized",
326
+ "phase": "planning",
327
+ "createdAt": "$(get_beijing_time_iso)",
328
+ "updatedAt": "$(get_beijing_time_iso)"
329
+ }
330
+ EOF
331
+ fi
332
+
333
+ # Create README.md for the requirement
334
+ cat > "$REQ_DIR/README.md" <<EOF
335
+ # $REQ_ID: ${TITLE:-"To be defined"}
336
+
337
+ **Status**: Initialized
338
+ **Type**: $REQ_TYPE
339
+ **Created**: $(get_beijing_time_full)
340
+
341
+ EOF
342
+
343
+ if [[ -n "$DESCRIPTION" ]]; then
344
+ cat >> "$REQ_DIR/README.md" <<EOF
345
+ ## Description
346
+ $DESCRIPTION
347
+
348
+ EOF
349
+ fi
350
+
351
+ cat >> "$REQ_DIR/README.md" <<'EOF'
352
+ ## Documents
353
+
354
+ ### Planning Phase
355
+ - [ ] PRD.md - Product Requirements Document
356
+ - [ ] EPIC.md - Epic Planning
357
+ - [ ] TASKS.md - Task Breakdown
358
+
359
+ ### Execution Phase
360
+ - [ ] TEST_PLAN.md - Test Plan
361
+ - [ ] SECURITY_PLAN.md - Security Plan
362
+ - [ ] EXECUTION_LOG.md - Event Log
363
+
364
+ ### Review Phase
365
+ - [ ] TEST_REPORT.md - Test Report
366
+ - [ ] SECURITY_REPORT.md - Security Report
367
+ - [ ] RELEASE_PLAN.md - Release Plan
368
+
369
+ ## Research Materials
370
+ Place external research materials in `research/` directory:
371
+ - API documentation
372
+ - Design specifications
373
+ - Reference implementations
374
+ - Planning documents
375
+
376
+ ## Workflow
377
+ 1. **Planning**: Create PRD → Generate EPIC → Break down TASKS
378
+ 2. **Development**: Implement tasks following TDD approach
379
+ 3. **Quality**: Execute test plan and security review
380
+ 4. **Release**: Create release plan and merge to main
381
+
382
+ EOF
383
+
384
+ # Log the creation event
385
+ log_event "$REQ_ID" "Requirement structure initialized"
386
+
387
+ if [[ -n "$TITLE" ]]; then
388
+ log_event "$REQ_ID" "Title: $TITLE"
389
+ fi
390
+
391
+ if [[ -n "$DESCRIPTION" ]]; then
392
+ log_event "$REQ_ID" "Description: $DESCRIPTION"
393
+ fi
394
+
395
+ # Create git branch/worktree if requested and available
396
+ GIT_BRANCH=""
397
+ WORKTREE_DIR=""
398
+ if ! $SKIP_GIT && has_git; then
399
+ # Generate branch name from title
400
+ if [[ -n "$BRANCH_TITLE" ]]; then
401
+ BRANCH_SUFFIX=$(slugify "$BRANCH_TITLE")
402
+ elif [[ -n "$TITLE" ]]; then
403
+ BRANCH_SUFFIX=$(slugify "$TITLE")
404
+ else
405
+ BRANCH_SUFFIX="new-requirement"
406
+ fi
407
+ if [[ -z "$BRANCH_SUFFIX" ]]; then
408
+ BRANCH_SUFFIX="new-requirement"
409
+ fi
410
+
411
+ # Determine branch prefix based on type
412
+ if [[ "$REQ_TYPE" == "bug" ]]; then
413
+ GIT_BRANCH="bugfix/$REQ_ID-$BRANCH_SUFFIX"
414
+ else
415
+ GIT_BRANCH="feature/$REQ_ID-$BRANCH_SUFFIX"
416
+ fi
417
+
418
+ # Check if branch already exists
419
+ if git rev-parse --verify "$GIT_BRANCH" >/dev/null 2>&1; then
420
+ if ! $JSON_MODE; then
421
+ echo "WARNING: Git branch already exists: $GIT_BRANCH" >&2
422
+ fi
423
+ # Branch exists - check if we should use worktree mode
424
+ if $USE_WORKTREE && ! $BRANCH_ONLY; then
425
+ REPO_NAME=$(basename "$REPO_ROOT")
426
+ WORKTREE_DIR="$(dirname "$REPO_ROOT")/${REPO_NAME}-${REQ_ID}"
427
+ if [[ -d "$WORKTREE_DIR" ]]; then
428
+ if ! $JSON_MODE; then
429
+ echo "Worktree already exists at: $WORKTREE_DIR" >&2
430
+ fi
431
+ else
432
+ # Create worktree with existing branch
433
+ git worktree add "$WORKTREE_DIR" "$GIT_BRANCH" >/dev/null 2>&1
434
+ log_event "$REQ_ID" "Created git worktree: $WORKTREE_DIR (existing branch: $GIT_BRANCH)"
435
+ if ! $JSON_MODE; then
436
+ echo "Created worktree at: $WORKTREE_DIR" >&2
437
+ fi
438
+ fi
439
+ fi
440
+ else
441
+ # Branch doesn't exist - create it
442
+ if $USE_WORKTREE && ! $BRANCH_ONLY; then
443
+ # Worktree mode (default)
444
+ REPO_NAME=$(basename "$REPO_ROOT")
445
+ WORKTREE_DIR="$(dirname "$REPO_ROOT")/${REPO_NAME}-${REQ_ID}"
446
+
447
+ if [[ -d "$WORKTREE_DIR" ]]; then
448
+ if ! $JSON_MODE; then
449
+ echo "WARNING: Worktree directory already exists: $WORKTREE_DIR" >&2
450
+ echo "Skipping worktree creation." >&2
451
+ fi
452
+ else
453
+ # Create worktree with new branch
454
+ git worktree add -b "$GIT_BRANCH" "$WORKTREE_DIR" >/dev/null 2>&1
455
+ log_event "$REQ_ID" "Created git worktree: $WORKTREE_DIR (branch: $GIT_BRANCH)"
456
+
457
+ if ! $JSON_MODE; then
458
+ echo "Created worktree at: $WORKTREE_DIR" >&2
459
+ echo "Branch: $GIT_BRANCH" >&2
460
+ fi
461
+ fi
462
+ else
463
+ # Traditional branch mode
464
+ git checkout -b "$GIT_BRANCH" >/dev/null 2>&1
465
+ log_event "$REQ_ID" "Created git branch: $GIT_BRANCH"
466
+
467
+ if ! $JSON_MODE; then
468
+ echo "Created and checked out branch: $GIT_BRANCH" >&2
469
+ fi
470
+ fi
471
+ fi
472
+
473
+ # Set environment variable for non-branch-based workflows
474
+ export DEVFLOW_REQ_ID="$REQ_ID"
475
+ fi
476
+
477
+ # Output results
478
+ if $JSON_MODE; then
479
+ printf '{"req_id":"%s","req_type":"%s","req_dir":"%s","title":"%s","git_branch":"%s","worktree_dir":"%s","mode":"%s","created_at":"%s"}\n' \
480
+ "$REQ_ID" \
481
+ "$REQ_TYPE" \
482
+ "$REQ_DIR" \
483
+ "${TITLE:-""}" \
484
+ "${GIT_BRANCH:-""}" \
485
+ "${WORKTREE_DIR:-""}" \
486
+ "$( $USE_WORKTREE && echo "worktree" || echo "branch" )" \
487
+ "$(get_beijing_time_iso)"
488
+ else
489
+ echo ""
490
+ echo "✅ Requirement structure created successfully!"
491
+ echo ""
492
+ echo "Requirement ID: $REQ_ID"
493
+ echo "Type: $REQ_TYPE"
494
+ echo "Directory: $REQ_DIR"
495
+ if [[ -n "$TITLE" ]]; then
496
+ echo "Title: $TITLE"
497
+ fi
498
+ if [[ -n "$GIT_BRANCH" ]]; then
499
+ echo "Git Branch: $GIT_BRANCH"
500
+ fi
501
+ if [[ -n "$WORKTREE_DIR" ]]; then
502
+ echo "Worktree: $WORKTREE_DIR"
503
+ echo "Mode: worktree (parallel development enabled)"
504
+ elif [[ -n "$GIT_BRANCH" ]]; then
505
+ echo "Mode: branch (traditional)"
506
+ fi
507
+ echo ""
508
+ echo "Next Steps:"
509
+ if [[ -n "$WORKTREE_DIR" && -d "$WORKTREE_DIR" ]]; then
510
+ echo " 1. cd $WORKTREE_DIR"
511
+ echo " 2. claude # Start new Claude Code session"
512
+ echo " 3. Continue with /flow-prd or /flow-spec"
513
+ elif [[ "$REQ_TYPE" == "bug" ]]; then
514
+ echo " 1. Run bug-analyzer agent to analyze the BUG"
515
+ echo " 2. Run /flow-fix to start BUG fix workflow"
516
+ echo " 3. Keep EXECUTION_LOG.md updated during fixes"
517
+ else
518
+ echo " 1. Add research materials to research/ (optional)"
519
+ echo " 2. Run prd-writer agent to create PRD.md"
520
+ echo " 3. Continue with planner and subsequent flow commands"
521
+ fi
522
+ echo ""
523
+ 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