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.
- package/README.ko.md +3 -2
- package/README.md +39 -4
- package/dist/commands/audit.d.ts +6 -0
- package/dist/commands/audit.d.ts.map +1 -0
- package/dist/commands/audit.js +111 -0
- package/dist/commands/audit.js.map +1 -0
- package/dist/commands/log.d.ts +6 -0
- package/dist/commands/log.d.ts.map +1 -0
- package/dist/commands/log.js +85 -0
- package/dist/commands/log.js.map +1 -0
- package/dist/commands/next.d.ts +15 -0
- package/dist/commands/next.d.ts.map +1 -0
- package/dist/commands/next.js +146 -0
- package/dist/commands/next.js.map +1 -0
- package/dist/commands/plan.d.ts +6 -0
- package/dist/commands/plan.d.ts.map +1 -0
- package/dist/commands/plan.js +83 -0
- package/dist/commands/plan.js.map +1 -0
- package/dist/commands/retro.d.ts +6 -0
- package/dist/commands/retro.d.ts.map +1 -0
- package/dist/commands/retro.js +74 -0
- package/dist/commands/retro.js.map +1 -0
- package/dist/commands/spec.d.ts +6 -0
- package/dist/commands/spec.d.ts.map +1 -0
- package/dist/commands/spec.js +56 -0
- package/dist/commands/spec.js.map +1 -0
- package/dist/commands/status.d.ts +6 -0
- package/dist/commands/status.d.ts.map +1 -0
- package/dist/commands/status.js +99 -0
- package/dist/commands/status.js.map +1 -0
- package/dist/daemon/index.d.ts.map +1 -1
- package/dist/daemon/index.js +12 -10
- package/dist/daemon/index.js.map +1 -1
- package/dist/daemon/meta-cache.d.ts +2 -1
- package/dist/daemon/meta-cache.d.ts.map +1 -1
- package/dist/daemon/meta-cache.js +20 -4
- package/dist/daemon/meta-cache.js.map +1 -1
- package/dist/index.js +15 -1
- package/dist/index.js.map +1 -1
- package/dist/lib/config.d.ts.map +1 -1
- package/dist/lib/config.js +14 -1
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/planning-parser.d.ts +65 -0
- package/dist/lib/planning-parser.d.ts.map +1 -0
- package/dist/lib/planning-parser.js +306 -0
- package/dist/lib/planning-parser.js.map +1 -0
- package/dist/lib/skill-generator.d.ts.map +1 -1
- package/dist/lib/skill-generator.js +7 -3
- package/dist/lib/skill-generator.js.map +1 -1
- package/dist/lib/template.d.ts.map +1 -1
- package/dist/lib/template.js +16 -5
- package/dist/lib/template.js.map +1 -1
- package/dist/lib/workflow-state.d.ts +77 -0
- package/dist/lib/workflow-state.d.ts.map +1 -1
- package/dist/lib/workflow-state.js +194 -0
- package/dist/lib/workflow-state.js.map +1 -1
- package/dist/types/config.d.ts +14 -0
- package/dist/types/config.d.ts.map +1 -1
- package/dist/types/config.js +13 -2
- package/dist/types/config.js.map +1 -1
- package/package.json +1 -1
- package/templates/base/agents/base/tsq-librarian.md +1 -1
- package/templates/base/scripts/calculate-retro-metrics.sh +46 -0
- package/templates/base/scripts/check-circular-deps.sh +82 -0
- package/templates/base/scripts/cleanup-trails.sh +44 -0
- package/templates/base/scripts/generate-prd-traceability.sh +91 -0
- package/templates/base/scripts/manage-fp-registry.sh +83 -0
- package/templates/base/scripts/validate-gherkin.sh +113 -0
- package/templates/base/skills/tsq-controller/SKILL.md +60 -37
- package/templates/base/skills/tsq-controller/references/model-routing.md +38 -0
- package/templates/base/skills/tsq-controller/references/wave-dispatch.md +50 -0
- package/templates/base/skills/tsq-full/SKILL.md +12 -9
- package/templates/base/skills/tsq-grill/SKILL.md +60 -55
- package/templates/base/skills/tsq-grill/references/interview-guide.md +86 -0
- package/templates/base/skills/tsq-inspect/SKILL.md +108 -0
- package/templates/base/skills/tsq-inspect/references/checklist.md +162 -0
- package/templates/base/skills/tsq-start/SKILL.md +17 -44
- package/templates/base/skills/tsq-start/references/onboarding-steps.md +85 -0
- package/templates/platforms/claude-code/scripts/build-gate.sh +25 -2
- package/templates/platforms/claude-code/scripts/check-capability.sh +41 -10
- package/templates/platforms/claude-code/scripts/completion-guard.sh +79 -3
- package/templates/platforms/claude-code/scripts/detect-env.sh +124 -0
- package/templates/platforms/claude-code/scripts/stale-guard.sh +47 -0
- package/templates/platforms/claude-code/scripts/subagent-stop.sh +41 -2
- package/templates/platforms/claude-code/scripts/tdd-guard.sh +57 -0
- package/templates/platforms/claude-code/scripts/validate-completion-report.sh +86 -0
- package/templates/platforms/claude-code/settings.json +10 -0
- package/templates/project-types/fintech/config.yaml +1 -1
- package/templates/project-types/mobile-app/config.yaml +1 -1
- package/templates/project-types/web-app/config.yaml +1 -1
- 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 설정 (
|
|
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
|
-
###
|
|
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 (
|
|
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
|
-
###
|
|
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
|
-
|
|
|
204
|
-
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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":"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"}
|
|
@@ -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 @@
|
|
|
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 @@
|
|
|
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"}
|