handoff-app 2.0.0-7 → 2.0.0-8

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 (98) hide show
  1. package/README.md +111 -11
  2. package/UPGRADE.md +20 -0
  3. package/dist/app-builder/build.js +10 -2
  4. package/dist/app-builder/client-config.js +3 -1
  5. package/dist/app-builder/watchers.js +17 -7
  6. package/dist/cache/build-cache.js +5 -1
  7. package/dist/cli/auth/device.d.ts +6 -1
  8. package/dist/cli/auth/device.js +5 -2
  9. package/dist/cli/auth/store.d.ts +15 -6
  10. package/dist/cli/auth/store.js +72 -19
  11. package/dist/commands/login/index.d.ts +5 -0
  12. package/dist/commands/login/index.js +18 -6
  13. package/dist/commands/logout/index.d.ts +5 -0
  14. package/dist/commands/logout/index.js +54 -15
  15. package/dist/commands/types.d.ts +2 -0
  16. package/dist/commands/utils.d.ts +21 -7
  17. package/dist/commands/utils.js +11 -10
  18. package/dist/config/catalog-include.d.ts +2 -2
  19. package/dist/config/defaults.d.ts +3 -3
  20. package/dist/config/defaults.js +54 -48
  21. package/dist/config/env.d.ts +9 -0
  22. package/dist/config/env.js +43 -0
  23. package/dist/config/errors.d.ts +4 -0
  24. package/dist/config/errors.js +11 -0
  25. package/dist/config/from-env.d.ts +24 -0
  26. package/dist/config/from-env.js +7 -0
  27. package/dist/config/helpers.d.ts +2 -0
  28. package/dist/config/helpers.js +3 -1
  29. package/dist/config/index.d.ts +2 -1
  30. package/dist/config/index.js +6 -1
  31. package/dist/config/loader.d.ts +29 -11
  32. package/dist/config/loader.js +119 -46
  33. package/dist/config/resolve-env.d.ts +5 -0
  34. package/dist/config/resolve-env.js +102 -0
  35. package/dist/config/runtime.d.ts +3 -3
  36. package/dist/config/validator.d.ts +2 -2
  37. package/dist/config/validator.js +2 -4
  38. package/dist/index.d.ts +33 -4
  39. package/dist/index.js +60 -16
  40. package/dist/pipeline/index.d.ts +1 -1
  41. package/dist/pipeline/index.js +1 -1
  42. package/dist/registry/asset-storage/adapters/vercel-blob.js +1 -1
  43. package/dist/registry/asset-storage/resolve.d.ts +2 -2
  44. package/dist/registry/asset-storage/resolve.js +4 -1
  45. package/dist/registry/checkout/index.js +4 -4
  46. package/dist/registry/connection.d.ts +28 -24
  47. package/dist/registry/connection.js +53 -67
  48. package/dist/registry/db/driver.d.ts +4 -11
  49. package/dist/registry/db/driver.js +4 -16
  50. package/dist/registry/db/index.d.ts +1 -1
  51. package/dist/registry/db/index.js +1 -2
  52. package/dist/registry/publish/index.js +4 -4
  53. package/dist/store/filesystem.d.ts +2 -2
  54. package/dist/types/config.d.ts +48 -29
  55. package/docs/api.md +31 -0
  56. package/docs/cli.md +2 -2
  57. package/package.json +1 -1
  58. package/src/app/pages/account/tokens.tsx +3 -1
  59. package/src/app-builder/build.ts +10 -2
  60. package/src/app-builder/client-config.ts +5 -3
  61. package/src/app-builder/watchers.ts +18 -8
  62. package/src/cache/build-cache.ts +5 -1
  63. package/src/cli/auth/device.ts +8 -3
  64. package/src/cli/auth/store.ts +75 -18
  65. package/src/commands/login/index.ts +20 -6
  66. package/src/commands/logout/index.ts +74 -20
  67. package/src/commands/types.ts +2 -0
  68. package/src/commands/utils.ts +14 -5
  69. package/src/config/README.md +61 -1
  70. package/src/config/catalog-include.ts +2 -2
  71. package/src/config/defaults.ts +24 -14
  72. package/src/config/env.ts +41 -0
  73. package/src/config/errors.ts +7 -0
  74. package/src/config/from-env.ts +26 -0
  75. package/src/config/helpers.ts +4 -2
  76. package/src/config/index.ts +4 -1
  77. package/src/config/loader.ts +156 -50
  78. package/src/config/resolve-env.ts +94 -0
  79. package/src/config/runtime.ts +3 -3
  80. package/src/config/validator.ts +4 -6
  81. package/src/index.d.ts +2 -2
  82. package/src/index.ts +85 -8
  83. package/src/pipeline/index.ts +1 -1
  84. package/src/registry/asset-storage/adapters/vercel-blob.ts +1 -1
  85. package/src/registry/asset-storage/resolve.ts +6 -3
  86. package/src/registry/checkout/index.ts +5 -5
  87. package/src/registry/connection.ts +72 -71
  88. package/src/registry/db/driver.ts +6 -17
  89. package/src/registry/db/index.ts +0 -1
  90. package/src/registry/publish/index.ts +5 -5
  91. package/src/store/filesystem.ts +2 -2
  92. package/src/types/config.ts +45 -29
  93. package/templates/default/env.tpl +10 -0
  94. package/templates/default/gitignore.tpl +7 -0
  95. package/templates/default/handoff.config.js.tpl +21 -172
  96. package/templates/default/handoff.config.ts.tpl +21 -156
  97. package/templates/default/handoff.config.with-examples.js.tpl +20 -171
  98. package/templates/default/handoff.config.with-examples.ts.tpl +20 -155
