handoff-app 2.0.0-0 → 2.0.0-10
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/AGENTS.md +7 -0
- package/CLAUDE.md +7 -0
- package/README.md +732 -304
- package/UPGRADE.md +218 -0
- package/config/config.template.js +1 -4
- package/config/config.template.ts +1 -2
- package/config/docs/foundations/colors/guidelines.md +9 -0
- package/config/docs/foundations/effects/guidelines.md +9 -0
- package/config/docs/foundations/effects/resources.md +9 -0
- package/config/docs/foundations/grid.md +10 -0
- package/config/docs/foundations/icons/guidelines.md +9 -0
- package/config/docs/foundations/images/guidelines.md +9 -0
- package/config/docs/foundations/images/resources.md +9 -0
- package/config/docs/foundations/images.md +10 -0
- package/config/docs/foundations/logo/resources.md +9 -0
- package/config/docs/foundations/typography/guidelines.md +9 -0
- package/config/docs/foundations/typography/resources.md +9 -0
- package/config/docs/foundations.md +5 -3
- package/dist/ai/connections.d.ts +64 -0
- package/dist/ai/connections.js +136 -0
- package/dist/ai/define.d.ts +10 -0
- package/dist/ai/define.js +13 -0
- package/dist/ai/types.d.ts +27 -0
- package/dist/ai/types.js +10 -0
- package/dist/app-builder/build.d.ts +12 -0
- package/dist/app-builder/build.js +227 -69
- package/dist/app-builder/client-config.js +16 -12
- package/dist/app-builder/config-diff/strategies/pattern.js +3 -3
- package/dist/app-builder/nav-shell.js +8 -15
- package/dist/app-builder/paths.js +23 -1
- package/dist/app-builder/static-export.js +25 -0
- package/dist/app-builder/vercel-output.js +6 -6
- package/dist/app-builder/watchers/component.js +5 -5
- package/dist/app-builder/watchers/utils.d.ts +2 -3
- package/dist/app-builder/watchers.d.ts +8 -15
- package/dist/app-builder/watchers.js +70 -61
- package/dist/artifacts/index.d.ts +1 -1
- package/dist/artifacts/index.js +4 -1
- package/dist/artifacts/url.d.ts +18 -0
- package/dist/artifacts/url.js +31 -1
- package/dist/cache/build-cache.js +23 -23
- package/dist/catalog/define.d.ts +6 -0
- package/dist/catalog/define.js +72 -0
- package/dist/catalog/implementation.d.ts +27 -0
- package/dist/catalog/implementation.js +133 -0
- package/dist/catalog/index.d.ts +6 -0
- package/dist/catalog/index.js +22 -0
- package/dist/catalog/normalize.d.ts +16 -0
- package/dist/catalog/normalize.js +118 -0
- package/dist/catalog/previews.d.ts +18 -0
- package/dist/catalog/previews.js +107 -0
- package/dist/catalog/renderers.d.ts +43 -0
- package/dist/catalog/renderers.js +62 -0
- package/dist/catalog/types.d.ts +71 -0
- package/dist/cli/auth/browser.d.ts +2 -0
- package/dist/cli/auth/browser.js +33 -0
- package/dist/cli/auth/device.d.ts +16 -0
- package/dist/cli/auth/device.js +158 -0
- package/dist/cli/auth/store.d.ts +38 -0
- package/dist/cli/auth/store.js +199 -0
- package/dist/cli/create.js +48 -3
- package/dist/cli/make.d.ts +0 -5
- package/dist/cli/make.js +24 -69
- package/dist/cli/scaffold.js +39 -181
- package/dist/cli.js +39 -7
- package/dist/commands/build/app.js +1 -5
- package/dist/commands/build/components.js +1 -5
- package/dist/commands/build/index.js +1 -5
- package/dist/commands/checkout/index.d.ts +18 -12
- package/dist/commands/checkout/index.js +19 -59
- package/dist/commands/compat/deprecations.d.ts +46 -0
- package/dist/commands/compat/deprecations.js +62 -0
- package/dist/commands/compat/push-args.d.ts +48 -0
- package/dist/commands/compat/push-args.js +73 -0
- package/dist/commands/db/migrate.js +1 -5
- package/dist/commands/dev/index.js +1 -5
- package/dist/commands/eject/config.js +1 -5
- package/dist/commands/eject/pages.js +1 -5
- package/dist/commands/eject/theme.js +1 -5
- package/dist/commands/fetch/index.js +1 -5
- package/dist/commands/index.js +8 -2
- package/dist/commands/login/index.d.ts +13 -0
- package/dist/commands/login/index.js +61 -0
- package/dist/commands/logout/index.d.ts +12 -0
- package/dist/commands/logout/index.js +89 -0
- package/dist/commands/make/component.js +1 -5
- package/dist/commands/make/page.js +3 -7
- package/dist/commands/publish/index.d.ts +21 -11
- package/dist/commands/publish/index.js +22 -58
- package/dist/commands/pull/index.d.ts +13 -0
- package/dist/commands/pull/index.js +20 -0
- package/dist/commands/push/index.d.ts +23 -0
- package/dist/commands/push/index.js +58 -0
- package/dist/commands/scaffold/index.js +1 -5
- package/dist/commands/start/index.js +1 -5
- package/dist/commands/types.d.ts +12 -0
- package/dist/commands/utils.d.ts +100 -1
- package/dist/commands/utils.js +103 -2
- package/dist/commands/validate/components.js +1 -5
- package/dist/config/catalog-include.d.ts +43 -0
- package/dist/config/catalog-include.js +203 -0
- package/dist/config/defaults.d.ts +4 -2
- package/dist/config/defaults.js +58 -49
- package/dist/config/env.d.ts +9 -0
- package/dist/config/env.js +43 -0
- package/dist/config/errors.d.ts +4 -0
- package/dist/config/errors.js +11 -0
- package/dist/config/from-env.d.ts +24 -0
- package/dist/config/from-env.js +7 -0
- package/dist/config/helpers.d.ts +2 -0
- package/dist/config/helpers.js +3 -1
- package/dist/config/index.d.ts +6 -2
- package/dist/config/index.js +12 -1
- package/dist/config/loader.d.ts +40 -9
- package/dist/config/loader.js +148 -35
- package/dist/config/normalizers/page.d.ts +4 -4
- package/dist/config/normalizers/page.js +2 -2
- package/dist/config/resolve-env.d.ts +6 -0
- package/dist/config/resolve-env.js +115 -0
- package/dist/config/runtime.d.ts +15 -16
- package/dist/config/runtime.js +178 -196
- package/dist/config/validator.d.ts +2 -2
- package/dist/config/validator.js +2 -4
- package/dist/handlebars.d.ts +17 -0
- package/dist/handlebars.js +16 -0
- package/dist/index.d.ts +120 -27
- package/dist/index.js +242 -53
- package/dist/nav/resolver.js +3 -1
- package/dist/nav/workspace.js +2 -2
- package/dist/pattern.d.ts +7 -0
- package/dist/pattern.js +13 -0
- package/dist/pipeline/index.d.ts +1 -1
- package/dist/pipeline/index.js +1 -1
- package/dist/react.d.ts +43 -0
- package/dist/react.js +11 -0
- package/dist/registry/asset-storage/adapters/vercel-blob.js +1 -1
- package/dist/registry/asset-storage/define.d.ts +1 -1
- package/dist/registry/asset-storage/define.js +1 -1
- package/dist/registry/asset-storage/resolve.d.ts +3 -3
- package/dist/registry/asset-storage/resolve.js +5 -2
- package/dist/registry/auth/access-tokens.d.ts +54 -0
- package/dist/registry/auth/access-tokens.js +191 -0
- package/dist/registry/auth/action-tokens.d.ts +66 -0
- package/dist/registry/auth/action-tokens.js +178 -0
- 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 +21 -0
- package/dist/registry/auth/crypto.js +76 -0
- package/dist/registry/auth/database.d.ts +7 -0
- package/dist/registry/auth/database.js +22 -0
- package/dist/registry/auth/device-authorizations.d.ts +51 -0
- package/dist/registry/auth/device-authorizations.js +170 -0
- package/dist/registry/auth/gravatar.d.ts +1 -0
- package/dist/registry/auth/gravatar.js +8 -0
- package/dist/registry/auth/index.d.ts +13 -0
- package/dist/registry/auth/index.js +89 -0
- package/dist/registry/auth/installation.d.ts +42 -0
- package/dist/registry/auth/installation.js +105 -0
- package/dist/registry/auth/password.d.ts +12 -0
- package/dist/registry/auth/password.js +58 -0
- package/dist/registry/auth/rate-limits.d.ts +22 -0
- package/dist/registry/auth/rate-limits.js +75 -0
- package/dist/registry/auth/sync-secret.d.ts +27 -0
- package/dist/registry/auth/sync-secret.js +65 -0
- package/dist/registry/auth/types.d.ts +45 -0
- package/dist/registry/auth/types.js +11 -0
- package/dist/registry/auth/user-record.d.ts +13 -0
- package/dist/registry/auth/user-record.js +16 -0
- package/dist/registry/auth/users.d.ts +31 -0
- package/dist/registry/auth/users.js +135 -0
- package/dist/registry/auth/validation.d.ts +14 -0
- package/dist/registry/auth/validation.js +45 -0
- package/dist/registry/checkout/assets.d.ts +1 -1
- package/dist/registry/checkout/assets.js +25 -8
- package/dist/registry/checkout/index.d.ts +27 -6
- package/dist/registry/checkout/index.js +479 -131
- package/dist/registry/checkout/tokens.d.ts +1 -1
- package/dist/registry/checkout/tokens.js +16 -7
- package/dist/registry/client.d.ts +2 -1
- package/dist/registry/client.js +8 -0
- package/dist/registry/connection.d.ts +34 -11
- package/dist/registry/connection.js +77 -18
- package/dist/registry/content-kinds.d.ts +27 -0
- package/dist/registry/content-kinds.js +33 -0
- package/dist/registry/db/client.d.ts +14 -9
- package/dist/registry/db/client.js +22 -9
- package/dist/registry/db/driver.d.ts +39 -0
- package/dist/registry/db/driver.js +50 -0
- package/dist/registry/db/index.d.ts +2 -2
- package/dist/registry/db/index.js +14 -9
- package/dist/registry/db/migrate.d.ts +1 -1
- package/dist/registry/db/migrate.js +5 -5
- package/dist/registry/db/schema.d.ts +2992 -963
- package/dist/registry/db/schema.js +158 -8
- package/dist/registry/publish/assets.d.ts +2 -2
- package/dist/registry/publish/assets.js +46 -35
- package/dist/registry/publish/errors.js +3 -3
- package/dist/registry/publish/index.d.ts +45 -3
- package/dist/registry/publish/index.js +247 -24
- package/dist/registry/publish/package.js +14 -1
- package/dist/registry/publish/tokens.d.ts +2 -2
- package/dist/registry/publish/tokens.js +30 -24
- package/dist/registry/selection.d.ts +32 -0
- package/dist/registry/selection.js +58 -0
- package/dist/registry/transfer.d.ts +13 -0
- package/dist/store/filesystem.d.ts +3 -3
- package/dist/store/filesystem.js +7 -7
- package/dist/store/registry.d.ts +48 -0
- package/dist/store/registry.js +99 -15
- package/dist/transformers/plugins/csf-render.js +4 -2
- package/dist/transformers/plugins/ssr-render.js +52 -18
- package/dist/transformers/preview/component/api.d.ts +8 -0
- package/dist/transformers/preview/component/api.js +11 -15
- package/dist/transformers/preview/component/artifacts.d.ts +1 -1
- package/dist/transformers/preview/component/artifacts.js +11 -7
- package/dist/transformers/preview/component/builder.js +15 -18
- package/dist/transformers/preview/component/css.d.ts +3 -0
- package/dist/transformers/preview/component/css.js +93 -58
- package/dist/transformers/preview/component/html.js +18 -16
- package/dist/transformers/preview/component/javascript.js +2 -4
- package/dist/transformers/preview/pattern/builder.js +31 -18
- package/dist/transformers/preview/pattern/html.js +3 -1
- package/dist/transformers/preview/types.d.ts +30 -3
- package/dist/transformers/utils/build.d.ts +19 -0
- package/dist/transformers/utils/build.js +83 -1
- package/dist/transformers/utils/module.js +2 -1
- package/dist/types/config.d.ts +156 -45
- package/dist/utils/markdown.d.ts +10 -0
- package/dist/utils/markdown.js +17 -0
- package/dist/utils/menu-shell.js +14 -7
- package/dist/utils/pages.d.ts +22 -0
- package/dist/utils/pages.js +73 -0
- package/dist/utils/path.d.ts +5 -0
- package/dist/utils/path.js +9 -0
- package/docs/api.md +35 -3
- package/docs/cli.md +6 -2
- package/drizzle/0002_add_pages.sql +5 -3
- package/drizzle/0005_add_registry_auth.sql +95 -0
- package/drizzle/0006_add_component_source_format.sql +3 -0
- package/drizzle/0007_add_ai_keys.sql +11 -0
- package/drizzle/meta/0002_snapshot.json +17 -8
- package/drizzle/meta/0003_snapshot.json +17 -8
- package/drizzle/meta/0004_snapshot.json +17 -8
- package/drizzle/meta/0005_snapshot.json +1935 -0
- package/drizzle/meta/0006_snapshot.json +1941 -0
- package/drizzle/meta/0007_snapshot.json +2013 -0
- package/drizzle/meta/_journal.json +21 -0
- package/drizzle.config.ts +1 -1
- package/package.json +44 -5
- package/src/ai/README.md +42 -0
- package/src/ai/connections.ts +172 -0
- package/src/ai/define.ts +15 -0
- package/src/ai/types.ts +31 -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 +674 -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 +22 -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 +59 -0
- package/src/app/components/Auth/AccountLayout.tsx +124 -0
- package/src/app/components/Auth/AuthControls.tsx +99 -0
- package/src/app/components/Auth/AuthShell.tsx +73 -0
- package/src/app/components/Auth/RegistryInstallGate.tsx +23 -0
- package/src/app/components/Auth/RegistrySessionProvider.tsx +15 -0
- package/src/app/components/Auth/api.ts +20 -0
- package/src/app/components/Component/PageSliceResolver.tsx +1 -0
- package/src/app/components/Component/Preview.tsx +406 -226
- package/src/app/components/Component/slices/ComponentDisplaySlice.tsx +4 -0
- package/src/app/components/CopyToClipboard.tsx +27 -26
- package/src/app/components/Foundations/DisplayLogo.tsx +8 -2
- package/src/app/components/Layout/Header.tsx +10 -14
- package/src/app/components/Layout/RuntimeModeBadge.tsx +18 -0
- package/src/app/components/Markdown/CodeHighlight.tsx +73 -70
- package/src/app/components/Markdown/MarkdownComponents.tsx +30 -32
- package/src/app/components/McpIntegration/McpConfigDialog.tsx +349 -0
- package/src/app/components/McpIntegration/McpIcon.tsx +10 -0
- package/src/app/components/Navigation/MobileNav.tsx +7 -1
- package/src/app/components/Navigation/SideNav.tsx +1 -15
- package/src/app/components/context/PreviewContext.tsx +5 -5
- 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/dialog.tsx +73 -0
- 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 +14 -38
- package/src/app/css/index.css +64 -0
- package/src/app/lib/ai/auth.ts +33 -0
- package/src/app/lib/ai/context.ts +96 -0
- package/src/app/lib/ai/model.ts +85 -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/auth/api.ts +105 -0
- package/src/app/lib/auth/config.ts +175 -0
- package/src/app/lib/auth/email.ts +34 -0
- package/src/app/lib/docs-api/backend.ts +16 -1
- package/src/app/lib/docs-api/errors.ts +8 -7
- package/src/app/lib/docs-api/handler.ts +2 -3
- package/src/app/lib/docs-api/index.ts +2 -0
- package/src/app/lib/docs-api/page-discovery.ts +121 -0
- package/src/app/lib/docs-api/page-rendering.ts +37 -0
- package/src/app/lib/docs-api/page-search.ts +191 -0
- package/src/app/lib/docs-api/records.ts +31 -24
- package/src/app/lib/docs-api/registry.ts +92 -11
- package/src/app/lib/docs-api/runtime-config.ts +42 -35
- package/src/app/lib/docs-api/search.ts +120 -0
- package/src/app/lib/mcp/auth.ts +64 -0
- package/src/app/lib/mcp/index.ts +2 -0
- package/src/app/lib/mcp/server.ts +357 -0
- package/src/app/lib/mcp/shape.ts +628 -0
- package/src/app/lib/registry-api/allowlist.ts +7 -5
- package/src/app/lib/registry-api/asset-transfer.ts +58 -31
- package/src/app/lib/registry-api/auth.ts +108 -45
- package/src/app/lib/registry-api/entity-routes.ts +17 -7
- package/src/app/lib/registry-api/errors.ts +12 -6
- package/src/app/lib/registry-api/handler.ts +22 -19
- package/src/app/lib/registry-api/meta.ts +4 -0
- package/src/app/lib/registry-api/revalidate.ts +31 -12
- package/src/app/lib/registry-api/store.ts +89 -26
- package/src/app/lib/registry-api/sync-compat.ts +166 -0
- package/src/app/lib/registry-api/token-transfer.ts +45 -13
- package/src/app/lib/registry-api/transfer-batch.ts +116 -0
- package/src/app/lib/registry-api/transfer.ts +99 -41
- package/src/app/lib/registry-api/validation.ts +33 -1
- package/src/app/lib/registry-connection.ts +2 -2
- package/src/app/lib/utils.ts +13 -0
- package/src/app/next.config.mjs +62 -16
- package/src/app/pages/[...slug]/index.tsx +52 -51
- package/src/app/pages/_app.tsx +14 -4
- package/src/app/pages/_document.tsx +6 -0
- package/src/app/pages/account/ai.tsx +162 -0
- package/src/app/pages/account/index.tsx +148 -0
- package/src/app/pages/account/tokens.tsx +232 -0
- package/src/app/pages/account/users.tsx +310 -0
- 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/account/index.ts +26 -0
- package/src/app/pages/api/account/tokens/[id].ts +17 -0
- package/src/app/pages/api/account/tokens/index.ts +35 -0
- package/src/app/pages/api/admin/users/[id]/[action].ts +89 -0
- package/src/app/pages/api/admin/users/index.ts +53 -0
- 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/[...nextauth].ts +4 -0
- package/src/app/pages/api/auth/request-reset.ts +53 -0
- package/src/app/pages/api/auth/reset-password.ts +29 -0
- package/src/app/pages/api/docs/search/pages.json.ts +25 -0
- package/src/app/pages/api/install.ts +102 -0
- package/src/app/pages/api/mcp.ts +56 -0
- package/src/app/pages/api/oauth/device/approve.ts +23 -0
- package/src/app/pages/api/oauth/device/index.ts +41 -0
- package/src/app/pages/api/oauth/revoke.ts +31 -0
- package/src/app/pages/api/oauth/token.ts +31 -0
- package/src/app/pages/api/registry/components/[id]/files/[...filePath].ts +1 -1
- package/src/app/pages/api/registry/components/[id].ts +2 -2
- package/src/app/pages/api/registry/components/index.ts +1 -1
- package/src/app/pages/api/registry/health.ts +4 -3
- package/src/app/pages/api/registry/pages/[...id].ts +20 -0
- package/src/app/pages/api/registry/pages/index.ts +19 -0
- package/src/app/pages/api/registry/patterns/[id]/files/[...filePath].ts +1 -1
- package/src/app/pages/api/registry/patterns/[id].ts +2 -2
- package/src/app/pages/api/registry/patterns/index.ts +1 -1
- package/src/app/pages/api/registry/transfer/[kind]/[id].ts +3 -3
- package/src/app/pages/api/registry/transfer/[kind]/index.ts +21 -0
- package/src/app/pages/api/registry/transfer/assets/[collection].ts +2 -1
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +2 -1
- package/src/app/pages/api/registry/transfer/assets/blobs/have.ts +2 -2
- package/src/app/pages/api/registry/transfer/tokens/[...setId].ts +2 -2
- package/src/app/pages/api/sync/upload.ts +21 -0
- package/src/app/pages/assets/logos.tsx +4 -1
- package/src/app/pages/cli/device.tsx +143 -0
- package/src/app/pages/foundations/icons/index.tsx +7 -5
- package/src/app/pages/foundations/icons/{[name] → library/[name]}/index.tsx +8 -8
- package/src/app/pages/foundations/logo.tsx +5 -4
- package/src/app/pages/index/index.tsx +14 -0
- package/src/app/pages/index.tsx +31 -5
- package/src/app/pages/install.tsx +336 -0
- package/src/app/pages/login.tsx +117 -0
- package/src/app/pages/reset-password.tsx +159 -0
- package/src/app/types/next-auth.d.ts +27 -0
- package/src/app-builder/build.ts +225 -86
- package/src/app-builder/client-config.ts +18 -14
- package/src/app-builder/config-diff/strategies/pattern.ts +1 -1
- package/src/app-builder/nav-shell.ts +8 -13
- package/src/app-builder/paths.ts +25 -1
- package/src/app-builder/static-export.ts +27 -0
- package/src/app-builder/vercel-output.ts +6 -6
- package/src/app-builder/watchers/component.ts +3 -3
- package/src/app-builder/watchers/utils.ts +2 -3
- package/src/app-builder/watchers.ts +63 -57
- package/src/artifacts/index.ts +8 -1
- package/src/artifacts/url.ts +32 -0
- package/src/cache/build-cache.ts +16 -15
- package/src/catalog/README.md +95 -0
- package/src/catalog/define.ts +79 -0
- package/src/catalog/implementation.ts +145 -0
- package/src/catalog/index.ts +31 -0
- package/src/catalog/normalize.ts +145 -0
- package/src/catalog/previews.ts +114 -0
- package/src/catalog/renderers.ts +94 -0
- package/src/catalog/types.ts +82 -0
- package/src/cli/README.md +1 -1
- package/src/cli/auth/browser.ts +29 -0
- package/src/cli/auth/device.ts +186 -0
- package/src/cli/auth/store.ts +194 -0
- package/src/cli/create.ts +58 -3
- package/src/cli/make.ts +22 -74
- package/src/cli/scaffold.ts +39 -222
- package/src/cli.ts +31 -7
- package/src/commands/README.md +1 -1
- package/src/commands/build/app.ts +2 -3
- package/src/commands/build/components.ts +2 -3
- package/src/commands/build/index.ts +2 -3
- package/src/commands/checkout/index.ts +29 -50
- package/src/commands/compat/deprecations.ts +79 -0
- package/src/commands/compat/push-args.ts +106 -0
- package/src/commands/db/migrate.ts +2 -3
- package/src/commands/dev/index.ts +2 -3
- package/src/commands/eject/config.ts +2 -3
- package/src/commands/eject/pages.ts +2 -3
- package/src/commands/eject/theme.ts +2 -3
- package/src/commands/fetch/index.ts +2 -3
- package/src/commands/index.ts +8 -2
- package/src/commands/login/index.ts +61 -0
- package/src/commands/logout/index.ts +104 -0
- package/src/commands/make/component.ts +2 -3
- package/src/commands/make/page.ts +4 -5
- package/src/commands/publish/index.ts +32 -49
- package/src/commands/pull/index.ts +32 -0
- package/src/commands/push/index.ts +115 -0
- package/src/commands/scaffold/index.ts +2 -3
- package/src/commands/start/index.ts +2 -3
- package/src/commands/types.ts +13 -1
- package/src/commands/utils.ts +107 -2
- package/src/commands/validate/components.ts +2 -3
- package/src/config/README.md +63 -2
- package/src/config/catalog-include.ts +227 -0
- package/src/config/defaults.ts +26 -13
- package/src/config/env.ts +41 -0
- package/src/config/errors.ts +7 -0
- package/src/config/from-env.ts +26 -0
- package/src/config/helpers.ts +4 -2
- package/src/config/index.ts +10 -2
- package/src/config/loader.ts +208 -43
- package/src/config/normalizers/page.ts +4 -4
- package/src/config/resolve-env.ts +107 -0
- package/src/config/runtime.ts +212 -226
- package/src/config/validator.ts +4 -6
- package/src/handlebars.ts +24 -0
- package/src/index.d.ts +2 -2
- package/src/index.ts +325 -72
- package/src/nav/resolver.ts +3 -1
- package/src/nav/workspace.ts +2 -2
- package/src/pattern.ts +14 -0
- package/src/pipeline/index.ts +1 -1
- package/src/react.ts +52 -0
- package/src/registry/asset-storage/adapters/vercel-blob.ts +1 -1
- package/src/registry/asset-storage/define.ts +1 -1
- package/src/registry/asset-storage/resolve.ts +7 -4
- package/src/registry/auth/access-tokens.ts +222 -0
- package/src/registry/auth/action-tokens.ts +225 -0
- package/src/registry/auth/ai-keys.ts +62 -0
- package/src/registry/auth/crypto.ts +75 -0
- package/src/registry/auth/database.ts +15 -0
- package/src/registry/auth/device-authorizations.ts +223 -0
- package/src/registry/auth/gravatar.ts +6 -0
- package/src/registry/auth/index.ts +105 -0
- package/src/registry/auth/installation.ts +117 -0
- package/src/registry/auth/password.ts +46 -0
- package/src/registry/auth/rate-limits.ts +84 -0
- package/src/registry/auth/sync-secret.ts +67 -0
- package/src/registry/auth/types.ts +57 -0
- package/src/registry/auth/user-record.ts +25 -0
- package/src/registry/auth/users.ts +145 -0
- package/src/registry/auth/validation.ts +42 -0
- package/src/registry/checkout/assets.ts +28 -9
- package/src/registry/checkout/index.ts +582 -130
- package/src/registry/checkout/tokens.ts +16 -8
- package/src/registry/client.ts +7 -1
- package/src/registry/connection.ts +91 -19
- package/src/registry/content-kinds.ts +39 -0
- package/src/registry/db/client.ts +34 -14
- package/src/registry/db/driver.ts +66 -0
- package/src/registry/db/index.ts +16 -5
- package/src/registry/db/migrate.ts +5 -5
- package/src/registry/db/schema.ts +225 -25
- package/src/registry/publish/assets.ts +47 -37
- package/src/registry/publish/errors.ts +3 -3
- package/src/registry/publish/index.ts +286 -27
- package/src/registry/publish/package.ts +14 -1
- package/src/registry/publish/tokens.ts +35 -26
- package/src/registry/selection.ts +63 -0
- package/src/registry/transfer.ts +14 -0
- package/src/store/filesystem.ts +6 -6
- package/src/store/registry.ts +131 -15
- package/src/transformers/plugins/csf-render.ts +4 -2
- package/src/transformers/plugins/ssr-render.ts +66 -19
- package/src/transformers/preview/component/api.ts +13 -1
- package/src/transformers/preview/component/artifacts.ts +8 -4
- package/src/transformers/preview/component/builder.ts +17 -4
- package/src/transformers/preview/component/css.ts +99 -60
- package/src/transformers/preview/component/html.ts +30 -19
- package/src/transformers/preview/component/javascript.ts +1 -3
- package/src/transformers/preview/pattern/builder.ts +33 -20
- package/src/transformers/preview/pattern/html.ts +3 -1
- package/src/transformers/preview/types.ts +31 -3
- package/src/transformers/utils/build.ts +80 -0
- package/src/transformers/utils/module.ts +4 -2
- package/src/types/config.ts +168 -45
- package/src/utils/README.md +1 -0
- package/src/utils/markdown.ts +11 -0
- package/src/utils/menu-shell.ts +14 -7
- package/src/utils/pages.ts +52 -0
- package/src/utils/path.ts +15 -6
- package/templates/default/README.md.tpl +68 -1
- package/templates/default/components/button/button.react.handoff.js.tpl +19 -23
- package/templates/default/components/button/button.react.handoff.ts.tpl +22 -22
- package/templates/default/env.tpl +10 -0
- package/templates/default/gitignore.tpl +26 -3
- package/templates/default/handoff.config.js.tpl +21 -166
- package/templates/default/handoff.config.ts.tpl +21 -150
- package/templates/default/handoff.config.with-examples.js.tpl +22 -164
- package/templates/default/handoff.config.with-examples.ts.tpl +22 -148
- package/templates/default/package.json.tpl +6 -1
- package/templates/default/vercel.json.tpl +4 -0
- package/config/docs/foundations/logos.md +0 -7
- package/config/templates/component/template.json +0 -49
- package/config/templates/template.html +0 -7
- package/dist/commands/make/template.d.ts +0 -8
- package/dist/commands/make/template.js +0 -47
- package/dist/config/normalizers/declaration.d.ts +0 -11
- package/dist/config/normalizers/declaration.js +0 -122
- package/dist/config/normalizers/pattern.d.ts +0 -8
- package/dist/config/normalizers/pattern.js +0 -41
- package/dist/declarations/helpers.d.ts +0 -6
- package/dist/declarations/helpers.js +0 -19
- package/dist/declarations/index.d.ts +0 -2
- package/dist/declarations/index.js +0 -9
- package/dist/declarations/types.d.ts +0 -60
- package/dist/registry/db/adapter.d.ts +0 -43
- package/dist/registry/db/adapter.js +0 -59
- package/src/app/lib/api/redact.ts +0 -46
- package/src/commands/make/template.ts +0 -47
- package/src/config/normalizers/declaration.ts +0 -179
- package/src/config/normalizers/pattern.ts +0 -59
- package/src/declarations/helpers.ts +0 -36
- package/src/declarations/index.ts +0 -19
- package/src/declarations/types.ts +0 -70
- package/src/registry/db/adapter.ts +0 -74
- /package/dist/{declarations → catalog}/types.js +0 -0
package/UPGRADE.md
ADDED
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
# Upgrade Handoff
|
|
2
|
+
|
|
3
|
+
This document contains migration steps for each major version upgrade.
|
|
4
|
+
|
|
5
|
+
## Version 1.x.x to version 2.x.x
|
|
6
|
+
|
|
7
|
+
This guide describes how to upgrade a Handoff project from version 1.x.x to version 2.x.x.
|
|
8
|
+
Each feature section identifies the affected projects and the required changes.
|
|
9
|
+
|
|
10
|
+
### Before you start
|
|
11
|
+
|
|
12
|
+
1. Verify that the project builds with its current Handoff version.
|
|
13
|
+
2. Save the project files, package version, and lockfile in version control.
|
|
14
|
+
3. Install the version 2.x.x package that you plan to use.
|
|
15
|
+
4. Apply the migration sections that affect your project.
|
|
16
|
+
|
|
17
|
+
### Breaking changes
|
|
18
|
+
|
|
19
|
+
| Change | Affected projects |
|
|
20
|
+
| --- | --- |
|
|
21
|
+
| [Figma token environment references](#figma-token-environment-references) | Projects that put a Figma token directly in config |
|
|
22
|
+
| [Catalog items](#catalog-items) | Projects with component or pattern declarations |
|
|
23
|
+
|
|
24
|
+
<!-- Add future breaking changes as feature sections before "Verify the upgrade". Add each section to this table. -->
|
|
25
|
+
|
|
26
|
+
### Figma token environment references
|
|
27
|
+
|
|
28
|
+
`devAccessToken` and its legacy spelling `dev_access_token` now accept only an environment reference.
|
|
29
|
+
A literal token throws `HandoffConfigError`, including in JavaScript and JSON configs.
|
|
30
|
+
Move the token to the environment and replace the literal:
|
|
31
|
+
|
|
32
|
+
```ts
|
|
33
|
+
import { defineConfig, fromEnv } from 'handoff-app';
|
|
34
|
+
|
|
35
|
+
export default defineConfig({
|
|
36
|
+
devAccessToken: fromEnv('HANDOFF_DEV_ACCESS_TOKEN'),
|
|
37
|
+
});
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
For JSON, use `"devAccessToken": { "$env": "HANDOFF_DEV_ACCESS_TOKEN" }`.
|
|
41
|
+
If you already use `HANDOFF_DEV_ACCESS_TOKEN` and omit the config property, no change is required.
|
|
42
|
+
Environment references resolve after profile merging. Higher-layer literals still override default
|
|
43
|
+
environment seeds for properties that allow literals, such as output directories.
|
|
44
|
+
|
|
45
|
+
### Catalog items
|
|
46
|
+
|
|
47
|
+
#### Affected projects
|
|
48
|
+
|
|
49
|
+
This change affects projects that use the old component or pattern registration API.
|
|
50
|
+
It also affects projects that use the deprecated API from an earlier version 2.x.x prerelease.
|
|
51
|
+
Version 2.x.x requires `defineCatalogItem` for implementations and compositions.
|
|
52
|
+
|
|
53
|
+
#### Register catalog directories
|
|
54
|
+
|
|
55
|
+
Move component and pattern directories from `entries` to `catalog.include`.
|
|
56
|
+
|
|
57
|
+
Version 1.x.x:
|
|
58
|
+
|
|
59
|
+
```js
|
|
60
|
+
entries: { components: ['components'], patterns: ['patterns'], scss: 'styles/main.scss' }
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Version 2.x.x:
|
|
64
|
+
|
|
65
|
+
```js
|
|
66
|
+
catalog: { include: ['components', 'patterns'] },
|
|
67
|
+
entries: { scss: 'styles/main.scss' }
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
Each path can name one item directory or a collection of item directories. Global `entries.js` and `entries.scss` still work.
|
|
71
|
+
|
|
72
|
+
#### Convert declaration files
|
|
73
|
+
|
|
74
|
+
Use `<name>.handoff.ts`, `<name>.handoff.js`, or `<name>.handoff.cjs`.
|
|
75
|
+
Replace legacy filenames such as `button.json` or `button.js`.
|
|
76
|
+
|
|
77
|
+
Version 2.x.x does not support JSON item declarations, including `.handoff.json`.
|
|
78
|
+
JSON project config (`handoff.config.json`) remains supported.
|
|
79
|
+
|
|
80
|
+
If `runtime.workspace.declarationFormat` is `json`, change it to `ts`, `js`, or `cjs`. The default remains `ts`.
|
|
81
|
+
|
|
82
|
+
#### Replace declaration helpers
|
|
83
|
+
|
|
84
|
+
| Removed API | Replacement |
|
|
85
|
+
| --- | --- |
|
|
86
|
+
| `defineReactComponent(Component, config)` | `defineCatalogItem({ ...config, implementation: Component })` from `handoff-app/react` |
|
|
87
|
+
| `defineHandlebarsComponent(config)` | `defineCatalogItem({ ...config, implementation: './Button.hbs' })` from `handoff-app/handlebars` |
|
|
88
|
+
| `defineCsfComponent(config)` | `defineCatalogItem({ ...config, implementation: fromCSF('./Button.stories.tsx') })` from `handoff-app/react` |
|
|
89
|
+
| `defineComponent(config)` | `defineCatalogItem({ ...config, implementation: './Button.tsx' })` from the module for its renderer |
|
|
90
|
+
| `definePattern({ components })` | `defineCatalogItem({ composition })` from `handoff-app/pattern` |
|
|
91
|
+
|
|
92
|
+
Remove the old `renderer`, `entries.component`, `entries.template`, and `entries.story` fields.
|
|
93
|
+
The implementation supplies the renderer and source file.
|
|
94
|
+
Keep the supporting `entries.js`, `entries.scss`, `entries.schema`, and `entries.templates` paths that your item uses.
|
|
95
|
+
Rename the metadata fields:
|
|
96
|
+
|
|
97
|
+
| Old field | Version 2.x.x field |
|
|
98
|
+
| --- | --- |
|
|
99
|
+
| `title` | `name` |
|
|
100
|
+
| `should_do` | `shouldDo` |
|
|
101
|
+
| `should_not_do` | `shouldNotDo` |
|
|
102
|
+
|
|
103
|
+
##### React
|
|
104
|
+
|
|
105
|
+
```ts
|
|
106
|
+
import { defineCatalogItem, type Preview } from 'handoff-app/react';
|
|
107
|
+
import Button from './Button';
|
|
108
|
+
|
|
109
|
+
const item = defineCatalogItem({
|
|
110
|
+
name: 'Button',
|
|
111
|
+
implementation: Button,
|
|
112
|
+
entries: { scss: './button.scss' },
|
|
113
|
+
});
|
|
114
|
+
export default item;
|
|
115
|
+
export const Primary = { args: { children: 'Save' } } satisfies Preview<typeof item>;
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Imported components retain their prop types. A file path also works: `implementation: './Button.tsx'`.
|
|
119
|
+
Keep implementation files inside the item directory to publish them.
|
|
120
|
+
|
|
121
|
+
##### Handlebars and CommonJS
|
|
122
|
+
|
|
123
|
+
```js
|
|
124
|
+
const { defineCatalogItem } = require('handoff-app/handlebars');
|
|
125
|
+
|
|
126
|
+
exports.default = defineCatalogItem({
|
|
127
|
+
name: 'Badge',
|
|
128
|
+
implementation: './Badge.hbs',
|
|
129
|
+
});
|
|
130
|
+
exports.Primary = { args: { children: 'New' } };
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
Use this form in `.handoff.js` or `.handoff.cjs`. JavaScript declarations can also use `import` and `export`.
|
|
134
|
+
|
|
135
|
+
##### CSF
|
|
136
|
+
|
|
137
|
+
```ts
|
|
138
|
+
import { defineCatalogItem, fromCSF } from 'handoff-app/react';
|
|
139
|
+
|
|
140
|
+
export default defineCatalogItem({
|
|
141
|
+
name: 'Button',
|
|
142
|
+
implementation: fromCSF('./Button.stories.tsx'),
|
|
143
|
+
});
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
CSF is a React source format. The story file supplies the previews.
|
|
147
|
+
The filename does not select CSF automatically.
|
|
148
|
+
|
|
149
|
+
##### Compositions
|
|
150
|
+
|
|
151
|
+
```ts
|
|
152
|
+
import { defineCatalogItem } from 'handoff-app/pattern';
|
|
153
|
+
|
|
154
|
+
export default defineCatalogItem({
|
|
155
|
+
name: 'Toolbar',
|
|
156
|
+
composition: [{ ref: 'button', preview: 'Primary', args: { children: 'Save' } }],
|
|
157
|
+
});
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
Rename `components` to `composition`.
|
|
161
|
+
Rename each member's `id` to `ref`.
|
|
162
|
+
Keep item IDs stable.
|
|
163
|
+
|
|
164
|
+
#### Export previews
|
|
165
|
+
|
|
166
|
+
Remove the inline `previews` map.
|
|
167
|
+
Export each preview beside the default catalog item.
|
|
168
|
+
Rename preview `title` to `name`.
|
|
169
|
+
Rename `values` to `args`:
|
|
170
|
+
|
|
171
|
+
```ts
|
|
172
|
+
export const Primary = { name: 'Primary action', args: { children: 'Save' } };
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
If a preview key is a valid export name, preserve its spelling and capitalization.
|
|
176
|
+
If a key is not a valid export name, rename it.
|
|
177
|
+
Update composition references to each renamed preview.
|
|
178
|
+
|
|
179
|
+
Previews appear in source export order.
|
|
180
|
+
|
|
181
|
+
For CommonJS declarations, use `exports.default` for the item.
|
|
182
|
+
Use a named export such as `exports.Primary` for each preview.
|
|
183
|
+
|
|
184
|
+
#### Replace declaration types
|
|
185
|
+
|
|
186
|
+
Replace imports of the removed types:
|
|
187
|
+
|
|
188
|
+
| Removed type | Replacement |
|
|
189
|
+
| --- | --- |
|
|
190
|
+
| `Component` | `CatalogItem` |
|
|
191
|
+
| `DeclarationPreview` | `CatalogPreview` or `Preview<typeof item>` |
|
|
192
|
+
| `PatternComponentRef` | `CompositionRef` |
|
|
193
|
+
| `ReactDeclarationConfig`, `HandlebarsDeclarationConfig`, `CsfDeclarationConfig` | The catalog helper's input type |
|
|
194
|
+
| `GenericDeclarationConfig`, `GenericPatternDeclarationConfig` | The catalog helper's input type, or `CatalogItemMeta` for shared metadata |
|
|
195
|
+
|
|
196
|
+
`RendererKind` comes from the catalog API and contains `react` and `handlebars`.
|
|
197
|
+
CSF uses `renderer: 'react'` with `format: 'csf'` inside `implementation`.
|
|
198
|
+
|
|
199
|
+
#### Registry projects
|
|
200
|
+
|
|
201
|
+
Checkout writes only catalog declarations.
|
|
202
|
+
Registry records require explicit renderer and source-format metadata where applicable.
|
|
203
|
+
|
|
204
|
+
### Verify the upgrade
|
|
205
|
+
|
|
206
|
+
After you apply the required migrations, verify the project:
|
|
207
|
+
|
|
208
|
+
1. Build the project with version 2.x.x.
|
|
209
|
+
2. Verify that all expected catalog items appear in the documentation.
|
|
210
|
+
3. Verify the preview order, arguments, and composition references.
|
|
211
|
+
4. Start the workspace with file watchers.
|
|
212
|
+
5. Edit a declaration to verify that its previews update.
|
|
213
|
+
|
|
214
|
+
If the project uses a registry, verify the published items:
|
|
215
|
+
|
|
216
|
+
1. Publish the migrated items.
|
|
217
|
+
2. Verify that checkout produces valid declarations.
|
|
218
|
+
3. Rebuild the checked-out items.
|
|
@@ -54,13 +54,10 @@ const config = {
|
|
|
54
54
|
ports: { app: 3000, websocket: 3001 },
|
|
55
55
|
},
|
|
56
56
|
// These are the entry points used to compile the target application
|
|
57
|
+
catalog: { include: ['./components'] },
|
|
57
58
|
entries: {
|
|
58
59
|
scss: './sass/main.scss',
|
|
59
60
|
js: './js/main.js',
|
|
60
|
-
components: ['./components'],
|
|
61
|
-
// Uncomment to enable pattern documentation pages.
|
|
62
|
-
// Patterns compose component previews into single-page views.
|
|
63
|
-
// patterns: ['./patterns'],
|
|
64
61
|
},
|
|
65
62
|
// These are the asset zip file download links
|
|
66
63
|
assetsZipLinks: {
|
|
@@ -34,11 +34,10 @@ export default defineConfig({
|
|
|
34
34
|
},
|
|
35
35
|
ports: { app: 3000, websocket: 3001 },
|
|
36
36
|
},
|
|
37
|
+
catalog: { include: ['./components'] },
|
|
37
38
|
entries: {
|
|
38
39
|
scss: './sass/main.scss',
|
|
39
40
|
js: './js/main.js',
|
|
40
|
-
components: ['./components'],
|
|
41
|
-
// patterns: ['./patterns'],
|
|
42
41
|
},
|
|
43
42
|
assetsZipLinks: {
|
|
44
43
|
icons: null,
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Color Guidelines
|
|
3
|
+
description: How to apply the color palette consistently and accessibly across products.
|
|
4
|
+
metaTitle: 'Color Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'How to apply the color palette consistently and accessibly across products.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Color Guidelines** page. Replace it with your rules for
|
|
9
|
+
contrast, pairing, and semantic usage. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Effects Guidelines
|
|
3
|
+
description: When and how to apply shadows, blurs, and elevation across the interface.
|
|
4
|
+
metaTitle: 'Effects Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'When and how to apply shadows, blurs, and elevation across the interface.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Effects Guidelines** page. Replace it with your rules for
|
|
9
|
+
elevation, depth, and motion. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Effects Resources
|
|
3
|
+
description: Reference values and assets for reproducing the brand's effects in any tool.
|
|
4
|
+
metaTitle: 'Effects Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Reference values and assets for reproducing effects in any tool.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Effects Resources** page. Replace it with your shadow tokens,
|
|
9
|
+
blur values, and export notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Grid
|
|
3
|
+
description: Layout grid and spacing system that keeps compositions aligned and balanced.
|
|
4
|
+
image: hero-design
|
|
5
|
+
metaTitle: 'Grid | Handoff Design System'
|
|
6
|
+
metaDescription: 'Layout grid and spacing system that keeps compositions aligned and balanced.'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This is placeholder content for the **Grid** page. Replace it with your columns, gutters, and
|
|
10
|
+
breakpoint rules. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Icon Guidelines
|
|
3
|
+
description: Sizing, spacing, and usage rules that keep the icon set consistent.
|
|
4
|
+
metaTitle: 'Icon Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'Sizing, spacing, and usage rules that keep the icon set consistent.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Icon Guidelines** page. Replace it with your rules for grid
|
|
9
|
+
sizing, stroke, and when to use each icon. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Image Guidelines
|
|
3
|
+
description: How to select, crop, and treat imagery so it stays on brand.
|
|
4
|
+
metaTitle: 'Image Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'How to select, crop, and treat imagery so it stays on brand.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Image Guidelines** page. Replace it with your rules for
|
|
9
|
+
composition, cropping, and treatments. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Image Resources
|
|
3
|
+
description: Source files and downloads for approved photography and illustration.
|
|
4
|
+
metaTitle: 'Image Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Source files and downloads for approved photography and illustration.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Image Resources** page. Replace it with your image library,
|
|
9
|
+
downloads, and licensing notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Images
|
|
3
|
+
description: Photography and illustration style that shapes how the brand looks and feels.
|
|
4
|
+
image: hero-design
|
|
5
|
+
metaTitle: 'Images | Handoff Design System'
|
|
6
|
+
metaDescription: 'Photography and illustration style that shapes how the brand looks and feels.'
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
This is placeholder content for the **Images** page. Replace it with your art direction,
|
|
10
|
+
photography style, and illustration principles. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Logo Resources
|
|
3
|
+
description: Downloadable logo files and everything teams need to represent the brand correctly.
|
|
4
|
+
metaTitle: 'Logo Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Downloadable logo files and everything teams need to represent the brand correctly.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Logo Resources** page. Replace it with your logo downloads,
|
|
9
|
+
file formats, and usage notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Typography Guidelines
|
|
3
|
+
description: Best practices for type scale, hierarchy, and readability across the system.
|
|
4
|
+
metaTitle: 'Typography Guidelines | Handoff Design System'
|
|
5
|
+
metaDescription: 'Best practices for type scale, hierarchy, and readability across the system.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Typography Guidelines** page. Replace it with your rules for
|
|
9
|
+
hierarchy, spacing, and responsive type. Markdown and <b>HTML</b> are both supported.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
---
|
|
2
|
+
title: Typography Resources
|
|
3
|
+
description: Font files, licenses, and assets needed to work with the brand typography.
|
|
4
|
+
metaTitle: 'Typography Resources | Handoff Design System'
|
|
5
|
+
metaDescription: 'Font files, licenses, and assets needed to work with the brand typography.'
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
This is placeholder content for the **Typography Resources** page. Replace it with your font
|
|
9
|
+
downloads, licensing details, and platform notes. Markdown and <b>HTML</b> are both supported.
|
|
@@ -67,8 +67,10 @@ menu:
|
|
|
67
67
|
title: Images
|
|
68
68
|
icon: image
|
|
69
69
|
menu:
|
|
70
|
-
- path: foundations/
|
|
71
|
-
title:
|
|
72
|
-
- path: foundations/
|
|
70
|
+
- path: foundations/images
|
|
71
|
+
title: Overview
|
|
72
|
+
- path: foundations/images/guidelines
|
|
73
73
|
title: Guidelines
|
|
74
|
+
- path: foundations/images/resources
|
|
75
|
+
title: Resources
|
|
74
76
|
---
|
|
@@ -0,0 +1,64 @@
|
|
|
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
|
+
export declare const mergeAiConnections: (baked: readonly AiConnectionSettings[], overrides: readonly AiConnectionSettings[]) => AiConnectionSettings[];
|
|
51
|
+
/** Parse the `HANDOFF_AI_CONNECTIONS` JSON array. A malformed value is ignored rather than fatal. */
|
|
52
|
+
export declare const parseAiConnections: (raw: string | undefined) => AiConnectionSettings[];
|
|
53
|
+
/**
|
|
54
|
+
* Whether this build serves the assistant. The `ai` block is the opt-in; `enabled: false` turns it
|
|
55
|
+
* back off. Config-only and baked, like `runtime.mcp`.
|
|
56
|
+
*/
|
|
57
|
+
export declare const isAiEnabled: (config: Pick<ResolvedConfig, "runtime"> | null | undefined) => boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Resolve the AI settings from a loaded config (CLI/build side).
|
|
60
|
+
*
|
|
61
|
+
* An authored connection that cannot be used fails the build rather than disappearing. A deployment
|
|
62
|
+
* list stays lenient by contrast: a bad `HANDOFF_AI_CONNECTIONS` entry must not take the server down.
|
|
63
|
+
*/
|
|
64
|
+
export declare const resolveAiFromConfig: (config: ResolvedConfig | null | undefined) => AiSettings;
|
|
@@ -0,0 +1,136 @@
|
|
|
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
|
+
/**
|
|
78
|
+
* Merge a deployment-supplied list over the baked one by `id`: a matching id replaces the baked
|
|
79
|
+
* connection outright, and a new id is appended. Replacement rather than a field-wise merge, so a
|
|
80
|
+
* deployment that repoints a gateway cannot leave a stale model list or key name behind.
|
|
81
|
+
*/
|
|
82
|
+
const mergeAiConnections = (baked, overrides) => {
|
|
83
|
+
const byId = new Map(baked.map((connection) => [connection.id, connection]));
|
|
84
|
+
for (const connection of overrides)
|
|
85
|
+
byId.set(connection.id, connection);
|
|
86
|
+
return [...byId.values()];
|
|
87
|
+
};
|
|
88
|
+
exports.mergeAiConnections = mergeAiConnections;
|
|
89
|
+
/** Parse the `HANDOFF_AI_CONNECTIONS` JSON array. A malformed value is ignored rather than fatal. */
|
|
90
|
+
const parseAiConnections = (raw) => {
|
|
91
|
+
if (!(raw === null || raw === void 0 ? void 0 : raw.trim()))
|
|
92
|
+
return [];
|
|
93
|
+
try {
|
|
94
|
+
const parsed = JSON.parse(raw);
|
|
95
|
+
return Array.isArray(parsed) ? toConnectionList(parsed) : [];
|
|
96
|
+
}
|
|
97
|
+
catch (_a) {
|
|
98
|
+
return [];
|
|
99
|
+
}
|
|
100
|
+
};
|
|
101
|
+
exports.parseAiConnections = parseAiConnections;
|
|
102
|
+
/**
|
|
103
|
+
* Whether this build serves the assistant. The `ai` block is the opt-in; `enabled: false` turns it
|
|
104
|
+
* back off. Config-only and baked, like `runtime.mcp`.
|
|
105
|
+
*/
|
|
106
|
+
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; };
|
|
107
|
+
exports.isAiEnabled = isAiEnabled;
|
|
108
|
+
/**
|
|
109
|
+
* Resolve the AI settings from a loaded config (CLI/build side).
|
|
110
|
+
*
|
|
111
|
+
* An authored connection that cannot be used fails the build rather than disappearing. A deployment
|
|
112
|
+
* list stays lenient by contrast: a bad `HANDOFF_AI_CONNECTIONS` entry must not take the server down.
|
|
113
|
+
*/
|
|
114
|
+
const resolveAiFromConfig = (config) => {
|
|
115
|
+
var _a, _b, _c, _d, _e, _f;
|
|
116
|
+
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 : []);
|
|
117
|
+
const fail = (problem, ids) => {
|
|
118
|
+
throw new errors_1.HandoffConfigError(`Config "runtime.ai.connections": ${problem} (${ids.map((id) => JSON.stringify(id !== null && id !== void 0 ? id : null)).join(', ')}).`);
|
|
119
|
+
};
|
|
120
|
+
const normalized = authored.map((connection) => ({ authored: connection, settings: toConnectionSettings(connection) }));
|
|
121
|
+
const unusable = normalized.filter((entry) => !entry.settings);
|
|
122
|
+
if (unusable.length > 0) {
|
|
123
|
+
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; }));
|
|
124
|
+
}
|
|
125
|
+
const ids = normalized.map((entry) => entry.settings.id);
|
|
126
|
+
const duplicates = ids.filter((id, index) => ids.indexOf(id) !== index);
|
|
127
|
+
if (duplicates.length > 0) {
|
|
128
|
+
fail('a connection id must be unique, because it is half of every model address', duplicates);
|
|
129
|
+
}
|
|
130
|
+
return {
|
|
131
|
+
enabled: (0, exports.isAiEnabled)(config),
|
|
132
|
+
connections: normalized.map((entry) => entry.settings),
|
|
133
|
+
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,
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
exports.resolveAiFromConfig = resolveAiFromConfig;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Typed identity helper for custom AI providers (mirrors `defineAssetStorage`): 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 `defineAssetStorage`): 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
|
+
}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Server-only AI provider contract for connections that are not OpenAI-compatible.
|
|
3
|
+
*
|
|
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
|
|
6
|
+
* them fronts Anthropic, Google and xAI models. A provider that fits nothing else names a
|
|
7
|
+
* {@link defineAiProvider} module instead of a base URL.
|
|
8
|
+
*/
|
|
9
|
+
import type { LanguageModel } from 'ai';
|
|
10
|
+
/** Context passed to a custom provider factory: its non-secret options, the process env, and the resolved key. */
|
|
11
|
+
export interface AiProviderContext {
|
|
12
|
+
/** Non-secret options from the connection's `options`. Put env-var *names* here, never values. */
|
|
13
|
+
options: Record<string, unknown>;
|
|
14
|
+
/** The process environment. Read secret *values* here by the env-var *names* carried in options. */
|
|
15
|
+
env: NodeJS.ProcessEnv;
|
|
16
|
+
/**
|
|
17
|
+
* The resolved key for this request: the deployment's own key for a service connection, or the
|
|
18
|
+
* reader's saved key for a `credential: 'user'` connection. Undefined when neither applies.
|
|
19
|
+
*/
|
|
20
|
+
apiKey?: string;
|
|
21
|
+
}
|
|
22
|
+
/** The pluggable provider contract: resolve one of the connection's declared models. */
|
|
23
|
+
export interface AiProvider {
|
|
24
|
+
languageModel(modelId: string): LanguageModel;
|
|
25
|
+
}
|
|
26
|
+
/** A custom provider may export the provider directly or a factory that builds it from its context. */
|
|
27
|
+
export type AiProviderFactory = (context: AiProviderContext) => AiProvider | Promise<AiProvider>;
|
package/dist/ai/types.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Server-only AI provider contract for connections that are not OpenAI-compatible.
|
|
4
|
+
*
|
|
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
|
|
7
|
+
* them fronts Anthropic, Google and xAI models. A provider that fits nothing else names a
|
|
8
|
+
* {@link defineAiProvider} module instead of a base URL.
|
|
9
|
+
*/
|
|
10
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|