@erclx/canon 5.43.0 → 5.44.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.
Files changed (133) hide show
  1. package/claude/.claude-plugin/plugin.json +1 -1
  2. package/claude/skills/backlog-triage/references/apply.md +6 -6
  3. package/claude/skills/canon-cli/SKILL.md +4 -4
  4. package/claude/skills/canvas-board/REQUIREMENT.md +1 -1
  5. package/claude/skills/canvas-board/SKILL.md +1 -1
  6. package/claude/skills/context-fold/references/context.md +1 -1
  7. package/claude/skills/create-skill/REQUIREMENT.md +1 -1
  8. package/claude/skills/create-skill/SKILL.md +2 -2
  9. package/claude/skills/create-skill/references/skill-requirement.md +68 -9
  10. package/claude/skills/create-skill/references/skill.md +1 -1
  11. package/claude/skills/design-identity/REQUIREMENT.md +40 -0
  12. package/claude/skills/design-identity/SKILL.md +138 -0
  13. package/claude/skills/{draft-identity → design-identity}/references/card-route.md +2 -2
  14. package/claude/skills/design-taste/REQUIREMENT.md +4 -4
  15. package/claude/skills/design-taste/SKILL.md +2 -2
  16. package/claude/skills/design-taste/references/kinds.md +1 -1
  17. package/claude/skills/design-taste/references/preflight.md +1 -1
  18. package/claude/skills/draft-and-pick/REQUIREMENT.md +8 -69
  19. package/claude/skills/draft-and-pick/SKILL.md +3 -153
  20. package/claude/skills/draft-doc/REQUIREMENT.md +9 -30
  21. package/claude/skills/draft-doc/SKILL.md +4 -76
  22. package/claude/skills/draft-figure/REQUIREMENT.md +8 -42
  23. package/claude/skills/draft-figure/SKILL.md +3 -77
  24. package/claude/skills/draft-identity/REQUIREMENT.md +8 -23
  25. package/claude/skills/draft-identity/SKILL.md +3 -130
  26. package/claude/skills/draft-ready/REQUIREMENT.md +8 -37
  27. package/claude/skills/draft-ready/SKILL.md +3 -128
  28. package/claude/skills/draft-screencast/REQUIREMENT.md +8 -23
  29. package/claude/skills/draft-screencast/SKILL.md +3 -62
  30. package/claude/skills/draft-slides/REQUIREMENT.md +8 -27
  31. package/claude/skills/draft-slides/SKILL.md +3 -72
  32. package/claude/skills/draw-figure/REQUIREMENT.md +59 -0
  33. package/claude/skills/draw-figure/SKILL.md +85 -0
  34. package/claude/skills/{draft-figure → draw-figure}/references/architecture-set.md +2 -2
  35. package/claude/skills/{draft-figure → draw-figure}/references/hand-drawn.md +2 -2
  36. package/claude/skills/{draft-figure → draw-figure}/references/mermaid-path.md +2 -2
  37. package/claude/skills/{draft-figure → draw-figure}/references/mermaid.md +1 -1
  38. package/claude/skills/make-deck/REQUIREMENT.md +44 -0
  39. package/claude/skills/make-deck/SKILL.md +80 -0
  40. package/claude/skills/markdown-craft/REQUIREMENT.md +1 -1
  41. package/claude/skills/markdown-craft/SKILL.md +2 -2
  42. package/claude/skills/pick-by-eye/REQUIREMENT.md +86 -0
  43. package/claude/skills/pick-by-eye/SKILL.md +161 -0
  44. package/claude/skills/plan-feature/SKILL.md +2 -1
  45. package/claude/skills/plan-feature/references/plan.md +24 -10
  46. package/claude/skills/plan-groundwork/SKILL.md +1 -1
  47. package/claude/skills/plan-intake/SKILL.md +1 -1
  48. package/claude/skills/plan-ready/REQUIREMENT.md +54 -0
  49. package/claude/skills/plan-ready/SKILL.md +136 -0
  50. package/claude/skills/{draft-ready → plan-ready}/references/assembly.md +1 -1
  51. package/claude/skills/{draft-ready → plan-ready}/references/ready.md +1 -1
  52. package/claude/skills/record-screencast/REQUIREMENT.md +3 -3
  53. package/claude/skills/record-screencast/SKILL.md +2 -2
  54. package/claude/skills/role-orchestrator/REQUIREMENT.md +1 -1
  55. package/claude/skills/role-orchestrator/references/orchestrator-dispatch.md +5 -2
  56. package/claude/skills/role-orchestrator/references/orchestrator-parked.md +2 -2
  57. package/claude/skills/role-orchestrator/references/orchestrator-refill.md +18 -13
  58. package/claude/skills/role-planner/SKILL.md +2 -1
  59. package/claude/skills/role-worker/SKILL.md +9 -0
  60. package/claude/skills/script-screencast/REQUIREMENT.md +40 -0
  61. package/claude/skills/script-screencast/SKILL.md +70 -0
  62. package/claude/skills/{draft-screencast → script-screencast}/references/beats-template.md +2 -2
  63. package/claude/skills/search-craft/REQUIREMENT.md +4 -4
  64. package/claude/skills/search-craft/SKILL.md +1 -1
  65. package/claude/skills/target-setup/SKILL.md +1 -0
  66. package/claude/skills/task-board/SKILL.md +11 -9
  67. package/claude/skills/task-board/references/board.md +15 -12
  68. package/claude/skills/teach-workspace/SKILL.md +1 -1
  69. package/claude/skills/teach-workspace/references/lesson-craft.md +2 -2
  70. package/claude/skills/ui-checklist/SKILL.md +2 -0
  71. package/claude/skills/write-doc/REQUIREMENT.md +46 -0
  72. package/claude/skills/write-doc/SKILL.md +83 -0
  73. package/claude/skills/{draft-doc → write-doc}/references/context.md +2 -2
  74. package/claude/skills/{draft-doc → write-doc}/references/docs.md +2 -2
  75. package/claude/skills/{draft-doc → write-doc}/references/readme.md +2 -2
  76. package/claude/skills/{draft-doc → write-doc}/references/wiki-kind.md +3 -3
  77. package/docs/agents/markdown-audit.md +4 -2
  78. package/docs/agents/migrate.md +2 -2
  79. package/docs/target/migrations.md +17 -4
  80. package/docs/target/projects.md +1 -1
  81. package/docs/workflow/parallel-features.md +3 -2
  82. package/docs/workflow/skill-map-on-request.md +18 -12
  83. package/docs/workflow/skill-map.md +13 -12
  84. package/docs/workflow/visual-design-workflow.md +2 -2
  85. package/governance/ledger/framework/astro.md +73 -0
  86. package/governance/ledger/framework/fastapi.md +76 -0
  87. package/governance/ledger/framework/nextjs.md +86 -0
  88. package/governance/ledger/framework/react.md +83 -0
  89. package/governance/ledger/framework/shadcn.md +60 -0
  90. package/governance/ledger/framework/tailwind.md +55 -0
  91. package/governance/rules/framework/astro.md +12 -14
  92. package/governance/rules/framework/fastapi.md +20 -24
  93. package/governance/rules/framework/nextjs.md +19 -27
  94. package/governance/rules/framework/react.md +22 -33
  95. package/governance/rules/framework/shadcn.md +11 -15
  96. package/governance/rules/framework/tailwind.md +12 -14
  97. package/governance/rules/writing/markdown.md +1 -1
  98. package/package.json +1 -1
  99. package/src/claude/cases/authoring.ts +15 -3
  100. package/src/claude/cases/misc.ts +12 -0
  101. package/src/claude/cases/workflow.ts +19 -1
  102. package/src/claude/skills-audit.ts +113 -1
  103. package/src/commands/claude.ts +34 -11
  104. package/src/commands/demo.ts +1 -1
  105. package/src/commands/markdown.ts +1 -1
  106. package/src/commands/migrate.ts +4 -0
  107. package/src/commands/pr.ts +30 -6
  108. package/src/commands/tasks.ts +383 -2
  109. package/src/context/audit.ts +1 -1
  110. package/src/demo/beats.ts +1 -1
  111. package/src/gov/audit.ts +3 -2
  112. package/src/markdown/scope.ts +45 -35
  113. package/src/migrate/record-layout.ts +1 -1
  114. package/src/migrate/skill-names.ts +68 -21
  115. package/src/pr/frames.ts +14 -3
  116. package/src/records/validate.ts +31 -0
  117. package/src/tasks/board.ts +854 -0
  118. package/src/tasks/record.ts +20 -1
  119. package/src/tasks/validate.ts +206 -9
  120. package/tooling/astro/configs/card-src/pages/og-card.astro +1 -1
  121. package/tooling/astro/reference.md +2 -2
  122. package/tooling/claude/seeds/.claude/hooks/board-validate.sh +65 -0
  123. package/tooling/claude/seeds/.claude/settings.json +4 -0
  124. /package/claude/skills/{draft-figure → draw-figure}/references/figures.md +0 -0
  125. /package/claude/skills/{draft-slides → make-deck}/references/deck.md +0 -0
  126. /package/claude/skills/{draft-and-pick → pick-by-eye}/references/live-arms.md +0 -0
  127. /package/claude/skills/{draft-doc → write-doc}/references/readme/agent-facing.md +0 -0
  128. /package/claude/skills/{draft-doc → write-doc}/references/readme/application.md +0 -0
  129. /package/claude/skills/{draft-doc → write-doc}/references/readme/cli.md +0 -0
  130. /package/claude/skills/{draft-doc → write-doc}/references/readme/library.md +0 -0
  131. /package/claude/skills/{draft-doc → write-doc}/references/readme/plugin.md +0 -0
  132. /package/claude/skills/{draft-doc → write-doc}/references/requirements.md +0 -0
  133. /package/claude/skills/{draft-doc → write-doc}/references/wiki.md +0 -0
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Enforce astro static-first architecture with explicit island opt-in
2
+ description: Enforce Astro static-first rendering, explicit island hydration, content collections, and asset placement
3
3
  paths:
4
4
  - '**/*.astro'
5
5
  - 'src/pages/**'
@@ -11,31 +11,29 @@ paths:
11
11
 
12
12
  ## Static first
13
13
 
14
- - Write pages and components as `.astro` unless interactivity requires a framework island.
15
- - Do not add a framework integration until the first island needs it.
16
- - Prefer server-rendered content over client-fetched data.
14
+ - Write a component as `.astro` when it has no client-side state or event handlers, since it renders to HTML with no client JS.
15
+ - Fetch page data in the component frontmatter, which runs at build or request time, not in a client island.
17
16
 
18
17
  ## Islands
19
18
 
20
- - Apply `client:*` directives on the component boundary, not on parents.
21
- - Prefer `client:visible` or `client:idle` over `client:load`. Use `client:load` only for above-the-fold interactivity.
22
- - Keep islands leaf-level. Do not wrap layout chrome in a framework component to enable nested islands.
19
+ - Put a `client:*` directive on the framework component itself, imported directly into a `.astro` file.
20
+ - Use `client:visible` for a component below the fold and `client:idle` for a low-priority one. Keep `client:load` for interactive UI above the fold.
23
21
 
24
22
  ## Routing and layouts
25
23
 
26
- - Place routes in `src/pages/`. Use `[param].astro` for dynamic segments and `[...rest].astro` for catch-alls.
27
- - Extract shared chrome into `src/layouts/` and compose pages with a `<Layout>` wrapper.
24
+ - Give a dynamic `[param].astro` route a `getStaticPaths()` in static output, which builds only the paths it returns.
25
+ - Wrap pages in a layout from `src/layouts/` that renders the page through `<slot />`.
28
26
 
