@tungvivas/angular-vibe-kit 0.1.0 → 0.2.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 CHANGED
@@ -18,7 +18,8 @@ and keeps the AI honest with version-correct Angular rules (v14 → v19).
18
18
 
19
19
  It also handles the real-world case: **the project isn't fully best-practice yet.**
20
20
  The kit adds correct rules for *new* code without forcing risky refactors on legacy
21
- modules (Strangler Fig).
21
+ modules (Strangler Fig). And when the project wraps its UI library in `shared/components/`,
22
+ the kit teaches the AI to always use the wrapper, not the raw library import.
22
23
 
23
24
  ---
24
25
 
@@ -104,6 +105,25 @@ Anything uncertain becomes a question — the kit never silently rewrites your r
104
105
 
105
106
  ---
106
107
 
108
+ ## Component Wrapping (generic UI convention)
109
+
110
+ The kit enforces a generic priority rule for UI components:
111
+
112
+ 1. **Wrapper in `shared/components/`** (or `ui/`, `common/`, etc.) — used if it exists for the need
113
+ 2. **UI library direct** — used only if no wrapper exists; warning logged
114
+ 3. **Custom build** — only when the library has no equivalent
115
+
116
+ When you run `/init`, it scans your codebase for wrapper components (sub-folders
117
+ of `shared/components/` that import a known UI library) and writes a
118
+ **Wrapped Components** table into `docs/DESIGN_SYSTEM.md`. From then on:
119
+ - `/new-feature` consults that table when generating UI code
120
+ - `/review-pr` flags a wrapper-bypass as 🔴 BLOCKER in new code
121
+ - `/write-context` captures the WHY behind any library-direct decisions
122
+
123
+ Works for any UI library — PrimeNG, Material, ng-zorro, ng-bootstrap, custom.
124
+
125
+ ---
126
+
107
127
  ## What gets created in your project
108
128
 
