@agent-native/core 0.182.0 → 0.182.1-nightly-20260916202735

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 (68) hide show
  1. package/corpus/README.md +1 -1
  2. package/corpus/templates/analytics/.agents/skills/shadcn-ui/SKILL.md +65 -6
  3. package/corpus/templates/analytics/.mcp.json +8 -0
  4. package/corpus/templates/analytics/changelog/2026-09-16-dashboards-open-without-background-synchronization-scans-dur.md +6 -0
  5. package/corpus/templates/analytics/server/plugins/collab.ts +2 -0
  6. package/corpus/templates/assets/.agents/skills/shadcn-ui/SKILL.md +65 -6
  7. package/corpus/templates/assets/.mcp.json +8 -0
  8. package/corpus/templates/brain/.agents/skills/shadcn-ui/SKILL.md +65 -6
  9. package/corpus/templates/brain/.mcp.json +8 -0
  10. package/corpus/templates/calendar/.agents/skills/shadcn-ui/SKILL.md +65 -6
  11. package/corpus/templates/calendar/.mcp.json +8 -0
  12. package/corpus/templates/chat/.agents/skills/shadcn-ui/SKILL.md +65 -6
  13. package/corpus/templates/chat/.mcp.json +8 -0
  14. package/corpus/templates/clips/.agents/skills/shadcn-ui/SKILL.md +65 -6
  15. package/corpus/templates/clips/.mcp.json +8 -0
  16. package/corpus/templates/clips/desktop/.mcp.json +8 -0
  17. package/corpus/templates/content/.agents/skills/shadcn-ui/SKILL.md +65 -6
  18. package/corpus/templates/content/.mcp.json +8 -0
  19. package/corpus/templates/crm/.agents/skills/shadcn-ui/SKILL.md +65 -6
  20. package/corpus/templates/crm/.mcp.json +8 -0
  21. package/corpus/templates/design/.agents/skills/shadcn-ui/SKILL.md +65 -6
  22. package/corpus/templates/design/.mcp.json +8 -0
  23. package/corpus/templates/design/changelog/2026-09-16-design-files-avoid-cold-start-scans-and-open-faster-after-id.md +6 -0
  24. package/corpus/templates/dispatch/.agents/skills/shadcn-ui/SKILL.md +65 -6
  25. package/corpus/templates/dispatch/.mcp.json +8 -0
  26. package/corpus/templates/factory/.agents/skills/shadcn-ui/SKILL.md +65 -6
  27. package/corpus/templates/factory/.mcp.json +8 -0
  28. package/corpus/templates/forms/.agents/skills/shadcn-ui/SKILL.md +65 -6
  29. package/corpus/templates/forms/.mcp.json +8 -0
  30. package/corpus/templates/mail/.agents/skills/shadcn-ui/SKILL.md +65 -6
  31. package/corpus/templates/mail/.mcp.json +8 -0
  32. package/corpus/templates/plan/.agents/skills/shadcn-ui/SKILL.md +65 -6
  33. package/corpus/templates/plan/.mcp.json +8 -0
  34. package/corpus/templates/slides/.agents/skills/shadcn-ui/SKILL.md +65 -6
  35. package/corpus/templates/slides/.mcp.json +8 -0
  36. package/corpus/templates/slides/server/plugins/collab.ts +3 -0
  37. package/corpus/templates/tasks/.agents/skills/shadcn-ui/SKILL.md +65 -6
  38. package/corpus/templates/tasks/.mcp.json +8 -0
  39. package/dist/automation/index.d.ts +1 -1
  40. package/dist/cli/create.js +10 -5
  41. package/dist/collab/storage.d.ts +1 -3
  42. package/dist/collab/storage.js +2 -9
  43. package/dist/collab/ydoc-manager.d.ts +2 -2
  44. package/dist/collab/ydoc-manager.js +45 -11
  45. package/dist/deploy/build.js +1 -1
  46. package/dist/file-upload/actions/upload-image.d.ts +1 -1
  47. package/dist/notifications/routes.d.ts +1 -1
  48. package/dist/observability/routes.d.ts +8 -8
  49. package/dist/org/handlers.d.ts +1 -1
  50. package/dist/provider-api/actions/provider-api.d.ts +4 -4
  51. package/dist/resources/handlers.d.ts +1 -1
  52. package/dist/server/collab-plugin.d.ts +18 -5
  53. package/dist/server/collab-plugin.js +173 -63
  54. package/dist/templates/chat/.agents/skills/shadcn-ui/SKILL.md +65 -6
  55. package/dist/templates/chat/.mcp.json +8 -0
  56. package/dist/templates/default/.agents/skills/shadcn-ui/SKILL.md +65 -6
  57. package/dist/templates/default/.mcp.json +8 -0
  58. package/dist/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +65 -6
  59. package/dist/templates/workspace-root/package.json +1 -1
  60. package/dist/templates/workspace-root/pnpm-workspace.yaml +18 -0
  61. package/package.json +4 -4
  62. package/src/templates/chat/.agents/skills/shadcn-ui/SKILL.md +65 -6
  63. package/src/templates/chat/.mcp.json +8 -0
  64. package/src/templates/default/.agents/skills/shadcn-ui/SKILL.md +65 -6
  65. package/src/templates/default/.mcp.json +8 -0
  66. package/src/templates/workspace-core/.agents/skills/shadcn-ui/SKILL.md +65 -6
  67. package/src/templates/workspace-root/package.json +1 -1
  68. package/src/templates/workspace-root/pnpm-workspace.yaml +18 -0