29
27
  ## Content
30
28
 
31
- - Use content collections in `src/content/` with a `config.ts` schema for any repeated structured content.
32
- - Access collection entries via `getCollection` and `getEntry` over direct file imports.
29
+ - Define collections in `content.config.ts` at the root of `src/`, each with a `glob()` or `file()` loader and a Zod schema.
30
+ - Read entries through `getCollection()` and `getEntry()`, never by importing content files directly.
33
31
 
34
32
  ## Styles and assets
35
33
 
36
- - Component styles are scoped by default. Use `is:global` only in layouts for reset or base styles.
37
- - Import images from `src/assets/` to get optimization. Use `public/` only for untouched static files.
34
+ - Keep component styles scoped. Use `is:global` or `:global()` only for a reset or base style in a layout.
35
+ - Keep local images in `src/` so Astro optimizes them. Use `public/` only for files served as-is.
38
36
 
39
37
  ## Environment
40
38
 
41
- - Read environment variables via `import.meta.env`. Prefix client-exposed variables with `PUBLIC_`.
39
+ - Read variables through `astro:env` with a schema, or `import.meta.env`, and prefix client-exposed ones with `PUBLIC_`.
@@ -1,43 +1,39 @@
1
1
  ---
2
- description: Enforce FastAPI router, dependency injection, and async handler patterns
2
+ description: Enforce FastAPI routers, sync and async handlers, dependency injection, lifespan, and error mapping
3
3
  paths:
4
4
  - '**/*.py'
5
5
  ---
6
6
 
7
7
  # FastAPI standards
8
8
 
9
- ## Project structure
9
+ ## Routers
10
10
 
