handoff-app 2.0.0-11 → 2.0.0-13

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 (141) hide show
  1. package/{Changelog.md → CHANGELOG.md} +84 -0
  2. package/{License.md → LICENSE.md} +1 -1
  3. package/README.md +760 -801
  4. package/RECIPES.md +975 -0
  5. package/components.json +20 -20
  6. package/config/docs/foundations/colors/guidelines.md +0 -1
  7. package/config/docs/foundations/colors.md +0 -1
  8. package/config/docs/foundations/effects/guidelines.md +0 -1
  9. package/config/docs/foundations/effects/resources.md +0 -1
  10. package/config/docs/foundations/effects.md +0 -1
  11. package/config/docs/foundations/fonts.md +0 -1
  12. package/config/docs/foundations/grid.md +0 -1
  13. package/config/docs/foundations/icon.md +0 -1
  14. package/config/docs/foundations/icons/guidelines.md +0 -1
  15. package/config/docs/foundations/icons.md +0 -1
  16. package/config/docs/foundations/images/guidelines.md +0 -1
  17. package/config/docs/foundations/images/resources.md +0 -1
  18. package/config/docs/foundations/images.md +0 -1
  19. package/config/docs/foundations/logo/resources.md +0 -1
  20. package/config/docs/foundations/logo.md +0 -1
  21. package/config/docs/foundations/typography/guidelines.md +0 -1
  22. package/config/docs/foundations/typography/resources.md +0 -1
  23. package/config/docs/foundations/typography.md +0 -1
  24. package/config/docs/foundations.md +0 -1
  25. package/config/docs/guidelines.md +0 -1
  26. package/config/docs/index.md +0 -1
  27. package/config/docs/system/tokens/foundations/colors.md +0 -4
  28. package/config/docs/system/tokens/foundations/effects.md +0 -4
  29. package/config/docs/system/tokens/foundations/typography.md +0 -2
  30. package/config/docs/system.md +0 -2
  31. package/config/templates/page.md +2 -1
  32. package/config/templates/page.mdx +2 -1
  33. package/dist/ai/define.d.ts +1 -1
  34. package/dist/ai/define.js +1 -1
  35. package/dist/ai/types.d.ts +1 -1
  36. package/dist/ai/types.js +1 -1
  37. package/dist/app-builder/build.js +16 -16
  38. package/dist/app-builder/client-config.js +1 -1
  39. package/dist/config/loader.js +1 -2
  40. package/dist/index.d.ts +2 -2
  41. package/dist/index.js +2 -2
  42. package/dist/nav/index.d.ts +2 -2
  43. package/dist/nav/registry.d.ts +3 -3
  44. package/dist/nav/registry.js +1 -1
  45. package/dist/nav/workspace.d.ts +3 -3
  46. package/dist/nav/workspace.js +1 -1
  47. package/dist/providers.d.ts +10 -0
  48. package/dist/{define.js → providers.js} +4 -4
  49. package/dist/registry/asset-storage/define.d.ts +5 -5
  50. package/dist/registry/asset-storage/define.js +4 -4
  51. package/dist/registry/asset-storage/resolve.d.ts +8 -11
  52. package/dist/registry/asset-storage/resolve.js +12 -13
  53. package/dist/registry/asset-storage/types.d.ts +12 -12
  54. package/dist/registry/asset-storage/types.js +2 -2
  55. package/dist/registry/db/schema.d.ts +2 -2
  56. package/dist/registry/db/schema.js +2 -2
  57. package/dist/registry/email/define.d.ts +1 -1
  58. package/dist/registry/email/define.js +1 -1
  59. package/dist/registry/email/resolve.d.ts +7 -8
  60. package/dist/registry/email/resolve.js +21 -23
  61. package/dist/registry/email/types.d.ts +1 -1
  62. package/dist/registry/email/types.js +1 -1
  63. package/dist/store/registry.d.ts +3 -3
  64. package/dist/store/registry.js +4 -4
  65. package/dist/types/config.d.ts +4 -13
  66. package/docs/cli.md +275 -54
  67. package/package.json +8 -9
  68. package/src/ai/define.ts +1 -1
  69. package/src/ai/types.ts +1 -1
  70. package/src/app/components/Auth/AccountLayout.tsx +1 -1
  71. package/src/app/components/Auth/AuthShell.tsx +10 -4
  72. package/src/app/components/Foundations/ColorGrid.tsx +13 -14
  73. package/src/app/components/Layout/Main.tsx +2 -2
  74. package/src/app/components/McpIntegration/McpConfigDialog.tsx +12 -51
  75. package/src/app/components/Navigation/MobileNav.tsx +0 -2
  76. package/src/app/components/util/index.ts +0 -11
  77. package/src/app/lib/asset-storage.ts +25 -25
  78. package/src/app/lib/auth/email.ts +4 -5
  79. package/src/app/lib/docs-api/page-rendering.ts +1 -1
  80. package/src/app/lib/docs-api/registry.ts +2 -3
  81. package/src/app/lib/docs-api/runtime-config.ts +8 -8
  82. package/src/app/lib/mcp/components.ts +33 -29
  83. package/src/app/lib/mcp/pages.ts +26 -19
  84. package/src/app/lib/mcp/server.ts +33 -9
  85. package/src/app/lib/mcp/tokens.ts +22 -16
  86. package/src/app/lib/mcp/tool.ts +19 -0
  87. package/src/app/lib/registry-api/asset-transfer.ts +25 -25
  88. package/src/app/lib/server-module.ts +1 -1
  89. package/src/app/lib/utils.ts +7 -0
  90. package/src/app/next.config.mjs +2 -2
  91. package/src/app/pages/[...slug]/index.tsx +2 -1
  92. package/src/app/pages/account/ai.tsx +1 -1
  93. package/src/app/pages/account/index.tsx +1 -1
  94. package/src/app/pages/account/tokens.tsx +1 -1
  95. package/src/app/pages/account/users.tsx +1 -1
  96. package/src/app/pages/api/docs/nav.json.ts +1 -1
  97. package/src/app/pages/api/mcp.ts +6 -0
  98. package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +1 -1
  99. package/src/app/pages/cli/device.tsx +1 -1
  100. package/src/app/pages/foundations/colors.tsx +9 -8
  101. package/src/app/pages/foundations/index.tsx +3 -3
  102. package/src/app/pages/index.tsx +2 -2
  103. package/src/app/pages/login.tsx +10 -5
  104. package/src/app/pages/reset-password.tsx +7 -2
  105. package/src/app/pages/system/component/[component]/index.tsx +2 -5
  106. package/src/app/pages/system/index.tsx +11 -11
  107. package/src/app/pages/system/pattern/[pattern]/index.tsx +2 -2
  108. package/src/app/pages/system/tokens/components/[component]/index.tsx +0 -4
  109. package/src/app-builder/build.ts +12 -12
  110. package/src/app-builder/client-config.ts +1 -1
  111. package/src/config/loader.ts +1 -2
  112. package/src/index.ts +6 -6
  113. package/src/nav/index.ts +2 -2
  114. package/src/nav/registry.ts +3 -3
  115. package/src/nav/workspace.ts +3 -3
  116. package/src/{define.ts → providers.ts} +8 -8
  117. package/src/registry/asset-storage/define.ts +6 -6
  118. package/src/registry/asset-storage/resolve.ts +16 -20
  119. package/src/registry/asset-storage/types.ts +12 -12
  120. package/src/registry/db/schema.ts +3 -3
  121. package/src/registry/email/define.ts +1 -1
  122. package/src/registry/email/resolve.ts +23 -23
  123. package/src/registry/email/types.ts +1 -1
  124. package/src/store/registry.ts +7 -7
  125. package/src/types/config.ts +4 -14
  126. package/.editorconfig +0 -19
  127. package/.eslintrc.json +0 -4
  128. package/.prettierignore +0 -0
  129. package/.prettierrc.json +0 -8
  130. package/.vscode/settings.json +0 -17
  131. package/dist/define.d.ts +0 -10
  132. package/dist/registry/email/adapters/resend.d.ts +0 -7
  133. package/dist/registry/email/adapters/resend.js +0 -35
  134. package/src/app/components/old/Header.tsx +0 -89
  135. package/src/app/pages/assets/fonts.tsx +0 -129
  136. package/src/app/pages/assets/index.tsx +0 -91
  137. package/src/app/pages/assets/logos.tsx +0 -75
  138. package/src/registry/email/adapters/resend.ts +0 -22
  139. /package/dist/registry/email/{adapters → providers}/smtp.d.ts +0 -0
  140. /package/dist/registry/email/{adapters → providers}/smtp.js +0 -0
  141. /package/src/registry/email/{adapters → providers}/smtp.ts +0 -0