@@ -1,10 +1,9 @@
1
1
  ---
2
2
  name: shadcn-ui
3
3
  description: >-
4
- The shadcn CLI, component composition, theming, and registry workflow. Use
5
- when adding, replacing, upgrading, or debugging a shadcn/ui primitive itself,
6
- or when changing a theme or registry. Do not load it for ordinary edits to a
7
- file that happens to import a shadcn component.
4
+ Project-aware shadcn/ui components, registry MCP, theming, and design-system
5
+ lint feedback. Use when adding or changing React/Tailwind UI, a primitive,
6
+ theme, registry, or component contract in an Agent-Native app.
8
7
  scope: dev
9
8
  source: https://ui.shadcn.com/docs/skills
10
9
  local-changes: >-
@@ -16,11 +15,18 @@ metadata:
16
15
 
17
16
  # shadcn/ui
18
17
 
19
- This skill keeps shadcn/ui work project-aware. Components are source files in the app, so always inspect the local project before adding, importing, or rewriting them.
18
+ This skill keeps shadcn/ui work project-aware. Components are source files in the
19
+ app, so always inspect the local project before adding, importing, or rewriting
20
+ them. When `@shadcn/lint` is configured, treat its feedback as implementation
21
+ guidance, not cosmetic noise. The framework repository runs it through the root
22
+ Oxlint configuration; generated workspaces carry this skill and the MCP
23
+ workflow, but do not automatically inherit that repository-only lint setup.
20
24
 
21
25
  ## First Steps
22
26
 
23
- 1. Work from the app root that owns `components.json`.
27
+ 1. Work from the app root that owns `components.json`. In this monorepo, that is
28
+ the selected app/template directory (usually under `templates/`), not the
29
+ repository root.
24
30
  2. In an Agent-Native app, inspect `app/design-system.ts` and
25
31
  `ToolkitProvider` before choosing a primitive. A registered company design
26
32
  system takes precedence over the default shadcn adapter.
@@ -29,6 +35,59 @@ This skill keeps shadcn/ui work project-aware. Components are source files in th
29
35
  5. Check `app/components/ui/` or the resolved `ui` path before importing a component.
30
36
  6. For unfamiliar components, run `pnpm dlx shadcn@latest docs <component>` and read the returned docs or examples before coding.
31
37
 
38
+ ## MCP Registry Workflow
39
+
40
+ Each first-party app keeps the official shadcn MCP configuration in `.mcp.json`
41
+ next to its `components.json`. Start the agent from that app root so the MCP
42
+ server resolves the correct aliases, local UI directory, and Tailwind theme.
43
+ Do not add a single repository-root server: the root is a workspace, not a
44
+ shadcn project, and would make installs target the wrong project.
45
+
46
+ - Use the shadcn MCP to search, inspect, and install registry items when it is
47
+ connected. Prefer the app's configured registries over copied source.
48
+ - Use `pnpm dlx shadcn@latest info --json` for project context; the MCP has no
49
+ equivalent project-info tool.
50
+ - If the MCP is unavailable, use the equivalent `pnpm dlx shadcn@latest`
51
+ command from the same app root and continue following this skill.
52
+ - Keep registry URLs and aliases in that app's `components.json`. Never put
53
+ registry credentials in MCP config or checked-in source.
54
+
55
+ ## Design-System Lint Feedback
56
+
57
+ In the framework repository, `pnpm lint` runs Oxlint with `@shadcn/lint` for the
58
+ scoped template UI paths. Run it after UI changes and fix every `shadcn/*`
59
+ finding before handing off. Template packages use the workspace lint
60
+ configuration; do not create a second local lint configuration just for one
61
+ app.
62
+
63
+ Before claiming that shadcn lint ran in another workspace, inspect its root
64
+ `package.json` and `.oxlintrc.json`. The generic generated workspace currently
65
+ exposes `pnpm lint` as formatting-only and does not ship `@shadcn/lint` or the
66
+ framework repository's Oxlint config. In that scaffold, use this skill plus the
67
+ connected shadcn MCP (or the CLI fallback) for design-system guidance, and do
68
+ not report `shadcn/*` checks as having run. If the workspace owner adopts the
69
+ linter, add the dependency, scoped config, and lint script together.
70
+
71
+ The Plan template is intentionally excluded from this rollout. Its files remain
72
+ under `templates/plan/**`, but the root Oxlint ignore list keeps them out of the
73
+ shadcn checks until that template has a separate lint baseline.
74
+
75
+ - `no-restyle`: use the component's `variant`, `size`, and semantic props; put
76
+ layout on a parent and add a component variant only when the design system
77
+ genuinely needs a new treatment.
78
+ - `no-raw-colors`: use the theme tokens in the app's `global.css`, not raw
79
+ Tailwind palette classes or hard-coded color attributes.
80
+ - `no-arbitrary-values`: use the theme scale or a declared token instead of
81
+ one-off bracket values.
82
+ - `no-inline-styles`: use classes or CSS custom properties for dynamic layout;
83
+ keep intentional editor/export exceptions scoped to their owning subsystem.
84
+ - `no-unknown-classes` and `require-static-classes`: use classes Tailwind can
85
+ generate and keep class strings statically discoverable.
86
+
87
+ The local primitive source is the contract boundary. Product code should consume
88
+ its props and variants; update `packages/toolkit/src/ui/` or an app's
89
+ `components/ui/` only when the design-system contract itself changes.
90
+
32
91
  ## Agent-Native Adapter Rule