11
- - Mount routes through `APIRouter` modules. Do not register handlers directly on `FastAPI()`.
12
- - Group routers by feature under `src/<pkg>/api/` and include them from the root app factory.
13
- - Use an `app_factory()` callable over a module-level `app = FastAPI()` for testability.
11
+ - Declare path operations on one `APIRouter` per feature and add each with `app.include_router()`, not on `FastAPI()` directly.
12
+ - Put a dependency every route in a group needs, such as auth, in the router's `dependencies=[...]`.
14
13
 
15
- ## Handlers
14
+ ## Path operations
16
15
 
17
- - Define path operations as `async def` unless the handler is purely CPU-bound.
18
- - Do not perform blocking I/O inside `async def`. Use async clients or `run_in_threadpool`.
19
- - Annotate path, query, and body parameters explicitly. Do not rely on `**kwargs`.
20
- - Return pydantic models and set `response_model=` on the decorator for serialization control.
16
+ - Declare a path operation `async def` only when every I/O call in it is awaited. Use plain `def` for a blocking library, which FastAPI runs in a threadpool.
17
+ - Declare the return type or `response_model` as a model that omits secrets, since FastAPI filters the output to it.
18
+ - Take a request body as a Pydantic model parameter, never by parsing `await request.json()` by hand.
21
19
 
22
- ## Dependency injection
20
+ ## Dependencies
23
21
 
24
- - Express shared logic (auth, db sessions, settings) as `Depends(...)` over decorators or globals.
25
- - Use `Annotated[T, Depends(...)]` over default-value `Depends()` for reusable dependencies.
26
- - Scope db sessions per request via a generator dependency that yields then closes.
22
+ - Declare a dependency as `Annotated[T, Depends(fn)]`, and share a repeated one as a type alias.
23
+ - Open a database session in a `yield` dependency and close it after the `yield`, so each request gets its own.
24
+ - Replace a dependency in tests through `app.dependency_overrides`, never by patching the module.
27
25
 
28
- ## Lifespan and configuration
26
+ ## Lifespan and settings
29
27
 
30
- - Use the `lifespan` context manager for startup and shutdown over deprecated `@app.on_event`.
31
- - Load settings via `pydantic_settings.BaseSettings`, injected through a cached dependency.
28
+ - Run startup and shutdown in a `lifespan` context manager, never `@app.on_event`, which stops running once `lifespan` is set.
29
+ - Load settings through `pydantic_settings.BaseSettings` behind an `@lru_cache` dependency, so `.env` is read once and tests can override it.
32
30
 
33
31
  ## Errors
34
32
 
35
- - Raise `HTTPException` for client-facing errors with explicit status codes.
36
- - Register `@app.exception_handler` mappings for domain exceptions over per-route try/except.
37
- - Do not leak internal exception messages. Map to safe summaries at the boundary.
33
+ - Raise `HTTPException` with an explicit status code for a client error.
34
+ - Map a domain exception to a response in one `@app.exception_handler`, over a try and except in each route.
35
+ - Return a safe summary from a handler, never the exception's message or traceback.
38
36
 
39
- ## Validation and security
37
+ ## Middleware
40
38
 
41
- - Validate request bodies through pydantic models. Do not parse `Request.json()` manually.
42
- - Apply `dependencies=[Depends(auth)]` at the router or app level for cross-cutting auth.
43
- - Configure CORS, trusted hosts, and HTTPS redirects through middleware, not per-route checks.
39
+ - Configure CORS through `CORSMiddleware`, listing origins explicitly when `allow_credentials=True`, since a wildcard is refused then.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Enforce Next.js App Router structure, server/client boundaries, and built-in primitives
2
+ description: Enforce Next.js App Router boundaries, caching, Server Action security, and built-in primitives
3
3
  paths:
4
4
  - '**/*.tsx'
5
5
  - '**/*.ts'
@@ -7,42 +7,34 @@ paths:
7
7
 
8
8
  # Next.js standards
9
9
 
10
- ## App Router structure
10
+ ## Routing
11
11
 
12
- - Use the App Router under `app/`. Do not introduce `pages/` in new code.
13
- - Use route segment files for their documented purpose: `page.tsx` for routes, `layout.tsx` for shared shells, `loading.tsx` for Suspense fallbacks, `error.tsx` for error boundaries, `route.ts` for HTTP handlers.
12
+ - Add routes under `app/` with the App Router, never under `pages/`.
13
+ - Await `params` and `searchParams`, which are Promises in a page, a layout, and a route handler.
14
14
 
15
15
  ## Server and client components
16
16
 