package/components.json CHANGED
@@ -1,21 +1,21 @@
1
1
  {
2
- "$schema": "https://ui.shadcn.com/schema.json",
3
- "style": "new-york",
4
- "rsc": false,
5
- "tsx": true,
6
- "tailwind": {
7
- "config": "tailwind.config.ts",
8
- "css": "src/app/css/index.css",
9
- "baseColor": "zinc",
10
- "cssVariables": true,
11
- "prefix": ""
12
- },
13
- "aliases": {
14
- "components": "src/app/components",
15
- "utils": "src/app/lib/utils",
16
- "ui": "src/app/components/ui",
17
- "lib": "src/app/lib",
18
- "hooks": "src/app/hooks"
19
- },
20
- "iconLibrary": "lucide"
21
- }
2
+ "$schema": "https://ui.shadcn.com/schema.json",
3
+ "style": "new-york",
4
+ "rsc": false,
5
+ "tsx": true,
6
+ "tailwind": {
7
+ "config": "tailwind.config.ts",
8
+ "css": "src/app/css/index.css",
9
+ "baseColor": "zinc",
10
+ "cssVariables": true,
11
+ "prefix": ""
12
+ },
13
+ "aliases": {
14
+ "components": "src/app/components",
15
+ "utils": "src/app/lib/utils",
16
+ "ui": "src/app/components/ui",
17
+ "lib": "src/app/lib",
18
+ "hooks": "src/app/hooks"
19
+ },
20
+ "iconLibrary": "lucide"
21
+ }
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Color Guidelines
3
3
  description: How to apply the color palette consistently and accessibly across products.
4
- metaTitle: 'Color Guidelines | Handoff Design System'
5
4
  metaDescription: 'How to apply the color palette consistently and accessibly across products.'
6
5
  ---
7
6
 
@@ -2,6 +2,5 @@
2
2
  title: Colors
3
3
  description: Color system built out of main brand colors and adjusted for variety of interfaces.
4
4
  image: hero-colors
5
- metaTitle: 'Colors | Handoff Design System'
6
5
  metaDescription: 'Color system built out of main brand colors and adjusted for variety of interfaces.'
7
6
  ---
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Effects Guidelines
3
3
  description: When and how to apply shadows, blurs, and elevation across the interface.