33
92
 
34
93
  Pages, routes, and domain components import controls through the app's local UI
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "shadcn": {
4
+ "command": "npx",
5
+ "args": ["shadcn@latest", "mcp"]
6
+ }
7
+ }
8
+ }
@@ -1,10 +1,9 @@
1
1
  ---
2
2
  name: shadcn-ui
3
3
  description: >-
4
- The shadcn CLI, component composition, theming, and registry workflow. Use
5
- when adding, replacing, upgrading, or debugging a shadcn/ui primitive itself,
6
- or when changing a theme or registry. Do not load it for ordinary edits to a
7
- file that happens to import a shadcn component.
4
+ Project-aware shadcn/ui components, registry MCP, theming, and design-system
5
+ lint feedback. Use when adding or changing React/Tailwind UI, a primitive,
6
+ theme, registry, or component contract in an Agent-Native app.
8
7
  scope: dev
9
8
  source: https://ui.shadcn.com/docs/skills
10
9
  local-changes: >-
@@ -16,11 +15,18 @@ metadata:
16
15
 
17
16
  # shadcn/ui
18
17
 
19
- This skill keeps shadcn/ui work project-aware. Components are source files in the app, so always inspect the local project before adding, importing, or rewriting them.
18
+ This skill keeps shadcn/ui work project-aware. Components are source files in the
19
+ app, so always inspect the local project before adding, importing, or rewriting
20
+ them. When `@shadcn/lint` is configured, treat its feedback as implementation
21
+ guidance, not cosmetic noise. The framework repository runs it through the root
22
+ Oxlint configuration; generated workspaces carry this skill and the MCP
23
+ workflow, but do not automatically inherit that repository-only lint setup.
20
24
 
21
25
  ## First Steps
22
26
 
23
- 1. Work from the app root that owns `components.json`.
27
+ 1. Work from the app root that owns `components.json`. In this monorepo, that is
28
+ the selected app/template directory (usually under `templates/`), not the
29
+ repository root.
24
30
  2. In an Agent-Native app, inspect `app/design-system.ts` and
25
31
  `ToolkitProvider` before choosing a primitive. A registered company design
26
32
  system takes precedence over the default shadcn adapter.
@@ -29,6 +35,59 @@ This skill keeps shadcn/ui work project-aware. Components are source files in th
29
35
  5. Check `app/components/ui/` or the resolved `ui` path before importing a component.
30
36
  6. For unfamiliar components, run `pnpm dlx shadcn@latest docs <component>` and read the returned docs or examples before coding.
31
37
 
38
+ ## MCP Registry Workflow
39
+
40
+ Each first-party app keeps the official shadcn MCP configuration in `.mcp.json`
41
+ next to its `components.json`. Start the agent from that app root so the MCP
42
+ server resolves the correct aliases, local UI directory, and Tailwind theme.
43
+ Do not add a single repository-root server: the root is a workspace, not a
44
+ shadcn project, and would make installs target the wrong project.
45
+
46
+ - Use the shadcn MCP to search, inspect, and install registry items when it is
47
+ connected. Prefer the app's configured registries over copied source.
48
+ - Use `pnpm dlx shadcn@latest info --json` for project context; the MCP has no
49
+ equivalent project-info tool.
50
+ - If the MCP is unavailable, use the equivalent `pnpm dlx shadcn@latest`
51
+ command from the same app root and continue following this skill.
52
+ - Keep registry URLs and aliases in that app's `components.json`. Never put
53
+ registry credentials in MCP config or checked-in source.
54
+
55
+ ## Design-System Lint Feedback
56
+
57
+ In the framework repository, `pnpm lint` runs Oxlint with `@shadcn/lint` for the
58
+ scoped template UI paths. Run it after UI changes and fix every `shadcn/*`
59
+ finding before handing off. Template packages use the workspace lint
60
+ configuration; do not create a second local lint configuration just for one
61
+ app.
62
+
63
+ Before claiming that shadcn lint ran in another workspace, inspect its root
64
+ `package.json` and `.oxlintrc.json`. The generic generated workspace currently
65
+ exposes `pnpm lint` as formatting-only and does not ship `@shadcn/lint` or the
66
+ framework repository's Oxlint config. In that scaffold, use this skill plus the
67
+ connected shadcn MCP (or the CLI fallback) for design-system guidance, and do
68
+ not report `shadcn/*` checks as having run. If the workspace owner adopts the
69
+ linter, add the dependency, scoped config, and lint script together.
70
+
71
+ The Plan template is intentionally excluded from this rollout. Its files remain
72
+ under `templates/plan/**`, but the root Oxlint ignore list keeps them out of the
73
+ shadcn checks until that template has a separate lint baseline.
74
+
75
+ - `no-restyle`: use the component's `variant`, `size`, and semantic props; put
76
+ layout on a parent and add a component variant only when the design system
77
+ genuinely needs a new treatment.
78
+ - `no-raw-colors`: use the theme tokens in the app's `global.css`, not raw
79
+ Tailwind palette classes or hard-coded color attributes.
80
+ - `no-arbitrary-values`: use the theme scale or a declared token instead of
81
+ one-off bracket values.
82
+ - `no-inline-styles`: use classes or CSS custom properties for dynamic layout;
83
+ keep intentional editor/export exceptions scoped to their owning subsystem.
84
+ - `no-unknown-classes` and `require-static-classes`: use classes Tailwind can
85
+ generate and keep class strings statically discoverable.
86
+
87
+ The local primitive source is the contract boundary. Product code should consume
88
+ its props and variants; update `packages/toolkit/src/ui/` or an app's
89
+ `components/ui/` only when the design-system contract itself changes.
90
+
32
91
  ## Agent-Native Adapter Rule