17
- - Default to Server Components. Add `"use client"` only when the file needs state, effects, browser APIs, or event handlers.
18
- - Place `"use client"` at the leaf, not at the layout. Push the boundary as deep as possible.
19
- - Do not import server-only modules (`fs`, db clients, secrets) from a client component. Mark server-only modules with `import "server-only"`.
20
- - Pass serializable props across the server/client boundary. Do not pass functions or class instances.
17
+ - Default to Server Components. Add `'use client'` only to a file needing state, event handlers, effects, or browser APIs.
18
+ - Put `'use client'` on the interactive leaf, not a layout, since every module it imports joins the client bundle.
19
+ - Pass a Client Component only serializable props holding the fields it renders, never a whole database record.
20
+ - Add `import 'server-only'` to a module that reads secrets or the database.
21
21
 
22
- ## Data fetching
22
+ ## Data and caching
23
23
 
24
- - Fetch data in Server Components or Route Handlers. Do not fetch in client components when a server alternative exists.
25
- - Set explicit caching on `fetch`: `cache: "force-cache"`, `cache: "no-store"`, or `next: { revalidate: <seconds> }`. Do not rely on defaults.
26
- - Use `revalidatePath` or `revalidateTag` for invalidation over manual refetch loops.
24
+ - Cache with `'use cache'` and a `cacheLife` call where Cache Components is on, the default for new apps. A `fetch` is not cached by default.
25
+ - Wrap a component reading `cookies()`, `headers()`, or uncached data in `<Suspense>` with a fallback.
26
+ - Call `revalidatePath` or `revalidateTag` in the Server Action after a mutation.
27
27
 
28
- ## Server Actions
28
+ ## Mutations
29
29
 
30
- - Mark Server Actions with `"use server"` at the top of the file or function.
31
- - Validate Server Action inputs with a Zod schema before use. The client/server boundary is implicit and easy to miss.
32
- - Return serializable values. Do not return Response or stream objects from a Server Action.
33
-
34
- ## Route handlers
35
-
36
- - Place HTTP endpoints in `app/**/route.ts`. Do not add `pages/api/`.
37
- - Export named methods (`GET`, `POST`, ...). Return `NextResponse` over raw `Response` for typed helpers.
38
- - Read params from the function signature (`{ params }`), not from the request URL.
30
+ - Verify authentication and resource ownership inside every Server Action, since each is reachable by a direct POST.
31
+ - Validate every Server Action argument before use, and return only the fields the UI needs.
39
32
 
40
33
  ## Built-in primitives
41
34
 
42
- - Use `next/link` over `<a>` for internal navigation. Use `next/image` over `<img>` for raster images. Use `next/font` over manual `<link>` tags for fonts.
43
- - Set explicit `width` and `height` (or `fill`) on `next/image`. Do not omit dimensions.
35
+ - Use `next/link` for internal navigation and `next/image` for raster images.
36
+ - Give `next/image` a `width` and `height` for a remote source, or `fill` inside a positioned parent.
44
37
 
45
- ## Metadata and environment
38
+ ## Environment
46
39
 
47
- - Export `metadata` or `generateMetadata` from `layout.tsx` or `page.tsx` over manual `<head>` injection.
48
- - Prefix browser-exposed env vars with `NEXT_PUBLIC_`. Never read unprefixed server-only env vars from a client component.
40
+ - Prefix a variable with `NEXT_PUBLIC_` only when the browser needs it, since its value is inlined at build time.
@@ -1,51 +1,40 @@
1
1
  ---
2
- description: Enforce opinionated React architecture and component patterns
2
+ description: Enforce React render purity, state derivation, memoization, and boundary placement
3
3
  paths:
4
4
  - '**/*.tsx'
5
5
  - '**/*.ts'
6
6
  ---
7
7
 
8
- # React architecture standards
8
+ # React standards
9
9
 
10
- ## Export conventions
10
+ ## Rendering
11
11
 
12
- - Use named exports exclusively for components and hooks.
13
- - Do not use default exports.
14
-
15
- ## Project structure
16
-
17
- - Place domain logic in `src/features/` and restrict `src/components/` to shared UI.
18
- - Do not place feature-specific components in the global components folder.
19
- - Import environment variables only from the validated configuration module.
20
-
21
- ## Component patterns
22
-
23
- - Use function declarations for components over arrow functions.
24
- - Define TypeScript interfaces for props immediately above the component.
25
- - Use `<>` shorthand for fragments unless key prop is required.
26
- - Use stable, unique keys for list items over array index.
27
- - Extract components when JSX exceeds a single responsibility.
12
+ - Keep components and hooks pure during render. Move side effects and `Math.random()` into an event handler or an effect.
13
+ - Never mutate props or state. Build a new value and pass it to the `useState` setter.
14
+ - Key list items by a stable ID from the data, never by array index or a value generated during render.
28
15
 
