cc-devflow 2.4.6 → 4.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/CLAUDE.md +1065 -48
- package/.claude/agents/dev-implementer.md +195 -0
- package/.claude/commands/{flow-archive.md → flow/archive.md} +46 -11
- package/.claude/commands/flow/context.md +150 -0
- package/.claude/commands/flow/delta.md +245 -0
- package/.claude/commands/{flow-dev.md → flow/dev.md} +112 -11
- package/.claude/commands/flow/init.md +45 -0
- package/.claude/commands/flow/quality.md +159 -0
- package/.claude/commands/flow/spec.md +186 -0
- package/.claude/commands/flow/workspace.md +146 -0
- package/.claude/commands/{cancel-ralph.md → util/cancel-ralph.md} +1 -0
- package/.claude/config/quality-gates.yml +305 -0
- package/.claude/docs/guides/TEAM_MODE_GUIDE.md +313 -0
- package/.claude/docs/templates/DELTA_SPEC_TEMPLATE.md +91 -0
- package/.claude/docs/templates/DESIGN_DECISIONS_TEMPLATE.md +151 -0
- package/.claude/docs/templates/JOURNAL_TEMPLATE.md +75 -0
- package/.claude/docs/templates/_shared/CLAUDE.md +36 -0
- package/.claude/docs/templates/_shared/CONSTITUTION_CHECK.md +125 -0
- package/.claude/docs/templates/_shared/VALIDATION_CHECKLIST.md +187 -0
- package/.claude/docs/templates/_shared/YAML_FRONTMATTER.md +164 -0
- package/.claude/docs/templates/context/dev.jsonl.template +6 -0
- package/.claude/docs/templates/context/epic.jsonl.template +5 -0
- package/.claude/docs/templates/context/prd.jsonl.template +4 -0
- package/.claude/docs/templates/context/research.jsonl.template +4 -0
- package/.claude/docs/templates/context/review.jsonl.template +5 -0
- package/.claude/docs/templates/context/tech.jsonl.template +5 -0
- package/.claude/hooks/CLAUDE.md +342 -0
- package/.claude/hooks/inject-agent-context.ts +480 -0
- package/.claude/hooks/inject-skill-context.ts +359 -0
- package/.claude/hooks/ralph-loop.ts +931 -0
- package/.claude/hooks/task-completed-hook.ts +593 -0
- package/.claude/hooks/teammate-idle-hook.ts +690 -0
- package/.claude/hooks/types/team-types.d.ts +238 -0
- package/.claude/rules/devflow-conventions.md +82 -9
- package/.claude/scripts/archive-requirement.sh +44 -1
- package/.claude/scripts/common.sh +670 -3
- package/.claude/scripts/delta-parser.ts +527 -0
- package/.claude/scripts/detect-file-conflicts.sh +151 -0
- package/.claude/scripts/flow-context-add.sh +134 -0
- package/.claude/scripts/flow-context-init.sh +133 -0
- package/.claude/scripts/flow-context-validate.sh +144 -0
- package/.claude/scripts/flow-delta-apply.sh +297 -0
- package/.claude/scripts/flow-delta-archive.sh +71 -0
- package/.claude/scripts/flow-delta-create.sh +202 -0
- package/.claude/scripts/flow-delta-list.sh +142 -0
- package/.claude/scripts/flow-delta-status.sh +235 -0
- package/.claude/scripts/flow-quality-full.sh +184 -0
- package/.claude/scripts/flow-quality-quick.sh +64 -0
- package/.claude/scripts/flow-workspace-init.sh +117 -0
- package/.claude/scripts/flow-workspace-record.sh +164 -0
- package/.claude/scripts/flow-workspace-start.sh +88 -0
- package/.claude/scripts/get-workflow-status.sh +415 -0
- package/.claude/scripts/parse-task-dependencies.js +334 -0
- package/.claude/scripts/record-quality-error.sh +165 -0
- package/.claude/scripts/run-quality-gates.sh +242 -0
- package/.claude/scripts/team-dev-init.sh +319 -0
- package/.claude/scripts/team-state-recovery.sh +229 -0
- package/.claude/scripts/workflow-status.ts +433 -0
- package/.claude/settings.json +19 -0
- package/.claude/skills/cc-devflow-orchestrator/SKILL.md +85 -200
- package/.claude/skills/domain/using-git-worktrees/SKILL.md +252 -0
- package/.claude/skills/domain/using-git-worktrees/assets/SHELL_ALIASES.md +133 -0
- package/.claude/skills/domain/using-git-worktrees/context.jsonl +4 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-cleanup.sh +218 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-create.sh +232 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-list.sh +130 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-status.sh +140 -0
- package/.claude/skills/domain/using-git-worktrees/scripts/worktree-switch.sh +70 -0
- package/.claude/skills/skill-rules.json +72 -1
- package/.claude/skills/utility/journey-checker/SKILL.md +199 -0
- package/.claude/skills/utility/journey-checker/pressure-scenarios.md +164 -0
- package/.claude/skills/utility/skill-creator/LICENSE.txt +202 -0
- package/.claude/skills/utility/skill-creator/SKILL.md +356 -0
- package/.claude/skills/utility/skill-creator/references/output-patterns.md +82 -0
- package/.claude/skills/utility/skill-creator/references/workflows.md +28 -0
- package/.claude/skills/utility/skill-creator/scripts/init_skill.py +303 -0
- package/.claude/skills/utility/skill-creator/scripts/package_skill.py +110 -0
- package/.claude/skills/utility/skill-creator/scripts/quick_validate.py +95 -0
- package/.claude/skills/workflow/flow-dev/CLAUDE.md +78 -0
- package/.claude/skills/workflow/flow-dev/SKILL.md +96 -0
- package/.claude/skills/workflow/flow-dev/assets/IMPLEMENTATION_PLAN_TEMPLATE.md +71 -0
- package/.claude/skills/workflow/flow-dev/context.jsonl +8 -0
- package/.claude/skills/workflow/flow-dev/dev-implementer.jsonl +8 -0
- package/.claude/skills/workflow/flow-dev/scripts/entry-gate.sh +116 -0
- package/.claude/skills/workflow/flow-dev/scripts/exit-gate.sh +101 -0
- package/.claude/skills/workflow/flow-dev/scripts/task-orchestrator.sh +106 -0
- package/.claude/skills/workflow/flow-fix/SKILL.md +105 -0
- package/.claude/skills/workflow/flow-fix/context.jsonl +6 -0
- package/.claude/skills/workflow/flow-fix/references/bug-analyzer.md +381 -0
- package/.claude/skills/workflow/flow-init/SKILL.md +211 -0
- package/.claude/skills/workflow/flow-init/assets/BRAINSTORM_TEMPLATE.md +148 -0
- package/.claude/skills/workflow/flow-init/assets/INIT_FLOW_TEMPLATE.md +198 -0
- package/.claude/skills/workflow/flow-init/assets/RESEARCH_TEMPLATE.md +276 -0
- package/.claude/skills/workflow/flow-init/context.jsonl +5 -0
- package/.claude/skills/workflow/flow-init/references/flow-researcher.md +132 -0
- package/.claude/skills/workflow/flow-init/scripts/check-prerequisites.sh +232 -0
- package/.claude/skills/workflow/flow-init/scripts/consolidate-research.sh +182 -0
- package/.claude/skills/workflow/flow-init/scripts/create-requirement.sh +515 -0
- package/.claude/skills/workflow/flow-init/scripts/generate-research-tasks.sh +157 -0
- package/.claude/skills/workflow/flow-init/scripts/populate-research-tasks.sh +284 -0
- package/.claude/skills/workflow/flow-init/scripts/validate-research.sh +332 -0
- package/.claude/skills/workflow/flow-quality/SKILL.md +94 -0
- package/.claude/skills/workflow/flow-quality/context.jsonl +6 -0
- package/.claude/skills/workflow/flow-quality/references/code-quality-reviewer.md +205 -0
- package/.claude/skills/workflow/flow-quality/references/qa-tester.md +313 -0
- package/.claude/skills/workflow/flow-quality/references/security-reviewer.md +314 -0
- package/.claude/skills/workflow/flow-quality/references/spec-reviewer.md +221 -0
- package/.claude/skills/workflow/flow-release/SKILL.md +126 -0
- package/.claude/skills/workflow/flow-release/context.jsonl +7 -0
- package/.claude/skills/workflow/flow-release/references/release-manager.md +295 -0
- package/.claude/skills/workflow/flow-spec/CLAUDE.md +103 -0
- package/.claude/skills/workflow/flow-spec/SKILL.md +545 -0
- package/.claude/skills/workflow/flow-spec/context.jsonl +7 -0
- package/.claude/skills/workflow/flow-spec/scripts/entry-gate.sh +194 -0
- package/.claude/skills/workflow/flow-spec/scripts/exit-gate.sh +244 -0
- package/.claude/skills/workflow/flow-spec/scripts/parallel-orchestrator.sh +205 -0
- package/.claude/skills/workflow/flow-spec/scripts/team-communication.sh +353 -0
- package/.claude/skills/workflow/flow-spec/scripts/team-init.sh +195 -0
- package/.claude/skills/workflow/flow-spec/scripts/test-team-mode.sh +496 -0
- package/.claude/skills/workflow/flow-spec/team-config.json +165 -0
- package/.claude/skills/workflow.yaml +417 -0
- package/CHANGELOG.md +254 -0
- package/README.md +193 -33
- package/README.zh-CN.md +206 -46
- package/lib/compiler/CLAUDE.md +77 -46
- package/lib/compiler/__tests__/multi-module-emitters.test.js +508 -0
- package/lib/compiler/context-expander.js +179 -0
- package/lib/compiler/emitters/antigravity-emitter.js +195 -5
- package/lib/compiler/emitters/base-emitter.js +217 -2
- package/lib/compiler/emitters/codex-emitter.js +200 -4
- package/lib/compiler/emitters/cursor-emitter.js +307 -3
- package/lib/compiler/emitters/qwen-emitter.js +196 -4
- package/lib/compiler/index.js +197 -2
- package/lib/compiler/platforms.js +270 -21
- package/package.json +1 -1
- package/.claude/commands/flow-epic.md +0 -183
- package/.claude/commands/flow-init.md +0 -370
- package/.claude/commands/flow-prd.md +0 -144
- package/.claude/commands/flow-qa.md +0 -93
- package/.claude/commands/flow-review.md +0 -257
- package/.claude/commands/flow-tech.md +0 -142
- package/.claude/commands/flow-ui.md +0 -189
- package/.claude/skills/file-header-guardian/SKILL.md +0 -56
- package/.claude/skills/skill-developer/ADVANCED.md +0 -197
- package/.claude/skills/skill-developer/HOOK_MECHANISMS.md +0 -306
- package/.claude/skills/skill-developer/PATTERNS_LIBRARY.md +0 -152
- package/.claude/skills/skill-developer/SKILL.md +0 -426
- package/.claude/skills/skill-developer/SKILL_RULES_REFERENCE.md +0 -315
- package/.claude/skills/skill-developer/TRIGGER_TYPES.md +0 -305
- package/.claude/skills/skill-developer/TROUBLESHOOTING.md +0 -514
- package/.claude/skills/writing-skills/SKILL.md +0 -655
- package/.claude/skills/writing-skills/anthropic-best-practices.md +0 -1150
- package/.claude/skills/writing-skills/examples/CLAUDE_MD_TESTING.md +0 -189
- package/.claude/skills/writing-skills/graphviz-conventions.dot +0 -172
- package/.claude/skills/writing-skills/persuasion-principles.md +0 -187
- package/.claude/skills/writing-skills/render-graphs.js +0 -168
- package/.claude/skills/writing-skills/testing-skills-with-subagents.md +0 -384
- package/.claude/tsc-cache/795ba6e3-b98a-423b-bab2-51aa62812569/affected-repos.txt +0 -1
- package/.claude/tsc-cache/ae335694-be5a-4ba4-a1a0-b676c09a7906/affected-repos.txt +0 -1
- /package/.claude/commands/{core-architecture.md → core/architecture.md} +0 -0
- /package/.claude/commands/{core-guidelines.md → core/guidelines.md} +0 -0
- /package/.claude/commands/{core-roadmap.md → core/roadmap.md} +0 -0
- /package/.claude/commands/{core-style.md → core/style.md} +0 -0
- /package/.claude/commands/{flow-checklist.md → flow/checklist.md} +0 -0
- /package/.claude/commands/{flow-clarify.md → flow/clarify.md} +0 -0
- /package/.claude/commands/{flow-constitution.md → flow/constitution.md} +0 -0
- /package/.claude/commands/{flow-fix.md → flow/fix.md} +0 -0
- /package/.claude/commands/{flow-ideate.md → flow/ideate.md} +0 -0
- /package/.claude/commands/{flow-new.md → flow/new.md} +0 -0
- /package/.claude/commands/{flow-release.md → flow/release.md} +0 -0
- /package/.claude/commands/{flow-restart.md → flow/restart.md} +0 -0
- /package/.claude/commands/{flow-status.md → flow/status.md} +0 -0
- /package/.claude/commands/{flow-update.md → flow/update.md} +0 -0
- /package/.claude/commands/{flow-upgrade.md → flow/upgrade.md} +0 -0
- /package/.claude/commands/{flow-verify.md → flow/verify.md} +0 -0
- /package/.claude/commands/{code-review-high.md → util/code-review.md} +0 -0
- /package/.claude/commands/{git-commit.md → util/git-commit.md} +0 -0
- /package/.claude/commands/{problem-analyzer.md → util/problem-analyzer.md} +0 -0
- /package/.claude/skills/{flow-attention-refresh → domain/attention-refresh}/SKILL.md +0 -0
- /package/.claude/skills/{flow-brainstorming → domain/brainstorming}/SKILL.md +0 -0
- /package/.claude/skills/{flow-debugging → domain/debugging}/SKILL.md +0 -0
- /package/.claude/skills/{flow-finishing-branch → domain/finishing-branch}/SKILL.md +0 -0
- /package/.claude/skills/{flow-receiving-review → domain/receiving-review}/SKILL.md +0 -0
- /package/.claude/skills/{flow-tdd → domain/tdd}/SKILL.md +0 -0
- /package/.claude/skills/{verification-before-completion → domain/verification}/SKILL.md +0 -0
- /package/.claude/skills/{constitution-guardian → guardrail/constitution-guardian}/SKILL.md +0 -0
- /package/.claude/skills/{devflow-tdd-enforcer → guardrail/tdd-enforcer}/SKILL.md +0 -0
- /package/.claude/skills/{devflow-constitution-quick-ref → utility/constitution-quick-ref}/SKILL.md +0 -0
- /package/.claude/skills/{devflow-file-standards → utility/file-standards}/SKILL.md +0 -0
- /package/.claude/skills/{fractal-docs-generator → utility/fractal-docs}/SKILL.md +0 -0
- /package/.claude/skills/{npm-release → utility/npm-release}/SKILL.md +0 -0
|
@@ -0,0 +1,496 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# =============================================================================
|
|
3
|
+
# Integration Tests for flow-spec Team Mode
|
|
4
|
+
# =============================================================================
|
|
5
|
+
# [INPUT]: 依赖 team-init.sh, common.sh
|
|
6
|
+
# [OUTPUT]: 测试结果报告
|
|
7
|
+
# [POS]: flow-spec/scripts/ 的集成测试
|
|
8
|
+
# [PROTOCOL]: 变更时更新此头部,然后检查 CLAUDE.md
|
|
9
|
+
# =============================================================================
|
|
10
|
+
|
|
11
|
+
set -euo pipefail
|
|
12
|
+
|
|
13
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
14
|
+
REPO_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
|
|
15
|
+
source "$REPO_ROOT/.claude/scripts/common.sh"
|
|
16
|
+
|
|
17
|
+
# =============================================================================
|
|
18
|
+
# Test Framework
|
|
19
|
+
# =============================================================================
|
|
20
|
+
|
|
21
|
+
TESTS_RUN=0
|
|
22
|
+
TESTS_PASSED=0
|
|
23
|
+
TESTS_FAILED=0
|
|
24
|
+
TEST_TEMP_DIR=""
|
|
25
|
+
|
|
26
|
+
# Colors
|
|
27
|
+
RED='\033[0;31m'
|
|
28
|
+
GREEN='\033[0;32m'
|
|
29
|
+
YELLOW='\033[0;33m'
|
|
30
|
+
NC='\033[0m' # No Color
|
|
31
|
+
|
|
32
|
+
# Assert equals
|
|
33
|
+
# Args: $1 - actual, $2 - expected, $3 - message
|
|
34
|
+
assert_equals() {
|
|
35
|
+
local actual="$1"
|
|
36
|
+
local expected="$2"
|
|
37
|
+
local message="${3:-Assertion failed}"
|
|
38
|
+
|
|
39
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
40
|
+
|
|
41
|
+
if [[ "$actual" == "$expected" ]]; then
|
|
42
|
+
echo -e "${GREEN} PASS${NC}: $message"
|
|
43
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
44
|
+
return 0
|
|
45
|
+
else
|
|
46
|
+
echo -e "${RED} FAIL${NC}: $message"
|
|
47
|
+
echo " Expected: '$expected'"
|
|
48
|
+
echo " Actual: '$actual'"
|
|
49
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
50
|
+
return 1
|
|
51
|
+
fi
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
# Assert not empty
|
|
55
|
+
# Args: $1 - value, $2 - message
|
|
56
|
+
assert_not_empty() {
|
|
57
|
+
local value="$1"
|
|
58
|
+
local message="${2:-Value should not be empty}"
|
|
59
|
+
|
|
60
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
61
|
+
|
|
62
|
+
if [[ -n "$value" ]]; then
|
|
63
|
+
echo -e "${GREEN} PASS${NC}: $message"
|
|
64
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
65
|
+
return 0
|
|
66
|
+
else
|
|
67
|
+
echo -e "${RED} FAIL${NC}: $message"
|
|
68
|
+
echo " Value is empty"
|
|
69
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
70
|
+
return 1
|
|
71
|
+
fi
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
# Assert file exists
|
|
75
|
+
# Args: $1 - file path, $2 - message
|
|
76
|
+
assert_file_exists() {
|
|
77
|
+
local file_path="$1"
|
|
78
|
+
local message="${2:-File should exist}"
|
|
79
|
+
|
|
80
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
81
|
+
|
|
82
|
+
if [[ -f "$file_path" ]]; then
|
|
83
|
+
echo -e "${GREEN} PASS${NC}: $message"
|
|
84
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
85
|
+
return 0
|
|
86
|
+
else
|
|
87
|
+
echo -e "${RED} FAIL${NC}: $message"
|
|
88
|
+
echo " File not found: $file_path"
|
|
89
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
90
|
+
return 1
|
|
91
|
+
fi
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
# Assert JSON field equals
|
|
95
|
+
# Args: $1 - json file, $2 - jq path, $3 - expected, $4 - message
|
|
96
|
+
assert_json_field() {
|
|
97
|
+
local json_file="$1"
|
|
98
|
+
local jq_path="$2"
|
|
99
|
+
local expected="$3"
|
|
100
|
+
local message="${4:-JSON field assertion}"
|
|
101
|
+
|
|
102
|
+
local actual
|
|
103
|
+
actual=$(jq -r "$jq_path" "$json_file" 2>/dev/null || echo "")
|
|
104
|
+
|
|
105
|
+
assert_equals "$actual" "$expected" "$message"
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
# Assert JSON field not null
|
|
109
|
+
# Args: $1 - json file, $2 - jq path, $3 - message
|
|
110
|
+
assert_json_not_null() {
|
|
111
|
+
local json_file="$1"
|
|
112
|
+
local jq_path="$2"
|
|
113
|
+
local message="${3:-JSON field should not be null}"
|
|
114
|
+
|
|
115
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
116
|
+
|
|
117
|
+
local value
|
|
118
|
+
value=$(jq -r "$jq_path" "$json_file" 2>/dev/null || echo "null")
|
|
119
|
+
|
|
120
|
+
if [[ "$value" != "null" ]] && [[ -n "$value" ]]; then
|
|
121
|
+
echo -e "${GREEN} PASS${NC}: $message"
|
|
122
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
123
|
+
return 0
|
|
124
|
+
else
|
|
125
|
+
echo -e "${RED} FAIL${NC}: $message"
|
|
126
|
+
echo " Path '$jq_path' is null or empty"
|
|
127
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
128
|
+
return 1
|
|
129
|
+
fi
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
# Setup test environment
|
|
133
|
+
setup_test_env() {
|
|
134
|
+
TEST_TEMP_DIR=$(mktemp -d)
|
|
135
|
+
mkdir -p "$TEST_TEMP_DIR/devflow/requirements/REQ-TEST"
|
|
136
|
+
|
|
137
|
+
# Create minimal orchestration_status.json
|
|
138
|
+
cat > "$TEST_TEMP_DIR/devflow/requirements/REQ-TEST/orchestration_status.json" <<EOF
|
|
139
|
+
{
|
|
140
|
+
"reqId": "REQ-TEST",
|
|
141
|
+
"status": "initialized",
|
|
142
|
+
"phase": "planning",
|
|
143
|
+
"createdAt": "$(get_beijing_time_iso)",
|
|
144
|
+
"updatedAt": "$(get_beijing_time_iso)"
|
|
145
|
+
}
|
|
146
|
+
EOF
|
|
147
|
+
|
|
148
|
+
# Create minimal TASKS.md
|
|
149
|
+
cat > "$TEST_TEMP_DIR/devflow/requirements/REQ-TEST/TASKS.md" <<EOF
|
|
150
|
+
# Tasks for REQ-TEST
|
|
151
|
+
|
|
152
|
+
## Phase 1: PRD
|
|
153
|
+
- [ ] **T001** Write PRD document
|
|
154
|
+
- [ ] **T002** Review PRD
|
|
155
|
+
|
|
156
|
+
## Phase 2: Design
|
|
157
|
+
- [ ] **T003** Create tech design
|
|
158
|
+
- [ ] **T004** Create UI prototype
|
|
159
|
+
EOF
|
|
160
|
+
|
|
161
|
+
echo "$TEST_TEMP_DIR"
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
# Cleanup test environment
|
|
165
|
+
cleanup_test_env() {
|
|
166
|
+
if [[ -n "$TEST_TEMP_DIR" ]] && [[ -d "$TEST_TEMP_DIR" ]]; then
|
|
167
|
+
rm -rf "$TEST_TEMP_DIR"
|
|
168
|
+
fi
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
# =============================================================================
|
|
172
|
+
# Test Cases
|
|
173
|
+
# =============================================================================
|
|
174
|
+
|
|
175
|
+
# Test 1: Mode Detection Tests
|
|
176
|
+
test_mode_detection() {
|
|
177
|
+
echo ""
|
|
178
|
+
echo -e "${YELLOW}=== Test Suite: Mode Detection ===${NC}"
|
|
179
|
+
|
|
180
|
+
# Source team-init.sh functions
|
|
181
|
+
source "$SCRIPT_DIR/team-init.sh"
|
|
182
|
+
|
|
183
|
+
# Test 1.1: Full mode should return "team"
|
|
184
|
+
local result
|
|
185
|
+
result=$(detect_execution_mode "false" "false")
|
|
186
|
+
assert_equals "$result" "team" "Full mode (no skip) should use team"
|
|
187
|
+
|
|
188
|
+
# Test 1.2: Skip tech should return "subagent"
|
|
189
|
+
result=$(detect_execution_mode "true" "false")
|
|
190
|
+
assert_equals "$result" "subagent" "Skip tech should use subagent"
|
|
191
|
+
|
|
192
|
+
# Test 1.3: Skip ui should return "subagent"
|
|
193
|
+
result=$(detect_execution_mode "false" "true")
|
|
194
|
+
assert_equals "$result" "subagent" "Skip ui should use subagent"
|
|
195
|
+
|
|
196
|
+
# Test 1.4: Skip both should return "subagent"
|
|
197
|
+
result=$(detect_execution_mode "true" "true")
|
|
198
|
+
assert_equals "$result" "subagent" "Skip both should use subagent"
|
|
199
|
+
}
|
|
200
|
+
|
|
201
|
+
# Test 2: Team Initialization Tests
|
|
202
|
+
test_team_initialization() {
|
|
203
|
+
echo ""
|
|
204
|
+
echo -e "${YELLOW}=== Test Suite: Team Initialization ===${NC}"
|
|
205
|
+
|
|
206
|
+
local temp_dir
|
|
207
|
+
temp_dir=$(setup_test_env)
|
|
208
|
+
|
|
209
|
+
# Source team-init.sh functions
|
|
210
|
+
source "$SCRIPT_DIR/team-init.sh"
|
|
211
|
+
|
|
212
|
+
# Test 2.1: Initialize team
|
|
213
|
+
init_spec_team "$temp_dir" "REQ-TEST" > /dev/null 2>&1
|
|
214
|
+
|
|
215
|
+
local status_file="$temp_dir/devflow/requirements/REQ-TEST/orchestration_status.json"
|
|
216
|
+
|
|
217
|
+
# Test 2.2: Verify team mode
|
|
218
|
+
assert_json_field "$status_file" ".team.mode" "parallel" "Team mode should be parallel"
|
|
219
|
+
|
|
220
|
+
# Test 2.3: Verify team lead
|
|
221
|
+
assert_json_field "$status_file" ".team.lead" "spec-lead" "Team lead should be spec-lead"
|
|
222
|
+
|
|
223
|
+
# Test 2.4: Verify teammates count
|
|
224
|
+
local teammates_count
|
|
225
|
+
teammates_count=$(jq '.team.teammates | length' "$status_file")
|
|
226
|
+
assert_equals "$teammates_count" "4" "Should have 4 teammates"
|
|
227
|
+
|
|
228
|
+
# Test 2.5: Verify prd-writer exists
|
|
229
|
+
local prd_writer
|
|
230
|
+
prd_writer=$(jq -r '.team.teammates[] | select(.id == "prd-writer") | .role' "$status_file")
|
|
231
|
+
assert_equals "$prd_writer" "analyst" "prd-writer should have analyst role"
|
|
232
|
+
|
|
233
|
+
# Test 2.6: Verify tech-architect exists
|
|
234
|
+
local tech_architect
|
|
235
|
+
tech_architect=$(jq -r '.team.teammates[] | select(.id == "tech-architect") | .role' "$status_file")
|
|
236
|
+
assert_equals "$tech_architect" "architect" "tech-architect should have architect role"
|
|
237
|
+
|
|
238
|
+
# Test 2.7: Verify ui-designer exists
|
|
239
|
+
local ui_designer
|
|
240
|
+
ui_designer=$(jq -r '.team.teammates[] | select(.id == "ui-designer") | .role' "$status_file")
|
|
241
|
+
assert_equals "$ui_designer" "designer" "ui-designer should have designer role"
|
|
242
|
+
|
|
243
|
+
# Test 2.8: Verify planner exists
|
|
244
|
+
local planner
|
|
245
|
+
planner=$(jq -r '.team.teammates[] | select(.id == "planner") | .role' "$status_file")
|
|
246
|
+
assert_equals "$planner" "planner" "planner should have planner role"
|
|
247
|
+
|
|
248
|
+
# Test 2.9: Verify Ralph Loop initialized
|
|
249
|
+
assert_json_not_null "$status_file" ".ralphLoop" "Ralph Loop should be initialized"
|
|
250
|
+
|
|
251
|
+
# Test 2.10: Verify Ralph Loop enabled
|
|
252
|
+
assert_json_field "$status_file" ".ralphLoop.enabled" "true" "Ralph Loop should be enabled"
|
|
253
|
+
|
|
254
|
+
cleanup_test_env
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
# Test 3: Team Configuration Tests
|
|
258
|
+
test_team_configuration() {
|
|
259
|
+
echo ""
|
|
260
|
+
echo -e "${YELLOW}=== Test Suite: Team Configuration ===${NC}"
|
|
261
|
+
|
|
262
|
+
# Test 3.1: Verify team-config.json exists
|
|
263
|
+
local config_file="$SCRIPT_DIR/../team-config.json"
|
|
264
|
+
assert_file_exists "$config_file" "team-config.json should exist"
|
|
265
|
+
|
|
266
|
+
# Test 3.2: Verify config is valid JSON
|
|
267
|
+
if jq empty "$config_file" 2>/dev/null; then
|
|
268
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
269
|
+
echo -e "${GREEN} PASS${NC}: team-config.json is valid JSON"
|
|
270
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
271
|
+
else
|
|
272
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
273
|
+
echo -e "${RED} FAIL${NC}: team-config.json is not valid JSON"
|
|
274
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
275
|
+
fi
|
|
276
|
+
|
|
277
|
+
# Test 3.3: Verify required fields
|
|
278
|
+
assert_json_field "$config_file" ".name" "spec-design-team" "Config name should be spec-design-team"
|
|
279
|
+
assert_json_field "$config_file" ".mode" "parallel" "Config mode should be parallel"
|
|
280
|
+
assert_json_field "$config_file" ".lead" "spec-lead" "Config lead should be spec-lead"
|
|
281
|
+
|
|
282
|
+
# Test 3.4: Verify members array
|
|
283
|
+
local members_count
|
|
284
|
+
members_count=$(jq '.members | length' "$config_file")
|
|
285
|
+
assert_equals "$members_count" "4" "Config should have 4 members"
|
|
286
|
+
|
|
287
|
+
# Test 3.5: Verify workflow stages
|
|
288
|
+
local stages_count
|
|
289
|
+
stages_count=$(jq '.workflow.stages | length' "$config_file")
|
|
290
|
+
assert_equals "$stages_count" "3" "Config should have 3 workflow stages"
|
|
291
|
+
|
|
292
|
+
# Test 3.6: Verify negotiate topics
|
|
293
|
+
local topics_count
|
|
294
|
+
topics_count=$(jq '.communication.negotiate_topics | length' "$config_file")
|
|
295
|
+
assert_not_empty "$topics_count" "Config should have negotiate topics"
|
|
296
|
+
|
|
297
|
+
# Test 3.7: Verify quality gates
|
|
298
|
+
assert_json_not_null "$config_file" ".quality_gates.entry" "Entry gate should be defined"
|
|
299
|
+
assert_json_not_null "$config_file" ".quality_gates.exit" "Exit gate should be defined"
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
# Test 4: Common.sh Team Functions Tests
|
|
303
|
+
test_common_team_functions() {
|
|
304
|
+
echo ""
|
|
305
|
+
echo -e "${YELLOW}=== Test Suite: Common.sh Team Functions ===${NC}"
|
|
306
|
+
|
|
307
|
+
local temp_dir
|
|
308
|
+
temp_dir=$(setup_test_env)
|
|
309
|
+
|
|
310
|
+
# Test 4.1: is_team_mode_enabled (before init)
|
|
311
|
+
if ! is_team_mode_enabled "$temp_dir" "REQ-TEST"; then
|
|
312
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
313
|
+
echo -e "${GREEN} PASS${NC}: Team mode not enabled before init"
|
|
314
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
315
|
+
else
|
|
316
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
317
|
+
echo -e "${RED} FAIL${NC}: Team mode should not be enabled before init"
|
|
318
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
319
|
+
fi
|
|
320
|
+
|
|
321
|
+
# Initialize team
|
|
322
|
+
init_team_state "$temp_dir" "REQ-TEST" "parallel" "spec-lead"
|
|
323
|
+
add_teammate "$temp_dir" "REQ-TEST" "test-dev" "developer"
|
|
324
|
+
|
|
325
|
+
# Test 4.2: is_team_mode_enabled (after init)
|
|
326
|
+
if is_team_mode_enabled "$temp_dir" "REQ-TEST"; then
|
|
327
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
328
|
+
echo -e "${GREEN} PASS${NC}: Team mode enabled after init"
|
|
329
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
330
|
+
else
|
|
331
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
332
|
+
echo -e "${RED} FAIL${NC}: Team mode should be enabled after init"
|
|
333
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
334
|
+
fi
|
|
335
|
+
|
|
336
|
+
# Test 4.3: get_teammate
|
|
337
|
+
local teammate
|
|
338
|
+
teammate=$(get_teammate "$temp_dir" "REQ-TEST" "test-dev")
|
|
339
|
+
local teammate_role
|
|
340
|
+
teammate_role=$(echo "$teammate" | jq -r '.role')
|
|
341
|
+
assert_equals "$teammate_role" "developer" "get_teammate should return correct role"
|
|
342
|
+
|
|
343
|
+
# Test 4.4: update_teammate_status
|
|
344
|
+
update_teammate_status "$temp_dir" "REQ-TEST" "test-dev" "working" "T001"
|
|
345
|
+
teammate=$(get_teammate "$temp_dir" "REQ-TEST" "test-dev")
|
|
346
|
+
local teammate_status
|
|
347
|
+
teammate_status=$(echo "$teammate" | jq -r '.status')
|
|
348
|
+
assert_equals "$teammate_status" "working" "update_teammate_status should update status"
|
|
349
|
+
|
|
350
|
+
local current_task
|
|
351
|
+
current_task=$(echo "$teammate" | jq -r '.currentTask')
|
|
352
|
+
assert_equals "$current_task" "T001" "update_teammate_status should update currentTask"
|
|
353
|
+
|
|
354
|
+
# Test 4.5: mark_teammate_task_complete
|
|
355
|
+
mark_teammate_task_complete "$temp_dir" "REQ-TEST" "test-dev" "T001"
|
|
356
|
+
teammate=$(get_teammate "$temp_dir" "REQ-TEST" "test-dev")
|
|
357
|
+
teammate_status=$(echo "$teammate" | jq -r '.status')
|
|
358
|
+
assert_equals "$teammate_status" "idle" "mark_teammate_task_complete should set status to idle"
|
|
359
|
+
|
|
360
|
+
local completed_tasks
|
|
361
|
+
completed_tasks=$(echo "$teammate" | jq -r '.completedTasks | length')
|
|
362
|
+
assert_equals "$completed_tasks" "1" "mark_teammate_task_complete should add to completedTasks"
|
|
363
|
+
|
|
364
|
+
# Test 4.6: assign_task_to_teammate
|
|
365
|
+
assign_task_to_teammate "$temp_dir" "REQ-TEST" "T002" "test-dev"
|
|
366
|
+
local status_file="$temp_dir/devflow/requirements/REQ-TEST/orchestration_status.json"
|
|
367
|
+
local assigned_to
|
|
368
|
+
assigned_to=$(jq -r '.team.taskAssignments.T002' "$status_file")
|
|
369
|
+
assert_equals "$assigned_to" "test-dev" "assign_task_to_teammate should update taskAssignments"
|
|
370
|
+
|
|
371
|
+
# Test 4.7: get_unassigned_tasks
|
|
372
|
+
local unassigned
|
|
373
|
+
unassigned=$(get_unassigned_tasks "$temp_dir" "REQ-TEST")
|
|
374
|
+
# T001 completed, T002 assigned, T003 and T004 should be unassigned
|
|
375
|
+
if echo "$unassigned" | grep -q "T003"; then
|
|
376
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
377
|
+
echo -e "${GREEN} PASS${NC}: get_unassigned_tasks returns T003"
|
|
378
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
379
|
+
else
|
|
380
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
381
|
+
echo -e "${RED} FAIL${NC}: get_unassigned_tasks should return T003"
|
|
382
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
383
|
+
fi
|
|
384
|
+
|
|
385
|
+
# Test 4.8: all_teammates_idle
|
|
386
|
+
update_teammate_status "$temp_dir" "REQ-TEST" "test-dev" "idle" "null"
|
|
387
|
+
if all_teammates_idle "$temp_dir" "REQ-TEST"; then
|
|
388
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
389
|
+
echo -e "${GREEN} PASS${NC}: all_teammates_idle returns true when all idle"
|
|
390
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
391
|
+
else
|
|
392
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
393
|
+
echo -e "${RED} FAIL${NC}: all_teammates_idle should return true"
|
|
394
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
395
|
+
fi
|
|
396
|
+
|
|
397
|
+
# Test 4.9: update_teammate_ralph_state
|
|
398
|
+
update_teammate_ralph_state "$temp_dir" "REQ-TEST" "test-dev" "passed"
|
|
399
|
+
local ralph_iteration
|
|
400
|
+
ralph_iteration=$(jq -r '.ralphLoop.teammates["test-dev"].iteration' "$status_file")
|
|
401
|
+
assert_equals "$ralph_iteration" "1" "update_teammate_ralph_state should increment iteration"
|
|
402
|
+
|
|
403
|
+
local ralph_result
|
|
404
|
+
ralph_result=$(jq -r '.ralphLoop.teammates["test-dev"].lastVerifyResult' "$status_file")
|
|
405
|
+
assert_equals "$ralph_result" "passed" "update_teammate_ralph_state should update lastVerifyResult"
|
|
406
|
+
|
|
407
|
+
# Test 4.10: cleanup_team_state
|
|
408
|
+
cleanup_team_state "$temp_dir" "REQ-TEST"
|
|
409
|
+
if ! is_team_mode_enabled "$temp_dir" "REQ-TEST"; then
|
|
410
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
411
|
+
echo -e "${GREEN} PASS${NC}: cleanup_team_state removes team state"
|
|
412
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
413
|
+
else
|
|
414
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
415
|
+
echo -e "${RED} FAIL${NC}: cleanup_team_state should remove team state"
|
|
416
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
417
|
+
fi
|
|
418
|
+
|
|
419
|
+
cleanup_test_env
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
# Test 5: CLI Interface Tests
|
|
423
|
+
test_cli_interface() {
|
|
424
|
+
echo ""
|
|
425
|
+
echo -e "${YELLOW}=== Test Suite: CLI Interface ===${NC}"
|
|
426
|
+
|
|
427
|
+
local temp_dir
|
|
428
|
+
temp_dir=$(setup_test_env)
|
|
429
|
+
|
|
430
|
+
# Test 5.1: detect command
|
|
431
|
+
local result
|
|
432
|
+
result=$("$SCRIPT_DIR/team-init.sh" detect "" "" "false" "false")
|
|
433
|
+
assert_equals "$result" "team" "CLI detect command should work"
|
|
434
|
+
|
|
435
|
+
# Test 5.2: config command
|
|
436
|
+
result=$("$SCRIPT_DIR/team-init.sh" config)
|
|
437
|
+
if echo "$result" | jq -e '.name' > /dev/null 2>&1; then
|
|
438
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
439
|
+
echo -e "${GREEN} PASS${NC}: CLI config command returns valid JSON"
|
|
440
|
+
TESTS_PASSED=$((TESTS_PASSED + 1))
|
|
441
|
+
else
|
|
442
|
+
TESTS_RUN=$((TESTS_RUN + 1))
|
|
443
|
+
echo -e "${RED} FAIL${NC}: CLI config command should return valid JSON"
|
|
444
|
+
TESTS_FAILED=$((TESTS_FAILED + 1))
|
|
445
|
+
fi
|
|
446
|
+
|
|
447
|
+
# Test 5.3: init command
|
|
448
|
+
"$SCRIPT_DIR/team-init.sh" init "$temp_dir" "REQ-TEST" > /dev/null 2>&1
|
|
449
|
+
local status_file="$temp_dir/devflow/requirements/REQ-TEST/orchestration_status.json"
|
|
450
|
+
assert_json_not_null "$status_file" ".team" "CLI init command should create team state"
|
|
451
|
+
|
|
452
|
+
cleanup_test_env
|
|
453
|
+
}
|
|
454
|
+
|
|
455
|
+
# =============================================================================
|
|
456
|
+
# Main
|
|
457
|
+
# =============================================================================
|
|
458
|
+
|
|
459
|
+
main() {
|
|
460
|
+
echo ""
|
|
461
|
+
echo "=============================================="
|
|
462
|
+
echo " flow-spec Team Mode Integration Tests"
|
|
463
|
+
echo "=============================================="
|
|
464
|
+
echo ""
|
|
465
|
+
|
|
466
|
+
# Run all test suites
|
|
467
|
+
test_mode_detection
|
|
468
|
+
test_team_initialization
|
|
469
|
+
test_team_configuration
|
|
470
|
+
test_common_team_functions
|
|
471
|
+
test_cli_interface
|
|
472
|
+
|
|
473
|
+
# Print summary
|
|
474
|
+
echo ""
|
|
475
|
+
echo "=============================================="
|
|
476
|
+
echo " Test Summary"
|
|
477
|
+
echo "=============================================="
|
|
478
|
+
echo ""
|
|
479
|
+
echo " Total: $TESTS_RUN"
|
|
480
|
+
echo -e " ${GREEN}Passed${NC}: $TESTS_PASSED"
|
|
481
|
+
echo -e " ${RED}Failed${NC}: $TESTS_FAILED"
|
|
482
|
+
echo ""
|
|
483
|
+
|
|
484
|
+
if [[ $TESTS_FAILED -eq 0 ]]; then
|
|
485
|
+
echo -e "${GREEN}All tests passed!${NC}"
|
|
486
|
+
exit 0
|
|
487
|
+
else
|
|
488
|
+
echo -e "${RED}Some tests failed.${NC}"
|
|
489
|
+
exit 1
|
|
490
|
+
fi
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
# Run if executed directly
|
|
494
|
+
if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then
|
|
495
|
+
main "$@"
|
|
496
|
+
fi
|
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "spec-design-team",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "并行规格设计团队 - tech-architect 和 ui-designer 可实时协商共享决策",
|
|
5
|
+
|
|
6
|
+
"mode": "parallel",
|
|
7
|
+
"lead": "spec-lead",
|
|
8
|
+
|
|
9
|
+
"members": [
|
|
10
|
+
{
|
|
11
|
+
"id": "prd-writer",
|
|
12
|
+
"role": "analyst",
|
|
13
|
+
"agent_type": "prd-writer",
|
|
14
|
+
"description": "PRD 生成,需求分析",
|
|
15
|
+
"agent_reference": "flow-prd/references/prd-writer.md",
|
|
16
|
+
"outputs": ["PRD.md"]
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"id": "tech-architect",
|
|
20
|
+
"role": "architect",
|
|
21
|
+
"agent_type": "tech-architect",
|
|
22
|
+
"description": "技术设计,架构方案",
|
|
23
|
+
"agent_reference": "flow-tech/references/tech-architect.md",
|
|
24
|
+
"outputs": ["TECH_DESIGN.md", "data-model.md", "contracts/openapi.yaml"]
|
|
25
|
+
},
|
|
26
|
+
{
|
|
27
|
+
"id": "ui-designer",
|
|
28
|
+
"role": "designer",
|
|
29
|
+
"agent_type": "ui-designer",
|
|
30
|
+
"description": "UI 原型,交互设计",
|
|
31
|
+
"agent_reference": "flow-ui/references/ui-designer.md",
|
|
32
|
+
"outputs": ["UI_PROTOTYPE.html", "ui_design_strategy.md"]
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "planner",
|
|
36
|
+
"role": "planner",
|
|
37
|
+
"agent_type": "planner",
|
|
38
|
+
"description": "Epic 规划,任务分解",
|
|
39
|
+
"agent_reference": "flow-epic/references/planner.md",
|
|
40
|
+
"outputs": ["EPIC.md", "TASKS.md"]
|
|
41
|
+
}
|
|
42
|
+
],
|
|
43
|
+
|
|
44
|
+
"workflow": {
|
|
45
|
+
"stages": [
|
|
46
|
+
{
|
|
47
|
+
"id": "stage-1",
|
|
48
|
+
"name": "PRD Generation",
|
|
49
|
+
"description": "生成产品需求文档",
|
|
50
|
+
"agents": ["prd-writer"],
|
|
51
|
+
"parallel": false,
|
|
52
|
+
"outputs": ["PRD.md"],
|
|
53
|
+
"wait_for": []
|
|
54
|
+
},
|
|
55
|
+
{
|
|
56
|
+
"id": "stage-2",
|
|
57
|
+
"name": "Design Parallel",
|
|
58
|
+
"description": "技术设计和 UI 原型并行执行,支持实时协商",
|
|
59
|
+
"agents": ["tech-architect", "ui-designer"],
|
|
60
|
+
"parallel": true,
|
|
61
|
+
"outputs": ["TECH_DESIGN.md", "UI_PROTOTYPE.html"],
|
|
62
|
+
"wait_for": ["stage-1"],
|
|
63
|
+
"negotiate": {
|
|
64
|
+
"enabled": true,
|
|
65
|
+
"topics": ["api_format", "field_naming", "auth_strategy", "state_management"]
|
|
66
|
+
}
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
"id": "stage-3",
|
|
70
|
+
"name": "Epic Planning",
|
|
71
|
+
"description": "基于 PRD 和设计文档生成 Epic 和任务",
|
|
72
|
+
"agents": ["planner"],
|
|
73
|
+
"parallel": false,
|
|
74
|
+
"outputs": ["EPIC.md", "TASKS.md"],
|
|
75
|
+
"wait_for": ["stage-2"]
|
|
76
|
+
}
|
|
77
|
+
]
|
|
78
|
+
},
|
|
79
|
+
|
|
80
|
+
"communication": {
|
|
81
|
+
"protocol": "direct_message",
|
|
82
|
+
"negotiate_topics": [
|
|
83
|
+
{
|
|
84
|
+
"id": "api_format",
|
|
85
|
+
"name": "API 响应格式",
|
|
86
|
+
"description": "确定 API 响应格式 (REST/GraphQL, JSON structure, pagination)",
|
|
87
|
+
"participants": ["tech-architect", "ui-designer"],
|
|
88
|
+
"decision_owner": "tech-architect",
|
|
89
|
+
"template": "我建议 API 响应格式采用 {format},因为 {reason}。你的前端需求是否有特殊要求?"
|
|
90
|
+
},
|
|
91
|
+
{
|
|
92
|
+
"id": "field_naming",
|
|
93
|
+
"name": "数据字段命名",
|
|
94
|
+
"description": "统一数据字段命名规范 (camelCase/snake_case, 字段名称)",
|
|
95
|
+
"participants": ["tech-architect", "ui-designer", "planner"],
|
|
96
|
+
"decision_owner": "tech-architect",
|
|
97
|
+
"template": "数据模型中的字段命名建议:{fields}。请确认是否与 UI 组件 props 一致。"
|
|
98
|
+
},
|
|
99
|
+
{
|
|
100
|
+
"id": "auth_strategy",
|
|
101
|
+
"name": "认证策略",
|
|
102
|
+
"description": "确定认证方案 (JWT, Session, OAuth)",
|
|
103
|
+
"participants": ["tech-architect", "ui-designer"],
|
|
104
|
+
"decision_owner": "tech-architect",
|
|
105
|
+
"template": "认证策略建议采用 {strategy}。前端需要处理的 token 存储和刷新逻辑是 {logic}。"
|
|
106
|
+
},
|
|
107
|
+
{
|
|
108
|
+
"id": "state_management",
|
|
109
|
+
"name": "状态管理方案",
|
|
110
|
+
"description": "前端状态管理方案 (Redux, Context, Zustand)",
|
|
111
|
+
"participants": ["tech-architect", "ui-designer"],
|
|
112
|
+
"decision_owner": "ui-designer",
|
|
113
|
+
"template": "前端状态管理建议采用 {solution},全局状态包括 {states}。"
|
|
114
|
+
},
|
|
115
|
+
{
|
|
116
|
+
"id": "component_granularity",
|
|
117
|
+
"name": "组件粒度",
|
|
118
|
+
"description": "UI 组件粒度和任务拆分依据",
|
|
119
|
+
"participants": ["ui-designer", "planner"],
|
|
120
|
+
"decision_owner": "ui-designer",
|
|
121
|
+
"template": "UI 组件拆分为 {components},每个组件的复杂度和预估时间是 {estimates}。"
|
|
122
|
+
}
|
|
123
|
+
],
|
|
124
|
+
"decision_record": {
|
|
125
|
+
"path": "devflow/requirements/{REQ}/research/design_decisions.md",
|
|
126
|
+
"format": "markdown",
|
|
127
|
+
"template": "## {topic_name}\n\n**决策**: {decision}\n**参与者**: {participants}\n**原因**: {reason}\n**时间**: {timestamp}\n"
|
|
128
|
+
}
|
|
129
|
+
},
|
|
130
|
+
|
|
131
|
+
"quality_gates": {
|
|
132
|
+
"entry": {
|
|
133
|
+
"required_files": ["BRAINSTORM.md", "research/research.md"],
|
|
134
|
+
"status_check": ["initialized", "spec_failed"]
|
|
135
|
+
},
|
|
136
|
+
"exit": {
|
|
137
|
+
"required_files": ["PRD.md", "EPIC.md", "TASKS.md"],
|
|
138
|
+
"optional_files": ["TECH_DESIGN.md", "UI_PROTOTYPE.html"],
|
|
139
|
+
"status_update": "spec_complete"
|
|
140
|
+
}
|
|
141
|
+
},
|
|
142
|
+
|
|
143
|
+
"error_handling": {
|
|
144
|
+
"stage_failure": {
|
|
145
|
+
"stage-1": {
|
|
146
|
+
"action": "abort",
|
|
147
|
+
"status": "spec_failed",
|
|
148
|
+
"message": "PRD generation failed"
|
|
149
|
+
},
|
|
150
|
+
"stage-2": {
|
|
151
|
+
"action": "continue_partial",
|
|
152
|
+
"message": "Design stage partially failed, continuing with available outputs"
|
|
153
|
+
},
|
|
154
|
+
"stage-3": {
|
|
155
|
+
"action": "abort",
|
|
156
|
+
"status": "spec_failed",
|
|
157
|
+
"message": "Epic planning failed"
|
|
158
|
+
}
|
|
159
|
+
},
|
|
160
|
+
"teammate_failure": {
|
|
161
|
+
"max_retries": 2,
|
|
162
|
+
"retry_delay_seconds": 5
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|