33
92
 
34
93
  Pages, routes, and domain components import controls through the app's local UI
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "shadcn": {
4
+ "command": "npx",
5
+ "args": ["shadcn@latest", "mcp"]
6
+ }
7
+ }
8
+ }
@@ -1,10 +1,9 @@
1
1
  ---
2
2
  name: shadcn-ui
3
3
  description: >-
4
- The shadcn CLI, component composition, theming, and registry workflow. Use
5
- when adding, replacing, upgrading, or debugging a shadcn/ui primitive itself,
6
- or when changing a theme or registry. Do not load it for ordinary edits to a
7
- file that happens to import a shadcn component.
4
+ Project-aware shadcn/ui components, registry MCP, theming, and design-system
5
+ lint feedback. Use when adding or changing React/Tailwind UI, a primitive,
6
+ theme, registry, or component contract in an Agent-Native app.
8
7
  scope: dev
9
8
  source: https://ui.shadcn.com/docs/skills
10
9
  local-changes: >-
@@ -16,11 +15,18 @@ metadata:
16
15
 
17
16
  # shadcn/ui
18
17
 
19
- This skill keeps shadcn/ui work project-aware. Components are source files in the app, so always inspect the local project before adding, importing, or rewriting them.
18
+ This skill keeps shadcn/ui work project-aware. Components are source files in the
19
+ app, so always inspect the local project before adding, importing, or rewriting
20
+ them. When `@shadcn/lint` is configured, treat its feedback as implementation
21
+ guidance, not cosmetic noise. The framework repository runs it through the root
22
+ Oxlint configuration; generated workspaces carry this skill and the MCP
23
+ workflow, but do not automatically inherit that repository-only lint setup.
20
24
 
21
25
  ## First Steps
22
26
 
23
- 1. Work from the app root that owns `components.json`.
27
+ 1. Work from the app root that owns `components.json`. In this monorepo, that is
28
+ the selected app/template directory (usually under `templates/`), not the
29
+ repository root.
24
30
  2. In an Agent-Native app, inspect `app/design-system.ts` and
25
31
  `ToolkitProvider` before choosing a primitive. A registered company design
26
32
  system takes precedence over the default shadcn adapter.
@@ -29,6 +35,59 @@ This skill keeps shadcn/ui work project-aware. Components are source files in th
29
35
  5. Check `app/components/ui/` or the resolved `ui` path before importing a component.
30
36
  6. For unfamiliar components, run `pnpm dlx shadcn@latest docs <component>` and read the returned docs or examples before coding.
31
37
 