4
- metaTitle: 'Effects Guidelines | Handoff Design System'
5
4
  metaDescription: 'When and how to apply shadows, blurs, and elevation across the interface.'
6
5
  ---
7
6
 
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Effects Resources
3
3
  description: Reference values and assets for reproducing the brand's effects in any tool.
4
- metaTitle: 'Effects Resources | Handoff Design System'
5
4
  metaDescription: 'Reference values and assets for reproducing effects in any tool.'
6
5
  ---
7
6
 
@@ -2,7 +2,6 @@
2
2
  title: Effects
3
3
  description: Effects are Drop Shadows, Inner Shadows and Blur Effects.
4
4
  image: hero-effects
5
- metaTitle: 'Effects | Handoff Design System'
6
5
  metaDescription: 'Effects are Drop Shadows, Inner Shadows and Blur Effects.'
7
6
  ---
8
7
 
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Fonts
3
3
  description: Approved library of font families that are approved and licensed for use across the organization.
4
- metaTitle: Fonts | Handoff Design System
5
4
  metaDescription: Font families are packaged as assets that can be used across platforms.
6
5
  ---
7
6
 
@@ -2,7 +2,6 @@
2
2
  title: Grid
3
3
  description: Layout grid and spacing system that keeps compositions aligned and balanced.
4
4
  image: hero-design
5
- metaTitle: 'Grid | Handoff Design System'
6
5
  metaDescription: 'Layout grid and spacing system that keeps compositions aligned and balanced.'
7
6
  ---
8
7
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  title: Icon Library
3
3
  description: Set of icons used to provide users with a way to process information faster and instinctively recognize actions signified by the icon.
4
- metaTitle: 'Icon Library | Handoff Design System'
5
4
  metaDescription: 'Set of icons used to provide users with a way to process information faster and instinctively recognize actions signified by the icon.'
6
5
  ---
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Icon Guidelines
3
3
  description: Sizing, spacing, and usage rules that keep the icon set consistent.
4
- metaTitle: 'Icon Guidelines | Handoff Design System'
5
4
  metaDescription: 'Sizing, spacing, and usage rules that keep the icon set consistent.'
6
5
  ---
7
6
 
@@ -1,6 +1,5 @@
1
1
  ---
2
2
  title: Icon Library
3
3
  description: Set of icons used to provide users with a way to process information faster and instinctively recognize actions signified by the icon.
4
- metaTitle: 'Icon Library | Handoff Design System'
5
4
  metaDescription: 'Set of icons used to provide users with a way to process information faster and instinctively recognize actions signified by the icon.'
6
5
  ---
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Image Guidelines
3
3
  description: How to select, crop, and treat imagery so it stays on brand.
4
- metaTitle: 'Image Guidelines | Handoff Design System'
5
4
  metaDescription: 'How to select, crop, and treat imagery so it stays on brand.'
6
5
  ---
7
6
 
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Image Resources
3
3
  description: Source files and downloads for approved photography and illustration.
4
- metaTitle: 'Image Resources | Handoff Design System'
5
4
  metaDescription: 'Source files and downloads for approved photography and illustration.'
6
5
  ---
7
6
 
@@ -2,7 +2,6 @@
2
2
  title: Images
3
3
  description: Photography and illustration style that shapes how the brand looks and feels.
4
4
  image: hero-design
5
- metaTitle: 'Images | Handoff Design System'
6
5
  metaDescription: 'Photography and illustration style that shapes how the brand looks and feels.'
7
6
  ---
8
7
 
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Logo Resources
3
3
  description: Downloadable logo files and everything teams need to represent the brand correctly.
4
- metaTitle: 'Logo Resources | Handoff Design System'
5
4
  metaDescription: 'Downloadable logo files and everything teams need to represent the brand correctly.'
6
5
  ---
7
6
 
@@ -2,6 +2,5 @@
2
2
  title: Logos
3
3
  description: Show the logos used for promoting public identification and recognition.
4
4
  image: react
5
- metaTitle: 'Logos | Handoff Design System'
6
5
  metaDescription: 'Show the logos used for promoting public identification and recognition.'
7
6
  ---
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Typography Guidelines
3
3
  description: Best practices for type scale, hierarchy, and readability across the system.
4
- metaTitle: 'Typography Guidelines | Handoff Design System'
5
4
  metaDescription: 'Best practices for type scale, hierarchy, and readability across the system.'
6
5
  ---
7
6
 
@@ -1,7 +1,6 @@
1
1
  ---
2
2
  title: Typography Resources
3
3
  description: Font files, licenses, and assets needed to work with the brand typography.
4
- metaTitle: 'Typography Resources | Handoff Design System'
5
4
  metaDescription: 'Font files, licenses, and assets needed to work with the brand typography.'
6
5
  ---
7
6
 
@@ -2,7 +2,6 @@
2
2
  title: Typography
3
3
  description: Typographic system establishes scale, sizes and weight of text.
4
4
  image: hero-design
5
- metaTitle: 'Typography | Handoff Design System'
6
5
  metaDescription: 'Typographic system establishes scale, sizes and weight of text.'
7
6
  ---
8
7
 
@@ -4,7 +4,6 @@ description: Set of design principles and visual guidelines that define the bran
4
4
  weight: 0
5
5
  image: hero-design
6
6
  menuTitle: 'Foundations'
7
- metaTitle: 'Design Foundations | Handoff Design System'
8
7
  metaDescription: 'Set of design principles and visual guidelines that define the brand across every experience'
