@tungvivas/angular-vibe-kit 0.2.0 → 0.3.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/bin/cli.js CHANGED
@@ -13,15 +13,18 @@
13
13
  * PROJECT-STATUS.md
14
14
  * decisions/
15
15
  * .claude/
16
- * commands/ ← 7 slash-commands
16
+ * commands/ ← 8 slash-commands
17
17
  * angular-practices/<ver>.md ← version-matched best-practice file
18
+ * skills/ ← skills Claude auto-applies (no command needed)
19
+ * agents/ ← Angular subagents (isolated context, run in parallel)
20
+ * settings.json ← allowlist (fewer prompts) + build-verify hook
18
21
  * rules/
19
22
  * project-rules.md ← auto-loaded by Claude Code every session
20
23
  *
21
24
  * Generation (filling in actual content) happens later via /init in Claude Code.
22
25
  */
23
26
 
24
- import { existsSync, mkdirSync, readFileSync, copyFileSync, readdirSync, statSync } from "node:fs";
27
+ import { existsSync, mkdirSync, readFileSync, writeFileSync, copyFileSync, readdirSync, statSync } from "node:fs";
25
28
  import { fileURLToPath } from "node:url";
26
29
  import { dirname, join, resolve, relative } from "node:path";
27
30
  import { createRequire } from "node:module";
@@ -71,8 +74,11 @@ ${c.bold}Options${c.reset}
71
74
  ${c.bold}What gets created${c.reset}
72
75
  CLAUDE.md ← project root entry point
73
76
  docs/ ← reference docs (fill in with /init)
74
- .claude/commands/ ← 7 slash-commands
77
+ .claude/commands/ ← 8 slash-commands
75
78
  .claude/angular-practices/ ← version-matched best-practice file