109
129
  ```
package/commands/init.md CHANGED
@@ -25,7 +25,8 @@ The version-matched best-practice file is in `.claude/angular-practices/`
25
25
 
26
26
  ## Stage 0: Scan (read-only, no output yet)
27
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.
28
+ 2. Read `package.json` → Angular version, **UI library (auto-detect from dependencies)**, test runner, state libs.
29
+ - **UI library detection**: scan `dependencies` and `devDependencies` for known third-party UI packages. Examples include but are NOT limited to: `primeng`, `@angular/material`, `@angular/cdk`, `ng-zorro-antd`, `@ng-bootstrap/*`, `ngx-bootstrap`, `@clr/angular`, `@progress/kendo-angular-*`, `@ionic/angular`, `@nebular/*`, `element-angular`, `@spike-rabbit/element-angular`, `flowbite-angular`, or any package whose name suggests a UI/design system. **Record all matches** — the project may use more than one. **Do NOT hardcode a fixed list** — infer from what is actually installed.
29
30
  3. Scan `src/`:
30
31
  - Module system: standalone vs NgModule
31
32
  - State: NgRx / Signals / BehaviorSubject / plain service
@@ -33,6 +34,17 @@ The version-matched best-practice file is in `.claude/angular-practices/`
33
34
  - HTTP pattern: HttpClient in services vs components
34
35
  - Interceptors, guards, auth flow, token handling
35
36
  - Test setup, shared components, UI library usage
37
+ - **Wrapped components detection** (library-agnostic — works for any UI library the project actually uses):
38
+ - Use the UI library list detected from `package.json` in Step 2 (NOT a hardcoded list)
39
+ - Enumerate the project's shared component folder (e.g. `shared/components/`, `ui/`, `common/`, `components/` — record the actual folder name)
40
+ - For each sub-folder, look for:
41
+ - A `*.component.ts` file with a `@Component` decorator
42
+ - A TypeScript `import` statement that matches one of the detected UI library packages
43
+ (e.g. if `primeng` is in deps → look for `from 'primeng/...'`; if `@clr/angular` is in deps → look for `from '@clr/angular'`)
44
+ - A simple `value`/`valueChange` input-output pair suggesting it wraps a single primitive
45
+ - Exclude framework imports from the match list: `@angular/core`, `@angular/common`, `@angular/router`, `@angular/forms`, `@angular/animations`, `@angular/platform-browser*`, `rxjs`, `@ngrx/*`, `zone.js`, `tslib` (these are NOT UI library imports)
46
+ - Record each candidate as `wrapper {name} → library {detected_package}/{imported_module}` for Stage 2 table generation
47
+ - Pick one as "Wrapper Reference Example" (simplest API + most reused) and record the path for `project-rules.md` Reference Examples table
36
48
  4. **Find the best-example files** — the most complete, idiomatic feature to use as a
37
49
  reference template. Pick the best example for each of: a service, a smart/page
38
50
  component, a dumb component, a test spec. Verify each path exists.
@@ -43,6 +55,9 @@ The version-matched best-practice file is in `.claude/angular-practices/`
43
55
  1. Gather every `uncertain` item across ALL seven files into a single list
44
56
  (e.g. "both NgRx and Signals present — which is primary?", "response envelope shape?",
45
57
  "auth model?", "which forms approach?", "confirm this legacy do-not-touch list").
58
+ - **Wrapper auto-detection**: if wrappers were detected in Stage 0, confirm for each:
59
+ (a) which library component it wraps, (b) custom additions, (c) is it required (BLOCKER) or preferred (SUGGESTION).
60
+ Default if team does not answer: treat as SUGGESTION.
46
61
  2. Ask them as ONE grouped batch of multiple-choice questions.
47
62
  3. **WAIT** for the answers. Do not write any file until the batch is answered.
48
63
  4. If nothing is uncertain, say so and proceed directly to Stage 2.
@@ -56,7 +71,7 @@ placeholder with real content. Do NOT stop between files.
56
71
  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
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).
58
73
  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).
74
+ 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.`
60
75
  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
76
 
62
77
  ### Coexistence Strategy (inside project-rules.md)
@@ -85,7 +100,7 @@ Print a summary so I can review everything at once:
85
100
  | docs/ARCHITECTURE.md | created/updated | ... |
86
101
  | .claude/rules/project-rules.md | created/updated | precedence + coexistence + reference examples |
87
102
  | docs/PROJECT-STATUS.md | created/updated | ... |
88
- | docs/DESIGN_SYSTEM.md | created/updated | ... |
103
+ | docs/DESIGN_SYSTEM.md | created/updated | ... | + Wrapped Components table (N rows, or omitted if none) |
89
104
  | docs/decisions/00x-*.md | created | ... |
90
105
 
91
106
  **3. Questions I asked & your answers** — short list (for the record).
@@ -10,7 +10,7 @@ has no convention or is below standard (new code only); legacy modules are never
10
10
  - Read `.claude/rules/project-rules.md` → naming, structure, Coexistence rules, **Reference Examples**
11
11
  - Read `docs/ARCHITECTURE.md` → where this feature fits
12
12
  - Read `docs/API_CONTRACT.md` → which endpoints this feature calls
13
- - Read `docs/DESIGN_SYSTEM.md` → shared components to use
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
14
  - **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
15
  - Ask me if anything is unclear before writing code
16
16
 
@@ -56,6 +56,7 @@ has no convention or is below standard (new code only); legacy modules are never
56
56
  - No `any` — interfaces/types for every model and response
57
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
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.
59
60
 
60
61
  ## Step 6: Update Documentation
61
62
  - `docs/API_CONTRACT.md` if you used/discovered endpoints
@@ -51,6 +51,14 @@ because it differs from the profile.
51
51
  - [ ] No dead code, no `console.log`
52
52
  - [ ] Naming follows `.claude/rules/project-rules.md`
53
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
+
54
62
  ## Documentation
55
63
  - [ ] New feature: `CONTEXT.md` created inside feature folder
56
64
  - [ ] Logic changed: `CONTEXT.md` Refactor Log updated (append only)
@@ -45,6 +45,12 @@ Note what is local component state vs shared state.
45
45
  - **{Decision}**: {reason}
46
46
  - **{Decision}**: {reason}
47
47
 
48
+ ## Component Wrapping Decisions
49
+ - **Wrapped components used**: list the `<app-*>` components used by this feature (e.g. `<app-select>`, `<app-data-table>`)
50
+ - **Library components used directly**: list any direct library imports and the reason (e.g. `p-tree` used directly because no wrapper exists yet, and creating one is out of scope for this feature)
51
+ - **New wrappers introduced**: if this feature adds a new wrapper to `shared/components/`, list it here and link to the PR/ADR
52
+ - **Wrappers NOT used (with reason)**: if a wrapper exists for the need but you chose not to use it, document why (e.g. "wrapper doesn't support X yet — track in #123")
53
+
48
54
  ## Considered and Rejected
49
55
  - **{Option}**: rejected because {reason}
50
56
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tungvivas/angular-vibe-kit",
3
- "version": "0.1.0",
3
+ "version": "0.2.0",
4
4
  "description": "Bootstrap a Vibe Coding workflow (CLAUDE.md, project docs, slash-commands) into any Angular project. Detects your Angular version and installs version-matched best-practice rules.",
5
5
  "keywords": [
6
6
  "angular",
@@ -21,7 +21,28 @@
21
21
  | ErrorMessage | Error display |
22
22
  | ConfirmDialog | Confirmation modal |
23
23
 
24
+ ## Wrapped Components
25
+ > If this section is present and non-empty, ALWAYS prefer the wrapper over the
26
+ > raw library component. Add a row only when a shared wrapper exists.
27
+ > `/init` auto-detects these; the team confirms in Stage 1.
28
+
29
+ | Need (library component) | Use this wrapper | Custom additions | Location |
30
+ |---------------------------|------------------|------------------|----------|
31
+ | `{{p-dropdown}}` | `{{<app-select>}}` | {{Loading state, error display, label slot}} | `{{shared/components/select/}}` |
32
+ | `{{p-calendar}}` | `{{<app-date-picker>}}` | {{Min/max date, locale, disabled dates}} | `{{shared/components/date-picker/}}` |
33
+
34
+ ### Priority Order (must follow)
35
+ 1. **Wrapper in `shared/components/`** (or `ui/`, `common/`, `components/` — record actual folder) — ALWAYS use it when one exists
36
+ 2. **Library component direct** — use only when no wrapper exists; import the library type
37
+ 3. **Custom build from scratch** — only when the library has no equivalent
38
+
39
+ ### When you cannot find a wrapper
40
+ - Search the project's wrapper folder first (recorded above)
41
+ - If still unsure, ASK the team: "Có wrapper nào tôi chưa biết không?"
42
+ - NEVER silently import the library and bypass the wrapper
43
+
24
44
  ## Rules
25
45
  - Every page must handle loading / error / empty states
26
46
  - Use design tokens, not hardcoded values
27
47
  - New shared UI goes in `shared/` only if used by 2+ features
48
+ - If a wrapped component exists for a UI need, you MUST use the wrapper — never the raw library component directly
@@ -49,11 +49,19 @@ When guidance conflicts, follow this order top to bottom:
49
49
  ## Coding Rules
50
50
  > /init will generate concrete rules based on Angular version + what the project does.
51
51
 
52
+ ## Component Wrapper Priority
53
+ - ALWAYS check `docs/DESIGN_SYSTEM.md` → **Wrapped Components** before importing a UI library
54
+ - If a wrapper exists for the need → import the wrapper (e.g. `import { AppSelectComponent } from '@shared/components/select'`), NEVER the raw library (`p-dropdown`)
55
+ - If no wrapper exists → use the library directly and log a warning to the user: `> ⚠️ No wrapper for <X> — using library directly. Consider creating one in shared/components/`
56
+ - If unsure whether a wrapper exists → ASK the team before writing the import
57
+ - This rule is enforced by `/review-pr` (🔴 BLOCKER if violated in new code)
58
+
52
59
  ## DO NOT
53
60
  - Do NOT use `any`
54
61
  - Do NOT call HttpClient from components
55
62
  - Do NOT store tokens in localStorage
56
63
  - Do NOT hardcode the backend URL
64
+ - Do NOT import UI library components directly in features when a wrapper exists in `shared/components/`
57
65
 
58
66
  ## Reference Examples
59
67
  > /init fills this with the best existing files to copy patterns from.