timsquad 3.7.0 → 3.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/README.ko.md +8 -9
  2. package/README.md +44 -11
  3. package/dist/commands/audit.d.ts +6 -0
  4. package/dist/commands/audit.d.ts.map +1 -0
  5. package/dist/commands/audit.js +111 -0
  6. package/dist/commands/audit.js.map +1 -0
  7. package/dist/commands/log.d.ts +6 -0
  8. package/dist/commands/log.d.ts.map +1 -0
  9. package/dist/commands/log.js +85 -0
  10. package/dist/commands/log.js.map +1 -0
  11. package/dist/commands/next.d.ts +15 -0
  12. package/dist/commands/next.d.ts.map +1 -0
  13. package/dist/commands/next.js +146 -0
  14. package/dist/commands/next.js.map +1 -0
  15. package/dist/commands/plan.d.ts +6 -0
  16. package/dist/commands/plan.d.ts.map +1 -0
  17. package/dist/commands/plan.js +83 -0
  18. package/dist/commands/plan.js.map +1 -0
  19. package/dist/commands/retro.d.ts +6 -0
  20. package/dist/commands/retro.d.ts.map +1 -0
  21. package/dist/commands/retro.js +74 -0
  22. package/dist/commands/retro.js.map +1 -0
  23. package/dist/commands/spec.d.ts +6 -0
  24. package/dist/commands/spec.d.ts.map +1 -0
  25. package/dist/commands/spec.js +56 -0
  26. package/dist/commands/spec.js.map +1 -0
  27. package/dist/commands/status.d.ts +6 -0
  28. package/dist/commands/status.d.ts.map +1 -0
  29. package/dist/commands/status.js +99 -0
  30. package/dist/commands/status.js.map +1 -0
  31. package/dist/daemon/index.d.ts.map +1 -1
  32. package/dist/daemon/index.js +12 -10
  33. package/dist/daemon/index.js.map +1 -1
  34. package/dist/daemon/meta-cache.d.ts +2 -1
  35. package/dist/daemon/meta-cache.d.ts.map +1 -1
  36. package/dist/daemon/meta-cache.js +20 -4
  37. package/dist/daemon/meta-cache.js.map +1 -1
  38. package/dist/index.js +15 -1
  39. package/dist/index.js.map +1 -1
  40. package/dist/lib/config.d.ts.map +1 -1
  41. package/dist/lib/config.js +14 -1
  42. package/dist/lib/config.js.map +1 -1
  43. package/dist/lib/planning-parser.d.ts +65 -0
  44. package/dist/lib/planning-parser.d.ts.map +1 -0
  45. package/dist/lib/planning-parser.js +306 -0
  46. package/dist/lib/planning-parser.js.map +1 -0
  47. package/dist/lib/skill-generator.d.ts.map +1 -1
  48. package/dist/lib/skill-generator.js +7 -3
  49. package/dist/lib/skill-generator.js.map +1 -1
  50. package/dist/lib/template.d.ts.map +1 -1
  51. package/dist/lib/template.js +22 -5
  52. package/dist/lib/template.js.map +1 -1
  53. package/dist/lib/workflow-state.d.ts +77 -0
  54. package/dist/lib/workflow-state.d.ts.map +1 -1
  55. package/dist/lib/workflow-state.js +194 -0
  56. package/dist/lib/workflow-state.js.map +1 -1
  57. package/dist/types/config.d.ts +14 -0
  58. package/dist/types/config.d.ts.map +1 -1
  59. package/dist/types/config.js +15 -1
  60. package/dist/types/config.js.map +1 -1
  61. package/package.json +1 -1
  62. package/templates/base/agents/base/tsq-librarian.md +1 -1
  63. package/templates/base/scripts/calculate-retro-metrics.sh +46 -0
  64. package/templates/base/scripts/check-circular-deps.sh +82 -0
  65. package/templates/base/scripts/cleanup-trails.sh +44 -0
  66. package/templates/base/scripts/generate-prd-traceability.sh +91 -0
  67. package/templates/base/scripts/manage-fp-registry.sh +83 -0
  68. package/templates/base/scripts/validate-gherkin.sh +113 -0
  69. package/templates/base/skills/tsq-controller/SKILL.md +60 -37
  70. package/templates/base/skills/tsq-controller/references/model-routing.md +38 -0
  71. package/templates/base/skills/tsq-controller/references/wave-dispatch.md +50 -0
  72. package/templates/base/skills/tsq-full/SKILL.md +70 -0
  73. package/templates/base/skills/tsq-grill/SKILL.md +60 -55
  74. package/templates/base/skills/tsq-grill/references/interview-guide.md +86 -0
  75. package/templates/base/skills/tsq-inspect/SKILL.md +108 -0
  76. package/templates/base/skills/tsq-inspect/references/checklist.md +162 -0
  77. package/templates/base/skills/tsq-quick/SKILL.md +58 -0
  78. package/templates/base/skills/tsq-start/SKILL.md +17 -44
  79. package/templates/base/skills/tsq-start/references/onboarding-steps.md +85 -0
  80. package/templates/platforms/claude-code/scripts/build-gate.sh +25 -2
  81. package/templates/platforms/claude-code/scripts/check-capability.sh +41 -10
  82. package/templates/platforms/claude-code/scripts/completion-guard.sh +79 -3
  83. package/templates/platforms/claude-code/scripts/detect-env.sh +124 -0
  84. package/templates/platforms/claude-code/scripts/stale-guard.sh +47 -0
  85. package/templates/platforms/claude-code/scripts/subagent-stop.sh +41 -2
  86. package/templates/platforms/claude-code/scripts/tdd-guard.sh +57 -0
  87. package/templates/platforms/claude-code/scripts/validate-completion-report.sh +86 -0
  88. package/templates/platforms/claude-code/settings.json +10 -0
  89. package/templates/project-types/fintech/config.yaml +1 -1
  90. package/templates/project-types/mobile-app/config.yaml +1 -1
  91. package/templates/project-types/web-app/config.yaml +1 -1
  92. package/templates/project-types/web-service/config.yaml +1 -1
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env bash
2
+ # cleanup-trails.sh — trail 아카이브 10개 초과 시 자동 정리
3
+ # Usage: bash .timsquad/scripts/cleanup-trails.sh [project_root] [max_count]
4
+ # Output: JSON {archived, remaining}
5
+ set -euo pipefail
6
+
7
+ ROOT="${1:-.}"
8
+ MAX_COUNT="${2:-10}"
9
+ TRAILS_DIR="$ROOT/.timsquad/trails"
10
+ ARCHIVE_DIR="$TRAILS_DIR/.archive"
11
+
12
+ if [ ! -d "$TRAILS_DIR" ]; then
13
+ echo '{"archived":0,"remaining":0,"reason":"trails directory not found"}'
14
+ exit 0
15
+ fi
16
+
17
+ # Count trail files (exclude .archive directory)
18
+ trail_files=()
19
+ while IFS= read -r -d '' f; do
20
+ trail_files+=("$f")
21
+ done < <(find "$TRAILS_DIR" -maxdepth 1 -type f -print0 | sort -z)
22
+
23
+ count=${#trail_files[@]}
24
+
25
+ if [ "$count" -le "$MAX_COUNT" ]; then
26
+ echo '{"archived":0,"remaining":'"$count"'}'
27
+ exit 0
28
+ fi
29
+
30
+ # Archive oldest files beyond MAX_COUNT
31
+ to_archive=$((count - MAX_COUNT))
32
+ archive_month=$(date -u +%Y-%m)
33
+ archive_dest="$ARCHIVE_DIR/$archive_month"
34
+ mkdir -p "$archive_dest"
35
+
36
+ archived=0
37
+ for ((i=0; i<to_archive; i++)); do
38
+ file="${trail_files[$i]}"
39
+ mv "$file" "$archive_dest/"
40
+ ((archived++))
41
+ done
42
+
43
+ remaining=$((count - archived))
44
+ echo '{"archived":'"$archived"',"remaining":'"$remaining"',"archive_path":"'"$archive_dest"'"}'
@@ -0,0 +1,91 @@
1
+ #!/usr/bin/env bash
2
+ # generate-prd-traceability.sh — planning.md ↔ PRD 추적성 매트릭스 생성
3
+ # Usage: bash .timsquad/scripts/generate-prd-traceability.sh [project_root]
4
+ # Output: .timsquad/reports/traceability-matrix.md
5
+ set -euo pipefail
6
+
7
+ ROOT="${1:-.}"
8
+ PRD="$ROOT/.timsquad/ssot/prd.md"
9
+ PLANNING="$ROOT/.timsquad/ssot/planning.md"
10
+ REPORT_DIR="$ROOT/.timsquad/reports"
11
+ OUTPUT="$REPORT_DIR/traceability-matrix.md"
12
+
13
+ if [ ! -f "$PRD" ]; then
14
+ echo '{"status":"skip","reason":"prd.md not found"}'
15
+ exit 0
16
+ fi
17
+
18
+ if [ ! -f "$PLANNING" ]; then
19
+ echo '{"status":"skip","reason":"planning.md not found"}'
20
+ exit 0
21
+ fi
22
+
23
+ mkdir -p "$REPORT_DIR"
24
+
25
+ # Extract PRD feature sections (## headings)
26
+ prd_features=()
27
+ while IFS= read -r line; do
28
+ if [[ "$line" =~ ^##[[:space:]]+(.+) ]]; then
29
+ prd_features+=("${BASH_REMATCH[1]}")
30
+ fi
31
+ done < "$PRD"
32
+
33
+ # Extract planning tasks with their phase/sequence context
34
+ declare -A task_map
35
+ current_phase=""
36
+ current_seq=""
37
+
38
+ while IFS= read -r line; do
39
+ if [[ "$line" =~ ^##[[:space:]]+Phase.*\(([A-Z][0-9]+)\) ]]; then
40
+ current_phase="${BASH_REMATCH[1]}"
41
+ elif [[ "$line" =~ ^##[[:space:]]+.+\(([A-Z][0-9]+-S[0-9]+)\) ]]; then
42
+ current_seq="${BASH_REMATCH[1]}"
43
+ elif [[ "$line" =~ ^###[[:space:]]+(.+)\(([A-Z][0-9]+-S[0-9]+-T[0-9]+)\) ]]; then
44
+ task_title="${BASH_REMATCH[1]}"
45
+ task_id="${BASH_REMATCH[2]}"
46
+ task_map["$task_id"]="$current_phase | $current_seq | $task_title"
47
+ fi
48
+ done < "$PLANNING"
49
+
50
+ # Generate traceability matrix
51
+ {
52
+ echo "# PRD Traceability Matrix"
53
+ echo ""
54
+ echo "> Generated: $(date -u +%Y-%m-%dT%H:%M:%SZ)"
55
+ echo ""
56
+ echo "| PRD Feature | Mapped Tasks | Coverage |"
57
+ echo "|-------------|-------------|----------|"
58
+
59
+ mapped=0
60
+ total=${#prd_features[@]}
61
+
62
+ for feature in "${prd_features[@]}"; do
63
+ # Find tasks that reference this feature (case-insensitive partial match)
64
+ feature_lower=$(echo "$feature" | tr '[:upper:]' '[:lower:]')
65
+ matching_tasks=""
66
+
67
+ for task_id in "${!task_map[@]}"; do
68
+ task_lower=$(echo "${task_map[$task_id]}" | tr '[:upper:]' '[:lower:]')
69
+ if [[ "$task_lower" == *"$feature_lower"* ]] || [[ "$feature_lower" == *"$task_lower"* ]]; then
70
+ matching_tasks+="$task_id "
71
+ fi
72
+ done
73
+
74
+ if [ -n "$matching_tasks" ]; then
75
+ echo "| $feature | $(echo "$matching_tasks" | xargs | tr ' ' ', ') | Mapped |"
76
+ ((mapped++))
77
+ else
78
+ echo "| $feature | — | **Unmapped** |"
79
+ fi
80
+ done
81
+
82
+ echo ""
83
+ if [ "$total" -gt 0 ]; then
84
+ coverage=$((mapped * 100 / total))
85
+ echo "**Coverage:** $mapped / $total ($coverage%)"
86
+ else
87
+ echo "**Coverage:** No PRD features found"
88
+ fi
89
+ } > "$OUTPUT"
90
+
91
+ echo '{"status":"ok","output":"'"$OUTPUT"'","features":'"$total"',"mapped":'"$mapped"'}'
@@ -0,0 +1,83 @@
1
+ #!/usr/bin/env bash
2
+ # manage-fp-registry.sh — audit False Positive 자동 필터링
3
+ # Usage: bash .timsquad/scripts/manage-fp-registry.sh [project_root]
4
+ # bash .timsquad/scripts/manage-fp-registry.sh . add "pattern-id"
5
+ # bash .timsquad/scripts/manage-fp-registry.sh . exclude "pattern-id"
6
+ # Output: JSON fp-registry
7
+ set -euo pipefail
8
+
9
+ ROOT="${1:-.}"
10
+ ACTION="${2:-scan}"
11
+ PATTERN_ID="${3:-}"
12
+ REGISTRY="$ROOT/.timsquad/retrospective/fp-registry.json"
13
+ RETRO_DIR="$ROOT/.timsquad/retrospective"
14
+
15
+ if ! command -v jq &>/dev/null; then
16
+ echo '{"error":"jq is required"}' >&2
17
+ exit 1
18
+ fi
19
+
20
+ # Initialize registry if missing
21
+ if [ ! -f "$REGISTRY" ]; then
22
+ mkdir -p "$RETRO_DIR"
23
+ echo '{"patterns":[],"excluded":[]}' > "$REGISTRY"
24
+ fi
25
+
26
+ case "$ACTION" in
27
+ scan)
28
+ # Scan retrospective cycles for repeated feedback patterns
29
+ CYCLES_DIR="$RETRO_DIR/cycles"
30
+ if [ ! -d "$CYCLES_DIR" ]; then
31
+ cat "$REGISTRY"
32
+ exit 0
33
+ fi
34
+
35
+ # Count feedback pattern occurrences across cycles
36
+ pattern_counts=$(find "$CYCLES_DIR" -name '*.json' -type f -exec \
37
+ jq -r '.problem[]? // empty' {} \; 2>/dev/null | \
38
+ sort | uniq -c | sort -rn | head -20)
39
+
40
+ # Update registry: patterns with 3+ occurrences → candidate FP
41
+ while IFS= read -r line; do
42
+ [ -z "$line" ] && continue
43
+ count=$(echo "$line" | awk '{print $1}')
44
+ pattern=$(echo "$line" | sed 's/^[[:space:]]*[0-9]*[[:space:]]*//')
45
+ [ "$count" -lt 3 ] && continue
46
+
47
+ # Add/update in registry
48
+ existing=$(jq -r --arg p "$pattern" '.patterns[] | select(.id == $p) | .id' "$REGISTRY" 2>/dev/null)
49
+ if [ -z "$existing" ]; then
50
+ jq --arg p "$pattern" --argjson c "$count" \
51
+ '.patterns += [{"id": $p, "count": $c, "last_occurrence": (now | todate)}]' \
52
+ "$REGISTRY" > "$REGISTRY.tmp" && mv "$REGISTRY.tmp" "$REGISTRY"
53
+ else
54
+ jq --arg p "$pattern" --argjson c "$count" \
55
+ '(.patterns[] | select(.id == $p)) |= (.count = $c | .last_occurrence = (now | todate))' \
56
+ "$REGISTRY" > "$REGISTRY.tmp" && mv "$REGISTRY.tmp" "$REGISTRY"
57
+ fi
58
+ done <<< "$pattern_counts"
59
+
60
+ cat "$REGISTRY"
61
+ ;;
62
+
63
+ add)
64
+ [ -z "$PATTERN_ID" ] && { echo '{"error":"pattern id required"}' >&2; exit 1; }
65
+ jq --arg p "$PATTERN_ID" \
66
+ 'if (.patterns | map(.id) | index($p)) then . else .patterns += [{"id": $p, "count": 1, "last_occurrence": (now | todate)}] end' \
67
+ "$REGISTRY" > "$REGISTRY.tmp" && mv "$REGISTRY.tmp" "$REGISTRY"
68
+ cat "$REGISTRY"
69
+ ;;
70
+
71
+ exclude)
72
+ [ -z "$PATTERN_ID" ] && { echo '{"error":"pattern id required"}' >&2; exit 1; }
73
+ jq --arg p "$PATTERN_ID" \
74
+ 'if (.excluded | index($p)) then . else .excluded += [$p] end' \
75
+ "$REGISTRY" > "$REGISTRY.tmp" && mv "$REGISTRY.tmp" "$REGISTRY"
76
+ cat "$REGISTRY"
77
+ ;;
78
+
79
+ *)
80
+ echo '{"error":"unknown action: '"$ACTION"'. Use scan|add|exclude"}' >&2
81
+ exit 1
82
+ ;;
83
+ esac
@@ -0,0 +1,113 @@
1
+ #!/usr/bin/env bash
2
+ # validate-gherkin.sh — BDD feature 파일 구문 검증
3
+ # Usage: bash .timsquad/scripts/validate-gherkin.sh [features_dir]
4
+ # Output: JSON {valid, errors, total_files}
5
+ set -euo pipefail
6
+
7
+ FEATURES_DIR="${1:-features}"
8
+
9
+ if [ ! -d "$FEATURES_DIR" ]; then
10
+ echo '{"valid":true,"errors":[],"total_files":0,"reason":"features directory not found"}'
11
+ exit 0
12
+ fi
13
+
14
+ errors=()
15
+ total=0
16
+
17
+ while IFS= read -r file; do
18
+ ((total++))
19
+ line_num=0
20
+ has_feature=false
21
+ has_scenario=false
22
+ in_scenario=false
23
+ step_order="" # track Given/When/Then order
24
+
25
+ while IFS= read -r line; do
26
+ ((line_num++))
27
+ trimmed=$(echo "$line" | sed 's/^[[:space:]]*//')
28
+
29
+ # Skip empty lines and comments
30
+ [[ -z "$trimmed" || "$trimmed" == \#* ]] && continue
31
+
32
+ # Feature keyword
33
+ if [[ "$trimmed" =~ ^Feature:[[:space:]]*.+ ]]; then
34
+ has_feature=true
35
+ continue
36
+ fi
37
+
38
+ # Scenario / Scenario Outline
39
+ if [[ "$trimmed" =~ ^(Scenario|Scenario\ Outline):[[:space:]]*.+ ]]; then
40
+ has_scenario=true
41
+ in_scenario=true
42
+ step_order=""
43
+ continue
44
+ fi
45
+
46
+ # Step keywords
47
+ if [[ "$trimmed" =~ ^(Given|When|Then|And|But)[[:space:]]+ ]]; then
48
+ keyword="${BASH_REMATCH[1]}"
49
+ if [[ "$keyword" == "Given" ]]; then
50
+ if [[ "$step_order" == *"Then"* ]]; then
51
+ errors+=("{\"file\":\"$file\",\"line\":$line_num,\"msg\":\"Given after Then\"}")
52
+ fi
53
+ step_order+="Given "
54
+ elif [[ "$keyword" == "When" ]]; then
55
+ step_order+="When "
56
+ elif [[ "$keyword" == "Then" ]]; then
57
+ step_order+="Then "
58
+ fi
59
+ continue
60
+ fi
61
+
62
+ # Examples keyword (only valid in Scenario Outline)
63
+ if [[ "$trimmed" =~ ^Examples: ]]; then
64
+ continue
65
+ fi
66
+
67
+ # Table rows
68
+ if [[ "$trimmed" =~ ^\| ]]; then
69
+ continue
70
+ fi
71
+
72
+ # Tags
73
+ if [[ "$trimmed" =~ ^@ ]]; then
74
+ continue
75
+ fi
76
+
77
+ # Background
78
+ if [[ "$trimmed" =~ ^Background: ]]; then
79
+ continue
80
+ fi
81
+
82
+ # Rule (Gherkin 6)
83
+ if [[ "$trimmed" =~ ^Rule:[[:space:]]*.+ ]]; then
84
+ continue
85
+ fi
86
+
87
+ # Doc strings
88
+ if [[ "$trimmed" == '"""' || "$trimmed" == '```' ]]; then
89
+ continue
90
+ fi
91
+
92
+ done < "$file"
93
+
94
+ # Validate structure
95
+ if ! $has_feature; then
96
+ errors+=("{\"file\":\"$file\",\"line\":1,\"msg\":\"Missing Feature keyword\"}")
97
+ fi
98
+ if ! $has_scenario; then
99
+ errors+=("{\"file\":\"$file\",\"line\":1,\"msg\":\"No Scenario defined\"}")
100
+ fi
101
+
102
+ done < <(find "$FEATURES_DIR" -name '*.feature' -type f | sort)
103
+
104
+ # Build JSON output
105
+ if [ ${#errors[@]} -eq 0 ]; then
106
+ echo '{"valid":true,"errors":[],"total_files":'"$total"'}'
107
+ exit 0
108
+ else
109
+ error_json=$(printf '%s,' "${errors[@]}")
110
+ error_json="[${error_json%,}]"
111
+ echo '{"valid":false,"errors":'"$error_json"',"total_files":'"$total"'}'
112
+ exit 1
113
+ fi
@@ -4,39 +4,63 @@ description: |
4
4
  Context DI 컨테이너. 서브에이전트 위임 시 compiled spec을 의존성으로 주입.
5
5
  서브에이전트 호출, Task() 위임, 에이전트 실행 시 자동 트리거.
6
6
  Use when: "구현해줘", "테스트해줘", "리뷰해줘", "설계해줘", 서브에이전트 위임
7
- version: "2.1.0"
8
- tags: [tsq, controller, di, context-injection]
7
+ version: "3.0.0"
8
+ tags: [tsq, controller, di, context-injection, hybrid]
9
9
  user-invocable: false
10
10
  ---
11
11
 
12
- # Controller (Context DI Container)
12
+ # Controller (Hybrid — Context DI + CLI)
13
13
 
14
14
  서브에이전트에게 작업을 위임할 때 컨텍스트를 자동 해석하고 주입하는 컨테이너.
15
+ v3.0: 결정론적 로직(상태, 순서, 게이트)은 `tsq next` CLI로 이동. Controller는 판단(스펙 결정, 품질 평가, 프롬프트 구성)에 집중.
15
16
 
16
17
  ## Contract
17
18
 
18
19
  - **Trigger**: 서브에이전트 위임 시 (구현, 테스트, 리뷰 등)
19
- - **Input**: 에이전트 파일 + prerequisites + compiled specs
20
+ - **Input**: `tsq next` JSON + 에이전트 파일 + compiled specs
20
21
  - **Output**: 조합된 프롬프트로 Task() 실행
21
22
  - **Error**: spec stale 시 `tsq compile` 재실행 안내
22
23
 
23
24
  ## Protocol
24
25
 
25
- 1. **Memory 참조**: `memory/` 디렉토리의 모든 .md 파일 Read
26
- 2. **SSOT Map 참조**: `.timsquad/ssot-map.yaml` → 티어 compiled spec 목록 확인
27
- 3. **Capability Token 발급**: `.timsquad/state/controller-active` + `allowed-paths.txt` 생성
28
- 4. **에이전트 파일 확인**: `.claude/agents/{agent}.md` 읽기
29
- 5. **Prerequisites 파싱**: `<prerequisites>` 태그에서 SSOT 목록 추출
30
- 6. **Spec Resolve**: `references/`에서 해당 compiled spec 로드
31
- 7. **Stale 체크**: `.compile-manifest.json` hash 비교
32
- 8. **방법론 참조**: `config.yaml`의 `methodology.development` → 해당 스킬 Protocol 로드
33
- 9. **프롬프트 조합**: tsq-protocol + **phase-memory carry-over** + memory + specs + methodology + phase 제약 + 지시
34
- - `.timsquad/state/phase-memory.md` 존재 carry-over/주의 섹션을 프롬프트 앞에 강제 삽입
35
- - 미존재 스킵 (초기 프로젝트)
36
- 10. **Task() 호출**: 조합된 프롬프트로 서브에이전트 실행. 에이전트 파일의 `model` 필드가 있으면 Task()의 model 파라미터로 전달 (예: model: sonnet → 빠른 모델, model: opus → 정밀 모델)
37
- 11. **Completion Report 검증**: 5개 필드(Task, Status, Files, Tests, Notes) 확인 — 누락 시 재요청
38
- 12. **완료 트리거**: Triggers 섹션의 해당 규칙 수행
39
- 13. **Capability Token 회수**: `controller-active` + `allowed-paths.txt` 삭제
26
+ 1. **다음 태스크 조회**: `tsq next` 실행 JSON 출력에서 taskId, phaseId, sequenceId, title, agent 추출
27
+ - `all_complete`사용자에게 완료 안내
28
+ - `error` planning.md 부재 `/tsq-decompose` 안내
29
+ 2. **Task Context 기록**: `.timsquad/.daemon/task-context.json`에 현재 태스크 정보 저장 (SubagentStop hook이 읽음)
30
+ 3. **Memory 참조**: `memory/` 디렉토리의 모든 .md 파일 Read
31
+ 4. **SSOT Map 참조**: `.timsquad/ssot-map.yaml` 티어 compiled spec 목록 확인
32
+ 5. **Capability Token 발급**: `.timsquad/state/controller-active` + `allowed-paths.txt` 생성
33
+ 6. **에이전트 파일 확인**: `.claude/agents/{agent}.md` 읽기
34
+ 7. **Prerequisites 파싱**: `<prerequisites>` 태그에서 SSOT 목록 추출
35
+ 8. **Spec Resolve**: `references/`에서 해당 compiled spec 로드
36
+ 9. **Meta Index 쿼리**: `.timsquad/.daemon/task-context.json` 읽기 scope 파일 구조를 프롬프트에 주입 (Daemon이 자동 갱신)
37
+ 10. **Stale 체크**: `.compile-manifest.json` hash 비교
38
+ 11. **방법론 참조**: `config.yaml`의 `methodology.development` 해당 스킬 Protocol 로드
39
+ 12. **프롬프트 조합**: tsq-protocol + **phase-memory carry-over** + memory + specs + meta-index scope + methodology + phase 제약 + 지시
40
+ - `.timsquad/state/phase-memory.md` 존재 carry-over/주의 섹션을 프롬프트 앞에 강제 삽입
41
+ 13. **Model Routing → Task() 호출**: Model Routing 테이블에 따라 최종 모델을 결정한 뒤, 조합된 프롬프트로 서브에이전트 실행. 결정된 모델을 Task()의 model 파라미터로 전달
42
+ 14. **Completion Report 검증**: 5개 필드(Task, Status, Files, Tests, Notes) 확인 — 누락 시 재요청
43
+ 15. **Capability Token 회수**: `controller-active` + `allowed-paths.txt` 삭제
44
+ 16. **다음 태스크**: Step 1로 돌아가서 반복 (또는 Phase 완료 시 Librarian 호출)
45
+
46
+ > 이전(v2.1)에서 Controller가 직접 하던 작업의 코드 이동:
47
+ > - ~~planning.md 파싱~~ → `tsq next` CLI (결정론적)
48
+ > - ~~workflow.json 갱신~~ → SubagentStop hook이 `tsq next --complete` 자동 호출
49
+ > - ~~Phase 완료 판정~~ → completion-guard hook이 `tsq next --phase-status` 호출
50
+ > - ~~phase-memory append~~ → SubagentStop hook이 자동 append
51
+
52
+ ## Model Routing
53
+
54
+ `references/model-routing.md` 참조. `config.yaml`의 `model_routing` 설정(enabled, strategy)에 따라 태스크 복잡도 기반 모델 동적 선택.
55
+ - **aggressive**: 최대 haiku 사용 (비용 최적화)
56
+ - **balanced**: phase 적합 모델 (기본값)
57
+ - **conservative**: 최대 opus 사용 (품질 우선, fintech 기본)
58
+
59
+ ## Wave Dispatch (병렬)
60
+
61
+ `references/wave-dispatch.md` 참조. `tsq next --wave`로 독립 태스크를 Wave로 묶어 동시 실행.
62
+ - `waveSize > 1` → 병렬 Task() 호출, 태스크별 Capability Token 개별 발급
63
+ - `waveSize === 1` → 기존 순차 Protocol 따름
40
64
 
41
65
  ## Delegation Rules
42
66
 
@@ -47,28 +71,27 @@ user-invocable: false
47
71
 
48
72
  ## Triggers
49
73
 
50
- 동기(Controller) = 프로세스 강제, 게이트 판정. 비동기(Daemon) = 관찰, 로그 기록. Daemon 장애 시 Controller는 정상 동작.
74
+ 코드 강제(Hook/CLI) + LLM 판단(Controller) 하이브리드. Daemon 장애 시 Controller는 정상 동작.
51
75
 
52
- ### task-complete (동기)
53
- 1. **Completion Report 검증** 5개 필드(Task, Status, Files, Tests, Notes) 확인, 누락 재요청
54
- 2. **단위 테스트 확인** — Status=pass 필수, fail 시 Developer에 재위임
55
- 3. **L1 로그 + Decision Log 확인** Daemon이 L1 생성 (SubagentStop Hook). Daemon 장애 Controller가 수동 기록
56
- 4. **workflow.json 갱신**`.timsquad/state/workflow.json`에 완료된 task/sequence/phase 상태 기록 (compact 후 재개 진행 상태 복구용)
57
- 5. **Sequence 완료 판정**: 해당 sequence의 expected_agents 모두 완료 sequence-complete
58
- 6. **미완료 시**: 다음 태스크 위임. planning.md의 해당 Task 산출물(출력 파일)이 이미 존재하면 스킵하고 그 다음 Task로 진행 (세션 재개 시 중복 작업 방지)
76
+ ### task-complete
77
+ - **Hook 자동 처리**: SubagentStop hook `tsq next --complete` workflow.json 갱신 + phase-memory append
78
+ - **Controller 판단** (LLM):
79
+ 1. Completion Report 검증5필드 확인, 누락재요청
80
+ 2. 단위 테스트 확인 Status=pass 필수, failDeveloper에 재위임
81
+ 3. L1 로그 확인 Daemon이 L1 생성 (SubagentStop Hook). Daemon 장애 시 수동 기록
82
+ 4. 다음 태스크 `tsq next` 실행하여 다음 미완료 태스크로 진행
59
83
 
60
- ### sequence-complete (동기)
84
+ ### sequence-complete
61
85
  1. **통합 게이트**: `npm run test:integration` + `tsc --noEmit` — 실패 시 차단, Developer에 수정 위임
62
86
  2. **L2 로그 확인**: `.timsquad/logs/sequences/{seq-id}.md` 존재 확인
63
- 3. **문서 갱신 체크**: ROADMAP/STATUS/CHANGELOG stale 여부 (7일 이상 미수정 경고)
64
- 3.5. **Spec Compliance 체크**: 해당 Sequence의 Sub-PRD Must-Have 목록과 완료된 Task 산출물을 대조. 누락 항목이 있으면 경고 표시 (block 아님 — 다른 Sequence나 Phase에서 처리 가능). 경고 내용을 L2 로그에 기록
65
- 4. **Phase 완료 판정**: 모든 시퀀스 완료 → phase-complete
66
-
67
- ### phase-complete (동기)
68
- 1. **E2E 게이트**: `npm run test:e2e` — 실패 시 차단
69
- 2. **L3 로그 + Phase Gate 확인**: `.timsquad/logs/phases/{phase-id}.md` 존재
70
- 3. **Librarian 호출**: Task(librarian) Phase Memory 아카이브 + 새 HEAD 생성 + Trail + 리포트
71
- 4. **사용자 안내**: "Phase {id} 완료. 다음 단계: (1) `/tsq-retro` — 회고 실행, (2) `/clear` — 컨텍스트 초기화 (phase-memory 자동 주입됩니다)"
87
+ 3. **Spec Compliance 체크**: Sub-PRD Must-Have vs 완료 산출물 대조 (경고, block 아님)
88
+
89
+ ### phase-complete
90
+ - **Hook 자동 감지**: completion-guard → `tsq next --phase-status` → Phase 완료 시 systemMessage로 안내
91
+ - **Controller 판단** (LLM):
92
+ 1. E2E 게이트: `npm run test:e2e` — 실패 시 차단
93
+ 2. Librarian 호출: Task(librarian) Phase Memory 아카이브 + 새 HEAD 생성
94
+ 3. 사용자 안내: "`/tsq-retro` `/clear`"
72
95
 
73
96
  ### ssot-changed (비동기, Daemon 전담)
74
97
  Daemon이 파일 감시로 `.compile-manifest.json` 갱신. 다음 Controller 실행 시 Stale 체크로 감지.
@@ -0,0 +1,38 @@
1
+ ---
2
+ title: Model Routing
3
+ category: reference
4
+ ---
5
+
6
+ # Model Routing Reference
7
+
8
+ `config.yaml`의 `model_routing.enabled`가 `true`이면 아래 테이블에 따라 모델을 동적 선택.
9
+ `false`이면 에이전트 파일의 `model` 필드(기본값)를 그대로 사용.
10
+
11
+ ## Strategy별 라우팅 테이블
12
+
13
+ | 에이전트 | 태스크 유형 | aggressive | balanced | conservative |
14
+ |---------|-----------|-----------|----------|-------------|
15
+ | **Architect** | 설계/리뷰 | sonnet | opus | opus |
16
+ | **Developer** | 복잡한 구현 (아키텍처 변경, 복잡한 비즈니스 로직) | sonnet | sonnet | opus |
17
+ | **Developer** | 일반 구현 | haiku | sonnet | sonnet |
18
+ | **Developer** | 단순 구현 (CRUD, 스캐폴딩, 보일러플레이트) | haiku | haiku | sonnet |
19
+ | **QA** | 코드 리뷰 | haiku | sonnet | opus |
20
+ | **Security** | 보안 검토 | sonnet | sonnet | opus |
21
+ | **DBA** | DB 설계/마이그레이션 | sonnet | sonnet | opus |
22
+ | **Designer** | UI/UX 설계 | haiku | sonnet | sonnet |
23
+ | **Librarian** | 문서 기록 | haiku | haiku | sonnet |
24
+
25
+ ## 복잡도 판정 기준
26
+
27
+ - **복잡**: 아키텍처 결정, 다중 모듈 연동, 상태 머신, 보안 로직, 트랜잭션
28
+ - **일반**: 단일 모듈 기능 구현, API 엔드포인트, 컴포넌트 개발
29
+ - **단순**: CRUD, 설정 파일 수정, 타입 정의, 보일러플레이트, 문서 갱신
30
+
31
+ ## 적용 절차
32
+
33
+ 1. `config.yaml` → `model_routing` 섹션 읽기
34
+ 2. `enabled: false`이면 에이전트 기본 모델 사용 → 종료
35
+ 3. 태스크 설명 + phase에서 복잡도 판정 (복잡/일반/단순)
36
+ 4. 라우팅 테이블에서 `strategy` 열의 모델 선택
37
+ 5. 선택된 모델을 Task()의 `model` 파라미터로 전달
38
+ 6. Completion Report 첫 줄에 `[MODEL: {selected}]` 표기
@@ -0,0 +1,50 @@
1
+ ---
2
+ title: Wave Dispatch
3
+ category: reference
4
+ ---
5
+
6
+ # Wave Dispatch — 병렬 서브에이전트 실행
7
+
8
+ ## 개요
9
+
10
+ `tsq next --wave` 실행 시 의존성이 충족된 독립 태스크를 Wave로 반환.
11
+ Controller는 Wave 내 태스크를 동시에 Task() 호출하여 속도를 3-5x 향상.
12
+
13
+ ## 프로토콜
14
+
15
+ 1. `tsq next --wave` 실행 → `{ wave: [...tasks], waveSize, parallel }` JSON
16
+ 2. `waveSize === 1` → 단일 태스크, 기존 순차 Protocol 12-16 따름
17
+ 3. `waveSize > 1` → 병렬 디스패치:
18
+ a. 각 태스크에 대해 개별 Capability Token 발급 (`.timsquad/state/cap-{taskId}`)
19
+ b. 각 태스크의 Model Routing 독립 수행
20
+ c. 모든 Task()를 동시 호출 (Agent tool 병렬 호출)
21
+ d. 모든 완료 후 각 Completion Report 검증
22
+ e. 개별 Capability Token 회수
23
+ 4. Wave 완료 → 다시 Step 1로 (다음 Wave 조회)
24
+
25
+ ## 의존성 분석 규칙
26
+
27
+ - `dependencies` 없는 태스크: 즉시 실행 가능
28
+ - `dependencies` 있는 태스크: 모든 선행 태스크 완료 후 실행 가능
29
+ - 같은 Sequence 내 태스크도 의존성 없으면 병렬 가능
30
+ - 순환 의존성 감지 시: fallback으로 첫 번째 태스크만 반환
31
+
32
+ ## Capability Token (병렬)
33
+
34
+ ```
35
+ # 순차 (기존)
36
+ .timsquad/state/controller-active
37
+ .timsquad/state/allowed-paths.txt
38
+
39
+ # 병렬 (Wave)
40
+ .timsquad/state/cap-P1-S001-T001
41
+ .timsquad/state/cap-P1-S001-T002
42
+ ```
43
+
44
+ 병렬 실행 시 각 태스크에 독립 토큰을 발급하여 격리. 완료 시 개별 회수.
45
+
46
+ ## 제약
47
+
48
+ - 같은 Phase 내 태스크만 Wave로 묶음 (Phase 간 병렬 불가)
49
+ - Wave 내 태스크가 같은 파일을 수정하면 충돌 가능 — outputs 필드로 사전 감지
50
+ - Wave 크기 상한: 5 (Claude Code 동시 에이전트 제한)
@@ -0,0 +1,70 @@
1
+ ---
2
+ name: tsq-full
3
+ description: |
4
+ Controller 경유 풀 파이프라인 실행. Phase-Sequence-Task DAG를 순차적으로 진행하며
5
+ 각 단계마다 게이트 검증(unit→integration→e2e), Librarian 기록, Phase Memory carry-over를 수행한다.
6
+ 세션이 끊겨도 workflow.json에서 마지막 위치를 복원하여 이어서 진행한다.
7
+ Use when: "/tsq-full", "전체 구현", "풀 파이프라인", "본격적으로 시작",
8
+ "새 기능 개발", "인증 시스템 구현", "결제 모듈 만들어", "대규모 리팩토링",
9
+ "Phase 진행", "Phase 2부터", "파이프라인 재개", "이어서 진행",
10
+ 또는 planning.md 기반으로 여러 태스크를 연속 실행해야 할 때.
11
+ 다단계 기능, 여러 파일/모듈에 걸친 구현, 아키텍처 변경이면 이 스킬을 사용한다.
12
+ version: "1.0.0"
13
+ tags: [tsq, full, controller, pipeline]
14
+ user-invocable: true
15
+ ---
16
+
17
+ # /tsq-full — Controller 경유 풀 파이프라인
18
+
19
+ Phase-Sequence-Task 전체 워크플로우를 Controller 경유로 실행한다.
20
+ planning.md 기반으로 체계적 구현, 게이트 검증, Librarian 기록까지 수행하는 이유:
21
+ 다단계 작업에서 각 Phase의 산출물이 다음 Phase의 입력이 되므로, 게이트로 품질을 보장하지 않으면
22
+ 후속 작업에서 누적 결함이 발생하기 때문이다.
23
+
24
+ ## Pre-conditions
25
+
26
+ 1. **planning.md 필수**: `.timsquad/ssot/planning.md` 존재 확인
27
+ - 없으면 → "`/tsq-decompose`로 실행 계획을 먼저 생성하세요" 안내
28
+ 2. **SSOT 충족**: PRD + requirements 최소 작성 완료
29
+ - 미충족 → "`/tsq-start`로 온보딩을 먼저 진행하세요" 안내
30
+
31
+ ## Protocol
32
+
33
+ 1. **다음 태스크 조회**: `tsq next` CLI 실행 → 다음 미완료 태스크 JSON 확인
34
+ - `all_complete` → 모든 태스크 완료. 사용자에게 안내
35
+ - `error: planning.md not found` → `/tsq-decompose` 안내
36
+ 2. **Controller 풀 실행** (tsq-controller Protocol 전체 수행):
37
+ - `tsq next`가 반환한 태스크부터 순차 진행
38
+ - Sequence 내 Task 위임 (Developer → QA)
39
+ - 게이트 검증: unit → integration → e2e
40
+ - Librarian 호출 (Phase 완료 시)
41
+ - Phase Memory carry-over
42
+ 3. **Phase 완료 안내**: "`/tsq-retro` 회고 → `/clear` 컨텍스트 초기화"
43
+
44
+ > workflow.json 갱신은 SubagentStop hook이 `tsq next --complete`를 자동 호출하여 처리.
45
+ > Phase 완료 감지는 completion-guard hook이 `tsq next --phase-status`를 호출하여 처리.
46
+
47
+ ## Resumption
48
+
49
+ 세션이 끊긴 후 `/tsq-full`을 다시 실행하면:
50
+ - `tsq next`가 workflow.json 기반으로 다음 미완료 Task를 자동 결정
51
+ - 이미 완료된 Task는 자동 스킵
52
+ - 컨텍스트 압축 후에도 phase-memory.md의 Progress 섹션에서 진행 상황 복원
53
+
54
+ ## vs /tsq-quick
55
+
56
+ | 항목 | /tsq-full | /tsq-quick |
57
+ |------|-----------|-----------|
58
+ | Phase-Sequence-Task | O (전체) | X (단일) |
59
+ | Controller 경유 | O | O |
60
+ | SSOT/메모리 참조 | O | O |
61
+ | 게이트 | unit → integration → e2e | unit만 |
62
+ | Librarian 호출 | O | X |
63
+ | planning.md 필요 | O | X |
64
+
65
+ ## Usage
66
+
67
+ ```
68
+ /tsq-full
69
+ /tsq-full Phase 2부터 재개
70
+ ```