79
+ .claude/skills/ ← skills Claude auto-applies (no command needed)
80
+ .claude/agents/ ← Angular subagents (isolated context, run in parallel)
81
+ .claude/settings.json ← allowlist (fewer prompts) + build-verify hook
76
82
  .claude/rules/project-rules.md ← auto-loaded every Claude Code session`);
77
83
  }
78
84
 
@@ -147,6 +153,76 @@ function copyDir(srcDir, destDir, cwd) {
147
153
  }
148
154
  }
149
155
 
156
+ // Write generated content to a file, honoring --force / --dry-run like copyOne.
157
+ function writeOne(content, dest, cwd) {
158
+ const rel = relative(cwd, dest);
159
+ if (existsSync(dest) && !flags.force) {
160
+ warn(`skip (exists): ${rel}`);
161
+ skipped++;
162
+ return;
163
+ }
164
+ if (flags.dryRun) {
165
+ log(`${c.dim}would create → ${rel}${c.reset}`);
166
+ copied++;
167
+ return;
168
+ }
169
+ ensureDir(dirname(dest));
170
+ writeFileSync(dest, content);
171
+ ok(rel);
172
+ copied++;
173
+ }
174
+
175
+ // Angular profile filename → human label for the skill description.
176
+ // e.g. "v20plus.md" → "v20+", "v18-19.md" → "v18-19", "v17.md" → "v17"
177
+ function profileLabel(practiceFile) {
178
+ return practiceFile.replace(/\.md$/, "").replace(/plus$/, "+");
179
+ }
180
+
181
+ // Detect the package manager from the target project's lockfile.
182
+ function detectPackageManager(cwd) {
183
+ if (existsSync(join(cwd, "pnpm-lock.yaml"))) return "pnpm";
184
+ if (existsSync(join(cwd, "yarn.lock"))) return "yarn";
185
+ return "npm";
186
+ }
187
+
188
+ // Resolve the build-verify command for the Stop hook. Prefers a project "typecheck"
189
+ // script; otherwise falls back to a fast type-check (npx tsc --noEmit). Returns null
190
+ // only if there is no package.json at all.
191
+ function buildVerifyCommand(cwd) {
192
+ const pkgPath = join(cwd, "package.json");
193
+ if (!existsSync(pkgPath)) return null;
194
+ const pm = detectPackageManager(cwd);
195
+ try {
196
+ const raw = readFileSync(pkgPath, "utf8").replace(/^/, "");
197
+ const scripts = (JSON.parse(raw).scripts) || {};
198
+ if (scripts.typecheck) return pm === "npm" ? "npm run typecheck" : `${pm} typecheck`;
199
+ } catch { /* fall through to tsc */ }
200
+ // Fast type-check that works without an Angular-specific script.
201
+ // Swap for `ng build` / `${pm} run build` if you want full template checking.
202
+ return "npx tsc --noEmit";
203
+ }
204
+
205
+ // Build the .claude/settings.json object: a safe allowlist + (optionally) a Stop hook
206
+ // that type-checks only when .ts/.html files changed since HEAD (skips question-only turns).
207
+ function buildSettings(cwd) {
208
+ const settings = {
209
+ permissions: {
210
+ allow: [
211
+ "Bash(ng *)", "Bash(npm *)", "Bash(npx *)", "Bash(pnpm *)", "Bash(yarn *)",
212
+ "Bash(git status *)", "Bash(git diff *)", "Bash(git log *)", "Bash(git show *)",
213
+ ],
214
+ },
215
+ };
216
+ const buildCmd = buildVerifyCommand(cwd);
217
+ if (buildCmd) {
218
+ const hookCmd = `git diff --quiet HEAD -- '*.ts' '*.html' || ${buildCmd}`;
219
+ settings.hooks = {
220
+ Stop: [{ hooks: [{ type: "command", command: hookCmd }] }],
221
+ };
222
+ }
223
+ return { settings, buildCmd };
224
+ }
225
+
150
226
  // --- main -----------------------------------------------------------------
151
227
  function main() {
152
228
  if (flags.help) { printHelp(); return; }
@@ -208,7 +284,7 @@ function main() {
208
284
  copyDir(join(KIT_ROOT, "templates", "docs"), join(cwd, "docs"), cwd);
209
285
  log("");
210
286
 
211
- // 5. .claude/commands/ → 7 slash-commands
287
+ // 5. .claude/commands/ → 8 slash-commands
212
288
  log(`${c.bold}Commands${c.reset} → .claude/commands/`);
213
289
  copyDir(join(KIT_ROOT, "commands"), join(claudeDir, "commands"), cwd);
214
290
  log("");
@@ -232,7 +308,50 @@ function main() {
232
308
  );
233
309
  log("");
234
310
 
235
- // 8. summary
311
+ // 7b. .claude/references/ → shared source of truth for review/test (read by both commands & agents)
312
+ log(`${c.bold}References${c.reset} → .claude/references/ ${c.dim}(shared standards for commands + agents)${c.reset}`);
313
+ copyDir(join(KIT_ROOT, "references"), join(claudeDir, "references"), cwd);
314
+ log("");
315
+
316
+ // 8. .claude/skills/ → model-invoked skills (auto-applied by Claude, no command needed)
317
+ log(`${c.bold}Skills${c.reset} → .claude/skills/ ${c.dim}(auto-applied by Claude — no command needed)${c.reset}`);
318
+ const skillsDir = join(claudeDir, "skills");
319
+ const kitSkillsDir = join(KIT_ROOT, "skills");
320
+
321
+ // Static skills: copy each folder wholesale (preserves templates/ and references/ subfiles).
322
+ // angular-practices is the only generated one (needs profile injection) — handled below.
323
+ for (const skill of readdirSync(kitSkillsDir)) {
324
+ if (skill === "angular-practices") continue;
325
+ const src = join(kitSkillsDir, skill);
326
+ if (!statSync(src).isDirectory()) continue;
327
+ copyDir(src, join(skillsDir, skill), cwd);
328
+ }
329
+
330
+ // angular-practices: generated — inject the matched profile filename + label
331
+ const apTemplate = join(kitSkillsDir, "angular-practices", "SKILL.md");
332
+ if (existsSync(apTemplate)) {
333
+ const body = readFileSync(apTemplate, "utf8")
334
+ .replace(/\{\{PRACTICE_FILE\}\}/g, practice)
335
+ .replace(/\{\{NG_PROFILE_LABEL\}\}/g, profileLabel(practice));
336
+ writeOne(body, join(skillsDir, "angular-practices", "SKILL.md"), cwd);
337
+ } else {
338
+ err(`skill template missing in kit: angular-practices/SKILL.md`);
339
+ }
340
+ log("");
341
+
342
+ // 9. .claude/agents/ → Angular-specialized subagents (isolated context, run in parallel)
343
+ log(`${c.bold}Agents${c.reset} → .claude/agents/ ${c.dim}(isolated context — dispatch to run in background/parallel)${c.reset}`);
344
+ copyDir(join(KIT_ROOT, "agents"), join(claudeDir, "agents"), cwd);
345
+ log("");
346
+
347
+ // 10. .claude/settings.json → permission allowlist + Stop-hook build verify
348
+ log(`${c.bold}Settings${c.reset} → .claude/settings.json ${c.dim}(allowlist + build verify)${c.reset}`);
349
+ const { settings, buildCmd } = buildSettings(cwd);
350
+ if (!buildCmd) warn("no package.json found — writing permissions only (no build-verify hook)");
351
+ writeOne(JSON.stringify(settings, null, 2) + "\n", join(claudeDir, "settings.json"), cwd);
352
+ log("");
353
+
354
+ // 11. summary
236
355
  log(`${c.bold}Done.${c.reset} ${copied} file(s) created, ${skipped} skipped.`);
237
356
  if (skipped > 0 && !flags.force) log(`${c.dim}Re-run with --force to overwrite skipped files.${c.reset}`);
238
357
  log("");
@@ -240,6 +359,13 @@ function main() {
240
359
  log(` 1. Open this project in ${c.cyan}Claude Code${c.reset}.`);
241
360
  log(` 2. Run ${c.cyan}/init${c.reset} — it will scan your codebase and fill in all the docs.`);
242
361
  log(` 3. Each session: ${c.cyan}/start${c.reset} → work → ${c.cyan}/update-status${c.reset}.`);
362
+ log("");
363
+ log(`${c.dim}Skills in .claude/skills/ apply automatically when you write or review`);
364
+ log(`Angular code — no command needed to trigger them.`);
365
+ log(`Agents in .claude/agents/ run in an isolated context — ask Claude to use one`);
366
+ log(`(e.g. "use angular-build-fixer to fix this build error"), even in the background.`);
367
+ log(`settings.json pre-allows ng/npm/pnpm/yarn/git-read (fewer prompts) and type-checks`);
368
+ log(`at turn end only when .ts/.html changed. Remove its "hooks" block to disable.${c.reset}`);
243
369
  }
244
370
 
245
371
  main();
@@ -5,6 +5,11 @@ This is an ORCHESTRATOR. It chains the other commands' logic, but it is NOT
5
5
  fully autonomous: after every phase it STOPS at a gate and waits for your
6
6
  explicit confirmation before continuing.
7
7
 
8
+ Angular idioms depend on the project version — read `.claude/angular-practices/` and follow it.
9
+ **Precedence** (see `.claude/rules/project-rules.md` → Precedence): a valid project convention wins
10
+ over the BP profile; the profile applies only where the project has no convention or is below
11
+ standard (new code only); legacy modules are never refactored.
12
+
8
13
  ---
9
14
 
10
15
  ## THE GATE RULE (applies after EVERY phase — non-negotiable)
@@ -26,28 +31,50 @@ Never skip a gate. Never batch multiple phases past a gate. The user is always i
26
31
  ## Phase 0 — Kickoff
27
32
 
28
33
  1. Read context:
29
- - `.claude/rules/project-rules.md`
34
+ - `CLAUDE.md`
35
+ - `.claude/rules/project-rules.md` → naming, structure, Coexistence, **Reference Examples**
30
36
  - `docs/ARCHITECTURE.md`
31
37
  - `docs/API_CONTRACT.md`
32
- - `docs/DESIGN_SYSTEM.md`
38
+ - `docs/DESIGN_SYSTEM.md` → shared components + Wrapped Components table
33
39
  - `.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.
