handoff-app 2.0.0-3 → 2.0.0-5
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 +302 -378
- package/dist/app-builder/build.js +2 -2
- package/dist/app-builder/nav-shell.js +8 -15
- package/dist/app-builder/vercel-output.js +4 -4
- package/dist/cli/make.js +2 -2
- 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 +15 -12
- package/dist/commands/checkout/index.js +15 -54
- 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 +4 -0
- package/dist/commands/login/index.js +1 -5
- package/dist/commands/logout/index.js +1 -5
- package/dist/commands/make/component.js +1 -5
- package/dist/commands/make/page.js +3 -7
- package/dist/commands/make/template.js +1 -5
- package/dist/commands/publish/index.d.ts +18 -12
- package/dist/commands/publish/index.js +18 -54
- 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 +10 -0
- package/dist/commands/utils.d.ts +74 -6
- package/dist/commands/utils.js +89 -10
- package/dist/commands/validate/components.js +1 -5
- package/dist/config/index.d.ts +2 -1
- package/dist/config/index.js +2 -1
- package/dist/config/loader.d.ts +19 -6
- package/dist/config/loader.js +43 -13
- package/dist/config/normalizers/page.d.ts +4 -4
- package/dist/config/normalizers/page.js +2 -2
- package/dist/config/runtime.js +9 -25
- package/dist/index.d.ts +69 -22
- package/dist/index.js +148 -35
- package/dist/nav/resolver.js +3 -1
- package/dist/nav/workspace.js +2 -2
- package/dist/registry/auth/access-tokens.d.ts +11 -3
- package/dist/registry/auth/access-tokens.js +29 -3
- package/dist/registry/auth/index.d.ts +4 -3
- package/dist/registry/auth/index.js +10 -2
- 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 +20 -1
- package/dist/registry/auth/types.js +3 -1
- package/dist/registry/auth/validation.d.ts +11 -0
- package/dist/registry/auth/validation.js +18 -1
- package/dist/registry/checkout/assets.d.ts +1 -1
- package/dist/registry/checkout/assets.js +21 -6
- package/dist/registry/checkout/index.d.ts +8 -1
- package/dist/registry/checkout/index.js +39 -6
- package/dist/registry/checkout/tokens.d.ts +1 -1
- package/dist/registry/checkout/tokens.js +12 -5
- package/dist/registry/connection.d.ts +10 -0
- package/dist/registry/connection.js +52 -7
- package/dist/registry/content-kinds.d.ts +27 -0
- package/dist/registry/content-kinds.js +33 -0
- package/dist/registry/db/client.d.ts +6 -1
- package/dist/registry/db/client.js +16 -3
- package/dist/registry/db/schema.d.ts +37 -3
- package/dist/registry/db/schema.js +9 -7
- package/dist/registry/publish/assets.d.ts +2 -2
- package/dist/registry/publish/assets.js +46 -35
- package/dist/registry/publish/index.d.ts +29 -5
- package/dist/registry/publish/index.js +87 -34
- package/dist/registry/publish/tokens.d.ts +2 -2
- package/dist/registry/publish/tokens.js +30 -24
- package/dist/registry/selection.d.ts +12 -0
- package/dist/registry/selection.js +22 -0
- package/dist/store/registry.d.ts +48 -0
- package/dist/store/registry.js +75 -12
- package/dist/transformers/preview/types.d.ts +2 -2
- 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 +1 -3
- package/docs/cli.md +1 -1
- package/drizzle/0002_add_pages.sql +5 -3
- 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 +17 -8
- package/package.json +1 -1
- package/src/app/components/util/index.ts +5 -23
- package/src/app/lib/docs-api/backend.ts +11 -0
- 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 +126 -0
- package/src/app/lib/docs-api/page-rendering.ts +17 -0
- package/src/app/lib/docs-api/page-search.ts +191 -0
- package/src/app/lib/docs-api/records.ts +11 -19
- package/src/app/lib/docs-api/registry.ts +90 -11
- package/src/app/lib/docs-api/search.ts +115 -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 +89 -9
- package/src/app/lib/registry-api/entity-routes.ts +17 -7
- package/src/app/lib/registry-api/errors.ts +10 -4
- package/src/app/lib/registry-api/handler.ts +13 -15
- 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 +44 -12
- package/src/app/lib/registry-api/transfer-batch.ts +116 -0
- package/src/app/lib/registry-api/transfer.ts +62 -35
- package/src/app/lib/registry-api/validation.ts +33 -1
- package/src/app/lib/registry-connection.ts +1 -1
- package/src/app/next.config.mjs +6 -0
- package/src/app/pages/[...slug]/index.tsx +37 -22
- package/src/app/pages/api/account/tokens/index.ts +4 -13
- package/src/app/pages/api/docs/search/pages.json.ts +25 -0
- package/src/app/pages/api/oauth/revoke.ts +14 -7
- 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/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/assets/blobs/have.ts +2 -2
- package/src/app/pages/api/sync/upload.ts +21 -0
- package/src/app/pages/index/index.tsx +14 -0
- package/src/app/pages/index.tsx +30 -5
- package/src/app-builder/build.ts +2 -2
- package/src/app-builder/nav-shell.ts +8 -13
- package/src/app-builder/vercel-output.ts +4 -4
- package/src/cli/make.ts +2 -2
- package/src/cli.ts +31 -7
- 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 +18 -44
- 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 +4 -0
- package/src/commands/login/index.ts +2 -3
- package/src/commands/logout/index.ts +2 -3
- package/src/commands/make/component.ts +2 -3
- package/src/commands/make/page.ts +4 -5
- package/src/commands/make/template.ts +2 -3
- package/src/commands/publish/index.ts +21 -44
- 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 +11 -1
- package/src/commands/utils.ts +80 -11
- package/src/commands/validate/components.ts +2 -3
- package/src/config/index.ts +2 -1
- package/src/config/loader.ts +57 -12
- package/src/config/normalizers/page.ts +4 -4
- package/src/config/runtime.ts +9 -24
- package/src/index.ts +183 -42
- package/src/nav/resolver.ts +3 -1
- package/src/nav/workspace.ts +2 -2
- package/src/registry/auth/access-tokens.ts +29 -5
- package/src/registry/auth/index.ts +7 -1
- package/src/registry/auth/sync-secret.ts +67 -0
- package/src/registry/auth/types.ts +24 -1
- package/src/registry/auth/validation.ts +18 -0
- package/src/registry/checkout/assets.ts +24 -7
- package/src/registry/checkout/index.ts +41 -5
- package/src/registry/checkout/tokens.ts +12 -6
- package/src/registry/connection.ts +53 -5
- package/src/registry/content-kinds.ts +39 -0
- package/src/registry/db/client.ts +22 -2
- package/src/registry/db/schema.ts +9 -7
- package/src/registry/publish/assets.ts +47 -37
- package/src/registry/publish/index.ts +102 -38
- package/src/registry/publish/tokens.ts +35 -26
- package/src/registry/selection.ts +19 -0
- package/src/store/registry.ts +118 -13
- package/src/transformers/preview/types.ts +2 -2
- 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/package.json.tpl +4 -0
- package/config/docs/foundations/logos.md +0 -7
- package/src/app/lib/api/redact.ts +0 -46
package/README.md
CHANGED
|
@@ -7,513 +7,437 @@
|
|
|
7
7
|
<img alt="" src="https://img.shields.io/npm/l/handoff-app?style=for-the-badge&labelColor=000000">
|
|
8
8
|
</a>
|
|
9
9
|
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
* [Running locally](#running-locally)
|
|
25
|
-
* [Building artifacts](#building-artifacts)
|
|
26
|
-
* [Static site (default)](#static-site-default)
|
|
27
|
-
* [Registry app](#registry-app)
|
|
28
|
-
* [Deploying](#deploying)
|
|
29
|
-
* [Publishing and checkout](#publishing-and-checkout)
|
|
30
|
-
* [Configuration](#configuration)
|
|
31
|
-
* [The runtime block](#the-runtime-block)
|
|
32
|
-
* [Environment variables](#environment-variables)
|
|
33
|
-
* [Registry installation and access](#registry-installation-and-access)
|
|
34
|
-
* [Hooks](#hooks)
|
|
35
|
-
* [CLI reference](#cli-reference)
|
|
36
|
-
* [Maintainers](#maintainers)
|
|
37
|
-
* [Contributing](#contributing)
|
|
38
|
-
* [License](#license)
|
|
39
|
-
|
|
40
|
-
## What is Handoff?
|
|
41
|
-
|
|
42
|
-
Handoff is an open source design system runtime that closes the gap between
|
|
43
|
-
design and development. By automating the delivery of your design system, it
|
|
44
|
-
helps eliminate the bottlenecks between the two.
|
|
45
|
-
|
|
46
|
-
It brings a few pieces together:
|
|
47
|
-
|
|
48
|
-
* **Token extraction.** Pull standardized foundations from your design source and
|
|
49
|
-
store them as JSON. Figma is supported out of the box through the Figma REST
|
|
50
|
-
API.
|
|
51
|
-
* **Transformation pipeline.** Produce SCSS and CSS by default, with optional
|
|
52
|
-
Style Dictionary or custom transformer output.
|
|
53
|
-
* **Documentation runtime.** Render live, working previews of your components,
|
|
54
|
-
tokens, and styles, served through a stable docs read API.
|
|
55
|
-
* **Delivery tooling.** Build and ship the deliverables, either as a static site
|
|
56
|
-
or as a deployed, database-backed catalog.
|
|
57
|
-
|
|
58
|
-
Use the global `entries.scss` and `entries.js` files to load a framework or your
|
|
59
|
-
own frontend code into previews. For example, a Bootstrap project can import
|
|
60
|
-
[Bootstrap 5](https://getbootstrap.com/) from its Sass and JavaScript entries.
|
|
61
|
-
|
|
62
|
-
You install `handoff-app` as a project-local dependency and run its commands in
|
|
63
|
-
your project's context, so every project pins its own toolchain version.
|
|
64
|
-
|
|
65
|
-
## How it works
|
|
66
|
-
|
|
67
|
-
Handoff has two runtime modes. Mode is resolved solely from `runtime.mode` in
|
|
68
|
-
your config and defaults to `workspace`. It is never inferred from environment
|
|
69
|
-
variables or token presence, so setting `DATABASE_URL` can never silently flip
|
|
70
|
-
your app into another mode. The app chrome shows a `Workspace` or `Registry`
|
|
71
|
-
badge so the active mode is always clear.
|
|
72
|
-
|
|
73
|
-
* **Workspace mode (default).** Your local filesystem is the source of truth.
|
|
74
|
-
You author components, patterns, and tokens locally, preview them with a dev
|
|
75
|
-
server, and build a static documentation snapshot. Local authoring stays fast
|
|
76
|
-
and self-contained, with no database or registry required.
|
|
77
|
-
* **Registry mode.** A deployed, dynamic Next.js app backed by PostgreSQL serves
|
|
78
|
-
a shared catalog from published records and packaged default pages. The
|
|
79
|
-
registry never compiles or materializes workspace source.
|
|
80
|
-
|
|
81
|
-
A **connected workspace** is workspace mode plus a registry connection. It still
|
|
82
|
-
renders only local files and still reads as `Workspace`, but it can publish and
|
|
83
|
-
check out components, patterns, pages, token sets, and asset collections.
|
|
84
|
-
|
|
85
|
-
Under the hood, documentation in every mode is consumed through one stable docs
|
|
86
|
-
read API and one canonical artifact URL scheme (`/api/docs/artifacts/{path}`),
|
|
87
|
-
so the same UI serves workspace, static, and registry backings without knowing
|
|
88
|
-
which store is behind it.
|
|
10
|
+
Design tokens, components, and patterns are turned by Handoff into working
|
|
11
|
+
documentation and distributable artifacts. A local workspace, a static site,
|
|
12
|
+
or a shared PostgreSQL-backed registry can be used.
|
|
13
|
+
|
|
14
|
+
## Runtime modes
|
|
15
|
+
|
|
16
|
+
- **Workspace** is the default. Local files are the source of truth and no
|
|
17
|
+
database is required.
|
|
18
|
+
- **Registry** is a deployed catalog backed by PostgreSQL.
|
|
19
|
+
- A **connected workspace** remains in workspace mode but can publish to and
|
|
20
|
+
check out from a registry.
|
|
21
|
+
|
|
22
|
+
Workspace mode is used by local projects for authoring. A separate
|
|
23
|
+
registry-mode application is created automatically by a registry build.
|
|
89
24
|
|
|
90
25
|
## Requirements
|
|
91
26
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
27
|
+
- Node.js 18.18 or newer; Node.js 20 LTS or newer is recommended
|
|
28
|
+
- npm 8 or newer
|
|
29
|
+
- A paid Figma account when fetching a Figma library
|
|
30
|
+
- PostgreSQL when running a registry
|
|
96
31
|
|
|
97
32
|
## Quick start
|
|
98
33
|
|
|
99
|
-
|
|
34
|
+
A project is created with the interactive wizard:
|
|
100
35
|
|
|
101
36
|
```bash
|
|
102
37
|
npx handoff-app init
|
|
38
|
+
cd my-handoff-project
|
|
103
39
|
```
|
|
104
40
|
|
|
105
|
-
The
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
the project
|
|
41
|
+
The project name, sample content, JavaScript or TypeScript, optional Vercel
|
|
42
|
+
setup, and optional Figma credentials are requested by the wizard. Starter
|
|
43
|
+
files are created and `handoff-app` is installed locally. Generated npm scripts
|
|
44
|
+
are used for project operations so the pinned project version is shared by
|
|
45
|
+
local development and CI:
|
|
109
46
|
|
|
110
47
|
```bash
|
|
111
|
-
|
|
112
|
-
npm run
|
|
113
|
-
npm run
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
```json
|
|
119
|
-
{
|
|
120
|
-
"scripts": {
|
|
121
|
-
"start": "handoff-app start",
|
|
122
|
-
"dev": "handoff-app dev",
|
|
123
|
-
"fetch": "handoff-app fetch",
|
|
124
|
-
"build": "handoff-app build",
|
|
125
|
-
"db:migrate": "handoff-app db:migrate"
|
|
126
|
-
}
|
|
127
|
-
}
|
|
48
|
+
npm run fetch # optional: fetch Figma foundations
|
|
49
|
+
npm run start # local server with Handoff file watchers
|
|
50
|
+
npm run dev # local development server without Handoff file watchers
|
|
51
|
+
npm run build # static build by default
|
|
52
|
+
npm run db:migrate # registry database migrations
|
|
53
|
+
npm run validate
|
|
128
54
|
```
|
|
129
55
|
|
|
130
|
-
Any other command can be run with `npx handoff-app <command>` or added as a
|
|
131
|
-
script of your own.
|
|
132
|
-
|
|
133
56
|
## Project layout
|
|
134
57
|
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
```
|
|
58
|
+
```text
|
|
138
59
|
my-handoff-project/
|
|
139
|
-
├─ handoff.config.ts
|
|
140
|
-
├─ .env
|
|
60
|
+
├─ handoff.config.ts
|
|
61
|
+
├─ .env
|
|
141
62
|
├─ components/
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
│ └─ hero/
|
|
147
|
-
│ └─ hero.handoff.ts
|
|
148
|
-
├─ pages/ # custom Markdown documentation and navigation
|
|
149
|
-
│ └─ guides/
|
|
150
|
-
│ └─ getting-started.md
|
|
151
|
-
├─ sass/ # optional global SCSS entry
|
|
152
|
-
├─ js/ # optional global JS entry
|
|
153
|
-
├─ public/ # optional static assets
|
|
154
|
-
├─ exported/ # fetched tokens and assets; commit this directory
|
|
155
|
-
└─ out/ # build output (gitignored)
|
|
63
|
+
├─ patterns/
|
|
64
|
+
├─ pages/
|
|
65
|
+
├─ exported/ # fetched tokens and assets; commit this directory
|
|
66
|
+
└─ out/ # build output; gitignored
|
|
156
67
|
```
|
|
157
68
|
|
|
158
|
-
|
|
159
|
-
React, Handlebars, and CSF components, composed patterns, nested Markdown pages,
|
|
160
|
-
and fetched files under `exported/<projectId>`.
|
|
69
|
+
## Components and patterns
|
|
161
70
|
|
|
162
|
-
|
|
71
|
+
An implementation and a `*.handoff.ts` declaration are required for a
|
|
72
|
+
TypeScript React component. Stable identity, documentation metadata, source
|
|
73
|
+
entries, and previews are supplied by the declaration.
|
|
163
74
|
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
75
|
+
```tsx
|
|
76
|
+
// components/example/Component.tsx
|
|
77
|
+
export type ComponentProps = {
|
|
78
|
+
label: string;
|
|
79
|
+
};
|
|
168
80
|
|
|
169
|
-
|
|
81
|
+
export default function Component({ label }: ComponentProps) {
|
|
82
|
+
return <div>{label}</div>;
|
|
83
|
+
}
|
|
84
|
+
```
|
|
170
85
|
|
|
171
86
|
```ts
|
|
87
|
+
// components/example/component.handoff.ts
|
|
172
88
|
import { defineReactComponent } from 'handoff-app';
|
|
173
|
-
import
|
|
89
|
+
import Component from './Component';
|
|
174
90
|
|
|
175
|
-
export default defineReactComponent(
|
|
176
|
-
id: '
|
|
177
|
-
name: '
|
|
178
|
-
description: '
|
|
179
|
-
group: '
|
|
91
|
+
export default defineReactComponent(Component, {
|
|
92
|
+
id: 'component-id',
|
|
93
|
+
name: 'Component name',
|
|
94
|
+
description: 'Usage guidance for the component.',
|
|
95
|
+
group: 'Group name',
|
|
180
96
|
entries: {
|
|
181
|
-
component: './
|
|
97
|
+
component: './Component.tsx',
|
|
182
98
|
},
|
|
183
99
|
previews: {
|
|
184
|
-
|
|
185
|
-
title: '
|
|
186
|
-
args: {
|
|
100
|
+
default: {
|
|
101
|
+
title: 'Default',
|
|
102
|
+
args: { label: 'Example' },
|
|
187
103
|
},
|
|
188
104
|
},
|
|
189
105
|
});
|
|
190
106
|
```
|
|
191
107
|
|
|
192
|
-
|
|
108
|
+
Components are referenced by stable ID in patterns. A named preview can be
|
|
109
|
+
selected and its arguments can be overridden by each reference. Additional
|
|
110
|
+
references can be added as required by the composition.
|
|
193
111
|
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
112
|
+
```ts
|
|
113
|
+
// patterns/example/pattern.handoff.ts
|
|
114
|
+
import { definePattern } from 'handoff-app';
|
|
115
|
+
|
|
116
|
+
export default definePattern({
|
|
117
|
+
id: 'pattern-id',
|
|
118
|
+
name: 'Pattern name',
|
|
119
|
+
description: 'Purpose and usage of the composition.',
|
|
120
|
+
group: 'Group name',
|
|
121
|
+
components: [
|
|
122
|
+
{
|
|
123
|
+
id: 'component-id',
|
|
124
|
+
preview: 'default',
|
|
125
|
+
args: { label: 'Pattern example' },
|
|
126
|
+
},
|
|
127
|
+
],
|
|
128
|
+
});
|
|
129
|
+
```
|
|
199
130
|
|
|
200
|
-
|
|
201
|
-
directory name). The display `name`/`title` is independent of the `id`, so you
|
|
202
|
-
can rename freely without breaking references. Identity is matched by `id`
|
|
203
|
-
during publish and checkout.
|
|
131
|
+
Component and pattern directories are registered in the project config:
|
|
204
132
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
registry ID, so `pages/guides/getting-started.md` is served and transferred as
|
|
209
|
-
`guides/getting-started`.
|
|
133
|
+
```ts
|
|
134
|
+
// handoff.config.ts
|
|
135
|
+
import { defineConfig } from 'handoff-app';
|
|
210
136
|
|
|
211
|
-
|
|
137
|
+
export default defineConfig({
|
|
138
|
+
entries: {
|
|
139
|
+
components: ['components/example'],
|
|
140
|
+
patterns: ['patterns'],
|
|
141
|
+
},
|
|
142
|
+
runtime: {
|
|
143
|
+
workspace: {
|
|
144
|
+
declarationFormat: 'ts',
|
|
145
|
+
},
|
|
146
|
+
},
|
|
147
|
+
});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
Custom documentation pages are Markdown files under `pages/`. Their relative
|
|
151
|
+
paths become their routes and registry IDs.
|
|
152
|
+
|
|
153
|
+
## Figma foundations
|
|
212
154
|
|
|
213
|
-
|
|
214
|
-
`.env
|
|
155
|
+
Figma integration is optional. When Figma credentials are entered during
|
|
156
|
+
`init`, they are written to `.env` by the wizard and the fetch command can be
|
|
157
|
+
run directly.
|
|
158
|
+
|
|
159
|
+
When that step is skipped or the Figma source must be changed, these values can
|
|
160
|
+
be added or updated in `.env`:
|
|
215
161
|
|
|
216
162
|
```bash
|
|
217
|
-
HANDOFF_FIGMA_PROJECT_ID=
|
|
218
|
-
HANDOFF_DEV_ACCESS_TOKEN=
|
|
163
|
+
HANDOFF_FIGMA_PROJECT_ID=figma-file-id
|
|
164
|
+
HANDOFF_DEV_ACCESS_TOKEN=figma-personal-access-token
|
|
219
165
|
```
|
|
220
166
|
|
|
221
|
-
|
|
167
|
+
The `file_content:read` and `library_content:read` scopes must be granted to the
|
|
168
|
+
personal access token. The configured library is fetched with:
|
|
222
169
|
|
|
223
170
|
```bash
|
|
224
171
|
npm run fetch
|
|
225
172
|
```
|
|
226
173
|
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
this directory in version control so local and CI builds use the same source
|
|
230
|
-
data.
|
|
174
|
+
After design changes, the Figma library should be republished and the command
|
|
175
|
+
should be run again so the latest foundations are pulled.
|
|
231
176
|
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
177
|
+
Generated tokens, CSS, Sass, and available assets are written below
|
|
178
|
+
`exported/<projectId>`. The `exported/` directory should be committed so the
|
|
179
|
+
same inputs are used by local and CI builds. A successful fetch can be verified
|
|
180
|
+
by checking for generated token data such as `exported/<projectId>/tokens.json`;
|
|
181
|
+
an empty foundation route does not prove that the fetch succeeded.
|
|
237
182
|
|
|
238
|
-
##
|
|
183
|
+
## Workspace
|
|
239
184
|
|
|
240
|
-
|
|
185
|
+
Components, patterns, pages, styles, and configuration are authored as local
|
|
186
|
+
workspace files. For day-to-day authoring, the documentation server and file
|
|
187
|
+
watchers are started with:
|
|
241
188
|
|
|
242
189
|
```bash
|
|
243
|
-
|
|
244
|
-
handoff-app start # dev server plus file watchers that rebuild on change
|
|
190
|
+
npm run start
|
|
245
191
|
```
|
|
246
192
|
|
|
247
|
-
|
|
248
|
-
|
|
193
|
+
Changes are rebuilt and reflected in the documentation while the command is
|
|
194
|
+
running. When Handoff file watchers are not required, the development server
|
|
195
|
+
can be started with `npm run dev` instead.
|
|
196
|
+
|
|
197
|
+
The following should be visible at http://localhost:3000:
|
|
249
198
|
|
|
250
|
-
|
|
199
|
+
- the app reports `Workspace` as the active runtime mode;
|
|
200
|
+
- components appear in the component list;
|
|
201
|
+
- component detail pages render every configured preview;
|
|
202
|
+
- patterns render their referenced components; and
|
|
203
|
+
- foundation pages contain the fetched values.
|
|
251
204
|
|
|
252
|
-
|
|
253
|
-
produced. The target, not `NODE_ENV`, drives this. The optional `--package`
|
|
254
|
-
decides *how* that target is packaged for deployment.
|
|
205
|
+
## Build outputs
|
|
255
206
|
|
|
256
|
-
|
|
207
|
+
A static documentation site is built with:
|
|
257
208
|
|
|
258
209
|
```bash
|
|
259
|
-
|
|
260
|
-
handoff-app build --target static # explicit, identical output
|
|
210
|
+
npm run build
|
|
261
211
|
```
|
|
262
212
|
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
static files, and exports to `out/<projectId>` (respecting
|
|
266
|
-
`sitesOutputDirectory`). The output renders list, detail, preview, and inspect
|
|
267
|
-
pages with no live server, so any static file server or CDN can serve it without
|
|
268
|
-
host-specific rewrites.
|
|
269
|
-
|
|
270
|
-
The build fails clearly if a required artifact referenced by generated HTML
|
|
271
|
-
cannot be materialized, and it fails if the runtime is registry-only (there is
|
|
272
|
-
no local workspace to export).
|
|
213
|
+
Static output is written below `out/<projectId>` and can be served by any
|
|
214
|
+
static file server or CDN.
|
|
273
215
|
|
|
274
|
-
|
|
216
|
+
A standalone registry application is built with:
|
|
275
217
|
|
|
276
218
|
```bash
|
|
277
|
-
|
|
219
|
+
npm run build -- --target registry
|
|
278
220
|
```
|
|
279
221
|
|
|
280
|
-
The
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
registry API from the database and published artifacts.
|
|
222
|
+
The generated application is automatically configured for registry mode by the
|
|
223
|
+
command. The database-backed Next.js bundle is written to `out/registry`, and
|
|
224
|
+
workspace source is not compiled or served. A Vercel Build Output bundle can be
|
|
225
|
+
produced for either target by adding `--package vercel`.
|
|
285
226
|
|
|
286
|
-
|
|
287
|
-
database connection, a session secret of at least 32 characters, and the public
|
|
288
|
-
registry URL at deploy time:
|
|
227
|
+
## Registry setup
|
|
289
228
|
|
|
290
|
-
|
|
291
|
-
DATABASE_URL="postgres://..." \
|
|
292
|
-
AUTH_SECRET="replace-with-a-long-random-value" \
|
|
293
|
-
AUTH_URL="https://registry.example.com" \
|
|
294
|
-
node out/registry/server.js
|
|
295
|
-
```
|
|
229
|
+
### 1. Database migrations
|
|
296
230
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
step (e.g. in CI/CD) before deploying:
|
|
231
|
+
Migrations are run from the source workspace or CI checkout, where the project
|
|
232
|
+
dependency and configuration are available:
|
|
300
233
|
|
|
301
234
|
```bash
|
|
302
|
-
handoff
|
|
235
|
+
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/handoff?schema=public" \
|
|
236
|
+
npm run db:migrate
|
|
303
237
|
```
|
|
304
238
|
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
the supported database; `runtime.registry.database.driver` selects the
|
|
308
|
-
connection driver (`pg` or `neon`), not the database engine. Both drivers ship
|
|
309
|
-
with the package.
|
|
239
|
+
Migrations are a controlled release step and are separate from the build,
|
|
240
|
+
server startup, and browser installer.
|
|
310
241
|
|
|
311
|
-
|
|
312
|
-
blob. Larger deployments can use the built-in Vercel Blob adapter or a custom
|
|
313
|
-
storage adapter through `runtime.registry.assetStorage`.
|
|
242
|
+
### 2. Registry runtime
|
|
314
243
|
|
|
315
|
-
|
|
244
|
+
The generated registry bundle uses these environment variables:
|
|
316
245
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
246
|
+
```dotenv
|
|
247
|
+
PORT=4000
|
|
248
|
+
HOSTNAME=0.0.0.0
|
|
249
|
+
DATABASE_URL="postgresql://postgres:postgres@localhost:5432/handoff?schema=public"
|
|
250
|
+
AUTH_SECRET="replace-with-at-least-32-random-characters"
|
|
251
|
+
AUTH_URL="http://localhost:4000"
|
|
252
|
+
```
|
|
323
253
|
|
|
324
|
-
|
|
325
|
-
|
|
254
|
+
`DATABASE_URL`, `AUTH_SECRET`, and `AUTH_URL` are required. The standalone
|
|
255
|
+
server also reads `PORT` and `HOSTNAME`. The generated entrypoint is
|
|
256
|
+
`out/registry/server.js`; how it is started and hosted depends on the deployment
|
|
257
|
+
environment.
|
|
326
258
|
|
|
327
|
-
|
|
328
|
-
| --- | --- |
|
|
329
|
-
| omitted (default) | `out/<projectId>` (static) or the `out/registry` Node bundle (registry) |
|
|
330
|
-
| `vercel` | `.vercel/output`, a Vercel Build Output API bundle |
|
|
259
|
+
### Vercel and Neon
|
|
331
260
|
|
|
332
|
-
|
|
333
|
-
|
|
261
|
+
Vercel packaging and the Neon PostgreSQL driver are supported independently.
|
|
262
|
+
Either integration can be used without the other.
|
|
334
263
|
|
|
335
|
-
|
|
264
|
+
#### Vercel packaging
|
|
336
265
|
|
|
337
|
-
|
|
266
|
+
A registry bundle that follows the Vercel Build Output API is produced with:
|
|
338
267
|
|
|
339
268
|
```bash
|
|
340
|
-
|
|
269
|
+
npm run build -- --target registry --package vercel
|
|
341
270
|
```
|
|
342
271
|
|
|
343
|
-
The
|
|
344
|
-
|
|
345
|
-
|
|
272
|
+
The generated deployment output is written to `.vercel/output`. The registry
|
|
273
|
+
runtime variables listed above are supplied through the deployment environment.
|
|
274
|
+
|
|
275
|
+
#### Neon PostgreSQL
|
|
276
|
+
|
|
277
|
+
The Neon connection driver is selected in `handoff.config.ts`:
|
|
346
278
|
|
|
347
279
|
```ts
|
|
348
280
|
runtime: {
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
281
|
+
registry: {
|
|
282
|
+
databaseUrlEnv: 'DATABASE_URL',
|
|
283
|
+
database: {
|
|
284
|
+
driver: 'neon',
|
|
285
|
+
},
|
|
286
|
+
},
|
|
287
|
+
},
|
|
288
|
+
```
|
|
289
|
+
|
|
290
|
+
A Neon PostgreSQL connection string is supplied through `DATABASE_URL`. The
|
|
291
|
+
same explicit database migration step is required before deployment.
|
|
292
|
+
|
|
293
|
+
#### Optional Vercel Blob storage
|
|
294
|
+
|
|
295
|
+
Registry assets are stored in PostgreSQL by default. Vercel Blob can be selected
|
|
296
|
+
when external asset storage is required:
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
runtime: {
|
|
300
|
+
registry: {
|
|
301
|
+
assetStorage: {
|
|
302
|
+
adapter: 'vercel-blob',
|
|
303
|
+
},
|
|
353
304
|
},
|
|
354
305
|
},
|
|
355
306
|
```
|
|
356
307
|
|
|
308
|
+
The associated `BLOB_READ_WRITE_TOKEN` is supplied through the deployment
|
|
309
|
+
environment.
|
|
310
|
+
|
|
311
|
+
### 3. Installation
|
|
312
|
+
|
|
313
|
+
The installer is opened at http://localhost:4000/install, where the first
|
|
314
|
+
administrator is created. The deployment is verified by the installer, but
|
|
315
|
+
migrations are never run by it.
|
|
316
|
+
|
|
317
|
+
An uninstalled registry can be claimed by the first visitor. A new deployment
|
|
318
|
+
should not be left unattended before installation is complete.
|
|
319
|
+
|
|
320
|
+
### 4. Workspace authorization
|
|
321
|
+
|
|
322
|
+
CLI authorization is started from the source workspace with:
|
|
323
|
+
|
|
357
324
|
```bash
|
|
358
|
-
|
|
359
|
-
HANDOFF_REGISTRY_ACCESS_TOKEN=your-registry-token
|
|
325
|
+
npm run login -- --url http://localhost:4000
|
|
360
326
|
```
|
|
361
327
|
|
|
362
|
-
|
|
363
|
-
|
|
328
|
+
Registry sign-in, entry of the displayed device code, and CLI approval are
|
|
329
|
+
completed in the browser. The revocable credential is saved in
|
|
330
|
+
`.handoff/cli-auth.json` for that exact registry URL.
|
|
331
|
+
|
|
332
|
+
### 5. Content publishing
|
|
333
|
+
|
|
334
|
+
Every kind in the workspace is published in dependency order with:
|
|
364
335
|
|
|
365
336
|
```bash
|
|
366
|
-
|
|
367
|
-
handoff-app checkout patterns hero # pull a registry entity into this workspace
|
|
368
|
-
handoff-app publish pages # publish every custom Markdown page
|
|
369
|
-
handoff-app checkout tokens foundation/colors
|
|
337
|
+
npm run publish -- all
|
|
370
338
|
```
|
|
371
339
|
|
|
372
|
-
|
|
373
|
-
include normalized metadata, referenced source files, rendered docs artifacts,
|
|
374
|
-
shared preview assets, and build metadata. Pages upload their Markdown source.
|
|
375
|
-
Tokens and assets upload their generated sets or collections. Declaration files
|
|
376
|
-
remain local to the workspace.
|
|
340
|
+
A single kind is published on its own:
|
|
377
341
|
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
342
|
+
```bash
|
|
343
|
+
npm run publish -- components
|
|
344
|
+
npm run publish -- patterns
|
|
345
|
+
npm run publish -- pages
|
|
346
|
+
npm run publish -- tokens
|
|
347
|
+
npm run publish -- assets
|
|
348
|
+
```
|
|
382
349
|
|
|
383
|
-
|
|
350
|
+
Publishing tokens or assets runs the Figma data pipeline before upload, so the
|
|
351
|
+
documented Figma credentials must be available.
|
|
384
352
|
|
|
385
|
-
|
|
386
|
-
in that order. Use `defineConfig` for typed authoring and camelCase aliases.
|
|
387
|
-
Plain object exports remain supported.
|
|
353
|
+
One or more IDs can be appended to narrow a publish to those entities:
|
|
388
354
|
|
|
389
|
-
```
|
|
390
|
-
|
|
355
|
+
```bash
|
|
356
|
+
npm run publish -- components component-id another-id
|
|
357
|
+
```
|
|
391
358
|
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
359
|
+
`--dry-run` reports what would be uploaded and contacts no registry at all, so
|
|
360
|
+
it needs neither a registry URL nor a token. It still runs the build, which
|
|
361
|
+
refreshes generated output on disk; `--no-build` skips the build and publishes
|
|
362
|
+
the existing output, and the two combine to leave the workspace untouched:
|
|
363
|
+
|
|
364
|
+
```bash
|
|
365
|
+
npm run publish -- all --dry-run
|
|
366
|
+
npm run publish -- components --no-build
|
|
400
367
|
```
|
|
401
368
|
|
|
402
|
-
|
|
369
|
+
`checkout` takes the same `all`, multi-ID, and `--dry-run` forms. A dry-run
|
|
370
|
+
checkout reads from the registry, lists the files it would create or overwrite,
|
|
371
|
+
and writes nothing.
|
|
372
|
+
|
|
373
|
+
After the registry is reloaded, the published components, patterns, and
|
|
374
|
+
foundations should be visible. Published database records are read by registry
|
|
375
|
+
pages; the local workspace is never read directly.
|
|
403
376
|
|
|
404
|
-
|
|
405
|
-
optional and deep-merged into the defaults, so a partial block never wipes them.
|
|
377
|
+
For CI, a registry connection and user-issued token are configured:
|
|
406
378
|
|
|
407
379
|
```ts
|
|
408
380
|
runtime: {
|
|
409
|
-
// Sole determinant of runtime mode. Defaults to 'workspace'.
|
|
410
|
-
mode: 'workspace', // 'workspace' | 'registry'
|
|
411
|
-
|
|
412
|
-
workspace: {
|
|
413
|
-
// Format for newly generated / checkout-synthesized declarations.
|
|
414
|
-
declarationFormat: 'ts', // 'ts' | 'js' | 'cjs' | 'json'
|
|
415
|
-
},
|
|
416
|
-
|
|
417
|
-
// Connect a workspace to a remote registry (publish/checkout).
|
|
418
381
|
registryConnection: {
|
|
419
382
|
url: 'https://registry.example.com',
|
|
420
383
|
accessTokenEnv: 'HANDOFF_REGISTRY_ACCESS_TOKEN',
|
|
421
384
|
},
|
|
422
|
-
|
|
423
|
-
// Registry deployment settings (build --target registry, db:migrate).
|
|
424
|
-
registry: {
|
|
425
|
-
databaseUrlEnv: 'DATABASE_URL',
|
|
426
|
-
database: { driver: 'pg' }, // connection driver: 'pg' | 'neon' (PostgreSQL only)
|
|
427
|
-
assetStorage: {
|
|
428
|
-
adapter: 'database', // 'database' | 'vercel-blob' | 'custom'
|
|
429
|
-
maxInlineBytes: 4194304,
|
|
430
|
-
},
|
|
431
|
-
},
|
|
432
385
|
},
|
|
433
386
|
```
|
|
434
387
|
|
|
435
|
-
|
|
436
|
-
|
|
388
|
+
## Configuration
|
|
389
|
+
|
|
390
|
+
Configuration is read from `handoff.config.ts`, `.js`, `.cjs`, or `.json`, in
|
|
391
|
+
that order. `defineConfig` provides typed authoring. A partial `runtime` block
|
|
392
|
+
is deep-merged with defaults.
|
|
437
393
|
|
|
438
|
-
|
|
394
|
+
Useful environment variables:
|
|
439
395
|
|
|
440
396
|
| Variable | Purpose |
|
|
441
397
|
| --- | --- |
|
|
442
398
|
| `HANDOFF_FIGMA_PROJECT_ID` | Figma file ID used by `fetch` |
|
|
443
399
|
| `HANDOFF_DEV_ACCESS_TOKEN` | Figma personal access token used by `fetch` |
|
|
444
|
-
| `HANDOFF_REGISTRY_URL` |
|
|
445
|
-
| `HANDOFF_REGISTRY_ACCESS_TOKEN` | User-issued CI token
|
|
446
|
-
| `
|
|
447
|
-
| `
|
|
448
|
-
| `
|
|
449
|
-
| `
|
|
450
|
-
| `
|
|
451
|
-
| `
|
|
452
|
-
| `
|
|
453
|
-
| `
|
|
454
|
-
| `
|
|
455
|
-
| `
|
|
456
|
-
| `
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
deployment but never changes the schema.
|
|
464
|
-
|
|
465
|
-
The first visitor can claim an uninstalled registry. Do not leave a new
|
|
466
|
-
deployment unattended before installation is complete.
|
|
467
|
-
|
|
468
|
-
Administrators can invite users, manage roles, and deactivate accounts. Members
|
|
469
|
-
receive read access for browsing and checkout, while administrators can also
|
|
470
|
-
publish. If Resend is not configured, the registry shows invitation links once
|
|
471
|
-
for manual delivery.
|
|
472
|
-
|
|
473
|
-
`handoff-app login` stores a revocable credential in
|
|
474
|
-
`.handoff/cli-auth.json` and only uses it for the exact registry URL that issued
|
|
475
|
-
it. For CI, create a scoped token in Account settings and expose it through
|
|
476
|
-
`runtime.registryConnection.accessTokenEnv`. The former
|
|
477
|
-
`HANDOFF_REGISTRY_API_TOKEN` server secret is no longer accepted.
|
|
478
|
-
|
|
479
|
-
### Hooks
|
|
480
|
-
|
|
481
|
-
Pipeline customization is done in your config under `hooks` (camelCase names such
|
|
482
|
-
as `validateComponent`, `jsBuildConfig`, `registerHandlebarsHelpers`). For
|
|
483
|
-
example, `registerHandlebarsHelpers` runs after Handoff registers the built-in
|
|
484
|
-
`field` and `eq` helpers, so you can register your own helpers for `.hbs`
|
|
485
|
-
preview templates.
|
|
486
|
-
|
|
487
|
-
See [docs/api.md](docs/api.md#hooks) for hook arguments and examples.
|
|
400
|
+
| `HANDOFF_REGISTRY_URL` | Connected workspace registry URL |
|
|
401
|
+
| `HANDOFF_REGISTRY_ACCESS_TOKEN` | User-issued CI token |
|
|
402
|
+
| `HANDOFF_SYNC_SECRET` | Optional deployment-wide registry credential |
|
|
403
|
+
| `DATABASE_URL` | Registry PostgreSQL connection string |
|
|
404
|
+
| `AUTH_SECRET` | Registry session-signing secret, at least 32 characters |
|
|
405
|
+
| `AUTH_URL` | Canonical public registry URL |
|
|
406
|
+
| `PORT` | Standalone registry server port |
|
|
407
|
+
| `HOSTNAME` | Standalone registry bind hostname |
|
|
408
|
+
| `BLOB_READ_WRITE_TOKEN` | Credential for the Vercel Blob asset adapter |
|
|
409
|
+
| `HANDOFF_OUTPUT_DIR` | Override the fetched output directory |
|
|
410
|
+
| `HANDOFF_SITES_DIR` | Override the build output directory |
|
|
411
|
+
| `HANDOFF_APP_PORT` | Workspace documentation server port |
|
|
412
|
+
| `HANDOFF_WEBSOCKET_PORT` | Workspace live-reload server port |
|
|
413
|
+
|
|
414
|
+
Registry assets are stored in PostgreSQL by default with a 4 MB per-blob limit.
|
|
415
|
+
Vercel Blob or a custom adapter can be selected through
|
|
416
|
+
`runtime.registry.assetStorage`. The `pg` or `neon` connection driver can be
|
|
417
|
+
selected through `runtime.registry.database.driver`; PostgreSQL is used by
|
|
418
|
+
both.
|
|
488
419
|
|
|
489
420
|
## CLI reference
|
|
490
421
|
|
|
491
422
|
| Command | Description |
|
|
492
423
|
| --- | --- |
|
|
493
|
-
| `init` |
|
|
494
|
-
| `fetch` |
|
|
495
|
-
| `
|
|
496
|
-
| `dev` |
|
|
497
|
-
| `
|
|
498
|
-
| `
|
|
499
|
-
| `
|
|
500
|
-
| `
|
|
501
|
-
| `
|
|
502
|
-
| `
|
|
503
|
-
| `
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
| `eject:pages` | Eject the default documentation pages |
|
|
511
|
-
| `eject:theme` | Eject the default theme |
|
|
512
|
-
| `validate:components` | Run component validation |
|
|
513
|
-
|
|
514
|
-
Global flags: `-c, --config <file>`, `-d, --debug`, `-f, --force`,
|
|
515
|
-
`-h, --help`, `-v, --version`. Run `handoff-app <command> --help` for the exact
|
|
516
|
-
options in your installed version.
|
|
424
|
+
| `npx handoff-app init` | A workspace is scaffolded with the interactive wizard |
|
|
425
|
+
| `npm run fetch` | Design tokens and assets are fetched from Figma |
|
|
426
|
+
| `npm run start` | The workspace server and Handoff file watchers are started |
|
|
427
|
+
| `npm run dev` | The workspace development server is started |
|
|
428
|
+
| `npm run build -- [--target static\|registry]` | The static site or standalone registry bundle is built |
|
|
429
|
+
| `npm run db:migrate` | Registry database migrations are applied |
|
|
430
|
+
| `npm run validate` | Configured components are validated |
|
|
431
|
+
| `npm run publish -- <kind\|all> [id...]` | Components, patterns, pages, tokens, or assets are published |
|
|
432
|
+
| `npm run checkout -- <kind\|all> [id...]` | Published content is pulled into a workspace |
|
|
433
|
+
| `npm run login -- --url <url>` | The CLI is authorized through the registry device flow |
|
|
434
|
+
| `npm run logout -- [--url <url>]` | A saved CLI credential is revoked and removed |
|
|
435
|
+
|
|
436
|
+
`publish` and `checkout` additionally accept `--dry-run`, and `publish` accepts `--no-build`.
|
|
437
|
+
|
|
438
|
+
Arguments after `--` are forwarded to the local CLI. Exact options can be shown
|
|
439
|
+
by adding `--help` after the separator. Advanced configuration and hooks are
|
|
440
|
+
documented in [docs/api.md](docs/api.md).
|
|
517
441
|
|
|
518
442
|
## Maintainers
|
|
519
443
|
|
|
@@ -525,8 +449,8 @@ options in your installed version.
|
|
|
525
449
|
|
|
526
450
|
## Contributing
|
|
527
451
|
|
|
528
|
-
|
|
529
|
-
|
|
452
|
+
[Issues](https://github.com/Convertiv/handoff-app/issues/new) and pull requests
|
|
453
|
+
are welcome.
|
|
530
454
|
|
|
531
455
|
Handoff follows the [Contributor Covenant](http://contributor-covenant.org/version/1/3/0/)
|
|
532
456
|
Code of Conduct.
|