handoff-app 2.0.0-4 → 2.0.0-6
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 +346 -377
- package/dist/app-builder/build.js +11 -4
- package/dist/app-builder/client-config.js +1 -0
- 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 +38 -6
- 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/defaults.d.ts +2 -0
- package/dist/config/defaults.js +4 -1
- package/dist/config/index.d.ts +3 -2
- package/dist/config/index.js +3 -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/types/config.d.ts +7 -0
- 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 +4 -2
- package/src/app/components/CopyToClipboard.tsx +27 -26
- package/src/app/components/Layout/Header.tsx +4 -12
- package/src/app/components/Layout/RuntimeModeBadge.tsx +18 -0
- 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 +3 -1
- package/src/app/components/ui/dialog.tsx +73 -0
- package/src/app/components/util/index.ts +5 -23
- 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 +5 -0
- 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 +343 -0
- package/src/app/lib/mcp/shape.ts +595 -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 +9 -0
- package/src/app/pages/[...slug]/index.tsx +52 -51
- 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/mcp.ts +56 -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 +31 -5
- package/src/app-builder/build.ts +11 -4
- package/src/app-builder/client-config.ts +2 -1
- 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 +30 -6
- 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/defaults.ts +3 -0
- package/src/config/index.ts +3 -2
- 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/types/config.ts +7 -0
- 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 +10 -0
- package/templates/default/handoff.config.js.tpl +6 -3
- package/templates/default/handoff.config.ts.tpl +6 -3
- package/templates/default/handoff.config.with-examples.js.tpl +6 -3
- package/templates/default/handoff.config.with-examples.ts.tpl +6 -3
- 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/dist/commands/utils.d.ts
CHANGED
|
@@ -1,10 +1,15 @@
|
|
|
1
1
|
import { Argv } from 'yargs';
|
|
2
|
-
import
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export
|
|
6
|
-
|
|
7
|
-
export declare const
|
|
2
|
+
import Handoff from '../';
|
|
3
|
+
import { SharedArgs } from './types';
|
|
4
|
+
/** The `type` argument accepted by publish/checkout: any content kind, or `all` for every kind. */
|
|
5
|
+
export declare const REGISTRY_TARGET_KINDS: readonly ["components", "patterns", "pages", "tokens", "assets", "all"];
|
|
6
|
+
export type RegistryTargetKind = (typeof REGISTRY_TARGET_KINDS)[number];
|
|
7
|
+
export declare const createHandoff: (args: SharedArgs) => Handoff;
|
|
8
|
+
/**
|
|
9
|
+
* Run a registry command against a fresh Handoff. Registry failures are the user's to act on, so they
|
|
10
|
+
* surface as one actionable line and a non-zero exit rather than a stack trace.
|
|
11
|
+
*/
|
|
12
|
+
export declare const runRegistryCommand: (args: SharedArgs, run: (handoff: Handoff) => Promise<unknown>) => Promise<void>;
|
|
8
13
|
export declare const getSharedOptions: (yargs: Argv) => Argv<import("yargs").Omit<{}, "debug" | "config" | "force"> & import("yargs").InferredOptionTypes<{
|
|
9
14
|
config: {
|
|
10
15
|
alias: string;
|
|
@@ -22,3 +27,66 @@ export declare const getSharedOptions: (yargs: Argv) => Argv<import("yargs").Omi
|
|
|
22
27
|
description: string;
|
|
23
28
|
};
|
|
24
29
|
}>>;
|
|
30
|
+
/** Shared options plus the transfer options: publish and its compatibility aliases use these. */
|
|
31
|
+
export declare const getPublishOptions: (yargs: Argv) => Argv<import("yargs").Omit<import("yargs").Omit<{}, "debug" | "config" | "force"> & import("yargs").InferredOptionTypes<{
|
|
32
|
+
config: {
|
|
33
|
+
alias: string;
|
|
34
|
+
type: "string";
|
|
35
|
+
description: string;
|
|
36
|
+
};
|
|
37
|
+
force: {
|
|
38
|
+
alias: string;
|
|
39
|
+
type: "boolean";
|
|
40
|
+
description: string;
|
|
41
|
+
};
|
|
42
|
+
debug: {
|
|
43
|
+
alias: string;
|
|
44
|
+
type: "boolean";
|
|
45
|
+
description: string;
|
|
46
|
+
};
|
|
47
|
+
}>, "build" | "dry-run"> & import("yargs").InferredOptionTypes<{
|
|
48
|
+
'dry-run': {
|
|
49
|
+
type: "boolean";
|
|
50
|
+
description: string;
|
|
51
|
+
};
|
|
52
|
+
build: {
|
|
53
|
+
type: "boolean";
|
|
54
|
+
default: boolean;
|
|
55
|
+
description: string;
|
|
56
|
+
};
|
|
57
|
+
}>>;
|
|
58
|
+
/** Shared options plus `--dry-run`: checkout and its compatibility aliases use these. */
|
|
59
|
+
export declare const getCheckoutOptions: (yargs: Argv) => Argv<import("yargs").Omit<import("yargs").Omit<{}, "debug" | "config" | "force"> & import("yargs").InferredOptionTypes<{
|
|
60
|
+
config: {
|
|
61
|
+
alias: string;
|
|
62
|
+
type: "string";
|
|
63
|
+
description: string;
|
|
64
|
+
};
|
|
65
|
+
force: {
|
|
66
|
+
alias: string;
|
|
67
|
+
type: "boolean";
|
|
68
|
+
description: string;
|
|
69
|
+
};
|
|
70
|
+
debug: {
|
|
71
|
+
alias: string;
|
|
72
|
+
type: "boolean";
|
|
73
|
+
description: string;
|
|
74
|
+
};
|
|
75
|
+
}>, "dry-run"> & import("yargs").InferredOptionTypes<{
|
|
76
|
+
'dry-run': {
|
|
77
|
+
type: "boolean";
|
|
78
|
+
description: string;
|
|
79
|
+
};
|
|
80
|
+
}>>;
|
|
81
|
+
/**
|
|
82
|
+
* Positional `type` + variadic `id`, shared by publish, checkout, and their compatibility aliases.
|
|
83
|
+
* `choices` is always declared: yargs allows an omitted optional positional while still rejecting an
|
|
84
|
+
* unrecognized one, so the deprecated commands get the same guard as the canonical ones.
|
|
85
|
+
*/
|
|
86
|
+
export declare const withTargetPositionals: (yargs: Argv, verb: "publish" | "checkout") => Argv<{
|
|
87
|
+
type: "pages" | "components" | "patterns" | "assets" | "tokens" | "all";
|
|
88
|
+
} & {
|
|
89
|
+
id: string[];
|
|
90
|
+
}>;
|
|
91
|
+
/** Dispatch one `type` argument to the matching Handoff entry point. */
|
|
92
|
+
export declare const runTarget: (handoff: Handoff, type: RegistryTargetKind, ids: string[] | undefined, verb: "publish" | "checkout") => Promise<Handoff>;
|
package/dist/commands/utils.js
CHANGED
|
@@ -1,20 +1,53 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
11
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
11
13
|
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.runTarget = exports.withTargetPositionals = exports.getCheckoutOptions = exports.getPublishOptions = exports.getSharedOptions = exports.runRegistryCommand = exports.createHandoff = exports.REGISTRY_TARGET_KINDS = void 0;
|
|
16
|
+
const __1 = __importDefault(require("../"));
|
|
17
|
+
const content_kinds_1 = require("../registry/content-kinds");
|
|
18
|
+
const logger_1 = require("../utils/logger");
|
|
19
|
+
/** The `type` argument accepted by publish/checkout: any content kind, or `all` for every kind. */
|
|
20
|
+
exports.REGISTRY_TARGET_KINDS = [...content_kinds_1.REGISTRY_ENTITY_KINDS, 'all'];
|
|
21
|
+
const createHandoff = (args) => new __1.default({
|
|
22
|
+
debug: args.debug,
|
|
23
|
+
force: args.force,
|
|
24
|
+
configPath: args.config,
|
|
25
|
+
dryRun: args.dryRun,
|
|
26
|
+
// yargs gives `--no-build` as `build: false`; anything else leaves the build in place.
|
|
27
|
+
skipBuild: args.build === false,
|
|
28
|
+
});
|
|
29
|
+
exports.createHandoff = createHandoff;
|
|
30
|
+
/**
|
|
31
|
+
* Run a registry command against a fresh Handoff. Registry failures are the user's to act on, so they
|
|
32
|
+
* surface as one actionable line and a non-zero exit rather than a stack trace.
|
|
33
|
+
*/
|
|
34
|
+
const runRegistryCommand = (args, run) => __awaiter(void 0, void 0, void 0, function* () {
|
|
35
|
+
const handoff = (0, exports.createHandoff)(args);
|
|
36
|
+
try {
|
|
37
|
+
yield run(handoff);
|
|
38
|
+
}
|
|
39
|
+
catch (error) {
|
|
40
|
+
logger_1.Logger.error(error instanceof Error ? error.message : String(error));
|
|
41
|
+
process.exitCode = 1;
|
|
42
|
+
}
|
|
43
|
+
});
|
|
44
|
+
exports.runRegistryCommand = runRegistryCommand;
|
|
12
45
|
const getSharedOptions = (yargs) => {
|
|
13
46
|
return yargs.options({
|
|
14
47
|
config: {
|
|
15
48
|
alias: 'c',
|
|
16
49
|
type: 'string',
|
|
17
|
-
description: 'Path to config file',
|
|
50
|
+
description: 'Path to config file, relative to the working directory',
|
|
18
51
|
},
|
|
19
52
|
force: {
|
|
20
53
|
alias: 'f',
|
|
@@ -29,3 +62,49 @@ const getSharedOptions = (yargs) => {
|
|
|
29
62
|
});
|
|
30
63
|
};
|
|
31
64
|
exports.getSharedOptions = getSharedOptions;
|
|
65
|
+
/** Shared options plus the transfer options: publish and its compatibility aliases use these. */
|
|
66
|
+
const getPublishOptions = (yargs) => (0, exports.getSharedOptions)(yargs).options({
|
|
67
|
+
'dry-run': {
|
|
68
|
+
type: 'boolean',
|
|
69
|
+
description: 'Report what would be published without contacting the registry (the build still runs; add --no-build to skip it)',
|
|
70
|
+
},
|
|
71
|
+
build: {
|
|
72
|
+
type: 'boolean',
|
|
73
|
+
default: true,
|
|
74
|
+
description: 'Run a fresh build first; use --no-build to publish the existing output',
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
exports.getPublishOptions = getPublishOptions;
|
|
78
|
+
/** Shared options plus `--dry-run`: checkout and its compatibility aliases use these. */
|
|
79
|
+
const getCheckoutOptions = (yargs) => (0, exports.getSharedOptions)(yargs).options({
|
|
80
|
+
'dry-run': {
|
|
81
|
+
type: 'boolean',
|
|
82
|
+
description: 'Report what would be written without changing any workspace file',
|
|
83
|
+
},
|
|
84
|
+
});
|
|
85
|
+
exports.getCheckoutOptions = getCheckoutOptions;
|
|
86
|
+
/**
|
|
87
|
+
* Positional `type` + variadic `id`, shared by publish, checkout, and their compatibility aliases.
|
|
88
|
+
* `choices` is always declared: yargs allows an omitted optional positional while still rejecting an
|
|
89
|
+
* unrecognized one, so the deprecated commands get the same guard as the canonical ones.
|
|
90
|
+
*/
|
|
91
|
+
const withTargetPositionals = (yargs, verb) => yargs
|
|
92
|
+
.positional('type', {
|
|
93
|
+
describe: `The kind of content to ${verb}, or "all" for every kind`,
|
|
94
|
+
choices: exports.REGISTRY_TARGET_KINDS,
|
|
95
|
+
type: 'string',
|
|
96
|
+
})
|
|
97
|
+
.positional('id', {
|
|
98
|
+
describe: `The stable id (component/pattern/page id, token set id, or asset collection); omit to ${verb} all of that kind`,
|
|
99
|
+
type: 'string',
|
|
100
|
+
array: true,
|
|
101
|
+
});
|
|
102
|
+
exports.withTargetPositionals = withTargetPositionals;
|
|
103
|
+
/** Dispatch one `type` argument to the matching Handoff entry point. */
|
|
104
|
+
const runTarget = (handoff, type, ids, verb) => {
|
|
105
|
+
if (type === 'all') {
|
|
106
|
+
return verb === 'publish' ? handoff.publishAll() : handoff.checkoutAll();
|
|
107
|
+
}
|
|
108
|
+
return verb === 'publish' ? handoff.publishKind(type, ids) : handoff.checkoutKind(type, ids);
|
|
109
|
+
};
|
|
110
|
+
exports.runTarget = runTarget;
|
|
@@ -8,11 +8,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
8
8
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
9
|
});
|
|
10
10
|
};
|
|
11
|
-
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
12
|
-
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
13
|
-
};
|
|
14
11
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
-
const __1 = __importDefault(require("../../"));
|
|
16
12
|
const utils_1 = require("../utils");
|
|
17
13
|
const command = {
|
|
18
14
|
command: 'validate:components',
|
|
@@ -27,7 +23,7 @@ const command = {
|
|
|
27
23
|
},
|
|
28
24
|
handler: (args) => __awaiter(void 0, void 0, void 0, function* () {
|
|
29
25
|
var _a;
|
|
30
|
-
const handoff =
|
|
26
|
+
const handoff = (0, utils_1.createHandoff)(args);
|
|
31
27
|
yield handoff.validateComponents((_a = args.skipBuild) !== null && _a !== void 0 ? _a : false);
|
|
32
28
|
}),
|
|
33
29
|
};
|
|
@@ -6,6 +6,8 @@ export interface ImageStyle {
|
|
|
6
6
|
width: number;
|
|
7
7
|
description: string;
|
|
8
8
|
}
|
|
9
|
+
/** Whether the MCP endpoint is served. On unless `runtime.mcp` is explicitly `false`. */
|
|
10
|
+
export declare const isMcpEnabled: (config: Config | null | undefined) => boolean;
|
|
9
11
|
export declare const defaultConfig: () => Config;
|
|
10
12
|
/**
|
|
11
13
|
* Retrieves the client configuration from the provided handoff configuration.
|
package/dist/config/defaults.js
CHANGED
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.getClientConfig = exports.defaultConfig = void 0;
|
|
3
|
+
exports.getClientConfig = exports.defaultConfig = exports.isMcpEnabled = void 0;
|
|
4
4
|
const connection_1 = require("../registry/connection");
|
|
5
|
+
/** Whether the MCP endpoint is served. On unless `runtime.mcp` is explicitly `false`. */
|
|
6
|
+
const isMcpEnabled = (config) => { var _a; return ((_a = config === null || config === void 0 ? void 0 : config.runtime) === null || _a === void 0 ? void 0 : _a.mcp) !== false; };
|
|
7
|
+
exports.isMcpEnabled = isMcpEnabled;
|
|
5
8
|
const defaultConfig = () => {
|
|
6
9
|
var _a, _b, _c, _d;
|
|
7
10
|
return ({
|
package/dist/config/index.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
export { defaultConfig, getClientConfig } from './defaults';
|
|
1
|
+
export { defaultConfig, getClientConfig, isMcpEnabled } from './defaults';
|
|
2
2
|
export type { ImageStyle } from './defaults';
|
|
3
|
-
export { initConfig, initConfigWithMetadata } from './loader';
|
|
3
|
+
export { HandoffConfigError, initConfig, initConfigWithMetadata } from './loader';
|
|
4
|
+
export type { ConfigLoadContext } from './loader';
|
|
4
5
|
export { defineConfig } from './helpers';
|
|
5
6
|
export { initRuntimeConfig } from './runtime';
|
|
6
7
|
export { validateConfig } from './validator';
|
package/dist/config/index.js
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.writeEntries = exports.isEntryCovered = exports.validateConfig = exports.initRuntimeConfig = exports.defineConfig = exports.initConfigWithMetadata = exports.initConfig = exports.getClientConfig = exports.defaultConfig = void 0;
|
|
3
|
+
exports.writeEntries = exports.isEntryCovered = exports.validateConfig = exports.initRuntimeConfig = exports.defineConfig = exports.initConfigWithMetadata = exports.initConfig = exports.HandoffConfigError = exports.isMcpEnabled = exports.getClientConfig = exports.defaultConfig = void 0;
|
|
4
4
|
// Config defaults and client config
|
|
5
5
|
var defaults_1 = require("./defaults");
|
|
6
6
|
Object.defineProperty(exports, "defaultConfig", { enumerable: true, get: function () { return defaults_1.defaultConfig; } });
|
|
7
7
|
Object.defineProperty(exports, "getClientConfig", { enumerable: true, get: function () { return defaults_1.getClientConfig; } });
|
|
8
|
+
Object.defineProperty(exports, "isMcpEnabled", { enumerable: true, get: function () { return defaults_1.isMcpEnabled; } });
|
|
8
9
|
// Config file loading
|
|
9
10
|
var loader_1 = require("./loader");
|
|
11
|
+
Object.defineProperty(exports, "HandoffConfigError", { enumerable: true, get: function () { return loader_1.HandoffConfigError; } });
|
|
10
12
|
Object.defineProperty(exports, "initConfig", { enumerable: true, get: function () { return loader_1.initConfig; } });
|
|
11
13
|
Object.defineProperty(exports, "initConfigWithMetadata", { enumerable: true, get: function () { return loader_1.initConfigWithMetadata; } });
|
|
12
14
|
// Config helpers
|
package/dist/config/loader.d.ts
CHANGED
|
@@ -1,20 +1,33 @@
|
|
|
1
1
|
import { Config } from '../types/config';
|
|
2
|
+
/** Raised when an explicitly requested config file cannot be used. */
|
|
3
|
+
export declare class HandoffConfigError extends Error {
|
|
4
|
+
constructor(message: string);
|
|
5
|
+
}
|
|
2
6
|
type ConfigLoadResult = {
|
|
3
7
|
config: Config;
|
|
4
8
|
configPath?: string;
|
|
5
9
|
};
|
|
10
|
+
/** Where to look for the config: the working directory, plus an optional explicit file. */
|
|
11
|
+
export type ConfigLoadContext = {
|
|
12
|
+
/** Directory relative config paths resolve from, and the root that gets searched. */
|
|
13
|
+
workingPath?: string;
|
|
14
|
+
/** Explicit config file (the CLI's `-c, --config`), replacing discovery entirely. */
|
|
15
|
+
configPath?: string;
|
|
16
|
+
};
|
|
6
17
|
/**
|
|
7
|
-
* Loads the handoff configuration
|
|
18
|
+
* Loads the handoff configuration for the given working directory and returns metadata.
|
|
8
19
|
*/
|
|
9
|
-
export declare const initConfigWithMetadata: (configOverride?: Partial<Config
|
|
20
|
+
export declare const initConfigWithMetadata: (configOverride?: Partial<Config>, context?: ConfigLoadContext) => ConfigLoadResult;
|
|
10
21
|
/**
|
|
11
|
-
* Loads the handoff configuration
|
|
22
|
+
* Loads the handoff configuration for the given working directory.
|
|
12
23
|
*
|
|
13
|
-
* Searches for config files in order: handoff.config.ts, handoff.config.js, handoff.config.cjs, handoff.config.json
|
|
14
|
-
* Merges file config with any provided overrides,
|
|
24
|
+
* Searches for config files in order: handoff.config.ts, handoff.config.js, handoff.config.cjs, handoff.config.json,
|
|
25
|
+
* unless `context.configPath` names one explicitly. Merges file config with any provided overrides,
|
|
26
|
+
* then applies defaults for missing values.
|
|
15
27
|
*
|
|
16
28
|
* @param configOverride - Optional partial config to override file-loaded values.
|
|
29
|
+
* @param context - Optional working directory and explicit config file to load.
|
|
17
30
|
* @returns The fully resolved Config object.
|
|
18
31
|
*/
|
|
19
|
-
export declare const initConfig: (configOverride?: Partial<Config
|
|
32
|
+
export declare const initConfig: (configOverride?: Partial<Config>, context?: ConfigLoadContext) => Config;
|
|
20
33
|
export {};
|
package/dist/config/loader.js
CHANGED
|
@@ -3,13 +3,14 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.initConfig = exports.initConfigWithMetadata = void 0;
|
|
6
|
+
exports.initConfig = exports.initConfigWithMetadata = exports.HandoffConfigError = void 0;
|
|
7
7
|
const esbuild_1 = __importDefault(require("esbuild"));
|
|
8
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
9
|
const merge_1 = __importDefault(require("lodash/merge"));
|
|
10
10
|
const module_1 = require("module");
|
|
11
11
|
const path_1 = __importDefault(require("path"));
|
|
12
12
|
const logger_1 = require("../utils/logger");
|
|
13
|
+
const path_2 = require("../utils/path");
|
|
13
14
|
const defaults_1 = require("./defaults");
|
|
14
15
|
const CONFIG_FILE_PREFERENCE = [
|
|
15
16
|
'handoff.config.ts',
|
|
@@ -17,6 +18,16 @@ const CONFIG_FILE_PREFERENCE = [
|
|
|
17
18
|
'handoff.config.cjs',
|
|
18
19
|
'handoff.config.json',
|
|
19
20
|
];
|
|
21
|
+
/** Extensions the loader knows how to evaluate, derived from the discoverable file names. */
|
|
22
|
+
const SUPPORTED_CONFIG_EXTENSIONS = Array.from(new Set(CONFIG_FILE_PREFERENCE.map((fileName) => path_1.default.extname(fileName))));
|
|
23
|
+
/** Raised when an explicitly requested config file cannot be used. */
|
|
24
|
+
class HandoffConfigError extends Error {
|
|
25
|
+
constructor(message) {
|
|
26
|
+
super(message);
|
|
27
|
+
this.name = 'HandoffConfigError';
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
exports.HandoffConfigError = HandoffConfigError;
|
|
20
31
|
const evaluateTypeScriptConfig = (filePath, handoffModulePath) => {
|
|
21
32
|
var _a, _b;
|
|
22
33
|
const buildResult = esbuild_1.default.buildSync({
|
|
@@ -49,11 +60,12 @@ const evaluateTypeScriptConfig = (filePath, handoffModulePath) => {
|
|
|
49
60
|
return mod.exports;
|
|
50
61
|
};
|
|
51
62
|
const loadConfigFile = (configPath) => {
|
|
52
|
-
|
|
63
|
+
const extension = path_1.default.extname(configPath);
|
|
64
|
+
if (extension === '.json') {
|
|
53
65
|
const buffer = fs_extra_1.default.readFileSync(configPath);
|
|
54
66
|
return JSON.parse(buffer.toString());
|
|
55
67
|
}
|
|
56
|
-
if (
|
|
68
|
+
if (extension === '.ts') {
|
|
57
69
|
const handoffModulePath = path_1.default.resolve(__dirname, '../..');
|
|
58
70
|
const importedConfig = evaluateTypeScriptConfig(configPath, handoffModulePath);
|
|
59
71
|
return (importedConfig.default || importedConfig);
|
|
@@ -63,9 +75,24 @@ const loadConfigFile = (configPath) => {
|
|
|
63
75
|
const importedConfig = require(configPath);
|
|
64
76
|
return (importedConfig.default || importedConfig);
|
|
65
77
|
};
|
|
66
|
-
|
|
78
|
+
/**
|
|
79
|
+
* Picks the config file to load. An explicitly requested file replaces discovery - it is resolved
|
|
80
|
+
* from `workingPath` and must exist in a format the loader can evaluate. Otherwise every known
|
|
81
|
+
* config name is looked for in `workingPath`, the first match winning.
|
|
82
|
+
*/
|
|
83
|
+
const resolveConfigFilePath = (workingPath, requestedPath) => {
|
|
84
|
+
if (requestedPath) {
|
|
85
|
+
const selected = path_1.default.resolve(workingPath, requestedPath);
|
|
86
|
+
if (!fs_extra_1.default.existsSync(selected)) {
|
|
87
|
+
throw new HandoffConfigError(`Config file not found: "${requestedPath}" (resolved to ${selected})`);
|
|
88
|
+
}
|
|
89
|
+
if (!SUPPORTED_CONFIG_EXTENSIONS.includes(path_1.default.extname(selected))) {
|
|
90
|
+
throw new HandoffConfigError(`Unsupported config file "${path_1.default.basename(selected)}". Supported extensions: ${SUPPORTED_CONFIG_EXTENSIONS.join(', ')}`);
|
|
91
|
+
}
|
|
92
|
+
return { selected, ignored: [] };
|
|
93
|
+
}
|
|
67
94
|
const existing = CONFIG_FILE_PREFERENCE
|
|
68
|
-
.map((fileName) => path_1.default.resolve(
|
|
95
|
+
.map((fileName) => path_1.default.resolve(workingPath, fileName))
|
|
69
96
|
.filter((filePath) => fs_extra_1.default.existsSync(filePath));
|
|
70
97
|
if (!existing.length) {
|
|
71
98
|
return { selected: undefined, ignored: [] };
|
|
@@ -74,11 +101,12 @@ const resolveConfigFilePath = () => {
|
|
|
74
101
|
return { selected, ignored };
|
|
75
102
|
};
|
|
76
103
|
/**
|
|
77
|
-
* Loads the handoff configuration
|
|
104
|
+
* Loads the handoff configuration for the given working directory and returns metadata.
|
|
78
105
|
*/
|
|
79
|
-
const initConfigWithMetadata = (configOverride) => {
|
|
106
|
+
const initConfigWithMetadata = (configOverride, context) => {
|
|
107
|
+
var _a;
|
|
80
108
|
let config = {};
|
|
81
|
-
const { selected: configPath, ignored } = resolveConfigFilePath();
|
|
109
|
+
const { selected: configPath, ignored } = resolveConfigFilePath((_a = context === null || context === void 0 ? void 0 : context.workingPath) !== null && _a !== void 0 ? _a : (0, path_2.resolveWorkingPath)(), context === null || context === void 0 ? void 0 : context.configPath);
|
|
82
110
|
if (ignored.length > 0 && configPath) {
|
|
83
111
|
logger_1.Logger.warn(`Multiple config files found. Using "${path_1.default.basename(configPath)}" and ignoring: ${ignored
|
|
84
112
|
.map((filePath) => `"${path_1.default.basename(filePath)}"`)
|
|
@@ -104,15 +132,17 @@ const initConfigWithMetadata = (configOverride) => {
|
|
|
104
132
|
};
|
|
105
133
|
exports.initConfigWithMetadata = initConfigWithMetadata;
|
|
106
134
|
/**
|
|
107
|
-
* Loads the handoff configuration
|
|
135
|
+
* Loads the handoff configuration for the given working directory.
|
|
108
136
|
*
|
|
109
|
-
* Searches for config files in order: handoff.config.ts, handoff.config.js, handoff.config.cjs, handoff.config.json
|
|
110
|
-
* Merges file config with any provided overrides,
|
|
137
|
+
* Searches for config files in order: handoff.config.ts, handoff.config.js, handoff.config.cjs, handoff.config.json,
|
|
138
|
+
* unless `context.configPath` names one explicitly. Merges file config with any provided overrides,
|
|
139
|
+
* then applies defaults for missing values.
|
|
111
140
|
*
|
|
112
141
|
* @param configOverride - Optional partial config to override file-loaded values.
|
|
142
|
+
* @param context - Optional working directory and explicit config file to load.
|
|
113
143
|
* @returns The fully resolved Config object.
|
|
114
144
|
*/
|
|
115
|
-
const initConfig = (configOverride) => {
|
|
116
|
-
return (0, exports.initConfigWithMetadata)(configOverride).config;
|
|
145
|
+
const initConfig = (configOverride, context) => {
|
|
146
|
+
return (0, exports.initConfigWithMetadata)(configOverride, context).config;
|
|
117
147
|
};
|
|
118
148
|
exports.initConfig = initConfig;
|
|
@@ -1,18 +1,18 @@
|
|
|
1
1
|
import { PageListObject } from '../../transformers/preview/types';
|
|
2
2
|
type RawPageFrontmatter = Record<string, any>;
|
|
3
3
|
type NormalizePageOptions = {
|
|
4
|
-
/** The page id
|
|
4
|
+
/** The page id derived from its file location (`index` is reserved for the root home page). */
|
|
5
5
|
id: string;
|
|
6
6
|
/** Logical route the page is served at (e.g. `/guides/setup`). */
|
|
7
7
|
routePath: string;
|
|
8
8
|
/** Absolute filesystem path of the source `.md` (workspace-only, stripped on publish). */
|
|
9
|
-
sourcePath
|
|
9
|
+
sourcePath?: string;
|
|
10
10
|
};
|
|
11
11
|
/**
|
|
12
12
|
* Normalize a page's parsed markdown frontmatter into a {@link PageListObject}. Pages have no
|
|
13
13
|
* required authored fields (a bare `.md` is valid); the title falls back to a humanized last slug
|
|
14
|
-
* segment. The
|
|
15
|
-
*
|
|
14
|
+
* segment. The file location is the source of identity for filesystem and registry serving. Normal
|
|
15
|
+
* page ids match their routes; the reserved `index` id is served at `/`.
|
|
16
16
|
*/
|
|
17
17
|
export declare const normalizePageDeclaration: (raw: RawPageFrontmatter, options: NormalizePageOptions) => PageListObject;
|
|
18
18
|
export {};
|
|
@@ -9,8 +9,8 @@ const humanize = (segment) => segment
|
|
|
9
9
|
/**
|
|
10
10
|
* Normalize a page's parsed markdown frontmatter into a {@link PageListObject}. Pages have no
|
|
11
11
|
* required authored fields (a bare `.md` is valid); the title falls back to a humanized last slug
|
|
12
|
-
* segment. The
|
|
13
|
-
*
|
|
12
|
+
* segment. The file location is the source of identity for filesystem and registry serving. Normal
|
|
13
|
+
* page ids match their routes; the reserved `index` id is served at `/`.
|
|
14
14
|
*/
|
|
15
15
|
const normalizePageDeclaration = (raw, options) => {
|
|
16
16
|
var _a;
|
package/dist/config/runtime.js
CHANGED
|
@@ -6,12 +6,14 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
6
6
|
exports.toLowerCaseKeysAndValues = exports.getItemsForPath = exports.getComponentsForPath = exports.isComponentDirectory = exports.initRuntimeConfig = exports.resolveComponentDeclaration = void 0;
|
|
7
7
|
const esbuild_1 = __importDefault(require("esbuild"));
|
|
8
8
|
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
9
|
-
const gray_matter_1 = __importDefault(require("gray-matter"));
|
|
10
9
|
const module_1 = require("module");
|
|
11
10
|
const path_1 = __importDefault(require("path"));
|
|
11
|
+
const content_kinds_1 = require("../registry/content-kinds");
|
|
12
12
|
const csf_1 = require("../transformers/utils/csf");
|
|
13
13
|
const module_2 = require("../transformers/utils/module");
|
|
14
14
|
const logger_1 = require("../utils/logger");
|
|
15
|
+
const markdown_1 = require("../utils/markdown");
|
|
16
|
+
const pages_1 = require("../utils/pages");
|
|
15
17
|
const path_2 = require("../utils/path");
|
|
16
18
|
const declaration_1 = require("./normalizers/declaration");
|
|
17
19
|
const page_1 = require("./normalizers/page");
|
|
@@ -240,15 +242,16 @@ const initRuntimeConfig = (handoff) => {
|
|
|
240
242
|
// Discover markdown pages
|
|
241
243
|
// -------------------------------------------------------------------------
|
|
242
244
|
// Working pages under `<workingPath>/pages/` are first-class registry entities (publish/checkout).
|
|
243
|
-
//
|
|
244
|
-
//
|
|
245
|
+
// The root `index.md` uses the stable id `index` but is served at `/`; nested index files remain
|
|
246
|
+
// excluded because section indexes are owned by dedicated routes. Package defaults are not entities.
|
|
245
247
|
const pagesRoot = path_1.default.resolve(handoff.workingPath, 'pages');
|
|
246
|
-
for (const segments of
|
|
248
|
+
for (const segments of (0, pages_1.collectPageSlugSegments)(pagesRoot, { includeRootIndex: true })) {
|
|
247
249
|
const slug = segments.join('/');
|
|
248
250
|
const sourcePath = path_1.default.resolve(pagesRoot, `${slug}.md`);
|
|
249
251
|
try {
|
|
250
|
-
const { data: frontmatter } = (0,
|
|
251
|
-
const
|
|
252
|
+
const { data: frontmatter } = (0, markdown_1.parseMarkdown)(fs_extra_1.default.readFileSync(sourcePath, 'utf-8'));
|
|
253
|
+
const routePath = slug === content_kinds_1.HOME_PAGE_ID ? content_kinds_1.HOME_PAGE_PATH : `/${slug}`;
|
|
254
|
+
const page = (0, page_1.normalizePageDeclaration)(frontmatter, { id: slug, routePath, sourcePath });
|
|
252
255
|
result.entries.pages[page.id] = page;
|
|
253
256
|
}
|
|
254
257
|
catch (err) {
|
|
@@ -263,25 +266,6 @@ const initRuntimeConfig = (handoff) => {
|
|
|
263
266
|
return [result, Array.from(configFiles), configFileIndex];
|
|
264
267
|
};
|
|
265
268
|
exports.initRuntimeConfig = initRuntimeConfig;
|
|
266
|
-
/**
|
|
267
|
-
* Recursively collect `.md` files under a root, returning slug segments (relative path without the
|
|
268
|
-
* `.md`). `index.md` is excluded — section index content is served by dedicated/home routes.
|
|
269
|
-
*/
|
|
270
|
-
const collectPageMarkdownPaths = (rootDir, relativeParts = []) => {
|
|
271
|
-
if (!fs_extra_1.default.existsSync(rootDir))
|
|
272
|
-
return [];
|
|
273
|
-
const results = [];
|
|
274
|
-
for (const entry of fs_extra_1.default.readdirSync(rootDir)) {
|
|
275
|
-
const fullPath = path_1.default.join(rootDir, entry);
|
|
276
|
-
if (fs_extra_1.default.lstatSync(fullPath).isDirectory()) {
|
|
277
|
-
results.push(...collectPageMarkdownPaths(fullPath, [...relativeParts, entry]));
|
|
278
|
-
}
|
|
279
|
-
else if (entry.endsWith('.md') && entry !== 'index.md') {
|
|
280
|
-
results.push([...relativeParts, entry.replace(/\.md$/, '')]);
|
|
281
|
-
}
|
|
282
|
-
}
|
|
283
|
-
return results;
|
|
284
|
-
};
|
|
285
269
|
/**
|
|
286
270
|
* True when `searchPath` is itself a single component directory: it holds a declaration file named
|
|
287
271
|
* after the directory (`{dirname}.handoff.*`, or a legacy `{dirname}.{json,js,cjs}`). This is what
|