timsquad 3.7.1 → 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 (91) hide show
  1. package/README.ko.md +3 -2
  2. package/README.md +39 -4
  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 +16 -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 +13 -2
  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 +12 -9
  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-start/SKILL.md +17 -44
  78. package/templates/base/skills/tsq-start/references/onboarding-steps.md +85 -0
  79. package/templates/platforms/claude-code/scripts/build-gate.sh +25 -2
  80. package/templates/platforms/claude-code/scripts/check-capability.sh +41 -10
  81. package/templates/platforms/claude-code/scripts/completion-guard.sh +79 -3
  82. package/templates/platforms/claude-code/scripts/detect-env.sh +124 -0
  83. package/templates/platforms/claude-code/scripts/stale-guard.sh +47 -0
  84. package/templates/platforms/claude-code/scripts/subagent-stop.sh +41 -2
  85. package/templates/platforms/claude-code/scripts/tdd-guard.sh +57 -0
  86. package/templates/platforms/claude-code/scripts/validate-completion-report.sh +86 -0
  87. package/templates/platforms/claude-code/settings.json +10 -0
  88. package/templates/project-types/fintech/config.yaml +1 -1
  89. package/templates/project-types/mobile-app/config.yaml +1 -1
  90. package/templates/project-types/web-app/config.yaml +1 -1
  91. package/templates/project-types/web-service/config.yaml +1 -1
package/README.ko.md CHANGED
@@ -68,7 +68,7 @@ tsq init -n my-app -t web-service -l 2 -y # 비대화형
68
68
  my-app/
69
69
  ├── CLAUDE.md # PM 역할 (자동 주입 ~15줄)
70
70
  ├── .claude/
71
- │ ├── settings.json # Claude Code 설정 (8개 Hook)
71
+ │ ├── settings.json # Claude Code 설정 (13개 Hook)
72
72
  │ ├── rules/ # 경로별 규칙 (15개)
73
73
  │ ├── agents/ # 7개 전문 에이전트
74
74
  │ │ ├── tsq-architect.md # 아키텍처 설계
@@ -96,6 +96,7 @@ my-app/
96
96
  ├── ssot/ # SSOT 문서 (레벨별 5~14개)
97
97
  ├── process/ # 워크플로우 정의
98
98
  ├── state/ # 상태 관리
99
+ ├── scripts/ # 자동화 스크립트 (6개)
99
100
  ├── trails/ # Phase 사고과정 아카이브
100
101
  ├── logs/ # 3계층 로그 (L1→L2→L3)
101
102
  └── retrospective/ # 회고 데이터
@@ -190,7 +191,7 @@ Layer 5: 감사 (비동기 사후 추적)
190
191
  | **방법론** | `tsq-tdd`, `tsq-bdd`, `tsq-ddd`, `tsq-debugging` |
191
192
  | **운영** | `tsq-librarian`, `tsq-log`, `tsq-retro`, `tsq-prompt` |
192
193
 
193
- ### 8개 Hook Gate
194
+ ### 13개 Hook Gate
194
195
 
195
196
  | Hook | 스크립트 | 역할 | 전략 |
196
197
  |------|---------|------|------|
package/README.md CHANGED
@@ -68,7 +68,7 @@ tsq init -n my-app -t web-service -l 2 -y # Non-interactive
68
68
  my-app/
69
69
  ├── CLAUDE.md # PM role (auto-injected ~15 lines)
70
70
  ├── .claude/
71
- │ ├── settings.json # Claude Code settings (8 hooks)
71
+ │ ├── settings.json # Claude Code settings (13 hooks)
72
72
  │ ├── rules/ # Path-specific rules (15)
73
73
  │ ├── agents/ # 7 specialized agents
74
74
  │ │ ├── tsq-architect.md # Architecture design
@@ -96,6 +96,7 @@ my-app/
96
96
  ├── ssot/ # SSOT documents (5–14 per level)
97
97
  ├── process/ # Workflow definitions
98
98
  ├── state/ # State management
99
+ ├── scripts/ # Automation scripts (6)
99
100
  ├── trails/ # Phase thinking archives
100
101
  ├── logs/ # 3-tier logs (L1→L2→L3)