40
+ - **`docs/plans/`** if a plan for this feature exists, read it in full; it is the source of
41
+ truth for scope, File Map, and task Interfaces (written by `/plan` per
42
+ `.claude/references/plan-spec.md`)
43
+ - **Open the Reference Example files** listed in `project-rules.md` (best existing service / page /
44
+ component / spec) and mirror their style — the strongest signal for matching real conventions
45
+ 2. Establish the feature:
46
+ - **If a plan was found** → the name and scope come from the plan's Goal. Do NOT re-ask them;
47
+ just confirm: **"Found plan `docs/plans/<file>` — follow it? (yes / no)"**.
48
+ - **If no plan** → ask ONE question: **"What is the feature name and what does it do?"** (name +
49
+ one sentence). If anything else about scope is unclear, ask it in the same batch — don't guess.
50
+ When the feature looks large (several screens or endpoints), add one line:
51
+ *"This looks sizeable — consider running `/plan` first for a reviewed task breakdown."* — then
52
+ continue anyway if the user wants to.
53
+ 3. **GATE:** Wait for the answer / confirmation. Write no code until you have it.
36
54
 
37
55
  ---
38
56
 
39
57
  ## Phase 1 — Scaffold
40
58
 
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).
59
+ 1. Create the full folder + empty-file structure. **If a plan was found in Phase 0, create exactly
60
+ the files in the plan's File Map** (it already reflects the project's real layout). Otherwise
61
+ follow `.claude/references/feature-structure.md` → Folder Structure, using the project's actual
62
+ layout and folder names from `project-rules.md` (the reference file's tree is only the default shape).
43
63
  2. Print the created file tree.
44
64
  3. **GATE:** "✅ Folder structure OK? Continue to Phase 2 (Model + Service)? (yes / no)"
45
65
 
46
66
  ---
47
67
 
68
+ > Follow `.claude/references/feature-structure.md` → Coding Rules throughout Phase 2a and 2b
69
+ > (`OnPush`, subscription teardown per profile, no `any`, project's forms approach, no hardcoded
70
+ > URLs, wrapper priority — never import a raw UI-library component when a wrapper exists).
71
+
72
+ > If a plan was found in Phase 0, implement each piece from its tasks: use the exact model/DTO
73
+ > shapes and service signatures declared in the tasks' `Interfaces: Consumes/Produces` blocks.
74
+
48
75
  ## Phase 2a — Implement Model + Service
49
76
 
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`).
77
+ 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`), matching the plan's declared types if a plan exists.
51
78
  2. Write `services/{feature}.service.ts` — data-access methods returning `Observable<T>` typed with the project's response shape,
52
79
  following the DI/idiom of the version profile.
53
80
  3. Print the two files.
@@ -68,10 +95,14 @@ Never skip a gate. Never batch multiple phases past a gate. The user is always i
68
95
 
69
96
  ## Phase 3 — Tests + Context
70
97
 