38
+ ## MCP Registry Workflow
39
+
40
+ Each first-party app keeps the official shadcn MCP configuration in `.mcp.json`
41
+ next to its `components.json`. Start the agent from that app root so the MCP
42
+ server resolves the correct aliases, local UI directory, and Tailwind theme.
43
+ Do not add a single repository-root server: the root is a workspace, not a
44
+ shadcn project, and would make installs target the wrong project.
45
+
46
+ - Use the shadcn MCP to search, inspect, and install registry items when it is
47
+ connected. Prefer the app's configured registries over copied source.
48
+ - Use `pnpm dlx shadcn@latest info --json` for project context; the MCP has no
49
+ equivalent project-info tool.
50
+ - If the MCP is unavailable, use the equivalent `pnpm dlx shadcn@latest`
51
+ command from the same app root and continue following this skill.
52
+ - Keep registry URLs and aliases in that app's `components.json`. Never put
53
+ registry credentials in MCP config or checked-in source.
54
+
55
+ ## Design-System Lint Feedback
56
+
57
+ In the framework repository, `pnpm lint` runs Oxlint with `@shadcn/lint` for the
58
+ scoped template UI paths. Run it after UI changes and fix every `shadcn/*`
59
+ finding before handing off. Template packages use the workspace lint
60
+ configuration; do not create a second local lint configuration just for one
61
+ app.
62
+
63
+ Before claiming that shadcn lint ran in another workspace, inspect its root
64
+ `package.json` and `.oxlintrc.json`. The generic generated workspace currently
65
+ exposes `pnpm lint` as formatting-only and does not ship `@shadcn/lint` or the
66
+ framework repository's Oxlint config. In that scaffold, use this skill plus the
67
+ connected shadcn MCP (or the CLI fallback) for design-system guidance, and do
68
+ not report `shadcn/*` checks as having run. If the workspace owner adopts the
69
+ linter, add the dependency, scoped config, and lint script together.
70
+
71
+ The Plan template is intentionally excluded from this rollout. Its files remain
72
+ under `templates/plan/**`, but the root Oxlint ignore list keeps them out of the
73
+ shadcn checks until that template has a separate lint baseline.
74
+
75
+ - `no-restyle`: use the component's `variant`, `size`, and semantic props; put
76
+ layout on a parent and add a component variant only when the design system
77
+ genuinely needs a new treatment.
78
+ - `no-raw-colors`: use the theme tokens in the app's `global.css`, not raw
79
+ Tailwind palette classes or hard-coded color attributes.
80
+ - `no-arbitrary-values`: use the theme scale or a declared token instead of
81
+ one-off bracket values.
82
+ - `no-inline-styles`: use classes or CSS custom properties for dynamic layout;
83
+ keep intentional editor/export exceptions scoped to their owning subsystem.
84
+ - `no-unknown-classes` and `require-static-classes`: use classes Tailwind can
85
+ generate and keep class strings statically discoverable.
86
+
87
+ The local primitive source is the contract boundary. Product code should consume
88
+ its props and variants; update `packages/toolkit/src/ui/` or an app's
89
+ `components/ui/` only when the design-system contract itself changes.
90
+
32
91
  ## Agent-Native Adapter Rule
33
92
 