101
102
  └── retrospective/ # Retrospective data
@@ -121,6 +122,13 @@ claude # Launch Claude Code
121
122
  tsq init # Initialize project
122
123
  tsq update # Update skills/agents to latest
123
124
  tsq daemon start # Start background daemon
125
+ tsq next # Next task (Controller internal)
126
+ tsq next --wave # Parallel-dispatchable task batch
127
+ tsq plan validate # Validate planning.md
128
+ tsq spec check # Check SSOT freshness
129
+ tsq status # Project status summary
130
+ tsq retro # Retrospective metrics
131
+ tsq audit score # 7-area audit score
124
132
  ```
125
133
 
126
134
  > All other operations use Claude Code slash commands. See [CLI Reference](docs/cli.en.md).
@@ -190,7 +198,29 @@ All skills use `tsq-*` flat namespace and are available as slash commands:
190
198
  | **Methodology** | `tsq-tdd`, `tsq-bdd`, `tsq-ddd`, `tsq-debugging` |
191
199
  | **Operations** | `tsq-librarian`, `tsq-log`, `tsq-retro`, `tsq-prompt` |
192
200
 
193
- ### 8 Hook Gates
201
+ ### Model Routing
202
+
203
+ Controller dynamically selects the optimal model per task based on complexity:
204
+
205
+ | Strategy | Use Case | Cost Impact |
206
+ |----------|----------|-------------|
207
+ | `aggressive` | Maximize haiku usage | Highest savings |
208
+ | `balanced` | Phase-appropriate selection (default) | Moderate savings |
209
+ | `conservative` | Maximize opus usage (fintech default) | Quality priority |
210
+
211
+ ### Wave Dispatch (Parallel Execution)
212
+
213
+ Controller groups independent tasks into Waves for parallel execution:
214
+
215
+ ```bash
216
+ tsq next --wave # Returns batch of independent tasks
217
+ ```
218
+
219
+ - Tasks with no unmet dependencies run simultaneously
220
+ - 3-5x speed improvement on multi-task sequences
221
+ - Capability Token issued per task for isolation
222
+
223
+ ### 13 Hook Gates
194
224
 
195
225
  | Hook | Script | Role | Strategy |
196
226
  |------|--------|------|----------|
@@ -198,10 +228,15 @@ All skills use `tsq-*` flat namespace and are available as slash commands:
198
228
  | PreToolUse (Write\|Edit) | `phase-guard.sh` | Phase file restrictions | Fail-closed |
199
229
  | PreToolUse (Write\|Edit) | `check-capability.sh` | Capability Token verification | Fail-closed |
200
230
  | PreToolUse (Write\|Edit) | `change-scope-guard.sh` | Change scope tracking | Fail-open |
231
+ | PreToolUse (Write\|Edit) | `tdd-guard.sh` | TDD test file existence | Fail-open |
232
+ | PreToolUse (Write\|Edit) | `stale-guard.sh` | SSOT freshness check | Fail-open |
233
+ | SessionStart | `tsq daemon start` | Start background daemon | Fail-open |
234
+ | SessionStart (compact) | `context-restore.sh` | Restore context + SSOT readiness | Fail-closed |
201
235
  | Stop | `completion-guard.sh` | Test + TDD + SSOT check | Fail-closed |
202
236
  | Stop | `build-gate.sh` | TypeScript build errors | Fail-closed |
203
- | PreCompact | `pre-compact.sh` | Save state before compact | Fail-open |
204
- | SessionStart (compact) | `context-restore.sh` | Restore context + SSOT readiness | Fail-open |
237
+ | SubagentStart | `subagent-start.sh` | Notify daemon of agent start | Fail-open |
238
+ | SubagentStop | `subagent-stop.sh` | Auto-complete task + notify | Fail-open |
239
+ | PreCompact | `pre-compact.sh` | Save state before compact | Fail-closed |
205
240
 
206
241
  ### Daemon-Based Automation
207
242
 
@@ -0,0 +1,6 @@
1
+ /**
2
+ * tsq audit score — 7영역 감사 점수 자동 계산
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function registerAuditCommand(program: Command): void;
6
+ //# sourceMappingURL=audit.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAc3D"}
@@ -0,0 +1,111 @@
1
+ /**
2
+ * tsq audit score — 7영역 감사 점수 자동 계산
3
+ */
4
+ import path from 'path';
5
+ import { findProjectRoot } from '../lib/project.js';
6
+ import { exists } from '../utils/fs.js';
7
+ import fs from 'fs-extra';
8
+ export function registerAuditCommand(program) {
9
+ const cmd = program.command('audit').description('Audit management');
10
+ cmd
11
+ .command('score')
12
+ .description('Calculate 7-area audit score matrix')
13
+ .action(async () => {
14
+ try {
15
+ await runScore();
16
+ }
17
+ catch (error) {
18
+ console.log(JSON.stringify({ error: error.message }));
19
+ process.exit(1);
20
+ }
21
+ });
22
+ }
23
+ async function runScore() {
24
+ const projectRoot = await findProjectRoot();
25
+ if (!projectRoot)
26
+ throw new Error('TimSquad project not found.');
27
+ const areas = [
28
+ await checkSSOT(projectRoot),
29
+ await checkTesting(projectRoot),
30
+ await checkSecurity(projectRoot),
31
+ await checkProcess(projectRoot),
32
+ await checkDocumentation(projectRoot),
33
+ await checkArchitecture(projectRoot),
34
+ await checkMaintainability(projectRoot),
35
+ ];
36
+ const totalScore = areas.reduce((s, a) => s + a.score, 0);
37
+ const totalMax = areas.reduce((s, a) => s + a.maxScore, 0);
38
+ console.log(JSON.stringify({
39
+ overallScore: totalMax > 0 ? Math.round((totalScore / totalMax) * 100) : 0,
40
+ areas,
41
+ }, null, 2));
42
+ }
43
+ async function checkSSOT(root) {
44
+ const checks = [];
45
+ const ssotDir = path.join(root, '.timsquad', 'ssot');
46
+ checks.push({ name: 'prd.md 존재', passed: await exists(path.join(ssotDir, 'prd.md')) });
47
+ checks.push({ name: 'requirements.md 존재', passed: await exists(path.join(ssotDir, 'requirements.md')) });
48
+ checks.push({ name: 'planning.md 존재', passed: await exists(path.join(ssotDir, 'planning.md')) });
49
+ const score = checks.filter(c => c.passed).length;
50
+ return { area: 'SSOT', score, maxScore: checks.length, checks };
51
+ }
52
+ async function checkTesting(root) {
53
+ const checks = [];
54
+ const hasPkg = await exists(path.join(root, 'package.json'));
55
+ if (hasPkg) {
56
+ const pkg = await fs.readJson(path.join(root, 'package.json')).catch(() => ({}));
57
+ const scripts = pkg.scripts || {};
58
+ checks.push({ name: 'test 스크립트 존재', passed: !!scripts.test });
59
+ checks.push({ name: 'test:unit 존재', passed: !!scripts['test:unit'] });
60
+ checks.push({ name: 'test:e2e 존재', passed: !!scripts['test:e2e'] });
61
+ }
62
+ const score = checks.filter(c => c.passed).length;
63
+ return { area: 'Testing', score, maxScore: checks.length, checks };
64
+ }
65
+ async function checkSecurity(root) {
66
+ const checks = [];
67
+ checks.push({ name: 'safe-guard.sh 존재', passed: await exists(path.join(root, '.claude', 'scripts', 'safe-guard.sh')) });
68
+ checks.push({ name: 'check-capability.sh 존재', passed: await exists(path.join(root, '.claude', 'scripts', 'check-capability.sh')) });
69
+ checks.push({ name: '.env가 .gitignore에 포함', passed: await checkGitignore(root, '.env') });
70
+ const score = checks.filter(c => c.passed).length;
71
+ return { area: 'Security', score, maxScore: checks.length, checks };
72
+ }
73
+ async function checkProcess(root) {
74
+ const checks = [];
75
+ checks.push({ name: 'workflow.json 존재', passed: await exists(path.join(root, '.timsquad', 'state', 'workflow.json')) });
76
+ checks.push({ name: 'config.json 존재', passed: await exists(path.join(root, '.timsquad', 'config.json')) });
77
+ checks.push({ name: 'ssot-map.yaml 존재', passed: await exists(path.join(root, '.timsquad', 'ssot-map.yaml')) });
78
+ const score = checks.filter(c => c.passed).length;
79
+ return { area: 'Process', score, maxScore: checks.length, checks };
80
+ }
81
+ async function checkDocumentation(root) {
82
+ const checks = [];
83
+ checks.push({ name: 'README.md 존재', passed: await exists(path.join(root, 'README.md')) });
84
+ checks.push({ name: 'CLAUDE.md 존재', passed: await exists(path.join(root, 'CLAUDE.md')) });
85
+ const score = checks.filter(c => c.passed).length;
86
+ return { area: 'Documentation', score, maxScore: checks.length, checks };
87
+ }
88
+ async function checkArchitecture(root) {
89
+ const checks = [];
90
+ checks.push({ name: 'tsconfig.json 존재', passed: await exists(path.join(root, 'tsconfig.json')) });
91
+ checks.push({ name: '.claude/agents/ 존재', passed: await exists(path.join(root, '.claude', 'agents')) });
92
+ const score = checks.filter(c => c.passed).length;
93
+ return { area: 'Architecture', score, maxScore: checks.length, checks };
94
+ }
95
+ async function checkMaintainability(root) {
96
+ const checks = [];
97
+ const logsDir = path.join(root, '.timsquad', 'logs');
98
+ checks.push({ name: '태스크 로그 존재', passed: await exists(logsDir) });
99
+ const retroDir = path.join(root, '.timsquad', 'retrospective');
100
+ checks.push({ name: '회고 디렉토리 존재', passed: await exists(retroDir) });
101
+ const score = checks.filter(c => c.passed).length;
102
+ return { area: 'Maintainability', score, maxScore: checks.length, checks };
103
+ }
104
+ async function checkGitignore(root, pattern) {
105
+ const gitignorePath = path.join(root, '.gitignore');
106
+ if (!await exists(gitignorePath))
107
+ return false;
108
+ const content = await fs.readFile(gitignorePath, 'utf-8');
109
+ return content.includes(pattern);
110
+ }
111
+ //# sourceMappingURL=audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit.js","sourceRoot":"","sources":["../../src/commands/audit.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * tsq log sequence <id> / tsq log phase <id> — L1→L2→L3 로그 집계
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function registerLogCommand(program: Command): void;
6
+ //# sourceMappingURL=log.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0BzD"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * tsq log sequence <id> / tsq log phase <id> — L1→L2→L3 로그 집계
3
+ */
4
+ import path from 'path';
5
+ import { findProjectRoot } from '../lib/project.js';
6
+ import { exists, readFile } from '../utils/fs.js';
7
+ import fs from 'fs-extra';
8
+ export function registerLogCommand(program) {
9
+ const cmd = program.command('log').description('Log aggregation');
10
+ cmd
11
+ .command('sequence <id>')
12
+ .description('Aggregate L1 task logs into L2 sequence summary')
13
+ .action(async (id) => {
14
+ try {
15
+ await runLogAggregate('sequence', id);
16
+ }
17
+ catch (error) {
18
+ console.log(JSON.stringify({ error: error.message }));
19
+ process.exit(1);
20
+ }
21
+ });
22
+ cmd
23
+ .command('phase <id>')
24
+ .description('Aggregate L2 sequence logs into L3 phase summary')
25
+ .action(async (id) => {
26
+ try {
27
+ await runLogAggregate('phase', id);
28
+ }
29
+ catch (error) {
30
+ console.log(JSON.stringify({ error: error.message }));
31
+ process.exit(1);
32
+ }
33
+ });
34
+ }
35
+ async function runLogAggregate(level, id) {
36
+ const projectRoot = await findProjectRoot();
37
+ if (!projectRoot)
38
+ throw new Error('TimSquad project not found.');
39
+ const logsDir = path.join(projectRoot, '.timsquad', 'logs');
40
+ if (!await exists(logsDir))
41
+ throw new Error('Logs directory not found.');
42
+ if (level === 'sequence') {
43
+ // L1 → L2: 특정 시퀀스의 태스크 로그 집계
44
+ const taskLogs = await findLogsByPattern(logsDir, id);
45
+ console.log(JSON.stringify({
46
+ level: 'L2',
47
+ sequenceId: id,
48
+ taskCount: taskLogs.length,
49
+ logs: taskLogs,
50
+ }, null, 2));
51
+ }
52
+ else {
53
+ // L2 → L3: 특정 Phase의 시퀀스 로그 집계
54
+ const seqDir = path.join(logsDir, 'sequences');
55
+ const seqLogs = await exists(seqDir)
56
+ ? await findLogsByPattern(seqDir, id)
57
+ : [];
58
+ console.log(JSON.stringify({
59
+ level: 'L3',
60
+ phaseId: id,
61
+ sequenceCount: seqLogs.length,
62
+ logs: seqLogs,
63
+ }, null, 2));
64
+ }
65
+ }
66
+ async function findLogsByPattern(dir, pattern) {
67
+ const results = [];
68
+ const entries = await fs.readdir(dir).catch(() => []);
69
+ for (const entry of entries) {
70
+ if (!entry.endsWith('.md'))
71
+ continue;
72
+ const filePath = path.join(dir, entry);
73
+ const stat = await fs.stat(filePath);
74
+ if (!stat.isFile())
75
+ continue;
76
+ // 파일명이나 내용에 패턴(시퀀스/페이즈 ID) 포함 여부
77
+ if (entry.includes(pattern)) {
78
+ const content = await readFile(filePath);
79
+ const firstLine = content.split('\n').find(l => l.trim().length > 0) || '';
80
+ results.push({ file: entry, summary: firstLine.replace(/^#+\s*/, '').slice(0, 100) });
81
+ }
82
+ }
83
+ return results;
84
+ }
85
+ //# sourceMappingURL=log.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"log.js","sourceRoot":"","sources":["../../src/commands/log.ts"],"names":[],"mappings":"AAAA;;GAEG;AAGH,OAAO,IAAI,MAAM,MAAM,CAAC;AACxB,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAClD,OAAO,EAAE,MAAM,UAAU,CAAC;AAE1B,MAAM,UAAU,kBAAkB,CAAC,OAAgB;IACjD,MAAM,GAAG,GAAG,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,WAAW,CAAC,iBAAiB,CAAC,CAAC;IAElE,GAAG;SACA,OAAO,CAAC,eAAe,CAAC;SACxB,WAAW,CAAC,iDAAiD,CAAC;SAC9D,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,UAAU,EAAE,EAAE,CAAC,CAAC;QACxC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;IAEL,GAAG;SACA,OAAO,CAAC,YAAY,CAAC;SACrB,WAAW,CAAC,kDAAkD,CAAC;SAC/D,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;QAC3B,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACrC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAG,KAAe,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC;YACjE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,eAAe,CAAC,KAA2B,EAAE,EAAU;IACpE,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAEjE,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,WAAW,EAAE,MAAM,CAAC,CAAC;IAC5D,IAAI,CAAC,MAAM,MAAM,CAAC,OAAO,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,2BAA2B,CAAC,CAAC;IAEzE,IAAI,KAAK,KAAK,UAAU,EAAE,CAAC;QACzB,6BAA6B;QAC7B,MAAM,QAAQ,GAAG,MAAM,iBAAiB,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;QACtD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,KAAK,EAAE,IAAI;YACX,UAAU,EAAE,EAAE;YACd,SAAS,EAAE,QAAQ,CAAC,MAAM;YAC1B,IAAI,EAAE,QAAQ;SACf,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACf,CAAC;SAAM,CAAC;QACN,+BAA+B;QAC/B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QAC/C,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,MAAM,CAAC;YAClC,CAAC,CAAC,MAAM,iBAAiB,CAAC,MAAM,EAAE,EAAE,CAAC;YACrC,CAAC,CAAC,EAAE,CAAC;QAEP,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,KAAK,EAAE,IAAI;YACX,OAAO,EAAE,EAAE;YACX,aAAa,EAAE,OAAO,CAAC,MAAM;YAC7B,IAAI,EAAE,OAAO;SACd,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACf,CAAC;AACH,CAAC;AAED,KAAK,UAAU,iBAAiB,CAC9B,GAAW,EACX,OAAe;IAEf,MAAM,OAAO,GAA6C,EAAE,CAAC;IAC7D,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,EAAc,CAAC,CAAC;IAElE,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,KAAK,CAAC;YAAE,SAAS;QACrC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QACvC,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACrC,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,SAAS;QAE7B,iCAAiC;QACjC,IAAI,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC;YAC5B,MAAM,OAAO,GAAG,MAAM,QAAQ,CAAC,QAAQ,CAAC,CAAC;YACzC,MAAM,SAAS,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;YAC3E,OAAO,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,SAAS,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,CAAC,CAAC;QACxF,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC"}
@@ -0,0 +1,15 @@
1
+ /**
2
+ * tsq next — 하이브리드 Controller의 핵심 CLI
3
+ *
4
+ * planning.md + workflow.json을 비교하여 다음 태스크를 결정론적으로 출력.
5
+ * Controller 스킬이 내부적으로 호출 — 사용자가 직접 치지 않음.
6
+ *
7
+ * Usage:
8
+ * tsq next # 다음 미완료 태스크 JSON 출력
9
+ * tsq next --complete T2-1-3 # 태스크 완료 기록
10
+ * tsq next --phase-status # Phase 완료 여부 + 누락 산출물 체크
11
+ * tsq next --phase-status P2 # 특정 Phase 상태 확인
12
+ */
13
+ import { Command } from 'commander';
14
+ export declare function registerNextCommand(program: Command): void;
15
+ //# sourceMappingURL=next.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.d.ts","sourceRoot":"","sources":["../../src/commands/next.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAoBpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAmB1D"}
@@ -0,0 +1,146 @@
1
+ /**
2
+ * tsq next — 하이브리드 Controller의 핵심 CLI
3
+ *
4
+ * planning.md + workflow.json을 비교하여 다음 태스크를 결정론적으로 출력.
5
+ * Controller 스킬이 내부적으로 호출 — 사용자가 직접 치지 않음.
6
+ *
7
+ * Usage:
8
+ * tsq next # 다음 미완료 태스크 JSON 출력
9
+ * tsq next --complete T2-1-3 # 태스크 완료 기록
10
+ * tsq next --phase-status # Phase 완료 여부 + 누락 산출물 체크
11
+ * tsq next --phase-status P2 # 특정 Phase 상태 확인
12
+ */
13
+ import { findProjectRoot } from '../lib/project.js';
14
+ import { parsePlanningFile } from '../lib/planning-parser.js';
15
+ import { loadWorkflowState, findNextTask, findNextWave, getPhaseStatus, markTaskComplete, appendPhaseMemoryProgress, } from '../lib/workflow-state.js';
16
+ export function registerNextCommand(program) {
17
+ program
18
+ .command('next')
19
+ .description('Show next task or manage task completion (used by Controller)')
20
+ .option('--complete <taskId>', 'Mark task as completed')
21
+ .option('--phase-status [phaseId]', 'Check phase completion status')
22
+ .option('--wave', 'Return all independent tasks as a wave (parallel dispatch)')
23
+ .option('--summary <text>', 'Task completion summary (with --complete)')
24
+ .option('--agent <type>', 'Agent that completed the task (with --complete)')
25
+ .action(async (options) => {
26
+ try {
27
+ await runNext(options);
28
+ }
29
+ catch (error) {
30
+ const msg = error.message;
31
+ // Output errors as JSON for machine consumption
32
+ console.log(JSON.stringify({ error: msg }));
33
+ process.exit(1);
34
+ }
35
+ });
36
+ }
37
+ async function runNext(options) {
38
+ const projectRoot = await findProjectRoot();
39
+ if (!projectRoot) {
40
+ throw new Error('TimSquad project not found. Run `tsq init` first.');
41
+ }
42
+ // Route to sub-command
43
+ if (options.complete) {
44
+ await handleComplete(projectRoot, options);
45
+ }
46
+ else if (options.phaseStatus !== undefined) {
47
+ await handlePhaseStatus(projectRoot, options);
48
+ }
49
+ else if (options.wave) {
50
+ await handleWave(projectRoot);
51
+ }
52
+ else {
53
+ await handleNext(projectRoot);
54
+ }
55
+ }
56
+ /**
57
+ * tsq next — 다음 미완료 태스크 출력
58
+ */
59
+ async function handleNext(projectRoot) {
60
+ const doc = await parsePlanningFile(projectRoot);
61
+ if (!doc) {
62
+ throw new Error('planning.md not found. Run /tsq-decompose to create planning.md');
63
+ }
64
+ const state = await loadWorkflowState(projectRoot);
65
+ const next = findNextTask(doc, state);
66
+ if (!next) {
67
+ console.log(JSON.stringify({
68
+ status: 'all_complete',
69
+ message: 'All tasks in planning.md are completed.',
70
+ }));
71
+ return;
72
+ }
73
+ console.log(JSON.stringify(next, null, 2));
74
+ }
75
+ /**
76
+ * tsq next --wave — 병렬 실행 가능한 독립 태스크 Wave 출력
77
+ */
78
+ async function handleWave(projectRoot) {
79
+ const doc = await parsePlanningFile(projectRoot);
80
+ if (!doc) {
81
+ throw new Error('planning.md not found. Run /tsq-decompose to create planning.md');
82
+ }
83
+ const state = await loadWorkflowState(projectRoot);
84
+ const result = findNextWave(doc, state);
85
+ if (!result) {
86
+ console.log(JSON.stringify({
87
+ status: 'all_complete',
88
+ message: 'All tasks in planning.md are completed.',
89
+ }));
90
+ return;
91
+ }
92
+ console.log(JSON.stringify({
93
+ status: 'wave',
94
+ wave: result.wave,
95
+ waveSize: result.wave.length,
96
+ totalRemaining: result.totalRemaining,
97
+ parallel: result.wave.length > 1,
98
+ }, null, 2));
99
+ }
100
+ /**
101
+ * tsq next --complete <taskId> — 태스크 완료 기록
102
+ */
103
+ async function handleComplete(projectRoot, options) {
104
+ const taskId = options.complete;
105
+ // Validate task ID format
106
+ if (!/^P\d+-S\d+-T\d+$/.test(taskId)) {
107
+ throw new Error(`Invalid task ID format: ${taskId}. Expected: P{N}-S{NNN}-T{NNN}`);
108
+ }
109
+ await markTaskComplete(projectRoot, {
110
+ taskId,
111
+ completedAt: new Date().toISOString(),
112
+ agent: options.agent,
113
+ summary: options.summary,
114
+ });
115
+ // Append to phase-memory
116
+ if (options.summary) {
117
+ await appendPhaseMemoryProgress(projectRoot, taskId, options.summary);
118
+ }
119
+ console.log(JSON.stringify({
120
+ status: 'completed',
121
+ taskId,
122
+ agent: options.agent || 'unknown',
123
+ summary: options.summary || null,
124
+ }));
125
+ }
126
+ /**
127
+ * tsq next --phase-status [phaseId] — Phase 완료 여부 체크
128
+ */
129
+ async function handlePhaseStatus(projectRoot, options) {
130
+ const doc = await parsePlanningFile(projectRoot);
131
+ if (!doc) {
132
+ throw new Error('planning.md not found. Run /tsq-decompose to create planning.md');
133
+ }
134
+ const state = await loadWorkflowState(projectRoot);
135
+ const phaseId = typeof options.phaseStatus === 'string' ? options.phaseStatus : undefined;
136
+ const status = getPhaseStatus(doc, state, phaseId);
137
+ if (!status) {
138
+ console.log(JSON.stringify({
139
+ status: 'all_complete',
140
+ message: 'All phases completed or no phases found.',
141
+ }));
142
+ return;
143
+ }
144
+ console.log(JSON.stringify(status, null, 2));
145
+ }
146
+ //# sourceMappingURL=next.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"next.js","sourceRoot":"","sources":["../../src/commands/next.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * tsq plan validate — planning.md DAG 무결성 + PRD 커버리지 검증
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function registerPlanCommand(program: Command): void;
6
+ //# sourceMappingURL=plan.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.d.ts","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAc1D"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * tsq plan validate — planning.md DAG 무결성 + PRD 커버리지 검증
3
+ */
4
+ import path from 'path';
5
+ import { findProjectRoot } from '../lib/project.js';
6
+ import { parsePlanningFile, getAllTasks } from '../lib/planning-parser.js';
7
+ import { exists, readFile } from '../utils/fs.js';
8
+ export function registerPlanCommand(program) {
9
+ const cmd = program.command('plan').description('Planning document management');
10
+ cmd
11
+ .command('validate')
12
+ .description('Validate planning.md DAG integrity and PRD coverage')
13
+ .action(async () => {
14
+ try {
15
+ await runValidate();
16
+ }
17
+ catch (error) {
18
+ console.log(JSON.stringify({ error: error.message }));
19
+ process.exit(1);
20
+ }
21
+ });
22
+ }
23
+ async function runValidate() {
24
+ const projectRoot = await findProjectRoot();
25
+ if (!projectRoot)
26
+ throw new Error('TimSquad project not found.');
27
+ const doc = await parsePlanningFile(projectRoot);
28
+ if (!doc)
29
+ throw new Error('planning.md not found.');
30
+ const allTasks = getAllTasks(doc);
31
+ const issues = [];
32
+ // 1. DAG 순환 의존성 체크
33
+ const taskIds = new Set(allTasks.map(t => t.id));
34
+ for (const task of allTasks) {
35
+ if (task.dependencies) {
36
+ for (const dep of task.dependencies) {
37
+ if (!taskIds.has(dep)) {
38
+ issues.push(`Task ${task.id}: 의존성 ${dep}이 존재하지 않음`);
39
+ }
40
+ if (dep === task.id) {
41
+ issues.push(`Task ${task.id}: 자기 참조 순환`);
42
+ }
43
+ }
44
+ }
45
+ }
46
+ // 간단한 순환 감지 (2-hop)
47
+ for (const task of allTasks) {
48
+ if (!task.dependencies)
49
+ continue;
50
+ for (const dep of task.dependencies) {
51
+ const depTask = allTasks.find(t => t.id === dep);
52
+ if (depTask?.dependencies?.includes(task.id)) {
53
+ issues.push(`순환 의존성: ${task.id} ↔ ${dep}`);
54
+ }
55
+ }
56
+ }
57
+ // 2. Phase 순서 검증
58
+ const phaseNums = doc.phases.map(p => parseInt(p.id.replace('P', ''), 10));
59
+ for (let i = 1; i < phaseNums.length; i++) {
60
+ if (phaseNums[i] <= phaseNums[i - 1]) {
61
+ issues.push(`Phase 순서 오류: ${doc.phases[i - 1].id} → ${doc.phases[i].id}`);
62
+ }
63
+ }
64
+ // 3. PRD 커버리지 (PRD 기능 인덱스 vs planning.md Phase)
65
+ let prdCoverage = null;
66
+ const prdPath = path.join(projectRoot, '.timsquad', 'ssot', 'prd.md');
67
+ if (await exists(prdPath)) {
68
+ const prdContent = await readFile(prdPath);
69
+ const featureRows = prdContent.match(/^\|[^|]+\|/gm)?.filter(r => !r.includes('---') && !r.includes('기능명') && !r.includes('Feature')) || [];
70
+ prdCoverage = {
71
+ total: featureRows.length,
72
+ covered: doc.phases.length > 0 ? Math.min(featureRows.length, allTasks.length) : 0,
73
+ };
74
+ }
75
+ console.log(JSON.stringify({
76
+ valid: issues.length === 0,
77
+ phases: doc.phases.length,
78
+ totalTasks: allTasks.length,
79
+ issues,
80
+ prdCoverage,
81
+ }, null, 2));
82
+ }
83
+ //# sourceMappingURL=plan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"plan.js","sourceRoot":"","sources":["../../src/commands/plan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * tsq retro metrics — 회고 메트릭 자동 추출
3
+ */
4
+ import { Command } from 'commander';
5
+ export declare function registerRetroCommand(program: Command): void;
6
+ //# sourceMappingURL=retro.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"retro.d.ts","sourceRoot":"","sources":["../../src/commands/retro.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAMpC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAc3D"}