71
- 1. Write tests following `/write-tests`:
98
+ 1. **Verify the build first**: `ng build` / `npx tsc --noEmit` and `ng lint`. Fix any failure
99
+ immediately — a broken build makes test results meaningless, and this must not slip through to
100
+ Phase 4 or the commit in Phase 5.
101
+ 2. Write tests by dispatching the **`angular-test-writer`** agent (isolated — it follows
102
+ `.claude/references/test-spec.md`), or run `/write-tests` inline:
72
103
  - `{feature}.service.spec.ts` (mock HttpClient: success + error + empty per method)
73
104
  - `{feature}-list.component.spec.ts` (mock service: render + interaction + loading + error)
74
- 2. **Harness loop — tests (automated within this phase, max 3 rounds):**
105
+ 3. **Harness loop — tests (automated within this phase, max 3 rounds):**
75
106
  ```
76
107
  round = 1
77
108
  while round <= 3:
@@ -84,14 +115,15 @@ Never skip a gate. Never batch multiple phases past a gate. The user is always i
84
115
  GATE: "❌ Tests still failing after 3 rounds. Exiting cycle — handle manually."
85
116
  → exit the automated cycle
86
117
  ```
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)"
118
+ 4. After tests pass, write the feature's `CONTEXT.md` in the same folder created in Phase 1 (per `/write-context`).
119
+ 5. **GATE:** "✅ Build/lint clean + tests pass (round {n}) + CONTEXT.md written. Continue to Phase 4 (Review)? (yes / no)"
89
120
 
90
121
  ---
91
122
 
92
123
  ## Phase 4 — Review + Harness
93
124
 
94
- 1. Run the full `/review-pr` checklist (all 8 categories).
125
+ 1. Review by dispatching the **`angular-reviewer`** agent (isolated), or run `/review-pr` inline
126
+ both apply `.claude/references/review-checklist.md` (all dimensions).
95
127
  2. Print the result: count of 🔴 blockers, 🟡 suggestions, 🟢 good parts.
96
128
  3. If 0 blockers → skip the loop, go straight to the Phase 4 gate.
97
129
  4. If there are blockers:
package/commands/init.md CHANGED
@@ -48,8 +48,12 @@ The version-matched best-practice file is in `.claude/angular-practices/`
48
48
  4. **Find the best-example files** — the most complete, idiomatic feature to use as a
49
49
  reference template. Pick the best example for each of: a service, a smart/page
50
50
  component, a dumb component, a test spec. Verify each path exists.
51
- 5. Classify each finding: `standard` / `below-standard` / `uncertain`.
52
- 6. Print a short findings summary (3–5 lines) + the chosen best-example files.
51
+ 5. **Detect the commit convention** — run `git log --oneline -50` (skip if no git history) and infer:
52
+ - **Prefix**: a consistent leading token before the type (e.g. `VIVAS_feat(...)` prefix `VIVAS_`); none if not present.
53
+ - **Language**: the language of commit subjects (`vi` / `en`).
54
+ - **Scope source**: the folder level scopes come from (e.g. `src/app/features/<scope>` or `src/app/modules/<scope>`), based on the detected Folder Structure.
55
+ 6. Classify each finding: `standard` / `below-standard` / `uncertain`.
56
+ 7. Print a short findings summary (3–5 lines) + the chosen best-example files.
53
57
 
54
58
  ## Stage 1: Ask ALL Open Questions at Once
55
59
  1. Gather every `uncertain` item across ALL seven files into a single list
@@ -58,6 +62,8 @@ The version-matched best-practice file is in `.claude/angular-practices/`
58
62
  - **Wrapper auto-detection**: if wrappers were detected in Stage 0, confirm for each:
59
63
  (a) which library component it wraps, (b) custom additions, (c) is it required (BLOCKER) or preferred (SUGGESTION).
60
64
  Default if team does not answer: treat as SUGGESTION.
65
+ - **Commit convention**: if the prefix or language is ambiguous from `git log`, confirm them
66
+ (default: no prefix, language vi).
61
67
  2. Ask them as ONE grouped batch of multiple-choice questions.
62
68
  3. **WAIT** for the answers. Do not write any file until the batch is answered.
63
69
  4. If nothing is uncertain, say so and proceed directly to Stage 2.
@@ -69,7 +75,7 @@ placeholder with real content. Do NOT stop between files.
69
75
  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.
70
76
  2. **docs/API_CONTRACT.md** — infer from existing `*.service.ts` calls; map endpoints → service methods → TypeScript interfaces. Mark gaps.
71
77
  3. **docs/ARCHITECTURE.md** — actual layer structure, routing/lazy-loading, state approach, HTTP/interceptor flow, auth strategy. Full detail here (not in CLAUDE.md).
72
- 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).
78
+ 4. **.claude/rules/project-rules.md** — tech stack, naming, coding rules (actionable, not prose). Include the `## Precedence` section, the `## Commit Convention` section (prefix / language / scope source detected in Stage 0 — default prefix none, language vi), the `## Reference Examples` section (best-example files from Stage 0 — paths that exist only), and the `## Coexistence Strategy` section (see below).
73
79
  5. **docs/PROJECT-STATUS.md** — snapshot: what exists, in progress, known issues, next tasks. Session counter = 1.
