create-claude-workspace 1.1.69 → 1.1.71

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.
@@ -47,8 +47,14 @@ nx g @nx/js:library --directory=libs/[domain]/[layer] --no-interactive
47
47
 
48
48
  **Creating components:**
49
49
  ```bash
50
+ # Each component MUST have its own subdirectory — [name] in --path is REQUIRED
50
51
  nx g @nx/angular:component --path=libs/[domain]/[layer]/src/lib/[name] --no-interactive
52
+
53
+ # Example: badge component in shared/ui library
54
+ nx g @nx/angular:component --path=libs/shared/ui/src/lib/badge --no-interactive
55
+ # Result: libs/shared/ui/src/lib/badge/badge.ts, badge.html, badge.scss
51
56
  ```
57
+ **NEVER** omit the component name from `--path`. Without it, all component files land flat in `lib/` — no subdirectory separation.
52
58
 
53
59
  **Bundler rule:** Omit `--bundler` for internal monorepo libs (no bundler needed). Only add `--bundler=esbuild|tsc|swc` for **publishable/buildable** libraries (npm packages, standalone deploys).
54
60
 
@@ -148,6 +154,53 @@ export class ProjectDetail {
148
154
  - WebSocket/SSE streams — use dedicated services
149
155
  - Non-HTTP async — use `resource()` instead
150
156
 
157
+ ## Forms — Signal Forms API
158
+
159
+ Use the **signal-based forms API** (`@angular/forms/signals`) for all form handling when available in the project's Angular version (stable or experimental). NEVER use legacy `FormControl`/`FormGroup`/`FormBuilder`/`ReactiveFormsModule`.
160
+
161
+ **Signal forms pattern:**
162
+ ```typescript
163
+ import { Component, signal } from '@angular/core';
164
+ import { form, FormField, required, email, minLength } from '@angular/forms/signals';
165
+
166
+ @Component({
167
+ imports: [FormField],
168
+ template: `
169
+ <input type="email" [formField]="loginForm.email" />
170
+ <input type="password" [formField]="loginForm.password" />
171
+ <button [disabled]="loginForm.invalid()">Submit</button>
172
+ `,
173
+ })
174
+ export class LoginForm {
175
+ readonly loginModel = signal({ email: '', password: '' });
176
+ readonly loginForm = form(this.loginModel, (schema) => {
177
+ required(schema.email);
178
+ email(schema.email);
179
+ required(schema.password);
180
+ minLength(schema.password, 8);
181
+ });
182
+
183
+ // Field state is signal-based:
184
+ // this.loginForm.email().value() — current value (signal)
185
+ // this.loginForm.email().dirty() — boolean signal
186
+ // this.loginForm.email().invalid() — boolean signal
187
+ // this.loginForm.email().value.set('new@email.com') — update programmatically
188
+ }
189
+ ```
190
+
191
+ **Key rules:**
192
+ - `form()` function with a signal model — form structure derived from model shape
193
+ - Validators from `@angular/forms/signals`: `required()`, `email()`, `minLength()`, `maxLength()`, `min()`, `max()`, `pattern()`
194
+ - Template binding via `[formField]` directive (import `FormField`)
195
+ - All field state (value, dirty, invalid, disabled) is signal-based — bind directly in templates
196
+ - No `.valueChanges` subscriptions — state is already reactive
197
+
198
+ **NEVER:**
199
+ - `new FormControl()` / `new FormGroup()` / `new FormArray()` / `FormBuilder` — use `form()` with signal model
200
+ - `ReactiveFormsModule` / `FormsModule` — use `FormField` directive from `@angular/forms/signals`
201
+ - `.valueChanges.subscribe()` — field state is already reactive via signals
202
+ - Wrapping validators in arrow functions (`control => Validators.required(control)`)
203
+
151
204
  ## Templates — MINIMAL Logic
152
205
 
153
206
  - ZERO method calls in templates — wrap in `computed()`, bind the signal
@@ -343,6 +396,8 @@ describe('CardBadge', () => {
343
396
 
344
397
  When reviewing Angular code, check:
345
398
  - Signal usage: signal/computed/input/output/model correctly used
399
+ - Forms: signal forms API used (no legacy FormControl/FormGroup/FormBuilder)
400
+ - Component file organization: each component in its own subdirectory (not flat in lib/)
346
401
  - ZERO method calls in templates — all derived state in computed()
347
402
  - Feature vs dumb separation — no inject() in ui/ components
348
403
  - Content projection (composite pattern) over deep @Input trees
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-claude-workspace",
3
- "version": "1.1.69",
3
+ "version": "1.1.71",
4
4
  "description": "Scaffold a project with Claude Code agents for autonomous AI-driven development",
5
5
  "type": "module",
6
6
  "bin": {