@alxyrgin/agent-forge 3.0.0 → 3.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +353 -118
- package/dist/index.js +162 -8
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
# agent-forge
|
|
2
2
|
|
|
3
|
-
AI-driven Development Framework for Claude Code.
|
|
3
|
+
AI-driven Development Framework for Claude Code. Generates a complete development infrastructure with 20 specialized agents, quality gates, and TDD pipelines.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
[](https://www.npmjs.com/package/@alxyrgin/agent-forge)
|
|
6
|
+
[](https://github.com/alxyrgin/agent-forge/blob/main/LICENSE)
|
|
7
|
+
[](https://nodejs.org)
|
|
6
8
|
|
|
7
9
|
## Quick Start
|
|
8
10
|
|
|
@@ -10,186 +12,419 @@ Scaffold a complete development infrastructure with Memory Bank, specialized age
|
|
|
10
12
|
npx @alxyrgin/agent-forge init
|
|
11
13
|
```
|
|
12
14
|
|
|
13
|
-
|
|
15
|
+
The interactive wizard asks for your project name, tech stack, team, and agent preset — then scaffolds the entire AI infrastructure in seconds. Start working immediately with `/start-session`.
|
|
14
16
|
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
- **`dev-infra/sessions/`** — Session logs
|
|
19
|
-
- **`dev-infra/tests/`** — Test structure (acceptance, PMI, results)
|
|
17
|
+
```bash
|
|
18
|
+
npx @alxyrgin/agent-forge init --yes # non-interactive, use defaults
|
|
19
|
+
```
|
|
20
20
|
|
|
21
|
-
##
|
|
21
|
+
## What Gets Generated
|
|
22
|
+
|
|
23
|
+
| Directory | Contents |
|
|
24
|
+
|-----------|----------|
|
|
25
|
+
| `.claude/CLAUDE.md` | Team Lead instructions — the orchestrator prompt |
|
|
26
|
+
| `.claude/agents/` | 5–20 specialized agents across 4 categories |
|
|
27
|
+
| `.claude/skills/` | 10–21 slash commands for development workflows |
|
|
28
|
+
| `.claude/rules/` | 8 development standards enforced automatically |
|
|
29
|
+
| `.claude/hooks/` | Git/tool hooks (protect-docs, stop hook) |
|
|
30
|
+
| `dev-infra/memory/` | 9 Memory Bank files for persistent context |
|
|
31
|
+
| `dev-infra/tasks/` | Task tracking system (`tasks.json`) |
|
|
32
|
+
| `dev-infra/sessions/` | Session logs |
|
|
33
|
+
| `dev-infra/tests/` | Test structure (acceptance criteria, PMI scenarios, results) |
|
|
34
|
+
|
|
35
|
+
## Architecture
|
|
36
|
+
|
|
37
|
+
The Team Lead (defined in `CLAUDE.md`) orchestrates four categories of specialized agents:
|
|
38
|
+
|
|
39
|
+
```mermaid
|
|
40
|
+
graph TD
|
|
41
|
+
subgraph "Orchestrator"
|
|
42
|
+
TL["Team Lead<br/>(CLAUDE.md)"]
|
|
43
|
+
end
|
|
44
|
+
|
|
45
|
+
subgraph "Pipeline — 8 agents"
|
|
46
|
+
analyst["analyst"]
|
|
47
|
+
architect["architect"]
|
|
48
|
+
skeptic["skeptic"]
|
|
49
|
+
developer["developer"]
|
|
50
|
+
tester["tester"]
|
|
51
|
+
inspector["inspector"]
|
|
52
|
+
reviewer["reviewer"]
|
|
53
|
+
planner["planner"]
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
subgraph "Planning — 4 agents"
|
|
57
|
+
researcher["researcher"]
|
|
58
|
+
interviewer["interviewer"]
|
|
59
|
+
validator["validator"]
|
|
60
|
+
decomposer["decomposer"]
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
subgraph "Security — 4 agents"
|
|
64
|
+
auditor["auditor"]
|
|
65
|
+
prompter["prompter"]
|
|
66
|
+
deployer["deployer"]
|
|
67
|
+
scaffolder["scaffolder"]
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
subgraph "Documentation — 4 agents"
|
|
71
|
+
librarian["librarian"]
|
|
72
|
+
writer["writer"]
|
|
73
|
+
gatekeeper["gatekeeper"]
|
|
74
|
+
verifier["verifier"]
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
TL --> analyst
|
|
78
|
+
TL --> researcher
|
|
79
|
+
TL --> auditor
|
|
80
|
+
TL --> librarian
|
|
81
|
+
|
|
82
|
+
analyst --> architect --> skeptic
|
|
83
|
+
developer <--> tester
|
|
84
|
+
tester --> inspector --> reviewer
|
|
85
|
+
```
|
|
22
86
|
|
|
23
|
-
|
|
87
|
+
Each agent has a defined role, a set of allowed tools, a model assignment, and structured JSON output with verdicts. The Team Lead reads each verdict and routes the pipeline accordingly.
|
|
24
88
|
|
|
25
|
-
|
|
89
|
+
## Pipelines
|
|
26
90
|
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
91
|
+
Every task is classified by size — **S**, **M**, or **L** — and routed through the appropriate pipeline. Larger tasks get more validation steps.
|
|
92
|
+
|
|
93
|
+
### S-Pipeline. Small tasks (1 file, < 50 lines)
|
|
94
|
+
|
|
95
|
+
```mermaid
|
|
96
|
+
graph LR
|
|
97
|
+
S1["checkpoint"] --> S2["developer"] --> S3["tester +<br/>inspector"] --> S4["quick-review"] --> S5["tech-debt"] --> S6["fixation"]
|
|
98
|
+
|
|
99
|
+
style S1 fill:#f0f0f0,stroke:#999
|
|
100
|
+
style S6 fill:#f0f0f0,stroke:#999
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### M-Pipeline. Medium tasks (2–5 files, new module)
|
|
38
104
|
|
|
39
|
-
|
|
105
|
+
```mermaid
|
|
106
|
+
graph LR
|
|
107
|
+
M1["checkpoint"] --> M2["analyst"] --> M3["TDD RED"] --> M4["developer ↔<br/>tester +<br/>inspector"] --> M5["quality<br/>gates"] --> M6["reviewer"] --> M7["tech-debt"] --> M8["fixation"]
|
|
40
108
|
|
|
41
|
-
|
|
109
|
+
style M1 fill:#f0f0f0,stroke:#999
|
|
110
|
+
style M8 fill:#f0f0f0,stroke:#999
|
|
111
|
+
```
|
|
42
112
|
|
|
43
|
-
|
|
44
|
-
|----------|--------|-------|
|
|
45
|
-
| Pipeline | analyst, architect, skeptic, developer, tester, inspector, reviewer, planner | 8 |
|
|
46
|
-
| Planning | researcher, validator, interviewer, decomposer | 4 |
|
|
47
|
-
| Security | auditor, prompter, deployer, scaffolder | 4 |
|
|
48
|
-
| Documentation | librarian, writer, gatekeeper, verifier | 4 |
|
|
113
|
+
### L-Pipeline. Large tasks (6+ files, architecture changes)
|
|
49
114
|
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
- **full** (20 agents) — all categories
|
|
115
|
+
```mermaid
|
|
116
|
+
graph LR
|
|
117
|
+
L1["checkpoint"] --> L2["analyst"] --> L3["architect +<br/>reviewer<br/>(plan)"] --> L4["skeptic"] --> L5["TDD RED"] --> L6["developer ↔<br/>tester +<br/>inspector"] --> L7["quality<br/>gates"] --> L8["reviewer"] --> L9["tech-debt"] --> L10["fixation"]
|
|
54
118
|
|
|
55
|
-
|
|
119
|
+
style L1 fill:#f0f0f0,stroke:#999
|
|
120
|
+
style L10 fill:#f0f0f0,stroke:#999
|
|
121
|
+
```
|
|
56
122
|
|
|
57
|
-
|
|
123
|
+
Key pipeline features:
|
|
124
|
+
- **TDD RED phase** (M/L) — tester writes failing tests *before* developer writes code
|
|
125
|
+
- **Per-feature loops** (L) — developer and tester iterate on each feature independently
|
|
126
|
+
- **Inspector gate** — validates test quality after tester, before reviewer
|
|
127
|
+
- **Multi-round review** — reviewer runs up to 3 rounds; CRITICAL/HIGH issues go back to developer
|
|
128
|
+
- **Tech-debt is mandatory** for all sizes — never skipped
|
|
129
|
+
|
|
130
|
+
## Agent Presets
|
|
131
|
+
|
|
132
|
+
Three presets control how many agents are scaffolded:
|
|
133
|
+
|
|
134
|
+
| Preset | Agents | Skills | Best for |
|
|
135
|
+
|--------|--------|--------|----------|
|
|
136
|
+
| **minimal** | 5 | 10 | Solo developer, small projects |
|
|
137
|
+
| **core** (default) | 8 | 10 | Teams, production projects |
|
|
138
|
+
| **full** | 20 | 21 | Complex systems, enterprise |
|
|
139
|
+
|
|
140
|
+
### Preset coverage
|
|
141
|
+
|
|
142
|
+
| Agent | minimal | core | full |
|
|
143
|
+
|-------|:-------:|:----:|:----:|
|
|
144
|
+
| analyst | x | x | x |
|
|
145
|
+
| architect | | x | x |
|
|
146
|
+
| skeptic | | x | x |
|
|
147
|
+
| developer | x | x | x |
|
|
148
|
+
| tester | x | x | x |
|
|
149
|
+
| inspector | x | x | x |
|
|
150
|
+
| reviewer | x | x | x |
|
|
151
|
+
| planner | | x | x |
|
|
152
|
+
| researcher | | | x |
|
|
153
|
+
| interviewer | | | x |
|
|
154
|
+
| validator | | | x |
|
|
155
|
+
| decomposer | | | x |
|
|
156
|
+
| auditor | | | x |
|
|
157
|
+
| prompter | | | x |
|
|
158
|
+
| deployer | | | x |
|
|
159
|
+
| scaffolder | | | x |
|
|
160
|
+
| librarian | | | x |
|
|
161
|
+
| writer | | | x |
|
|
162
|
+
| gatekeeper | | | x |
|
|
163
|
+
| verifier | | | x |
|
|
164
|
+
|
|
165
|
+
## Agents
|
|
166
|
+
|
|
167
|
+
### Pipeline (8 agents)
|
|
168
|
+
|
|
169
|
+
Core development cycle — from analysis to code review.
|
|
170
|
+
|
|
171
|
+
| Agent | Description | Verdicts |
|
|
172
|
+
|-------|-------------|----------|
|
|
173
|
+
| **analyst** | Analyzes task requirements from documentation, extracts acceptance criteria and PMI scenarios | `COMPLETE`, `NEEDS_DISCOVERY` |
|
|
174
|
+
| **architect** | Designs module architecture — structure, API contracts, data schemas | `READY`, `NEEDS_INPUT` |
|
|
175
|
+
| **skeptic** | Reality checker — verifies plans against actual codebase, finds "mirages" (non-existent files, APIs, modules) | `PASS`, `PASS_WITH_WARNINGS`, `FAIL` |
|
|
176
|
+
| **developer** | Writes code following project patterns, makes failing TDD tests green | `DONE`, `BLOCKED` |
|
|
177
|
+
| **tester** | Parametric testing agent — unit, integration, acceptance, smoke. Supports TDD mode | `PASS`, `FAIL` |
|
|
178
|
+
| **inspector** | Validates test quality — coverage, naming, assertions, mocking, isolation, edge cases | `APPROVE`, `REQUEST_CHANGES` |
|
|
179
|
+
| **reviewer** | Code review with iterations and escalation. Modes: default, plan_review, quick | `APPROVE`, `REQUEST_CHANGES`, `ESCALATE` |
|
|
180
|
+
| **planner** | Project-level planning — milestones, tasks, dependencies, completeness validation | `VALID`, `ISSUES_FOUND` |
|
|
181
|
+
|
|
182
|
+
### Planning (4 agents)
|
|
183
|
+
|
|
184
|
+
Deep analysis and task decomposition. Available in the **full** preset.
|
|
185
|
+
|
|
186
|
+
| Agent | Description |
|
|
187
|
+
|-------|-------------|
|
|
188
|
+
| **researcher** | Codebase exploration — entry points, patterns, dependencies, integrations |
|
|
189
|
+
| **interviewer** | Structured discovery interview — 3 cycles (general, code-informed, edge cases) |
|
|
190
|
+
| **validator** | Specification validation — 4 modes: userspec, techspec, task, completeness |
|
|
191
|
+
| **decomposer** | Task decomposition — generates atomic tasks with TDD anchors, acceptance criteria, and verify steps |
|
|
192
|
+
|
|
193
|
+
### Security (4 agents)
|
|
194
|
+
|
|
195
|
+
Security audits and infrastructure review. Available in the **full** preset.
|
|
196
|
+
|
|
197
|
+
| Agent | Description |
|
|
198
|
+
|-------|-------------|
|
|
199
|
+
| **auditor** | Security analysis — OWASP Top 10, hardcoded secrets, threat modeling, access control |
|
|
200
|
+
| **prompter** | LLM prompt review — clarity, few-shot quality, output format, injection safety, token efficiency |
|
|
201
|
+
| **deployer** | CI/CD review — workflow correctness, secrets management, platform config, deploy scripts |
|
|
202
|
+
| **scaffolder** | Project infrastructure review — structure, Docker, pre-commit hooks, .gitignore, dependency management |
|
|
203
|
+
|
|
204
|
+
### Documentation (4 agents)
|
|
205
|
+
|
|
206
|
+
Documentation quality and deployment validation. Available in the **full** preset.
|
|
207
|
+
|
|
208
|
+
| Agent | Description |
|
|
209
|
+
|-------|-------------|
|
|
210
|
+
| **librarian** | Documentation review — completeness, freshness, absence of bloat, consistency |
|
|
211
|
+
| **writer** | Generates stakeholder-facing reports and internal documentation |
|
|
212
|
+
| **gatekeeper** | Pre-deploy QA — runs tests, verifies acceptance criteria, checks deferred criteria |
|
|
213
|
+
| **verifier** | Post-deploy QA — live environment verification, manual verification plans |
|
|
214
|
+
|
|
215
|
+
## Skills (Slash Commands)
|
|
216
|
+
|
|
217
|
+
### Core skills (all presets) — 10 commands
|
|
58
218
|
|
|
59
219
|
| Command | Description |
|
|
60
220
|
|---------|-------------|
|
|
61
|
-
| `/start-session` | Begin work
|
|
62
|
-
| `/end-session` | Save context, checkpoint, create session log, commit
|
|
221
|
+
| `/start-session` | Begin work — sync repo, check checkpoint, load context, show progress |
|
|
222
|
+
| `/end-session` | Save context, checkpoint, create session log, commit and push |
|
|
63
223
|
| `/take-task [id]` | Full development cycle with feature-size routing (S/M/L) |
|
|
64
224
|
| `/complete-task [id]` | Verify task, smoke test, update progress, clear checkpoint |
|
|
65
225
|
| `/status` | Show project status, deadlines, blockers |
|
|
66
|
-
| `/plan [mode]` | Plan
|
|
67
|
-
| `/review [file]` | Code review for file or task |
|
|
226
|
+
| `/plan [mode]` | Plan, replan, or validate tasks from documentation |
|
|
227
|
+
| `/review [file]` | Code review for a file or task |
|
|
68
228
|
| `/code [task]` | Direct code generation for a specific task |
|
|
69
229
|
| `/test [target]` | Run or generate tests for a target |
|
|
70
230
|
| `/done [id]` | Quick-complete a task with minimal ceremony |
|
|
71
231
|
|
|
72
|
-
|
|
232
|
+
### Extra skills (full preset only) — 11 commands
|
|
73
233
|
|
|
74
234
|
| Command | Description |
|
|
75
235
|
|---------|-------------|
|
|
76
236
|
| `/interview` | Structured discovery interview (3 cycles, completeness >= 85%) |
|
|
77
237
|
| `/audit-wave` | Comprehensive pre-milestone audit with GO/NO-GO verdict |
|
|
78
238
|
| `/write-report` | Generate non-technical progress report for stakeholders |
|
|
79
|
-
| `/dashboard` | Project dashboard
|
|
239
|
+
| `/dashboard` | Project dashboard — progress, health, tech debt, activity |
|
|
80
240
|
| `/skill-master [name]` | Create a new custom skill from template |
|
|
81
|
-
| `/decompose [task]` | Break down a task into subtasks |
|
|
241
|
+
| `/decompose [task]` | Break down a task into subtasks with TDD anchors |
|
|
82
242
|
| `/feature [name]` | Scaffold a new feature end-to-end |
|
|
83
243
|
| `/security [target]` | Run security analysis on a target |
|
|
84
244
|
| `/spec [feature]` | Generate specification for a feature |
|
|
85
245
|
| `/techspec [module]` | Generate technical specification for a module |
|
|
86
246
|
| `/prompts [agent]` | Manage and optimize agent prompts |
|
|
87
247
|
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
Tasks are automatically classified and routed through the appropriate pipeline:
|
|
91
|
-
|
|
92
|
-
| Size | Criteria | Steps |
|
|
93
|
-
|------|----------|-------|
|
|
94
|
-
| **S** | 1 file, < 50 lines | checkpoint → code → tester+inspector → quick-review → tech-debt → fixation (6 steps) |
|
|
95
|
-
| **M** | 2-5 files, new module | checkpoint → analysis → TDD(RED) → code+tester+inspector → review → tech-debt → fixation (8 steps) |
|
|
96
|
-
| **L** | 6+ files, architecture changes | full cycle with architect, skeptic, per-feature loops, inspector, multi-round review (10 steps) |
|
|
97
|
-
|
|
98
|
-
### Checkpoint System
|
|
248
|
+
## Rules
|
|
99
249
|
|
|
100
|
-
|
|
250
|
+
8 development standards that are loaded automatically and enforced across all agents:
|
|
101
251
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
-
|
|
105
|
-
|
|
106
|
-
|
|
252
|
+
| Rule | Purpose |
|
|
253
|
+
|------|---------|
|
|
254
|
+
| `commit-conventions` | Commit message format — `[type](scope): description` |
|
|
255
|
+
| `development-cycle` | Feature-size routing (S/M/L) and pipeline step definitions |
|
|
256
|
+
| `testing-standards` | Test coverage >= 80%, edge cases, access control testing |
|
|
257
|
+
| `shared-resources` | Singleton resource registry — no duplicate DB connections or API clients |
|
|
258
|
+
| `context-loading` | Just-in-time context loading — pass data, not file references |
|
|
259
|
+
| `agent-output-format` | JSON output standard for all agents with structured verdicts |
|
|
260
|
+
| `quality-gates` | Verdict-based routing between pipeline steps |
|
|
261
|
+
| `rollback-protocol` | Rollback procedures for failed deployments |
|
|
107
262
|
|
|
108
|
-
|
|
109
|
-
- **Stop hook** — Reminds to save checkpoint and run `/end-session` before exiting
|
|
263
|
+
## Quality Gates
|
|
110
264
|
|
|
111
|
-
|
|
265
|
+
Every agent returns a structured verdict. The Team Lead reads the verdict and routes the pipeline:
|
|
112
266
|
|
|
113
|
-
|
|
267
|
+
```mermaid
|
|
268
|
+
graph TD
|
|
269
|
+
A["Agent returns verdict"] --> B{"Verdict type?"}
|
|
270
|
+
B -->|"PASS / APPROVE / DONE"| C["Continue pipeline"]
|
|
271
|
+
B -->|"WARNINGS / ATTENTION"| D["Show to user,<br/>continue"]
|
|
272
|
+
B -->|"FAIL / BLOCKED"| E{"Retry count < 3?"}
|
|
273
|
+
E -->|"Yes"| F["Return to<br/>previous step"]
|
|
274
|
+
E -->|"No"| G["Escalate to user"]
|
|
275
|
+
F --> A
|
|
114
276
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
| `testing-standards` | Test coverage and quality requirements |
|
|
120
|
-
| `shared-resources` | Singleton resource registry and patterns |
|
|
121
|
-
| `context-loading` | Just-in-time context loading, anti-patterns |
|
|
122
|
-
| `agent-output-format` | JSON output standard for all agents |
|
|
123
|
-
| `quality-gates` | Verdict-based routing and quality checkpoints |
|
|
124
|
-
| `rollback-protocol` | Rollback procedures for failed deployments |
|
|
277
|
+
style C fill:#d4edda,stroke:#28a745
|
|
278
|
+
style D fill:#fff3cd,stroke:#ffc107
|
|
279
|
+
style G fill:#f8d7da,stroke:#dc3545
|
|
280
|
+
```
|
|
125
281
|
|
|
126
|
-
|
|
282
|
+
### Verdict matrix
|
|
283
|
+
|
|
284
|
+
```mermaid
|
|
285
|
+
graph LR
|
|
286
|
+
subgraph "Analysis"
|
|
287
|
+
A1["analyst"] -->|COMPLETE| A2["architect"]
|
|
288
|
+
A1 -->|NEEDS_DISCOVERY| A3["ask user"]
|
|
289
|
+
A3 --> A1
|
|
290
|
+
end
|
|
291
|
+
|
|
292
|
+
subgraph "Architecture"
|
|
293
|
+
A2 -->|READY| SK["skeptic"]
|
|
294
|
+
A2 -->|NEEDS_INPUT| A4["ask user"]
|
|
295
|
+
A4 --> A2
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
subgraph "Reality Check"
|
|
299
|
+
SK -->|PASS| DEV["developer"]
|
|
300
|
+
SK -->|FAIL| A2
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
subgraph "Code + Tests"
|
|
304
|
+
DEV -->|DONE| TST["tester"]
|
|
305
|
+
TST -->|PASS| INS["inspector"]
|
|
306
|
+
TST -->|FAIL| DEV
|
|
307
|
+
INS -->|APPROVE| REV["reviewer"]
|
|
308
|
+
INS -->|REQUEST_CHANGES| TST
|
|
309
|
+
end
|
|
310
|
+
|
|
311
|
+
subgraph "Review"
|
|
312
|
+
REV -->|APPROVE| FIN["finalize"]
|
|
313
|
+
REV -->|REQUEST_CHANGES| DEV
|
|
314
|
+
end
|
|
315
|
+
|
|
316
|
+
style FIN fill:#d4edda,stroke:#28a745
|
|
317
|
+
```
|
|
127
318
|
|
|
128
|
-
|
|
319
|
+
## CLI Commands
|
|
129
320
|
|
|
130
|
-
|
|
131
|
-
|--------|--------|--------|-------------|
|
|
132
|
-
| **minimal** | 5 | 10 | Essentials + inspector |
|
|
133
|
-
| **core** (default) | 8 | 10 | Full development pipeline |
|
|
134
|
-
| **full** | 20 | 21 | All categories + extra skills |
|
|
321
|
+
### `agent-forge init`
|
|
135
322
|
|
|
136
|
-
|
|
323
|
+
Initialize AI-driven development infrastructure in the current directory.
|
|
137
324
|
|
|
138
325
|
```bash
|
|
139
|
-
npx @alxyrgin/agent-forge init
|
|
326
|
+
npx @alxyrgin/agent-forge init # interactive setup
|
|
327
|
+
npx @alxyrgin/agent-forge init --yes # use defaults (TypeScript, core preset)
|
|
328
|
+
npx @alxyrgin/agent-forge init --overwrite # overwrite existing files
|
|
140
329
|
```
|
|
141
330
|
|
|
142
|
-
|
|
331
|
+
The wizard prompts for:
|
|
143
332
|
- Project name and description
|
|
144
|
-
- Technology stack (Python/TypeScript/Go/Rust)
|
|
333
|
+
- Technology stack (Python / TypeScript / Go / Rust)
|
|
145
334
|
- Framework and test framework
|
|
146
335
|
- Team members (names, roles, emails)
|
|
147
336
|
- Milestones (optional)
|
|
148
|
-
- Agent preset (core/full
|
|
149
|
-
- Commit style (standard/conventional)
|
|
337
|
+
- Agent preset (minimal / core / full)
|
|
338
|
+
- Commit style (standard / conventional)
|
|
339
|
+
|
|
340
|
+
### `agent-forge update`
|
|
150
341
|
|
|
151
|
-
|
|
342
|
+
Update framework files while preserving your data.
|
|
152
343
|
|
|
153
344
|
```bash
|
|
154
|
-
npx @alxyrgin/agent-forge
|
|
345
|
+
npx @alxyrgin/agent-forge update
|
|
155
346
|
```
|
|
156
347
|
|
|
157
|
-
|
|
348
|
+
**Overwritten** (updated to latest version):
|
|
349
|
+
- `.claude/CLAUDE.md`
|
|
350
|
+
- `.claude/agents/*`
|
|
351
|
+
- `.claude/skills/*`
|
|
352
|
+
- `.claude/rules/*`
|
|
353
|
+
- `.claude/hooks/*`
|
|
354
|
+
- `.claude/settings.json`
|
|
158
355
|
|
|
159
|
-
|
|
356
|
+
**Preserved** (your data stays intact):
|
|
357
|
+
- `dev-infra/memory/*` — your Memory Bank
|
|
358
|
+
- `dev-infra/tasks/*` — your task tracking
|
|
359
|
+
- `dev-infra/sessions/*` — your session logs
|
|
360
|
+
- `dev-infra/tests/*` — your test structure
|
|
160
361
|
|
|
161
|
-
|
|
362
|
+
### `agent-forge doctor`
|
|
162
363
|
|
|
163
|
-
|
|
164
|
-
- `--yes, -y` — skip prompts, use defaults
|
|
165
|
-
- `--overwrite` — overwrite existing files
|
|
364
|
+
Check integrity of the generated structure. Verifies that all expected files exist and are not empty.
|
|
166
365
|
|
|
167
|
-
|
|
366
|
+
```bash
|
|
367
|
+
npx @alxyrgin/agent-forge doctor
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
## Memory Bank
|
|
371
|
+
|
|
372
|
+
9 files that persist context across sessions. The Team Lead reads and updates these automatically.
|
|
373
|
+
|
|
374
|
+
| File | Purpose |
|
|
375
|
+
|------|---------|
|
|
376
|
+
| `active-context.md` | Current session state — what is done, what is next |
|
|
377
|
+
| `progress.md` | Milestone progress, task statuses |
|
|
378
|
+
| `project-brief.md` | Project overview, team, stack |
|
|
379
|
+
| `decisions.md` | Architectural Decision Records (ADR) |
|
|
380
|
+
| `tech-stack.md` | Technology stack details |
|
|
381
|
+
| `tech-debt.md` | Technical debt registry with lifecycle tracking (open / in_progress / resolved) |
|
|
382
|
+
| `patterns.md` | Code patterns and conventions |
|
|
383
|
+
| `troubleshooting.md` | Problem solutions log |
|
|
384
|
+
| `checkpoint.yml` | Recovery checkpoint for interrupted sessions |
|
|
168
385
|
|
|
169
|
-
|
|
386
|
+
### Checkpoint System
|
|
387
|
+
|
|
388
|
+
The checkpoint (`dev-infra/memory/checkpoint.yml`) enables recovery after session interruptions:
|
|
389
|
+
|
|
390
|
+
- **Automatic saving** — updated after each pipeline step
|
|
391
|
+
- **Recovery on start** — `/start-session` detects an active checkpoint and offers to resume
|
|
392
|
+
- **Cleanup on completion** — `/complete-task` clears the checkpoint
|
|
170
393
|
|
|
171
|
-
|
|
394
|
+
```mermaid
|
|
395
|
+
graph LR
|
|
396
|
+
A["Session interrupted"] --> B["checkpoint.yml<br/>saved automatically"]
|
|
397
|
+
B --> C["Next session:<br/>/start-session"]
|
|
398
|
+
C --> D{"Active<br/>checkpoint?"}
|
|
399
|
+
D -->|"Yes"| E["Offer to resume<br/>from last step"]
|
|
400
|
+
D -->|"No"| F["Fresh start"]
|
|
401
|
+
|
|
402
|
+
style B fill:#fff3cd,stroke:#ffc107
|
|
403
|
+
style E fill:#d4edda,stroke:#28a745
|
|
404
|
+
```
|
|
172
405
|
|
|
173
406
|
## Generated Structure
|
|
174
407
|
|
|
175
408
|
```
|
|
176
409
|
your-project/
|
|
177
410
|
├── .claude/
|
|
178
|
-
│ ├── CLAUDE.md
|
|
179
|
-
│ ├── settings.json
|
|
411
|
+
│ ├── CLAUDE.md # Team Lead instructions
|
|
412
|
+
│ ├── settings.json # Claude Code hooks and env
|
|
180
413
|
│ ├── hooks/
|
|
181
|
-
│ │ └── protect-docs.sh
|
|
182
|
-
│ ├── agents/
|
|
183
|
-
│ │ ├── pipeline/
|
|
184
|
-
│ │ │
|
|
185
|
-
│ │ ├── planning/
|
|
186
|
-
│ │ ├── security/
|
|
187
|
-
│ │ └── documentation/
|
|
188
|
-
│ ├── skills/
|
|
414
|
+
│ │ └── protect-docs.sh # PreToolUse hook — blocks edits in docs/
|
|
415
|
+
│ ├── agents/
|
|
416
|
+
│ │ ├── pipeline/ # analyst, architect, skeptic, developer,
|
|
417
|
+
│ │ │ # tester, inspector, reviewer, planner
|
|
418
|
+
│ │ ├── planning/ # researcher, validator, interviewer, decomposer
|
|
419
|
+
│ │ ├── security/ # auditor, prompter, deployer, scaffolder
|
|
420
|
+
│ │ └── documentation/ # librarian, writer, gatekeeper, verifier
|
|
421
|
+
│ ├── skills/
|
|
189
422
|
│ │ ├── start-session/SKILL.md
|
|
190
423
|
│ │ ├── take-task/SKILL.md
|
|
191
|
-
│ │
|
|
192
|
-
│
|
|
424
|
+
│ │ ├── code/SKILL.md
|
|
425
|
+
│ │ ├── test/SKILL.md
|
|
426
|
+
│ │ └── ... # 10–21 slash commands
|
|
427
|
+
│ └── rules/
|
|
193
428
|
│ ├── commit-conventions.md
|
|
194
429
|
│ ├── development-cycle.md
|
|
195
430
|
│ ├── testing-standards.md
|
|
@@ -199,19 +434,19 @@ your-project/
|
|
|
199
434
|
│ ├── quality-gates.md
|
|
200
435
|
│ └── rollback-protocol.md
|
|
201
436
|
├── dev-infra/
|
|
202
|
-
│ ├── memory/
|
|
437
|
+
│ ├── memory/ # 9 Memory Bank files
|
|
203
438
|
│ │ ├── active-context.md
|
|
204
439
|
│ │ ├── progress.md
|
|
205
440
|
│ │ ├── checkpoint.yml
|
|
206
441
|
│ │ └── ...
|
|
207
442
|
│ ├── tasks/
|
|
208
|
-
│ │ └── tasks.json
|
|
209
|
-
│ ├── sessions/
|
|
210
|
-
│ └── tests/
|
|
211
|
-
│ ├── acceptance/
|
|
212
|
-
│ ├── pmi/
|
|
213
|
-
│ └── results/
|
|
214
|
-
└── .claude-forge.json
|
|
443
|
+
│ │ └── tasks.json # Task tracking
|
|
444
|
+
│ ├── sessions/ # Session logs
|
|
445
|
+
│ └── tests/
|
|
446
|
+
│ ├── acceptance/ # Acceptance criteria
|
|
447
|
+
│ ├── pmi/ # PMI scenarios
|
|
448
|
+
│ └── results/ # Test results
|
|
449
|
+
└── .claude-forge.json # Manifest for doctor and update
|
|
215
450
|
```
|
|
216
451
|
|
|
217
452
|
## License
|
package/dist/index.js
CHANGED
|
@@ -639,14 +639,7 @@ async function generateInfra(ctx, overwrite) {
|
|
|
639
639
|
}
|
|
640
640
|
}
|
|
641
641
|
try {
|
|
642
|
-
const manifest =
|
|
643
|
-
version: "3.0.0",
|
|
644
|
-
createdAt: ctx.today,
|
|
645
|
-
projectName: ctx.projectName,
|
|
646
|
-
agentPreset: ctx.agentPreset,
|
|
647
|
-
language: ctx.language,
|
|
648
|
-
expectedFiles: getExpectedFiles(ctx)
|
|
649
|
-
};
|
|
642
|
+
const manifest = buildManifest(ctx);
|
|
650
643
|
const outputPath = path8.join(ctx.targetDir, ".claude-forge.json");
|
|
651
644
|
const status = await writeFileSafe(
|
|
652
645
|
outputPath,
|
|
@@ -663,6 +656,25 @@ async function generateInfra(ctx, overwrite) {
|
|
|
663
656
|
}
|
|
664
657
|
return result;
|
|
665
658
|
}
|
|
659
|
+
function buildManifest(ctx) {
|
|
660
|
+
return {
|
|
661
|
+
version: "3.0.0",
|
|
662
|
+
createdAt: ctx.today,
|
|
663
|
+
updatedAt: ctx.today,
|
|
664
|
+
projectName: ctx.projectName,
|
|
665
|
+
projectDescription: ctx.projectDescription,
|
|
666
|
+
language: ctx.language,
|
|
667
|
+
agentPreset: ctx.agentPreset,
|
|
668
|
+
stack: ctx.stack,
|
|
669
|
+
framework: ctx.framework,
|
|
670
|
+
testFramework: ctx.testFramework,
|
|
671
|
+
testCommand: ctx.testCommand,
|
|
672
|
+
srcDir: ctx.srcDir,
|
|
673
|
+
testDir: ctx.testDir,
|
|
674
|
+
commitStyle: ctx.commitStyle,
|
|
675
|
+
expectedFiles: getExpectedFiles(ctx)
|
|
676
|
+
};
|
|
677
|
+
}
|
|
666
678
|
function getExpectedFiles(ctx) {
|
|
667
679
|
const files = [
|
|
668
680
|
".claude/CLAUDE.md",
|
|
@@ -942,10 +954,152 @@ async function doctorCommand() {
|
|
|
942
954
|
}
|
|
943
955
|
}
|
|
944
956
|
|
|
957
|
+
// src/commands/update.ts
|
|
958
|
+
import path11 from "path";
|
|
959
|
+
import chalk3 from "chalk";
|
|
960
|
+
import ora2 from "ora";
|
|
961
|
+
function today2() {
|
|
962
|
+
return (/* @__PURE__ */ new Date()).toISOString().split("T")[0];
|
|
963
|
+
}
|
|
964
|
+
function contextFromManifest(manifest, targetDir) {
|
|
965
|
+
return {
|
|
966
|
+
projectName: manifest.projectName || targetDir.split("/").pop() || "my-project",
|
|
967
|
+
projectDescription: manifest.projectDescription || "AI-driven project",
|
|
968
|
+
stack: manifest.stack || "typescript",
|
|
969
|
+
framework: manifest.framework || "None",
|
|
970
|
+
testFramework: manifest.testFramework || "vitest",
|
|
971
|
+
testCommand: manifest.testCommand || "npx vitest run",
|
|
972
|
+
srcDir: manifest.srcDir || "src/",
|
|
973
|
+
testDir: manifest.testDir || "tests/",
|
|
974
|
+
team: [],
|
|
975
|
+
milestones: [],
|
|
976
|
+
agentPreset: manifest.agentPreset || "core",
|
|
977
|
+
language: manifest.language || "ru",
|
|
978
|
+
commitStyle: manifest.commitStyle || "standard",
|
|
979
|
+
today: today2(),
|
|
980
|
+
targetDir
|
|
981
|
+
};
|
|
982
|
+
}
|
|
983
|
+
async function updateCommand() {
|
|
984
|
+
const targetDir = process.cwd();
|
|
985
|
+
console.log();
|
|
986
|
+
console.log(chalk3.bold(" agent-forge update v3.0.0"));
|
|
987
|
+
console.log(chalk3.dim(" Updating framework files..."));
|
|
988
|
+
console.log();
|
|
989
|
+
const manifestPath = path11.join(targetDir, ".claude-forge.json");
|
|
990
|
+
const manifestExists = await fileExists(manifestPath);
|
|
991
|
+
if (!manifestExists) {
|
|
992
|
+
console.log(chalk3.red(" .claude-forge.json not found"));
|
|
993
|
+
console.log(
|
|
994
|
+
chalk3.dim(" This project is not initialized. Run `agent-forge init` first.")
|
|
995
|
+
);
|
|
996
|
+
console.log();
|
|
997
|
+
process.exit(1);
|
|
998
|
+
}
|
|
999
|
+
const manifestRaw = await readFile(manifestPath);
|
|
1000
|
+
let existingManifest;
|
|
1001
|
+
try {
|
|
1002
|
+
existingManifest = JSON.parse(manifestRaw);
|
|
1003
|
+
} catch {
|
|
1004
|
+
console.log(chalk3.red(" .claude-forge.json is corrupted. Cannot update."));
|
|
1005
|
+
console.log(
|
|
1006
|
+
chalk3.dim(" Run `agent-forge init --overwrite` to reinitialize.")
|
|
1007
|
+
);
|
|
1008
|
+
console.log();
|
|
1009
|
+
process.exit(1);
|
|
1010
|
+
}
|
|
1011
|
+
const previousVersion = existingManifest.version || "unknown";
|
|
1012
|
+
const ctx = contextFromManifest(existingManifest, targetDir);
|
|
1013
|
+
const spinner = ora2("Updating framework files...").start();
|
|
1014
|
+
try {
|
|
1015
|
+
const result = {
|
|
1016
|
+
filesCreated: [],
|
|
1017
|
+
filesSkipped: [],
|
|
1018
|
+
errors: []
|
|
1019
|
+
};
|
|
1020
|
+
const frameworkGenerators = [
|
|
1021
|
+
generateClaudeMd,
|
|
1022
|
+
generateAgents,
|
|
1023
|
+
generateSkills,
|
|
1024
|
+
generateRules,
|
|
1025
|
+
generateHooks
|
|
1026
|
+
];
|
|
1027
|
+
for (const generator of frameworkGenerators) {
|
|
1028
|
+
try {
|
|
1029
|
+
const partial = await generator(ctx, true);
|
|
1030
|
+
result.filesCreated.push(...partial.filesCreated);
|
|
1031
|
+
result.filesSkipped.push(...partial.filesSkipped);
|
|
1032
|
+
result.errors.push(...partial.errors);
|
|
1033
|
+
} catch (err) {
|
|
1034
|
+
result.errors.push(`Generator error: ${err}`);
|
|
1035
|
+
}
|
|
1036
|
+
}
|
|
1037
|
+
const userDataGenerators = [
|
|
1038
|
+
generateMemoryBank,
|
|
1039
|
+
generateInfra
|
|
1040
|
+
];
|
|
1041
|
+
for (const generator of userDataGenerators) {
|
|
1042
|
+
try {
|
|
1043
|
+
const partial = await generator(ctx, false);
|
|
1044
|
+
result.filesCreated.push(...partial.filesCreated);
|
|
1045
|
+
result.filesSkipped.push(...partial.filesSkipped);
|
|
1046
|
+
result.errors.push(...partial.errors);
|
|
1047
|
+
} catch (err) {
|
|
1048
|
+
result.errors.push(`Generator error: ${err}`);
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
const updatedManifest = buildManifest(ctx);
|
|
1052
|
+
updatedManifest.createdAt = existingManifest.createdAt || updatedManifest.createdAt;
|
|
1053
|
+
updatedManifest.updatedAt = today2();
|
|
1054
|
+
await writeFileSafe(
|
|
1055
|
+
manifestPath,
|
|
1056
|
+
JSON.stringify(updatedManifest, null, 2) + "\n",
|
|
1057
|
+
true
|
|
1058
|
+
);
|
|
1059
|
+
spinner.succeed(chalk3.green("Framework files updated"));
|
|
1060
|
+
const newFiles = result.filesCreated.filter((f) => !result.filesSkipped.includes(f));
|
|
1061
|
+
const updatedCount = newFiles.length;
|
|
1062
|
+
const skippedCount = result.filesSkipped.length;
|
|
1063
|
+
console.log();
|
|
1064
|
+
if (updatedCount > 0) {
|
|
1065
|
+
console.log(
|
|
1066
|
+
chalk3.green(` + ${updatedCount} files updated/added`)
|
|
1067
|
+
);
|
|
1068
|
+
}
|
|
1069
|
+
if (skippedCount > 0) {
|
|
1070
|
+
console.log(
|
|
1071
|
+
chalk3.yellow(` ~ ${skippedCount} files skipped (user data preserved)`)
|
|
1072
|
+
);
|
|
1073
|
+
}
|
|
1074
|
+
if (result.errors.length > 0) {
|
|
1075
|
+
console.log(chalk3.red(` ! ${result.errors.length} errors:`));
|
|
1076
|
+
for (const err of result.errors) {
|
|
1077
|
+
console.log(chalk3.red(` - ${err}`));
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
console.log();
|
|
1081
|
+
if (previousVersion !== updatedManifest.version) {
|
|
1082
|
+
console.log(
|
|
1083
|
+
chalk3.dim(` .claude-forge.json updated: ${previousVersion} -> v${updatedManifest.version}`)
|
|
1084
|
+
);
|
|
1085
|
+
} else {
|
|
1086
|
+
console.log(
|
|
1087
|
+
chalk3.dim(` .claude-forge.json updated (v${updatedManifest.version})`)
|
|
1088
|
+
);
|
|
1089
|
+
}
|
|
1090
|
+
console.log();
|
|
1091
|
+
} catch (err) {
|
|
1092
|
+
spinner.fail(chalk3.red("Failed to update framework files"));
|
|
1093
|
+
console.error(err);
|
|
1094
|
+
process.exit(1);
|
|
1095
|
+
}
|
|
1096
|
+
}
|
|
1097
|
+
|
|
945
1098
|
// src/index.ts
|
|
946
1099
|
var program = new Command();
|
|
947
1100
|
program.name("agent-forge").description("AI-driven Development Framework for Claude Code").version("3.0.0");
|
|
948
1101
|
program.command("init").description("Initialize AI-driven development infrastructure in the current project").option("-y, --yes", "Skip prompts and use defaults").option("--overwrite", "Overwrite existing files").action(initCommand);
|
|
949
1102
|
program.command("doctor").description("Check integrity of the generated structure").action(doctorCommand);
|
|
1103
|
+
program.command("update").description("Update framework files to the latest version (preserves user data)").action(updateCommand);
|
|
950
1104
|
program.parse();
|
|
951
1105
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/prompts/project-setup.ts","../src/generators/memory-bank.ts","../src/utils/template.ts","../src/utils/fs.ts","../src/generators/agents.ts","../src/generators/skills.ts","../src/generators/rules.ts","../src/generators/claude-md.ts","../src/generators/infra.ts","../src/generators/hooks.ts","../src/generators/index.ts","../src/commands/doctor.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { initCommand } from './commands/init.js';\nimport { doctorCommand } from './commands/doctor.js';\n\nconst program = new Command();\n\nprogram\n .name('agent-forge')\n .description('AI-driven Development Framework for Claude Code')\n .version('3.0.0');\n\nprogram\n .command('init')\n .description('Initialize AI-driven development infrastructure in the current project')\n .option('-y, --yes', 'Skip prompts and use defaults')\n .option('--overwrite', 'Overwrite existing files')\n .action(initCommand);\n\nprogram\n .command('doctor')\n .description('Check integrity of the generated structure')\n .action(doctorCommand);\n\nprogram.parse();\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { promptProjectSetup, getDefaultContext } from '../prompts/project-setup.js';\nimport { generateAll } from '../generators/index.js';\n\ninterface InitOptions {\n yes?: boolean;\n overwrite?: boolean;\n}\n\nexport async function initCommand(options: InitOptions): Promise<void> {\n const targetDir = process.cwd();\n\n console.log();\n console.log(chalk.bold(' agent-forge v3.0.0'));\n console.log(chalk.dim(' AI-driven Development Framework for Claude Code'));\n console.log();\n\n let ctx;\n if (options.yes) {\n ctx = getDefaultContext(targetDir);\n console.log(chalk.dim(' Using default configuration (--yes)'));\n console.log();\n } else {\n ctx = await promptProjectSetup(targetDir);\n console.log();\n }\n\n const spinner = ora('Creating project structure...').start();\n\n try {\n const result = await generateAll(ctx, options.overwrite ?? false);\n\n spinner.succeed(\n chalk.green(`${result.filesCreated.length} files created`)\n );\n\n if (result.filesSkipped.length > 0) {\n console.log(\n chalk.yellow(` ${result.filesSkipped.length} files skipped (already exist)`)\n );\n }\n\n if (result.errors.length > 0) {\n console.log(chalk.red(` ${result.errors.length} errors:`));\n for (const err of result.errors) {\n console.log(chalk.red(` - ${err}`));\n }\n }\n\n console.log();\n console.log(chalk.bold(' Next steps:'));\n console.log(chalk.dim(' 1. Open Claude Code in this directory'));\n console.log(chalk.dim(' 2. /start-session — begin your first session'));\n console.log(chalk.dim(' 3. /plan init — create tasks from your documentation'));\n console.log();\n } catch (err) {\n spinner.fail(chalk.red('Failed to create project structure'));\n console.error(err);\n process.exit(1);\n }\n}\n","import inquirer from 'inquirer';\nimport type { ProjectContext, TeamMember, Milestone, AgentPreset, Language, CommitStyle } from '../types.js';\n\nfunction today(): string {\n return new Date().toISOString().split('T')[0];\n}\n\nconst STACK_CHOICES = [\n { name: 'Python', value: 'python' },\n { name: 'TypeScript / Node.js', value: 'typescript' },\n { name: 'Go', value: 'go' },\n { name: 'Rust', value: 'rust' },\n { name: 'Other', value: 'other' },\n];\n\nconst FRAMEWORK_MAP: Record<string, string[]> = {\n python: ['FastAPI', 'Django', 'Flask', 'None'],\n typescript: ['Next.js', 'Express', 'Fastify', 'None'],\n go: ['Gin', 'Echo', 'Chi', 'None'],\n rust: ['Actix', 'Axum', 'Rocket', 'None'],\n other: ['None'],\n};\n\nconst TEST_MAP: Record<string, { framework: string; command: string }> = {\n python: { framework: 'pytest', command: 'pytest' },\n typescript: { framework: 'vitest', command: 'npx vitest run' },\n go: { framework: 'go test', command: 'go test ./...' },\n rust: { framework: 'cargo test', command: 'cargo test' },\n other: { framework: 'custom', command: 'echo \"no tests configured\"' },\n};\n\nexport async function promptProjectSetup(targetDir: string): Promise<ProjectContext> {\n const base = await inquirer.prompt([\n {\n type: 'input',\n name: 'projectName',\n message: 'Project name:',\n default: targetDir.split('/').pop(),\n },\n {\n type: 'input',\n name: 'projectDescription',\n message: 'Project description:',\n default: 'AI-driven project',\n },\n {\n type: 'list',\n name: 'stack',\n message: 'Technology stack:',\n choices: STACK_CHOICES,\n },\n ]);\n\n const frameworks = FRAMEWORK_MAP[base.stack] || ['None'];\n const frameworkAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'framework',\n message: 'Framework:',\n choices: frameworks,\n },\n ]);\n\n const testDefaults = TEST_MAP[base.stack] || TEST_MAP.other;\n const dirs = await inquirer.prompt([\n {\n type: 'input',\n name: 'testFramework',\n message: 'Test framework:',\n default: testDefaults.framework,\n },\n {\n type: 'input',\n name: 'testCommand',\n message: 'Test command:',\n default: testDefaults.command,\n },\n {\n type: 'input',\n name: 'srcDir',\n message: 'Source directory:',\n default: 'src/',\n },\n {\n type: 'input',\n name: 'testDir',\n message: 'Test directory:',\n default: base.stack === 'python' ? 'src/tests/' : 'tests/',\n },\n ]);\n\n // Team members\n const team: TeamMember[] = [];\n let addMore = true;\n let first = true;\n while (addMore) {\n const member = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: first ? 'Team member name:' : 'Next team member name (leave empty to stop):',\n default: first ? undefined : '',\n },\n ]);\n\n if (!member.name) break;\n\n const details = await inquirer.prompt([\n {\n type: 'input',\n name: 'role',\n message: `${member.name}'s role:`,\n default: 'developer',\n },\n {\n type: 'input',\n name: 'email',\n message: `${member.name}'s email:`,\n },\n ]);\n\n team.push({ name: member.name, role: details.role, email: details.email });\n first = false;\n\n if (team.length >= 10) break;\n const cont = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: 'Add another team member?',\n default: false,\n },\n ]);\n addMore = cont.addMore;\n }\n\n // Milestones\n const milestones: Milestone[] = [];\n const addMilestones = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'add',\n message: 'Add milestones?',\n default: false,\n },\n ]);\n\n if (addMilestones.add) {\n let addMoreMs = true;\n while (addMoreMs) {\n const ms = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Milestone name:',\n },\n {\n type: 'input',\n name: 'deadline',\n message: 'Deadline (YYYY-MM-DD):',\n },\n {\n type: 'input',\n name: 'description',\n message: 'Description (optional):',\n default: '',\n },\n ]);\n milestones.push({\n name: ms.name,\n deadline: ms.deadline,\n description: ms.description || undefined,\n });\n\n const cont = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: 'Add another milestone?',\n default: false,\n },\n ]);\n addMoreMs = cont.addMore;\n }\n }\n\n const config = await inquirer.prompt([\n {\n type: 'list',\n name: 'agentPreset',\n message: 'Agent preset:',\n choices: [\n { name: 'Core (8 agents — development pipeline)', value: 'core' },\n { name: 'Full (20 agents — all categories + extra skills)', value: 'full' },\n { name: 'Minimal (5 agents — essentials + inspector)', value: 'minimal' },\n ],\n },\n {\n type: 'list',\n name: 'language',\n message: 'Instructions language:',\n choices: [\n { name: 'Russian', value: 'ru' },\n { name: 'English', value: 'en' },\n ],\n },\n {\n type: 'list',\n name: 'commitStyle',\n message: 'Commit style:',\n choices: [\n { name: 'Standard (type(scope): description)', value: 'standard' },\n { name: 'Conventional Commits', value: 'conventional' },\n ],\n },\n ]);\n\n return {\n projectName: base.projectName,\n projectDescription: base.projectDescription,\n stack: base.stack,\n framework: frameworkAnswer.framework,\n testFramework: dirs.testFramework,\n testCommand: dirs.testCommand,\n srcDir: dirs.srcDir,\n testDir: dirs.testDir,\n team,\n milestones,\n agentPreset: config.agentPreset as AgentPreset,\n language: config.language as Language,\n commitStyle: config.commitStyle as CommitStyle,\n today: today(),\n targetDir,\n };\n}\n\nexport function getDefaultContext(targetDir: string): ProjectContext {\n return {\n projectName: targetDir.split('/').pop() || 'my-project',\n projectDescription: 'AI-driven project',\n stack: 'typescript',\n framework: 'None',\n testFramework: 'vitest',\n testCommand: 'npx vitest run',\n srcDir: 'src/',\n testDir: 'tests/',\n team: [{ name: 'Developer', role: 'developer', email: '' }],\n milestones: [],\n agentPreset: 'core',\n language: 'en',\n commitStyle: 'standard',\n today: today(),\n targetDir,\n };\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nconst MEMORY_FILES = [\n 'active-context.md',\n 'progress.md',\n 'project-brief.md',\n 'decisions.md',\n 'tech-stack.md',\n 'tech-debt.md',\n 'patterns.md',\n 'troubleshooting.md',\n 'checkpoint.yml',\n];\n\nexport async function generateMemoryBank(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n for (const file of MEMORY_FILES) {\n try {\n const content = await renderTemplate(`memory/${file}.ejs`, templateData);\n const outputPath = path.join(ctx.targetDir, 'dev-infra/memory', file);\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Memory ${file}: ${err}`);\n }\n }\n\n return result;\n}\n","import ejs from 'ejs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { readFile } from './fs.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// In dev: src/utils/template.ts -> ../../templates\n// In dist: dist/index.mjs -> ../templates\n// We try ../templates first (dist), then ../../templates (dev/test)\nimport fs from 'fs';\nconst distPath = path.resolve(__dirname, '../templates');\nconst devPath = path.resolve(__dirname, '../../templates');\nconst TEMPLATES_DIR = fs.existsSync(distPath) ? distPath : devPath;\n\nexport function getTemplatesDir(): string {\n return TEMPLATES_DIR;\n}\n\nexport async function renderTemplate(\n templatePath: string,\n data: Record<string, unknown>\n): Promise<string> {\n const fullPath = path.join(TEMPLATES_DIR, templatePath);\n const template = await readFile(fullPath);\n return ejs.render(template, data, {\n filename: fullPath,\n async: false,\n });\n}\n\nexport function renderString(\n template: string,\n data: Record<string, unknown>\n): string {\n return ejs.render(template, data);\n}\n","import fs from 'fs-extra';\nimport path from 'path';\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n overwrite: boolean = false\n): Promise<'created' | 'skipped' | 'overwritten'> {\n const dir = path.dirname(filePath);\n await fs.ensureDir(dir);\n\n if (await fs.pathExists(filePath)) {\n if (!overwrite) {\n return 'skipped';\n }\n await fs.writeFile(filePath, content, 'utf-8');\n return 'overwritten';\n }\n\n await fs.writeFile(filePath, content, 'utf-8');\n return 'created';\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n return fs.pathExists(filePath);\n}\n\nexport async function readFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf-8');\n}\n\nexport async function makeExecutable(filePath: string): Promise<void> {\n await fs.chmod(filePath, 0o755);\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult, AgentPreset } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\n// --- Agent categories ---\n\nconst PIPELINE_AGENTS = [\n 'analyst',\n 'architect',\n 'skeptic',\n 'developer',\n 'tester',\n 'inspector',\n 'reviewer',\n 'planner',\n];\n\nconst PLANNING_AGENTS = [\n 'researcher',\n 'validator',\n 'interviewer',\n 'decomposer',\n];\n\nconst SECURITY_AGENTS = [\n 'auditor',\n 'prompter',\n 'deployer',\n 'scaffolder',\n];\n\nconst DOCUMENTATION_AGENTS = [\n 'librarian',\n 'writer',\n 'gatekeeper',\n 'verifier',\n];\n\n// --- Presets ---\n\nconst MINIMAL_AGENTS = [\n 'analyst',\n 'developer',\n 'tester',\n 'reviewer',\n 'inspector',\n];\n\nconst CORE_AGENTS = [...PIPELINE_AGENTS];\n\nconst FULL_AGENTS = [\n ...PIPELINE_AGENTS,\n ...PLANNING_AGENTS,\n ...SECURITY_AGENTS,\n ...DOCUMENTATION_AGENTS,\n];\n\n// --- Helpers ---\n\nconst CATEGORY_MAP: Record<string, string> = {};\n\nfor (const name of PIPELINE_AGENTS) {\n CATEGORY_MAP[name] = 'pipeline';\n}\nfor (const name of PLANNING_AGENTS) {\n CATEGORY_MAP[name] = 'planning';\n}\nfor (const name of SECURITY_AGENTS) {\n CATEGORY_MAP[name] = 'security';\n}\nfor (const name of DOCUMENTATION_AGENTS) {\n CATEGORY_MAP[name] = 'documentation';\n}\n\n/**\n * Returns the template subdirectory for a given agent name.\n * Templates live at templates/agents/[category]/[name].md.ejs\n */\nexport function getAgentCategory(name: string): string {\n return CATEGORY_MAP[name] || 'pipeline';\n}\n\n/**\n * Returns the list of agents for the given preset.\n */\nexport function getAgentList(preset: AgentPreset): { name: string; category: string }[] {\n let names: string[];\n\n switch (preset) {\n case 'minimal':\n names = MINIMAL_AGENTS;\n break;\n case 'full':\n names = FULL_AGENTS;\n break;\n case 'core':\n default:\n names = CORE_AGENTS;\n break;\n }\n\n return names.map((name) => ({\n name,\n category: getAgentCategory(name),\n }));\n}\n\nexport async function generateAgents(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const agents = getAgentList(ctx.agentPreset);\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n for (const agent of agents) {\n try {\n const content = await renderTemplate(\n `agents/${agent.category}/${agent.name}.md.ejs`,\n templateData\n );\n // Output is always flat: .claude/agents/[name].md\n const outputPath = path.join(ctx.targetDir, '.claude/agents', `${agent.name}.md`);\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Agent ${agent.name}: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult, AgentPreset } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nconst CORE_SKILLS = [\n 'start-session',\n 'end-session',\n 'take-task',\n 'complete-task',\n 'status',\n 'plan',\n 'review',\n 'code',\n 'test',\n 'done',\n];\n\nconst EXTRA_SKILLS = [\n 'interview',\n 'audit-wave',\n 'write-report',\n 'dashboard',\n 'skill-master',\n 'decompose',\n 'feature',\n 'security',\n 'spec',\n 'techspec',\n 'prompts',\n];\n\nfunction getSkillList(preset: AgentPreset): { name: string; dir: string }[] {\n const skills: { name: string; dir: string }[] = [];\n\n for (const name of CORE_SKILLS) {\n skills.push({ name, dir: 'core' });\n }\n\n if (preset === 'full') {\n for (const name of EXTRA_SKILLS) {\n skills.push({ name, dir: 'extra' });\n }\n }\n\n return skills;\n}\n\nexport async function generateSkills(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n const skills = getSkillList(ctx.agentPreset);\n\n for (const skill of skills) {\n try {\n const content = await renderTemplate(\n `skills/${skill.dir}/${skill.name}/SKILL.md.ejs`,\n templateData\n );\n const outputPath = path.join(ctx.targetDir, `.claude/skills/${skill.name}`, 'SKILL.md');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Skill ${skill.name}: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nconst RULES = [\n 'commit-conventions',\n 'development-cycle',\n 'testing-standards',\n 'shared-resources',\n 'context-loading',\n 'agent-output-format',\n 'quality-gates',\n 'rollback-protocol',\n];\n\nexport async function generateRules(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n for (const rule of RULES) {\n try {\n const content = await renderTemplate(`rules/${rule}.md.ejs`, templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/rules', `${rule}.md`);\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Rule ${rule}: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nexport async function generateClaudeMd(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n // CLAUDE.md\n try {\n const content = await renderTemplate('root/CLAUDE.md.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/CLAUDE.md');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`CLAUDE.md: ${err}`);\n }\n\n // settings.json\n try {\n const content = await renderTemplate('root/settings.json.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/settings.json');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`settings.json: ${err}`);\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe, ensureDir } from '../utils/fs.js';\n\nexport async function generateInfra(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n // tasks.json\n try {\n const content = await renderTemplate('tasks/tasks.json.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, 'dev-infra/tasks/tasks.json');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`tasks.json: ${err}`);\n }\n\n // Create empty directories with .gitkeep\n const dirs = [\n 'dev-infra/sessions',\n 'dev-infra/tests/acceptance',\n 'dev-infra/tests/pmi',\n 'dev-infra/tests/results',\n ];\n\n for (const dir of dirs) {\n try {\n const dirPath = path.join(ctx.targetDir, dir);\n await ensureDir(dirPath);\n const gitkeepPath = path.join(dirPath, '.gitkeep');\n const status = await writeFileSafe(gitkeepPath, '', overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(gitkeepPath);\n } else {\n result.filesCreated.push(gitkeepPath);\n }\n } catch (err) {\n result.errors.push(`Dir ${dir}: ${err}`);\n }\n }\n\n // .claude-forge.json — manifest for doctor command\n try {\n const manifest = {\n version: '3.0.0',\n createdAt: ctx.today,\n projectName: ctx.projectName,\n agentPreset: ctx.agentPreset,\n language: ctx.language,\n expectedFiles: getExpectedFiles(ctx),\n };\n const outputPath = path.join(ctx.targetDir, '.claude-forge.json');\n const status = await writeFileSafe(\n outputPath,\n JSON.stringify(manifest, null, 2) + '\\n',\n overwrite\n );\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`.claude-forge.json: ${err}`);\n }\n\n return result;\n}\n\nfunction getExpectedFiles(ctx: ProjectContext): string[] {\n const files = [\n '.claude/CLAUDE.md',\n '.claude/settings.json',\n '.claude-forge.json',\n 'dev-infra/tasks/tasks.json',\n 'dev-infra/memory/active-context.md',\n 'dev-infra/memory/progress.md',\n 'dev-infra/memory/project-brief.md',\n 'dev-infra/memory/decisions.md',\n 'dev-infra/memory/tech-stack.md',\n 'dev-infra/memory/tech-debt.md',\n 'dev-infra/memory/patterns.md',\n 'dev-infra/memory/troubleshooting.md',\n 'dev-infra/memory/checkpoint.yml',\n ];\n\n // Hooks\n files.push('.claude/hooks/protect-docs.sh');\n\n // Rules (8 total)\n files.push(\n '.claude/rules/commit-conventions.md',\n '.claude/rules/development-cycle.md',\n '.claude/rules/testing-standards.md',\n '.claude/rules/shared-resources.md',\n '.claude/rules/context-loading.md',\n '.claude/rules/agent-output-format.md',\n '.claude/rules/quality-gates.md',\n '.claude/rules/rollback-protocol.md',\n );\n\n // Skills (10 core + 11 extra for full)\n const coreSkills = [\n 'start-session', 'end-session', 'take-task',\n 'complete-task', 'status', 'plan', 'review',\n 'code', 'test', 'done',\n ];\n const extraSkills = [\n 'interview', 'audit-wave', 'write-report', 'dashboard', 'skill-master',\n 'decompose', 'feature', 'security', 'spec', 'techspec', 'prompts',\n ];\n const skills = ctx.agentPreset === 'full'\n ? [...coreSkills, ...extraSkills]\n : coreSkills;\n for (const skill of skills) {\n files.push(`.claude/skills/${skill}/SKILL.md`);\n }\n\n // Agents depend on preset\n const pipelineAgents = [\n 'analyst', 'architect', 'skeptic', 'developer',\n 'tester', 'inspector', 'reviewer', 'planner',\n ];\n const planningAgents = ['researcher', 'validator', 'interviewer', 'decomposer'];\n const securityAgents = ['auditor', 'prompter', 'deployer', 'scaffolder'];\n const documentationAgents = ['librarian', 'writer', 'gatekeeper', 'verifier'];\n\n const minimalAgents = ['analyst', 'developer', 'tester', 'reviewer', 'inspector'];\n\n const coreAgents = [...pipelineAgents];\n const fullAgents = [\n ...pipelineAgents,\n ...planningAgents,\n ...securityAgents,\n ...documentationAgents,\n ];\n\n const agents = ctx.agentPreset === 'minimal'\n ? minimalAgents\n : ctx.agentPreset === 'full'\n ? fullAgents\n : coreAgents;\n\n for (const agent of agents) {\n files.push(`.claude/agents/${agent}.md`);\n }\n\n return files;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe, makeExecutable } from '../utils/fs.js';\n\nexport async function generateHooks(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n try {\n const content = await renderTemplate('hooks/protect-docs.sh.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/hooks/protect-docs.sh');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n await makeExecutable(outputPath);\n }\n } catch (err) {\n result.errors.push(`Hook protect-docs.sh: ${err}`);\n }\n\n return result;\n}\n","import type { ProjectContext, GeneratorResult } from '../types.js';\nimport { generateMemoryBank } from './memory-bank.js';\nimport { generateAgents } from './agents.js';\nimport { generateSkills } from './skills.js';\nimport { generateRules } from './rules.js';\nimport { generateClaudeMd } from './claude-md.js';\nimport { generateInfra } from './infra.js';\nimport { generateHooks } from './hooks.js';\n\nexport async function generateAll(\n ctx: ProjectContext,\n overwrite: boolean = false\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const generators = [\n generateClaudeMd,\n generateAgents,\n generateSkills,\n generateRules,\n generateMemoryBank,\n generateHooks,\n generateInfra,\n ];\n\n for (const generator of generators) {\n try {\n const partial = await generator(ctx, overwrite);\n result.filesCreated.push(...partial.filesCreated);\n result.filesSkipped.push(...partial.filesSkipped);\n result.errors.push(...partial.errors);\n } catch (err) {\n result.errors.push(`Generator error: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport chalk from 'chalk';\nimport { fileExists, readFile } from '../utils/fs.js';\nimport type { DoctorCheck } from '../types.js';\n\nexport async function doctorCommand(): Promise<void> {\n const targetDir = process.cwd();\n\n console.log();\n console.log(chalk.bold(' agent-forge doctor'));\n console.log(chalk.dim(' Checking project structure integrity...'));\n console.log();\n\n // Load manifest\n const manifestPath = path.join(targetDir, '.claude-forge.json');\n const manifestExists = await fileExists(manifestPath);\n\n if (!manifestExists) {\n console.log(chalk.red(' .claude-forge.json not found'));\n console.log(chalk.dim(' Run `agent-forge init` first to initialize the project.'));\n console.log();\n process.exit(1);\n }\n\n const manifestRaw = await readFile(manifestPath);\n let manifest: { version: string; expectedFiles: string[]; projectName: string };\n\n try {\n manifest = JSON.parse(manifestRaw);\n } catch {\n console.log(chalk.red(' .claude-forge.json is corrupted'));\n process.exit(1);\n }\n\n console.log(chalk.dim(` Project: ${manifest.projectName}`));\n console.log(chalk.dim(` Version: ${manifest.version}`));\n console.log();\n\n const checks: DoctorCheck[] = [];\n let okCount = 0;\n let failCount = 0;\n\n for (const file of manifest.expectedFiles) {\n const filePath = path.join(targetDir, file);\n const exists = await fileExists(filePath);\n\n const check: DoctorCheck = {\n name: file,\n path: filePath,\n exists,\n ok: exists,\n };\n\n if (exists) {\n // Check if file is not empty\n try {\n const content = await readFile(filePath);\n if (content.trim().length === 0) {\n check.ok = false;\n check.message = 'File is empty';\n }\n } catch {\n check.ok = false;\n check.message = 'Cannot read file';\n }\n } else {\n check.message = 'File not found';\n }\n\n checks.push(check);\n if (check.ok) okCount++;\n else failCount++;\n }\n\n // Display results grouped by category\n const categories: Record<string, DoctorCheck[]> = {};\n for (const check of checks) {\n const category = check.name.startsWith('.claude/agents')\n ? 'Agents'\n : check.name.startsWith('.claude/skills')\n ? 'Skills'\n : check.name.startsWith('.claude/rules')\n ? 'Rules'\n : check.name.startsWith('.claude/')\n ? 'Claude Config'\n : check.name.startsWith('dev-infra/memory')\n ? 'Memory Bank'\n : check.name.startsWith('dev-infra/')\n ? 'Infrastructure'\n : 'Other';\n\n if (!categories[category]) categories[category] = [];\n categories[category].push(check);\n }\n\n for (const [category, items] of Object.entries(categories)) {\n const allOk = items.every(c => c.ok);\n const icon = allOk ? chalk.green('OK') : chalk.red('!!');\n console.log(` ${icon} ${chalk.bold(category)}`);\n\n for (const item of items) {\n if (item.ok) {\n console.log(chalk.green(` + ${item.name}`));\n } else {\n console.log(chalk.red(` - ${item.name} (${item.message})`));\n }\n }\n console.log();\n }\n\n // Summary\n console.log(chalk.bold(' Summary'));\n console.log(chalk.green(` OK: ${okCount}`));\n if (failCount > 0) {\n console.log(chalk.red(` Missing/broken: ${failCount}`));\n console.log();\n console.log(chalk.dim(' Run `agent-forge init --overwrite` to regenerate missing files.'));\n } else {\n console.log(chalk.green(' All checks passed!'));\n }\n console.log();\n\n if (failCount > 0) {\n process.exit(1);\n }\n}\n"],"mappings":";;;AAAA,SAAS,eAAe;;;ACAxB,OAAO,WAAW;AAClB,OAAO,SAAS;;;ACDhB,OAAO,cAAc;AAGrB,SAAS,QAAgB;AACvB,UAAO,oBAAI,KAAK,GAAE,YAAY,EAAE,MAAM,GAAG,EAAE,CAAC;AAC9C;AAEA,IAAM,gBAAgB;AAAA,EACpB,EAAE,MAAM,UAAU,OAAO,SAAS;AAAA,EAClC,EAAE,MAAM,wBAAwB,OAAO,aAAa;AAAA,EACpD,EAAE,MAAM,MAAM,OAAO,KAAK;AAAA,EAC1B,EAAE,MAAM,QAAQ,OAAO,OAAO;AAAA,EAC9B,EAAE,MAAM,SAAS,OAAO,QAAQ;AAClC;AAEA,IAAM,gBAA0C;AAAA,EAC9C,QAAQ,CAAC,WAAW,UAAU,SAAS,MAAM;AAAA,EAC7C,YAAY,CAAC,WAAW,WAAW,WAAW,MAAM;AAAA,EACpD,IAAI,CAAC,OAAO,QAAQ,OAAO,MAAM;AAAA,EACjC,MAAM,CAAC,SAAS,QAAQ,UAAU,MAAM;AAAA,EACxC,OAAO,CAAC,MAAM;AAChB;AAEA,IAAM,WAAmE;AAAA,EACvE,QAAQ,EAAE,WAAW,UAAU,SAAS,SAAS;AAAA,EACjD,YAAY,EAAE,WAAW,UAAU,SAAS,iBAAiB;AAAA,EAC7D,IAAI,EAAE,WAAW,WAAW,SAAS,gBAAgB;AAAA,EACrD,MAAM,EAAE,WAAW,cAAc,SAAS,aAAa;AAAA,EACvD,OAAO,EAAE,WAAW,UAAU,SAAS,6BAA6B;AACtE;AAEA,eAAsB,mBAAmB,WAA4C;AACnF,QAAM,OAAO,MAAM,SAAS,OAAO;AAAA,IACjC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,UAAU,MAAM,GAAG,EAAE,IAAI;AAAA,IACpC;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,QAAM,aAAa,cAAc,KAAK,KAAK,KAAK,CAAC,MAAM;AACvD,QAAM,kBAAkB,MAAM,SAAS,OAAO;AAAA,IAC5C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,QAAM,eAAe,SAAS,KAAK,KAAK,KAAK,SAAS;AACtD,QAAM,OAAO,MAAM,SAAS,OAAO;AAAA,IACjC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,aAAa;AAAA,IACxB;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,aAAa;AAAA,IACxB;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS,KAAK,UAAU,WAAW,eAAe;AAAA,IACpD;AAAA,EACF,CAAC;AAGD,QAAM,OAAqB,CAAC;AAC5B,MAAI,UAAU;AACd,MAAI,QAAQ;AACZ,SAAO,SAAS;AACd,UAAM,SAAS,MAAM,SAAS,OAAO;AAAA,MACnC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,QAAQ,sBAAsB;AAAA,QACvC,SAAS,QAAQ,SAAY;AAAA,MAC/B;AAAA,IACF,CAAC;AAED,QAAI,CAAC,OAAO,KAAM;AAElB,UAAM,UAAU,MAAM,SAAS,OAAO;AAAA,MACpC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,GAAG,OAAO,IAAI;AAAA,QACvB,SAAS;AAAA,MACX;AAAA,MACA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS,GAAG,OAAO,IAAI;AAAA,MACzB;AAAA,IACF,CAAC;AAED,SAAK,KAAK,EAAE,MAAM,OAAO,MAAM,MAAM,QAAQ,MAAM,OAAO,QAAQ,MAAM,CAAC;AACzE,YAAQ;AAER,QAAI,KAAK,UAAU,GAAI;AACvB,UAAM,OAAO,MAAM,SAAS,OAAO;AAAA,MACjC;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,SAAS;AAAA,QACT,SAAS;AAAA,MACX;AAAA,IACF,CAAC;AACD,cAAU,KAAK;AAAA,EACjB;AAGA,QAAM,aAA0B,CAAC;AACjC,QAAM,gBAAgB,MAAM,SAAS,OAAO;AAAA,IAC1C;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,IACX;AAAA,EACF,CAAC;AAED,MAAI,cAAc,KAAK;AACrB,QAAI,YAAY;AAChB,WAAO,WAAW;AAChB,YAAM,KAAK,MAAM,SAAS,OAAO;AAAA,QAC/B;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,QACX;AAAA,QACA;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AACD,iBAAW,KAAK;AAAA,QACd,MAAM,GAAG;AAAA,QACT,UAAU,GAAG;AAAA,QACb,aAAa,GAAG,eAAe;AAAA,MACjC,CAAC;AAED,YAAM,OAAO,MAAM,SAAS,OAAO;AAAA,QACjC;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,SAAS;AAAA,UACT,SAAS;AAAA,QACX;AAAA,MACF,CAAC;AACD,kBAAY,KAAK;AAAA,IACnB;AAAA,EACF;AAEA,QAAM,SAAS,MAAM,SAAS,OAAO;AAAA,IACnC;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,+CAA0C,OAAO,OAAO;AAAA,QAChE,EAAE,MAAM,yDAAoD,OAAO,OAAO;AAAA,QAC1E,EAAE,MAAM,oDAA+C,OAAO,UAAU;AAAA,MAC1E;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,QAC/B,EAAE,MAAM,WAAW,OAAO,KAAK;AAAA,MACjC;AAAA,IACF;AAAA,IACA;AAAA,MACE,MAAM;AAAA,MACN,MAAM;AAAA,MACN,SAAS;AAAA,MACT,SAAS;AAAA,QACP,EAAE,MAAM,uCAAuC,OAAO,WAAW;AAAA,QACjE,EAAE,MAAM,wBAAwB,OAAO,eAAe;AAAA,MACxD;AAAA,IACF;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL,aAAa,KAAK;AAAA,IAClB,oBAAoB,KAAK;AAAA,IACzB,OAAO,KAAK;AAAA,IACZ,WAAW,gBAAgB;AAAA,IAC3B,eAAe,KAAK;AAAA,IACpB,aAAa,KAAK;AAAA,IAClB,QAAQ,KAAK;AAAA,IACb,SAAS,KAAK;AAAA,IACd;AAAA,IACA;AAAA,IACA,aAAa,OAAO;AAAA,IACpB,UAAU,OAAO;AAAA,IACjB,aAAa,OAAO;AAAA,IACpB,OAAO,MAAM;AAAA,IACb;AAAA,EACF;AACF;AAEO,SAAS,kBAAkB,WAAmC;AACnE,SAAO;AAAA,IACL,aAAa,UAAU,MAAM,GAAG,EAAE,IAAI,KAAK;AAAA,IAC3C,oBAAoB;AAAA,IACpB,OAAO;AAAA,IACP,WAAW;AAAA,IACX,eAAe;AAAA,IACf,aAAa;AAAA,IACb,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,MAAM,CAAC,EAAE,MAAM,aAAa,MAAM,aAAa,OAAO,GAAG,CAAC;AAAA,IAC1D,YAAY,CAAC;AAAA,IACb,aAAa;AAAA,IACb,UAAU;AAAA,IACV,aAAa;AAAA,IACb,OAAO,MAAM;AAAA,IACb;AAAA,EACF;AACF;;;AC9PA,OAAOA,WAAU;;;ACAjB,OAAO,SAAS;AAChB,OAAOC,WAAU;AACjB,SAAS,qBAAqB;;;ACF9B,OAAO,QAAQ;AACf,OAAO,UAAU;AAEjB,eAAsB,UAAU,SAAgC;AAC9D,QAAM,GAAG,UAAU,OAAO;AAC5B;AAEA,eAAsB,cACpB,UACA,SACA,YAAqB,OAC2B;AAChD,QAAM,MAAM,KAAK,QAAQ,QAAQ;AACjC,QAAM,GAAG,UAAU,GAAG;AAEtB,MAAI,MAAM,GAAG,WAAW,QAAQ,GAAG;AACjC,QAAI,CAAC,WAAW;AACd,aAAO;AAAA,IACT;AACA,UAAM,GAAG,UAAU,UAAU,SAAS,OAAO;AAC7C,WAAO;AAAA,EACT;AAEA,QAAM,GAAG,UAAU,UAAU,SAAS,OAAO;AAC7C,SAAO;AACT;AAEA,eAAsB,WAAW,UAAoC;AACnE,SAAO,GAAG,WAAW,QAAQ;AAC/B;AAEA,eAAsB,SAAS,UAAmC;AAChE,SAAO,GAAG,SAAS,UAAU,OAAO;AACtC;AAEA,eAAsB,eAAe,UAAiC;AACpE,QAAM,GAAG,MAAM,UAAU,GAAK;AAChC;;;AD1BA,OAAOC,SAAQ;AANf,IAAM,aAAa,cAAc,YAAY,GAAG;AAChD,IAAM,YAAYC,MAAK,QAAQ,UAAU;AAMzC,IAAM,WAAWA,MAAK,QAAQ,WAAW,cAAc;AACvD,IAAM,UAAUA,MAAK,QAAQ,WAAW,iBAAiB;AACzD,IAAM,gBAAgBD,IAAG,WAAW,QAAQ,IAAI,WAAW;AAM3D,eAAsB,eACpB,cACA,MACiB;AACjB,QAAM,WAAWE,MAAK,KAAK,eAAe,YAAY;AACtD,QAAM,WAAW,MAAM,SAAS,QAAQ;AACxC,SAAO,IAAI,OAAO,UAAU,MAAM;AAAA,IAChC,UAAU;AAAA,IACV,OAAO;AAAA,EACT,CAAC;AACH;;;ADzBA,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAsB,mBACpB,KACA,WAC0B;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,eAAe;AAAA,EACjB;AAEA,aAAW,QAAQ,cAAc;AAC/B,QAAI;AACF,YAAM,UAAU,MAAM,eAAe,UAAU,IAAI,QAAQ,YAAY;AACvE,YAAM,aAAaC,MAAK,KAAK,IAAI,WAAW,oBAAoB,IAAI;AACpE,YAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,UAAI,WAAW,WAAW;AACxB,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC,OAAO;AACL,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK,UAAU,IAAI,KAAK,GAAG,EAAE;AAAA,IAC7C;AAAA,EACF;AAEA,SAAO;AACT;;;AGjDA,OAAOC,WAAU;AAOjB,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,kBAAkB;AAAA,EACtB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,uBAAuB;AAAA,EAC3B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAIA,IAAM,iBAAiB;AAAA,EACrB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,cAAc,CAAC,GAAG,eAAe;AAEvC,IAAM,cAAc;AAAA,EAClB,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AAAA,EACH,GAAG;AACL;AAIA,IAAM,eAAuC,CAAC;AAE9C,WAAW,QAAQ,iBAAiB;AAClC,eAAa,IAAI,IAAI;AACvB;AACA,WAAW,QAAQ,iBAAiB;AAClC,eAAa,IAAI,IAAI;AACvB;AACA,WAAW,QAAQ,iBAAiB;AAClC,eAAa,IAAI,IAAI;AACvB;AACA,WAAW,QAAQ,sBAAsB;AACvC,eAAa,IAAI,IAAI;AACvB;AAMO,SAAS,iBAAiB,MAAsB;AACrD,SAAO,aAAa,IAAI,KAAK;AAC/B;AAKO,SAAS,aAAa,QAA2D;AACtF,MAAI;AAEJ,UAAQ,QAAQ;AAAA,IACd,KAAK;AACH,cAAQ;AACR;AAAA,IACF,KAAK;AACH,cAAQ;AACR;AAAA,IACF,KAAK;AAAA,IACL;AACE,cAAQ;AACR;AAAA,EACJ;AAEA,SAAO,MAAM,IAAI,CAAC,UAAU;AAAA,IAC1B;AAAA,IACA,UAAU,iBAAiB,IAAI;AAAA,EACjC,EAAE;AACJ;AAEA,eAAsB,eACpB,KACA,WAC0B;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,SAAS,aAAa,IAAI,WAAW;AAC3C,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,eAAe;AAAA,EACjB;AAEA,aAAW,SAAS,QAAQ;AAC1B,QAAI;AACF,YAAM,UAAU,MAAM;AAAA,QACpB,UAAU,MAAM,QAAQ,IAAI,MAAM,IAAI;AAAA,QACtC;AAAA,MACF;AAEA,YAAM,aAAaC,MAAK,KAAK,IAAI,WAAW,kBAAkB,GAAG,MAAM,IAAI,KAAK;AAChF,YAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,UAAI,WAAW,WAAW;AACxB,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC,OAAO;AACL,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK,SAAS,MAAM,IAAI,KAAK,GAAG,EAAE;AAAA,IAClD;AAAA,EACF;AAEA,SAAO;AACT;;;ACjJA,OAAOC,WAAU;AAKjB,IAAM,cAAc;AAAA,EAClB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,IAAM,eAAe;AAAA,EACnB;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,SAAS,aAAa,QAAsD;AAC1E,QAAM,SAA0C,CAAC;AAEjD,aAAW,QAAQ,aAAa;AAC9B,WAAO,KAAK,EAAE,MAAM,KAAK,OAAO,CAAC;AAAA,EACnC;AAEA,MAAI,WAAW,QAAQ;AACrB,eAAW,QAAQ,cAAc;AAC/B,aAAO,KAAK,EAAE,MAAM,KAAK,QAAQ,CAAC;AAAA,IACpC;AAAA,EACF;AAEA,SAAO;AACT;AAEA,eAAsB,eACpB,KACA,WAC0B;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,eAAe;AAAA,EACjB;AAEA,QAAM,SAAS,aAAa,IAAI,WAAW;AAE3C,aAAW,SAAS,QAAQ;AAC1B,QAAI;AACF,YAAM,UAAU,MAAM;AAAA,QACpB,UAAU,MAAM,GAAG,IAAI,MAAM,IAAI;AAAA,QACjC;AAAA,MACF;AACA,YAAM,aAAaC,MAAK,KAAK,IAAI,WAAW,kBAAkB,MAAM,IAAI,IAAI,UAAU;AACtF,YAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,UAAI,WAAW,WAAW;AACxB,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC,OAAO;AACL,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK,SAAS,MAAM,IAAI,KAAK,GAAG,EAAE;AAAA,IAClD;AAAA,EACF;AAEA,SAAO;AACT;;;ACrFA,OAAOC,WAAU;AAKjB,IAAM,QAAQ;AAAA,EACZ;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAEA,eAAsB,cACpB,KACA,WAC0B;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,eAAe;AAAA,EACjB;AAEA,aAAW,QAAQ,OAAO;AACxB,QAAI;AACF,YAAM,UAAU,MAAM,eAAe,SAAS,IAAI,WAAW,YAAY;AACzE,YAAM,aAAaC,MAAK,KAAK,IAAI,WAAW,iBAAiB,GAAG,IAAI,KAAK;AACzE,YAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,UAAI,WAAW,WAAW;AACxB,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC,OAAO;AACL,eAAO,aAAa,KAAK,UAAU;AAAA,MACrC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK,QAAQ,IAAI,KAAK,GAAG,EAAE;AAAA,IAC3C;AAAA,EACF;AAEA,SAAO;AACT;;;AChDA,OAAOC,WAAU;AAKjB,eAAsB,iBACpB,KACA,WAC0B;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,eAAe;AAAA,EACjB;AAGA,MAAI;AACF,UAAM,UAAU,MAAM,eAAe,sBAAsB,YAAY;AACvE,UAAM,aAAaC,MAAK,KAAK,IAAI,WAAW,mBAAmB;AAC/D,UAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,QAAI,WAAW,WAAW;AACxB,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC,OAAO;AACL,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,OAAO,KAAK,cAAc,GAAG,EAAE;AAAA,EACxC;AAGA,MAAI;AACF,UAAM,UAAU,MAAM,eAAe,0BAA0B,YAAY;AAC3E,UAAM,aAAaA,MAAK,KAAK,IAAI,WAAW,uBAAuB;AACnE,UAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,QAAI,WAAW,WAAW;AACxB,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC,OAAO;AACL,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,OAAO,KAAK,kBAAkB,GAAG,EAAE;AAAA,EAC5C;AAEA,SAAO;AACT;;;ACnDA,OAAOC,WAAU;AAKjB,eAAsB,cACpB,KACA,WAC0B;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,eAAe;AAAA,EACjB;AAGA,MAAI;AACF,UAAM,UAAU,MAAM,eAAe,wBAAwB,YAAY;AACzE,UAAM,aAAaC,MAAK,KAAK,IAAI,WAAW,4BAA4B;AACxE,UAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,QAAI,WAAW,WAAW;AACxB,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC,OAAO;AACL,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,OAAO,KAAK,eAAe,GAAG,EAAE;AAAA,EACzC;AAGA,QAAM,OAAO;AAAA,IACX;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,OAAO,MAAM;AACtB,QAAI;AACF,YAAM,UAAUA,MAAK,KAAK,IAAI,WAAW,GAAG;AAC5C,YAAM,UAAU,OAAO;AACvB,YAAM,cAAcA,MAAK,KAAK,SAAS,UAAU;AACjD,YAAM,SAAS,MAAM,cAAc,aAAa,IAAI,SAAS;AAE7D,UAAI,WAAW,WAAW;AACxB,eAAO,aAAa,KAAK,WAAW;AAAA,MACtC,OAAO;AACL,eAAO,aAAa,KAAK,WAAW;AAAA,MACtC;AAAA,IACF,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK,OAAO,GAAG,KAAK,GAAG,EAAE;AAAA,IACzC;AAAA,EACF;AAGA,MAAI;AACF,UAAM,WAAW;AAAA,MACf,SAAS;AAAA,MACT,WAAW,IAAI;AAAA,MACf,aAAa,IAAI;AAAA,MACjB,aAAa,IAAI;AAAA,MACjB,UAAU,IAAI;AAAA,MACd,eAAe,iBAAiB,GAAG;AAAA,IACrC;AACA,UAAM,aAAaA,MAAK,KAAK,IAAI,WAAW,oBAAoB;AAChE,UAAM,SAAS,MAAM;AAAA,MACnB;AAAA,MACA,KAAK,UAAU,UAAU,MAAM,CAAC,IAAI;AAAA,MACpC;AAAA,IACF;AAEA,QAAI,WAAW,WAAW;AACxB,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC,OAAO;AACL,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,OAAO,KAAK,uBAAuB,GAAG,EAAE;AAAA,EACjD;AAEA,SAAO;AACT;AAEA,SAAS,iBAAiB,KAA+B;AACvD,QAAM,QAAQ;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,KAAK,+BAA+B;AAG1C,QAAM;AAAA,IACJ;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAGA,QAAM,aAAa;AAAA,IACjB;AAAA,IAAiB;AAAA,IAAe;AAAA,IAChC;AAAA,IAAiB;AAAA,IAAU;AAAA,IAAQ;AAAA,IACnC;AAAA,IAAQ;AAAA,IAAQ;AAAA,EAClB;AACA,QAAM,cAAc;AAAA,IAClB;AAAA,IAAa;AAAA,IAAc;AAAA,IAAgB;AAAA,IAAa;AAAA,IACxD;AAAA,IAAa;AAAA,IAAW;AAAA,IAAY;AAAA,IAAQ;AAAA,IAAY;AAAA,EAC1D;AACA,QAAM,SAAS,IAAI,gBAAgB,SAC/B,CAAC,GAAG,YAAY,GAAG,WAAW,IAC9B;AACJ,aAAW,SAAS,QAAQ;AAC1B,UAAM,KAAK,kBAAkB,KAAK,WAAW;AAAA,EAC/C;AAGA,QAAM,iBAAiB;AAAA,IACrB;AAAA,IAAW;AAAA,IAAa;AAAA,IAAW;AAAA,IACnC;AAAA,IAAU;AAAA,IAAa;AAAA,IAAY;AAAA,EACrC;AACA,QAAM,iBAAiB,CAAC,cAAc,aAAa,eAAe,YAAY;AAC9E,QAAM,iBAAiB,CAAC,WAAW,YAAY,YAAY,YAAY;AACvE,QAAM,sBAAsB,CAAC,aAAa,UAAU,cAAc,UAAU;AAE5E,QAAM,gBAAgB,CAAC,WAAW,aAAa,UAAU,YAAY,WAAW;AAEhF,QAAM,aAAa,CAAC,GAAG,cAAc;AACrC,QAAM,aAAa;AAAA,IACjB,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,IACH,GAAG;AAAA,EACL;AAEA,QAAM,SAAS,IAAI,gBAAgB,YAC/B,gBACA,IAAI,gBAAgB,SACpB,aACA;AAEJ,aAAW,SAAS,QAAQ;AAC1B,UAAM,KAAK,kBAAkB,KAAK,KAAK;AAAA,EACzC;AAEA,SAAO;AACT;;;ACxKA,OAAOC,WAAU;AAKjB,eAAsB,cACpB,KACA,WAC0B;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,eAAe;AAAA,IACnB,GAAG;AAAA,IACH,eAAe;AAAA,EACjB;AAEA,MAAI;AACF,UAAM,UAAU,MAAM,eAAe,6BAA6B,YAAY;AAC9E,UAAM,aAAaC,MAAK,KAAK,IAAI,WAAW,+BAA+B;AAC3E,UAAM,SAAS,MAAM,cAAc,YAAY,SAAS,SAAS;AAEjE,QAAI,WAAW,WAAW;AACxB,aAAO,aAAa,KAAK,UAAU;AAAA,IACrC,OAAO;AACL,aAAO,aAAa,KAAK,UAAU;AACnC,YAAM,eAAe,UAAU;AAAA,IACjC;AAAA,EACF,SAAS,KAAK;AACZ,WAAO,OAAO,KAAK,yBAAyB,GAAG,EAAE;AAAA,EACnD;AAEA,SAAO;AACT;;;AC3BA,eAAsB,YACpB,KACA,YAAqB,OACK;AAC1B,QAAM,SAA0B;AAAA,IAC9B,cAAc,CAAC;AAAA,IACf,cAAc,CAAC;AAAA,IACf,QAAQ,CAAC;AAAA,EACX;AAEA,QAAM,aAAa;AAAA,IACjB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF;AAEA,aAAW,aAAa,YAAY;AAClC,QAAI;AACF,YAAM,UAAU,MAAM,UAAU,KAAK,SAAS;AAC9C,aAAO,aAAa,KAAK,GAAG,QAAQ,YAAY;AAChD,aAAO,aAAa,KAAK,GAAG,QAAQ,YAAY;AAChD,aAAO,OAAO,KAAK,GAAG,QAAQ,MAAM;AAAA,IACtC,SAAS,KAAK;AACZ,aAAO,OAAO,KAAK,oBAAoB,GAAG,EAAE;AAAA,IAC9C;AAAA,EACF;AAEA,SAAO;AACT;;;AX/BA,eAAsB,YAAY,SAAqC;AACrE,QAAM,YAAY,QAAQ,IAAI;AAE9B,UAAQ,IAAI;AACZ,UAAQ,IAAI,MAAM,KAAK,sBAAsB,CAAC;AAC9C,UAAQ,IAAI,MAAM,IAAI,mDAAmD,CAAC;AAC1E,UAAQ,IAAI;AAEZ,MAAI;AACJ,MAAI,QAAQ,KAAK;AACf,UAAM,kBAAkB,SAAS;AACjC,YAAQ,IAAI,MAAM,IAAI,uCAAuC,CAAC;AAC9D,YAAQ,IAAI;AAAA,EACd,OAAO;AACL,UAAM,MAAM,mBAAmB,SAAS;AACxC,YAAQ,IAAI;AAAA,EACd;AAEA,QAAM,UAAU,IAAI,+BAA+B,EAAE,MAAM;AAE3D,MAAI;AACF,UAAM,SAAS,MAAM,YAAY,KAAK,QAAQ,aAAa,KAAK;AAEhE,YAAQ;AAAA,MACN,MAAM,MAAM,GAAG,OAAO,aAAa,MAAM,gBAAgB;AAAA,IAC3D;AAEA,QAAI,OAAO,aAAa,SAAS,GAAG;AAClC,cAAQ;AAAA,QACN,MAAM,OAAO,KAAK,OAAO,aAAa,MAAM,gCAAgC;AAAA,MAC9E;AAAA,IACF;AAEA,QAAI,OAAO,OAAO,SAAS,GAAG;AAC5B,cAAQ,IAAI,MAAM,IAAI,KAAK,OAAO,OAAO,MAAM,UAAU,CAAC;AAC1D,iBAAW,OAAO,OAAO,QAAQ;AAC/B,gBAAQ,IAAI,MAAM,IAAI,SAAS,GAAG,EAAE,CAAC;AAAA,MACvC;AAAA,IACF;AAEA,YAAQ,IAAI;AACZ,YAAQ,IAAI,MAAM,KAAK,eAAe,CAAC;AACvC,YAAQ,IAAI,MAAM,IAAI,yCAAyC,CAAC;AAChE,YAAQ,IAAI,MAAM,IAAI,qDAAgD,CAAC;AACvE,YAAQ,IAAI,MAAM,IAAI,6DAAwD,CAAC;AAC/E,YAAQ,IAAI;AAAA,EACd,SAAS,KAAK;AACZ,YAAQ,KAAK,MAAM,IAAI,oCAAoC,CAAC;AAC5D,YAAQ,MAAM,GAAG;AACjB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AY7DA,OAAOC,YAAU;AACjB,OAAOC,YAAW;AAIlB,eAAsB,gBAA+B;AACnD,QAAM,YAAY,QAAQ,IAAI;AAE9B,UAAQ,IAAI;AACZ,UAAQ,IAAIC,OAAM,KAAK,sBAAsB,CAAC;AAC9C,UAAQ,IAAIA,OAAM,IAAI,2CAA2C,CAAC;AAClE,UAAQ,IAAI;AAGZ,QAAM,eAAeC,OAAK,KAAK,WAAW,oBAAoB;AAC9D,QAAM,iBAAiB,MAAM,WAAW,YAAY;AAEpD,MAAI,CAAC,gBAAgB;AACnB,YAAQ,IAAID,OAAM,IAAI,gCAAgC,CAAC;AACvD,YAAQ,IAAIA,OAAM,IAAI,2DAA2D,CAAC;AAClF,YAAQ,IAAI;AACZ,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,cAAc,MAAM,SAAS,YAAY;AAC/C,MAAI;AAEJ,MAAI;AACF,eAAW,KAAK,MAAM,WAAW;AAAA,EACnC,QAAQ;AACN,YAAQ,IAAIA,OAAM,IAAI,mCAAmC,CAAC;AAC1D,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,UAAQ,IAAIA,OAAM,IAAI,cAAc,SAAS,WAAW,EAAE,CAAC;AAC3D,UAAQ,IAAIA,OAAM,IAAI,cAAc,SAAS,OAAO,EAAE,CAAC;AACvD,UAAQ,IAAI;AAEZ,QAAM,SAAwB,CAAC;AAC/B,MAAI,UAAU;AACd,MAAI,YAAY;AAEhB,aAAW,QAAQ,SAAS,eAAe;AACzC,UAAM,WAAWC,OAAK,KAAK,WAAW,IAAI;AAC1C,UAAM,SAAS,MAAM,WAAW,QAAQ;AAExC,UAAM,QAAqB;AAAA,MACzB,MAAM;AAAA,MACN,MAAM;AAAA,MACN;AAAA,MACA,IAAI;AAAA,IACN;AAEA,QAAI,QAAQ;AAEV,UAAI;AACF,cAAM,UAAU,MAAM,SAAS,QAAQ;AACvC,YAAI,QAAQ,KAAK,EAAE,WAAW,GAAG;AAC/B,gBAAM,KAAK;AACX,gBAAM,UAAU;AAAA,QAClB;AAAA,MACF,QAAQ;AACN,cAAM,KAAK;AACX,cAAM,UAAU;AAAA,MAClB;AAAA,IACF,OAAO;AACL,YAAM,UAAU;AAAA,IAClB;AAEA,WAAO,KAAK,KAAK;AACjB,QAAI,MAAM,GAAI;AAAA,QACT;AAAA,EACP;AAGA,QAAM,aAA4C,CAAC;AACnD,aAAW,SAAS,QAAQ;AAC1B,UAAM,WAAW,MAAM,KAAK,WAAW,gBAAgB,IACnD,WACA,MAAM,KAAK,WAAW,gBAAgB,IACtC,WACA,MAAM,KAAK,WAAW,eAAe,IACrC,UACA,MAAM,KAAK,WAAW,UAAU,IAChC,kBACA,MAAM,KAAK,WAAW,kBAAkB,IACxC,gBACA,MAAM,KAAK,WAAW,YAAY,IAClC,mBACA;AAEJ,QAAI,CAAC,WAAW,QAAQ,EAAG,YAAW,QAAQ,IAAI,CAAC;AACnD,eAAW,QAAQ,EAAE,KAAK,KAAK;AAAA,EACjC;AAEA,aAAW,CAAC,UAAU,KAAK,KAAK,OAAO,QAAQ,UAAU,GAAG;AAC1D,UAAM,QAAQ,MAAM,MAAM,OAAK,EAAE,EAAE;AACnC,UAAM,OAAO,QAAQD,OAAM,MAAM,IAAI,IAAIA,OAAM,IAAI,IAAI;AACvD,YAAQ,IAAI,KAAK,IAAI,IAAIA,OAAM,KAAK,QAAQ,CAAC,EAAE;AAE/C,eAAW,QAAQ,OAAO;AACxB,UAAI,KAAK,IAAI;AACX,gBAAQ,IAAIA,OAAM,MAAM,UAAU,KAAK,IAAI,EAAE,CAAC;AAAA,MAChD,OAAO;AACL,gBAAQ,IAAIA,OAAM,IAAI,UAAU,KAAK,IAAI,KAAK,KAAK,OAAO,GAAG,CAAC;AAAA,MAChE;AAAA,IACF;AACA,YAAQ,IAAI;AAAA,EACd;AAGA,UAAQ,IAAIA,OAAM,KAAK,WAAW,CAAC;AACnC,UAAQ,IAAIA,OAAM,MAAM,WAAW,OAAO,EAAE,CAAC;AAC7C,MAAI,YAAY,GAAG;AACjB,YAAQ,IAAIA,OAAM,IAAI,uBAAuB,SAAS,EAAE,CAAC;AACzD,YAAQ,IAAI;AACZ,YAAQ,IAAIA,OAAM,IAAI,mEAAmE,CAAC;AAAA,EAC5F,OAAO;AACL,YAAQ,IAAIA,OAAM,MAAM,wBAAwB,CAAC;AAAA,EACnD;AACA,UAAQ,IAAI;AAEZ,MAAI,YAAY,GAAG;AACjB,YAAQ,KAAK,CAAC;AAAA,EAChB;AACF;;;AbzHA,IAAM,UAAU,IAAI,QAAQ;AAE5B,QACG,KAAK,aAAa,EAClB,YAAY,iDAAiD,EAC7D,QAAQ,OAAO;AAElB,QACG,QAAQ,MAAM,EACd,YAAY,wEAAwE,EACpF,OAAO,aAAa,+BAA+B,EACnD,OAAO,eAAe,0BAA0B,EAChD,OAAO,WAAW;AAErB,QACG,QAAQ,QAAQ,EAChB,YAAY,4CAA4C,EACxD,OAAO,aAAa;AAEvB,QAAQ,MAAM;","names":["path","path","fs","path","path","path","path","path","path","path","path","path","path","path","path","path","path","path","path","chalk","chalk","path"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/commands/init.ts","../src/prompts/project-setup.ts","../src/generators/memory-bank.ts","../src/utils/template.ts","../src/utils/fs.ts","../src/generators/agents.ts","../src/generators/skills.ts","../src/generators/rules.ts","../src/generators/claude-md.ts","../src/generators/infra.ts","../src/generators/hooks.ts","../src/generators/index.ts","../src/commands/doctor.ts","../src/commands/update.ts"],"sourcesContent":["import { Command } from 'commander';\nimport { initCommand } from './commands/init.js';\nimport { doctorCommand } from './commands/doctor.js';\nimport { updateCommand } from './commands/update.js';\n\nconst program = new Command();\n\nprogram\n .name('agent-forge')\n .description('AI-driven Development Framework for Claude Code')\n .version('3.0.0');\n\nprogram\n .command('init')\n .description('Initialize AI-driven development infrastructure in the current project')\n .option('-y, --yes', 'Skip prompts and use defaults')\n .option('--overwrite', 'Overwrite existing files')\n .action(initCommand);\n\nprogram\n .command('doctor')\n .description('Check integrity of the generated structure')\n .action(doctorCommand);\n\nprogram\n .command('update')\n .description('Update framework files to the latest version (preserves user data)')\n .action(updateCommand);\n\nprogram.parse();\n","import chalk from 'chalk';\nimport ora from 'ora';\nimport { promptProjectSetup, getDefaultContext } from '../prompts/project-setup.js';\nimport { generateAll } from '../generators/index.js';\n\ninterface InitOptions {\n yes?: boolean;\n overwrite?: boolean;\n}\n\nexport async function initCommand(options: InitOptions): Promise<void> {\n const targetDir = process.cwd();\n\n console.log();\n console.log(chalk.bold(' agent-forge v3.0.0'));\n console.log(chalk.dim(' AI-driven Development Framework for Claude Code'));\n console.log();\n\n let ctx;\n if (options.yes) {\n ctx = getDefaultContext(targetDir);\n console.log(chalk.dim(' Using default configuration (--yes)'));\n console.log();\n } else {\n ctx = await promptProjectSetup(targetDir);\n console.log();\n }\n\n const spinner = ora('Creating project structure...').start();\n\n try {\n const result = await generateAll(ctx, options.overwrite ?? false);\n\n spinner.succeed(\n chalk.green(`${result.filesCreated.length} files created`)\n );\n\n if (result.filesSkipped.length > 0) {\n console.log(\n chalk.yellow(` ${result.filesSkipped.length} files skipped (already exist)`)\n );\n }\n\n if (result.errors.length > 0) {\n console.log(chalk.red(` ${result.errors.length} errors:`));\n for (const err of result.errors) {\n console.log(chalk.red(` - ${err}`));\n }\n }\n\n console.log();\n console.log(chalk.bold(' Next steps:'));\n console.log(chalk.dim(' 1. Open Claude Code in this directory'));\n console.log(chalk.dim(' 2. /start-session — begin your first session'));\n console.log(chalk.dim(' 3. /plan init — create tasks from your documentation'));\n console.log();\n } catch (err) {\n spinner.fail(chalk.red('Failed to create project structure'));\n console.error(err);\n process.exit(1);\n }\n}\n","import inquirer from 'inquirer';\nimport type { ProjectContext, TeamMember, Milestone, AgentPreset, Language, CommitStyle } from '../types.js';\n\nfunction today(): string {\n return new Date().toISOString().split('T')[0];\n}\n\nconst STACK_CHOICES = [\n { name: 'Python', value: 'python' },\n { name: 'TypeScript / Node.js', value: 'typescript' },\n { name: 'Go', value: 'go' },\n { name: 'Rust', value: 'rust' },\n { name: 'Other', value: 'other' },\n];\n\nconst FRAMEWORK_MAP: Record<string, string[]> = {\n python: ['FastAPI', 'Django', 'Flask', 'None'],\n typescript: ['Next.js', 'Express', 'Fastify', 'None'],\n go: ['Gin', 'Echo', 'Chi', 'None'],\n rust: ['Actix', 'Axum', 'Rocket', 'None'],\n other: ['None'],\n};\n\nconst TEST_MAP: Record<string, { framework: string; command: string }> = {\n python: { framework: 'pytest', command: 'pytest' },\n typescript: { framework: 'vitest', command: 'npx vitest run' },\n go: { framework: 'go test', command: 'go test ./...' },\n rust: { framework: 'cargo test', command: 'cargo test' },\n other: { framework: 'custom', command: 'echo \"no tests configured\"' },\n};\n\nexport async function promptProjectSetup(targetDir: string): Promise<ProjectContext> {\n const base = await inquirer.prompt([\n {\n type: 'input',\n name: 'projectName',\n message: 'Project name:',\n default: targetDir.split('/').pop(),\n },\n {\n type: 'input',\n name: 'projectDescription',\n message: 'Project description:',\n default: 'AI-driven project',\n },\n {\n type: 'list',\n name: 'stack',\n message: 'Technology stack:',\n choices: STACK_CHOICES,\n },\n ]);\n\n const frameworks = FRAMEWORK_MAP[base.stack] || ['None'];\n const frameworkAnswer = await inquirer.prompt([\n {\n type: 'list',\n name: 'framework',\n message: 'Framework:',\n choices: frameworks,\n },\n ]);\n\n const testDefaults = TEST_MAP[base.stack] || TEST_MAP.other;\n const dirs = await inquirer.prompt([\n {\n type: 'input',\n name: 'testFramework',\n message: 'Test framework:',\n default: testDefaults.framework,\n },\n {\n type: 'input',\n name: 'testCommand',\n message: 'Test command:',\n default: testDefaults.command,\n },\n {\n type: 'input',\n name: 'srcDir',\n message: 'Source directory:',\n default: 'src/',\n },\n {\n type: 'input',\n name: 'testDir',\n message: 'Test directory:',\n default: base.stack === 'python' ? 'src/tests/' : 'tests/',\n },\n ]);\n\n // Team members\n const team: TeamMember[] = [];\n let addMore = true;\n let first = true;\n while (addMore) {\n const member = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: first ? 'Team member name:' : 'Next team member name (leave empty to stop):',\n default: first ? undefined : '',\n },\n ]);\n\n if (!member.name) break;\n\n const details = await inquirer.prompt([\n {\n type: 'input',\n name: 'role',\n message: `${member.name}'s role:`,\n default: 'developer',\n },\n {\n type: 'input',\n name: 'email',\n message: `${member.name}'s email:`,\n },\n ]);\n\n team.push({ name: member.name, role: details.role, email: details.email });\n first = false;\n\n if (team.length >= 10) break;\n const cont = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: 'Add another team member?',\n default: false,\n },\n ]);\n addMore = cont.addMore;\n }\n\n // Milestones\n const milestones: Milestone[] = [];\n const addMilestones = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'add',\n message: 'Add milestones?',\n default: false,\n },\n ]);\n\n if (addMilestones.add) {\n let addMoreMs = true;\n while (addMoreMs) {\n const ms = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Milestone name:',\n },\n {\n type: 'input',\n name: 'deadline',\n message: 'Deadline (YYYY-MM-DD):',\n },\n {\n type: 'input',\n name: 'description',\n message: 'Description (optional):',\n default: '',\n },\n ]);\n milestones.push({\n name: ms.name,\n deadline: ms.deadline,\n description: ms.description || undefined,\n });\n\n const cont = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'addMore',\n message: 'Add another milestone?',\n default: false,\n },\n ]);\n addMoreMs = cont.addMore;\n }\n }\n\n const config = await inquirer.prompt([\n {\n type: 'list',\n name: 'agentPreset',\n message: 'Agent preset:',\n choices: [\n { name: 'Core (8 agents — development pipeline)', value: 'core' },\n { name: 'Full (20 agents — all categories + extra skills)', value: 'full' },\n { name: 'Minimal (5 agents — essentials + inspector)', value: 'minimal' },\n ],\n },\n {\n type: 'list',\n name: 'language',\n message: 'Instructions language:',\n choices: [\n { name: 'Russian', value: 'ru' },\n { name: 'English', value: 'en' },\n ],\n },\n {\n type: 'list',\n name: 'commitStyle',\n message: 'Commit style:',\n choices: [\n { name: 'Standard (type(scope): description)', value: 'standard' },\n { name: 'Conventional Commits', value: 'conventional' },\n ],\n },\n ]);\n\n return {\n projectName: base.projectName,\n projectDescription: base.projectDescription,\n stack: base.stack,\n framework: frameworkAnswer.framework,\n testFramework: dirs.testFramework,\n testCommand: dirs.testCommand,\n srcDir: dirs.srcDir,\n testDir: dirs.testDir,\n team,\n milestones,\n agentPreset: config.agentPreset as AgentPreset,\n language: config.language as Language,\n commitStyle: config.commitStyle as CommitStyle,\n today: today(),\n targetDir,\n };\n}\n\nexport function getDefaultContext(targetDir: string): ProjectContext {\n return {\n projectName: targetDir.split('/').pop() || 'my-project',\n projectDescription: 'AI-driven project',\n stack: 'typescript',\n framework: 'None',\n testFramework: 'vitest',\n testCommand: 'npx vitest run',\n srcDir: 'src/',\n testDir: 'tests/',\n team: [{ name: 'Developer', role: 'developer', email: '' }],\n milestones: [],\n agentPreset: 'core',\n language: 'en',\n commitStyle: 'standard',\n today: today(),\n targetDir,\n };\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nconst MEMORY_FILES = [\n 'active-context.md',\n 'progress.md',\n 'project-brief.md',\n 'decisions.md',\n 'tech-stack.md',\n 'tech-debt.md',\n 'patterns.md',\n 'troubleshooting.md',\n 'checkpoint.yml',\n];\n\nexport async function generateMemoryBank(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n for (const file of MEMORY_FILES) {\n try {\n const content = await renderTemplate(`memory/${file}.ejs`, templateData);\n const outputPath = path.join(ctx.targetDir, 'dev-infra/memory', file);\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Memory ${file}: ${err}`);\n }\n }\n\n return result;\n}\n","import ejs from 'ejs';\nimport path from 'path';\nimport { fileURLToPath } from 'url';\nimport { readFile } from './fs.js';\n\nconst __filename = fileURLToPath(import.meta.url);\nconst __dirname = path.dirname(__filename);\n\n// In dev: src/utils/template.ts -> ../../templates\n// In dist: dist/index.mjs -> ../templates\n// We try ../templates first (dist), then ../../templates (dev/test)\nimport fs from 'fs';\nconst distPath = path.resolve(__dirname, '../templates');\nconst devPath = path.resolve(__dirname, '../../templates');\nconst TEMPLATES_DIR = fs.existsSync(distPath) ? distPath : devPath;\n\nexport function getTemplatesDir(): string {\n return TEMPLATES_DIR;\n}\n\nexport async function renderTemplate(\n templatePath: string,\n data: Record<string, unknown>\n): Promise<string> {\n const fullPath = path.join(TEMPLATES_DIR, templatePath);\n const template = await readFile(fullPath);\n return ejs.render(template, data, {\n filename: fullPath,\n async: false,\n });\n}\n\nexport function renderString(\n template: string,\n data: Record<string, unknown>\n): string {\n return ejs.render(template, data);\n}\n","import fs from 'fs-extra';\nimport path from 'path';\n\nexport async function ensureDir(dirPath: string): Promise<void> {\n await fs.ensureDir(dirPath);\n}\n\nexport async function writeFileSafe(\n filePath: string,\n content: string,\n overwrite: boolean = false\n): Promise<'created' | 'skipped' | 'overwritten'> {\n const dir = path.dirname(filePath);\n await fs.ensureDir(dir);\n\n if (await fs.pathExists(filePath)) {\n if (!overwrite) {\n return 'skipped';\n }\n await fs.writeFile(filePath, content, 'utf-8');\n return 'overwritten';\n }\n\n await fs.writeFile(filePath, content, 'utf-8');\n return 'created';\n}\n\nexport async function fileExists(filePath: string): Promise<boolean> {\n return fs.pathExists(filePath);\n}\n\nexport async function readFile(filePath: string): Promise<string> {\n return fs.readFile(filePath, 'utf-8');\n}\n\nexport async function makeExecutable(filePath: string): Promise<void> {\n await fs.chmod(filePath, 0o755);\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult, AgentPreset } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\n// --- Agent categories ---\n\nconst PIPELINE_AGENTS = [\n 'analyst',\n 'architect',\n 'skeptic',\n 'developer',\n 'tester',\n 'inspector',\n 'reviewer',\n 'planner',\n];\n\nconst PLANNING_AGENTS = [\n 'researcher',\n 'validator',\n 'interviewer',\n 'decomposer',\n];\n\nconst SECURITY_AGENTS = [\n 'auditor',\n 'prompter',\n 'deployer',\n 'scaffolder',\n];\n\nconst DOCUMENTATION_AGENTS = [\n 'librarian',\n 'writer',\n 'gatekeeper',\n 'verifier',\n];\n\n// --- Presets ---\n\nconst MINIMAL_AGENTS = [\n 'analyst',\n 'developer',\n 'tester',\n 'reviewer',\n 'inspector',\n];\n\nconst CORE_AGENTS = [...PIPELINE_AGENTS];\n\nconst FULL_AGENTS = [\n ...PIPELINE_AGENTS,\n ...PLANNING_AGENTS,\n ...SECURITY_AGENTS,\n ...DOCUMENTATION_AGENTS,\n];\n\n// --- Helpers ---\n\nconst CATEGORY_MAP: Record<string, string> = {};\n\nfor (const name of PIPELINE_AGENTS) {\n CATEGORY_MAP[name] = 'pipeline';\n}\nfor (const name of PLANNING_AGENTS) {\n CATEGORY_MAP[name] = 'planning';\n}\nfor (const name of SECURITY_AGENTS) {\n CATEGORY_MAP[name] = 'security';\n}\nfor (const name of DOCUMENTATION_AGENTS) {\n CATEGORY_MAP[name] = 'documentation';\n}\n\n/**\n * Returns the template subdirectory for a given agent name.\n * Templates live at templates/agents/[category]/[name].md.ejs\n */\nexport function getAgentCategory(name: string): string {\n return CATEGORY_MAP[name] || 'pipeline';\n}\n\n/**\n * Returns the list of agents for the given preset.\n */\nexport function getAgentList(preset: AgentPreset): { name: string; category: string }[] {\n let names: string[];\n\n switch (preset) {\n case 'minimal':\n names = MINIMAL_AGENTS;\n break;\n case 'full':\n names = FULL_AGENTS;\n break;\n case 'core':\n default:\n names = CORE_AGENTS;\n break;\n }\n\n return names.map((name) => ({\n name,\n category: getAgentCategory(name),\n }));\n}\n\nexport async function generateAgents(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const agents = getAgentList(ctx.agentPreset);\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n for (const agent of agents) {\n try {\n const content = await renderTemplate(\n `agents/${agent.category}/${agent.name}.md.ejs`,\n templateData\n );\n // Output is always flat: .claude/agents/[name].md\n const outputPath = path.join(ctx.targetDir, '.claude/agents', `${agent.name}.md`);\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Agent ${agent.name}: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult, AgentPreset } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nconst CORE_SKILLS = [\n 'start-session',\n 'end-session',\n 'take-task',\n 'complete-task',\n 'status',\n 'plan',\n 'review',\n 'code',\n 'test',\n 'done',\n];\n\nconst EXTRA_SKILLS = [\n 'interview',\n 'audit-wave',\n 'write-report',\n 'dashboard',\n 'skill-master',\n 'decompose',\n 'feature',\n 'security',\n 'spec',\n 'techspec',\n 'prompts',\n];\n\nfunction getSkillList(preset: AgentPreset): { name: string; dir: string }[] {\n const skills: { name: string; dir: string }[] = [];\n\n for (const name of CORE_SKILLS) {\n skills.push({ name, dir: 'core' });\n }\n\n if (preset === 'full') {\n for (const name of EXTRA_SKILLS) {\n skills.push({ name, dir: 'extra' });\n }\n }\n\n return skills;\n}\n\nexport async function generateSkills(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n const skills = getSkillList(ctx.agentPreset);\n\n for (const skill of skills) {\n try {\n const content = await renderTemplate(\n `skills/${skill.dir}/${skill.name}/SKILL.md.ejs`,\n templateData\n );\n const outputPath = path.join(ctx.targetDir, `.claude/skills/${skill.name}`, 'SKILL.md');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Skill ${skill.name}: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nconst RULES = [\n 'commit-conventions',\n 'development-cycle',\n 'testing-standards',\n 'shared-resources',\n 'context-loading',\n 'agent-output-format',\n 'quality-gates',\n 'rollback-protocol',\n];\n\nexport async function generateRules(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n for (const rule of RULES) {\n try {\n const content = await renderTemplate(`rules/${rule}.md.ejs`, templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/rules', `${rule}.md`);\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`Rule ${rule}: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe } from '../utils/fs.js';\n\nexport async function generateClaudeMd(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n // CLAUDE.md\n try {\n const content = await renderTemplate('root/CLAUDE.md.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/CLAUDE.md');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`CLAUDE.md: ${err}`);\n }\n\n // settings.json\n try {\n const content = await renderTemplate('root/settings.json.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/settings.json');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`settings.json: ${err}`);\n }\n\n return result;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe, ensureDir } from '../utils/fs.js';\n\nexport async function generateInfra(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n // tasks.json\n try {\n const content = await renderTemplate('tasks/tasks.json.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, 'dev-infra/tasks/tasks.json');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`tasks.json: ${err}`);\n }\n\n // Create empty directories with .gitkeep\n const dirs = [\n 'dev-infra/sessions',\n 'dev-infra/tests/acceptance',\n 'dev-infra/tests/pmi',\n 'dev-infra/tests/results',\n ];\n\n for (const dir of dirs) {\n try {\n const dirPath = path.join(ctx.targetDir, dir);\n await ensureDir(dirPath);\n const gitkeepPath = path.join(dirPath, '.gitkeep');\n const status = await writeFileSafe(gitkeepPath, '', overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(gitkeepPath);\n } else {\n result.filesCreated.push(gitkeepPath);\n }\n } catch (err) {\n result.errors.push(`Dir ${dir}: ${err}`);\n }\n }\n\n // .claude-forge.json — manifest for doctor command\n try {\n const manifest = buildManifest(ctx);\n\n const outputPath = path.join(ctx.targetDir, '.claude-forge.json');\n const status = await writeFileSafe(\n outputPath,\n JSON.stringify(manifest, null, 2) + '\\n',\n overwrite\n );\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n }\n } catch (err) {\n result.errors.push(`.claude-forge.json: ${err}`);\n }\n\n return result;\n}\n\nexport interface ForgeManifest {\n version: string;\n createdAt: string;\n updatedAt: string;\n projectName: string;\n projectDescription: string;\n agentPreset: string;\n language: string;\n stack: string;\n framework: string;\n testFramework: string;\n testCommand: string;\n srcDir: string;\n testDir: string;\n commitStyle: string;\n expectedFiles: string[];\n}\n\nexport function buildManifest(ctx: ProjectContext): ForgeManifest {\n return {\n version: '3.0.0',\n createdAt: ctx.today,\n updatedAt: ctx.today,\n projectName: ctx.projectName,\n projectDescription: ctx.projectDescription,\n language: ctx.language,\n agentPreset: ctx.agentPreset,\n stack: ctx.stack,\n framework: ctx.framework,\n testFramework: ctx.testFramework,\n testCommand: ctx.testCommand,\n srcDir: ctx.srcDir,\n testDir: ctx.testDir,\n commitStyle: ctx.commitStyle,\n expectedFiles: getExpectedFiles(ctx),\n };\n}\n\nexport function getExpectedFiles(ctx: ProjectContext): string[] {\n const files = [\n '.claude/CLAUDE.md',\n '.claude/settings.json',\n '.claude-forge.json',\n 'dev-infra/tasks/tasks.json',\n 'dev-infra/memory/active-context.md',\n 'dev-infra/memory/progress.md',\n 'dev-infra/memory/project-brief.md',\n 'dev-infra/memory/decisions.md',\n 'dev-infra/memory/tech-stack.md',\n 'dev-infra/memory/tech-debt.md',\n 'dev-infra/memory/patterns.md',\n 'dev-infra/memory/troubleshooting.md',\n 'dev-infra/memory/checkpoint.yml',\n ];\n\n // Hooks\n files.push('.claude/hooks/protect-docs.sh');\n\n // Rules (8 total)\n files.push(\n '.claude/rules/commit-conventions.md',\n '.claude/rules/development-cycle.md',\n '.claude/rules/testing-standards.md',\n '.claude/rules/shared-resources.md',\n '.claude/rules/context-loading.md',\n '.claude/rules/agent-output-format.md',\n '.claude/rules/quality-gates.md',\n '.claude/rules/rollback-protocol.md',\n );\n\n // Skills (10 core + 11 extra for full)\n const coreSkills = [\n 'start-session', 'end-session', 'take-task',\n 'complete-task', 'status', 'plan', 'review',\n 'code', 'test', 'done',\n ];\n const extraSkills = [\n 'interview', 'audit-wave', 'write-report', 'dashboard', 'skill-master',\n 'decompose', 'feature', 'security', 'spec', 'techspec', 'prompts',\n ];\n const skills = ctx.agentPreset === 'full'\n ? [...coreSkills, ...extraSkills]\n : coreSkills;\n for (const skill of skills) {\n files.push(`.claude/skills/${skill}/SKILL.md`);\n }\n\n // Agents depend on preset\n const pipelineAgents = [\n 'analyst', 'architect', 'skeptic', 'developer',\n 'tester', 'inspector', 'reviewer', 'planner',\n ];\n const planningAgents = ['researcher', 'validator', 'interviewer', 'decomposer'];\n const securityAgents = ['auditor', 'prompter', 'deployer', 'scaffolder'];\n const documentationAgents = ['librarian', 'writer', 'gatekeeper', 'verifier'];\n\n const minimalAgents = ['analyst', 'developer', 'tester', 'reviewer', 'inspector'];\n\n const coreAgents = [...pipelineAgents];\n const fullAgents = [\n ...pipelineAgents,\n ...planningAgents,\n ...securityAgents,\n ...documentationAgents,\n ];\n\n const agents = ctx.agentPreset === 'minimal'\n ? minimalAgents\n : ctx.agentPreset === 'full'\n ? fullAgents\n : coreAgents;\n\n for (const agent of agents) {\n files.push(`.claude/agents/${agent}.md`);\n }\n\n return files;\n}\n","import path from 'path';\nimport type { ProjectContext, GeneratorResult } from '../types.js';\nimport { renderTemplate } from '../utils/template.js';\nimport { writeFileSafe, makeExecutable } from '../utils/fs.js';\n\nexport async function generateHooks(\n ctx: ProjectContext,\n overwrite: boolean\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const templateData = {\n ...ctx,\n defaultBranch: 'main',\n };\n\n try {\n const content = await renderTemplate('hooks/protect-docs.sh.ejs', templateData);\n const outputPath = path.join(ctx.targetDir, '.claude/hooks/protect-docs.sh');\n const status = await writeFileSafe(outputPath, content, overwrite);\n\n if (status === 'skipped') {\n result.filesSkipped.push(outputPath);\n } else {\n result.filesCreated.push(outputPath);\n await makeExecutable(outputPath);\n }\n } catch (err) {\n result.errors.push(`Hook protect-docs.sh: ${err}`);\n }\n\n return result;\n}\n","import type { ProjectContext, GeneratorResult } from '../types.js';\nimport { generateMemoryBank } from './memory-bank.js';\nimport { generateAgents } from './agents.js';\nimport { generateSkills } from './skills.js';\nimport { generateRules } from './rules.js';\nimport { generateClaudeMd } from './claude-md.js';\nimport { generateInfra } from './infra.js';\nimport { generateHooks } from './hooks.js';\n\nexport async function generateAll(\n ctx: ProjectContext,\n overwrite: boolean = false\n): Promise<GeneratorResult> {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n const generators = [\n generateClaudeMd,\n generateAgents,\n generateSkills,\n generateRules,\n generateMemoryBank,\n generateHooks,\n generateInfra,\n ];\n\n for (const generator of generators) {\n try {\n const partial = await generator(ctx, overwrite);\n result.filesCreated.push(...partial.filesCreated);\n result.filesSkipped.push(...partial.filesSkipped);\n result.errors.push(...partial.errors);\n } catch (err) {\n result.errors.push(`Generator error: ${err}`);\n }\n }\n\n return result;\n}\n","import path from 'path';\nimport chalk from 'chalk';\nimport { fileExists, readFile } from '../utils/fs.js';\nimport type { DoctorCheck } from '../types.js';\n\nexport async function doctorCommand(): Promise<void> {\n const targetDir = process.cwd();\n\n console.log();\n console.log(chalk.bold(' agent-forge doctor'));\n console.log(chalk.dim(' Checking project structure integrity...'));\n console.log();\n\n // Load manifest\n const manifestPath = path.join(targetDir, '.claude-forge.json');\n const manifestExists = await fileExists(manifestPath);\n\n if (!manifestExists) {\n console.log(chalk.red(' .claude-forge.json not found'));\n console.log(chalk.dim(' Run `agent-forge init` first to initialize the project.'));\n console.log();\n process.exit(1);\n }\n\n const manifestRaw = await readFile(manifestPath);\n let manifest: { version: string; expectedFiles: string[]; projectName: string };\n\n try {\n manifest = JSON.parse(manifestRaw);\n } catch {\n console.log(chalk.red(' .claude-forge.json is corrupted'));\n process.exit(1);\n }\n\n console.log(chalk.dim(` Project: ${manifest.projectName}`));\n console.log(chalk.dim(` Version: ${manifest.version}`));\n console.log();\n\n const checks: DoctorCheck[] = [];\n let okCount = 0;\n let failCount = 0;\n\n for (const file of manifest.expectedFiles) {\n const filePath = path.join(targetDir, file);\n const exists = await fileExists(filePath);\n\n const check: DoctorCheck = {\n name: file,\n path: filePath,\n exists,\n ok: exists,\n };\n\n if (exists) {\n // Check if file is not empty\n try {\n const content = await readFile(filePath);\n if (content.trim().length === 0) {\n check.ok = false;\n check.message = 'File is empty';\n }\n } catch {\n check.ok = false;\n check.message = 'Cannot read file';\n }\n } else {\n check.message = 'File not found';\n }\n\n checks.push(check);\n if (check.ok) okCount++;\n else failCount++;\n }\n\n // Display results grouped by category\n const categories: Record<string, DoctorCheck[]> = {};\n for (const check of checks) {\n const category = check.name.startsWith('.claude/agents')\n ? 'Agents'\n : check.name.startsWith('.claude/skills')\n ? 'Skills'\n : check.name.startsWith('.claude/rules')\n ? 'Rules'\n : check.name.startsWith('.claude/')\n ? 'Claude Config'\n : check.name.startsWith('dev-infra/memory')\n ? 'Memory Bank'\n : check.name.startsWith('dev-infra/')\n ? 'Infrastructure'\n : 'Other';\n\n if (!categories[category]) categories[category] = [];\n categories[category].push(check);\n }\n\n for (const [category, items] of Object.entries(categories)) {\n const allOk = items.every(c => c.ok);\n const icon = allOk ? chalk.green('OK') : chalk.red('!!');\n console.log(` ${icon} ${chalk.bold(category)}`);\n\n for (const item of items) {\n if (item.ok) {\n console.log(chalk.green(` + ${item.name}`));\n } else {\n console.log(chalk.red(` - ${item.name} (${item.message})`));\n }\n }\n console.log();\n }\n\n // Summary\n console.log(chalk.bold(' Summary'));\n console.log(chalk.green(` OK: ${okCount}`));\n if (failCount > 0) {\n console.log(chalk.red(` Missing/broken: ${failCount}`));\n console.log();\n console.log(chalk.dim(' Run `agent-forge init --overwrite` to regenerate missing files.'));\n } else {\n console.log(chalk.green(' All checks passed!'));\n }\n console.log();\n\n if (failCount > 0) {\n process.exit(1);\n }\n}\n","import path from 'path';\nimport chalk from 'chalk';\nimport ora from 'ora';\nimport { fileExists, readFile, writeFileSafe } from '../utils/fs.js';\nimport { generateClaudeMd } from '../generators/claude-md.js';\nimport { generateAgents } from '../generators/agents.js';\nimport { generateSkills } from '../generators/skills.js';\nimport { generateRules } from '../generators/rules.js';\nimport { generateMemoryBank } from '../generators/memory-bank.js';\nimport { generateHooks } from '../generators/hooks.js';\nimport { generateInfra } from '../generators/infra.js';\nimport { buildManifest } from '../generators/infra.js';\nimport type { ForgeManifest } from '../generators/infra.js';\nimport type { ProjectContext, GeneratorResult, AgentPreset, Language, CommitStyle } from '../types.js';\n\nfunction today(): string {\n return new Date().toISOString().split('T')[0];\n}\n\nfunction contextFromManifest(manifest: ForgeManifest, targetDir: string): ProjectContext {\n return {\n projectName: manifest.projectName || targetDir.split('/').pop() || 'my-project',\n projectDescription: manifest.projectDescription || 'AI-driven project',\n stack: manifest.stack || 'typescript',\n framework: manifest.framework || 'None',\n testFramework: manifest.testFramework || 'vitest',\n testCommand: manifest.testCommand || 'npx vitest run',\n srcDir: manifest.srcDir || 'src/',\n testDir: manifest.testDir || 'tests/',\n team: [],\n milestones: [],\n agentPreset: (manifest.agentPreset as AgentPreset) || 'core',\n language: (manifest.language as Language) || 'ru',\n commitStyle: (manifest.commitStyle as CommitStyle) || 'standard',\n today: today(),\n targetDir,\n };\n}\n\nexport async function updateCommand(): Promise<void> {\n const targetDir = process.cwd();\n\n console.log();\n console.log(chalk.bold(' agent-forge update v3.0.0'));\n console.log(chalk.dim(' Updating framework files...'));\n console.log();\n\n // 1. Check .claude-forge.json exists\n const manifestPath = path.join(targetDir, '.claude-forge.json');\n const manifestExists = await fileExists(manifestPath);\n\n if (!manifestExists) {\n console.log(chalk.red(' .claude-forge.json not found'));\n console.log(\n chalk.dim(' This project is not initialized. Run `agent-forge init` first.')\n );\n console.log();\n process.exit(1);\n }\n\n // 2. Read existing manifest\n const manifestRaw = await readFile(manifestPath);\n let existingManifest: ForgeManifest;\n\n try {\n existingManifest = JSON.parse(manifestRaw);\n } catch {\n console.log(chalk.red(' .claude-forge.json is corrupted. Cannot update.'));\n console.log(\n chalk.dim(' Run `agent-forge init --overwrite` to reinitialize.')\n );\n console.log();\n process.exit(1);\n }\n\n const previousVersion = existingManifest.version || 'unknown';\n\n // 3. Build ProjectContext from manifest (no interactive prompts)\n const ctx = contextFromManifest(existingManifest, targetDir);\n\n const spinner = ora('Updating framework files...').start();\n\n try {\n const result: GeneratorResult = {\n filesCreated: [],\n filesSkipped: [],\n errors: [],\n };\n\n // 4. Framework files — overwrite=true\n const frameworkGenerators = [\n generateClaudeMd,\n generateAgents,\n generateSkills,\n generateRules,\n generateHooks,\n ];\n\n for (const generator of frameworkGenerators) {\n try {\n const partial = await generator(ctx, true);\n result.filesCreated.push(...partial.filesCreated);\n result.filesSkipped.push(...partial.filesSkipped);\n result.errors.push(...partial.errors);\n } catch (err) {\n result.errors.push(`Generator error: ${err}`);\n }\n }\n\n // 5. User data files — overwrite=false (preserve)\n const userDataGenerators = [\n generateMemoryBank,\n generateInfra,\n ];\n\n for (const generator of userDataGenerators) {\n try {\n const partial = await generator(ctx, false);\n result.filesCreated.push(...partial.filesCreated);\n result.filesSkipped.push(...partial.filesSkipped);\n result.errors.push(...partial.errors);\n } catch (err) {\n result.errors.push(`Generator error: ${err}`);\n }\n }\n\n // 6. Update .claude-forge.json manually (always overwrite)\n const updatedManifest = buildManifest(ctx);\n // Preserve original createdAt\n updatedManifest.createdAt = existingManifest.createdAt || updatedManifest.createdAt;\n updatedManifest.updatedAt = today();\n\n await writeFileSafe(\n manifestPath,\n JSON.stringify(updatedManifest, null, 2) + '\\n',\n true\n );\n\n spinner.succeed(chalk.green('Framework files updated'));\n\n // 7. Build report\n // Separate newly added files from overwritten files\n const newFiles = result.filesCreated.filter(f => !result.filesSkipped.includes(f));\n const updatedCount = newFiles.length;\n const skippedCount = result.filesSkipped.length;\n\n console.log();\n if (updatedCount > 0) {\n console.log(\n chalk.green(` + ${updatedCount} files updated/added`)\n );\n }\n if (skippedCount > 0) {\n console.log(\n chalk.yellow(` ~ ${skippedCount} files skipped (user data preserved)`)\n );\n }\n if (result.errors.length > 0) {\n console.log(chalk.red(` ! ${result.errors.length} errors:`));\n for (const err of result.errors) {\n console.log(chalk.red(` - ${err}`));\n }\n }\n\n console.log();\n if (previousVersion !== updatedManifest.version) {\n console.log(\n chalk.dim(` .claude-forge.json updated: ${previousVersion} -> v${updatedManifest.version}`)\n );\n } else {\n console.log(\n chalk.dim(` .claude-forge.json updated (v${updatedManifest.version})`)\n );\n }\n console.log();\n } catch (err) {\n spinner.fail(chalk.red('Failed to update framework files'));\n console.error(err);\n process.exit(1);\n }\n}\n"],"mappings":"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","names":["path","path","fs","path","path","path","path","path","path","path","path","path","path","path","path","path","path","path","path","chalk","chalk","path","path","chalk","ora","today","chalk","path","ora"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@alxyrgin/agent-forge",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.1.0",
|
|
4
4
|
"description": "AI-driven Development Framework for Claude Code — scaffold Memory Bank, agents, skills, and rules in any project",
|
|
5
5
|
"homepage": "https://github.com/alxyrgin/agent-forge#readme",
|
|
6
6
|
"bugs": {
|