handoff-app 2.0.0-8 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{Changelog.md → CHANGELOG.md} +85 -1
- package/{License.md → LICENSE.md} +1 -1
- package/README.md +816 -393
- package/RECIPES.md +975 -0
- package/UPGRADE.md +57 -9
- package/components.json +20 -20
- package/config/docs/foundations/colors/guidelines.md +0 -1
- package/config/docs/foundations/colors.md +0 -1
- package/config/docs/foundations/effects/guidelines.md +0 -1
- package/config/docs/foundations/effects/resources.md +0 -1
- package/config/docs/foundations/effects.md +0 -1
- package/config/docs/foundations/fonts.md +0 -1
- package/config/docs/foundations/grid.md +0 -1
- package/config/docs/foundations/icon.md +0 -1
- package/config/docs/foundations/icons/guidelines.md +0 -1
- package/config/docs/foundations/icons.md +0 -1
- package/config/docs/foundations/images/guidelines.md +0 -1
- package/config/docs/foundations/images/resources.md +0 -1
- package/config/docs/foundations/images.md +0 -1
- package/config/docs/foundations/logo/resources.md +0 -1
- package/config/docs/foundations/logo.md +0 -1
- package/config/docs/foundations/typography/guidelines.md +0 -1
- package/config/docs/foundations/typography/resources.md +0 -1
- package/config/docs/foundations/typography.md +0 -1
- package/config/docs/foundations.md +0 -1
- package/config/docs/guidelines.md +0 -1
- package/config/docs/index.md +0 -1
- package/config/docs/system/tokens/foundations/colors.md +0 -4
- package/config/docs/system/tokens/foundations/effects.md +0 -4
- package/config/docs/system/tokens/foundations/typography.md +0 -2
- package/config/docs/system.md +0 -2
- package/config/templates/page.md +2 -1
- package/config/templates/page.mdx +2 -1
- package/dist/ai/connections.d.ts +66 -0
- package/dist/ai/connections.js +149 -0
- package/dist/ai/define.d.ts +10 -0
- package/dist/ai/define.js +13 -0
- package/dist/ai/types.d.ts +26 -0
- package/dist/ai/types.js +10 -0
- package/dist/app-builder/build.d.ts +14 -7
- package/dist/app-builder/build.js +195 -66
- package/dist/app-builder/client-config.js +3 -2
- package/dist/app-builder/paths.d.ts +0 -12
- package/dist/app-builder/paths.js +3 -20
- package/dist/app-builder/static-export.js +1 -1
- package/dist/app-builder/vercel-output.d.ts +1 -1
- package/dist/app-builder/vercel-output.js +5 -4
- package/dist/cache/build-cache.d.ts +27 -4
- package/dist/cache/build-cache.js +114 -47
- package/dist/cache/build-inputs.d.ts +13 -0
- package/dist/cache/build-inputs.js +19 -0
- package/dist/cache/index.d.ts +2 -1
- package/dist/cache/index.js +5 -1
- package/dist/catalog/normalize.js +3 -0
- package/dist/catalog/previews.js +5 -4
- package/dist/catalog/types.d.ts +8 -0
- package/dist/cli/create.js +1 -2
- package/dist/commands/build/index.d.ts +1 -1
- package/dist/commands/build/index.js +1 -1
- package/dist/commands/utils.d.ts +3 -3
- package/dist/config/defaults.js +7 -4
- package/dist/config/from-env.d.ts +4 -0
- package/dist/config/from-env.js +38 -1
- package/dist/config/helpers.js +2 -2
- package/dist/config/index.d.ts +0 -1
- package/dist/config/index.js +1 -4
- package/dist/config/loader.js +28 -2
- package/dist/config/resolve-env.d.ts +2 -1
- package/dist/config/resolve-env.js +28 -12
- package/dist/config/runtime.js +9 -11
- package/dist/handlebars.d.ts +10 -2
- package/dist/index.d.ts +12 -7
- package/dist/index.js +18 -22
- package/dist/nav/index.d.ts +2 -2
- package/dist/nav/registry.d.ts +3 -3
- package/dist/nav/registry.js +1 -1
- package/dist/nav/workspace.d.ts +3 -3
- package/dist/nav/workspace.js +1 -1
- package/dist/pipeline/figma.d.ts +13 -2
- package/dist/pipeline/figma.js +86 -46
- package/dist/pipeline/styles.js +1 -1
- package/dist/pipeline/validation.d.ts +1 -1
- package/dist/pipeline/validation.js +3 -3
- package/dist/providers.d.ts +10 -0
- package/dist/providers.js +13 -0
- package/dist/registry/asset-storage/define.d.ts +5 -5
- package/dist/registry/asset-storage/define.js +4 -4
- package/dist/registry/asset-storage/resolve.d.ts +9 -19
- package/dist/registry/asset-storage/resolve.js +33 -21
- package/dist/registry/asset-storage/types.d.ts +37 -17
- package/dist/registry/asset-storage/types.js +5 -5
- package/dist/registry/auth/ai-keys.d.ts +32 -0
- package/dist/registry/auth/ai-keys.js +69 -0
- package/dist/registry/auth/crypto.d.ts +17 -0
- package/dist/registry/auth/crypto.js +61 -1
- package/dist/registry/auth/index.d.ts +2 -1
- package/dist/registry/auth/index.js +11 -2
- package/dist/registry/checkout/index.d.ts +2 -1
- package/dist/registry/checkout/index.js +57 -127
- package/dist/registry/client.js +53 -17
- package/dist/registry/db/driver.js +3 -3
- package/dist/registry/db/schema.d.ts +261 -3
- package/dist/registry/db/schema.js +29 -4
- package/dist/registry/email/define.d.ts +10 -0
- package/dist/registry/email/define.js +13 -0
- package/dist/registry/email/providers/smtp.d.ts +10 -0
- package/dist/registry/email/providers/smtp.js +73 -0
- package/dist/registry/email/resolve.d.ts +28 -0
- package/dist/registry/email/resolve.js +74 -0
- package/dist/registry/email/types.d.ts +24 -0
- package/dist/registry/email/types.js +6 -0
- package/dist/registry/path.d.ts +2 -0
- package/dist/registry/path.js +11 -1
- package/dist/registry/publish/package.js +8 -0
- package/dist/registry/transfer.d.ts +4 -0
- package/dist/store/registry.d.ts +3 -3
- package/dist/store/registry.js +4 -4
- package/dist/transformers/plugins/ssr-render.js +40 -15
- package/dist/transformers/preview/component/builder.d.ts +1 -9
- package/dist/transformers/preview/component/builder.js +17 -17
- package/dist/transformers/preview/component/css.d.ts +3 -1
- package/dist/transformers/preview/component/css.js +92 -51
- package/dist/transformers/preview/component/html.d.ts +3 -1
- package/dist/transformers/preview/component/html.js +6 -2
- package/dist/transformers/preview/component/javascript.d.ts +2 -1
- package/dist/transformers/preview/component/javascript.js +10 -4
- package/dist/transformers/preview/pattern/html.js +3 -1
- package/dist/transformers/preview/types.d.ts +13 -0
- package/dist/transformers/utils/build.d.ts +24 -0
- package/dist/transformers/utils/build.js +100 -1
- package/dist/transformers/utils/module.js +2 -1
- package/dist/types/config.d.ts +135 -18
- package/dist/utils/path.d.ts +1 -5
- package/dist/utils/path.js +6 -23
- package/docs/api.md +6 -4
- package/docs/cli.md +275 -54
- package/drizzle/0007_add_ai_keys.sql +11 -0
- package/drizzle/0008_add_source_dir.sql +2 -0
- package/drizzle/meta/0007_snapshot.json +2013 -0
- package/drizzle/meta/0008_snapshot.json +2025 -0
- package/drizzle/meta/_journal.json +14 -0
- package/package.json +19 -8
- package/src/ai/README.md +42 -0
- package/src/ai/connections.ts +189 -0
- package/src/ai/define.ts +15 -0
- package/src/ai/types.ts +30 -0
- package/src/app/components/AiAssistant/AiAssistantPanel.tsx +144 -0
- package/src/app/components/AiAssistant/AiAssistantProvider.tsx +215 -0
- package/src/app/components/AiAssistant/AiConversation.tsx +737 -0
- package/src/app/components/AiAssistant/AiToolResult.tsx +99 -0
- package/src/app/components/AiAssistant/dockState.ts +86 -0
- package/src/app/components/AiAssistant/toolLabel.ts +24 -0
- package/src/app/components/AiAssistant/useAiChat.ts +147 -0
- package/src/app/components/AiAssistant/useAiConnections.ts +86 -0
- package/src/app/components/AiAssistant/usePageContext.ts +63 -0
- package/src/app/components/Auth/AccountLayout.tsx +58 -19
- package/src/app/components/Auth/AuthShell.tsx +27 -33
- package/src/app/components/Auth/RegistryInstallGate.tsx +4 -8
- package/src/app/components/Auth/installStatus.ts +29 -0
- package/src/app/components/Component/PageSliceResolver.tsx +1 -0
- package/src/app/components/Component/Preview.tsx +383 -189
- package/src/app/components/Component/slices/ComponentDisplaySlice.tsx +4 -0
- package/src/app/components/Foundations/ColorGrid.tsx +13 -14
- package/src/app/components/Layout/Header.tsx +21 -15
- package/src/app/components/Layout/Main.tsx +2 -2
- package/src/app/components/Markdown/MarkdownComponents.tsx +30 -32
- package/src/app/components/McpIntegration/McpConfigDialog.tsx +12 -51
- package/src/app/components/Navigation/MobileNav.tsx +2 -2
- package/src/app/components/Navigation/SideNav.tsx +1 -15
- package/src/app/components/context/NavProvider.tsx +7 -3
- package/src/app/components/ui/attachment.tsx +50 -0
- package/src/app/components/ui/bubble.tsx +57 -0
- package/src/app/components/ui/button.tsx +3 -1
- package/src/app/components/ui/confirm-dialog.tsx +87 -0
- package/src/app/components/ui/dialog.tsx +7 -2
- package/src/app/components/ui/marker.tsx +56 -0
- package/src/app/components/ui/sidebar.tsx +3 -1
- package/src/app/components/util/index.ts +3 -12
- package/src/app/css/index.css +64 -0
- package/src/app/lib/ai/auth.ts +33 -0
- package/src/app/lib/ai/context.ts +99 -0
- package/src/app/lib/ai/model.ts +79 -0
- package/src/app/lib/ai/prompt.ts +36 -0
- package/src/app/lib/ai/resolve.ts +97 -0
- package/src/app/lib/ai/tools.ts +120 -0
- package/src/app/lib/api/methods.ts +13 -0
- package/src/app/lib/asset-storage.ts +35 -36
- package/src/app/lib/auth/api.ts +4 -12
- package/src/app/lib/auth/email.ts +96 -23
- package/src/app/lib/docs-api/page-rendering.ts +1 -1
- package/src/app/lib/docs-api/registry.ts +2 -3
- package/src/app/lib/docs-api/runtime-config.ts +47 -21
- package/src/app/lib/mcp/components.ts +523 -0
- package/src/app/lib/mcp/page-url.ts +24 -0
- package/src/app/lib/mcp/pages.ts +84 -0
- package/src/app/lib/mcp/result.ts +33 -0
- package/src/app/lib/mcp/server.ts +39 -318
- package/src/app/lib/mcp/tokens.ts +334 -0
- package/src/app/lib/mcp/tool.ts +19 -0
- package/src/app/lib/registry-api/asset-transfer.ts +119 -11
- package/src/app/lib/registry-api/errors.ts +2 -0
- package/src/app/lib/registry-api/handler.ts +7 -1
- package/src/app/lib/registry-api/transfer.ts +28 -6
- package/src/app/lib/server-module.ts +34 -0
- package/src/app/lib/utils.ts +20 -0
- package/src/app/next.config.mjs +26 -24
- package/src/app/pages/[...slug]/index.tsx +2 -1
- package/src/app/pages/_app.tsx +6 -2
- package/src/app/pages/_document.tsx +6 -0
- package/src/app/pages/account/ai.tsx +183 -0
- package/src/app/pages/account/index.tsx +68 -68
- package/src/app/pages/account/tokens.tsx +37 -7
- package/src/app/pages/account/users.tsx +75 -15
- package/src/app/pages/api/account/ai/keys/[connectionId].ts +60 -0
- package/src/app/pages/api/account/ai/keys/index.ts +20 -0
- package/src/app/pages/api/admin/users/[id]/[action].ts +80 -11
- package/src/app/pages/api/admin/users/index.ts +2 -2
- package/src/app/pages/api/ai/chat.ts +115 -0
- package/src/app/pages/api/ai/connections.ts +23 -0
- package/src/app/pages/api/auth/request-reset.ts +14 -16
- package/src/app/pages/api/docs/nav.json.ts +1 -1
- package/src/app/pages/api/install.ts +3 -3
- package/src/app/pages/api/mcp.ts +6 -0
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash]/complete.ts +11 -0
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash]/upload.ts +12 -0
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +1 -1
- package/src/app/pages/cli/device.tsx +10 -5
- package/src/app/pages/foundations/colors.tsx +9 -8
- package/src/app/pages/foundations/index.tsx +3 -3
- package/src/app/pages/index.tsx +2 -2
- package/src/app/pages/install.tsx +7 -2
- package/src/app/pages/login.tsx +32 -27
- package/src/app/pages/reset-password.tsx +21 -20
- package/src/app/pages/system/component/[component]/index.tsx +2 -5
- package/src/app/pages/system/index.tsx +11 -11
- package/src/app/pages/system/pattern/[pattern]/index.tsx +2 -2
- package/src/app/pages/system/tokens/components/[component]/index.tsx +0 -4
- package/src/app-builder/README.md +2 -1
- package/src/app-builder/build.ts +218 -73
- package/src/app-builder/client-config.ts +3 -2
- package/src/app-builder/paths.ts +3 -22
- package/src/app-builder/static-export.ts +1 -1
- package/src/app-builder/vercel-output.ts +5 -4
- package/src/cache/README.md +4 -1
- package/src/cache/build-cache.ts +128 -43
- package/src/cache/build-inputs.ts +28 -0
- package/src/cache/index.ts +4 -0
- package/src/catalog/README.md +3 -0
- package/src/catalog/normalize.ts +2 -0
- package/src/catalog/previews.ts +6 -3
- package/src/catalog/types.ts +8 -0
- package/src/cli/create.ts +1 -2
- package/src/commands/build/index.ts +1 -1
- package/src/config/README.md +10 -9
- package/src/config/defaults.ts +7 -4
- package/src/config/from-env.ts +33 -0
- package/src/config/helpers.ts +1 -3
- package/src/config/index.ts +0 -3
- package/src/config/loader.ts +27 -3
- package/src/config/resolve-env.ts +28 -15
- package/src/config/runtime.ts +10 -5
- package/src/handlebars.ts +8 -2
- package/src/index.ts +33 -29
- package/src/nav/index.ts +2 -2
- package/src/nav/registry.ts +3 -3
- package/src/nav/workspace.ts +3 -3
- package/src/pipeline/README.md +1 -1
- package/src/pipeline/figma.ts +98 -49
- package/src/pipeline/styles.ts +1 -1
- package/src/pipeline/validation.ts +3 -3
- package/src/providers.ts +18 -0
- package/src/registry/asset-storage/define.ts +6 -6
- package/src/registry/asset-storage/resolve.ts +38 -37
- package/src/registry/asset-storage/types.ts +39 -17
- package/src/registry/auth/ai-keys.ts +62 -0
- package/src/registry/auth/crypto.ts +63 -1
- package/src/registry/auth/index.ts +11 -1
- package/src/registry/checkout/index.ts +60 -138
- package/src/registry/client.ts +60 -20
- package/src/registry/db/driver.ts +2 -2
- package/src/registry/db/schema.ts +49 -22
- package/src/registry/email/define.ts +15 -0
- package/src/registry/email/providers/smtp.ts +39 -0
- package/src/registry/email/resolve.ts +94 -0
- package/src/registry/email/types.ts +28 -0
- package/src/registry/path.ts +11 -0
- package/src/registry/publish/package.ts +9 -0
- package/src/registry/transfer.ts +4 -0
- package/src/store/registry.ts +7 -7
- package/src/transformers/plugins/ssr-render.ts +53 -16
- package/src/transformers/preview/component/builder.ts +19 -25
- package/src/transformers/preview/component/css.ts +101 -53
- package/src/transformers/preview/component/html.ts +6 -2
- package/src/transformers/preview/component/javascript.ts +14 -4
- package/src/transformers/preview/pattern/html.ts +3 -1
- package/src/transformers/preview/types.ts +14 -0
- package/src/transformers/utils/build.ts +93 -0
- package/src/transformers/utils/module.ts +4 -2
- package/src/types/config.ts +148 -20
- package/src/utils/README.md +1 -1
- package/src/utils/path.ts +6 -29
- package/templates/default/handoff.config.js.tpl +10 -2
- package/templates/default/handoff.config.ts.tpl +10 -2
- package/templates/default/handoff.config.with-examples.js.tpl +10 -2
- package/templates/default/handoff.config.with-examples.ts.tpl +10 -2
- package/templates/default/package.json.tpl +2 -2
- package/.editorconfig +0 -19
- package/.eslintrc.json +0 -4
- package/.prettierignore +0 -0
- package/.prettierrc.json +0 -8
- package/.vscode/settings.json +0 -17
- package/dist/config/validator.d.ts +0 -9
- package/dist/config/validator.js +0 -24
- package/dist/registry/asset-storage/adapters/vercel-blob.d.ts +0 -17
- package/dist/registry/asset-storage/adapters/vercel-blob.js +0 -87
- package/src/app/components/old/Header.tsx +0 -89
- package/src/app/lib/mcp/shape.ts +0 -596
- package/src/app/pages/assets/fonts.tsx +0 -129
- package/src/app/pages/assets/index.tsx +0 -91
- package/src/app/pages/assets/logos.tsx +0 -75
- package/src/config/validator.ts +0 -22
- package/src/registry/asset-storage/adapters/vercel-blob.ts +0 -51
package/UPGRADE.md
CHANGED
|
@@ -18,29 +18,54 @@ Each feature section identifies the affected projects and the required changes.
|
|
|
18
18
|
|
|
19
19
|
| Change | Affected projects |
|
|
20
20
|
| --- | --- |
|
|
21
|
-
| [
|
|
21
|
+
| [Node.js 22](#nodejs-22) | All projects |
|
|
22
|
+
| [Figma settings](#figma-settings) | Projects that set Figma values in config |
|
|
22
23
|
| [Catalog items](#catalog-items) | Projects with component or pattern declarations |
|
|
24
|
+
| [Output directories](#output-directories) | Projects that deploy the static build, commit `exported/`, or use a `public-<projectId>` directory |
|
|
23
25
|
|
|
24
26
|
<!-- Add future breaking changes as feature sections before "Verify the upgrade". Add each section to this table. -->
|
|
25
27
|
|
|
26
|
-
###
|
|
28
|
+
### Node.js 22
|
|
27
29
|
|
|
28
|
-
|
|
30
|
+
Handoff 2.x.x requires Node.js 22 or newer and npm 10 or newer. Version 1.x.x supported Node.js 16.
|
|
31
|
+
Update Node.js, CI images, and hosting runtimes before you install the new package.
|
|
32
|
+
|
|
33
|
+
Projects created by `handoff-app init` in version 1.x.x declare the old minimum in `package.json`.
|
|
34
|
+
Change it to:
|
|
35
|
+
|
|
36
|
+
```json
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22",
|
|
39
|
+
"npm": ">=10"
|
|
40
|
+
}
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Figma settings
|
|
44
|
+
|
|
45
|
+
The Figma file ID and access token moved to `integrations.figma`.
|
|
46
|
+
The top-level `figmaProjectId`, `figma_project_id`, `devAccessToken`, and `dev_access_token` were removed, and Handoff ignores them.
|
|
47
|
+
If you use `HANDOFF_FIGMA_PROJECT_ID` and `HANDOFF_DEV_ACCESS_TOKEN` and do not set Figma values in config, no change is required.
|
|
48
|
+
|
|
49
|
+
The access token accepts only an environment reference.
|
|
29
50
|
A literal token throws `HandoffConfigError`, including in JavaScript and JSON configs.
|
|
30
|
-
|
|
51
|
+
Replace the old keys. Move a literal token to the environment:
|
|
31
52
|
|
|
32
53
|
```ts
|
|
33
54
|
import { defineConfig, fromEnv } from 'handoff-app';
|
|
34
55
|
|
|
35
56
|
export default defineConfig({
|
|
36
|
-
|
|
57
|
+
integrations: {
|
|
58
|
+
figma: {
|
|
59
|
+
projectId: 'your-figma-file-id',
|
|
60
|
+
accessToken: fromEnv('HANDOFF_DEV_ACCESS_TOKEN'),
|
|
61
|
+
},
|
|
62
|
+
},
|
|
37
63
|
});
|
|
38
64
|
```
|
|
39
65
|
|
|
40
|
-
For JSON, use `"
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
environment seeds for properties that allow literals, such as output directories.
|
|
66
|
+
For JSON, use `"accessToken": { "$env": "HANDOFF_DEV_ACCESS_TOKEN" }`.
|
|
67
|
+
Environment references resolve after profile merging. A profile can change one value, such as `integrations.figma.projectId`, and keep the other.
|
|
68
|
+
A literal in a higher layer, such as `projectId: 'your-figma-file-id'`, overrides the default environment variable.
|
|
44
69
|
|
|
45
70
|
### Catalog items
|
|
46
71
|
|
|
@@ -201,6 +226,29 @@ CSF uses `renderer: 'react'` with `format: 'csf'` inside `implementation`.
|
|
|
201
226
|
Checkout writes only catalog declarations.
|
|
202
227
|
Registry records require explicit renderer and source-format metadata where applicable.
|
|
203
228
|
|
|
229
|
+
### Output directories
|
|
230
|
+
|
|
231
|
+
Version 1.x.x put the static site and the fetched tokens in a directory named after `<projectId>`.
|
|
232
|
+
`<projectId>` was the Figma file ID, or a name made from the project path when no Figma file was set.
|
|
233
|
+
Version 2.x.x uses fixed directory names:
|
|
234
|
+
|
|
235
|
+
| Content | 1.x.x | 2.x.x |
|
|
236
|
+
| --- | --- | --- |
|
|
237
|
+
| Static site from `handoff-app build` | `out/<projectId>` | `out/static` |
|
|
238
|
+
| Tokens and assets from `fetch` and `checkout` | `exported/<projectId>` | `exported` |
|
|
239
|
+
| Project-specific public files | `public-<projectId>` | Removed. Use `public` |
|
|
240
|
+
|
|
241
|
+
Do these steps:
|
|
242
|
+
|
|
243
|
+
1. Update deploy scripts and CI steps that read `out/<projectId>`.
|
|
244
|
+
If you set `sitesOutputDirectory` or `HANDOFF_SITES_DIR`, the site is in `static` below that directory.
|
|
245
|
+
2. Move the contents of `exported/<projectId>` up to `exported`, or run `npm run fetch` again.
|
|
246
|
+
Then remove `exported/<projectId>` and commit the result.
|
|
247
|
+
3. Merge the files from `public-<projectId>` into `public`, then remove `public-<projectId>`.
|
|
248
|
+
|
|
249
|
+
A repository that builds more than one Figma file gets one `out/static` and one `exported` directory.
|
|
250
|
+
Set `HANDOFF_SITES_DIR` and `HANDOFF_OUTPUT_DIR`, or the matching config values in a profile, to a different directory for each build.
|
|
251
|
+
|
|
204
252
|
### Verify the upgrade
|
|
205
253
|
|
|
206
254
|
After you apply the required migrations, verify the project:
|
package/components.json
CHANGED
|
@@ -1,21 +1,21 @@
|
|
|
1
1
|
{
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
|
|
@@ -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,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
|
---
|
|
@@ -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
|
|
|
@@ -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
|
|
|
@@ -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:
|
package/config/docs/index.md
CHANGED
|
@@ -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
|
package/config/docs/system.md
CHANGED
|
@@ -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
|
package/config/templates/page.md
CHANGED
|
@@ -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
|
|
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
|
|
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
|
---
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AI connection resolution.
|
|
3
|
+
*
|
|
4
|
+
* `runtime.ai.connections` declares the whole surface a reader can reach. Mirrors
|
|
5
|
+
* {@link import('../registry/asset-storage/resolve')}: only provider selection, module location,
|
|
6
|
+
* non-secret options, and env-var *names* are ever persisted; secret *values* are read from
|
|
7
|
+
* `process.env` at request time.
|
|
8
|
+
*
|
|
9
|
+
* The list is deployment data rather than build shape, so `HANDOFF_AI_CONNECTIONS` can extend or
|
|
10
|
+
* replace the baked list at request time. A registry is built once and redeployed many times, and a
|
|
11
|
+
* new gateway should not need a rebuild.
|
|
12
|
+
*/
|
|
13
|
+
import type { AiCredentialKind, ResolvedConfig } from '../types/config';
|
|
14
|
+
/** A connection as it is baked and read back: env-var names, never secret values. */
|
|
15
|
+
export interface AiConnectionSettings {
|
|
16
|
+
id: string;
|
|
17
|
+
label: string;
|
|
18
|
+
baseUrl?: string;
|
|
19
|
+
module?: string;
|
|
20
|
+
/** Name of the env var holding the deployment's own key. Its presence marks a service connection. */
|
|
21
|
+
apiKeyEnv?: string;
|
|
22
|
+
credential?: 'user';
|
|
23
|
+
models?: string[];
|
|
24
|
+
options?: Record<string, unknown>;
|
|
25
|
+
}
|
|
26
|
+
/** The resolved AI block: whether this build serves the assistant, and what it can reach. */
|
|
27
|
+
export interface AiSettings {
|
|
28
|
+
enabled: boolean;
|
|
29
|
+
connections: AiConnectionSettings[];
|
|
30
|
+
defaultModel?: string;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Which of the three credential states a connection declares. Derived from the declaration, never
|
|
34
|
+
* from a missing key: without the explicit `user` state, a connection that needs a reader's key
|
|
35
|
+
* would be indistinguishable from one that needs none.
|
|
36
|
+
*/
|
|
37
|
+
export declare const aiCredentialKind: (connection: AiConnectionSettings) => AiCredentialKind;
|
|
38
|
+
/** Split `<connectionId>/<model>`. Only the first slash separates them, since model ids carry slashes. */
|
|
39
|
+
export declare const parseAiModelId: (value: string) => {
|
|
40
|
+
connectionId: string;
|
|
41
|
+
model: string;
|
|
42
|
+
} | null;
|
|
43
|
+
/** Join a connection id and a model into the address the client sends back. */
|
|
44
|
+
export declare const formatAiModelId: (connectionId: string, model: string) => string;
|
|
45
|
+
/**
|
|
46
|
+
* Merge a deployment-supplied list over the baked one by `id`: a matching id replaces the baked
|
|
47
|
+
* connection outright, and a new id is appended. Replacement rather than a field-wise merge, so a
|
|
48
|
+
* deployment that repoints a gateway cannot leave a stale model list or key name behind.
|
|
49
|
+
*
|
|
50
|
+
* A deployment-supplied connection can use only a `module` that the build includes.
|
|
51
|
+
*/
|
|
52
|
+
export declare const mergeAiConnections: (baked: readonly AiConnectionSettings[], overrides: readonly AiConnectionSettings[]) => AiConnectionSettings[];
|
|
53
|
+
/** Parse the `HANDOFF_AI_CONNECTIONS` JSON array. A malformed value is ignored rather than fatal. */
|
|
54
|
+
export declare const parseAiConnections: (raw: string | undefined) => AiConnectionSettings[];
|
|
55
|
+
/**
|
|
56
|
+
* Whether this build serves the assistant. The `ai` block is the opt-in; `enabled: false` turns it
|
|
57
|
+
* back off. Config-only and baked, like `runtime.mcp`.
|
|
58
|
+
*/
|
|
59
|
+
export declare const isAiEnabled: (config: Pick<ResolvedConfig, "runtime"> | null | undefined) => boolean;
|
|
60
|
+
/**
|
|
61
|
+
* Resolve the AI settings from a loaded config (CLI/build side).
|
|
62
|
+
*
|
|
63
|
+
* An authored connection that cannot be used fails the build rather than disappearing. A deployment
|
|
64
|
+
* list stays lenient by contrast: a bad `HANDOFF_AI_CONNECTIONS` entry must not take the server down.
|
|
65
|
+
*/
|
|
66
|
+
export declare const resolveAiFromConfig: (config: ResolvedConfig | null | undefined) => AiSettings;
|
|
@@ -0,0 +1,149 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* AI connection resolution.
|
|
4
|
+
*
|
|
5
|
+
* `runtime.ai.connections` declares the whole surface a reader can reach. Mirrors
|
|
6
|
+
* {@link import('../registry/asset-storage/resolve')}: only provider selection, module location,
|
|
7
|
+
* non-secret options, and env-var *names* are ever persisted; secret *values* are read from
|
|
8
|
+
* `process.env` at request time.
|
|
9
|
+
*
|
|
10
|
+
* The list is deployment data rather than build shape, so `HANDOFF_AI_CONNECTIONS` can extend or
|
|
11
|
+
* replace the baked list at request time. A registry is built once and redeployed many times, and a
|
|
12
|
+
* new gateway should not need a rebuild.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.resolveAiFromConfig = exports.isAiEnabled = exports.parseAiConnections = exports.mergeAiConnections = exports.formatAiModelId = exports.parseAiModelId = exports.aiCredentialKind = void 0;
|
|
16
|
+
const errors_1 = require("../config/errors");
|
|
17
|
+
/** A connection id addresses a model as `<id>/<model>`, so it cannot itself contain a slash. */
|
|
18
|
+
const isUsableId = (id) => typeof id === 'string' && id.trim().length > 0 && !id.includes('/');
|
|
19
|
+
/**
|
|
20
|
+
* Which of the three credential states a connection declares. Derived from the declaration, never
|
|
21
|
+
* from a missing key: without the explicit `user` state, a connection that needs a reader's key
|
|
22
|
+
* would be indistinguishable from one that needs none.
|
|
23
|
+
*/
|
|
24
|
+
const aiCredentialKind = (connection) => {
|
|
25
|
+
if (connection.credential === 'user')
|
|
26
|
+
return 'user';
|
|
27
|
+
return connection.apiKeyEnv ? 'service' : 'none';
|
|
28
|
+
};
|
|
29
|
+
exports.aiCredentialKind = aiCredentialKind;
|
|
30
|
+
/** Split `<connectionId>/<model>`. Only the first slash separates them, since model ids carry slashes. */
|
|
31
|
+
const parseAiModelId = (value) => {
|
|
32
|
+
const separator = value.indexOf('/');
|
|
33
|
+
if (separator <= 0 || separator === value.length - 1)
|
|
34
|
+
return null;
|
|
35
|
+
return { connectionId: value.slice(0, separator), model: value.slice(separator + 1) };
|
|
36
|
+
};
|
|
37
|
+
exports.parseAiModelId = parseAiModelId;
|
|
38
|
+
/** Join a connection id and a model into the address the client sends back. */
|
|
39
|
+
const formatAiModelId = (connectionId, model) => `${connectionId}/${model}`;
|
|
40
|
+
exports.formatAiModelId = formatAiModelId;
|
|
41
|
+
/** Normalize one authored or deployment-supplied connection, dropping anything unusable. */
|
|
42
|
+
const toConnectionSettings = (input) => {
|
|
43
|
+
if (!input || typeof input !== 'object' || Array.isArray(input))
|
|
44
|
+
return null;
|
|
45
|
+
const raw = input;
|
|
46
|
+
if (!isUsableId(raw.id))
|
|
47
|
+
return null;
|
|
48
|
+
const baseUrl = typeof raw.baseUrl === 'string' ? raw.baseUrl.trim() : undefined;
|
|
49
|
+
const module = typeof raw.module === 'string' ? raw.module.trim() : undefined;
|
|
50
|
+
if (!baseUrl && !module)
|
|
51
|
+
return null;
|
|
52
|
+
// An authored config carries `apiKey` as a deferred `{ $env }` reference; a baked or
|
|
53
|
+
// deployment-supplied list carries the name it resolved to.
|
|
54
|
+
const reference = raw.apiKey;
|
|
55
|
+
const apiKeyEnv = typeof raw.apiKeyEnv === 'string' && raw.apiKeyEnv.trim()
|
|
56
|
+
? raw.apiKeyEnv.trim()
|
|
57
|
+
: typeof (reference === null || reference === void 0 ? void 0 : reference.$env) === 'string'
|
|
58
|
+
? reference.$env
|
|
59
|
+
: undefined;
|
|
60
|
+
// A repeated model would be two picker entries for one choice, so the first occurrence wins.
|
|
61
|
+
const models = Array.isArray(raw.models)
|
|
62
|
+
? [...new Set(raw.models.filter((model) => typeof model === 'string' && !!model.trim()).map((model) => model.trim()))]
|
|
63
|
+
: [];
|
|
64
|
+
const options = raw.options && typeof raw.options === 'object' && !Array.isArray(raw.options) ? raw.options : undefined;
|
|
65
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ id: raw.id.trim(), label: typeof raw.label === 'string' && raw.label.trim() ? raw.label.trim() : raw.id.trim() }, (baseUrl ? { baseUrl } : {})), (module ? { module } : {})), (apiKeyEnv ? { apiKeyEnv } : {})), (raw.credential === 'user' ? { credential: 'user' } : {})), (models.length ? { models } : {})), (options ? { options } : {}));
|
|
66
|
+
};
|
|
67
|
+
/** Normalize a declared list, keeping the first entry for any repeated id. */
|
|
68
|
+
const toConnectionList = (input) => {
|
|
69
|
+
const byId = new Map();
|
|
70
|
+
for (const entry of input !== null && input !== void 0 ? input : []) {
|
|
71
|
+
const connection = toConnectionSettings(entry);
|
|
72
|
+
if (connection && !byId.has(connection.id))
|
|
73
|
+
byId.set(connection.id, connection);
|
|
74
|
+
}
|
|
75
|
+
return [...byId.values()];
|
|
76
|
+
};
|
|
77
|
+
const ignoredOverrides = new Set();
|
|
78
|
+
/**
|
|
79
|
+
* Merge a deployment-supplied list over the baked one by `id`: a matching id replaces the baked
|
|
80
|
+
* connection outright, and a new id is appended. Replacement rather than a field-wise merge, so a
|
|
81
|
+
* deployment that repoints a gateway cannot leave a stale model list or key name behind.
|
|
82
|
+
*
|
|
83
|
+
* A deployment-supplied connection can use only a `module` that the build includes.
|
|
84
|
+
*/
|
|
85
|
+
const mergeAiConnections = (baked, overrides) => {
|
|
86
|
+
const byId = new Map(baked.map((connection) => [connection.id, connection]));
|
|
87
|
+
const bakedModules = new Set(baked.map((connection) => connection.module).filter(Boolean));
|
|
88
|
+
for (const connection of overrides) {
|
|
89
|
+
if (connection.module && !bakedModules.has(connection.module)) {
|
|
90
|
+
if (!ignoredOverrides.has(connection.id)) {
|
|
91
|
+
ignoredOverrides.add(connection.id);
|
|
92
|
+
console.warn(`HANDOFF_AI_CONNECTIONS: connection "${connection.id}" is ignored, because the build does not include its module ` +
|
|
93
|
+
`"${connection.module}". Declare the connection in runtime.ai.connections.`);
|
|
94
|
+
}
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
byId.set(connection.id, connection);
|
|
98
|
+
}
|
|
99
|
+
return [...byId.values()];
|
|
100
|
+
};
|
|
101
|
+
exports.mergeAiConnections = mergeAiConnections;
|
|
102
|
+
/** Parse the `HANDOFF_AI_CONNECTIONS` JSON array. A malformed value is ignored rather than fatal. */
|
|
103
|
+
const parseAiConnections = (raw) => {
|
|
104
|
+
if (!(raw === null || raw === void 0 ? void 0 : raw.trim()))
|
|
105
|
+
return [];
|
|
106
|
+
try {
|
|
107
|
+
const parsed = JSON.parse(raw);
|
|
108
|
+
return Array.isArray(parsed) ? toConnectionList(parsed) : [];
|
|
109
|
+
}
|
|
110
|
+
catch (_a) {
|
|
111
|
+
return [];
|
|
112
|
+
}
|
|
113
|
+
};
|
|
114
|
+
exports.parseAiConnections = parseAiConnections;
|
|
115
|
+
/**
|
|
116
|
+
* Whether this build serves the assistant. The `ai` block is the opt-in; `enabled: false` turns it
|
|
117
|
+
* back off. Config-only and baked, like `runtime.mcp`.
|
|
118
|
+
*/
|
|
119
|
+
const isAiEnabled = (config) => { var _a, _b, _c; return Boolean((_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.ai) && ((_c = (_b = config === null || config === void 0 ? void 0 : config.runtime) === null || _b === void 0 ? void 0 : _b.ai) === null || _c === void 0 ? void 0 : _c.enabled) !== false; };
|
|
120
|
+
exports.isAiEnabled = isAiEnabled;
|
|
121
|
+
/**
|
|
122
|
+
* Resolve the AI settings from a loaded config (CLI/build side).
|
|
123
|
+
*
|
|
124
|
+
* An authored connection that cannot be used fails the build rather than disappearing. A deployment
|
|
125
|
+
* list stays lenient by contrast: a bad `HANDOFF_AI_CONNECTIONS` entry must not take the server down.
|
|
126
|
+
*/
|
|
127
|
+
const resolveAiFromConfig = (config) => {
|
|
128
|
+
var _a, _b, _c, _d, _e, _f;
|
|
129
|
+
const authored = ((_c = (_b = (_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.ai) === null || _b === void 0 ? void 0 : _b.connections) !== null && _c !== void 0 ? _c : []);
|
|
130
|
+
const fail = (problem, ids) => {
|
|
131
|
+
throw new errors_1.HandoffConfigError(`Config "runtime.ai.connections": ${problem} (${ids.map((id) => JSON.stringify(id !== null && id !== void 0 ? id : null)).join(', ')}).`);
|
|
132
|
+
};
|
|
133
|
+
const normalized = authored.map((connection) => ({ authored: connection, settings: toConnectionSettings(connection) }));
|
|
134
|
+
const unusable = normalized.filter((entry) => !entry.settings);
|
|
135
|
+
if (unusable.length > 0) {
|
|
136
|
+
fail('every connection needs an "id" without a slash, and either a "baseUrl" or a "module"', unusable.map((entry) => { var _a; return (_a = entry.authored) === null || _a === void 0 ? void 0 : _a.id; }));
|
|
137
|
+
}
|
|
138
|
+
const ids = normalized.map((entry) => entry.settings.id);
|
|
139
|
+
const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
|
|
140
|
+
if (duplicates.length > 0) {
|
|
141
|
+
fail('a connection id must be unique, because it is half of every model address', duplicates);
|
|
142
|
+
}
|
|
143
|
+
return {
|
|
144
|
+
enabled: (0, exports.isAiEnabled)(config),
|
|
145
|
+
connections: normalized.map((entry) => entry.settings),
|
|
146
|
+
defaultModel: ((_f = (_e = (_d = config === null || config === void 0 ? void 0 : config.runtime) === null || _d === void 0 ? void 0 : _d.ai) === null || _e === void 0 ? void 0 : _e.defaultModel) === null || _f === void 0 ? void 0 : _f.trim()) || undefined,
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
exports.resolveAiFromConfig = resolveAiFromConfig;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed identity helper for custom AI providers (mirrors `defineStorageProvider`): a consumer
|
|
3
|
+
* default-exports its result from a **server-only** module and points a connection's `module` at
|
|
4
|
+
* it. It must be its own module (not an inline `defineConfig` function) so the build can trace it
|
|
5
|
+
* into the deployed registry. The default export may be the provider object, or a factory
|
|
6
|
+
* `(context) => AiProvider` when it needs its options, env or the resolved key.
|
|
7
|
+
*/
|
|
8
|
+
import type { AiProvider, AiProviderFactory } from './types';
|
|
9
|
+
export declare function defineAiProvider(provider: AiProvider): AiProvider;
|
|
10
|
+
export declare function defineAiProvider(factory: AiProviderFactory): AiProviderFactory;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Typed identity helper for custom AI providers (mirrors `defineStorageProvider`): a consumer
|
|
4
|
+
* default-exports its result from a **server-only** module and points a connection's `module` at
|
|
5
|
+
* it. It must be its own module (not an inline `defineConfig` function) so the build can trace it
|
|
6
|
+
* into the deployed registry. The default export may be the provider object, or a factory
|
|
7
|
+
* `(context) => AiProvider` when it needs its options, env or the resolved key.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.defineAiProvider = defineAiProvider;
|
|
11
|
+
function defineAiProvider(input) {
|
|
12
|
+
return input;
|
|
13
|
+
}
|