74
80
  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), AND the **Wrapped Components** table (filled from Stage 0 detection, confirmed in Stage 1). If no wrappers found, OMIT the Wrapped Components section and add: `> This project uses UI library components directly — no shared wrappers.`
75
81
  7. **docs/decisions/** — one ADR per real decision confirmed (e.g. `001-state-management.md`, `002-auth-token-storage.md`). Only for actual decisions.
@@ -11,60 +11,39 @@ has no convention or is below standard (new code only); legacy modules are never
11
11
  - Read `docs/ARCHITECTURE.md` → where this feature fits
12
12
  - Read `docs/API_CONTRACT.md` → which endpoints this feature calls
13
13
  - Read `docs/DESIGN_SYSTEM.md` → shared components to use, **AND the Wrapped Components table → which wrapper to use for each UI library primitive** (e.g. for a dropdown, use `<app-select>` not `p-dropdown`)
14
+ - Check `docs/plans/` → **if a plan for this feature exists** (written by `/plan`), it is the source
15
+ of truth for scope, File Map, and task Interfaces — follow it for Steps 2 and 3. If the feature is
16
+ large and no plan exists, suggest running `/plan` first, then continue if I want to.
14
17
  - **Open the Reference Example files** listed in `project-rules.md` (best existing service / page / component / spec) and mirror their style — this is the strongest signal for matching the project's real conventions
15
18
  - Ask me if anything is unclear before writing code
16
19
 
17
20
  ## Step 2: Create Feature Structure
18
-
19
- > **Use the project's actual layout and folder names from `project-rules.md`.**
20
- > The tree below is only the DEFAULT shape if the project calls things differently
21
- > (e.g. `containers/` instead of `pages/`, `ui/` or `common/` instead of `shared/`,
22
- > an Nx `libs/` layout, or NgModule-based folders), follow the project, not this tree.
23
-
24
- ```
25
- {features-dir}/{feature-name}/ # e.g. features/, modules/, or an Nx lib
26
- ├── {feature}.routes.ts
27
- ├── models/
28
- │ └── {feature}.model.ts # Interfaces mirroring the backend response shape
29
- ├── services/
30
- │ └── {feature}.service.ts # All data-access calls
31
- ├── pages/ # Smart (container) componentsproject may call these containers/
32
- │ ├── {feature}-list/
33
- │ │ ├── {feature}-list.component.ts
34
- │ │ ├── {feature}-list.component.html
35
- │ │ └── {feature}-list.component.scss
36
- │ └── {feature}-detail/
37
- └── components/ # Dumb (presentational) components
38
- └── {feature}-form/
39
- ```
40
-
41
- ## Step 3: Implement in This Order
42
- 1. **Model** — interfaces for entity, request/response, mirroring the backend's actual DTOs / response shape (per `project-rules.md` — envelope, raw DTO, or GraphQL type)
43
- 2. **Service** — data-access methods returning `Observable<T>` typed with the project's response shape (HttpClient, or the project's client if it uses Apollo/another)
44
- 3. **Routes** — lazy-loaded, guard-protected where needed
45
- 4. **Page components (smart)** — data, loading/error/empty states
46
- 5. **Presentational components (dumb)** — inputs/outputs only, no data access
47
-
48
- ## Step 4: Write Tests (see /write-tests)
21
+ If a plan was found in Step 1, create exactly the files in its File Map. Otherwise follow
22
+ `.claude/references/feature-structure.md` → Folder Structure. **Always use the project's
23
+ actual layout and folder names from `project-rules.md`** the reference file's tree is only the
24
+ default shape (e.g. the project may use `containers/` instead of `pages/`, an Nx `libs/` layout, etc.).
25
+
26
+ ## Step 3: Implement
27
+ Follow `.claude/references/feature-structure.md` for both **Implementation Order** (Model → Service →
28
+ Routes Page components Presentational components) and **Coding Rules** (data access in services
29
+ only, `OnPush`, subscription teardown, no `any`, project's forms approach, no hardcoded URLs, wrapper
30
+ priority) — apply the rules AS you write each piece, not as an afterthought. If a plan was found, use
31
+ the exact model/DTO shapes and service signatures from its tasks' `Interfaces` blocks.
32
+
33
+ ## Step 4: Write Tests
34
+ Dispatch the **`angular-test-writer`** agent (isolated contextit follows
35
+ `.claude/references/test-spec.md`), or run `/write-tests` inline for a small feature. Either way:
49
36
  - Service: mock HttpClient, test success + error + empty per method
50
37
  - Component: mock service, test render + interaction + loading + error states
51
38
 
52
- ## Step 5: Rules (from .claude/rules/project-rules.md + .claude/angular-practices/)
53
- - Data access ONLY in services — never in components
54
- - `ChangeDetectionStrategy.OnPush` on every component
55
- - Tear down subscriptions per profile: `takeUntilDestroyed` (v16+) or `takeUntil(destroy$)` + `ngOnDestroy` (v12–15)
56
- - No `any` — interfaces/types for every model and response
57
- - Use the project's forms approach from `project-rules.md` (Reactive Forms by default; Formly / template-driven if that's what the project uses)
58
- - No hardcoded backend URL — use `environment`
59
- - **Wrapper priority**: import from `@shared/components/<name>` (or the project's wrapper folder) if a wrapper exists; never import the library component directly. See `docs/DESIGN_SYSTEM.md` → Wrapped Components.
60
-
61
- ## Step 6: Update Documentation
39
+ ## Step 5: Update Documentation
62
40
  - `docs/API_CONTRACT.md` if you used/discovered endpoints
63
41
  - Create `CONTEXT.md` inside the feature folder (use /write-context)
64
42
  - `docs/PROJECT-STATUS.md` (use /update-status)
65
43
 
66
- ## Step 7: Verify
44
+ ## Step 6: Verify
67
45
  - Build passes: `ng build` / `npx tsc --noEmit`
68
46
  - All tests pass: `ng test` / `jest`
69
47
  - Lint passes: `ng lint`
70
- - Review with /review-pr before committing
48
+ - Review before committing: dispatch the **`angular-reviewer`** agent (applies
49
+ `.claude/references/review-checklist.md` in an isolated context), or run `/review-pr` inline
@@ -0,0 +1,136 @@
1
+ Plan a feature before writing any code: clarify the requirement, weigh approaches, agree on a
2
+ design, then write a detailed, task-by-task implementation plan to `docs/plans/`.
3
+
4
+ This command produces a PLAN, not code. It writes exactly one file — the plan document — and
5
+ nothing else. `/dev-cycle` (gated, recommended) or `/new-feature` (linear) then execute it.
6
+
7
+ Angular idioms depend on the project version — the plan defers to `.claude/angular-practices/` and
8
+ to the **Precedence** rule in `.claude/rules/project-rules.md` (a valid project convention wins over
9
+ the BP profile; the profile applies only where the project has no convention or is below standard,
10
+ new code only; legacy modules are never refactored).
11
+
12
+ ## Running under Claude Code's Plan Mode
13
+
14
+ If this session is in **Plan Mode** (you were given a plan-mode file path and told to use
15
+ `ExitPlanMode` for approval), `Write`/`Edit` are restricted to that one file — you cannot write
16
+ `docs/plans/<feature>.md` directly until Plan Mode ends. In that case:
17
+ - Phases A–D run exactly as written below (they are read-only or pure conversation).
18
+ - Phase D's GATE is skipped as a separate yes/no — approval happens via `ExitPlanMode` instead (see
19
+ Phase E's Plan Mode branch).
20
+ - Phase E branches: compose + self-review the plan first, write it into the Plan Mode file, call
21
+ `ExitPlanMode`, and only after the user approves (Plan Mode ends) write the real
22
+ `docs/plans/<feature>.md` — same content, now at its real path.
23
+
24
+ If this session is NOT in Plan Mode, ignore this section — run every phase as written, gates
25
+ included.
26
+
27
+ ---
28
+
29
+ ## THE GATE RULE (applies after Phases B, C, D — non-negotiable)
30
+
31
+ After a gated phase you MUST:
32
+ 1. Print a short summary of what was decided.
33
+ 2. Ask the gate question exactly as written for that phase.
34
+ 3. Then WAIT. Do not proceed on silence or assumption.
35
+ 4. If the user approves → continue to the next phase.
36
+ 5. If the user asks for changes → revise in place and re-ask the same gate. Do not skip ahead.
37
+
38
+ Write NO code and scaffold NOTHING in any phase. The only file this command creates is the plan doc.
39
+
40
+ ---
41
+
42
+ ## Phase A — Context (no gate)
43
+
44
+ Read, in this order:
45
+ - `CLAUDE.md`
46
+ - `.claude/rules/project-rules.md` → Precedence, naming, structure, Coexistence, **Reference Examples**
47
+ - `docs/ARCHITECTURE.md` → where this feature fits
48
+ - `docs/API_CONTRACT.md` → endpoints + payload shapes this feature will touch
49
+ - `docs/DESIGN_SYSTEM.md` → shared components + **Wrapped Components table**
50
+ - `.claude/angular-practices/` → the version profile
51
+ - **Open the Reference Example files** listed in `project-rules.md` (best existing service / page /
52
+ component / spec) — the plan's file shapes and interfaces should mirror them.
53
+
54
+ ---
55
+
56
+ ## Phase B — Clarify the requirement
57
+
58
+ 1. **Scope check first.** If the request describes several independent subsystems (e.g. "a portal
59
+ with orders, chat, billing, and reports"), STOP and propose splitting it: name the independent
60
+ pieces and suggest one plan per piece. Brainstorm the first piece here; the rest get their own
61
+ `/plan` runs later. Do not spend questions on a feature that needs decomposition first.
62
+ 2. For an appropriately-scoped feature, ask the clarifying questions you need — purpose,
63
+ constraints, success criteria, edge cases, which endpoints/screens are in scope.
64
+ - **Batch them** (ask all open questions in one message, like `/init` Stage 1). Do not drip one
65
+ question per message.
66
+ - Prefer multiple-choice / yes-no phrasing where possible.
67
+ - Don't ask what the docs already answer — pull it from Phase A instead.
68
+ 3. **Adaptive follow-up:** if an answer reveals a new ambiguity you didn't anticipate (e.g. the user
69
+ mentions a status field that implies a workflow you need to understand), ask that **one**
70
+ follow-up question before the gate — don't silently guess, and don't revert to asking every
71
+ remaining question one at a time.
72
+ 4. **GATE:** "✅ Requirements clear? (yes / add more)" — WAIT for answers. Write nothing until you
73
+ have them.
74
+
75
+ ---
76
+
77
+ ## Phase C — Approaches
78
+
79
+ 1. Propose **2-3 approaches** with trade-offs (e.g. one feature service vs. split by concern;
80
+ reuse an existing service's pagination vs. a new one; smart/dumb split granularity).
81
+ 2. Lead with your **recommendation and why**, framed against this project's conventions and version
82
+ idioms — not generic advice.
83
+ 3. **GATE:** "✅ Which approach? (1 / 2 / 3 / other)" — WAIT.
84
+
85
+ ---
86
+
87
+ ## Phase D — Design
88
+
89
+ 1. Present the design in short sections, each scaled to its complexity (a few sentences each, more
90
+ only if nuanced): architecture & where it sits, data flow, components (smart/dumb split),
91
+ error/loading/empty handling, testing scope.
92
+ 2. Note explicitly which **shared wrappers** the UI will use (from the Wrapped Components table) and
93
+ which **endpoints** from `API_CONTRACT.md` it consumes.
94
+ 3. **GATE (skip if in Plan Mode — see below):** "✅ Design OK? Write the plan? (yes / revise)" — WAIT.
95
+ There is no separate design file — once approved, the design goes straight into the plan header.
96
+ **If in Plan Mode**, don't ask this separately — go straight to Phase E; `ExitPlanMode` there is
97
+ the approval.
98
+
99
+ ---
100
+
101
+ ## Phase E — Write the plan
102
+
103
+ 1. Determine today's date and the feature name → target path
104
+ `docs/plans/YYYY-MM-DD-<feature-name>.md`.
105
+ 2. Compose the plan content **strictly following `.claude/references/plan-spec.md`**: header (Goal /
106
+ Architecture / Approach chosen / Global Constraints), File Map, then tasks in Implementation
107
+ Order (Model → Service → Routes → Pages → Components → Tests), each with `Files:`,
108
+ `Interfaces: Consumes/Produces`, and concrete steps with real code — **no placeholders**.
109
+ 3. Run the **Self-Review checklist** from `plan-spec.md` (requirement coverage, placeholder scan,
110
+ type consistency vs. `API_CONTRACT.md`, wrapper check, layout check). Fix issues inline. Do this
111
+ BEFORE anything gets written below — either route commits the reviewed version.
112
+
113
+ **Not in Plan Mode:**
114
+ 4. Create `docs/plans/` if it doesn't exist, write the reviewed content to the target path. Done.
115
+
116
+ **In Plan Mode:**
117
+ 4. Write the reviewed content to the Plan Mode file (the one path you're currently allowed to
118
+ write). This is the plan the user will see when reviewing.
119
+ 5. Call `ExitPlanMode`. This IS the approval gate for Phases D and E — do not also ask the Phase D
120
+ text gate.
121
+ 6. Once the user approves and Plan Mode ends, immediately — before doing anything else — create
122
+ `docs/plans/` if needed and write the **same reviewed content** to
123
+ `docs/plans/YYYY-MM-DD-<feature-name>.md`. This is the real deliverable; the Plan Mode file was
124
+ only the approval copy.
125
+
126
+ ---
127
+
128
+ ## Phase F — Handoff
129
+
130
+ Once `docs/plans/<file>.md` exists for real (directly from Phase E, or after the Plan Mode
131
+ approval + follow-up write), print:
132
+ > ✅ Plan saved to `docs/plans/<file>` — <N> tasks. I ran the self-review and fixed: <list, or "no
133
+ > issues">. Review it, then run **`/dev-cycle`** (gated, recommended) or **`/new-feature`** (linear)
134
+ > — both will detect and follow this plan.
135
+
136
+ Do not start implementing. The user reviews the plan first.
@@ -1,71 +1,12 @@
1
- Review the code changes in this PR. Check every item — flag violations clearly.
2
-
3
- Read `.claude/angular-practices/` for version-correct idioms, and
4
- `.claude/rules/project-rules.md` for project-specific rules.
5
-
6
- **Precedence (see `project-rules.md` Precedence):** a valid project convention wins over
7
- the BP profile; flag a BP deviation as a blocker only when it's an objective defect in NEW
8
- code. Do NOT flag legacy modules listed in the Coexistence Strategy they are kept as-is.
9
- Do NOT flag a valid project choice (naming, structure, state lib, response shape) just
10
- because it differs from the profile.
11
-
12
- ## Architecture
13
- - [ ] Smart / dumb separation: pages own data; presentational components only render + emit
14
- - [ ] HTTP calls ONLY in services — never in components
15
- - [ ] No business logic in templates
16
- - [ ] Feature routes are lazy-loaded
17
-
18
- ## Type Safety
19
- - [ ] No `any` — interfaces/types for every model and API response
20
- - [ ] Responses typed with the project's response shape recorded in `project-rules.md` (e.g. an `ApiResponse<T>` envelope, a raw DTO, or a GraphQL type — whatever the backend actually returns)
21
- - [ ] No `@ts-ignore` / `@ts-expect-error`
22
-
23
- ## Dependency Injection (follow `.claude/angular-practices/`)
24
- - [ ] DI matches the profile: `inject()` (v16+) or constructor injection (v12–15) — consistent across the project
25
- - [ ] Services `@Injectable({ providedIn: 'root' })`
26
-
27
- ## Reactive / RxJS / Signals (follow `.claude/angular-practices/`)
28
- - [ ] Subscriptions torn down: `takeUntilDestroyed` (v16+) or `takeUntil(destroy$)` + `ngOnDestroy` (v12–15)
29
- - [ ] `async` pipe preferred over manual subscribe
30
- - [ ] No `toPromise()` — use `firstValueFrom()` if needed
31
- - [ ] Services return `Observable<T>` — do NOT subscribe internally
32
- - [ ] Signals used per profile: stable for state (v16+); derived state via `computed()`. `resource`/`httpResource` are experimental (v19+) — only if the team opted in
33
-
34
- ## Error Handling
35
- - [ ] Loading / error / empty states handled in list/detail pages
36
- - [ ] HTTP errors surfaced to user (not swallowed)
37
- - [ ] Auth errors (e.g. 401) handled centrally by an interceptor — not per-feature
38
-
39
- ## Security
40
- - [ ] Auth handled per the project's model in `project-rules.md` (token in memory / httpOnly cookie / session / OAuth) — and consistent with it. If tokens are used, they are NOT in localStorage
41
- - [ ] No hardcoded backend URL — uses `environment`
42
- - [ ] Routes needing auth are guarded
43
- - [ ] No unsanitized HTML (`innerHTML` / `bypassSecurityTrust*`) without a clear, reviewed reason
44
-
45
- ## Performance
46
- - [ ] `ChangeDetectionStrategy.OnPush` on every component (or zoneless on v20+ if enabled)
47
- - [ ] List tracking present: `@for` with `track` (v17+) or `*ngFor` with `trackBy` (v12–16)
48
-
49
- ## Code Quality
50
- - [ ] Component file < ~300 lines; method < ~50 lines
51
- - [ ] No dead code, no `console.log`
52
- - [ ] Naming follows `.claude/rules/project-rules.md`
53
-
54
- ## Component Wrapping (follow `docs/DESIGN_SYSTEM.md` → Wrapped Components)
55
- - [ ] No feature imports a raw UI library component (`p-dropdown`, `mat-form-field`, `nz-input`, etc.) when a wrapper exists in `shared/components/`
56
- - [ ] All UI primitive imports go through the project's wrapper (check the import path matches the wrapper's location)
57
- - [ ] If a wrapper exists for the need but the PR uses the library directly → 🔴 BLOCKER
58
- - [ ] If no wrapper exists and the library is used directly → 🟡 SUGGESTION: "Consider creating a wrapper in `shared/components/` for consistency"
59
- - [ ] New components do NOT silently re-implement logic an existing wrapper already provides
60
- - [ ] If a brand-new wrapper is introduced → verify it follows the Wrapper Reference Example from `project-rules.md`
61
-
62
- ## Documentation
63
- - [ ] New feature: `CONTEXT.md` created inside feature folder
64
- - [ ] Logic changed: `CONTEXT.md` Refactor Log updated (append only)
65
- - [ ] Endpoint changed: `docs/API_CONTRACT.md` updated
66
- - [ ] `docs/PROJECT-STATUS.md` updated
67
-
68
- ## Summary
69
- 1. **Blockers** 🔴 — must fix before merge
70
- 2. **Suggestions** 🟡 — improve but not blocking
71
- 3. **Good parts** 🟢 — what was done well
1
+ Review the current code changes against this project's Angular standards.
2
+
3
+ 1. Get the diff: run `git diff` (unstaged) and `git diff --staged`, or `git diff <base>...HEAD` if a
4
+ base branch is named. Review only the changed code.
5
+ 2. Apply the full checklist in `.claude/references/review-checklist.md` — it defines the review
6
+ dimensions, the Precedence rule (a valid project convention wins; don't flag legacy), and the
7
+ 🔴/🟡/🟢 output format. That file is the single source of truth for what "correct" means here.
8
+ 3. Output the report **inline** in this conversation using the format from the checklist. If there are
9
+ no blockers, say so explicitly.
10
+
11
+ > For a large diff, or to review in the background while you keep coding, dispatch the
12
+ > `angular-reviewer` agent instead — it applies the same checklist in an isolated context.