29
16
  ## State and effects
30
17
 
31
- - Encapsulate data fetching and complex effects in custom hooks.
32
- - Use `useMemo` for derived state over `useEffect`.
33
- - Do not call `setState` inside `useEffect` to sync derived state. The `react-hooks/set-state-in-effect` lint enforces this.
34
- - Compare the previous value during render and call `setState` from the render body when it changes, over syncing in an effect.
35
- - Lift the state to a parent and reset the child with a `key` prop, over running a reset effect in the child.
36
- - Return a sentinel (`undefined` or a `useSyncExternalStore` placeholder) from hooks that hydrate asynchronously and gate consumers on it, over running a hydration effect.
18
+ - Calculate a value derivable from props or state during render, never in an effect that syncs it into state.
19
+ - Reset a child's state by passing it a new `key`, over a reset effect in the child.
20
+ - Read a browser or external store with `useSyncExternalStore` and a `getServerSnapshot` matching the server output.
21
+ - Wrap a data-fetching effect in a custom hook whose cleanup ignores stale responses, when the framework has no fetching primitive.
37
22
 
38
23
  ## Memoization
39
24
 
40
- - Memoize components receiving non-primitive props with `React.memo`.
41
- - Use `useCallback` for handler props passed to children.
25
+ - Leave memoization to React Compiler where it is enabled, as React recommends for new code. Add `useMemo` only for precise control.
26
+ - Without the compiler, memoize only a calculation measured at 1ms or more, or a value a `memo` child or a Hook dependency reads.
27
+
28
+ ## Composition
29
+
30
+ - Pass props first, then extract components and pass JSX as `children`. Reach for context only when neither works.
42
31
 
43
- ## Composition and props
32
+ ## Error and loading boundaries
44
33
 
45
- - Avoid prop drilling beyond 2 levels. Use context or composition.
34
+ - Place an error boundary where an error message makes sense, such as around a list and each item, never around every component.
35
+ - Expect Suspense to catch `lazy`, `use` on a cached Promise, or a framework loader, never a fetch inside an effect.
36
+ - Place Suspense boundaries to match the loading sequence the user should see.
46
37
 
47
- ## Error boundaries and Suspense
38
+ ## Exports
48
39
 
49
- - Place error boundaries at route level.
50
- - Place Suspense at data-fetching boundaries.
51
- - Do not use a single root-level error boundary as the only safety net.
40
+ - Use named exports for components and hooks, since a default export renamed at import drifts from its name in a search.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Enforce shadcn/ui v4 component patterns, semantic tokens, and composition rules
2
+ description: Enforce shadcn/ui component ownership, typed primitives, semantic tokens, and composition props
3
3
  paths:
4
4
  - '**/*.tsx'
5
5
  - '**/*.jsx'
@@ -9,26 +9,22 @@ paths:
9
9
 
10
10
  ## Source files
11
11
 
12
- - Do not edit component files installed by the shadcn CLI. Treat them as vendored.
13
- - Check `components.json` for the install path.
14
- - Extend behavior via wrapper components over modifying installed files.
12
+ - Edit an installed component in place when the design needs it, since the code is the project's own.
13
+ - Read `shadcn add --diff` before running `--overwrite` on a component, since overwriting discards local edits.
14
+ - Import components and `cn` through the aliases in `components.json`, which the CLI uses to place files and rewrite imports.
15
15
 
16
16
  ## Component authoring
17
17
 
18
- - Use `React.ComponentProps<typeof Primitive>` over `React.forwardRef`.
19
- - Add `data-slot="component-name"` to every primitive root for Tailwind targeting.
18
+ - Type a component's props as `React.ComponentProps<typeof Primitive>`, not `React.forwardRef`.
19
+ - Add `data-slot="<name>"` to the root of a new primitive, matching the installed components.
20
20
 
21
21
  ## Tokens and styling
22
22
 
23
- - Use semantic color tokens (`bg-background`, `text-foreground`, `border-border`) over hardcoded colors.
24
- - Use `cn()` from `@/lib/utils` for all className merging and conditional classes.
25
- - Do not override shadcn component internals with arbitrary classes.
26
- - Extend via `className` prop only.
23
+ - Use semantic tokens such as `bg-background`, `text-foreground`, and `border-border` over hardcoded colors.
24
+ - Merge classes with `cn()` from `@/lib/utils`, so a caller's `className` overrides the component's defaults.
27
25
 
