cc-devflow 1.0.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.
- package/.claude/CLAUDE.md +83 -0
- package/.claude/agents/architecture-designer.md +443 -0
- package/.claude/agents/bug-analyzer.md +382 -0
- package/.claude/agents/checklist-agent.md +175 -0
- package/.claude/agents/clarify-analyst.md +50 -0
- package/.claude/agents/code-reviewer.md +71 -0
- package/.claude/agents/codex-analyzer.md +39 -0
- package/.claude/agents/compatibility-checker.md +580 -0
- package/.claude/agents/consistency-checker.md +532 -0
- package/.claude/agents/impact-analyzer.md +441 -0
- package/.claude/agents/planner.md +230 -0
- package/.claude/agents/prd-writer.md +320 -0
- package/.claude/agents/project-guidelines-generator.md +1329 -0
- package/.claude/agents/qa-tester.md +313 -0
- package/.claude/agents/release-manager.md +295 -0
- package/.claude/agents/security-reviewer.md +314 -0
- package/.claude/agents/style-guide-generator.md +458 -0
- package/.claude/agents/tech-architect.md +516 -0
- package/.claude/agents/ui-designer.md +485 -0
- package/.claude/commands/code-review-high.md +58 -0
- package/.claude/commands/core-architecture.md +429 -0
- package/.claude/commands/core-guidelines.md +486 -0
- package/.claude/commands/core-roadmap.md +439 -0
- package/.claude/commands/core-style.md +293 -0
- package/.claude/commands/flow-archive.md +245 -0
- package/.claude/commands/flow-checklist.md +260 -0
- package/.claude/commands/flow-clarify.md +136 -0
- package/.claude/commands/flow-constitution.md +82 -0
- package/.claude/commands/flow-dev.md +134 -0
- package/.claude/commands/flow-epic.md +150 -0
- package/.claude/commands/flow-fix.md +104 -0
- package/.claude/commands/flow-ideate.md +214 -0
- package/.claude/commands/flow-init.md +313 -0
- package/.claude/commands/flow-new.md +394 -0
- package/.claude/commands/flow-prd.md +131 -0
- package/.claude/commands/flow-qa.md +93 -0
- package/.claude/commands/flow-release.md +92 -0
- package/.claude/commands/flow-restart.md +98 -0
- package/.claude/commands/flow-status.md +64 -0
- package/.claude/commands/flow-tech.md +142 -0
- package/.claude/commands/flow-ui.md +189 -0
- package/.claude/commands/flow-update.md +111 -0
- package/.claude/commands/flow-upgrade.md +115 -0
- package/.claude/commands/flow-verify.md +96 -0
- package/.claude/commands/problem-analyzer.md +60 -0
- package/.claude/config/quality-rules.yml +161 -0
- package/.claude/docs/SPEC_KIT_CONSTITUTION_ANALYSIS.md +426 -0
- package/.claude/docs/design/consistency-conflict-detection-algorithms.md +658 -0
- package/.claude/docs/design/intent-driven-input-design.md +380 -0
- package/.claude/docs/design/prd-version-management-design.md +437 -0
- package/.claude/docs/guides/INIT_TROUBLESHOOTING.md +117 -0
- package/.claude/docs/guides/NEW_TROUBLESHOOTING.md +151 -0
- package/.claude/docs/guides/ROADMAP_TROUBLESHOOTING.md +188 -0
- package/.claude/docs/guides/TASK_COMPLETION_MARKING.md +338 -0
- package/.claude/docs/templates/ARCHITECTURE_TEMPLATE.md +633 -0
- package/.claude/docs/templates/BACKLOG_TEMPLATE.md +261 -0
- package/.claude/docs/templates/CHECKLIST_TEMPLATE.md +52 -0
- package/.claude/docs/templates/CLARIFICATION_REPORT_TEMPLATE.md +206 -0
- package/.claude/docs/templates/CODE_REVIEW_TEMPLATE.md +71 -0
- package/.claude/docs/templates/EPIC_TEMPLATE.md +805 -0
- package/.claude/docs/templates/INIT_FLOW_TEMPLATE.md +213 -0
- package/.claude/docs/templates/INTENT_CLARIFICATION_TEMPLATE.md +57 -0
- package/.claude/docs/templates/NEW_ORCHESTRATION_TEMPLATE.md +148 -0
- package/.claude/docs/templates/PRD_TEMPLATE.md +562 -0
- package/.claude/docs/templates/RESEARCH_TEMPLATE.md +276 -0
- package/.claude/docs/templates/REVIEW-HIGH.md +57 -0
- package/.claude/docs/templates/ROADMAP_DIALOGUE_TEMPLATE.md +198 -0
- package/.claude/docs/templates/ROADMAP_TEMPLATE.md +310 -0
- package/.claude/docs/templates/STYLE_TEMPLATE.md +1266 -0
- package/.claude/docs/templates/TASKS_TEMPLATE.md +523 -0
- package/.claude/docs/templates/TECH_DESIGN_TEMPLATE.md +1019 -0
- package/.claude/docs/templates/UI_PROTOTYPE_TEMPLATE.md +1436 -0
- package/.claude/guides/agent-guides/agent-coordination-guide.md +459 -0
- package/.claude/guides/project-guidelines-system.md +463 -0
- package/.claude/guides/technical-guides/datetime-handling-guide.md +563 -0
- package/.claude/guides/technical-guides/git-github-guide.md +642 -0
- package/.claude/guides/technical-guides/test-execution-guide.md +618 -0
- package/.claude/guides/workflow-guides/bug-fix-orchestrator.md +217 -0
- package/.claude/guides/workflow-guides/flow-orchestrator.md +282 -0
- package/.claude/hooks/checklist-gate.js +397 -0
- package/.claude/hooks/error-handling-reminder.sh +12 -0
- package/.claude/hooks/error-handling-reminder.ts +459 -0
- package/.claude/hooks/post-tool-use-tracker.sh +280 -0
- package/.claude/hooks/pre-tool-use-guardrail.sh +36 -0
- package/.claude/hooks/pre-tool-use-guardrail.ts +342 -0
- package/.claude/hooks/skill-activation-prompt.sh +36 -0
- package/.claude/hooks/skill-activation-prompt.ts +214 -0
- package/.claude/hooks/state/skills-used-test-guard.json +3 -0
- package/.claude/rules/devflow-conventions.md +305 -0
- package/.claude/rules/project-constitution.md +748 -0
- package/.claude/schemas/constitution.schema.json +43 -0
- package/.claude/scripts/analyze-upgrade-impact.sh +200 -0
- package/.claude/scripts/archive-requirement.sh +351 -0
- package/.claude/scripts/calculate-checklist-completion.sh +243 -0
- package/.claude/scripts/calculate-quarter.sh +206 -0
- package/.claude/scripts/check-dependencies.sh +409 -0
- package/.claude/scripts/check-prerequisites.sh +232 -0
- package/.claude/scripts/check-task-status.sh +264 -0
- package/.claude/scripts/checklist-errors.sh +131 -0
- package/.claude/scripts/common.sh +570 -0
- package/.claude/scripts/consolidate-research.sh +182 -0
- package/.claude/scripts/create-requirement.sh +426 -0
- package/.claude/scripts/export-contracts.sh +117 -0
- package/.claude/scripts/extract-data-model.sh +78 -0
- package/.claude/scripts/generate-clarification-questions.sh +377 -0
- package/.claude/scripts/generate-clarification-report.sh +463 -0
- package/.claude/scripts/generate-quickstart.sh +146 -0
- package/.claude/scripts/generate-research-tasks.sh +157 -0
- package/.claude/scripts/generate-status-report.sh +523 -0
- package/.claude/scripts/generate-tech-analysis.sh +46 -0
- package/.claude/scripts/locate-requirement-in-roadmap.sh +233 -0
- package/.claude/scripts/manage-constitution.sh +602 -0
- package/.claude/scripts/mark-task-complete.sh +198 -0
- package/.claude/scripts/populate-research-tasks.sh +259 -0
- package/.claude/scripts/recover-workflow.sh +460 -0
- package/.claude/scripts/run-clarify-scan.sh +601 -0
- package/.claude/scripts/run-high-review.sh +62 -0
- package/.claude/scripts/run-problem-analysis.sh +68 -0
- package/.claude/scripts/setup-epic.sh +173 -0
- package/.claude/scripts/sync-roadmap-progress.sh +300 -0
- package/.claude/scripts/sync-task-marks.sh +199 -0
- package/.claude/scripts/test-clarify-scan.sh +515 -0
- package/.claude/scripts/update-agent-context.sh +806 -0
- package/.claude/scripts/validate-constitution.sh +567 -0
- package/.claude/scripts/validate-hooks.sh +487 -0
- package/.claude/scripts/validate-research.sh +332 -0
- package/.claude/scripts/validate-scope-boundary.sh +493 -0
- package/.claude/scripts/verify-setup.sh +37 -0
- package/.claude/settings.json +76 -0
- package/.claude/skills/_reference-implementations/README.md +96 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/SKILL.md +302 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/architecture-overview.md +451 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/async-and-errors.md +307 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/complete-examples.md +638 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/configuration.md +275 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/database-patterns.md +224 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/middleware-guide.md +213 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/routing-and-controllers.md +756 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/sentry-and-monitoring.md +336 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/services-and-repositories.md +789 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/testing-guide.md +235 -0
- package/.claude/skills/_reference-implementations/backend-express-prisma/resources/validation-patterns.md +754 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/SKILL.md +399 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/common-patterns.md +331 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/complete-examples.md +872 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/component-patterns.md +502 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/data-fetching.md +767 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/file-organization.md +502 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/loading-and-error-states.md +501 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/performance.md +406 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/routing-guide.md +364 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/styling-guide.md +428 -0
- package/.claude/skills/_reference-implementations/frontend-react-mui/resources/typescript-standards.md +418 -0
- package/.claude/skills/cc-devflow-orchestrator/SKILL.md +229 -0
- package/.claude/skills/constitution-guardian/SKILL.md +306 -0
- package/.claude/skills/devflow-constitution-quick-ref/SKILL.md +374 -0
- package/.claude/skills/devflow-file-standards/SKILL.md +353 -0
- package/.claude/skills/devflow-tdd-enforcer/SKILL.md +192 -0
- package/.claude/skills/skill-developer/ADVANCED.md +197 -0
- package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +306 -0
- package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +152 -0
- package/.claude/skills/skill-developer/SKILL.md +426 -0
- package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +315 -0
- package/.claude/skills/skill-developer/TRIGGER_TYPES.md +305 -0
- package/.claude/skills/skill-developer/TROUBLESHOOTING.md +514 -0
- package/.claude/skills/skill-rules.json +213 -0
- package/.claude/tests/README.md +300 -0
- package/.claude/tests/TODO.md +69 -0
- package/.claude/tests/__pycache__/test_analyze_upgrade_impact.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_consolidate_research.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_export_contracts.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_extract_data_model.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_generate_quickstart.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/__pycache__/test_generate_research_tasks.cpython-311-pytest-7.2.2.pyc +0 -0
- package/.claude/tests/constitution/run_all_constitution_tests.sh +111 -0
- package/.claude/tests/constitution/test_agent_assignment.sh +207 -0
- package/.claude/tests/constitution/test_article_coverage.sh +201 -0
- package/.claude/tests/constitution/test_template_completeness.sh +150 -0
- package/.claude/tests/constitution/test_version_consistency.sh +120 -0
- package/.claude/tests/fixtures/spec_delta_full.md +16 -0
- package/.claude/tests/fixtures/tasks_progress_sample.md +5 -0
- package/.claude/tests/run-all-tests.sh +229 -0
- package/.claude/tests/scripts/run.sh +30 -0
- package/.claude/tests/scripts/test-framework.sh +128 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh +511 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak +504 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak2 +505 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak3 +506 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak4 +507 -0
- package/.claude/tests/scripts/test_check_prerequisites.sh.bak5 +508 -0
- package/.claude/tests/scripts/test_check_task_status.sh +499 -0
- package/.claude/tests/scripts/test_common.sh +244 -0
- package/.claude/tests/scripts/test_generate_status_report.sh +71 -0
- package/.claude/tests/scripts/test_mark_task_complete.sh +441 -0
- package/.claude/tests/scripts/test_mark_task_complete.sh.backup +410 -0
- package/.claude/tests/scripts/test_recover_workflow.sh +304 -0
- package/.claude/tests/scripts/test_setup_epic.sh +437 -0
- package/.claude/tests/scripts/test_sync_task_marks.sh +196 -0
- package/.claude/tests/scripts/test_validate_constitution.sh +74 -0
- package/.claude/tests/scripts/test_validate_research.sh +462 -0
- package/.claude/tests/slugify.bats +82 -0
- package/.claude/tests/test-framework.sh +732 -0
- package/.claude/tests/test_analyze_upgrade_impact.py +34 -0
- package/.claude/tests/test_consolidate_research.py +48 -0
- package/.claude/tests/test_export_contracts.py +43 -0
- package/.claude/tests/test_extract_data_model.py +33 -0
- package/.claude/tests/test_generate_quickstart.py +50 -0
- package/.claude/tests/test_generate_research_tasks.py +52 -0
- package/.claude/tsc-cache/6e64f818-6398-49ca-8623-581a9af85c44/edited-files.log +1 -0
- package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/affected-repos.txt +1 -0
- package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/edited-files.log +1 -0
- package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/affected-repos.txt +1 -0
- package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/edited-files.log +1 -0
- package/CHANGELOG.md +507 -0
- package/LICENSE +21 -0
- package/README.md +534 -0
- package/README.zh-CN.md +530 -0
- package/bin/adapt.js +240 -0
- package/bin/cc-devflow-cli.js +185 -0
- package/bin/cc-devflow.js +78 -0
- package/config/adapters.yml +5 -0
- package/config/schema/adapters.schema.json +44 -0
- package/docs/CLAUDE.md +26 -0
- package/docs/commands/README.md +61 -0
- package/docs/commands/README.zh-CN.md +55 -0
- package/docs/commands/core-roadmap.md +106 -0
- package/docs/commands/core-roadmap.zh-CN.md +102 -0
- package/docs/commands/core-style.md +405 -0
- package/docs/commands/core-style.zh-CN.md +405 -0
- package/docs/commands/flow-init.md +134 -0
- package/docs/commands/flow-init.zh-CN.md +163 -0
- package/docs/commands/flow-new.md +274 -0
- package/docs/commands/flow-new.zh-CN.md +270 -0
- package/docs/guides/getting-started.md +204 -0
- package/docs/guides/getting-started.zh-CN.md +152 -0
- package/lib/adapters/adapter-interface.js +57 -0
- package/lib/adapters/claude-adapter.js +74 -0
- package/lib/adapters/codex-adapter.js +40 -0
- package/lib/adapters/config-validator.js +68 -0
- package/lib/adapters/logger.js +42 -0
- package/lib/adapters/registry.js +153 -0
- package/lib/compiler/CLAUDE.md +92 -0
- package/lib/compiler/__tests__/drift.test.js +215 -0
- package/lib/compiler/__tests__/errors.test.js +184 -0
- package/lib/compiler/__tests__/incremental.test.js +174 -0
- package/lib/compiler/__tests__/integration.test.js +174 -0
- package/lib/compiler/__tests__/manifest.test.js +233 -0
- package/lib/compiler/__tests__/parser.test.js +456 -0
- package/lib/compiler/__tests__/schemas.test.js +301 -0
- package/lib/compiler/__tests__/skills-registry.test.js +125 -0
- package/lib/compiler/__tests__/transformer.test.js +286 -0
- package/lib/compiler/emitters/antigravity-emitter.js +171 -0
- package/lib/compiler/emitters/base-emitter.js +73 -0
- package/lib/compiler/emitters/codex-emitter.js +52 -0
- package/lib/compiler/emitters/cursor-emitter.js +31 -0
- package/lib/compiler/emitters/index.js +50 -0
- package/lib/compiler/emitters/qwen-emitter.js +39 -0
- package/lib/compiler/errors.js +119 -0
- package/lib/compiler/index.js +256 -0
- package/lib/compiler/manifest.js +242 -0
- package/lib/compiler/parser.js +258 -0
- package/lib/compiler/platforms.js +113 -0
- package/lib/compiler/resource-copier.js +320 -0
- package/lib/compiler/rules-emitters/__tests__/antigravity-rules-emitter.test.js +191 -0
- package/lib/compiler/rules-emitters/__tests__/codex-rules-emitter.test.js +109 -0
- package/lib/compiler/rules-emitters/__tests__/cursor-rules-emitter.test.js +123 -0
- package/lib/compiler/rules-emitters/__tests__/qwen-rules-emitter.test.js +123 -0
- package/lib/compiler/rules-emitters/antigravity-rules-emitter.js +253 -0
- package/lib/compiler/rules-emitters/base-rules-emitter.js +83 -0
- package/lib/compiler/rules-emitters/codex-rules-emitter.js +116 -0
- package/lib/compiler/rules-emitters/cursor-rules-emitter.js +98 -0
- package/lib/compiler/rules-emitters/index.js +71 -0
- package/lib/compiler/rules-emitters/qwen-rules-emitter.js +70 -0
- package/lib/compiler/schemas.js +144 -0
- package/lib/compiler/skills-registry.js +225 -0
- package/lib/compiler/transformer.js +236 -0
- package/package.json +50 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# shellcheck disable=SC2312
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
usage() {
|
|
7
|
+
cat <<'USAGE'
|
|
8
|
+
Usage: scripts/bash/consolidate-research.sh <requirement-dir>
|
|
9
|
+
|
|
10
|
+
Aggregates research findings into research/research.md using the standard
|
|
11
|
+
Decision/Rationale/Alternatives format. Existing files are overwritten.
|
|
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 sys
|
|
38
|
+
from datetime import datetime, timezone
|
|
39
|
+
from pathlib import Path
|
|
40
|
+
|
|
41
|
+
req_dir = Path(sys.argv[1]).resolve()
|
|
42
|
+
research_dir = req_dir / "research"
|
|
43
|
+
research_dir.mkdir(exist_ok=True, parents=True)
|
|
44
|
+
summary_path = research_dir / "research.md"
|
|
45
|
+
tasks_path = research_dir / "tasks.json"
|
|
46
|
+
|
|
47
|
+
def detect_feature_title() -> str:
|
|
48
|
+
readme = req_dir / "README.md"
|
|
49
|
+
if readme.exists():
|
|
50
|
+
for line in readme.read_text(encoding="utf-8").splitlines():
|
|
51
|
+
line = line.strip("# ").strip()
|
|
52
|
+
if line:
|
|
53
|
+
return line
|
|
54
|
+
return req_dir.name
|
|
55
|
+
|
|
56
|
+
def validate_task_completeness(tasks: list) -> tuple[int, int, list]:
|
|
57
|
+
"""Validate tasks have decision/rationale/alternatives fields.
|
|
58
|
+
|
|
59
|
+
Returns:
|
|
60
|
+
(total_tasks, completed_tasks, incomplete_task_ids)
|
|
61
|
+
"""
|
|
62
|
+
total = len(tasks)
|
|
63
|
+
completed = 0
|
|
64
|
+
incomplete = []
|
|
65
|
+
|
|
66
|
+
for task in tasks:
|
|
67
|
+
task_id = task.get("id", "???")
|
|
68
|
+
decision = task.get("decision", "")
|
|
69
|
+
rationale = task.get("rationale", "")
|
|
70
|
+
alternatives = task.get("alternatives", "")
|
|
71
|
+
|
|
72
|
+
# 字段完整的条件:非空 + 不是 TODO 占位符
|
|
73
|
+
has_decision = bool(decision and decision.strip() and decision != "TODO - fill decision outcome")
|
|
74
|
+
has_rationale = bool(rationale and rationale.strip() and rationale != "TODO - explain why this decision was chosen")
|
|
75
|
+
has_alternatives = bool(alternatives and alternatives.strip() and alternatives != "TODO - list evaluated alternatives")
|
|
76
|
+
|
|
77
|
+
if has_decision and has_rationale and has_alternatives:
|
|
78
|
+
completed += 1
|
|
79
|
+
else:
|
|
80
|
+
incomplete.append(task_id)
|
|
81
|
+
|
|
82
|
+
return total, completed, incomplete
|
|
83
|
+
|
|
84
|
+
feature_title = detect_feature_title()
|
|
85
|
+
generated_at = datetime.now(timezone.utc).isoformat()
|
|
86
|
+
|
|
87
|
+
tasks_data = {}
|
|
88
|
+
if tasks_path.exists():
|
|
89
|
+
try:
|
|
90
|
+
tasks_data = json.loads(tasks_path.read_text(encoding="utf-8"))
|
|
91
|
+
except json.JSONDecodeError:
|
|
92
|
+
print(f"ERROR: {tasks_path} is not valid JSON", file=sys.stderr)
|
|
93
|
+
sys.exit(1)
|
|
94
|
+
|
|
95
|
+
tasks = tasks_data.get("tasks", [])
|
|
96
|
+
|
|
97
|
+
# Validate task completion
|
|
98
|
+
if tasks:
|
|
99
|
+
total, completed, incomplete = validate_task_completeness(tasks)
|
|
100
|
+
completion_rate = completed / total if total > 0 else 0
|
|
101
|
+
|
|
102
|
+
print(f"Research Tasks: {completed}/{total} completed ({completion_rate:.0%})", file=sys.stderr)
|
|
103
|
+
|
|
104
|
+
if completion_rate < 0.5:
|
|
105
|
+
print(f"WARNING: Research incomplete. Only {completed}/{total} tasks have decisions.", file=sys.stderr)
|
|
106
|
+
print(f"Incomplete tasks: {', '.join(incomplete)}", file=sys.stderr)
|
|
107
|
+
print(f"Generated research.md will contain TODO placeholders.", file=sys.stderr)
|
|
108
|
+
print(f"Fix: Add decision/rationale/alternatives fields to tasks.json", file=sys.stderr)
|
|
109
|
+
|
|
110
|
+
sources = []
|
|
111
|
+
for path in research_dir.rglob("*.md"):
|
|
112
|
+
if path.name in {"research.md"}:
|
|
113
|
+
continue
|
|
114
|
+
sources.append(str(path.relative_to(req_dir)))
|
|
115
|
+
|
|
116
|
+
lines = []
|
|
117
|
+
lines.append(f"# Research Summary — {feature_title}")
|
|
118
|
+
lines.append("")
|
|
119
|
+
lines.append(f"Generated: {generated_at}")
|
|
120
|
+
lines.append("")
|
|
121
|
+
lines.append("## Decisions")
|
|
122
|
+
lines.append("")
|
|
123
|
+
|
|
124
|
+
if not tasks:
|
|
125
|
+
lines.append("_No research tasks detected. Populate research/tasks.json to track clarifications._")
|
|
126
|
+
else:
|
|
127
|
+
for task in tasks:
|
|
128
|
+
task_id = task.get("id", "R???")
|
|
129
|
+
prompt = task.get("prompt", "(unknown prompt)")
|
|
130
|
+
lines.append(f"### {task_id} — {prompt}")
|
|
131
|
+
|
|
132
|
+
# 处理空字符串,替换为 TODO 占位符
|
|
133
|
+
decision = task.get("decision", "")
|
|
134
|
+
rationale = task.get("rationale", "")
|
|
135
|
+
alternatives = task.get("alternatives", "")
|
|
136
|
+
|
|
137
|
+
decision = decision.strip() if decision.strip() else "TODO - fill decision outcome"
|
|
138
|
+
rationale = rationale.strip() if rationale.strip() else "TODO - explain why this decision was chosen"
|
|
139
|
+
alternatives = alternatives.strip() if alternatives.strip() else "TODO - list evaluated alternatives"
|
|
140
|
+
|
|
141
|
+
lines.append(f"- Decision: {decision}")
|
|
142
|
+
lines.append(f"- Rationale: {rationale}")
|
|
143
|
+
lines.append(f"- Alternatives considered: {alternatives}")
|
|
144
|
+
source = task.get("source")
|
|
145
|
+
if source:
|
|
146
|
+
lines.append(f"- Source: {source}")
|
|
147
|
+
lines.append("")
|
|
148
|
+
|
|
149
|
+
lines.append("## Source Library")
|
|
150
|
+
lines.append("")
|
|
151
|
+
if sources:
|
|
152
|
+
for src in sorted(sources):
|
|
153
|
+
lines.append(f"- {src}")
|
|
154
|
+
else:
|
|
155
|
+
lines.append("_No research source files detected yet._")
|
|
156
|
+
|
|
157
|
+
summary_path.write_text("\n".join(lines) + "\n", encoding="utf-8")
|
|
158
|
+
|
|
159
|
+
# Post-write validation: detect TODO placeholders
|
|
160
|
+
content = summary_path.read_text(encoding="utf-8")
|
|
161
|
+
todo_count = content.count("TODO")
|
|
162
|
+
placeholder_count = content.count("{{") + content.count("}}")
|
|
163
|
+
|
|
164
|
+
if todo_count > 0 or placeholder_count > 0:
|
|
165
|
+
print(f"⚠️ WARNING: Generated research.md contains quality issues:", file=sys.stderr)
|
|
166
|
+
if todo_count > 0:
|
|
167
|
+
print(f" - {todo_count} TODO marker(s) found", file=sys.stderr)
|
|
168
|
+
if placeholder_count > 0:
|
|
169
|
+
print(f" - Placeholder markers {{{{ }}}} found", file=sys.stderr)
|
|
170
|
+
print(f"", file=sys.stderr)
|
|
171
|
+
print(f"This will cause validate-research.sh to FAIL.", file=sys.stderr)
|
|
172
|
+
print(f"", file=sys.stderr)
|
|
173
|
+
print(f"Fix Options:", file=sys.stderr)
|
|
174
|
+
print(f" 1. Update tasks.json with actual decision/rationale/alternatives", file=sys.stderr)
|
|
175
|
+
print(f" 2. Manually edit {summary_path.relative_to(req_dir)}", file=sys.stderr)
|
|
176
|
+
print(f" 3. Use .claude/docs/templates/RESEARCH_TEMPLATE.md as reference", file=sys.stderr)
|
|
177
|
+
print(f"", file=sys.stderr)
|
|
178
|
+
print(f"Wrote research summary → {summary_path} (WITH WARNINGS)", file=sys.stderr)
|
|
179
|
+
else:
|
|
180
|
+
print(f"✅ Wrote research summary → {summary_path}", file=sys.stderr)
|
|
181
|
+
print(f" Quality check: No TODO/PLACEHOLDER markers detected", file=sys.stderr)
|
|
182
|
+
PY
|
|
@@ -0,0 +1,426 @@
|
|
|
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 (for git branch)
|
|
16
|
+
# --description DESC Brief description (optional)
|
|
17
|
+
# --skip-git Skip git branch creation
|
|
18
|
+
# --interactive, -i Interactive mode (prompts for inputs)
|
|
19
|
+
# --json Output in JSON format
|
|
20
|
+
# --help, -h Show help message
|
|
21
|
+
#
|
|
22
|
+
# EXAMPLES:
|
|
23
|
+
# # Create requirement with title
|
|
24
|
+
# ./create-requirement.sh REQ-123 --title "User authentication"
|
|
25
|
+
#
|
|
26
|
+
# # Interactive mode
|
|
27
|
+
# ./create-requirement.sh --interactive
|
|
28
|
+
#
|
|
29
|
+
# # Create BUG structure
|
|
30
|
+
# ./create-requirement.sh BUG-456 --title "Fix login issue" --skip-git
|
|
31
|
+
#
|
|
32
|
+
# # JSON output for automation
|
|
33
|
+
# ./create-requirement.sh REQ-123 --title "API Gateway" --json
|
|
34
|
+
|
|
35
|
+
set -e
|
|
36
|
+
|
|
37
|
+
# Parse command line arguments
|
|
38
|
+
REQ_ID=""
|
|
39
|
+
TITLE=""
|
|
40
|
+
DESCRIPTION=""
|
|
41
|
+
SKIP_GIT=false
|
|
42
|
+
INTERACTIVE=false
|
|
43
|
+
JSON_MODE=false
|
|
44
|
+
AUTO_ID=false
|
|
45
|
+
|
|
46
|
+
while [[ $# -gt 0 ]]; do
|
|
47
|
+
case "$1" in
|
|
48
|
+
--title)
|
|
49
|
+
TITLE="$2"
|
|
50
|
+
shift 2
|
|
51
|
+
;;
|
|
52
|
+
--description)
|
|
53
|
+
DESCRIPTION="$2"
|
|
54
|
+
shift 2
|
|
55
|
+
;;
|
|
56
|
+
--skip-git)
|
|
57
|
+
SKIP_GIT=true
|
|
58
|
+
shift
|
|
59
|
+
;;
|
|
60
|
+
--interactive|-i)
|
|
61
|
+
INTERACTIVE=true
|
|
62
|
+
shift
|
|
63
|
+
;;
|
|
64
|
+
--json)
|
|
65
|
+
JSON_MODE=true
|
|
66
|
+
shift
|
|
67
|
+
;;
|
|
68
|
+
--auto-id)
|
|
69
|
+
AUTO_ID=true
|
|
70
|
+
shift
|
|
71
|
+
;;
|
|
72
|
+
--help|-h)
|
|
73
|
+
cat << 'EOF'
|
|
74
|
+
Usage: create-requirement.sh [REQ_ID] [OPTIONS]
|
|
75
|
+
|
|
76
|
+
Create new requirement or BUG structure for cc-devflow.
|
|
77
|
+
|
|
78
|
+
ARGUMENTS:
|
|
79
|
+
REQ_ID Requirement ID (REQ-XXX or BUG-XXX format)
|
|
80
|
+
Optional if --interactive mode is used
|
|
81
|
+
|
|
82
|
+
OPTIONS:
|
|
83
|
+
--title TITLE Requirement title (for git branch naming)
|
|
84
|
+
--description DESC Brief description (optional)
|
|
85
|
+
--skip-git Skip git branch creation
|
|
86
|
+
--interactive, -i Interactive mode (prompts for inputs)
|
|
87
|
+
--json Output results in JSON format
|
|
88
|
+
--auto-id Auto-select next available REQ-ID when missing or duplicated
|
|
89
|
+
--help, -h Show this help message
|
|
90
|
+
|
|
91
|
+
EXAMPLES:
|
|
92
|
+
# Create requirement with title
|
|
93
|
+
./create-requirement.sh REQ-123 --title "User authentication"
|
|
94
|
+
|
|
95
|
+
# Interactive mode
|
|
96
|
+
./create-requirement.sh --interactive
|
|
97
|
+
|
|
98
|
+
# Create BUG structure
|
|
99
|
+
./create-requirement.sh BUG-456 --title "Fix login issue"
|
|
100
|
+
|
|
101
|
+
# JSON output
|
|
102
|
+
./create-requirement.sh REQ-123 --title "API Gateway" --json
|
|
103
|
+
|
|
104
|
+
STRUCTURE CREATED:
|
|
105
|
+
Requirements (REQ-XXX):
|
|
106
|
+
devflow/requirements/REQ-XXX/
|
|
107
|
+
├── research/ # External research materials
|
|
108
|
+
├── EXECUTION_LOG.md # Event log
|
|
109
|
+
└── orchestration_status.json # Status tracking
|
|
110
|
+
|
|
111
|
+
BUG Fixes (BUG-XXX):
|
|
112
|
+
devflow/bugs/BUG-XXX/
|
|
113
|
+
├── EXECUTION_LOG.md
|
|
114
|
+
└── status.json
|
|
115
|
+
|
|
116
|
+
GIT BRANCH:
|
|
117
|
+
- Requirements: feature/REQ-XXX-title
|
|
118
|
+
- BUG Fixes: bugfix/BUG-XXX-title
|
|
119
|
+
|
|
120
|
+
EOF
|
|
121
|
+
exit 0
|
|
122
|
+
;;
|
|
123
|
+
-*)
|
|
124
|
+
echo "ERROR: Unknown option '$1'. Use --help for usage information." >&2
|
|
125
|
+
exit 1
|
|
126
|
+
;;
|
|
127
|
+
*)
|
|
128
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
129
|
+
REQ_ID="$1"
|
|
130
|
+
else
|
|
131
|
+
echo "ERROR: Too many arguments. Use --help for usage information." >&2
|
|
132
|
+
exit 1
|
|
133
|
+
fi
|
|
134
|
+
shift
|
|
135
|
+
;;
|
|
136
|
+
esac
|
|
137
|
+
done
|
|
138
|
+
|
|
139
|
+
# Source common functions
|
|
140
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
141
|
+
source "$SCRIPT_DIR/common.sh"
|
|
142
|
+
REPO_ROOT=$(get_repo_root)
|
|
143
|
+
|
|
144
|
+
# Interactive mode
|
|
145
|
+
if $INTERACTIVE; then
|
|
146
|
+
if ! $JSON_MODE; then
|
|
147
|
+
echo "=== Create New Requirement ==="
|
|
148
|
+
echo ""
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Prompt for requirement ID if not provided
|
|
152
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
153
|
+
suggested_req_id=$(next_available_req_id "$REPO_ROOT")
|
|
154
|
+
read -p "Requirement ID (REQ-XXX or BUG-XXX) [${suggested_req_id}]: " input_req_id
|
|
155
|
+
input_req_id=$(echo "${input_req_id}" | tr '[:lower:]' '[:upper:]')
|
|
156
|
+
if [[ -z "$input_req_id" ]]; then
|
|
157
|
+
AUTO_ID=true
|
|
158
|
+
REQ_ID="$suggested_req_id"
|
|
159
|
+
else
|
|
160
|
+
REQ_ID="$input_req_id"
|
|
161
|
+
fi
|
|
162
|
+
fi
|
|
163
|
+
|
|
164
|
+
# Prompt for title if not provided
|
|
165
|
+
if [[ -z "$TITLE" ]]; then
|
|
166
|
+
read -p "Requirement Title: " TITLE
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# Prompt for description
|
|
170
|
+
if [[ -z "$DESCRIPTION" ]]; then
|
|
171
|
+
read -p "Brief Description (optional): " DESCRIPTION
|
|
172
|
+
fi
|
|
173
|
+
|
|
174
|
+
# Prompt for git branch creation
|
|
175
|
+
if ! $SKIP_GIT && has_git; then
|
|
176
|
+
read -p "Create git branch? (y/n): " create_branch
|
|
177
|
+
if [[ "$create_branch" != "y" && "$create_branch" != "Y" ]]; then
|
|
178
|
+
SKIP_GIT=true
|
|
179
|
+
fi
|
|
180
|
+
fi
|
|
181
|
+
fi
|
|
182
|
+
|
|
183
|
+
# Ensure requirement ID is set, auto-select when allowed
|
|
184
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
185
|
+
AUTO_ID=true
|
|
186
|
+
REQ_ID=$(next_available_req_id "$REPO_ROOT")
|
|
187
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
188
|
+
echo "ERROR: Unable to determine next requirement ID" >&2
|
|
189
|
+
exit 1
|
|
190
|
+
fi
|
|
191
|
+
if ! $JSON_MODE; then
|
|
192
|
+
echo "Auto-selected requirement ID: $REQ_ID" >&2
|
|
193
|
+
fi
|
|
194
|
+
fi
|
|
195
|
+
|
|
196
|
+
# Normalize requirement ID to uppercase
|
|
197
|
+
REQ_ID=$(echo "$REQ_ID" | tr '[:lower:]' '[:upper:]')
|
|
198
|
+
|
|
199
|
+
# Validate requirement ID format
|
|
200
|
+
validate_req_id "$REQ_ID" || exit 1
|
|
201
|
+
|
|
202
|
+
# Resolve conflicts when requirement ID already exists
|
|
203
|
+
if req_id_in_use "$REPO_ROOT" "$REQ_ID"; then
|
|
204
|
+
if $AUTO_ID; then
|
|
205
|
+
original_req_id="$REQ_ID"
|
|
206
|
+
while req_id_in_use "$REPO_ROOT" "$REQ_ID"; do
|
|
207
|
+
next_candidate=$(next_available_req_id "$REPO_ROOT")
|
|
208
|
+
if [[ "$next_candidate" == "$REQ_ID" ]]; then
|
|
209
|
+
next_candidate="REQ-$(date +%Y%m%d%H%M%S)"
|
|
210
|
+
fi
|
|
211
|
+
REQ_ID="$next_candidate"
|
|
212
|
+
done
|
|
213
|
+
if [[ "$REQ_ID" != "$original_req_id" ]] && ! $JSON_MODE; then
|
|
214
|
+
echo "Requirement ID in use; switched to $REQ_ID" >&2
|
|
215
|
+
fi
|
|
216
|
+
else
|
|
217
|
+
suggested_req_id=$(next_available_req_id "$REPO_ROOT")
|
|
218
|
+
conflict_dir=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
|
|
219
|
+
echo "ERROR: Requirement directory already exists: $conflict_dir" >&2
|
|
220
|
+
if [[ "$suggested_req_id" != "$REQ_ID" ]]; then
|
|
221
|
+
echo "Suggested next available ID: $suggested_req_id" >&2
|
|
222
|
+
fi
|
|
223
|
+
exit 1
|
|
224
|
+
fi
|
|
225
|
+
fi
|
|
226
|
+
|
|
227
|
+
# Get requirement type and directory
|
|
228
|
+
REQ_TYPE=$(get_req_type "$REQ_ID")
|
|
229
|
+
REQ_DIR=$(get_req_dir "$REPO_ROOT" "$REQ_ID")
|
|
230
|
+
|
|
231
|
+
# Create directory structure
|
|
232
|
+
if ! $JSON_MODE; then
|
|
233
|
+
echo "Creating requirement structure at $REQ_DIR..." >&2
|
|
234
|
+
fi
|
|
235
|
+
|
|
236
|
+
# Create directories
|
|
237
|
+
mkdir -p "$REQ_DIR/research"
|
|
238
|
+
|
|
239
|
+
# Initialize EXECUTION_LOG.md
|
|
240
|
+
cat > "$REQ_DIR/EXECUTION_LOG.md" <<EOF
|
|
241
|
+
# Execution Log: $REQ_ID
|
|
242
|
+
|
|
243
|
+
**Title**: ${TITLE:-"To be defined"}
|
|
244
|
+
**Type**: $REQ_TYPE
|
|
245
|
+
**Created**: $(get_beijing_time_full)
|
|
246
|
+
|
|
247
|
+
EOF
|
|
248
|
+
|
|
249
|
+
if [[ -n "$DESCRIPTION" ]]; then
|
|
250
|
+
cat >> "$REQ_DIR/EXECUTION_LOG.md" <<EOF
|
|
251
|
+
## Description
|
|
252
|
+
$DESCRIPTION
|
|
253
|
+
|
|
254
|
+
EOF
|
|
255
|
+
fi
|
|
256
|
+
|
|
257
|
+
cat >> "$REQ_DIR/EXECUTION_LOG.md" <<'EOF'
|
|
258
|
+
## Events
|
|
259
|
+
|
|
260
|
+
EOF
|
|
261
|
+
|
|
262
|
+
# Initialize status file
|
|
263
|
+
if [[ "$REQ_TYPE" == "bug" ]]; then
|
|
264
|
+
# BUG-specific status file
|
|
265
|
+
cat > "$REQ_DIR/status.json" <<EOF
|
|
266
|
+
{
|
|
267
|
+
"bugId": "$REQ_ID",
|
|
268
|
+
"title": "${TITLE:-"To be defined"}",
|
|
269
|
+
"status": "initialized",
|
|
270
|
+
"phase": "analysis",
|
|
271
|
+
"severity": "unknown",
|
|
272
|
+
"createdAt": "$(get_beijing_time_iso)",
|
|
273
|
+
"updatedAt": "$(get_beijing_time_iso)"
|
|
274
|
+
}
|
|
275
|
+
EOF
|
|
276
|
+
else
|
|
277
|
+
# Requirement status file
|
|
278
|
+
cat > "$REQ_DIR/orchestration_status.json" <<EOF
|
|
279
|
+
{
|
|
280
|
+
"reqId": "$REQ_ID",
|
|
281
|
+
"title": "${TITLE:-"To be defined"}",
|
|
282
|
+
"status": "initialized",
|
|
283
|
+
"phase": "planning",
|
|
284
|
+
"createdAt": "$(get_beijing_time_iso)",
|
|
285
|
+
"updatedAt": "$(get_beijing_time_iso)"
|
|
286
|
+
}
|
|
287
|
+
EOF
|
|
288
|
+
fi
|
|
289
|
+
|
|
290
|
+
# Create README.md for the requirement
|
|
291
|
+
cat > "$REQ_DIR/README.md" <<EOF
|
|
292
|
+
# $REQ_ID: ${TITLE:-"To be defined"}
|
|
293
|
+
|
|
294
|
+
**Status**: Initialized
|
|
295
|
+
**Type**: $REQ_TYPE
|
|
296
|
+
**Created**: $(get_beijing_time_full)
|
|
297
|
+
|
|
298
|
+
EOF
|
|
299
|
+
|
|
300
|
+
if [[ -n "$DESCRIPTION" ]]; then
|
|
301
|
+
cat >> "$REQ_DIR/README.md" <<EOF
|
|
302
|
+
## Description
|
|
303
|
+
$DESCRIPTION
|
|
304
|
+
|
|
305
|
+
EOF
|
|
306
|
+
fi
|
|
307
|
+
|
|
308
|
+
cat >> "$REQ_DIR/README.md" <<'EOF'
|
|
309
|
+
## Documents
|
|
310
|
+
|
|
311
|
+
### Planning Phase
|
|
312
|
+
- [ ] PRD.md - Product Requirements Document
|
|
313
|
+
- [ ] EPIC.md - Epic Planning
|
|
314
|
+
- [ ] TASKS.md - Task Breakdown
|
|
315
|
+
|
|
316
|
+
### Execution Phase
|
|
317
|
+
- [ ] TEST_PLAN.md - Test Plan
|
|
318
|
+
- [ ] SECURITY_PLAN.md - Security Plan
|
|
319
|
+
- [ ] EXECUTION_LOG.md - Event Log
|
|
320
|
+
|
|
321
|
+
### Review Phase
|
|
322
|
+
- [ ] TEST_REPORT.md - Test Report
|
|
323
|
+
- [ ] SECURITY_REPORT.md - Security Report
|
|
324
|
+
- [ ] RELEASE_PLAN.md - Release Plan
|
|
325
|
+
|
|
326
|
+
## Research Materials
|
|
327
|
+
Place external research materials in `research/` directory:
|
|
328
|
+
- API documentation
|
|
329
|
+
- Design specifications
|
|
330
|
+
- Reference implementations
|
|
331
|
+
- Planning documents
|
|
332
|
+
|
|
333
|
+
## Workflow
|
|
334
|
+
1. **Planning**: Create PRD → Generate EPIC → Break down TASKS
|
|
335
|
+
2. **Development**: Implement tasks following TDD approach
|
|
336
|
+
3. **Quality**: Execute test plan and security review
|
|
337
|
+
4. **Release**: Create release plan and merge to main
|
|
338
|
+
|
|
339
|
+
EOF
|
|
340
|
+
|
|
341
|
+
# Log the creation event
|
|
342
|
+
log_event "$REQ_ID" "Requirement structure initialized"
|
|
343
|
+
|
|
344
|
+
if [[ -n "$TITLE" ]]; then
|
|
345
|
+
log_event "$REQ_ID" "Title: $TITLE"
|
|
346
|
+
fi
|
|
347
|
+
|
|
348
|
+
if [[ -n "$DESCRIPTION" ]]; then
|
|
349
|
+
log_event "$REQ_ID" "Description: $DESCRIPTION"
|
|
350
|
+
fi
|
|
351
|
+
|
|
352
|
+
# Create git branch if requested and available
|
|
353
|
+
GIT_BRANCH=""
|
|
354
|
+
if ! $SKIP_GIT && has_git; then
|
|
355
|
+
# Generate branch name from title
|
|
356
|
+
if [[ -n "$TITLE" ]]; then
|
|
357
|
+
BRANCH_SUFFIX=$(slugify "$TITLE")
|
|
358
|
+
if [[ -z "$BRANCH_SUFFIX" ]]; then
|
|
359
|
+
BRANCH_SUFFIX="new-requirement"
|
|
360
|
+
fi
|
|
361
|
+
else
|
|
362
|
+
BRANCH_SUFFIX="new-requirement"
|
|
363
|
+
fi
|
|
364
|
+
|
|
365
|
+
# Determine branch prefix based on type
|
|
366
|
+
if [[ "$REQ_TYPE" == "bug" ]]; then
|
|
367
|
+
GIT_BRANCH="bugfix/$REQ_ID-$BRANCH_SUFFIX"
|
|
368
|
+
else
|
|
369
|
+
GIT_BRANCH="feature/$REQ_ID-$BRANCH_SUFFIX"
|
|
370
|
+
fi
|
|
371
|
+
|
|
372
|
+
# Check if branch already exists
|
|
373
|
+
if git rev-parse --verify "$GIT_BRANCH" >/dev/null 2>&1; then
|
|
374
|
+
if ! $JSON_MODE; then
|
|
375
|
+
echo "WARNING: Git branch already exists: $GIT_BRANCH" >&2
|
|
376
|
+
echo "Skipping branch creation." >&2
|
|
377
|
+
fi
|
|
378
|
+
else
|
|
379
|
+
# Create and checkout new branch
|
|
380
|
+
git checkout -b "$GIT_BRANCH" >/dev/null 2>&1
|
|
381
|
+
log_event "$REQ_ID" "Created git branch: $GIT_BRANCH"
|
|
382
|
+
|
|
383
|
+
if ! $JSON_MODE; then
|
|
384
|
+
echo "Created and checked out branch: $GIT_BRANCH" >&2
|
|
385
|
+
fi
|
|
386
|
+
fi
|
|
387
|
+
|
|
388
|
+
# Set environment variable for non-branch-based workflows
|
|
389
|
+
export DEVFLOW_REQ_ID="$REQ_ID"
|
|
390
|
+
fi
|
|
391
|
+
|
|
392
|
+
# Output results
|
|
393
|
+
if $JSON_MODE; then
|
|
394
|
+
printf '{"req_id":"%s","req_type":"%s","req_dir":"%s","title":"%s","git_branch":"%s","created_at":"%s"}\n' \
|
|
395
|
+
"$REQ_ID" \
|
|
396
|
+
"$REQ_TYPE" \
|
|
397
|
+
"$REQ_DIR" \
|
|
398
|
+
"${TITLE:-""}" \
|
|
399
|
+
"${GIT_BRANCH:-""}" \
|
|
400
|
+
"$(get_beijing_time_iso)"
|
|
401
|
+
else
|
|
402
|
+
echo ""
|
|
403
|
+
echo "✅ Requirement structure created successfully!"
|
|
404
|
+
echo ""
|
|
405
|
+
echo "Requirement ID: $REQ_ID"
|
|
406
|
+
echo "Type: $REQ_TYPE"
|
|
407
|
+
echo "Directory: $REQ_DIR"
|
|
408
|
+
if [[ -n "$TITLE" ]]; then
|
|
409
|
+
echo "Title: $TITLE"
|
|
410
|
+
fi
|
|
411
|
+
if [[ -n "$GIT_BRANCH" ]]; then
|
|
412
|
+
echo "Git Branch: $GIT_BRANCH"
|
|
413
|
+
fi
|
|
414
|
+
echo ""
|
|
415
|
+
echo "Next Steps:"
|
|
416
|
+
if [[ "$REQ_TYPE" == "bug" ]]; then
|
|
417
|
+
echo " 1. Run bug-analyzer agent to analyze the BUG"
|
|
418
|
+
echo " 2. Run /flow-fix to start BUG fix workflow"
|
|
419
|
+
echo " 3. Keep EXECUTION_LOG.md updated during fixes"
|
|
420
|
+
else
|
|
421
|
+
echo " 1. Add research materials to research/ (optional)"
|
|
422
|
+
echo " 2. Run prd-writer agent to create PRD.md"
|
|
423
|
+
echo " 3. Continue with planner and subsequent flow commands"
|
|
424
|
+
fi
|
|
425
|
+
echo ""
|
|
426
|
+
fi
|