9
8
  enabled: true
10
9
  menu:
@@ -4,7 +4,6 @@ description: How to build out a robust project built on the designs, tokens, and
4
4
  weight: 10
5
5
  image: hero-components
6
6
  menuTitle: 'Guidelines'
7
- metaTitle: 'Guidelines | Handoff Design System'
8
7
  metaDescription: 'How to build out a robust project built on the designs, tokens, and components documented here.'
9
8
  enabled: true
10
9
  menu:
@@ -3,7 +3,6 @@ title: 'Handoff Design System for building better user experiences.'
3
3
  description: This is a sample page where you could insert a style guide.
4
4
  weight: -5
5
5
  menuTitle: 'Handoff'
6
- metaTitle: 'Style Guide | Handoff Design System'
7
6
  metaDescription: 'A sample page in the handoff design system, in markdown'
8
7
  enabled: true
9
8
  ---
@@ -7,10 +7,6 @@ description: |
7
7
  weight: 5
8
8
  image: hero-components
9
9
  menuTitle: 'Colors'
10
- metaTitle: 'Colors | Handoff Design System'
11
- metaDescription: |
12
- Element that represents a control that provides a menu of options, collection
13
- of UI components used.'
14
10
  enabled: true
15
11
  menu:
16
12
  - title: Design System
@@ -4,10 +4,6 @@ description: Effects are the shadows and insets pulled automatically from Figma
4
4
  weight: 5
5
5
  image: hero-components
6
6
  menuTitle: 'Effects'
7
- metaTitle: 'Effects | Handoff Design System'
8
- metaDescription: |
9
- Element that represents a control that provides a menu of options, collection
10
- of UI components used.
11
7
  enabled: true
12
8
  menu:
13
9
  - title: Design System
@@ -9,8 +9,6 @@ description: |
9
9
  weight: 5
10
10
  image: hero-components
11
11
  menuTitle: 'Typography'
12
- metaTitle: 'Typography | Handoff Design System'
13
- metaDescription: 'Element that represents a control that provides a menu of options, collection of UI components used.'
14
12
  enabled: true
15
13
  menu:
16
14
  - title: Design System
@@ -4,8 +4,6 @@ description: Library of production-ready UI components built to deliver consiste
4
4
  weight: 5
5
5
  image: hero-components
6
6
  menuTitle: 'Design System'
7
- metaTitle: 'Design System | Handoff Design System'
8
- metaDescription: 'Element that represents a control that provides a menu of options, collection of UI components used.'
9
7
  enabled: true
10
8
  menu:
11
9
  - title: Design System
@@ -3,7 +3,8 @@ title: 'The visible title of the page.'
3
3
  description: A description of the page.
4
4
  weight: 0
5
5
  menuTitle: 'Menu Title'
6
- metaTitle: 'Meta Title'
6
+ # metaTitle replaces the whole browser title. Without it, the title is "<title> | <app.title>".
7
+ # metaTitle: 'Meta Title'
7
8
  metaDescription: 'Insert a meta description'
8
9
  enabled: true
9
10
  ---
@@ -3,7 +3,8 @@ title: 'The visible title of the page.'
3
3
  description: A description of the page.
4
4
  weight: 0
5
5
  menuTitle: 'Menu Title'
6
- metaTitle: 'Meta Title'
6
+ # metaTitle replaces the whole browser title. Without it, the title is "<title> | <app.title>".
7
+ # metaTitle: 'Meta Title'
7
8
  metaDescription: 'Insert a meta description'
8
9
  enabled: true
9
10
  ---
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Typed identity helper for custom AI providers (mirrors `defineAssetStorage`): a consumer
2
+ * Typed identity helper for custom AI providers (mirrors `defineStorageProvider`): a consumer
3
3
  * default-exports its result from a **server-only** module and points a connection's `module` at
4
4
  * it. It must be its own module (not an inline `defineConfig` function) so the build can trace it
5
5
  * into the deployed registry. The default export may be the provider object, or a factory
package/dist/ai/define.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  /**
3
- * Typed identity helper for custom AI providers (mirrors `defineAssetStorage`): a consumer
3
+ * Typed identity helper for custom AI providers (mirrors `defineStorageProvider`): a consumer
4
4
  * default-exports its result from a **server-only** module and points a connection's `module` at
5
5
  * it. It must be its own module (not an inline `defineConfig` function) so the build can trace it
6
6
  * into the deployed registry. The default export may be the provider object, or a factory
@@ -2,7 +2,7 @@
2
2
  * Server-only AI provider contract for connections that are not OpenAI-compatible.
3
3
  *
4
4
  * Every built-in connection speaks the OpenAI-compatible `/chat/completions` API and needs no
5
- * adapter — Ollama, LiteLLM, OpenRouter, vLLM, LM Studio and Azure OpenAI all serve it, and each of
5
+ * custom module — Ollama, LiteLLM, OpenRouter, vLLM, LM Studio and Azure OpenAI all serve it, and each of
6
6
  * them fronts Anthropic, Google and xAI models. A provider that fits nothing else names a
7
7
  * {@link defineAiProvider} module instead of a base URL.
8
8
  */
package/dist/ai/types.js CHANGED
@@ -3,7 +3,7 @@
3
3
  * Server-only AI provider contract for connections that are not OpenAI-compatible.
4
4
  *
5
5
  * Every built-in connection speaks the OpenAI-compatible `/chat/completions` API and needs no