28
26
  ## Composition
29
27
 
30
- - Compose shadcn primitives as documented.
31
- - Do not destructure or restructure internal component trees.
32
- - Use `asChild` prop with `<Slot>` for polymorphic rendering.
33
- - Do not wrap primitives in extra DOM elements.
34
- - Use `sonner` for toasts over the deprecated `toast` component.
28
+ - Compose through `render` in a Base UI project, the default for new ones, and through `asChild` in a Radix one.
29
+ - Style a link as a button with `buttonVariants()`, never a Base UI `Button` rendering an `<a>`, which forces `role="button"`.
30
+ - Use `sonner` for toasts, since the `toast` component is deprecated.
@@ -1,5 +1,5 @@
1
1
  ---
2
- description: Enforce Tailwind CSS v4 utility patterns, theme tokens, dark mode, and custom styles
2
+ description: Enforce Tailwind CSS v4 theme variables, dark mode, layout spacing, and class application
3
3
  paths:
4
4
  - '**/*.tsx'
5
5
  - '**/*.jsx'
@@ -11,22 +11,20 @@ paths:
11
11
 
12
12
  ## Theme variables
13
13
 
14
- - Use `@theme` for design tokens that generate utility classes.
15
- - Use `:root` for plain CSS variables with no utility counterpart.
16
- - Define dark mode color overrides in `.dark { }` at root level over `@layer base`.
17
- - Always pair light and dark utilities explicitly: `bg-white dark:bg-gray-900`.
14
+ - Define a token in a top-level `@theme` block when it needs a utility class, and in `:root` when it does not.
15
+ - Add `@custom-variant dark (&:where(.dark, .dark *))` when a `.dark` class toggles dark mode, since `dark:` follows `prefers-color-scheme` by default.
18
16
 
19
17
  ## Layout and spacing
20
18
 
21
- - Use `flex` and `grid` for all layouts.
22
- - Never use floats or absolute positioning for flow.
23
- - Use `gap-*` for sibling spacing over margins.
24
- - Use `size-*` over `w-* h-*` for equal dimensions.
25
- - Mobile-first: default styles apply to mobile. Use `sm:` and up to override.
19
+ - Lay out flow content with `flex` or `grid`, never `float` or `absolute`, which pulls an element out of flow so it overlaps at other widths.
20
+ - Space siblings with `gap-*` on the parent over margins on the children, which leave a stray edge when an item wraps or hides.
21
+ - Use `size-*` over a matching `w-*` and `h-*` pair.
22
+ - Write unprefixed utilities for mobile and add `sm:` and up for wider screens, since `sm:` means that breakpoint and above.
26
23
 
27
24
  ## Class application
28
25
 
29
- - Use `cn()` from `@/lib/utils` for all conditional class application.
30
- - Do not use the `!` important modifier.
31
- - Do not use inline `style` props for static styling. Use arbitrary values (`bg-[#316ff6]`) instead.
32
- - Use inline styles only for dynamic values from JS/API or to set CSS variables for utility consumption.
26
+ - Write every class name in full, mapping a prop to a complete class, since Tailwind cannot detect a class built by concatenation.
27
+ - Never put two conflicting utilities on one element. Merge a caller's override through `cn()`, which drops the losing class.
28
+ - Add the trailing `!` modifier only when no other way to manage specificity exists.
29
+ - Use an arbitrary value such as `bg-[#316ff6]` for a static one-off, never an inline `style`.
30
+ - Keep inline `style` for a value from a dynamic source, or to set a CSS variable a utility reads.
@@ -21,4 +21,4 @@ paths:
21
21
 
22
22
  ## Figures
23
23
 
24
- - Load the `canon:draft-figure` skill before drafting or revising a Mermaid fence or a figure, and report it rather than proceeding silently when it does not resolve.
24
+ - Load the `canon:draw-figure` skill before drafting or revising a Mermaid fence or a figure, and report it rather than proceeding silently when it does not resolve.
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@erclx/canon",
3
3
  "type": "module",
4
- "version": "5.43.0",
4
+ "version": "5.44.0",
5
5
  "description": "Runs your agent's work and keeps its code good, on one setup for every repo.",
6
6
  "license": "MIT",