34
93
  Pages, routes, and domain components import controls through the app's local UI
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "shadcn": {
4
+ "command": "npx",
5
+ "args": ["shadcn@latest", "mcp"]
6
+ }
7
+ }
8
+ }
@@ -23,6 +23,9 @@ export default createCollabPlugin({
23
23
  table: "decks",
24
24
  contentColumn: "data",
25
25
  idColumn: "id",
26
+ // These documents carry presence and cursors, not deck content. Seeding the
27
+ // full deck into every deck/slide presence document wastes cold-start work.
28
+ autoSeed: false,
26
29
  access: {
27
30
  mode: "resource",
28
31
  resourceType: "deck",
@@ -1,10 +1,9 @@
1
1
  ---
2
2
  name: shadcn-ui
3
3
  description: >-
4
- The shadcn CLI, component composition, theming, and registry workflow. Use
5
- when adding, replacing, upgrading, or debugging a shadcn/ui primitive itself,
6
- or when changing a theme or registry. Do not load it for ordinary edits to a
7
- file that happens to import a shadcn component.
4
+ Project-aware shadcn/ui components, registry MCP, theming, and design-system
5
+ lint feedback. Use when adding or changing React/Tailwind UI, a primitive,
6
+ theme, registry, or component contract in an Agent-Native app.
8
7
  scope: dev
9
8
  source: https://ui.shadcn.com/docs/skills
10
9
  local-changes: >-
@@ -16,11 +15,18 @@ metadata:
16
15
 
17
16
  # shadcn/ui
18
17
 
19
- This skill keeps shadcn/ui work project-aware. Components are source files in the app, so always inspect the local project before adding, importing, or rewriting them.
18
+ This skill keeps shadcn/ui work project-aware. Components are source files in the
19
+ app, so always inspect the local project before adding, importing, or rewriting
20
+ them. When `@shadcn/lint` is configured, treat its feedback as implementation
21
+ guidance, not cosmetic noise. The framework repository runs it through the root
22
+ Oxlint configuration; generated workspaces carry this skill and the MCP
23
+ workflow, but do not automatically inherit that repository-only lint setup.
20
24
 
21
25
  ## First Steps
22
26
 
23
- 1. Work from the app root that owns `components.json`.
27
+ 1. Work from the app root that owns `components.json`. In this monorepo, that is
28
+ the selected app/template directory (usually under `templates/`), not the
29
+ repository root.
24
30
  2. In an Agent-Native app, inspect `app/design-system.ts` and
25
31
  `ToolkitProvider` before choosing a primitive. A registered company design
26
32
  system takes precedence over the default shadcn adapter.
@@ -29,6 +35,59 @@ This skill keeps shadcn/ui work project-aware. Components are source files in th
29
35
  5. Check `app/components/ui/` or the resolved `ui` path before importing a component.
30
36
  6. For unfamiliar components, run `pnpm dlx shadcn@latest docs <component>` and read the returned docs or examples before coding.
31
37
 
38
+ ## MCP Registry Workflow
39
+
40
+ Each first-party app keeps the official shadcn MCP configuration in `.mcp.json`
41
+ next to its `components.json`. Start the agent from that app root so the MCP
42
+ server resolves the correct aliases, local UI directory, and Tailwind theme.
43
+ Do not add a single repository-root server: the root is a workspace, not a
44
+ shadcn project, and would make installs target the wrong project.
45
+
46
+ - Use the shadcn MCP to search, inspect, and install registry items when it is
47
+ connected. Prefer the app's configured registries over copied source.
48
+ - Use `pnpm dlx shadcn@latest info --json` for project context; the MCP has no
49
+ equivalent project-info tool.
50
+ - If the MCP is unavailable, use the equivalent `pnpm dlx shadcn@latest`
51
+ command from the same app root and continue following this skill.
52
+ - Keep registry URLs and aliases in that app's `components.json`. Never put
53
+ registry credentials in MCP config or checked-in source.
54
+
55
+ ## Design-System Lint Feedback
56
+
57
+ In the framework repository, `pnpm lint` runs Oxlint with `@shadcn/lint` for the
58
+ scoped template UI paths. Run it after UI changes and fix every `shadcn/*`
59
+ finding before handing off. Template packages use the workspace lint
60
+ configuration; do not create a second local lint configuration just for one
61
+ app.
62
+
63
+ Before claiming that shadcn lint ran in another workspace, inspect its root
64
+ `package.json` and `.oxlintrc.json`. The generic generated workspace currently
65
+ exposes `pnpm lint` as formatting-only and does not ship `@shadcn/lint` or the
66
+ framework repository's Oxlint config. In that scaffold, use this skill plus the
67
+ connected shadcn MCP (or the CLI fallback) for design-system guidance, and do
68
+ not report `shadcn/*` checks as having run. If the workspace owner adopts the
69
+ linter, add the dependency, scoped config, and lint script together.
70
+
71
+ The Plan template is intentionally excluded from this rollout. Its files remain
72
+ under `templates/plan/**`, but the root Oxlint ignore list keeps them out of the
73
+ shadcn checks until that template has a separate lint baseline.
74
+
75
+ - `no-restyle`: use the component's `variant`, `size`, and semantic props; put
76
+ layout on a parent and add a component variant only when the design system
77
+ genuinely needs a new treatment.
78
+ - `no-raw-colors`: use the theme tokens in the app's `global.css`, not raw
79
+ Tailwind palette classes or hard-coded color attributes.
80
+ - `no-arbitrary-values`: use the theme scale or a declared token instead of
81
+ one-off bracket values.
82
+ - `no-inline-styles`: use classes or CSS custom properties for dynamic layout;
83
+ keep intentional editor/export exceptions scoped to their owning subsystem.
84
+ - `no-unknown-classes` and `require-static-classes`: use classes Tailwind can
85
+ generate and keep class strings statically discoverable.
86
+
87
+ The local primitive source is the contract boundary. Product code should consume
88
+ its props and variants; update `packages/toolkit/src/ui/` or an app's
89
+ `components/ui/` only when the design-system contract itself changes.
90
+
32
91
  ## Agent-Native Adapter Rule
33
92
 
34
93
  Pages, routes, and domain components import controls through the app's local UI
@@ -0,0 +1,8 @@
1
+ {
2
+ "mcpServers": {
3
+ "shadcn": {
4
+ "command": "npx",
5
+ "args": ["shadcn@latest", "mcp"]
6
+ }
7
+ }
8
+ }
@@ -186,8 +186,8 @@ export declare function createAutomationCallbackHandler(runtime: AutomationRunti
186
186
  duplicate?: undefined;
187
187
  eventId?: undefined;
188
188
  } | {
189
+ error?: undefined;
189
190
  accepted: boolean;
190
191
  duplicate: boolean;
191
192
  eventId: string;
192
- error?: undefined;
193
193
  }>;
@@ -1226,13 +1226,14 @@ function localPackageTarball(packageDir) {
1226
1226
  const npm = process.platform === "win32" ? "npm.cmd" : "npm";
1227
1227
  execFileSync(npm, ["pack", "--ignore-scripts", "--pack-destination", packDir], {
1228
1228
  cwd: packageDir,
1229
- encoding: "utf-8",
1230
1229
  env: {
1231
1230
  ...process.env,
1232
1231
  npm_config_cache: npmCacheDir,
1233
1232
  npm_config_ignore_scripts: "true",
1234
1233
  },
1235
- stdio: "pipe",
1234
+ // npm pack prints one line per included file; piping that output through
1235
+ // execFileSync can hit Node's 1 MiB buffer before the artifact exists.
1236
+ stdio: "ignore",
1236
1237
  });
1237
1238
  const tarballs = fs
1238
1239
  .readdirSync(packDir)
@@ -1250,13 +1251,12 @@ function localPackageTarball(packageDir) {
1250
1251
  const repackNpmCacheDir = path.join(repackDir, "npm-cache");
1251
1252
  execFileSync(npm, ["pack", "--ignore-scripts", "--pack-destination", repackDir], {
1252
1253
  cwd: path.join(unpackDir, "package"),
1253
- encoding: "utf-8",
1254
1254
  env: {
1255
1255
  ...process.env,
1256
1256
  npm_config_cache: repackNpmCacheDir,
1257
1257
  npm_config_ignore_scripts: "true",
1258
1258
  },
1259
- stdio: "pipe",
1259
+ stdio: "ignore",
1260
1260
  });
1261
1261
  const repackedTarballs = fs
1262
1262
  .readdirSync(repackDir)
@@ -1633,7 +1633,12 @@ function postProcessStandalone(name, targetDir, templateName, resolution) {
1633
1633
  ].some((deps) => Boolean(deps?.["node-pty"]));
1634
1634
  fs.writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
1635
1635
  }
1636
- catch { }
1636
+ catch (error) {
1637
+ const detail = error instanceof Error ? error.message : String(error);
1638
+ throw new Error(`Could not finalize ${pkgPath}: ${detail}`, {
1639
+ cause: error,
1640
+ });
1641
+ }
1637
1642
  }
1638
1643
  // Write pnpm-workspace.yaml for pnpm v11 compatibility. pnpm v11 no longer
1639
1644
  // reads the pnpm field in package.json, so allowBuilds and overrides must
@@ -29,10 +29,8 @@ export declare function trySaveYDocState(docId: string, state: Uint8Array, textS
29
29
  export declare function trySaveYDocStateWithClient(client: DbExec, docId: string, state: Uint8Array, textSnapshot: string, expectedVersion: number | null): Promise<boolean>;
30
30
  /** Save Yjs state (Uint8Array) and a plain-text snapshot. */
31
31
  export declare function saveYDocState(docId: string, state: Uint8Array, textSnapshot: string): Promise<void>;
32
- /** Check if a document has collaborative state. */
32
+ /** Check if a document has non-empty collaborative state. */
33
33
  export declare function hasCollabState(docId: string): Promise<boolean>;
34
- /** Load all existing document ids in one query for startup reconciliation. */
35
- export declare function listCollabDocIds(): Promise<Set<string>>;
36
34
  /** Delete collaborative state for a document. */
37
35
  export declare function deleteCollabState(docId: string): Promise<void>;
38
36
  declare function uint8ArrayToBase64(arr: Uint8Array): string;
@@ -119,23 +119,16 @@ export async function saveYDocState(docId, state, textSnapshot) {
119
119
  args: [b64, textSnapshot, docId],
120
120
  });
121
121
  }
122
- /** Check if a document has collaborative state. */
122
+ /** Check if a document has non-empty collaborative state. */
123
123
  export async function hasCollabState(docId) {
124
124
  await ensureTable();
125
125
  const client = getDbExec();
126
126
  const { rows } = await client.execute({
127
- sql: `SELECT 1 FROM _collab_docs WHERE doc_id = ?`,
127
+ sql: `SELECT 1 FROM _collab_docs WHERE doc_id = ? AND yjs_state <> ''`,
128
128
  args: [docId],
129
129
  });
130
130
  return rows.length > 0;
131
131
  }
132
- /** Load all existing document ids in one query for startup reconciliation. */
133
- export async function listCollabDocIds() {
134
- await ensureTable();
135
- const client = getDbExec();
136
- const { rows } = await client.execute("SELECT doc_id FROM _collab_docs");
137
- return new Set(rows.flatMap((row) => typeof row.doc_id === "string" && row.doc_id ? [row.doc_id] : []));
138
- }
139
132
  /** Delete collaborative state for a document. */
140
133
  export async function deleteCollabState(docId) {
141
134
  await ensureTable();
@@ -121,7 +121,7 @@ export declare function getIncUpdate(docId: string, clientStateVector: Uint8Arra
121
121
  * Seed a document from existing text content (for migration).
122
122
  * Only seeds if no collab state exists yet.
123
123
  */
124
- export declare function seedFromText(docId: string, text: string, fieldName?: string): Promise<void>;
124
+ export declare function seedFromText(docId: string, text: string, fieldName?: string, client?: DbExec): Promise<void>;
125
125
  /**
126
126
  * Apply a full JSON update to a document. Computes the minimal diff
127
127
  * and converts it to Yjs operations on Y.Map/Y.Array.
@@ -139,7 +139,7 @@ export declare function getJson(docId: string, fieldName?: string): Promise<any>
139
139
  * Seed a document from existing JSON content (for migration).
140
140
  * Only seeds if no collab state exists yet.
141
141
  */
142
- export declare function seedFromJson(docId: string, json: any, fieldName?: string, type?: "map" | "array"): Promise<void>;
142
+ export declare function seedFromJson(docId: string, json: any, fieldName?: string, type?: "map" | "array", client?: DbExec): Promise<void>;
143
143
  /**
144
144
  * Release a document from the in-memory cache.
145
145
  */
@@ -21,7 +21,7 @@
21
21
  import * as Y from "yjs";
22
22
  import { emitCollabUpdate } from "./emitter.js";
23
23
  import { applyJsonDiff, applyJsonPatch, yDocToJson, initYDocWithJson, } from "./json-to-yjs.js";
24
- import { loadYDocRecord, loadYDocState, loadYDocVersion, trySaveYDocState, trySaveYDocStateWithClient, } from "./storage.js";
24
+ import { loadYDocRecord, loadYDocRecordWithClient, loadYDocVersion, trySaveYDocState, trySaveYDocStateWithClient, } from "./storage.js";
25
25
  import { uint8ArrayToBase64 } from "./storage.js";
26
26
  import { applyTextToYDoc, initYDocWithText } from "./text-to-yjs.js";
27
27
  import { searchAndReplaceInYXml, extractTextFromYXml } from "./xml-ops.js";
@@ -527,27 +527,44 @@ export async function getIncUpdate(docId, clientStateVector) {
527
527
  * Seed a document from existing text content (for migration).
528
528
  * Only seeds if no collab state exists yet.
529
529
  */
530
- export async function seedFromText(docId, text, fieldName = DEFAULT_FIELD) {
530
+ export async function seedFromText(docId, text, fieldName = DEFAULT_FIELD, client) {
531
531
  return withDocWriteLock(docId, async () => {
532
- const existing = await loadYDocState(docId);
533
- if (existing && existing.length > 0)
532
+ const existing = client
533
+ ? await loadYDocRecordWithClient(client, docId)
534
+ : await loadYDocRecord(docId);
535
+ if (existing && existing.state.length > 0)
534
536
  return; // Already seeded
537
+ const expectedVersion = existing ? existing.version : null;
535
538
  const { doc, state } = initYDocWithText(fieldName, text);
536
539
  let saved;
537
540
  try {
538
- saved = await trySaveYDocState(docId, state, text, null);
541
+ saved = client
542
+ ? await trySaveYDocStateWithClient(client, docId, state, text, expectedVersion)
543
+ : await trySaveYDocState(docId, state, text, expectedVersion);
539
544
  }
540
545
  catch (error) {
541
546
  doc.destroy();
542
547
  throw error;
543
548
  }
544
549
  if (!saved) {
550
+ releaseDoc(docId);
551
+ doc.destroy();
552
+ return;
553
+ }
554
+ releaseDoc(docId);
555
+ // A caller-owned transaction may still roll back after this function
556
+ // returns, so never publish its uncommitted doc into the process cache.
557
+ if (client) {
545
558
  doc.destroy();
546
559
  return;
547
560
  }
548
561
  // Cache the doc
549
562
  evictIfNeeded();
550
- _cache.set(docId, { doc, lastAccess: Date.now(), syncedVersion: 0 });
563
+ _cache.set(docId, {
564
+ doc,
565
+ lastAccess: Date.now(),
566
+ syncedVersion: existing ? existing.version + 1 : 0,
567
+ });
551
568
  });
552
569
  }
553
570
  // ─── Structured JSON Operations ─────────────────────────────────────
@@ -599,27 +616,44 @@ export async function getJson(docId, fieldName = "data") {
599
616
  * Seed a document from existing JSON content (for migration).
600
617
  * Only seeds if no collab state exists yet.
601
618
  */
602
- export async function seedFromJson(docId, json, fieldName = "data", type = "map") {
619
+ export async function seedFromJson(docId, json, fieldName = "data", type = "map", client) {
603
620
  return withDocWriteLock(docId, async () => {
604
- const existing = await loadYDocState(docId);
605
- if (existing && existing.length > 0)
621
+ const existing = client
622
+ ? await loadYDocRecordWithClient(client, docId)
623
+ : await loadYDocRecord(docId);
624
+ if (existing && existing.state.length > 0)
606
625
  return; // Already seeded
626
+ const expectedVersion = existing ? existing.version : null;
607
627
  const { doc, state } = initYDocWithJson(fieldName, json, type);
608
628
  let saved;
609
629
  try {
610
- saved = await trySaveYDocState(docId, state, JSON.stringify(json), null);
630
+ saved = client
631
+ ? await trySaveYDocStateWithClient(client, docId, state, JSON.stringify(json), expectedVersion)
632
+ : await trySaveYDocState(docId, state, JSON.stringify(json), expectedVersion);
611
633
  }
612
634
  catch (error) {
613
635
  doc.destroy();
614
636
  throw error;
615
637
  }
616
638
  if (!saved) {
639
+ releaseDoc(docId);
640
+ doc.destroy();
641
+ return;
642
+ }
643
+ releaseDoc(docId);
644
+ // See seedFromText: a transaction-owned seed becomes cacheable only after
645
+ // its commit, when the route reads the now-durable state.
646
+ if (client) {
617
647
  doc.destroy();
618
648
  return;
619
649
  }
620
650
  // Cache the doc
621
651
  evictIfNeeded();
622
- _cache.set(docId, { doc, lastAccess: Date.now(), syncedVersion: 0 });
652
+ _cache.set(docId, {
653
+ doc,
654
+ lastAccess: Date.now(),
655
+ syncedVersion: existing ? existing.version + 1 : 0,
656
+ });
623
657
  });
624
658
  }
625
659
  /**