create-claude-workspace 1.1.75 → 1.1.77
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/dist/template/.claude/agents/backend-ts-architect.md +5 -4
- package/dist/template/.claude/profiles/angular.md +40 -4
- package/dist/template/.claude/profiles/react.md +26 -2
- package/dist/template/.claude/profiles/svelte.md +24 -1
- package/dist/template/.claude/profiles/vue.md +28 -3
- package/dist/template/.claude/templates/claude-md.md +12 -3
- package/package.json +1 -1
|
@@ -61,13 +61,14 @@ Always prefer `@cibule/*` packages over custom implementations:
|
|
|
61
61
|
- NEVER use Node.js-specific APIs (`fs`, `path`, `process`, `Buffer`) in business/domain/api layers
|
|
62
62
|
- NEVER use Cloudflare-specific APIs (`env.DB`, `ctx.waitUntil()`) in business/domain layers
|
|
63
63
|
- Platform-specific code lives ONLY in `infrastructure/` layer behind abstract repository interfaces
|
|
64
|
+
- **Platform-specific code MUST be in separate libraries** — NEVER mix Node.js and Cloudflare implementations in the same library. Barrel exports pull both platforms into the bundle, causing compilation errors (e.g. `better-sqlite3` in Cloudflare). Split into: `infrastructure-d1/` (Cloudflare) and `infrastructure-sqlite/` (Node.js). Same applies to shared providers: `shared/infrastructure-d1/` vs `shared/infrastructure-sqlite/`.
|
|
64
65
|
- Use Web Standard APIs: `fetch`, `Request`, `Response`, `URL`, `crypto`, `TextEncoder`/`TextDecoder`
|
|
65
66
|
- Hono is inherently platform-agnostic — inject platform bindings via DI, not `c.env` in routes
|
|
66
67
|
- **OpenAPI-first**: All API routes MUST use `hono-openapi` with `openAPIRouteHandler` — generates OpenAPI spec from TypeBox schemas. Serve API docs via `@scalar/hono-api-reference` at `/reference`. Never define routes without OpenAPI metadata.
|
|
67
|
-
- Entry points handle platform wiring:
|
|
68
|
-
- Worker entry: exports `default { fetch }` with Hono app + D1 bindings
|
|
69
|
-
- Node entry: `serve()` with Hono app + SQLite/better-sqlite3 bindings
|
|
70
|
-
- When planning, always structure FILES to keep platform-specific code
|
|
68
|
+
- Entry points handle platform wiring (each imports ONLY its platform's infrastructure library):
|
|
69
|
+
- Worker entry: exports `default { fetch }` with Hono app + D1 bindings → imports `infrastructure-d1`
|
|
70
|
+
- Node entry: `serve()` with Hono app + SQLite/better-sqlite3 bindings → imports `infrastructure-sqlite`
|
|
71
|
+
- When planning, always structure FILES to keep platform-specific code in separate libraries per platform
|
|
71
72
|
|
|
72
73
|
## Task Approach
|
|
73
74
|
|
|
@@ -240,11 +240,46 @@ export class LoginForm {
|
|
|
240
240
|
- `withViewTransitions()` — smooth page transitions
|
|
241
241
|
- Route-level code splitting: each page is a separate chunk
|
|
242
242
|
|
|
243
|
-
## i18n (Internationalization)
|
|
243
|
+
## i18n (Internationalization) — MANDATORY
|
|
244
|
+
|
|
245
|
+
All Angular projects are set up with multi-language support from day one. **Every user-facing text MUST be marked for translation — no exceptions.**
|
|
244
246
|
|
|
245
247
|
- `@angular/localize` with build-time XLIFF — zero runtime cost
|
|
246
|
-
-
|
|
247
|
-
|
|
248
|
+
- Project setup: `ng add @angular/localize` (or ensure `@angular/localize/init` is in polyfills)
|
|
249
|
+
|
|
250
|
+
**Template texts — `i18n` attribute (STRICT):**
|
|
251
|
+
```html
|
|
252
|
+
<!-- EVERY visible text gets i18n attribute -->
|
|
253
|
+
<h1 i18n="page title|Main heading on login page">Welcome back</h1>
|
|
254
|
+
<button i18n="action|Submit login form">Sign in</button>
|
|
255
|
+
<p i18n="hint|Password requirements hint">At least 8 characters</p>
|
|
256
|
+
|
|
257
|
+
<!-- Attributes with user-facing text -->
|
|
258
|
+
<input i18n-placeholder="form|Email placeholder" placeholder="Enter your email" />
|
|
259
|
+
<img i18n-alt="image|Profile photo alt text" alt="Profile photo" />
|
|
260
|
+
|
|
261
|
+
<!-- Plurals and select -->
|
|
262
|
+
<span i18n>{count, plural, =0 {No items} =1 {1 item} other {{{count}} items}}</span>
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
**TypeScript texts — `$localize`:**
|
|
266
|
+
```typescript
|
|
267
|
+
const title = $localize`:page title|Dashboard heading:Dashboard`;
|
|
268
|
+
const error = $localize`:error|Login failed message:Invalid credentials`;
|
|
269
|
+
```
|
|
270
|
+
|
|
271
|
+
**Key rules:**
|
|
272
|
+
- EVERY user-facing string in templates MUST have `i18n` attribute — headings, labels, buttons, links, placeholders, tooltips, alt texts, ARIA labels
|
|
273
|
+
- Use `i18n-placeholder`, `i18n-title`, `i18n-alt`, `i18n-aria-label` for attribute translations
|
|
274
|
+
- Format: `i18n="meaning|description"` — meaning groups related translations, description helps translators
|
|
275
|
+
- EVERY user-facing string in TypeScript MUST use `$localize` with description
|
|
276
|
+
- Keep translation keys stable — don't change meaning/description without updating XLIFF files
|
|
277
|
+
- NEVER hardcode user-facing text without i18n markup — even "OK", "Cancel", "Back" must be translated
|
|
278
|
+
|
|
279
|
+
**NEVER:**
|
|
280
|
+
- Bare text in templates without `i18n`: `<button>Submit</button>` → WRONG
|
|
281
|
+
- String literals for UI text without `$localize`: `this.error = 'Failed'` → WRONG
|
|
282
|
+
- Interpolated text without i18n: `<p>Hello {{name}}</p>` → needs `<p i18n>Hello {{name}}</p>`
|
|
248
283
|
|
|
249
284
|
## Theme System — @themecraft
|
|
250
285
|
|
|
@@ -446,4 +481,5 @@ When reviewing Angular code, check:
|
|
|
446
481
|
- SCSS imports: via package name (no relative paths), no redundant `as` aliases
|
|
447
482
|
- Lazy loading via loadComponent/loadChildren, no eager page imports
|
|
448
483
|
- @defer for heavy below-fold components
|
|
449
|
-
- Naming: PascalCase components, lib- selectors, kebab-case files
|
|
484
|
+
- Naming: PascalCase components, lib- selectors, kebab-case files
|
|
485
|
+
- i18n: ALL user-facing text has `i18n` attribute (templates) or `$localize` (TS) — no bare text
|
|
@@ -142,12 +142,35 @@ src/
|
|
|
142
142
|
- Route-level code splitting: each page is a separate chunk (automatic with Next.js App Router)
|
|
143
143
|
- Prefetch critical routes: Next.js `<Link>` prefetches by default; for React Router use `route.lazy`
|
|
144
144
|
|
|
145
|
-
## i18n (Internationalization)
|
|
145
|
+
## i18n (Internationalization) — MANDATORY
|
|
146
|
+
|
|
147
|
+
All projects are set up with multi-language support from day one. **Every user-facing text MUST use translation functions — no exceptions.**
|
|
146
148
|
|
|
147
149
|
- **Next.js**: `next-intl` for type-safe translations with App Router support (server + client components)
|
|
148
150
|
- **SPA**: `react-i18next` with namespace-based splitting
|
|
149
|
-
|
|
151
|
+
|
|
152
|
+
**Usage (STRICT):**
|
|
153
|
+
```tsx
|
|
154
|
+
// In components — EVERY visible text goes through t()
|
|
155
|
+
const { t } = useTranslations('login'); // next-intl
|
|
156
|
+
// or: const { t } = useTranslation('login'); // react-i18next
|
|
157
|
+
|
|
158
|
+
return (
|
|
159
|
+
<h1>{t('title')}</h1>
|
|
160
|
+
<button>{t('submit')}</button>
|
|
161
|
+
<input placeholder={t('emailPlaceholder')} aria-label={t('emailLabel')} />
|
|
162
|
+
);
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
**Key rules:**
|
|
166
|
+
- EVERY user-facing string MUST go through `t()` — headings, labels, buttons, links, placeholders, tooltips, alt texts, ARIA labels
|
|
167
|
+
- Keep translation keys stable, descriptive, and namespaced by feature
|
|
150
168
|
- Co-locate translations near features when possible
|
|
169
|
+
- NEVER hardcode user-facing text — even "OK", "Cancel", "Back" must be translated
|
|
170
|
+
|
|
171
|
+
**NEVER:**
|
|
172
|
+
- Bare text in JSX: `<button>Submit</button>` → WRONG, use `<button>{t('submit')}</button>`
|
|
173
|
+
- String literals for UI text: `setError('Failed')` → WRONG, use `setError(t('error.failed'))`
|
|
151
174
|
|
|
152
175
|
## Theme System — @themecraft
|
|
153
176
|
|
|
@@ -318,5 +341,6 @@ When reviewing React code, check:
|
|
|
318
341
|
- Code splitting: `React.lazy` + `Suspense` for heavy routes/components, no eager imports of page-level components
|
|
319
342
|
- Dynamic imports for heavy third-party libraries
|
|
320
343
|
- Naming: PascalCase components, camelCase hooks, kebab-case files
|
|
344
|
+
- i18n: ALL user-facing text goes through `t()` — no bare strings in JSX or UI logic
|
|
321
345
|
- No unstable nested component definitions (components defined inside render)
|
|
322
346
|
- `React.memo` only on components with measured re-render cost — not as a default
|
|
@@ -144,11 +144,33 @@ SvelteKit file-based routing:
|
|
|
144
144
|
- `+page.svelte` components are automatically code-split per route by SvelteKit
|
|
145
145
|
- Dynamic imports (`import()`) for heavy components not tied to routes
|
|
146
146
|
|
|
147
|
-
## i18n (Internationalization)
|
|
147
|
+
## i18n (Internationalization) — MANDATORY
|
|
148
|
+
|
|
149
|
+
All projects are set up with multi-language support from day one. **Every user-facing text MUST use translation functions — no exceptions.**
|
|
148
150
|
|
|
149
151
|
- `paraglide-sveltekit` (recommended) — compile-time, tree-shakeable, type-safe messages
|
|
150
152
|
- Alternative: `svelte-i18n` — runtime-based, ICU message format
|
|
153
|
+
|
|
154
|
+
**Usage with paraglide (STRICT):**
|
|
155
|
+
```svelte
|
|
156
|
+
<script>
|
|
157
|
+
import * as m from '$lib/paraglide/messages';
|
|
158
|
+
</script>
|
|
159
|
+
|
|
160
|
+
<!-- EVERY visible text goes through message functions -->
|
|
161
|
+
<h1>{m.loginTitle()}</h1>
|
|
162
|
+
<button>{m.loginSubmit()}</button>
|
|
163
|
+
<input placeholder={m.emailPlaceholder()} aria-label={m.emailLabel()} />
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Key rules:**
|
|
167
|
+
- EVERY user-facing string MUST go through translation functions — headings, labels, buttons, links, placeholders, tooltips, alt texts, ARIA labels
|
|
151
168
|
- Keep translation keys stable, co-locate message files with features when possible
|
|
169
|
+
- NEVER hardcode user-facing text — even "OK", "Cancel", "Back" must be translated
|
|
170
|
+
|
|
171
|
+
**NEVER:**
|
|
172
|
+
- Bare text in templates: `<button>Submit</button>` → WRONG, use `<button>{m.submit()}</button>`
|
|
173
|
+
- String literals for UI text: `error = 'Failed'` → WRONG, use `error = m.errorFailed()`
|
|
152
174
|
|
|
153
175
|
## Theme System — @themecraft
|
|
154
176
|
|
|
@@ -320,6 +342,7 @@ When reviewing Svelte code, check:
|
|
|
320
342
|
- Theme compliance: generated @themecraft SCSS variables — no hardcoded colors/sizes, no direct `color-var()`/`size-var()` calls
|
|
321
343
|
- SCSS imports: via package name (no relative paths), no redundant `as` aliases
|
|
322
344
|
- Lazy loading: routes auto-split, dynamic `import()` for heavy non-route components
|
|
345
|
+
- i18n: ALL user-facing text goes through translation functions — no bare strings in templates
|
|
323
346
|
- Accessibility: all Svelte compiler a11y warnings resolved (not suppressed)
|
|
324
347
|
- No `{@html}` without sanitization
|
|
325
348
|
- Callback props for outputs (not `createEventDispatcher` — that's Svelte 4)
|
|
@@ -167,13 +167,37 @@ src/
|
|
|
167
167
|
- Nuxt auto-imports and auto-splits by page — leverage this by default
|
|
168
168
|
- `<Suspense>` with async setup for loading states on async components
|
|
169
169
|
|
|
170
|
-
## i18n (Internationalization)
|
|
170
|
+
## i18n (Internationalization) — MANDATORY
|
|
171
|
+
|
|
172
|
+
All projects are set up with multi-language support from day one. **Every user-facing text MUST use translation functions — no exceptions.**
|
|
171
173
|
|
|
172
174
|
- `@nuxtjs/i18n` for Nuxt projects — lazy-loaded locales, SEO-friendly routes, auto-detection
|
|
173
175
|
- `vue-i18n` for non-Nuxt projects
|
|
174
|
-
|
|
175
|
-
|
|
176
|
+
|
|
177
|
+
**Usage (STRICT):**
|
|
178
|
+
```vue
|
|
179
|
+
<template>
|
|
180
|
+
<!-- EVERY visible text goes through $t() -->
|
|
181
|
+
<h1>{{ $t('login.title') }}</h1>
|
|
182
|
+
<button>{{ $t('login.submit') }}</button>
|
|
183
|
+
<input :placeholder="$t('login.emailPlaceholder')" :aria-label="$t('login.emailLabel')" />
|
|
184
|
+
</template>
|
|
185
|
+
|
|
186
|
+
<script setup lang="ts">
|
|
187
|
+
const { t } = useI18n();
|
|
188
|
+
const errorMsg = t('login.error.failed');
|
|
189
|
+
</script>
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
**Key rules:**
|
|
193
|
+
- EVERY user-facing string MUST go through `$t()` / `t()` — headings, labels, buttons, links, placeholders, tooltips, alt texts, ARIA labels
|
|
194
|
+
- Keep translation keys stable, organized by feature/domain
|
|
176
195
|
- Locale files: JSON format, one per language (`en.json`, `cs.json`)
|
|
196
|
+
- NEVER hardcode user-facing text — even "OK", "Cancel", "Back" must be translated
|
|
197
|
+
|
|
198
|
+
**NEVER:**
|
|
199
|
+
- Bare text in templates: `<button>Submit</button>` → WRONG, use `<button>{{ $t('submit') }}</button>`
|
|
200
|
+
- String literals for UI text: `error.value = 'Failed'` → WRONG, use `error.value = t('error.failed')`
|
|
177
201
|
|
|
178
202
|
## Theme System — @themecraft
|
|
179
203
|
|
|
@@ -350,3 +374,4 @@ When reviewing Vue code, check:
|
|
|
350
374
|
- Props defined with TypeScript types via `defineProps<{ ... }>()` — not runtime-only validation
|
|
351
375
|
- Emits declared via `defineEmits<{ ... }>()` — not untyped string arrays
|
|
352
376
|
- Naming: PascalCase components, `Base` prefix for atoms, `use` prefix for composables
|
|
377
|
+
- i18n: ALL user-facing text goes through `$t()` / `t()` — no bare strings in templates or script
|
|
@@ -323,9 +323,18 @@ Key rules enforced (do NOT weaken):
|
|
|
323
323
|
- NEVER use Cloudflare-specific APIs (`env.DB`, `ctx.waitUntil()`) in business/domain layers
|
|
324
324
|
- Platform-specific code lives ONLY in `infrastructure/` layer behind abstract interfaces
|
|
325
325
|
- Use Web Standard APIs where possible: `fetch`, `Request`, `Response`, `URL`, `crypto`, `TextEncoder`/`TextDecoder`, `Headers`, `FormData`, `ReadableStream`
|
|
326
|
-
-
|
|
327
|
-
|
|
328
|
-
|
|
326
|
+
- **Platform-specific code MUST be in separate libraries (STRICT)** — NEVER mix Node.js and Cloudflare code in the same library. Barrel exports (`index.ts`) would pull both platforms into the bundle, causing compilation errors (e.g. `better-sqlite3` in Cloudflare, or D1 bindings in Node.js):
|
|
327
|
+
```
|
|
328
|
+
libs/[domain]/
|
|
329
|
+
infrastructure-d1/ # Cloudflare D1 implementation ONLY
|
|
330
|
+
infrastructure-sqlite/ # Node.js SQLite implementation ONLY
|
|
331
|
+
libs/shared/
|
|
332
|
+
infrastructure-d1/ # shared D1 providers (provideD1Database)
|
|
333
|
+
infrastructure-sqlite/ # shared SQLite providers (provideSqliteDatabase)
|
|
334
|
+
```
|
|
335
|
+
Each entry point imports ONLY its platform's library:
|
|
336
|
+
- Worker entry → `@[PREFIX]/shared-infrastructure-d1`
|
|
337
|
+
- Node entry → `@[PREFIX]/shared-infrastructure-sqlite`
|
|
329
338
|
- Hono is inherently platform-agnostic — use its standard APIs, avoid `c.env` directly in routes (inject via DI)
|
|
330
339
|
- Entry points handle platform wiring:
|
|
331
340
|
- `apps/api/src/main.ts` — Node.js entry (optional, for local dev)
|