@tungvivas/angular-vibe-kit 0.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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 angular-vibe-kit contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,129 @@
1
+ # angular-vibe-kit
2
+
3
+ Bootstrap a **Vibe Coding workflow** into any Angular project: a `CLAUDE.md`, a set
4
+ of project docs, and Claude Code slash-commands — with **best-practice rules matched
5
+ to your Angular version**.
6
+
7
+ Join an existing Angular project, run one command, and your AI assistant gains a
8
+ persistent memory of how *this* codebase works.
9
+
10
+ ---
11
+
12
+ ## Why
13
+
14
+ AI coding tools have no memory between sessions. Without a project context file they
15
+ re-guess your conventions every time — wrong component patterns, wrong API shapes,
16
+ wrong state management. This kit generates that context **from your actual codebase**,
17
+ and keeps the AI honest with version-correct Angular rules (v14 → v19).
18
+
19
+ It also handles the real-world case: **the project isn't fully best-practice yet.**
20
+ The kit adds correct rules for *new* code without forcing risky refactors on legacy
21
+ modules (Strangler Fig).
22
+
23
+ ---
24
+
25
+ ## Install
26
+
27
+ Run inside the root of your Angular project:
28
+
29
+ ```bash
30
+ npx @tungvivas/angular-vibe-kit
31
+ ```
32
+
33
+ The installer (no AI, fully deterministic):
34
+
35
+ 1. Reads `./package.json` → detects your Angular version
36
+ 2. Copies slash-commands → `./.claude/commands/`
37
+ 3. Copies the **version-matched** best-practice file → `./.claude/angular-practices/`
38
+ 4. Copies doc templates → `./.claude/angular-kit/templates/`
39
+ 5. Tells you to run `/init` in Claude Code
40
+
41
+ ### Options
42
+ | Flag | Effect |
43
+ |------|--------|
44
+ | `--version <n>` | Override detected version (e.g. `--version 17`) |
45
+ | `--force` | Overwrite files that already exist |
46
+ | `--dry-run` | Show what would happen, write nothing |
47
+ | `-h, --help` | Help |
48
+
49
+ ---
50
+
51
+ ## Use
52
+
53
+ After install, open the project in **Claude Code**:
54
+
55
+ ```
56
+ /init ← scan codebase, ask to confirm uncertain bits, generate docs
57
+ ```
58
+
59
+ `/init` generates, one file at a time (you review each):
60
+ `CLAUDE.md` → `docs/API_CONTRACT.md` → `docs/ARCHITECTURE.md` →
61
+ `docs/PROJECT-RULES.md` → `docs/PROJECT-STATUS.md` → `docs/DESIGN_SYSTEM.md` →
62
+ `docs/decisions/`.
63
+
64
+ Then every working session:
65
+
66
+ | Command | When | Does |
67
+ |---------|------|------|
68
+ | `/start` | Start of session | Read docs, summarize progress, wait |
69
+ | `/new-feature` | New module | Scaffold → implement → test → docs |
70
+ | `/write-tests` | Code without tests | Service spec + component test |
71
+ | `/write-context` | New/complex module | Create `CONTEXT.md` snapshot |
72
+ | `/review-pr` | Before commit | Angular review checklist → 🔴/🟡/🟢 |
73
+ | `/update-status` | End of session | Update `PROJECT-STATUS.md` + commit |
74
+
75
+ ---
76
+
77
+ ## Version-matched best practices
78
+
79
+ The installer copies exactly one profile based on your `@angular/core`:
80
+
81
+ | Angular | Profile | Key idioms |
82
+ |---------|---------|-----------|
83
+ | 14–15 | `v14-15.md` | NgModule, `*ngIf/*ngFor`, constructor DI, RxJS + `BehaviorSubject` |
84
+ | 16 | `v16.md` | `inject()`, required inputs, `takeUntilDestroyed`, Signals (preview) |
85
+ | 17 | `v17.md` | Standalone default, `@if/@for/@switch`, `@defer`, Signals stable |
86
+ | 18–19 | `v18-19.md` | Signal inputs/outputs, `linkedSignal`/`resource`, zoneless (experimental) |
87
+
88
+ These files cover **framework idioms only** (syntax, DI, components, RxJS/Signals).
89
+ Project-specific choices — folder layout, state-management, naming — are inferred
90
+ from your code and written into `docs/PROJECT-RULES.md`.
91
+
92
+ ---
93
+
94
+ ## Coexistence (joining a not-yet-standard project)
95
+
96
+ `/init` classifies what it finds as `standard`, `below-standard`, or `uncertain`,
97
+ then writes a **Coexistence Strategy** into `PROJECT-RULES.md`:
98
+
99
+ - Patterns you already do right → kept as required rules.
100
+ - Sub-standard patterns → correct rule applied to **new code only**.
101
+ - Legacy modules → listed as **do-not-touch** (no refactor unless asked).
102
+
103
+ Anything uncertain becomes a question — the kit never silently rewrites your rules.
104
+
105
+ ---
106
+
107
+ ## What gets created in your project
108
+
109
+ ```
110
+ your-angular-app/
111
+ ├── CLAUDE.md # generated by /init
112
+ ├── .claude/
113
+ │ ├── commands/ # 7 slash-commands (copied by installer)
114
+ │ │ ├── init.md start.md new-feature.md review-pr.md
115
+ │ │ ├── write-tests.md write-context.md update-status.md
116
+ │ ├── angular-practices/ # 1 version-matched profile (copied)
117
+ │ │ └── v17.md
118
+ │ └── angular-kit/templates/ # doc templates (copied)
119
+ └── docs/ # generated by /init
120
+ ├── PROJECT-RULES.md ARCHITECTURE.md API_CONTRACT.md
121
+ ├── PROJECT-STATUS.md DESIGN_SYSTEM.md
122
+ └── decisions/
123
+ ```
124
+
125
+ ---
126
+
127
+ ## License
128
+
129
+ MIT
package/bin/cli.js ADDED
@@ -0,0 +1,245 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * angular-vibe-kit installer
4
+ *
5
+ * Deterministic, no AI. Detects the target project's Angular version from
6
+ * package.json, then scaffolds the Vibe Coding workspace:
7
+ *
8
+ * CLAUDE.md ← project root (entry point)
9
+ * docs/ ← reference docs
10
+ * ARCHITECTURE.md
11
+ * API_CONTRACT.md
12
+ * DESIGN_SYSTEM.md
13
+ * PROJECT-STATUS.md
14
+ * decisions/
15
+ * .claude/
16
+ * commands/ ← 7 slash-commands
17
+ * angular-practices/<ver>.md ← version-matched best-practice file
18
+ * rules/
19
+ * project-rules.md ← auto-loaded by Claude Code every session
20
+ *
21
+ * Generation (filling in actual content) happens later via /init in Claude Code.
22
+ */
23
+
24
+ import { existsSync, mkdirSync, readFileSync, copyFileSync, readdirSync, statSync } from "node:fs";
25
+ import { fileURLToPath } from "node:url";
26
+ import { dirname, join, resolve, relative } from "node:path";
27
+ import { createRequire } from "node:module";
28
+
29
+ const __dirname = dirname(fileURLToPath(import.meta.url));
30
+ const KIT_ROOT = resolve(__dirname, "..");
31
+
32
+ // --- package metadata (single source of truth = package.json) -----------
33
+ const require = createRequire(import.meta.url);
34
+ const pkg = require("../package.json");
35
+ const VERSION = pkg.version;
36
+ const HOMEPAGE = pkg.homepage;
37
+
38
+ // --- tiny ansi helpers (no deps) -----------------------------------------
39
+ const c = { reset: "\x1b[0m", bold: "\x1b[1m", dim: "\x1b[2m", red: "\x1b[31m", green: "\x1b[32m", yellow: "\x1b[33m", cyan: "\x1b[36m" };
40
+ const log = (msg = "") => process.stdout.write(msg + "\n");
41
+ const ok = (msg) => log(`${c.green}✓${c.reset} ${msg}`);
42
+ const warn = (msg) => log(`${c.yellow}!${c.reset} ${msg}`);
43
+ const err = (msg) => log(`${c.red}✗${c.reset} ${msg}`);
44
+
45
+ // --- arg parsing ----------------------------------------------------------
46
+ const args = process.argv.slice(2);
47
+ const flags = {
48
+ force: args.includes("--force"),
49
+ dryRun: args.includes("--dry-run"),
50
+ help: args.includes("--help") || args.includes("-h"),
51
+ version: getFlagValue("--version"),
52
+ };
53
+
54
+ function getFlagValue(name) {
55
+ const i = args.indexOf(name);
56
+ return i === -1 ? null : (args[i + 1] ?? null);
57
+ }
58
+
59
+ function printHelp() {
60
+ log(`${c.bold}angular-vibe-kit${c.reset} — bootstrap the Vibe Coding workflow into an Angular project
61
+
62
+ ${c.bold}Usage${c.reset}
63
+ npx @tungvivas/angular-vibe-kit [options]
64
+
65
+ ${c.bold}Options${c.reset}
66
+ --version <n> Override detected Angular major version (e.g. 17)
67
+ --force Overwrite files that already exist
68
+ --dry-run Show what would happen without writing anything
69
+ -h, --help Show this help
70
+
71
+ ${c.bold}What gets created${c.reset}
72
+ CLAUDE.md ← project root entry point
73
+ docs/ ← reference docs (fill in with /init)
74
+ .claude/commands/ ← 7 slash-commands
75
+ .claude/angular-practices/ ← version-matched best-practice file
76
+ .claude/rules/project-rules.md ← auto-loaded every Claude Code session`);
77
+ }
78
+
79
+ // --- version detection ----------------------------------------------------
80
+ const MIN_SUPPORTED = 12;
81
+ const PRACTICE_BY_MAJOR = {
82
+ 12: "v12-13.md", 13: "v12-13.md",
83
+ 14: "v14-15.md", 15: "v14-15.md",
84
+ 16: "v16.md",
85
+ 17: "v17.md",
86
+ 18: "v18-19.md", 19: "v18-19.md",
87
+ 20: "v20plus.md", // Signal-native: zoneless stable, signals graduated; resource/httpResource still experimental
88
+ };
89
+ const NEWEST_PRACTICE = "v20plus.md"; // fallback for v21+ (future)
90
+
91
+ function detectAngularMajor(cwd) {
92
+ const pkgPath = join(cwd, "package.json");
93
+ if (!existsSync(pkgPath)) return { major: null, reason: "no package.json found" };
94
+ let pkg;
95
+ try {
96
+ const raw = readFileSync(pkgPath, "utf8").replace(/^/, ""); // strip BOM
97
+ pkg = JSON.parse(raw);
98
+ } catch { return { major: null, reason: "package.json is not valid JSON" }; }
99
+ const deps = { ...(pkg.dependencies || {}), ...(pkg.devDependencies || {}) };
100
+ const raw = deps["@angular/core"] || deps["@angular/cli"];
101
+ if (!raw) return { major: null, reason: "no @angular/core or @angular/cli dependency" };
102
+ const match = String(raw).match(/(\d+)\s*\.\s*\d+/) || String(raw).match(/(\d+)/);
103
+ if (!match) return { major: null, reason: `could not parse version "${raw}"` };
104
+ return { major: Number(match[1]), reason: null, raw };
105
+ }
106
+
107
+ function resolvePractice(major) {
108
+ if (major === null) return { file: null, issue: "unknown" };
109
+ if (major < MIN_SUPPORTED) return { file: null, issue: "below-min" };
110
+ if (PRACTICE_BY_MAJOR[major]) return { file: PRACTICE_BY_MAJOR[major], issue: null };
111
+ // v20+ future: use newest
112
+ return { file: NEWEST_PRACTICE, issue: "future" };
113
+ }
114
+
115
+ // --- copy helpers ---------------------------------------------------------
116
+ let copied = 0;
117
+ let skipped = 0;
118
+
119
+ function ensureDir(dir) {
120
+ if (!flags.dryRun) mkdirSync(dir, { recursive: true });
121
+ }
122
+
123
+ function copyOne(src, dest, cwd) {
124
+ const rel = relative(cwd, dest);
125
+ if (existsSync(dest) && !flags.force) {
126
+ warn(`skip (exists): ${rel}`);
127
+ skipped++;
128
+ return;
129
+ }
130
+ if (flags.dryRun) {
131
+ log(`${c.dim}would copy → ${rel}${c.reset}`);
132
+ copied++;
133
+ return;
134
+ }
135
+ ensureDir(dirname(dest));
136
+ copyFileSync(src, dest);
137
+ ok(rel);
138
+ copied++;
139
+ }
140
+
141
+ function copyDir(srcDir, destDir, cwd) {
142
+ for (const entry of readdirSync(srcDir)) {
143
+ const srcPath = join(srcDir, entry);
144
+ const destPath = join(destDir, entry);
145
+ if (statSync(srcPath).isDirectory()) copyDir(srcPath, destPath, cwd);
146
+ else copyOne(srcPath, destPath, cwd);
147
+ }
148
+ }
149
+
150
+ // --- main -----------------------------------------------------------------
151
+ function main() {
152
+ if (flags.help) { printHelp(); return; }
153
+
154
+ const cwd = process.cwd();
155
+ log(`${c.bold}angular-vibe-kit${c.reset} ${c.dim}v${VERSION}${c.reset}`);
156
+ if (flags.dryRun) warn("dry-run: no files will be written");
157
+ log("");
158
+
159
+ // 1. detect version
160
+ let major;
161
+ if (flags.version) {
162
+ major = Number(flags.version);
163
+ log(`Using forced Angular version: ${c.cyan}${major}${c.reset}`);
164
+ } else {
165
+ const detected = detectAngularMajor(cwd);
166
+ if (detected.major) {
167
+ major = detected.major;
168
+ log(`Detected Angular version: ${c.cyan}${major}${c.reset} ${c.dim}(${detected.raw})${c.reset}`);
169
+ } else {
170
+ err(`Cannot detect Angular version: ${detected.reason}`);
171
+ log("");
172
+ log(`${c.bold}Fix options:${c.reset}`);
173
+ log(` 1. Run inside the Angular project folder (where package.json lives)`);
174
+ log(` 2. Use ${c.cyan}--version <n>${c.reset} to specify manually, e.g. ${c.cyan}--version 17${c.reset}`);
175
+ process.exit(1);
176
+ }
177
+ }
178
+
179
+ // 2. resolve which practice file to use
180
+ const { file: practice, issue } = resolvePractice(major);
181
+
182
+ if (issue === "below-min") {
183
+ err(`Angular ${major} is below the minimum supported version (${MIN_SUPPORTED}).`);
184
+ log("");
185
+ log(`${c.bold}Supported versions:${c.reset} 12, 13, 14, 15, 16, 17, 18, 19`);
186
+ log(`If you still want to proceed, use the closest profile:`);
187
+ log(` ${c.cyan}npx @tungvivas/angular-vibe-kit --version 12${c.reset} (v12-13 best practices)`);
188
+ process.exit(1);
189
+ }
190
+
191
+ if (issue === "future") {
192
+ warn(`Angular ${major} has no dedicated profile yet — using v20+ profile (${NEWEST_PRACTICE}).`);
193
+ warn(`Check ${HOMEPAGE} for a dedicated update.`);
194
+ }
195
+
196
+ log(`Best-practice profile: ${c.cyan}${practice}${c.reset}`);
197
+ log("");
198
+
199
+ const claudeDir = join(cwd, ".claude");
200
+
201
+ // 3. CLAUDE.md → project root
202
+ log(`${c.bold}Entry point${c.reset}`);
203
+ copyOne(join(KIT_ROOT, "templates", "CLAUDE.md"), join(cwd, "CLAUDE.md"), cwd);
204
+ log("");
205
+
206
+ // 4. docs/ → project root/docs/
207
+ log(`${c.bold}Docs${c.reset} → docs/`);
208
+ copyDir(join(KIT_ROOT, "templates", "docs"), join(cwd, "docs"), cwd);
209
+ log("");
210
+
211
+ // 5. .claude/commands/ → 7 slash-commands
212
+ log(`${c.bold}Commands${c.reset} → .claude/commands/`);
213
+ copyDir(join(KIT_ROOT, "commands"), join(claudeDir, "commands"), cwd);
214
+ log("");
215
+
216
+ // 6. .claude/angular-practices/ → 1 matched BP file
217
+ log(`${c.bold}Best practices${c.reset} → .claude/angular-practices/`);
218
+ const practiceSrc = join(KIT_ROOT, "practices", practice);
219
+ if (existsSync(practiceSrc)) {
220
+ copyOne(practiceSrc, join(claudeDir, "angular-practices", practice), cwd);
221
+ } else {
222
+ err(`practice file missing in kit: ${practice}`);
223
+ }
224
+ log("");
225
+
226
+ // 7. .claude/rules/project-rules.md → auto-loaded by Claude Code
227
+ log(`${c.bold}Rules${c.reset} → .claude/rules/ ${c.dim}(auto-loaded every session)${c.reset}`);
228
+ copyOne(
229
+ join(KIT_ROOT, "templates", "rules", "project-rules.md"),
230
+ join(claudeDir, "rules", "project-rules.md"),
231
+ cwd
232
+ );
233
+ log("");
234
+
235
+ // 8. summary
236
+ log(`${c.bold}Done.${c.reset} ${copied} file(s) created, ${skipped} skipped.`);
237
+ if (skipped > 0 && !flags.force) log(`${c.dim}Re-run with --force to overwrite skipped files.${c.reset}`);
238
+ log("");
239
+ log(`${c.bold}Next steps${c.reset}`);
240
+ log(` 1. Open this project in ${c.cyan}Claude Code${c.reset}.`);
241
+ log(` 2. Run ${c.cyan}/init${c.reset} — it will scan your codebase and fill in all the docs.`);
242
+ log(` 3. Each session: ${c.cyan}/start${c.reset} → work → ${c.cyan}/update-status${c.reset}.`);
243
+ }
244
+
245
+ main();
@@ -0,0 +1,139 @@
1
+ Run the full feature development cycle for one Angular feature, end to end:
2
+ scaffold → implement → test → context → review → wrap up.
3
+
4
+ This is an ORCHESTRATOR. It chains the other commands' logic, but it is NOT
5
+ fully autonomous: after every phase it STOPS at a gate and waits for your
6
+ explicit confirmation before continuing.
7
+
8
+ ---
9
+
10
+ ## THE GATE RULE (applies after EVERY phase — non-negotiable)
11
+
12
+ After finishing each phase, you MUST:
13
+ 1. Print a short summary of what was just done.
14
+ 2. Ask exactly: **"✅ Continue to Phase X? (yes / no)"**
15
+ 3. Then WAIT. Do not proceed on silence, timeout, or assumption.
16
+ 4. If the user replies **yes / ok / continue / tiếp** → move to the next phase.
17
+ 5. If the user replies **anything else** (no / stop / "sửa lại ..." / a change request / a question)
18
+ → **EXIT the automated cycle immediately.** Drop into normal interactive mode and
19
+ do whatever the user asks. Do NOT try to resume the cycle unless the user explicitly
20
+ says to continue.
21
+
22
+ Never skip a gate. Never batch multiple phases past a gate. The user is always in control.
23
+
24
+ ---
25
+
26
+ ## Phase 0 — Kickoff
27
+
28
+ 1. Read context:
29
+ - `.claude/rules/project-rules.md`
30
+ - `docs/ARCHITECTURE.md`
31
+ - `docs/API_CONTRACT.md`
32
+ - `docs/DESIGN_SYSTEM.md`
33
+ - `.claude/angular-practices/` (the version profile)
34
+ 2. Ask ONE question: **"What is the feature name and what does it do?"** (name + one sentence)
35
+ 3. **GATE:** Wait for the answer. Write no code until you have it.
36
+
37
+ ---
38
+
39
+ ## Phase 1 — Scaffold
40
+
41
+ 1. Create the full folder + empty-file structure for `features/{feature-name}/`
42
+ (model, service, routes, pages/, components/ — match the layout in project-rules.md).
43
+ 2. Print the created file tree.
44
+ 3. **GATE:** "✅ Folder structure OK? Continue to Phase 2 (Model + Service)? (yes / no)"
45
+
46
+ ---
47
+
48
+ ## Phase 2a — Implement Model + Service
49
+
50
+ 1. Write `models/{feature}.model.ts` — interfaces mirroring the backend's actual response shape from `API_CONTRACT.md` (envelope, raw DTO, or GraphQL type — per `project-rules.md`).
51
+ 2. Write `services/{feature}.service.ts` — data-access methods returning `Observable<T>` typed with the project's response shape,
52
+ following the DI/idiom of the version profile.
53
+ 3. Print the two files.
54
+ 4. **GATE:** "✅ Model + Service OK? Continue to Phase 2b (Routes + UI)? (yes / no)"
55
+ > This gate matters most — a wrong type/endpoint here breaks every component after it.
56
+
57
+ ---
58
+
59
+ ## Phase 2b — Implement Routes + Pages + Components
60
+
61
+ 1. Write `{feature}.routes.ts` (lazy-loaded).
62
+ 2. Write page (smart) components — data, loading/error/empty states.
63
+ 3. Write presentational (dumb) components — inputs/outputs only.
64
+ 4. Print a summary of files written.
65
+ 5. **GATE:** "✅ UI components OK? Continue to Phase 3 (Tests)? (yes / no)"
66
+
67
+ ---
68
+
69
+ ## Phase 3 — Tests + Context
70
+
71
+ 1. Write tests following `/write-tests`:
72
+ - `{feature}.service.spec.ts` (mock HttpClient: success + error + empty per method)
73
+ - `{feature}-list.component.spec.ts` (mock service: render + interaction + loading + error)
74
+ 2. **Harness loop — tests (automated within this phase, max 3 rounds):**
75
+ ```
76
+ round = 1
77
+ while round <= 3:
78
+ say "Running tests, round {round}/3..."
79
+ run: ng test {feature} (or jest {feature})
80
+ if PASS: break
81
+ read the failure output → fix the code/test → round += 1
82
+ if still failing after 3 rounds:
83
+ print remaining errors
84
+ GATE: "❌ Tests still failing after 3 rounds. Exiting cycle — handle manually."
85
+ → exit the automated cycle
86
+ ```
87
+ 3. After tests pass, write the feature's `CONTEXT.md` in the same folder created in Phase 1 (per `/write-context`).
88
+ 4. **GATE:** "✅ Tests pass (round {n}) + CONTEXT.md written. Continue to Phase 4 (Review)? (yes / no)"
89
+
90
+ ---
91
+
92
+ ## Phase 4 — Review + Harness
93
+
94
+ 1. Run the full `/review-pr` checklist (all 8 categories).
95
+ 2. Print the result: count of 🔴 blockers, 🟡 suggestions, 🟢 good parts.
96
+ 3. If 0 blockers → skip the loop, go straight to the Phase 4 gate.
97
+ 4. If there are blockers:
98
+ - **GATE:** "🔴 {n} blockers found. Auto-fix and re-review? (yes / no)"
99
+ - NO → exit the automated cycle; user fixes manually.
100
+ - YES → **Harness loop — review (max 3 rounds):**
101
+ ```
102
+ round = 1
103
+ while round <= 3:
104
+ say "Fix round {round}/3 — fixing: {list of blockers}"
105
+ fix ALL 🔴 blockers
106
+ re-run /review-pr checklist
107
+ if 0 blockers: break
108
+ round += 1
109
+ if blockers remain after 3 rounds:
110
+ print remaining blockers
111
+ GATE: "❌ Blockers remain after 3 rounds. Exiting cycle — handle manually."
112
+ → exit the automated cycle
113
+ ```
114
+ 5. 🟡 Suggestions are NOT blocking — list them so the user can decide later.
115
+ 6. **GATE:** "✅ Review clean (0 blockers after {n} rounds). Continue to Phase 5 (Wrap up)? (yes / no)"
116
+
117
+ ---
118
+
119
+ ## Phase 5 — Wrap up
120
+
121
+ 1. Update `docs/PROJECT-STATUS.md` (per `/update-status` — move to Completed, bump session).
122
+ 2. Update `docs/API_CONTRACT.md` if new endpoints were used.
123
+ 3. Generate a commit message: `feat({feature-name}): {description} + tests + docs`.
124
+ 4. Print the git command for the user to run:
125
+ ```
126
+ git add CLAUDE.md docs/ .claude/rules/ src/
127
+ git commit -m "feat({feature-name}): {description} + tests + docs"
128
+ ```
129
+ 5. **Do NOT run git yourself.** The user reviews and commits.
130
+ 6. Final message: "✅ dev-cycle complete. Run the git command above to commit."
131
+
132
+ ---
133
+
134
+ ## Notes
135
+ - Harness loops (Phase 3 tests, Phase 4 review) run automatically WITHIN their phase —
136
+ they handle mechanical errors (compile, test failures, checklist blockers) without bugging you.
137
+ - But the loops are bounded (max 3 rounds) and never cross a phase gate.
138
+ - Logic correctness ("does it do what I actually wanted?") is checked by YOU at the gates,
139
+ not by the harness — that is why the human gates exist.
@@ -0,0 +1,103 @@
1
+ Scan this Angular project's codebase and fill in the skeleton docs that were
2
+ created by the installer. This command runs **one-shot**: scan → ask all open
3
+ questions once → write all files → verify → summarize. Reads code and writes
4
+ docs only — never modifies application source files.
5
+
6
+ The skeleton files already exist at their correct locations:
7
+ CLAUDE.md ← project root (keep under 200 lines)
8
+ docs/ARCHITECTURE.md
9
+ docs/API_CONTRACT.md
10
+ docs/DESIGN_SYSTEM.md
11
+ docs/PROJECT-STATUS.md
12
+ docs/decisions/
13
+ .claude/rules/project-rules.md ← auto-loaded every session
14
+
15
+ The version-matched best-practice file is in `.claude/angular-practices/`
16
+ (one file, already matched to this project's Angular version by the installer).
17
+
18
+ ## Core Principles
19
+ - **Infer from code first.** Read before asking — do not ask about things you can determine.
20
+ - **Batch the questions.** Collect EVERY uncertain point across ALL files and ask them in ONE round (Stage 1). Do not drip-feed questions file by file.
21
+ - **Then write everything.** After the answers come back, write all 7 files in one pass (Stage 2) — no per-file stops.
22
+ - **Review is at the end.** The human review happens once, after the summary (Stage 4) — not between files.
23
+ - **Precedence: codebase first, then the BP profile.** A valid project convention wins over the Angular best-practice profile; the profile applies only where the project has no convention or is objectively below standard (new code only). Legacy is never refactored. Write this exact precedence into `project-rules.md` (the `## Precedence` section).
24
+ - **CLAUDE.md stays under 200 lines.** Link to docs/ for details, do not inline everything.
25
+
26
+ ## Stage 0: Scan (read-only, no output yet)
27
+ 1. Read the BP file in `.claude/angular-practices/` (one file — the version's idioms).
28
+ 2. Read `package.json` → Angular version, UI library, test runner, state libs.
29
+ 3. Scan `src/`:
30
+ - Module system: standalone vs NgModule
31
+ - State: NgRx / Signals / BehaviorSubject / plain service
32
+ - Folder layout: `core/ shared/ features/` or other
33
+ - HTTP pattern: HttpClient in services vs components
34
+ - Interceptors, guards, auth flow, token handling
35
+ - Test setup, shared components, UI library usage
36
+ 4. **Find the best-example files** — the most complete, idiomatic feature to use as a
37
+ reference template. Pick the best example for each of: a service, a smart/page
38
+ component, a dumb component, a test spec. Verify each path exists.
39
+ 5. Classify each finding: `standard` / `below-standard` / `uncertain`.
40
+ 6. Print a short findings summary (3–5 lines) + the chosen best-example files.
41
+
42
+ ## Stage 1: Ask ALL Open Questions at Once
43
+ 1. Gather every `uncertain` item across ALL seven files into a single list
44
+ (e.g. "both NgRx and Signals present — which is primary?", "response envelope shape?",
45
+ "auth model?", "which forms approach?", "confirm this legacy do-not-touch list").
46
+ 2. Ask them as ONE grouped batch of multiple-choice questions.
47
+ 3. **WAIT** for the answers. Do not write any file until the batch is answered.
48
+ 4. If nothing is uncertain, say so and proceed directly to Stage 2.
49
+
50
+ ## Stage 2: Write ALL Files (one pass, no stops)
51
+ Using the scan + the answers, write all files in this order. Replace every `{{...}}`
52
+ placeholder with real content. Do NOT stop between files.
53
+
54
+ 1. **CLAUDE.md** (root) — `Read first` links, `Common commands` from `package.json` scripts, `Runtime and tooling` from detected stack, `High-level architecture` (2–4 line summary, link to docs/ARCHITECTURE.md). Under 200 lines.
55
+ 2. **docs/API_CONTRACT.md** — infer from existing `*.service.ts` calls; map endpoints → service methods → TypeScript interfaces. Mark gaps.
56
+ 3. **docs/ARCHITECTURE.md** — actual layer structure, routing/lazy-loading, state approach, HTTP/interceptor flow, auth strategy. Full detail here (not in CLAUDE.md).
57
+ 4. **.claude/rules/project-rules.md** — tech stack, naming, coding rules (actionable, not prose). Include the `## Precedence` section, the `## Reference Examples` section (best-example files from Stage 0 — paths that exist only), and the `## Coexistence Strategy` section (see below).
58
+ 5. **docs/PROJECT-STATUS.md** — snapshot: what exists, in progress, known issues, next tasks. Session counter = 1.
59
+ 6. **docs/DESIGN_SYSTEM.md** — UI library, design tokens (infer from styles/theme), shared/reusable components in whatever the project calls that folder (record the actual name).
60
+ 7. **docs/decisions/** — one ADR per real decision confirmed (e.g. `001-state-management.md`, `002-auth-token-storage.md`). Only for actual decisions.
61
+
62
+ ### Coexistence Strategy (inside project-rules.md)
63
+ - `standard` items → required rules (the project already does this; keep doing it).
64
+ - `below-standard` items → correct rule from the BP file, scoped to **new code only**, with note: "Legacy modules keep their style — do NOT refactor unless explicitly asked."
65
+ - List the **legacy / do-not-touch modules** (confirmed in the Stage 1 batch).
66
+
67
+ ## Stage 3: Self-Verification (prove the docs work)
68
+ 1. **Placeholder scan:** no leftover `{{...}}` / `TODO` / `TBD`. Report "0 placeholders left".
69
+ 2. **Path check:** every file path mentioned (Reference Examples, CLAUDE.md links, ADR pointers) actually exists. Fix any broken path.
70
+ 3. **Comprehension test:** answer this using ONLY the generated docs —
71
+ > "If I add a new `XyzService` + list page: (a) which folder, (b) which DI/RxJS/Signals idiom, (c) what response shape does the service return, (d) where does the test go and what's it named?"
72
+ If any part can't be answered from the docs, fill the gap.
73
+
74
+ ## Stage 4: Final Summary (always print this last)
75
+ Print a summary so I can review everything at once:
76
+
77
+ **1. What I did** — 2–4 bullet lines (version detected, key conventions captured, legacy modules flagged).
78
+
79
+ **2. Files changed** — a table:
80
+
81
+ | File | Status | Key content / decisions captured |
82
+ |------|--------|----------------------------------|
83
+ | CLAUDE.md | created/updated | ... |
84
+ | docs/API_CONTRACT.md | created/updated | ... |
85
+ | docs/ARCHITECTURE.md | created/updated | ... |
86
+ | .claude/rules/project-rules.md | created/updated | precedence + coexistence + reference examples |
87
+ | docs/PROJECT-STATUS.md | created/updated | ... |
88
+ | docs/DESIGN_SYSTEM.md | created/updated | ... |
89
+ | docs/decisions/00x-*.md | created | ... |
90
+
91
+ **3. Questions I asked & your answers** — short list (for the record).
92
+
93
+ **4. Verification** — placeholders left (should be 0), broken paths (should be 0), comprehension-test answer.
94
+
95
+ **5. Anything still uncertain / needs your eyes** — gaps, assumptions, endpoints to confirm.
96
+
97
+ Then: "Review the summary above. Commit when ready:
98
+ `git add CLAUDE.md docs/ .claude/rules/ && git commit -m \"docs: init angular-vibe-kit workspace\"`"
99
+
100
+ ## Rules
101
+ - Do NOT modify `.ts`, `.html`, `.scss` application files.
102
+ - Do NOT add content that is not inferable from the codebase or confirmed in the Stage 1 batch.
103
+ - Stage 1 (questions) and Stage 4 (summary + review) are the only interactive points — everything between is one pass.