@@ -1,3 +1,4 @@
1
+ import type { EnvValue, EnvSecret, RuntimeEnvReference } from '../config/from-env';
1
2
  import { BuildOptions } from 'esbuild';
2
3
  import type Handlebars from 'handlebars';
3
4
  import { Types as HandoffTypes } from 'handoff-core';
@@ -58,8 +59,8 @@ export type RegisterHandlebarsHelpersContext = {
58
59
 
59
60
  export interface NextAppConfig {
60
61
  theme?: string;
61
- title: string;
62
- client: string;
62
+ title?: string;
63
+ client?: string;
63
64
  google_tag_manager?: string | null | undefined;
64
65
  googleTagManager?: string | null | undefined;
65
66
  type_copy?: string;
@@ -68,15 +69,17 @@ export interface NextAppConfig {
68
69
  typeSort?: string[];
69
70
  color_sort?: string[];
70
71
  colorSort?: string[];
71
- breakpoints: Breakpoints;
72
+ /** Omit to keep the defaults; a declared block merges onto them rather than replacing them. */
73
+ breakpoints?: Breakpoints;
72
74
  component_sort?: string[];
73
75
  componentSort?: string[];
74
76
  base_path?: string;
75
77
  basePath?: string;
76
- attribution: boolean;
78
+ /** @default true */
79
+ attribution?: boolean;
77
80
  ports?: {
78
- app: number;
79
- websocket: number;
81
+ app: EnvValue<number>;
82
+ websocket: EnvValue<number>;
80
83
  };
81
84
  }
82
85
 
@@ -139,13 +142,8 @@ export interface HandoffRuntimeConfig {
139
142
  };
140
143
  /** Registry-mode host settings. Env-var values are stored as names, never as secrets. */
141
144
  registry?: {
142
- /** Name of the env var holding the database URL. @default "DATABASE_URL" */
143
- databaseUrlEnv?: string;
144
- /**
145
- * @deprecated Fixed registry secrets are no longer authorized. This option remains parseable
146
- * only so existing configuration files do not break.
147
- */
148
- apiTokenEnv?: string;
145
+ /** Environment reference to the database URL. @default fromEnv('DATABASE_URL') */
146
+ databaseUrl?: RuntimeEnvReference<string>;
149
147
  database?: {
150
148
  /**
151
149
  * PostgreSQL is the supported database. `driver` selects the built-in connection driver — how
@@ -168,11 +166,11 @@ export interface HandoffRuntimeConfig {
168
166
  adapter?: 'database' | 'vercel-blob' | 'custom';
169
167
  /** For `adapter: "custom"` - server-only module path default-exporting a `defineAssetStorage` adapter. */
170
168
  module?: string;
171
- /** For `adapter: "vercel-blob"` - env var name holding the Blob read/write token. @default "BLOB_READ_WRITE_TOKEN" */
172
- tokenEnv?: string;
169
+ /** For `adapter: "vercel-blob"` - environment reference to the Blob read/write token. @default fromEnv('BLOB_READ_WRITE_TOKEN') */
170
+ token?: RuntimeEnvReference<string>;
173
171
  /** Max bytes kept inline in the database `bytea` column (larger uploads are rejected). @default 4194304 */
174
172
  maxInlineBytes?: number;
175
- /** Non-secret adapter options (bucket env-var names, region, a custom `providerId`, …). */
173
+ /** Non-secret options, JSON-encoded into the bundle. Environment references are rejected. Pass variable names instead. */
176
174
  options?: Record<string, unknown>;
177
175
  };
178
176
  };
@@ -181,22 +179,21 @@ export interface HandoffRuntimeConfig {
181
179
  * `mode: 'workspace'` plus this block — it is not a third runtime mode.
182
180
  */
183
181
  registryConnection?: {
184
- url?: string;
185
- /** @default "HANDOFF_REGISTRY_URL" */
186
- urlEnv?: string;
187
- /** @default "HANDOFF_REGISTRY_ACCESS_TOKEN" */
188
- accessTokenEnv?: string;
182
+ /** @default fromEnv('HANDOFF_REGISTRY_URL', { default: '' }) */
183
+ url?: EnvValue<string>;
184
+ /** @default fromEnv('HANDOFF_REGISTRY_ACCESS_TOKEN', { default: '' }) */
185
+ accessToken?: EnvSecret<string>;
189
186
  };
190
187
  }
191
188
 
192
189
  export interface Config {
193
- dev_access_token?: string | null | undefined;
194
- devAccessToken?: string | null | undefined;
195
- figma_project_id?: string | null | undefined;
196
- figmaProjectId?: string | null | undefined;
197
- exportsOutputDirectory?: string;
198
- sitesOutputDirectory?: string;
199
- useVariables?: boolean;
190
+ dev_access_token?: EnvSecret<string | null>;
191
+ devAccessToken?: EnvSecret<string | null>;
192
+ figma_project_id?: EnvValue<string | null>;
193
+ figmaProjectId?: EnvValue<string | null>;
194
+ exportsOutputDirectory?: EnvValue<string>;
195
+ sitesOutputDirectory?: EnvValue<string>;
196
+ useVariables?: EnvValue<boolean>;
200
197
  /**
201
198
  * Configuration for React component docs generation (handoff-docgen).
202
199
  */
@@ -396,7 +393,26 @@ export interface ClientRuntimeConfig {
396
393
  connected: boolean;
397
394
  }
398
395
 
399
- export type ClientConfig = Pick<Config, 'app' | 'exportsOutputDirectory' | 'sitesOutputDirectory' | 'assets_zip_links' | 'useVariables'> & {
396
+ /** Values available after config loading. Deferred references retain their names. */
397
+ export type ResolvedConfig = Omit<
398
+ Config,
399
+ 'dev_access_token' | 'devAccessToken' | 'figma_project_id' | 'figmaProjectId' |
400
+ 'exportsOutputDirectory' | 'sitesOutputDirectory' | 'useVariables' | 'app' | 'runtime'
401
+ > & {
402
+ dev_access_token?: string | null;
403
+ devAccessToken?: string | null;
404
+ figma_project_id?: string | null;
405
+ figmaProjectId?: string | null;
406
+ exportsOutputDirectory?: string;
407
+ sitesOutputDirectory?: string;
408
+ useVariables?: boolean;
409
+ app?: Omit<NextAppConfig, 'ports'> & { ports?: { app: number; websocket: number } };
410
+ runtime?: Omit<HandoffRuntimeConfig, 'registryConnection'> & {
411
+ registryConnection?: { url?: string; accessToken?: string };
412
+ };
413
+ };
414
+
415
+ export type ClientConfig = Pick<ResolvedConfig, 'app' | 'exportsOutputDirectory' | 'sitesOutputDirectory' | 'assets_zip_links' | 'useVariables'> & {
400
416
  runtime: ClientRuntimeConfig;
401
417
  };
402
418
 
@@ -1,2 +1,12 @@
1
1
  HANDOFF_FIGMA_PROJECT_ID={{figmaProjectId}}
2
2
  HANDOFF_DEV_ACCESS_TOKEN={{figmaAccessToken}}
3
+
4
+ # Optional. Select a Handoff configuration profile.
5
+ # HANDOFF_PROFILE=local
6
+ #
7
+ # A selected profile also reads .env.<profile> on top of this file, when that file exists.
8
+
9
+ # Optional. Connect this workspace to a registry.
10
+ # A token is created in the registry under Account > Access tokens.
11
+ # HANDOFF_REGISTRY_URL=https://registry.example.com
12
+ # HANDOFF_REGISTRY_ACCESS_TOKEN=hnd_...
@@ -11,8 +11,15 @@ public/api
11
11
 
12
12
  # Environment
13
13
  .env
14
+ .env.*
14
15
  .handoff/
15
16
 
17
+ # Local configuration profile
18
+ handoff.config.local.ts
19
+ handoff.config.local.js
20
+ handoff.config.local.cjs
21
+ handoff.config.local.json
22
+
16
23
  # Deployment
17
24
  .vercel
18
25
 
@@ -1,4 +1,4 @@
1
- const { defineConfig } = require('handoff-app');
1
+ const { defineConfig, fromEnv } = require('handoff-app');
2
2
  /** @typedef {import('handoff-app').Config} HandoffConfig */
3
3
 
4
4
  /** @type {HandoffConfig} */
@@ -42,181 +42,30 @@ const config = {
42
42
  }
43
43
  },
44
44
 
45
- // catalog: {
46
- // /**
47
- // * Directories to search for catalog items. A path is either an item directory or a
48
- // * collection directory whose subdirectories are each treated as an item. An item declares
49
- // * an implementation (React, Handlebars) or a composition of other items.
50
- // */
51
- // include: ["components", "patterns"],
52
- // },
53
-
54
- // Runtime settings, all optional. The default is workspace mode with the MCP endpoint served.
55
- // `mcp: false` leaves the /api/mcp/ endpoint, and the connect affordance in the docs header, out
56
- // of the build; the route then answers 404.
57
- // The registry block is only needed when deploying a hosted registry, and is used by
58
- // `build --target registry` and `db:migrate`. The default workspace mode uses no database.
59
- // Handoff runs on PostgreSQL, and `driver` just picks the connection driver to use, not
60
- // the database engine. Secrets are referenced by env var name and never written here.
61
- // runtime: {
62
- // mode: "registry",
63
- // mcp: false,
64
- // registry: {
65
- // databaseUrlEnv: "DATABASE_URL",
66
- // database: { driver: "pg" }, // 'pg' | 'neon'
67
- // },
68
- // },
69
-
70
- // Optional handoff-docgen settings used by component docs generation
71
- // reactDocgen: {
72
- // maxDepth: 7,
73
- // excludeDirectories: ["dist", "build", ".next"]
74
- // },
75
-
76
- hooks: {
77
- /**
78
- * Optional validation callback for components
79
- * @param component - The component instance to validate
80
- * @returns A record of validation results where keys are validation types and values are detailed validation results
81
- *
82
- * @example
83
- * validateComponent: async (component) => ({
84
- * a11y: {
85
- * description: 'Accessibility validation check',
86
- * passed: true,
87
- * messages: ['No accessibility issues found']
88
- * },
89
- * responsive: {
90
- * description: 'Responsive design validation',
91
- * passed: false,
92
- * messages: ['Component breaks at mobile breakpoint']
93
- * }
94
- * })
95
- */
96
- // validateComponent: async (component) => {
97
- // // Add your custom validation logic here
98
- // return {};
99
- // },
100
-
101
- /**
102
- * Optional hook to override the SSR build configuration used in the ssrRenderPlugin
103
- * @param config - The default esbuild configuration
104
- * @returns Modified esbuild configuration
105
- *
106
- * @example
107
- * ssrBuildConfig: (config) => {
108
- * // Modify the esbuild config as needed
109
- * return config;
110
- * }
111
- */
112
- // ssrBuildConfig: (config) => {
113
- // // Add your custom SSR build configuration here
114
- // return config;
115
- // },
116
-
117
- /**
118
- * Optional hook to override the client-side build configuration used in the ssrRenderPlugin
119
- * @param config - The default esbuild configuration
120
- * @returns Modified esbuild configuration
121
- *
122
- * @example
123
- * clientBuildConfig: (config) => {
124
- * // Modify the esbuild config as needed
125
- * return config;
126
- * }
127
- */
128
- // clientBuildConfig: (config) => {
129
- // // Add your custom client build configuration here
130
- // return config;
131
- // },
45
+ // Where catalog items live. A path is either an item directory, or a collection directory whose
46
+ // subdirectories are each an item.
47
+ // catalog: { include: ["components", "patterns"] },
132
48
 
133
- /**
134
- * Optional hook to specify which export property contains the schema
135
- * @param exports - The module exports object containing the schema
136
- * @returns The schema object from the exports
137
- *
138
- * @example
139
- * getSchemaFromExports: (exports) => exports.customSchema || exports.default
140
- */
141
- // getSchemaFromExports: (exports) => {
142
- // // Add your custom schema extraction logic here
143
- // return exports.default;
144
- // },
145
-
146
- /**
147
- * Optional hook to transform the schema into properties
148
- * @param schema - The schema object to transform
149
- * @returns The transformed properties object
150
- */
151
- // schemaToProperties: (schema) => {
152
- // // Add your custom schema to properties transformation here
153
- // return {};
154
- // },
155
-
156
- /**
157
- * Optional hook to override the JavaScript Vite configuration
158
- * @param config - The default Vite configuration
159
- * @returns Modified Vite configuration
160
- *
161
- * @example
162
- * jsBuildConfig: (config) => {
163
- * // Modify the Vite config as needed
164
- * return config;
165
- * }
166
- */
167
- // jsBuildConfig: (config) => {
168
- // // Add your custom JavaScript build configuration here
169
- // return config;
170
- // },
171
-
172
- /**
173
- * Optional hook to override the CSS Vite configuration
174
- * @param config - The default Vite configuration
175
- * @returns Modified Vite configuration
176
- *
177
- * @example
178
- * cssBuildConfig: (config) => {
179
- * // Modify the Vite config as needed
180
- * return config;
181
- * }
182
- */
183
- // cssBuildConfig: (config) => {
184
- // // Add your custom CSS build configuration here
185
- // return config;
49
+ // `mode` selects the runtime: "workspace" (no database) or "registry" (Postgres). The registry
50
+ // block is read only by `build --target registry` and `db:migrate`, and secrets are referenced by
51
+ // env var name. A named profile (`handoff.config.registry.*`, `--profile registry`) is a good home
52
+ // for it.
53
+ runtime: {
54
+ mode: "workspace",
55
+ // mcp: false,
56
+ // registry: {
57
+ // databaseUrl: fromEnv("DATABASE_URL"),
58
+ // database: { driver: "pg" }, // 'pg' | 'neon'
186
59
  // },
60
+ },
187
61
 
188
- /**
189
- * Optional hook to override the HTML Vite configuration
190
- * @param config - The default Vite configuration
191
- * @returns Modified Vite configuration
192
- *
193
- * @example
194
- * htmlBuildConfig: (config) => {
195
- * // Modify the Vite config as needed
196
- * return config;
197
- * }
198
- */
199
- // htmlBuildConfig: (config) => {
200
- // // Add your custom HTML build configuration here
201
- // return config;
202
- // },
62
+ // reactDocgen: { maxDepth: 7, excludeDirectories: ["dist", "build", ".next"] },
203
63
 
204
- /**
205
- * Optional hook run after built-in Handlebars helpers (`field`, `eq`) for preview HTML.
206
- * @param context.handlebars - Handlebars module (use registerHelper)
207
- * @param context.componentId - Current component id
208
- * @param context.properties - Slot metadata map from the schema
209
- * @param context.injectFieldWrappers - True when generating inspect-mode previews
210
- *
211
- * @example
212
- * registerHandlebarsHelpers: ({ handlebars, componentId }) => {
213
- * handlebars.registerHelper('upperId', () => componentId.toUpperCase());
214
- * }
215
- */
216
- // registerHandlebarsHelpers: ({ handlebars, componentId, properties, injectFieldWrappers }) => {
217
- // // Add your custom Handlebars helpers here
218
- // },
219
- },
64
+ // Optional build hooks: component validation, esbuild and Vite config overrides, Handlebars
65
+ // helper registration. Signatures and examples are on the `Config` type.
66
+ // hooks: {
67
+ // validateComponent: async (component) => ({}),
68
+ // },
220
69
  };
221
70
 
222
71
  module.exports = defineConfig(config);
@@ -1,4 +1,4 @@
1
- import { defineConfig } from 'handoff-app';
1
+ import { defineConfig, fromEnv } from 'handoff-app';
2
2
 
3
3
  export default defineConfig({
4
4
  app: {
@@ -40,163 +40,28 @@ export default defineConfig({
40
40
  }
41
41
  },
42
42
 
43
- // catalog: {
44
- // /**
45
- // * Directories to search for catalog items. A path is either an item directory or a
46
- // * collection directory whose subdirectories are each treated as an item. An item declares
47
- // * an implementation (React, Handlebars) or a composition of other items.
48
- // */
49
- // include: ["components", "patterns"],
50
- // },
51
-
52
- // Runtime settings, all optional. The default is workspace mode with the MCP endpoint served.
53
- // `mcp: false` leaves the /api/mcp/ endpoint, and the connect affordance in the docs header, out
54
- // of the build; the route then answers 404.
55
- // The registry block is only needed when deploying a hosted registry, and is used by
56
- // `build --target registry` and `db:migrate`. The default workspace mode uses no database.
57
- // Handoff runs on PostgreSQL, and `driver` just picks the connection driver to use, not
58
- // the database engine. Secrets are referenced by env var name and never written here.
59
- // runtime: {
60
- // mode: "registry",
61
- // mcp: false,
62
- // registry: {
63
- // databaseUrlEnv: "DATABASE_URL",
64
- // database: { driver: "pg" }, // 'pg' | 'neon'
65
- // },
66
- // },
67
-
68
- // Optional handoff-docgen settings used by component docs generation
69
- // reactDocgen: {
70
- // maxDepth: 7,
71
- // excludeDirectories: ["dist", "build", ".next"]
72
- // },
73
-
74
- hooks: {
75
- /**
76
- * Optional validation callback for components
77
- * @param component - The component instance to validate
78
- * @returns A record of validation results where keys are validation types and values are detailed validation results
79
- *
80
- * @example
81
- * validateComponent: async (component) => ({
82
- * a11y: {
83
- * description: 'Accessibility validation check',
84
- * passed: true,
85
- * messages: ['No accessibility issues found']
86
- * },
87
- * responsive: {
88
- * description: 'Responsive design validation',
89
- * passed: false,
90
- * messages: ['Component breaks at mobile breakpoint']
91
- * }
92
- * })
93
- */
94
- // validateComponent: async (component) => {
95
- // // Add your custom validation logic here
96
- // return {};
97
- // },
98
-
99
- /**
100
- * Optional hook to override the SSR build configuration used in the ssrRenderPlugin
101
- * @param config - The default esbuild configuration
102
- * @returns Modified esbuild configuration
103
- *
104
- * @example
105
- * ssrBuildConfig: (config) => {
106
- * // Modify the esbuild config as needed
107
- * return config;
108
- * }
109
- */
110
- // ssrBuildConfig: (config) => {
111
- // // Add your custom SSR build configuration here
112
- // return config;
113
- // },
114
-
115
- /**
116
- * Optional hook to override the client-side build configuration used in the ssrRenderPlugin
117
- * @param config - The default esbuild configuration
118
- * @returns Modified esbuild configuration
119
- *
120
- * @example
121
- * clientBuildConfig: (config) => {
122
- * // Modify the esbuild config as needed
123
- * return config;
124
- * }
125
- */
126
- // clientBuildConfig: (config) => {
127
- // // Add your custom client build configuration here
128
- // return config;
129
- // },
130
-
131
- /**
132
- * Optional hook to specify which export property contains the schema
133
- * @param exports - The module exports object containing the schema
134
- * @returns The schema object from the exports
135
- *
136
- * @example
137
- * getSchemaFromExports: (exports) => exports.customSchema || exports.default
138
- */
139
- // getSchemaFromExports: (exports) => {
140
- // // Add your custom schema extraction logic here
141
- // return exports.default;
142
- // },
143
-
144
- /**
145
- * Optional hook to transform the schema into properties
146
- * @param schema - The schema object to transform
147
- * @returns The transformed properties object
148
- */
149
- // schemaToProperties: (schema) => {
150
- // // Add your custom schema to properties transformation here
151
- // return {};
152
- // },
43
+ // Where catalog items live. A path is either an item directory, or a collection directory whose
44
+ // subdirectories are each an item.
45
+ // catalog: { include: ["components", "patterns"] },
153
46
 
154
- /**
155
- * Optional hook to override the JavaScript Vite configuration
156
- * @param config - The default Vite configuration
157
- * @returns Modified Vite configuration
158
- *
159
- * @example
160
- * jsBuildConfig: (config) => {
161
- * // Modify the Vite config as needed
162
- * return config;
163
- * }
164
- */
165
- // jsBuildConfig: (config) => {
166
- // // Add your custom JavaScript build configuration here
167
- // return config;
47
+ // `mode` selects the runtime: "workspace" (no database) or "registry" (Postgres). The registry
48
+ // block is read only by `build --target registry` and `db:migrate`, and secrets are referenced by
49
+ // env var name. A named profile (`handoff.config.registry.*`, `--profile registry`) is a good home
50
+ // for it.
51
+ runtime: {
52
+ mode: "workspace",
53
+ // mcp: false,
54
+ // registry: {
55
+ // databaseUrl: fromEnv("DATABASE_URL"),
56
+ // database: { driver: "pg" }, // 'pg' | 'neon'
168
57
  // },
58
+ },
169
59
 
170
- /**
171
- * Optional hook to override the CSS Vite configuration
172
- * @param config - The default Vite configuration
173
- * @returns Modified Vite configuration
174
- *
175
- * @example
176
- * cssBuildConfig: (config) => {
177
- * // Modify the Vite config as needed
178
- * return config;
179
- * }
180
- */
181
- // cssBuildConfig: (config) => {
182
- // // Add your custom CSS build configuration here
183
- // return config;
184
- // },
60
+ // reactDocgen: { maxDepth: 7, excludeDirectories: ["dist", "build", ".next"] },
185
61
 
186
- /**
187
- * Optional hook to override the HTML Vite configuration
188
- * @param config - The default Vite configuration
189
- * @returns Modified Vite configuration
190
- *
191
- * @example
192
- * htmlBuildConfig: (config) => {
193
- * // Modify the Vite config as needed
194
- * return config;
195
- * }
196
- */
197
- // htmlBuildConfig: (config) => {
198
- // // Add your custom HTML build configuration here
199
- // return config;
200
- // },
201
- },
62
+ // Optional build hooks: component validation, esbuild and Vite config overrides, Handlebars
63
+ // helper registration. Signatures and examples are on the `Config` type.
64
+ // hooks: {
65
+ // validateComponent: async (component) => ({}),
66
+ // },
202
67
  });