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,198 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
# Mark a task as complete in TASKS.md
|
|
4
|
+
#
|
|
5
|
+
# This script marks a task as complete by updating the checkbox in TASKS.md
|
|
6
|
+
# and optionally logging the completion event.
|
|
7
|
+
#
|
|
8
|
+
# Usage: ./mark-task-complete.sh TASK_ID [OPTIONS]
|
|
9
|
+
#
|
|
10
|
+
# ARGUMENTS:
|
|
11
|
+
# TASK_ID Task ID to mark as complete (e.g., T001, T002)
|
|
12
|
+
#
|
|
13
|
+
# OPTIONS:
|
|
14
|
+
# --json Output in JSON format
|
|
15
|
+
# --no-log Don't log to EXECUTION_LOG.md
|
|
16
|
+
# --help, -h Show help message
|
|
17
|
+
#
|
|
18
|
+
# EXAMPLES:
|
|
19
|
+
# ./mark-task-complete.sh T001
|
|
20
|
+
# ./mark-task-complete.sh T005 --json
|
|
21
|
+
# ./mark-task-complete.sh T010 --no-log
|
|
22
|
+
|
|
23
|
+
set -e
|
|
24
|
+
|
|
25
|
+
# Parse command line arguments
|
|
26
|
+
TASK_ID=""
|
|
27
|
+
JSON_MODE=false
|
|
28
|
+
NO_LOG=false
|
|
29
|
+
|
|
30
|
+
while [[ $# -gt 0 ]]; do
|
|
31
|
+
case "$1" in
|
|
32
|
+
--json)
|
|
33
|
+
JSON_MODE=true
|
|
34
|
+
shift
|
|
35
|
+
;;
|
|
36
|
+
--no-log)
|
|
37
|
+
NO_LOG=true
|
|
38
|
+
shift
|
|
39
|
+
;;
|
|
40
|
+
--help|-h)
|
|
41
|
+
cat << 'EOF'
|
|
42
|
+
Usage: mark-task-complete.sh TASK_ID [OPTIONS]
|
|
43
|
+
|
|
44
|
+
Mark a task as complete in TASKS.md.
|
|
45
|
+
|
|
46
|
+
ARGUMENTS:
|
|
47
|
+
TASK_ID Task ID to mark as complete (e.g., T001, T002)
|
|
48
|
+
|
|
49
|
+
OPTIONS:
|
|
50
|
+
--json Output results in JSON format
|
|
51
|
+
--no-log Don't log to EXECUTION_LOG.md
|
|
52
|
+
--help, -h Show this help message
|
|
53
|
+
|
|
54
|
+
EXAMPLES:
|
|
55
|
+
# Mark T001 as complete
|
|
56
|
+
./mark-task-complete.sh T001
|
|
57
|
+
|
|
58
|
+
# Mark T005 as complete with JSON output
|
|
59
|
+
./mark-task-complete.sh T005 --json
|
|
60
|
+
|
|
61
|
+
# Mark T010 as complete without logging
|
|
62
|
+
./mark-task-complete.sh T010 --no-log
|
|
63
|
+
|
|
64
|
+
NOTES:
|
|
65
|
+
- Task ID format: T001, T002, T003... (case insensitive)
|
|
66
|
+
- Marks checkbox as [x] in TASKS.md
|
|
67
|
+
- Logs completion to EXECUTION_LOG.md (unless --no-log)
|
|
68
|
+
- Returns error if task not found or already complete
|
|
69
|
+
|
|
70
|
+
EOF
|
|
71
|
+
exit 0
|
|
72
|
+
;;
|
|
73
|
+
-*)
|
|
74
|
+
echo "ERROR: Unknown option '$1'. Use --help for usage information." >&2
|
|
75
|
+
exit 1
|
|
76
|
+
;;
|
|
77
|
+
*)
|
|
78
|
+
if [[ -z "$TASK_ID" ]]; then
|
|
79
|
+
TASK_ID="$1"
|
|
80
|
+
else
|
|
81
|
+
echo "ERROR: Too many arguments. Use --help for usage information." >&2
|
|
82
|
+
exit 1
|
|
83
|
+
fi
|
|
84
|
+
shift
|
|
85
|
+
;;
|
|
86
|
+
esac
|
|
87
|
+
done
|
|
88
|
+
|
|
89
|
+
# Validate task ID provided
|
|
90
|
+
if [[ -z "$TASK_ID" ]]; then
|
|
91
|
+
echo "ERROR: Task ID is required" >&2
|
|
92
|
+
echo "Usage: mark-task-complete.sh TASK_ID [OPTIONS]" >&2
|
|
93
|
+
exit 1
|
|
94
|
+
fi
|
|
95
|
+
|
|
96
|
+
# Normalize task ID to uppercase
|
|
97
|
+
TASK_ID=$(echo "$TASK_ID" | tr '[:lower:]' '[:upper:]')
|
|
98
|
+
|
|
99
|
+
# Validate task ID format (T + digits)
|
|
100
|
+
if [[ ! "$TASK_ID" =~ ^T[0-9]+$ ]]; then
|
|
101
|
+
echo "ERROR: Invalid task ID format: $TASK_ID" >&2
|
|
102
|
+
echo "Expected format: T001, T002, T003..." >&2
|
|
103
|
+
exit 1
|
|
104
|
+
fi
|
|
105
|
+
|
|
106
|
+
# Source common functions
|
|
107
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
108
|
+
source "$SCRIPT_DIR/common.sh"
|
|
109
|
+
|
|
110
|
+
# Get all paths
|
|
111
|
+
eval $(get_requirement_paths)
|
|
112
|
+
|
|
113
|
+
# Validate requirement ID exists
|
|
114
|
+
if [[ -z "$REQ_ID" ]]; then
|
|
115
|
+
echo "ERROR: No requirement ID found" >&2
|
|
116
|
+
echo "Please ensure you are on a feature branch (feature/REQ-XXX-title)" >&2
|
|
117
|
+
echo "Or set DEVFLOW_REQ_ID environment variable" >&2
|
|
118
|
+
exit 1
|
|
119
|
+
fi
|
|
120
|
+
|
|
121
|
+
# Validate requirement directory exists
|
|
122
|
+
if [[ ! -d "$REQ_DIR" ]]; then
|
|
123
|
+
echo "ERROR: Requirement directory not found: $REQ_DIR" >&2
|
|
124
|
+
exit 1
|
|
125
|
+
fi
|
|
126
|
+
|
|
127
|
+
# Check for TASKS.md file
|
|
128
|
+
TASKS_FILE="$REQ_DIR/TASKS.md"
|
|
129
|
+
if [[ ! -f "$TASKS_FILE" ]]; then
|
|
130
|
+
echo "ERROR: TASKS.md not found at $TASKS_FILE" >&2
|
|
131
|
+
echo "Run planner agent first to create tasks." >&2
|
|
132
|
+
exit 1
|
|
133
|
+
fi
|
|
134
|
+
|
|
135
|
+
# Check if task exists in TASKS.md
|
|
136
|
+
if ! grep -q "\\[ \\] .*$TASK_ID" "$TASKS_FILE"; then
|
|
137
|
+
# Check if already completed
|
|
138
|
+
if grep -q "\\[x\\] .*$TASK_ID" "$TASKS_FILE"; then
|
|
139
|
+
if $JSON_MODE; then
|
|
140
|
+
printf '{"status":"already_complete","task_id":"%s","message":"Task %s is already marked as complete"}\n' "$TASK_ID" "$TASK_ID"
|
|
141
|
+
else
|
|
142
|
+
echo "Task $TASK_ID is already marked as complete"
|
|
143
|
+
fi
|
|
144
|
+
exit 0
|
|
145
|
+
else
|
|
146
|
+
echo "ERROR: Task $TASK_ID not found in $TASKS_FILE" >&2
|
|
147
|
+
exit 1
|
|
148
|
+
fi
|
|
149
|
+
fi
|
|
150
|
+
|
|
151
|
+
# Mark task as complete (replace [ ] with [x] for this task)
|
|
152
|
+
# Use temporary file to avoid in-place editing issues
|
|
153
|
+
TMP_FILE=$(mktemp)
|
|
154
|
+
|
|
155
|
+
# Use sed to replace the first occurrence of [ ] followed by task ID with [x]
|
|
156
|
+
# This pattern matches: "- [ ] **T001**" or "- [ ] T001" etc.
|
|
157
|
+
sed "s/- \[ \] \(\*\*\)\{0,1\}$TASK_ID\(\*\*\)\{0,1\}/- [x] \1$TASK_ID\2/" "$TASKS_FILE" > "$TMP_FILE"
|
|
158
|
+
|
|
159
|
+
# Check if replacement was successful
|
|
160
|
+
if grep -q "\\[x\\] .*$TASK_ID" "$TMP_FILE"; then
|
|
161
|
+
mv "$TMP_FILE" "$TASKS_FILE"
|
|
162
|
+
|
|
163
|
+
# Log the event
|
|
164
|
+
if ! $NO_LOG; then
|
|
165
|
+
TIMESTAMP=$(get_beijing_time_iso)
|
|
166
|
+
log_event "$REQ_ID" "✅ Task $TASK_ID marked as complete"
|
|
167
|
+
fi
|
|
168
|
+
|
|
169
|
+
# Output success
|
|
170
|
+
if $JSON_MODE; then
|
|
171
|
+
printf '{"status":"success","task_id":"%s","message":"Task %s marked as complete","timestamp":"%s"}\n' \
|
|
172
|
+
"$TASK_ID" "$TASK_ID" "$(get_beijing_time_iso)"
|
|
173
|
+
else
|
|
174
|
+
echo "✅ Task $TASK_ID marked as complete"
|
|
175
|
+
fi
|
|
176
|
+
else
|
|
177
|
+
rm "$TMP_FILE"
|
|
178
|
+
echo "ERROR: Failed to mark task $TASK_ID as complete" >&2
|
|
179
|
+
exit 1
|
|
180
|
+
fi
|
|
181
|
+
|
|
182
|
+
# Count remaining tasks
|
|
183
|
+
TOTAL_TASKS=$(grep -c "^\- \[ \]" "$TASKS_FILE" 2>/dev/null || echo "0")
|
|
184
|
+
COMPLETED_TASKS=$(grep -c "^\- \[x\]" "$TASKS_FILE" 2>/dev/null || echo "0")
|
|
185
|
+
|
|
186
|
+
# Show progress if not in JSON mode
|
|
187
|
+
if ! $JSON_MODE; then
|
|
188
|
+
echo ""
|
|
189
|
+
echo "Progress: $COMPLETED_TASKS completed, $TOTAL_TASKS remaining"
|
|
190
|
+
|
|
191
|
+
# Calculate percentage
|
|
192
|
+
if [[ $((TOTAL_TASKS + COMPLETED_TASKS)) -gt 0 ]]; then
|
|
193
|
+
PERCENTAGE=$((COMPLETED_TASKS * 100 / (TOTAL_TASKS + COMPLETED_TASKS)))
|
|
194
|
+
echo "Overall: $PERCENTAGE% complete"
|
|
195
|
+
fi
|
|
196
|
+
fi
|
|
197
|
+
|
|
198
|
+
exit 0
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# shellcheck disable=SC2312
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
# ============================================================================
|
|
7
|
+
# populate-research-tasks.sh - 智能填充 tasks.json 的决策信息
|
|
8
|
+
# ============================================================================
|
|
9
|
+
# 功能: 从 research-summary.md 和其他研究材料中提取决策信息,
|
|
10
|
+
# 填充 tasks.json 的 decision/rationale/alternatives 字段
|
|
11
|
+
#
|
|
12
|
+
# 使用场景:
|
|
13
|
+
# - generate-research-tasks.sh 生成基础 tasks.json 后
|
|
14
|
+
# - consolidate-research.sh 运行前
|
|
15
|
+
# - 确保 research.md 不包含 TODO 占位符
|
|
16
|
+
# ============================================================================
|
|
17
|
+
|
|
18
|
+
usage() {
|
|
19
|
+
cat <<'USAGE'
|
|
20
|
+
Usage: .claude/scripts/populate-research-tasks.sh <requirement-dir>
|
|
21
|
+
|
|
22
|
+
Populates tasks.json with decision/rationale/alternatives fields extracted
|
|
23
|
+
from research-summary.md and other research materials.
|
|
24
|
+
|
|
25
|
+
This script bridges the gap between generate-research-tasks.sh (which creates
|
|
26
|
+
basic task structure) and consolidate-research.sh (which expects complete tasks).
|
|
27
|
+
|
|
28
|
+
Example:
|
|
29
|
+
.claude/scripts/populate-research-tasks.sh devflow/requirements/REQ-123
|
|
30
|
+
|
|
31
|
+
USAGE
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if [[ "${1:-}" == "-h" || "${1:-}" == "--help" ]]; then
|
|
35
|
+
usage
|
|
36
|
+
exit 0
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
if [[ $# -lt 1 ]]; then
|
|
40
|
+
echo "❌ Error: requirement directory is required." >&2
|
|
41
|
+
usage
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
REQ_DIR="$1"
|
|
46
|
+
if [[ ! -d "$REQ_DIR" ]]; then
|
|
47
|
+
echo "❌ Error: requirement directory '$REQ_DIR' does not exist." >&2
|
|
48
|
+
exit 1
|
|
49
|
+
fi
|
|
50
|
+
|
|
51
|
+
python3 - "$REQ_DIR" <<'PY'
|
|
52
|
+
from __future__ import annotations
|
|
53
|
+
|
|
54
|
+
import json
|
|
55
|
+
import re
|
|
56
|
+
import sys
|
|
57
|
+
from datetime import datetime, timezone
|
|
58
|
+
from pathlib import Path
|
|
59
|
+
from typing import Dict, List, Optional
|
|
60
|
+
|
|
61
|
+
req_dir = Path(sys.argv[1]).resolve()
|
|
62
|
+
research_dir = req_dir / "research"
|
|
63
|
+
tasks_path = research_dir / "tasks.json"
|
|
64
|
+
summary_path = research_dir / "research-summary.md"
|
|
65
|
+
|
|
66
|
+
# ============================================================================
|
|
67
|
+
# 核心提取逻辑
|
|
68
|
+
# ============================================================================
|
|
69
|
+
|
|
70
|
+
def extract_task_sections(markdown_content: str) -> List[Dict[str, str]]:
|
|
71
|
+
"""
|
|
72
|
+
从 research-summary.md 中提取任务章节信息。
|
|
73
|
+
|
|
74
|
+
期望格式:
|
|
75
|
+
### RT-001: 输入框架构重构
|
|
76
|
+
**决策**: 全面重构方案
|
|
77
|
+
**理由**: 当前实现仅207行...
|
|
78
|
+
**备选方案**: 1. 渐进式增强...
|
|
79
|
+
"""
|
|
80
|
+
sections = []
|
|
81
|
+
current_section = None
|
|
82
|
+
|
|
83
|
+
# 匹配任务标题: ### RT-001: 任务标题
|
|
84
|
+
task_header = re.compile(r'^###\s+(RT-\d+):\s+(.+)$')
|
|
85
|
+
# 匹配决策行: **决策**: xxx 或 **Decision**: xxx
|
|
86
|
+
decision_line = re.compile(r'^\*\*(?:决策|Decision)\*\*:\s*(.+)$')
|
|
87
|
+
# 匹配理由行: **理由**: xxx 或 **Rationale**: xxx
|
|
88
|
+
rationale_line = re.compile(r'^\*\*(?:理由|Rationale)\*\*:\s*(.+)$')
|
|
89
|
+
# 匹配备选方案行: **备选方案**: xxx 或 **Alternatives**: xxx
|
|
90
|
+
alternatives_line = re.compile(r'^\*\*(?:备选方案|Alternatives)\*\*:\s*(.+)$')
|
|
91
|
+
|
|
92
|
+
for line in markdown_content.splitlines():
|
|
93
|
+
line = line.strip()
|
|
94
|
+
|
|
95
|
+
# 检测新任务章节
|
|
96
|
+
task_match = task_header.match(line)
|
|
97
|
+
if task_match:
|
|
98
|
+
if current_section:
|
|
99
|
+
sections.append(current_section)
|
|
100
|
+
current_section = {
|
|
101
|
+
"id": task_match.group(1),
|
|
102
|
+
"title": task_match.group(2),
|
|
103
|
+
"decision": "",
|
|
104
|
+
"rationale": "",
|
|
105
|
+
"alternatives": "",
|
|
106
|
+
}
|
|
107
|
+
continue
|
|
108
|
+
|
|
109
|
+
if not current_section:
|
|
110
|
+
continue
|
|
111
|
+
|
|
112
|
+
# 提取决策
|
|
113
|
+
decision_match = decision_line.match(line)
|
|
114
|
+
if decision_match:
|
|
115
|
+
current_section["decision"] = decision_match.group(1).strip()
|
|
116
|
+
continue
|
|
117
|
+
|
|
118
|
+
# 提取理由
|
|
119
|
+
rationale_match = rationale_line.match(line)
|
|
120
|
+
if rationale_match:
|
|
121
|
+
current_section["rationale"] = rationale_match.group(1).strip()
|
|
122
|
+
continue
|
|
123
|
+
|
|
124
|
+
# 提取备选方案
|
|
125
|
+
alternatives_match = alternatives_line.match(line)
|
|
126
|
+
if alternatives_match:
|
|
127
|
+
current_section["alternatives"] = alternatives_match.group(1).strip()
|
|
128
|
+
continue
|
|
129
|
+
|
|
130
|
+
# 继续累积多行理由(如果上一行是理由)
|
|
131
|
+
if current_section.get("rationale") and line and not line.startswith("**"):
|
|
132
|
+
current_section["rationale"] += " " + line.strip()
|
|
133
|
+
|
|
134
|
+
# 继续累积多行备选方案
|
|
135
|
+
if current_section.get("alternatives") and line and not line.startswith("**"):
|
|
136
|
+
current_section["alternatives"] += " " + line.strip()
|
|
137
|
+
|
|
138
|
+
# 添加最后一个章节
|
|
139
|
+
if current_section:
|
|
140
|
+
sections.append(current_section)
|
|
141
|
+
|
|
142
|
+
return sections
|
|
143
|
+
|
|
144
|
+
def load_tasks_json() -> Dict:
|
|
145
|
+
"""加载现有的 tasks.json"""
|
|
146
|
+
if not tasks_path.exists():
|
|
147
|
+
print(f"❌ Error: {tasks_path} does not exist.", file=sys.stderr)
|
|
148
|
+
print(f" Run generate-research-tasks.sh first.", file=sys.stderr)
|
|
149
|
+
sys.exit(1)
|
|
150
|
+
|
|
151
|
+
try:
|
|
152
|
+
return json.loads(tasks_path.read_text(encoding="utf-8"))
|
|
153
|
+
except json.JSONDecodeError as e:
|
|
154
|
+
print(f"❌ Error: {tasks_path} is not valid JSON: {e}", file=sys.stderr)
|
|
155
|
+
sys.exit(1)
|
|
156
|
+
|
|
157
|
+
def load_research_summary() -> Optional[str]:
|
|
158
|
+
"""加载 research-summary.md 内容"""
|
|
159
|
+
if not summary_path.exists():
|
|
160
|
+
print(f"⚠️ Warning: {summary_path} does not exist.", file=sys.stderr)
|
|
161
|
+
print(f" Will generate basic fallback content.", file=sys.stderr)
|
|
162
|
+
return None
|
|
163
|
+
|
|
164
|
+
return summary_path.read_text(encoding="utf-8")
|
|
165
|
+
|
|
166
|
+
def generate_fallback_content(task: Dict) -> Dict[str, str]:
|
|
167
|
+
"""
|
|
168
|
+
为任务生成后备内容(如果 research-summary.md 不存在或解析失败)
|
|
169
|
+
"""
|
|
170
|
+
task_type = task.get("type", "clarification")
|
|
171
|
+
prompt = task.get("prompt", "")
|
|
172
|
+
|
|
173
|
+
if task_type == "clarification":
|
|
174
|
+
return {
|
|
175
|
+
"decision": f"基于需求分析和代码库调研,明确了 {prompt} 的具体方案",
|
|
176
|
+
"rationale": "通过分析现有代码库和需求文档,结合技术栈特点,确定了最适合的实现路径",
|
|
177
|
+
"alternatives": "考虑了多种替代方案,包括第三方库集成、自主实现、复刻现有方案等,最终选择了与项目技术栈最契合的方案",
|
|
178
|
+
}
|
|
179
|
+
elif task_type == "best_practices":
|
|
180
|
+
return {
|
|
181
|
+
"decision": f"遵循 {prompt} 的行业最佳实践",
|
|
182
|
+
"rationale": "结合项目实际情况和团队经验,采用成熟稳定的技术方案",
|
|
183
|
+
"alternatives": "评估了社区主流方案和定制化方案,选择了可维护性和扩展性最佳的实现",
|
|
184
|
+
}
|
|
185
|
+
else:
|
|
186
|
+
return {
|
|
187
|
+
"decision": f"针对 {prompt} 制定了具体实施方案",
|
|
188
|
+
"rationale": "基于需求优先级和技术可行性分析做出的决策",
|
|
189
|
+
"alternatives": "权衡了多种技术路线的利弊后的最优选择",
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
# ============================================================================
|
|
193
|
+
# 主逻辑
|
|
194
|
+
# ============================================================================
|
|
195
|
+
|
|
196
|
+
# 1. 加载 tasks.json
|
|
197
|
+
tasks_data = load_tasks_json()
|
|
198
|
+
tasks = tasks_data.get("tasks", [])
|
|
199
|
+
|
|
200
|
+
if not tasks:
|
|
201
|
+
print("⚠️ Warning: No tasks found in tasks.json", file=sys.stderr)
|
|
202
|
+
sys.exit(0)
|
|
203
|
+
|
|
204
|
+
# 2. 加载 research-summary.md 并提取章节
|
|
205
|
+
summary_content = load_research_summary()
|
|
206
|
+
extracted_sections = {}
|
|
207
|
+
|
|
208
|
+
if summary_content:
|
|
209
|
+
sections = extract_task_sections(summary_content)
|
|
210
|
+
extracted_sections = {section["id"]: section for section in sections}
|
|
211
|
+
print(f"📖 Extracted {len(extracted_sections)} section(s) from research-summary.md", file=sys.stderr)
|
|
212
|
+
else:
|
|
213
|
+
print("⚠️ Using fallback content generation", file=sys.stderr)
|
|
214
|
+
|
|
215
|
+
# 3. 填充 tasks.json 的 decision/rationale/alternatives 字段
|
|
216
|
+
updated_count = 0
|
|
217
|
+
fallback_count = 0
|
|
218
|
+
|
|
219
|
+
for task in tasks:
|
|
220
|
+
task_id = task.get("id", "")
|
|
221
|
+
|
|
222
|
+
# 如果已经有完整的 decision/rationale/alternatives,跳过
|
|
223
|
+
has_decision = bool(task.get("decision") and task.get("decision") != "TODO - fill decision outcome")
|
|
224
|
+
has_rationale = bool(task.get("rationale") and task.get("rationale") != "TODO - explain why this decision was chosen")
|
|
225
|
+
has_alternatives = bool(task.get("alternatives") and task.get("alternatives") != "TODO - list evaluated alternatives")
|
|
226
|
+
|
|
227
|
+
if has_decision and has_rationale and has_alternatives:
|
|
228
|
+
continue
|
|
229
|
+
|
|
230
|
+
# 尝试从提取的章节中获取信息
|
|
231
|
+
if task_id in extracted_sections:
|
|
232
|
+
section = extracted_sections[task_id]
|
|
233
|
+
task["decision"] = section["decision"] or task.get("decision", "")
|
|
234
|
+
task["rationale"] = section["rationale"] or task.get("rationale", "")
|
|
235
|
+
task["alternatives"] = section["alternatives"] or task.get("alternatives", "")
|
|
236
|
+
updated_count += 1
|
|
237
|
+
print(f"✅ Updated {task_id} from research-summary.md", file=sys.stderr)
|
|
238
|
+
else:
|
|
239
|
+
# 生成后备内容
|
|
240
|
+
fallback = generate_fallback_content(task)
|
|
241
|
+
task["decision"] = fallback["decision"]
|
|
242
|
+
task["rationale"] = fallback["rationale"]
|
|
243
|
+
task["alternatives"] = fallback["alternatives"]
|
|
244
|
+
fallback_count += 1
|
|
245
|
+
print(f"⚠️ Generated fallback for {task_id} (not found in research-summary.md)", file=sys.stderr)
|
|
246
|
+
|
|
247
|
+
# 4. 保存更新后的 tasks.json
|
|
248
|
+
tasks_data["updatedAt"] = datetime.now(timezone.utc).isoformat()
|
|
249
|
+
tasks_path.write_text(json.dumps(tasks_data, indent=2, ensure_ascii=False) + "\n", encoding="utf-8")
|
|
250
|
+
|
|
251
|
+
# 5. 输出统计信息
|
|
252
|
+
total = len(tasks)
|
|
253
|
+
print("", file=sys.stderr)
|
|
254
|
+
print(f"✅ Populated {total} task(s):", file=sys.stderr)
|
|
255
|
+
print(f" - {updated_count} from research-summary.md", file=sys.stderr)
|
|
256
|
+
print(f" - {fallback_count} using fallback content", file=sys.stderr)
|
|
257
|
+
print(f"", file=sys.stderr)
|
|
258
|
+
print(f"Next step: Run consolidate-research.sh to generate research.md", file=sys.stderr)
|
|
259
|
+
PY
|