6
- * adapter — Ollama, LiteLLM, OpenRouter, vLLM, LM Studio and Azure OpenAI all serve it, and each of
6
+ * custom module — Ollama, LiteLLM, OpenRouter, vLLM, LM Studio and Azure OpenAI all serve it, and each of
7
7
  * them fronts Anthropic, Google and xAI models. A provider that fits nothing else names a
8
8
  * {@link defineAiProvider} module instead of a base URL.
9
9
  */
@@ -212,7 +212,7 @@ const cleanupAppDirectory = (handoff) => __awaiter(void 0, void 0, void 0, funct
212
212
  * @returns The path to the prepared application directory
213
213
  */
214
214
  const initializeProjectApp = (handoff_1, ...args_1) => __awaiter(void 0, [handoff_1, ...args_1], void 0, function* (handoff, options = {}) {
215
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o;
215
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
216
216
  const includeWorkspaceArtifacts = (_a = options.includeWorkspaceArtifacts) !== null && _a !== void 0 ? _a : true;
217
217
  const runtimeMode = (_e = (_b = options.runtimeModeOverride) !== null && _b !== void 0 ? _b : (_d = (_c = handoff.config) === null || _c === void 0 ? void 0 : _c.runtime) === null || _d === void 0 ? void 0 : _d.mode) !== null && _e !== void 0 ? _e : 'workspace';
218
218
  const srcPath = path_1.default.resolve(handoff.modulePath, 'src', 'app');
@@ -261,16 +261,16 @@ const initializeProjectApp = (handoff_1, ...args_1) => __awaiter(void 0, [handof
261
261
  const escapedMcpEnabled = escapeForSingleQuotedJsString(String((0, config_1.isMcpEnabled)(handoff.config)));
262
262
  const escapedRegistryDriver = escapeForSingleQuotedJsString((0, driver_1.resolveRegistryDriver)(handoff.config));
263
263
  const escapedDatabaseUrlEnv = escapeForSingleQuotedJsString((0, driver_1.resolveDatabaseUrlEnv)(handoff.config));
264
- // Asset storage selection baked (adapter + module + options JSON with `{ $env }` references).
264
+ // Asset storage selection baked (provider + module + options JSON with `{ $env }` references).
265
265
  const assetStorage = (0, resolve_1.resolveAssetStorageFromConfig)(handoff.config);
266
- const escapedAssetStorageAdapter = escapeForSingleQuotedJsString(assetStorage.adapterKind);
266
+ const escapedAssetStorageProvider = escapeForSingleQuotedJsString(assetStorage.provider);
267
267
  const escapedAssetStorageModule = escapeForSingleQuotedJsString((_j = assetStorage.module) !== null && _j !== void 0 ? _j : '');
268
268
  const escapedAssetStorageMaxInline = escapeForSingleQuotedJsString(String(assetStorage.maxInlineBytes));
269
269
  const escapedAssetStorageOptions = escapeForSingleQuotedJsString(JSON.stringify((_k = assetStorage.options) !== null && _k !== void 0 ? _k : {}));
270
270
  const email = (0, resolve_2.resolveEmailFromConfig)(handoff.config);
271
- const escapedEmailProvider = escapeForSingleQuotedJsString(email.provider);
272
- const escapedEmailFrom = escapeForSingleQuotedJsString((_l = email.from) !== null && _l !== void 0 ? _l : '');
273
- const escapedEmailModule = escapeForSingleQuotedJsString((_m = email.module) !== null && _m !== void 0 ? _m : '');
271
+ const escapedEmailProvider = escapeForSingleQuotedJsString((_l = email.provider) !== null && _l !== void 0 ? _l : '');
272
+ const escapedEmailFrom = escapeForSingleQuotedJsString((_m = email.from) !== null && _m !== void 0 ? _m : '');
273
+ const escapedEmailModule = escapeForSingleQuotedJsString((_o = email.module) !== null && _o !== void 0 ? _o : '');
274
274
  const escapedEmailOptions = escapeForSingleQuotedJsString(JSON.stringify(email.options));
275
275
  // AI assistant selection baked (enabled flag + declared connections + default model). Connections
276
276
  // carry env-var names and non-secret options only; keys are read from their named env var at
@@ -278,7 +278,7 @@ const initializeProjectApp = (handoff_1, ...args_1) => __awaiter(void 0, [handof
278
278
  const ai = (0, connections_1.resolveAiFromConfig)(handoff.config);
279
279
  const escapedAiEnabled = escapeForSingleQuotedJsString(String(ai.enabled));
280
280
  const escapedAiConnections = escapeForSingleQuotedJsString(JSON.stringify(ai.connections));
281
- const escapedAiDefaultModel = escapeForSingleQuotedJsString((_o = ai.defaultModel) !== null && _o !== void 0 ? _o : '');
281
+ const escapedAiDefaultModel = escapeForSingleQuotedJsString((_p = ai.defaultModel) !== null && _p !== void 0 ? _p : '');
282
282
  const placeholderValues = {
283
283
  '%HANDOFF_PROJECT_ID%': escapedProjectId,
284
284
  '%HANDOFF_APP_BASE_PATH%': escapedAppBasePath,
@@ -291,7 +291,7 @@ const initializeProjectApp = (handoff_1, ...args_1) => __awaiter(void 0, [handof
291
291
  '%HANDOFF_MCP_ENABLED%': escapedMcpEnabled,
292
292
  '%HANDOFF_REGISTRY_DRIVER%': escapedRegistryDriver,
293
293
  '%HANDOFF_REGISTRY_DATABASE_URL_ENV%': escapedDatabaseUrlEnv,
294
- '%HANDOFF_ASSET_STORAGE_ADAPTER%': escapedAssetStorageAdapter,
294
+ '%HANDOFF_ASSET_STORAGE_PROVIDER%': escapedAssetStorageProvider,
295
295
  '%HANDOFF_ASSET_STORAGE_MODULE%': escapedAssetStorageModule,
296
296
  '%HANDOFF_ASSET_STORAGE_MAX_INLINE_BYTES%': escapedAssetStorageMaxInline,
297
297
  '%HANDOFF_ASSET_STORAGE_OPTIONS%': escapedAssetStorageOptions,
@@ -406,7 +406,7 @@ ${aiOptionEnvs.map((name) => `- \`${name}\` — read by a custom AI provider at
406
406
  merged over the list this build baked in, keyed by \`id\`. Use it to add or repoint a provider
407
407
  without rebuilding.
408
408
  `;
409
- const assetStorageEnvs = assetStorage.adapterKind === 'custom' ? (0, from_env_1.envReferenceNames)(assetStorage.options) : [];
409
+ const assetStorageEnvs = assetStorage.provider === 'custom' ? (0, from_env_1.envReferenceNames)(assetStorage.options) : [];
410
410
  const emailEnvs = (0, from_env_1.envReferenceNames)(email.options);
411
411
  const emailSection = !email.from
412
412
  ? 'Email delivery is off because `runtime.registry.email.from` is not set. Invitation links are shown once to an administrator for manual delivery.'
@@ -427,7 +427,7 @@ and \`.next/static/\` already copied alongside so the server serves them.
427
427
  - \`${databaseUrlEnv}\` — PostgreSQL/Neon connection string, read at request time.
428
428
  - \`AUTH_SECRET\` — a long, random secret used to sign browser sessions.
429
429
  - \`AUTH_URL\` — the canonical public registry URL, including the configured base path.
430
- ${assetStorageEnvs.map((name) => `- \`${name}\` — read by the custom asset storage adapter at request time.\n`).join('')}
430
+ ${assetStorageEnvs.map((name) => `- \`${name}\` — read by the custom asset storage provider at request time.\n`).join('')}
431
431
  ${emailSection}
432
432
  ${aiSection}
433
433
  ## Database migrations
@@ -498,8 +498,8 @@ For multi-instance self-hosting, front \`/_next/static\` with a CDN and configur
498
498
 
499
499
  ## Deploying to Vercel
500
500
 
501
- Vercel does **not** use \`output: 'standalone'\` — it ignores that setting and builds with its own
502
- adapter, so this pre-built bundle is **not** the artifact you deploy there. For Vercel, deploy the
501
+ Vercel does **not** use \`output: 'standalone'\` — it ignores that setting and runs its
502
+ own build, so this pre-built bundle is **not** the artifact you deploy there. For Vercel, deploy the
503
503
  registry app via Vercel's Git/CLI source build (it produces and serves the dynamic app itself) and
504
504
  supply the same environment variables above as project env vars. Use this standalone bundle for
505
505
  containers, custom Node servers, and other non-Vercel hosts.
@@ -510,7 +510,7 @@ containers, custom Node servers, and other non-Vercel hosts.
510
510
  * Resolve the set of npm packages the packaged registry app must be able to `require`/`import` at
511
511
  * runtime, given the configured database driver. `next`/`react`/`react-dom` run the server and React
512
512
  * runtime; `drizzle-orm` backs both the request-time DB client and the migration runner; the MCP SDK
513
- * (and its `zod` peer) is only needed when `/api/mcp/` is enabled; the driver package is
513
+ * is only needed when `/api/mcp/` is enabled; the driver package is
514
514
  * driver-specific (the Neon serverless driver also needs `ws` for its Node WebSocket transport); the
515
515
  * SMTP email provider needs `nodemailer`.
516
516
  */
@@ -520,7 +520,7 @@ const getRequiredRegistryRuntimeModules = (handoff) => {
520
520
  // The assistant runs the MCP tools in-process, so it needs the MCP SDK whether or not the HTTP
521
521
  // endpoint is served.
522
522
  if ((0, config_1.isMcpEnabled)(handoff.config) || ai.enabled) {
523
- base.push('@modelcontextprotocol/sdk', 'zod');
523
+ base.push('@modelcontextprotocol/sdk');
524
524
  }
525
525
  if (ai.enabled) {
526
526
  base.push('ai', '@ai-sdk/openai-compatible');
@@ -559,7 +559,7 @@ const getCustomServerModules = (handoff) => {
559
559
  const assetStorage = (0, resolve_1.resolveAssetStorageFromConfig)(handoff.config);
560
560
  const email = (0, resolve_2.resolveEmailFromConfig)(handoff.config);
561
561
  const modules = [
562
- assetStorage.adapterKind === 'custom' ? assetStorage.module : undefined,
562
+ assetStorage.provider === 'custom' ? assetStorage.module : undefined,
563
563
  email.provider === 'custom' ? email.module : undefined,
564
564
  ...(0, connections_1.resolveAiFromConfig)(handoff.config).connections.map((connection) => connection.module),
565
565
  ];
@@ -586,7 +586,7 @@ const copyCustomServerModules = (handoff, tracingRoot, entryDir) => __awaiter(vo
586
586
  `Install the packages it imports so that they resolve from "${handoff.workingPath}".`);
587
587
  }
588
588
  if ([...fileList].some((file) => file.split(path_1.default.sep).join('/').endsWith('node_modules/handoff-app/dist/index.js'))) {
589
- throw new HandoffBuildError(`The custom server module "${module}" imports "handoff-app", which loads the whole CLI. Import the define helpers from "handoff-app/define".`);
589
+ throw new HandoffBuildError(`The custom server module "${module}" imports "handoff-app", which loads the whole CLI. Import the define helpers from "handoff-app/providers".`);
590
590
  }
591
591
  fileList.forEach((file) => files.add(file));
592
592
  }
@@ -72,7 +72,7 @@ const buildServerRuntimeConfig = (config, modeOverride) => {
72
72
  databaseUrlEnv: (0, driver_1.resolveDatabaseUrlEnv)(config),
73
73
  },
74
74
  assetStorage: {
75
- adapter: assetStorage.adapterKind,
75
+ provider: assetStorage.provider,
76
76
  module: assetStorage.module,
77
77
  maxInlineBytes: assetStorage.maxInlineBytes,
78
78
  options: assetStorage.options,
@@ -11,7 +11,6 @@ const mergeWith_1 = __importDefault(require("lodash/mergeWith"));
11
11
  const omit_1 = __importDefault(require("lodash/omit"));
12
12
  const module_1 = require("module");
13
13
  const path_1 = __importDefault(require("path"));
14
- const resolve_1 = require("../registry/email/resolve");
15
14
  const logger_1 = require("../utils/logger");
16
15
  const path_2 = require("../utils/path");
17
16
  const defaults_1 = require("./defaults");
@@ -179,7 +178,7 @@ const replaceValues = (destination, source) => {
179
178
  * the deep merge never mixes the settings of two providers.
180
179
  */
181
180
  const resetEmailOnProviderChange = (layers) => {
182
- let provider = resolve_1.DEFAULT_EMAIL_PROVIDER;
181
+ let provider;
183
182
  let start = 0;
184
183
  layers.forEach((layer, index) => {
185
184
  var _a, _b, _c;
package/dist/index.d.ts CHANGED
@@ -261,8 +261,8 @@ export { defineConfig } from './config';
261
261
  export { fromEnv } from './config/from-env';
262
262
  export type { EnvValue, EnvSecret, RuntimeEnvReference } from './config/from-env';
263
263
  export type { CatalogItem, CatalogItemEntries, CatalogItemInput, CatalogItemMeta, CatalogPreview, CompositionRef, Preview, SourceDescriptor, SourceFormat, RendererKind, } from './catalog';
264
- export { defineAssetStorage } from './registry/asset-storage/define';
265
- export type { AssetStorage, AssetStorageContext, AssetStorageFactory, AssetStorageInput, AssetStorageReadResult, AssetUpload, AssetUploadInput, } from './registry/asset-storage/types';
264
+ export { defineStorageProvider } from './registry/asset-storage/define';
265
+ export type { StorageProvider, StorageProviderContext, StorageProviderFactory, StorageInput, StorageReadResult, AssetUpload, AssetUploadInput, } from './registry/asset-storage/types';
266
266
  export { defineEmailProvider } from './registry/email/define';
267
267
  export type { EmailMessage, EmailProvider, EmailProviderContext, EmailProviderFactory } from './registry/email/types';
268
268
  export { defineAiProvider } from './ai/define';
package/dist/index.js CHANGED
@@ -35,7 +35,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
35
35
  return (mod && mod.__esModule) ? mod : { "default": mod };
36
36
  };
37
37
  Object.defineProperty(exports, "__esModule", { value: true });
38
- exports.CoreTypes = exports.CoreTransformerUtils = exports.CoreTransformers = exports.defineAiProvider = exports.defineEmailProvider = exports.defineAssetStorage = exports.fromEnv = exports.defineConfig = void 0;
38
+ exports.CoreTypes = exports.CoreTransformerUtils = exports.CoreTransformers = exports.defineAiProvider = exports.defineEmailProvider = exports.defineStorageProvider = exports.fromEnv = exports.defineConfig = void 0;
39
39
  require("./config/env");
40
40
  const fs_extra_1 = __importDefault(require("fs-extra"));
41
41
  const handoff_core_1 = require("handoff-core");
@@ -643,7 +643,7 @@ Object.defineProperty(exports, "defineConfig", { enumerable: true, get: function
643
643
  var from_env_1 = require("./config/from-env");
644
644
  Object.defineProperty(exports, "fromEnv", { enumerable: true, get: function () { return from_env_1.fromEnv; } });
645
645
  var define_1 = require("./registry/asset-storage/define");
646
- Object.defineProperty(exports, "defineAssetStorage", { enumerable: true, get: function () { return define_1.defineAssetStorage; } });
646
+ Object.defineProperty(exports, "defineStorageProvider", { enumerable: true, get: function () { return define_1.defineStorageProvider; } });
647
647
  var define_2 = require("./registry/email/define");
648
648
  Object.defineProperty(exports, "defineEmailProvider", { enumerable: true, get: function () { return define_2.defineEmailProvider; } });
649
649
  var define_3 = require("./ai/define");
@@ -78,6 +78,6 @@ export interface NavData {
78
78
  export { getNavData } from './resolver';
79
79
  export type { GetNavDataInput } from './resolver';
80
80
  export { getWorkspaceNavData } from './workspace';
81
- export type { WorkspaceNavAdapterOptions, WorkspaceNavLoaders } from './workspace';
81
+ export type { WorkspaceNavOptions, WorkspaceNavLoaders } from './workspace';
82
82
  export { getRegistryNavData } from './registry';
83
- export type { RegistryNavAdapterOptions, RegistryNavRecords } from './registry';
83
+ export type { RegistryNavOptions, RegistryNavRecords } from './registry';
@@ -5,11 +5,11 @@ export interface RegistryNavRecords {
5
5
  pages: NavPageRecord[];
6
6
  tokenSets: NavTokenSet[];
7
7
  }
8
- export interface RegistryNavAdapterOptions {
8
+ export interface RegistryNavOptions {
9
9
  shell: SectionLink[];
10
10
  load: NavLoad;
11
11
  basePath?: string;
12
12
  fetchRecords: () => Promise<RegistryNavRecords>;
13
13
  }
14
- /** Registry adapter: shell-only initial load, or one best-effort runtime-record fetch on refresh. */
15
- export declare const getRegistryNavData: (options: RegistryNavAdapterOptions) => Promise<NavData>;
14
+ /** Registry nav data: shell-only initial load, or one best-effort runtime-record fetch on refresh. */
15
+ export declare const getRegistryNavData: (options: RegistryNavOptions) => Promise<NavData>;
@@ -13,7 +13,7 @@ exports.getRegistryNavData = void 0;
13
13
  const menu_shell_1 = require("../utils/menu-shell");
14
14
  const resolver_1 = require("./resolver");
15
15
  const emptyRecords = () => ({ components: [], patterns: [], pages: [], tokenSets: [] });
16
- /** Registry adapter: shell-only initial load, or one best-effort runtime-record fetch on refresh. */
16
+ /** Registry nav data: shell-only initial load, or one best-effort runtime-record fetch on refresh. */
17
17
  const getRegistryNavData = (options) => __awaiter(void 0, void 0, void 0, function* () {
18
18
  var _a;
19
19
  let records = emptyRecords();
@@ -6,13 +6,13 @@ export interface WorkspaceNavLoaders {
6
6
  pages: () => Awaitable<NavPageRecord[]>;
7
7
  tokenSets: () => Awaitable<NavTokenSet[]>;
8
8
  }
9
- export interface WorkspaceNavAdapterOptions {
9
+ export interface WorkspaceNavOptions {
10
10
  docRoot: string;
11
11
  workingPagesDir?: string;
12
12
  basePath?: string;
13
13
  load?: NavLoad;
14
14
  loaders: WorkspaceNavLoaders;
15
15
  }
16
- /** Workspace/static adapter: live filesystem shell plus best-effort local snapshot loaders. */
17
- export declare const getWorkspaceNavData: (options: WorkspaceNavAdapterOptions) => Promise<NavData>;
16
+ /** Workspace/static nav data: live filesystem shell plus best-effort local snapshot loaders. */
17
+ export declare const getWorkspaceNavData: (options: WorkspaceNavOptions) => Promise<NavData>;
18
18
  export {};
@@ -64,7 +64,7 @@ const markdownTitle = (id, docRoot, workingPagesDir) => {
64
64
  }
65
65
  return undefined;
66
66
  };
67
- /** Workspace/static adapter: live filesystem shell plus best-effort local snapshot loaders. */
67
+ /** Workspace/static nav data: live filesystem shell plus best-effort local snapshot loaders. */
68
68
  const getWorkspaceNavData = (options) => __awaiter(void 0, void 0, void 0, function* () {
69
69
  var _a;
70
70
  const [loadedComponents, patterns, pages, loadedTokenSets] = yield Promise.all([
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Define helpers for custom server modules: storage, email and AI providers. This entry point has no
3
+ * runtime dependencies, so a module that imports it does not pull the CLI into the registry bundle.
4
+ */
5
+ export { defineAiProvider } from './ai/define';
6
+ export type { AiProvider, AiProviderContext, AiProviderFactory } from './ai/types';
7
+ export { defineStorageProvider } from './registry/asset-storage/define';
8
+ export type { StorageProvider, StorageProviderContext, StorageProviderFactory, StorageInput, StorageReadResult, AssetUpload, AssetUploadInput, } from './registry/asset-storage/types';
9
+ export { defineEmailProvider } from './registry/email/define';
10
+ export type { EmailMessage, EmailProvider, EmailProviderContext, EmailProviderFactory } from './registry/email/types';
@@ -1,13 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.defineEmailProvider = exports.defineAssetStorage = exports.defineAiProvider = void 0;
3
+ exports.defineEmailProvider = exports.defineStorageProvider = exports.defineAiProvider = void 0;
4
4
  /**
5
- * Define helpers for custom server modules. This entry point has no runtime dependencies, so a module
6
- * that imports it does not pull the CLI into the registry bundle.
5
+ * Define helpers for custom server modules: storage, email and AI providers. This entry point has no
6
+ * runtime dependencies, so a module that imports it does not pull the CLI into the registry bundle.
7
7
  */
8
8
  var define_1 = require("./ai/define");
9
9
  Object.defineProperty(exports, "defineAiProvider", { enumerable: true, get: function () { return define_1.defineAiProvider; } });
10
10
  var define_2 = require("./registry/asset-storage/define");
11
- Object.defineProperty(exports, "defineAssetStorage", { enumerable: true, get: function () { return define_2.defineAssetStorage; } });
11
+ Object.defineProperty(exports, "defineStorageProvider", { enumerable: true, get: function () { return define_2.defineStorageProvider; } });
12
12
  var define_3 = require("./registry/email/define");
13
13
  Object.defineProperty(exports, "defineEmailProvider", { enumerable: true, get: function () { return define_3.defineEmailProvider; } });