handoff-app 2.0.0-12 → 2.0.0-13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/{Changelog.md → CHANGELOG.md} +84 -0
- package/{License.md → LICENSE.md} +1 -1
- package/README.md +760 -801
- package/RECIPES.md +975 -0
- package/components.json +20 -20
- package/config/docs/foundations/colors/guidelines.md +0 -1
- package/config/docs/foundations/colors.md +0 -1
- package/config/docs/foundations/effects/guidelines.md +0 -1
- package/config/docs/foundations/effects/resources.md +0 -1
- package/config/docs/foundations/effects.md +0 -1
- package/config/docs/foundations/fonts.md +0 -1
- package/config/docs/foundations/grid.md +0 -1
- package/config/docs/foundations/icon.md +0 -1
- package/config/docs/foundations/icons/guidelines.md +0 -1
- package/config/docs/foundations/icons.md +0 -1
- package/config/docs/foundations/images/guidelines.md +0 -1
- package/config/docs/foundations/images/resources.md +0 -1
- package/config/docs/foundations/images.md +0 -1
- package/config/docs/foundations/logo/resources.md +0 -1
- package/config/docs/foundations/logo.md +0 -1
- package/config/docs/foundations/typography/guidelines.md +0 -1
- package/config/docs/foundations/typography/resources.md +0 -1
- package/config/docs/foundations/typography.md +0 -1
- package/config/docs/foundations.md +0 -1
- package/config/docs/guidelines.md +0 -1
- package/config/docs/index.md +0 -1
- package/config/docs/system/tokens/foundations/colors.md +0 -4
- package/config/docs/system/tokens/foundations/effects.md +0 -4
- package/config/docs/system/tokens/foundations/typography.md +0 -2
- package/config/docs/system.md +0 -2
- package/config/templates/page.md +2 -1
- package/config/templates/page.mdx +2 -1
- package/dist/ai/define.d.ts +1 -1
- package/dist/ai/define.js +1 -1
- package/dist/ai/types.d.ts +1 -1
- package/dist/ai/types.js +1 -1
- package/dist/app-builder/build.js +14 -14
- package/dist/app-builder/client-config.js +1 -1
- package/dist/config/loader.js +1 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/nav/index.d.ts +2 -2
- package/dist/nav/registry.d.ts +3 -3
- package/dist/nav/registry.js +1 -1
- package/dist/nav/workspace.d.ts +3 -3
- package/dist/nav/workspace.js +1 -1
- package/dist/providers.d.ts +10 -0
- package/dist/{define.js → providers.js} +4 -4
- package/dist/registry/asset-storage/define.d.ts +5 -5
- package/dist/registry/asset-storage/define.js +4 -4
- package/dist/registry/asset-storage/resolve.d.ts +8 -11
- package/dist/registry/asset-storage/resolve.js +12 -13
- package/dist/registry/asset-storage/types.d.ts +12 -12
- package/dist/registry/asset-storage/types.js +2 -2
- package/dist/registry/db/schema.d.ts +2 -2
- package/dist/registry/db/schema.js +2 -2
- package/dist/registry/email/define.d.ts +1 -1
- package/dist/registry/email/define.js +1 -1
- package/dist/registry/email/resolve.d.ts +7 -8
- package/dist/registry/email/resolve.js +21 -23
- package/dist/registry/email/types.d.ts +1 -1
- package/dist/registry/email/types.js +1 -1
- package/dist/store/registry.d.ts +3 -3
- package/dist/store/registry.js +4 -4
- package/dist/types/config.d.ts +4 -13
- package/docs/cli.md +275 -54
- package/package.json +7 -7
- package/src/ai/define.ts +1 -1
- package/src/ai/types.ts +1 -1
- package/src/app/components/Auth/AccountLayout.tsx +1 -1
- package/src/app/components/Auth/AuthShell.tsx +10 -4
- package/src/app/components/Foundations/ColorGrid.tsx +13 -14
- package/src/app/components/Layout/Main.tsx +2 -2
- package/src/app/components/McpIntegration/McpConfigDialog.tsx +12 -51
- package/src/app/components/Navigation/MobileNav.tsx +0 -2
- package/src/app/components/util/index.ts +0 -11
- package/src/app/lib/asset-storage.ts +25 -25
- package/src/app/lib/auth/email.ts +4 -5
- package/src/app/lib/docs-api/page-rendering.ts +1 -1
- package/src/app/lib/docs-api/registry.ts +2 -3
- package/src/app/lib/docs-api/runtime-config.ts +8 -8
- package/src/app/lib/registry-api/asset-transfer.ts +25 -25
- package/src/app/lib/server-module.ts +1 -1
- package/src/app/lib/utils.ts +7 -0
- package/src/app/next.config.mjs +2 -2
- package/src/app/pages/[...slug]/index.tsx +2 -1
- package/src/app/pages/account/ai.tsx +1 -1
- package/src/app/pages/account/index.tsx +1 -1
- package/src/app/pages/account/tokens.tsx +1 -1
- package/src/app/pages/account/users.tsx +1 -1
- package/src/app/pages/api/docs/nav.json.ts +1 -1
- package/src/app/pages/api/mcp.ts +6 -0
- package/src/app/pages/api/registry/transfer/assets/blobs/[hash].ts +1 -1
- package/src/app/pages/cli/device.tsx +1 -1
- package/src/app/pages/foundations/colors.tsx +9 -8
- package/src/app/pages/foundations/index.tsx +3 -3
- package/src/app/pages/index.tsx +2 -2
- package/src/app/pages/login.tsx +10 -5
- package/src/app/pages/reset-password.tsx +7 -2
- package/src/app/pages/system/component/[component]/index.tsx +2 -5
- package/src/app/pages/system/index.tsx +11 -11
- package/src/app/pages/system/pattern/[pattern]/index.tsx +2 -2
- package/src/app/pages/system/tokens/components/[component]/index.tsx +0 -4
- package/src/app-builder/build.ts +10 -10
- package/src/app-builder/client-config.ts +1 -1
- package/src/config/loader.ts +1 -2
- package/src/index.ts +6 -6
- package/src/nav/index.ts +2 -2
- package/src/nav/registry.ts +3 -3
- package/src/nav/workspace.ts +3 -3
- package/src/{define.ts → providers.ts} +8 -8
- package/src/registry/asset-storage/define.ts +6 -6
- package/src/registry/asset-storage/resolve.ts +16 -20
- package/src/registry/asset-storage/types.ts +12 -12
- package/src/registry/db/schema.ts +3 -3
- package/src/registry/email/define.ts +1 -1
- package/src/registry/email/resolve.ts +23 -23
- package/src/registry/email/types.ts +1 -1
- package/src/store/registry.ts +7 -7
- package/src/types/config.ts +4 -14
- package/.editorconfig +0 -19
- package/.eslintrc.json +0 -4
- package/.prettierignore +0 -0
- package/.prettierrc.json +0 -8
- package/.vscode/settings.json +0 -17
- package/dist/define.d.ts +0 -10
- package/dist/registry/email/adapters/resend.d.ts +0 -7
- package/dist/registry/email/adapters/resend.js +0 -35
- package/src/app/components/old/Header.tsx +0 -89
- package/src/app/pages/assets/fonts.tsx +0 -129
- package/src/app/pages/assets/index.tsx +0 -91
- package/src/app/pages/assets/logos.tsx +0 -75
- package/src/registry/email/adapters/resend.ts +0 -22
- /package/dist/registry/email/{adapters → providers}/smtp.d.ts +0 -0
- /package/dist/registry/email/{adapters → providers}/smtp.js +0 -0
- /package/src/registry/email/{adapters → providers}/smtp.ts +0 -0
package/docs/cli.md
CHANGED
|
@@ -1,78 +1,299 @@
|
|
|
1
1
|
# Handoff CLI
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The `handoff-app` CLI fetches Figma foundations, builds and serves the
|
|
4
|
+
documentation, and transfers content between a workspace and a registry. The
|
|
5
|
+
[README](../README.md) explains the concepts and the configuration. This page
|
|
6
|
+
lists every command and option.
|
|
6
7
|
|
|
7
|
-
##
|
|
8
|
-
The CLI will allow you to fetch all data from Figma, build the documentation
|
|
9
|
-
app and run a local dev site. For these use the build, fetch, and serve commands
|
|
10
|
-
documented below.
|
|
8
|
+
## Run the CLI
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
but the various kinds of configurations can be tailored or extended.
|
|
10
|
+
`init` installs `handoff-app` in the project and adds npm scripts for the
|
|
11
|
+
common commands. Use the npm scripts, so that local development and CI use the
|
|
12
|
+
project version:
|
|
16
13
|
|
|
17
|
-
|
|
14
|
+
```bash
|
|
15
|
+
npm run build -- --target registry
|
|
16
|
+
```
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
app
|
|
22
|
-
`exportables` - JSON schemas for each component in your figma file that you
|
|
23
|
-
want to pull into handoff.
|
|
24
|
-
`integration` - scss mappings and html templates for making it easy to map
|
|
25
|
-
handoff tokens to your frontend framework.
|
|
18
|
+
npm forwards the arguments after `--` to the CLI. For a command without an npm
|
|
19
|
+
script, use `npx`:
|
|
26
20
|
|
|
27
|
-
|
|
21
|
+
```bash
|
|
22
|
+
npx handoff-app validate:components
|
|
23
|
+
```
|
|
28
24
|
|
|
29
|
-
|
|
30
|
-
the current working directory. If you customize these configurations, then run
|
|
31
|
-
handoff commands in that directory, these configs will be executed. `eject:config` now prompts for TypeScript or JavaScript config format.
|
|
32
|
-
__Make__ commands will generate a boilerplate configuration in the current
|
|
33
|
-
working directory. This is useful for extending handoff for different components
|
|
34
|
-
or integrations.
|
|
25
|
+
Show the help of the CLI or of one command:
|
|
35
26
|
|
|
36
|
-
|
|
37
|
-
|
|
27
|
+
```bash
|
|
28
|
+
npx handoff-app --help
|
|
29
|
+
npx handoff-app publish --help
|
|
30
|
+
```
|
|
38
31
|
|
|
39
|
-
|
|
32
|
+
Each command runs against the working directory. The working directory is the
|
|
33
|
+
directory that holds `handoff.config.ts`. It is the current directory, or the
|
|
34
|
+
directory that `HANDOFF_WORKING_PATH` sets.
|
|
40
35
|
|
|
41
|
-
|
|
36
|
+
## Shared options
|
|
42
37
|
|
|
43
|
-
|
|
38
|
+
Every command except `init` accepts these options:
|
|
39
|
+
|
|
40
|
+
| Option | Description |
|
|
41
|
+
| --- | --- |
|
|
42
|
+
| `-c, --config <file>` | Load this config file, relative to the working directory, instead of `handoff.config.*` |
|
|
43
|
+
| `--profile <name>` | Merge `handoff.config.<name>.*` onto the base config, and use the registry login of this profile. Has priority over `HANDOFF_PROFILE`. |
|
|
44
|
+
| `-d, --debug` | Show debug logs |
|
|
45
|
+
| `-f, --force` | Force the action. The effect depends on the command. |
|
|
46
|
+
| `--help` | Show the help of the command |
|
|
47
|
+
|
|
48
|
+
`handoff-app --version` shows the CLI version.
|
|
49
|
+
|
|
50
|
+
`HANDOFF_LOG_LEVEL` (`debug`, `info`, `warn`, `error`, or `silent`) and
|
|
51
|
+
`HANDOFF_LOG_SCOPES` (`handoff`, `vite`, `next`) control the log output of
|
|
52
|
+
every command. The README lists all
|
|
53
|
+
[environment variables](../README.md#environment-variables).
|
|
54
|
+
|
|
55
|
+
## Project
|
|
56
|
+
|
|
57
|
+
### init
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
npx handoff-app init
|
|
61
|
+
```
|
|
62
|
+
|
|
63
|
+
Creates a project with an interactive wizard. The wizard asks for the project
|
|
64
|
+
name, sample content, JavaScript or TypeScript, an optional Vercel setup, and
|
|
65
|
+
optional Figma credentials. It installs `handoff-app` and adds these npm
|
|
66
|
+
scripts: `start`, `dev`, `fetch`, `build`, `login`, `logout`, `publish`,
|
|
67
|
+
`checkout`, and `db:migrate`.
|
|
68
|
+
|
|
69
|
+
### fetch
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
handoff-app fetch
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
Fetches tokens and assets from the Figma file and writes them to `exported/`.
|
|
76
|
+
It reads `HANDOFF_FIGMA_PROJECT_ID` and `HANDOFF_DEV_ACCESS_TOKEN`. If a value
|
|
77
|
+
is empty, `fetch` asks for it in the terminal. Without a terminal, `fetch`
|
|
78
|
+
stops with an error that names the missing variable.
|
|
79
|
+
|
|
80
|
+
### start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
handoff-app start
|
|
84
|
+
```
|
|
85
|
+
|
|
86
|
+
Starts the workspace documentation server and the Handoff file watchers. While
|
|
87
|
+
the command runs, Handoff rebuilds changed files and updates the
|
|
88
|
+
documentation.
|
|
89
|
+
|
|
90
|
+
### dev
|
|
91
|
+
|
|
92
|
+
```bash
|
|
93
|
+
handoff-app dev
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
Starts the workspace documentation server without the Handoff file watchers.
|
|
97
|
+
|
|
98
|
+
### build
|
|
99
|
+
|
|
100
|
+
```bash
|
|
101
|
+
handoff-app build [--target static|registry] [--package standalone|vercel] [--skip-components]
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
Builds the documentation.
|
|
105
|
+
|
|
106
|
+
| Option | Description |
|
|
107
|
+
| --- | --- |
|
|
108
|
+
| `--target static` | Default. Builds a static site in `out/static`. |
|
|
109
|
+
| `--target registry` | Builds a standalone registry server in `out/registry`. The application is always in registry mode. |
|
|
110
|
+
| `--package vercel` | Writes a Vercel Build Output bundle to `.vercel/output` for the selected target |
|
|
111
|
+
| `--package standalone` | Writes the default output of the target |
|
|
112
|
+
| `--skip-components` | Builds the application without a component build first |
|
|
113
|
+
| `-f, --force` | Builds every component again, and ignores the build cache |
|
|
114
|
+
|
|
115
|
+
`--package` never changes the target.
|
|
116
|
+
|
|
117
|
+
### build:app
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
handoff-app build:app [--skip-components]
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
Builds the static site. It is the same as `build --target static`.
|
|
124
|
+
|
|
125
|
+
### build:components
|
|
126
|
+
|
|
127
|
+
```bash
|
|
128
|
+
handoff-app build:components [component]
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Builds the catalog items without the documentation application. A name builds
|
|
132
|
+
only that item.
|
|
133
|
+
|
|
134
|
+
### validate:components
|
|
135
|
+
|
|
136
|
+
```bash
|
|
137
|
+
handoff-app validate:components [--skip-build]
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
Validates the catalog items. `--skip-build` validates the existing build
|
|
141
|
+
output without a build first.
|
|
142
|
+
|
|
143
|
+
## Content
|
|
144
|
+
|
|
145
|
+
### make:component
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
handoff-app make:component <name>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Creates a Handlebars catalog item: a template, a CommonJS declaration, and,
|
|
152
|
+
if you select them, a JavaScript file and a Sass file. The item goes into the
|
|
153
|
+
first directory in `catalog.include`, or into `components/`. If that directory
|
|
154
|
+
is not registered, Handoff adds it to `catalog.include`. The name can contain
|
|
155
|
+
letters, numbers, hyphens, and underscores. `--force` overwrites an existing
|
|
156
|
+
template.
|
|
157
|
+
|
|
158
|
+
### make:page
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
handoff-app make:page <name> [parent]
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Creates a Markdown page in `pages/`, or in `pages/<parent>/`. If a default page
|
|
165
|
+
has the same name, the new page starts with its content. `--force` overwrites
|
|
166
|
+
an existing page.
|
|
167
|
+
|
|
168
|
+
### scaffold
|
|
169
|
+
|
|
170
|
+
```bash
|
|
171
|
+
handoff-app scaffold
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
Creates catalog item stubs for the components in the fetched Figma data. The
|
|
175
|
+
command asks which components to create and how.
|
|
176
|
+
|
|
177
|
+
### eject:config
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
handoff-app eject:config
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Writes the default config to the working directory. The command asks for
|
|
184
|
+
TypeScript or JavaScript. `--force` overwrites an existing config file.
|
|
185
|
+
|
|
186
|
+
### eject:pages
|
|
187
|
+
|
|
188
|
+
```bash
|
|
189
|
+
handoff-app eject:pages
|
|
190
|
+
```
|
|
191
|
+
|
|
192
|
+
Copies the default documentation pages to `pages/`, so that you can change
|
|
193
|
+
them. `--force` adds the default pages that you did not change.
|
|
194
|
+
|
|
195
|
+
### eject:theme
|
|
196
|
+
|
|
197
|
+
```bash
|
|
198
|
+
handoff-app eject:theme
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
Copies the Sass file of the selected theme to `theme/default.scss`, so that
|
|
202
|
+
you can change it.
|
|
203
|
+
|
|
204
|
+
## Registry
|
|
205
|
+
|
|
206
|
+
### db:migrate
|
|
207
|
+
|
|
208
|
+
```bash
|
|
209
|
+
DATABASE_URL="postgresql://…" handoff-app db:migrate
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
Applies the registry database migrations. The command reads the project config
|
|
213
|
+
and the database variables, and uses the same database driver as the registry
|
|
214
|
+
build. Run it before the first deployment and before each upgrade. The build,
|
|
215
|
+
the server start, and the installer never run migrations.
|
|
216
|
+
|
|
217
|
+
### login
|
|
218
|
+
|
|
219
|
+
```bash
|
|
220
|
+
handoff-app login [--url <registry-url>] [--profile <name>] [--no-browser]
|
|
221
|
+
```
|
|
222
|
+
|
|
223
|
+
Authorizes the CLI through the device flow of the registry. The CLI saves the
|
|
224
|
+
token in `.handoff/cli-auth.json`, under the selected profile.
|
|
225
|
+
|
|
226
|
+
| Option | Description |
|
|
227
|
+
| --- | --- |
|
|
228
|
+
| `--url <registry-url>` | Registry URL, with its base path when the registry has one. Without it, the CLI uses the configured registry URL. |
|
|
229
|
+
| `--profile <name>` | Saves the login under this profile. The profile needs no config file. |
|
|
230
|
+
| `--no-browser` | Shows the approval URL, but does not open the browser. `HANDOFF_LOGIN_NO_BROWSER=true` does the same. |
|
|
231
|
+
|
|
232
|
+
### logout
|
|
233
|
+
|
|
234
|
+
```bash
|
|
235
|
+
handoff-app logout [--profile <name>] [--url <registry-url>] [--all]
|
|
236
|
+
```
|
|
237
|
+
|
|
238
|
+
Revokes the saved token when possible. Then it removes the saved login of the
|
|
239
|
+
selected profile.
|
|
240
|
+
|
|
241
|
+
| Option | Description |
|
|
242
|
+
| --- | --- |
|
|
243
|
+
| `--url <registry-url>` | Revokes the login only if it belongs to this exact registry URL |
|
|
244
|
+
| `--all` | Revokes and removes the logins of every profile |
|
|
245
|
+
|
|
246
|
+
### publish
|
|
247
|
+
|
|
248
|
+
```bash
|
|
249
|
+
handoff-app publish <catalog|pages|tokens|assets|all> [id...] [--dry-run] [--no-build]
|
|
250
|
+
```
|
|
251
|
+
|
|
252
|
+
Builds the content and publishes it to the connected registry. `all` publishes
|
|
253
|
+
every kind in dependency order. One or more ids limit the publish to those
|
|
254
|
+
entities: catalog item ids, page ids, token set ids, or asset collections.
|
|
255
|
+
`tokens` and `assets` run the Figma pipeline first.
|
|
44
256
|
|
|
45
|
-
|
|
257
|
+
| Option | Description |
|
|
258
|
+
| --- | --- |
|
|
259
|
+
| `--dry-run` | Lists the content that a real publish uploads. Does not connect to a registry. The build still runs. |
|
|
260
|
+
| `--no-build` | Publishes the existing build output without a build first |
|
|
46
261
|
|
|
47
|
-
|
|
262
|
+
### checkout
|
|
48
263
|
|
|
49
|
-
|
|
264
|
+
```bash
|
|
265
|
+
handoff-app checkout <catalog|pages|tokens|assets|all> [id...] [--dry-run]
|
|
266
|
+
```
|
|
50
267
|
|
|
51
|
-
|
|
52
|
-
|
|
268
|
+
Writes content from the connected registry into the workspace. Checkout writes
|
|
269
|
+
declarations in the format that `runtime.workspace.declarationFormat` sets.
|
|
53
270
|
|
|
54
|
-
|
|
55
|
-
|
|
271
|
+
| Option | Description |
|
|
272
|
+
| --- | --- |
|
|
273
|
+
| `--dry-run` | Lists the files that a real checkout creates or overwrites. Writes nothing. |
|
|
56
274
|
|
|
57
|
-
|
|
275
|
+
### Registry connection
|
|
58
276
|
|
|
59
|
-
|
|
277
|
+
`publish` and `checkout` find the registry URL and the token in this order:
|
|
60
278
|
|
|
61
|
-
|
|
279
|
+
1. `HANDOFF_REGISTRY_URL` and `HANDOFF_REGISTRY_ACCESS_TOKEN`, or
|
|
280
|
+
`runtime.registryConnection` in the config.
|
|
281
|
+
2. The saved login of the selected profile, if it belongs to the same registry
|
|
282
|
+
URL. A profile without a login uses the default login.
|
|
283
|
+
3. `HANDOFF_SYNC_SECRET`, when no token and no login is available.
|
|
62
284
|
|
|
63
|
-
|
|
285
|
+
## Deprecated commands
|
|
64
286
|
|
|
65
|
-
|
|
66
|
-
make:component <name> [opts] - Creates a new catalog item with a declaration
|
|
67
|
-
make:page <component> <state> [opts] - Creates a new page
|
|
287
|
+
These commands still work. Each shows a deprecation warning.
|
|
68
288
|
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
289
|
+
| Command | Replacement |
|
|
290
|
+
| --- | --- |
|
|
291
|
+
| `push [type] [id...]` | `publish` |
|
|
292
|
+
| `push:all` | `publish all` |
|
|
293
|
+
| `push:tokens [setId...]` | `publish tokens` |
|
|
294
|
+
| `push:assets [collection]` | `publish assets` |
|
|
295
|
+
| `pull [type] [id...]` | `checkout` |
|
|
73
296
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
-h, --help Show this help message
|
|
78
|
-
-v, --version Show the handoff version number
|
|
297
|
+
The `push` and `pull` commands also accept `components` and `patterns` as the
|
|
298
|
+
type. They accept the options for features that Handoff 2 does not have, and
|
|
299
|
+
show a warning for each one.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "handoff-app",
|
|
3
|
-
"version": "2.0.0-
|
|
3
|
+
"version": "2.0.0-13",
|
|
4
4
|
"description": "Automated documentation toolchain for building client side documentation from figma",
|
|
5
5
|
"author ": {
|
|
6
6
|
"name": "Convertiv",
|
|
@@ -40,9 +40,9 @@
|
|
|
40
40
|
"types": "./dist/pattern.d.ts",
|
|
41
41
|
"default": "./dist/pattern.js"
|
|
42
42
|
},
|
|
43
|
-
"./
|
|
44
|
-
"types": "./dist/
|
|
45
|
-
"default": "./dist/
|
|
43
|
+
"./providers": {
|
|
44
|
+
"types": "./dist/providers.d.ts",
|
|
45
|
+
"default": "./dist/providers.js"
|
|
46
46
|
},
|
|
47
47
|
"./package.json": "./package.json",
|
|
48
48
|
"./*": "./*"
|
|
@@ -58,8 +58,8 @@
|
|
|
58
58
|
"pattern": [
|
|
59
59
|
"./dist/pattern.d.ts"
|
|
60
60
|
],
|
|
61
|
-
"
|
|
62
|
-
"./dist/
|
|
61
|
+
"providers": [
|
|
62
|
+
"./dist/providers.d.ts"
|
|
63
63
|
]
|
|
64
64
|
}
|
|
65
65
|
},
|
|
@@ -89,7 +89,7 @@
|
|
|
89
89
|
"plugins": [
|
|
90
90
|
"prettier-plugin-tailwindcss"
|
|
91
91
|
],
|
|
92
|
-
"
|
|
92
|
+
"tailwindStylesheet": "./src/app/css/index.css"
|
|
93
93
|
},
|
|
94
94
|
"dependencies": {
|
|
95
95
|
"@ai-sdk/openai-compatible": "^3.0.53",
|
package/src/ai/define.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* Typed identity helper for custom AI providers (mirrors `
|
|
2
|
+
* Typed identity helper for custom AI providers (mirrors `defineStorageProvider`): a consumer
|
|
3
3
|
* default-exports its result from a **server-only** module and points a connection's `module` at
|
|
4
4
|
* it. It must be its own module (not an inline `defineConfig` function) so the build can trace it
|
|
5
5
|
* into the deployed registry. The default export may be the provider object, or a factory
|
package/src/ai/types.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Server-only AI provider contract for connections that are not OpenAI-compatible.
|
|
3
3
|
*
|
|
4
4
|
* Every built-in connection speaks the OpenAI-compatible `/chat/completions` API and needs no
|
|
5
|
-
*
|
|
5
|
+
* custom module — Ollama, LiteLLM, OpenRouter, vLLM, LM Studio and Azure OpenAI all serve it, and each of
|
|
6
6
|
* them fronts Anthropic, Google and xAI models. A provider that fits nothing else names a
|
|
7
7
|
* {@link defineAiProvider} module instead of a base URL.
|
|
8
8
|
*/
|
|
@@ -41,7 +41,7 @@ interface AccountLayoutProps {
|
|
|
41
41
|
|
|
42
42
|
export function AccountLayout({ children, config, title, description }: AccountLayoutProps) {
|
|
43
43
|
if (process.env.HANDOFF_RUNTIME_MODE !== 'registry') {
|
|
44
|
-
return <AuthShell title={title}>{null}</AuthShell>;
|
|
44
|
+
return <AuthShell config={config} title={title}>{null}</AuthShell>;
|
|
45
45
|
}
|
|
46
46
|
|
|
47
47
|
return (
|
|
@@ -3,6 +3,7 @@ import Head from 'next/head';
|
|
|
3
3
|
import Link from 'next/link';
|
|
4
4
|
import type { ClientConfig } from '@handoff/types/config';
|
|
5
5
|
import type { ReactNode } from 'react';
|
|
6
|
+
import { pageTitle } from '../../lib/utils';
|
|
6
7
|
import { ConfigContextProvider } from '../context/ConfigContext';
|
|
7
8
|
import { Header } from '../Layout/Header';
|
|
8
9
|
import { Button } from '../ui/button';
|
|
@@ -21,9 +22,17 @@ interface AuthShellProps {
|
|
|
21
22
|
}
|
|
22
23
|
|
|
23
24
|
export function AuthShell({ children, config, title, description, wide = false, hideNav = false, centered = false }: AuthShellProps) {
|
|
25
|
+
const head = (
|
|
26
|
+
<Head>
|
|
27
|
+
<title>{pageTitle({ title }, config?.app?.title)}</title>
|
|
28
|
+
{description ? <meta name="description" content={description} /> : null}
|
|
29
|
+
</Head>
|
|
30
|
+
);
|
|
31
|
+
|
|
24
32
|
if (!isRegistryRuntime) {
|
|
25
33
|
return (
|
|
26
34
|
<main className="flex min-h-screen items-center justify-center px-6">
|
|
35
|
+
{head}
|
|
27
36
|
<div className="max-w-md text-center">
|
|
28
37
|
<h1 className="text-2xl font-semibold">Registry only</h1>
|
|
29
38
|
<p className="mt-2 text-sm text-muted-foreground">Account management is available only in a deployed registry.</p>
|
|
@@ -40,10 +49,7 @@ export function AuthShell({ children, config, title, description, wide = false,
|
|
|
40
49
|
|
|
41
50
|
return (
|
|
42
51
|
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
|
43
|
-
|
|
44
|
-
<title>{title} · Handoff Registry</title>
|
|
45
|
-
{description ? <meta name="description" content={description} /> : null}
|
|
46
|
-
</Head>
|
|
52
|
+
{head}
|
|
47
53
|
{centered ? (
|
|
48
54
|
<main className="flex min-h-[calc(100vh-8rem)] items-center justify-center bg-background px-4 py-12">
|
|
49
55
|
<div className="w-full max-w-md">{children}</div>
|
|
@@ -16,7 +16,7 @@ import {
|
|
|
16
16
|
import { Separator } from '../ui/separator';
|
|
17
17
|
import { Sheet, SheetClose, SheetContent, SheetHeader } from '../ui/sheet';
|
|
18
18
|
import { Tooltip, TooltipContent, TooltipProvider, TooltipTrigger } from '../ui/tooltip';
|
|
19
|
-
import { hexToRgb } from '../util/colors';
|
|
19
|
+
import { hexToRgb, hexToRgbaCss } from '../util/colors';
|
|
20
20
|
import ColorContrast from './ColorContrast';
|
|
21
21
|
import ColorInfo from './ColorInfo';
|
|
22
22
|
import ColorSpaces from './ColorSpaces';
|
|
@@ -25,7 +25,6 @@ import ColorTailwind from './ColorTailwind';
|
|
|
25
25
|
type ColorGridProps = {
|
|
26
26
|
title: string;
|
|
27
27
|
group: string;
|
|
28
|
-
description: string;
|
|
29
28
|
colors: CoreTypes.IColorObject[];
|
|
30
29
|
};
|
|
31
30
|
|
|
@@ -33,7 +32,7 @@ const LargeColorGrid: React.FC<{ colors: CoreTypes.IColorObject[]; setOpen: (col
|
|
|
33
32
|
<div className="@container">
|
|
34
33
|
<div className="mb-6 grid grid-cols-1 gap-6 @md:grid-cols-2">
|
|
35
34
|
{colors.map((color) => (
|
|
36
|
-
<
|
|
35
|
+
<div className="flex flex-col items-start" key={color.group + '-' + color.name}>
|
|
37
36
|
<div
|
|
38
37
|
className="group relative mb-2 block h-32 w-full rounded-lg"
|
|
39
38
|
style={{ background: color.value ?? '', backgroundBlendMode: color.blend ?? '' }}
|
|
@@ -42,7 +41,7 @@ const LargeColorGrid: React.FC<{ colors: CoreTypes.IColorObject[]; setOpen: (col
|
|
|
42
41
|
</div>
|
|
43
42
|
<p className="mb-1 text-sm font-medium line-clamp-1" title={color.name}>{color.name}</p>
|
|
44
43
|
<small className="font-mono text-xs font-light text-gray-400 line-clamp-1" title={color.value}>{color.value}</small>
|
|
45
|
-
</
|
|
44
|
+
</div>
|
|
46
45
|
))}
|
|
47
46
|
</div>
|
|
48
47
|
</div>
|
|
@@ -52,10 +51,11 @@ const SmallColorGrid: React.FC<{ colors: CoreTypes.IColorObject[]; setOpen: (col
|
|
|
52
51
|
// group colors by subgroup
|
|
53
52
|
const groupedColors = colors.reduce(
|
|
54
53
|
(acc, color) => {
|
|
55
|
-
|
|
56
|
-
|
|
54
|
+
const subgroup = color.subgroup ?? '';
|
|
55
|
+
if (!acc[subgroup]) {
|
|
56
|
+
acc[subgroup] = [];
|
|
57
57
|
}
|
|
58
|
-
acc[
|
|
58
|
+
acc[subgroup].push(color);
|
|
59
59
|
return acc;
|
|
60
60
|
},
|
|
61
61
|
{} as Record<string, CoreTypes.IColorObject[]>
|
|
@@ -64,11 +64,11 @@ const SmallColorGrid: React.FC<{ colors: CoreTypes.IColorObject[]; setOpen: (col
|
|
|
64
64
|
<>
|
|
65
65
|
{Object.entries(groupedColors).map(([subgroup]) => (
|
|
66
66
|
<div className="mb-5" key={`group-${subgroup}`}>
|
|
67
|
-
<HeadersType.H4
|
|
67
|
+
{subgroup && <HeadersType.H4>{startCase(subgroup.replaceAll('-', ' '))}</HeadersType.H4>}
|
|
68
68
|
<div className="grid grid-cols-[repeat(auto-fit,minmax(60px,60px))] gap-6">
|
|
69
69
|
{groupedColors[subgroup].map((color) => (
|
|
70
70
|
<React.Fragment key={`group-${subgroup}-${color.name}`}>
|
|
71
|
-
<
|
|
71
|
+
<div className="flex flex-col">
|
|
72
72
|
<div
|
|
73
73
|
className="group relative mb-2 block h-14 rounded-lg"
|
|
74
74
|
style={{ background: color.value ?? '', backgroundBlendMode: color.blend ?? '' }}
|
|
@@ -77,7 +77,7 @@ const SmallColorGrid: React.FC<{ colors: CoreTypes.IColorObject[]; setOpen: (col
|
|
|
77
77
|
</div>
|
|
78
78
|
<p className="mb-1 text-xs font-medium line-clamp-1" title={color.name}>{color.name}</p>
|
|
79
79
|
<small className="font-mono text-xs font-light text-gray-400 line-clamp-1" title={color.value}>{color.value}</small>
|
|
80
|
-
</
|
|
80
|
+
</div>
|
|
81
81
|
</React.Fragment>
|
|
82
82
|
))}
|
|
83
83
|
</div>
|
|
@@ -87,7 +87,7 @@ const SmallColorGrid: React.FC<{ colors: CoreTypes.IColorObject[]; setOpen: (col
|
|
|
87
87
|
);
|
|
88
88
|
};
|
|
89
89
|
|
|
90
|
-
const ColorGrid: React.FC<ColorGridProps> = ({ title,
|
|
90
|
+
const ColorGrid: React.FC<ColorGridProps> = ({ title, colors, group }) => {
|
|
91
91
|
const [open, setOpen] = React.useState(false);
|
|
92
92
|
const [selectedColor, setSelectedColor] = React.useState(null);
|
|
93
93
|
const openSheet = (color) => {
|
|
@@ -96,8 +96,7 @@ const ColorGrid: React.FC<ColorGridProps> = ({ title, description, colors, group
|
|
|
96
96
|
};
|
|
97
97
|
return (
|
|
98
98
|
<div id={`${group}-colors`} className="scroll-mt-24 scroll-smooth pb-10">
|
|
99
|
-
<h3 className="text-lg font-medium">{title}</h3>
|
|
100
|
-
<p className="mb-8">{description}</p>
|
|
99
|
+
<h3 className="mb-8 text-lg font-medium">{title}</h3>
|
|
101
100
|
{colors.length < 5 ? <LargeColorGrid colors={colors} setOpen={openSheet} /> : <SmallColorGrid colors={colors} setOpen={openSheet} />}
|
|
102
101
|
<ColorSheet color={selectedColor} open={open} setOpen={setOpen} />
|
|
103
102
|
</div>
|
|
@@ -122,7 +121,7 @@ const ColorDropdown: React.FC<{ color: CoreTypes.IColorObject; openSheet: (color
|
|
|
122
121
|
<Copy className="text-gray-400" /> HEX
|
|
123
122
|
<DropdownMenuShortcut className="max-w-[100px] truncate">{color.value}</DropdownMenuShortcut>
|
|
124
123
|
</DropdownMenuItem>
|
|
125
|
-
<DropdownMenuItem onClick={() => navigator.clipboard.writeText(
|
|
124
|
+
<DropdownMenuItem onClick={() => navigator.clipboard.writeText(hexToRgbaCss(color.value) ?? color.value)}>
|
|
126
125
|
<Copy className="text-gray-400" /> RGBA
|
|
127
126
|
<DropdownMenuShortcut className="max-w-[100px] truncate">{hexToRgb(color.value)}</DropdownMenuShortcut>
|
|
128
127
|
</DropdownMenuItem>
|
|
@@ -5,7 +5,7 @@ import { Header } from '../../components/Layout/Header';
|
|
|
5
5
|
import { ThemeProvider } from '../../components/util/theme-provider';
|
|
6
6
|
import SideNav from '../Navigation/SideNav';
|
|
7
7
|
import { ConfigContextProvider } from '../context/ConfigContext';
|
|
8
|
-
import { hasRenderableNav } from '../../lib/utils';
|
|
8
|
+
import { hasRenderableNav, pageTitle } from '../../lib/utils';
|
|
9
9
|
import { SidebarInset, SidebarProvider } from '../ui/sidebar';
|
|
10
10
|
import { SectionLink } from '../util';
|
|
11
11
|
|
|
@@ -34,7 +34,7 @@ export default function Layout<LayoutComponentProps>({ children, config, menu, m
|
|
|
34
34
|
<ConfigContextProvider defaultConfig={config} defaultMenu={menu}>
|
|
35
35
|
<ThemeProvider attribute="class" defaultTheme="system" enableSystem disableTransitionOnChange>
|
|
36
36
|
<Head>
|
|
37
|
-
<title>{metadata
|
|
37
|
+
<title>{pageTitle(metadata, config?.app?.title)}</title>
|
|
38
38
|
<meta name="description" content={metadata.metaDescription} />
|
|
39
39
|
</Head>
|
|
40
40
|
<div className="absolute left-[-200px] top-[-200px] z-[-1] h-[400px] w-[600px] bg-[#111111] opacity-[0.05] blur-[350px]">
|