7
7
  "bin": {
@@ -22,26 +22,38 @@ export const AUTHORING_CASES: readonly SkillCase[] = [
22
22
  {
23
23
  prompt:
24
24
  'Write a brand-new docs page for the capture command, nothing under docs/ covers it yet.',
25
+ expect: 'write-doc',
26
+ },
27
+ {
28
+ prompt:
29
+ 'I typed draft-doc and it said the doc skill was renamed to write-doc.', // canon-keep-retired
30
+ // The pointer answers under its old name on purpose. canon-keep-retired
25
31
  expect: 'draft-doc',
26
32
  },
27
33
  {
28
34
  prompt:
29
35
  'I already wrote the finished skill files, package them as a ready folder with a plan and a task for a worker to copy.',
36
+ expect: 'plan-ready',
37
+ },
38
+ {
39
+ prompt:
40
+ 'I typed draft-ready and it said the ready skill was renamed to plan-ready.', // canon-keep-retired
41
+ // The pointer answers under its old name on purpose. canon-keep-retired
30
42
  expect: 'draft-ready',
31
43
  },
32
44
  {
33
45
  prompt: 'This project has no README.md at all, write one from scratch.',
34
- expect: 'draft-doc',
46
+ expect: 'write-doc',
35
47
  },
36
48
  {
37
49
  prompt:
38
50
  'Write a context entry for the payments domain, there is no canon/context page for it yet.',
39
- expect: 'draft-doc',
51
+ expect: 'write-doc',
40
52
  },
41
53
  {
42
54
  prompt:
43
55
  'Write a wiki reference page for Claude Code output styles, no page covers that subject yet.',
44
- expect: 'draft-doc',
56
+ expect: 'write-doc',
45
57
  },
46
58
  {
47
59
  prompt: 'This passage reads flat and robotic, give it some real cadence.',
@@ -10,6 +10,12 @@ export const MISC_CASES: readonly SkillCase[] = [
10
10
  {
11
11
  prompt:
12
12
  'Show me a few different treatments for this callout so I can pick one by looking.',
13
+ expect: 'pick-by-eye',
14
+ },
15
+ {
16
+ prompt:
17
+ 'I typed draft-and-pick and it said the pick skill was renamed to pick-by-eye.', // canon-keep-retired
18
+ // The pointer answers under its old name on purpose. canon-keep-retired
13
19
  expect: 'draft-and-pick',
14
20
  },
15
21
  {
@@ -20,6 +26,12 @@ export const MISC_CASES: readonly SkillCase[] = [
20
26
  {
21
27
  prompt:
22
28
  'This project has no logo yet. Draft one and give me a social card to go with it.',
29
+ expect: 'design-identity',
30
+ },
31
+ {
32
+ prompt:
33
+ 'I typed draft-identity and it said the identity skill was renamed to design-identity.', // canon-keep-retired
34
+ // The pointer answers under its old name on purpose. canon-keep-retired
23
35
  expect: 'draft-identity',
24
36
  },
25
37
  {
@@ -22,12 +22,18 @@ export const WORKFLOW_CASES: readonly SkillCase[] = [
22
22
  },
23
23
  {
24
24
  prompt: 'Draw me a diagram of how the pieces of this system connect.',
25
+ expect: 'draw-figure',
26
+ },
27
+ {
28
+ prompt:
29
+ 'I typed draft-figure and it said the figure skill was renamed to draw-figure.', // canon-keep-retired
30
+ // The pointer answers under its old name on purpose. canon-keep-retired
25
31
  expect: 'draft-figure',
26
32
  },
27
33
  {
28
34
  prompt:
29
35
  'This onboarding doc needs a hand-drawn picture of the signup-to-active path, sketch it in and make sure it actually renders correctly.',
30
- expect: 'draft-figure',
36
+ expect: 'draw-figure',
31
37
  },
32
38
  {
33
39
  prompt:
@@ -108,10 +114,22 @@ export const WORKFLOW_CASES: readonly SkillCase[] = [
108
114
  },
109
115
  {
110
116
  prompt: 'Draft me a script with beats for a screencast recording.',
117
+ expect: 'script-screencast',
118
+ },
119
+ {
120
+ prompt:
121
+ 'I typed draft-screencast and it said the screencast skill was renamed to script-screencast.', // canon-keep-retired
122
+ // The pointer answers under its old name on purpose. canon-keep-retired
111
123
  expect: 'draft-screencast',
112
124
  },
113
125
  {
114
126
  prompt: 'Turn this topic into a slide deck I can render.',
127
+ expect: 'make-deck',
128
+ },
129
+ {
130
+ prompt:
131
+ 'I typed draft-slides and it said the slides skill was renamed to make-deck.', // canon-keep-retired
132
+ // The pointer answers under its old name on purpose. canon-keep-retired
115
133
  expect: 'draft-slides',
116
134
  },
117
135
  // Rot across documents nobody changed is what this reads, rather than a