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.
- package/README.ko.md +8 -9
- package/README.md +44 -11
- 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 +22 -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 +15 -1
- 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 +70 -0
- 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-quick/SKILL.md +58 -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/ # 회고 데이터
|
|
@@ -108,13 +109,11 @@ claude # Claude Code 실행
|
|
|
108
109
|
|
|
109
110
|
# 슬래시 커맨드로 모든 작업 수행
|
|
110
111
|
/tsq-start # 파이프라인 시작 + 온보딩
|
|
112
|
+
/tsq-quick 로그인 버튼 색상 수정 # 단일 태스크 (Controller 경유)
|
|
113
|
+
/tsq-full # 풀 파이프라인 (Phase-Sequence-Task)
|
|
111
114
|
/tsq-status # 현재 상태 확인
|
|
112
115
|
/tsq-grill # Sub-PRD 심층 인터뷰
|
|
113
116
|
/tsq-decompose # Phase-Sequence-Task 계획 생성
|
|
114
|
-
|
|
115
|
-
# PM(CLAUDE.md)이 controller를 통해 에이전트에 위임
|
|
116
|
-
@tsq-developer "로그인 API 구현해줘"
|
|
117
|
-
@tsq-qa "코드 리뷰해줘"
|
|
118
117
|
```
|
|
119
118
|
|
|
120
119
|
### 4. CLI 명령어
|
|
@@ -145,7 +144,7 @@ Layer 3: CLAUDE.md (역할 정의만)
|
|
|
145
144
|
└ PM 역할 + 파이프라인 사전조건 (~15줄)
|
|
146
145
|
|
|
147
146
|
Layer 4: 슬래시 커맨드 (명시적 프로세스)
|
|
148
|
-
└ /tsq-start, /tsq-status, /tsq-grill, /tsq-retro
|
|
147
|
+
└ /tsq-start, /tsq-quick, /tsq-full, /tsq-status, /tsq-grill, /tsq-retro
|
|
149
148
|
|
|
150
149
|
Layer 5: 감사 (비동기 사후 추적)
|
|
151
150
|
└ 데몬이 관찰 → 세션 로그, 메트릭
|
|
@@ -176,13 +175,13 @@ Layer 5: 감사 (비동기 사후 추적)
|
|
|
176
175
|
| `@tsq-designer` | UI/UX 설계, 접근성, 디자인 토큰 |
|
|
177
176
|
| `@tsq-librarian` | Phase 기록, 메모리 관리 |
|
|
178
177
|
|
|
179
|
-
###
|
|
178
|
+
### 37개 스킬 (슬래시 커맨드)
|
|
180
179
|
|
|
181
180
|
모든 스킬은 `tsq-*` flat namespace로 통일되었으며 슬래시 커맨드로 사용:
|
|
182
181
|
|
|
183
182
|
| 카테고리 | 스킬 |
|
|
184
183
|
|----------|------|
|
|
185
|
-
| **핵심** | `tsq-protocol`, `tsq-controller`, `tsq-start`, `tsq-status` |
|
|
184
|
+
| **핵심** | `tsq-protocol`, `tsq-controller`, `tsq-start`, `tsq-quick`, `tsq-full`, `tsq-status` |
|
|
186
185
|
| **코딩** | `tsq-coding`, `tsq-testing`, `tsq-typescript`, `tsq-hono` |
|
|
187
186
|
| **기획** | `tsq-planning`, `tsq-spec`, `tsq-grill`, `tsq-decompose` |
|
|
188
187
|
| **프론트엔드** | `tsq-react`, `tsq-nextjs`, `tsq-ui` |
|
|
@@ -192,7 +191,7 @@ Layer 5: 감사 (비동기 사후 추적)
|
|
|
192
191
|
| **방법론** | `tsq-tdd`, `tsq-bdd`, `tsq-ddd`, `tsq-debugging` |
|
|
193
192
|
| **운영** | `tsq-librarian`, `tsq-log`, `tsq-retro`, `tsq-prompt` |
|
|
194
193
|
|
|
195
|
-
###
|
|
194
|
+
### 13개 Hook Gate
|
|
196
195
|
|
|
197
196
|
| Hook | 스크립트 | 역할 | 전략 |
|
|
198
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
|
|
@@ -108,13 +109,11 @@ claude # Launch Claude Code
|
|
|
108
109
|
|
|
109
110
|
# Use slash commands for all operations
|
|
110
111
|
/tsq-start # Start pipeline + onboarding
|
|
112
|
+
/tsq-quick fix login button color # Single task via Controller
|
|
113
|
+
/tsq-full # Full pipeline (Phase-Sequence-Task)
|
|
111
114
|
/tsq-status # Check current status
|
|
112
115
|
/tsq-grill # Deep interview for Sub-PRD
|
|
113
116
|
/tsq-decompose # Generate Phase-Sequence-Task plan
|
|
114
|
-
|
|
115
|
-
# PM (CLAUDE.md) delegates to agents via controller
|
|
116
|
-
@tsq-developer "Implement the login API"
|
|
117
|
-
@tsq-qa "Review the code"
|
|
118
117
|
```
|
|
119
118
|
|
|
120
119
|
### 4. CLI Commands
|
|
@@ -123,6 +122,13 @@ claude # Launch Claude Code
|
|
|
123
122
|
tsq init # Initialize project
|
|
124
123
|
tsq update # Update skills/agents to latest
|
|
125
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
|
|
126
132
|
```
|
|
127
133
|
|
|
128
134
|
> All other operations use Claude Code slash commands. See [CLI Reference](docs/cli.en.md).
|
|
@@ -145,7 +151,7 @@ Layer 3: CLAUDE.md (role definition only)
|
|
|
145
151
|
└ PM role + pipeline prerequisites (~15 lines)
|
|
146
152
|
|
|
147
153
|
Layer 4: Slash Commands (explicit process)
|
|
148
|
-
└ /tsq-start, /tsq-status, /tsq-grill, /tsq-retro
|
|
154
|
+
└ /tsq-start, /tsq-quick, /tsq-full, /tsq-status, /tsq-grill, /tsq-retro
|
|
149
155
|
|
|
150
156
|
Layer 5: Audit (async post-tracking)
|
|
151
157
|
└ Daemon observes → session logs, metrics
|
|
@@ -176,13 +182,13 @@ Required documents are automatically determined by project level:
|
|
|
176
182
|
| `@tsq-designer` | UI/UX design, accessibility, design tokens |
|
|
177
183
|
| `@tsq-librarian` | Phase recording, memory management |
|
|
178
184
|
|
|
179
|
-
###
|
|
185
|
+
### 37 Skills (Slash Commands)
|
|
180
186
|
|
|
181
187
|
All skills use `tsq-*` flat namespace and are available as slash commands:
|
|
182
188
|
|
|
183
189
|
| Category | Skills |
|
|
184
190
|
|----------|--------|
|
|
185
|
-
| **Core** | `tsq-protocol`, `tsq-controller`, `tsq-start`, `tsq-status` |
|
|
191
|
+
| **Core** | `tsq-protocol`, `tsq-controller`, `tsq-start`, `tsq-quick`, `tsq-full`, `tsq-status` |
|
|
186
192
|
| **Coding** | `tsq-coding`, `tsq-testing`, `tsq-typescript`, `tsq-hono` |
|
|
187
193
|
| **Planning** | `tsq-planning`, `tsq-spec`, `tsq-grill`, `tsq-decompose` |
|
|
188
194
|
| **Frontend** | `tsq-react`, `tsq-nextjs`, `tsq-ui` |
|
|
@@ -192,7 +198,29 @@ All skills use `tsq-*` flat namespace and are available as slash commands:
|
|
|
192
198
|
| **Methodology** | `tsq-tdd`, `tsq-bdd`, `tsq-ddd`, `tsq-debugging` |
|
|
193
199
|
| **Operations** | `tsq-librarian`, `tsq-log`, `tsq-retro`, `tsq-prompt` |
|
|
194
200
|
|
|
195
|
-
###
|
|
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
|
|
196
224
|
|
|
197
225
|
| Hook | Script | Role | Strategy |
|
|
198
226
|
|------|--------|------|----------|
|
|
@@ -200,10 +228,15 @@ All skills use `tsq-*` flat namespace and are available as slash commands:
|
|
|
200
228
|
| PreToolUse (Write\|Edit) | `phase-guard.sh` | Phase file restrictions | Fail-closed |
|
|
201
229
|
| PreToolUse (Write\|Edit) | `check-capability.sh` | Capability Token verification | Fail-closed |
|
|
202
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 |
|
|
203
235
|
| Stop | `completion-guard.sh` | Test + TDD + SSOT check | Fail-closed |
|
|
204
236
|
| Stop | `build-gate.sh` | TypeScript build errors | Fail-closed |
|
|
205
|
-
|
|
|
206
|
-
|
|
|
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 |
|
|
207
240
|
|
|
208
241
|
### Daemon-Based Automation
|
|
209
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":"AAAA;;;;;;;;;;;GAWG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EACL,iBAAiB,EACjB,YAAY,EACZ,YAAY,EACZ,cAAc,EACd,gBAAgB,EAChB,yBAAyB,GAC1B,MAAM,0BAA0B,CAAC;AAUlC,MAAM,UAAU,mBAAmB,CAAC,OAAgB;IAClD,OAAO;SACJ,OAAO,CAAC,MAAM,CAAC;SACf,WAAW,CAAC,+DAA+D,CAAC;SAC5E,MAAM,CAAC,qBAAqB,EAAE,wBAAwB,CAAC;SACvD,MAAM,CAAC,0BAA0B,EAAE,+BAA+B,CAAC;SACnE,MAAM,CAAC,QAAQ,EAAE,4DAA4D,CAAC;SAC9E,MAAM,CAAC,kBAAkB,EAAE,2CAA2C,CAAC;SACvE,MAAM,CAAC,gBAAgB,EAAE,iDAAiD,CAAC;SAC3E,MAAM,CAAC,KAAK,EAAE,OAAoB,EAAE,EAAE;QACrC,IAAI,CAAC;YACH,MAAM,OAAO,CAAC,OAAO,CAAC,CAAC;QACzB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,GAAG,GAAI,KAAe,CAAC,OAAO,CAAC;YACrC,gDAAgD;YAChD,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,GAAG,EAAE,CAAC,CAAC,CAAC;YAC5C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC,CAAC,CAAC;AACP,CAAC;AAED,KAAK,UAAU,OAAO,CAAC,OAAoB;IACzC,MAAM,WAAW,GAAG,MAAM,eAAe,EAAE,CAAC;IAC5C,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAC;IACvE,CAAC;IAED,uBAAuB;IACvB,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;QACrB,MAAM,cAAc,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAC7C,CAAC;SAAM,IAAI,OAAO,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QAC7C,MAAM,iBAAiB,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;IAChD,CAAC;SAAM,IAAI,OAAO,CAAC,IAAI,EAAE,CAAC;QACxB,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;IAChC,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,CAAC,WAAW,CAAC,CAAC;IAChC,CAAC;AACH,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,UAAU,CAAC,WAAmB;IAC3C,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACnD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAEtC,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,yCAAyC;SACnD,CAAC,CAAC,CAAC;QACJ,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC7C,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,UAAU,CAAC,WAAmB;IAC3C,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACnD,MAAM,MAAM,GAAG,YAAY,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAExC,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,yCAAyC;SACnD,CAAC,CAAC,CAAC;QACJ,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QACzB,MAAM,EAAE,MAAM;QACd,IAAI,EAAE,MAAM,CAAC,IAAI;QACjB,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM;QAC5B,cAAc,EAAE,MAAM,CAAC,cAAc;QACrC,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC;KACjC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACf,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,cAAc,CAAC,WAAmB,EAAE,OAAoB;IACrE,MAAM,MAAM,GAAG,OAAO,CAAC,QAAS,CAAC;IAEjC,0BAA0B;IAC1B,IAAI,CAAC,kBAAkB,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;QACrC,MAAM,IAAI,KAAK,CAAC,2BAA2B,MAAM,gCAAgC,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,gBAAgB,CAAC,WAAW,EAAE;QAClC,MAAM;QACN,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,KAAK,EAAE,OAAO,CAAC,KAAK;QACpB,OAAO,EAAE,OAAO,CAAC,OAAO;KACzB,CAAC,CAAC;IAEH,yBAAyB;IACzB,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,yBAAyB,CAAC,WAAW,EAAE,MAAM,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC;IACxE,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;QACzB,MAAM,EAAE,WAAW;QACnB,MAAM;QACN,KAAK,EAAE,OAAO,CAAC,KAAK,IAAI,SAAS;QACjC,OAAO,EAAE,OAAO,CAAC,OAAO,IAAI,IAAI;KACjC,CAAC,CAAC,CAAC;AACN,CAAC;AAED;;GAEG;AACH,KAAK,UAAU,iBAAiB,CAAC,WAAmB,EAAE,OAAoB;IACxE,MAAM,GAAG,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACjD,IAAI,CAAC,GAAG,EAAE,CAAC;QACT,MAAM,IAAI,KAAK,CAAC,iEAAiE,CAAC,CAAC;IACrF,CAAC;IAED,MAAM,KAAK,GAAG,MAAM,iBAAiB,CAAC,WAAW,CAAC,CAAC;IACnD,MAAM,OAAO,GAAG,OAAO,OAAO,CAAC,WAAW,KAAK,QAAQ,CAAC,CAAC,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1F,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,EAAE,KAAK,EAAE,OAAO,CAAC,CAAC;IAEnD,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC;YACzB,MAAM,EAAE,cAAc;YACtB,OAAO,EAAE,0CAA0C;SACpD,CAAC,CAAC,CAAC;QACJ,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAC/C,CAAC"}
|
|
@@ -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"}
|