handoff-app 2.0.0-5 → 2.0.0-7

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.
Files changed (201) hide show
  1. package/README.md +174 -41
  2. package/UPGRADE.md +198 -0
  3. package/config/config.template.js +1 -4
  4. package/config/config.template.ts +1 -2
  5. package/dist/app-builder/build.js +11 -6
  6. package/dist/app-builder/client-config.js +1 -0
  7. package/dist/app-builder/config-diff/strategies/pattern.js +3 -3
  8. package/dist/app-builder/watchers/component.js +5 -5
  9. package/dist/app-builder/watchers/utils.d.ts +2 -3
  10. package/dist/app-builder/watchers.d.ts +8 -15
  11. package/dist/app-builder/watchers.js +53 -54
  12. package/dist/cache/build-cache.js +18 -22
  13. package/dist/catalog/define.d.ts +6 -0
  14. package/dist/catalog/define.js +72 -0
  15. package/dist/catalog/implementation.d.ts +27 -0
  16. package/dist/catalog/implementation.js +133 -0
  17. package/dist/catalog/index.d.ts +6 -0
  18. package/dist/catalog/index.js +22 -0
  19. package/dist/catalog/normalize.d.ts +16 -0
  20. package/dist/catalog/normalize.js +115 -0
  21. package/dist/catalog/previews.d.ts +18 -0
  22. package/dist/catalog/previews.js +106 -0
  23. package/dist/catalog/renderers.d.ts +43 -0
  24. package/dist/catalog/renderers.js +62 -0
  25. package/dist/catalog/types.d.ts +63 -0
  26. package/dist/cli/make.d.ts +0 -5
  27. package/dist/cli/make.js +22 -67
  28. package/dist/cli/scaffold.js +25 -33
  29. package/dist/commands/checkout/index.d.ts +7 -4
  30. package/dist/commands/checkout/index.js +9 -6
  31. package/dist/commands/compat/push-args.d.ts +2 -2
  32. package/dist/commands/index.js +0 -2
  33. package/dist/commands/publish/index.d.ts +9 -6
  34. package/dist/commands/publish/index.js +11 -8
  35. package/dist/commands/pull/index.js +1 -1
  36. package/dist/commands/push/index.js +1 -1
  37. package/dist/commands/utils.d.ts +15 -4
  38. package/dist/commands/utils.js +19 -6
  39. package/dist/config/catalog-include.d.ts +43 -0
  40. package/dist/config/catalog-include.js +203 -0
  41. package/dist/config/defaults.d.ts +2 -0
  42. package/dist/config/defaults.js +4 -1
  43. package/dist/config/index.d.ts +3 -3
  44. package/dist/config/index.js +6 -5
  45. package/dist/config/loader.js +9 -1
  46. package/dist/config/runtime.d.ts +5 -6
  47. package/dist/config/runtime.js +154 -154
  48. package/dist/handlebars.d.ts +9 -0
  49. package/dist/handlebars.js +16 -0
  50. package/dist/index.d.ts +15 -4
  51. package/dist/index.js +29 -15
  52. package/dist/pattern.d.ts +7 -0
  53. package/dist/pattern.js +13 -0
  54. package/dist/react.d.ts +43 -0
  55. package/dist/react.js +11 -0
  56. package/dist/registry/asset-storage/define.d.ts +1 -1
  57. package/dist/registry/asset-storage/define.js +1 -1
  58. package/dist/registry/checkout/index.d.ts +9 -0
  59. package/dist/registry/checkout/index.js +335 -149
  60. package/dist/registry/db/schema.d.ts +34 -0
  61. package/dist/registry/db/schema.js +2 -0
  62. package/dist/registry/publish/index.d.ts +13 -2
  63. package/dist/registry/publish/index.js +109 -25
  64. package/dist/registry/publish/package.js +14 -1
  65. package/dist/registry/selection.d.ts +20 -0
  66. package/dist/registry/selection.js +37 -1
  67. package/dist/store/filesystem.d.ts +1 -1
  68. package/dist/store/filesystem.js +7 -7
  69. package/dist/store/registry.js +24 -3
  70. package/dist/transformers/plugins/csf-render.js +4 -2
  71. package/dist/transformers/plugins/ssr-render.js +14 -5
  72. package/dist/transformers/preview/component/api.d.ts +8 -0
  73. package/dist/transformers/preview/component/api.js +11 -15
  74. package/dist/transformers/preview/component/artifacts.d.ts +1 -1
  75. package/dist/transformers/preview/component/artifacts.js +11 -7
  76. package/dist/transformers/preview/component/builder.js +15 -18
  77. package/dist/transformers/preview/component/css.d.ts +2 -0
  78. package/dist/transformers/preview/component/css.js +8 -11
  79. package/dist/transformers/preview/component/html.js +18 -16
  80. package/dist/transformers/preview/component/javascript.js +2 -4
  81. package/dist/transformers/preview/pattern/builder.js +31 -18
  82. package/dist/transformers/preview/types.d.ts +15 -1
  83. package/dist/types/config.d.ts +36 -11
  84. package/docs/api.md +3 -0
  85. package/docs/cli.md +1 -1
  86. package/drizzle/0006_add_component_source_format.sql +3 -0
  87. package/drizzle/meta/0006_snapshot.json +1941 -0
  88. package/drizzle/meta/_journal.json +8 -1
  89. package/package.json +37 -2
  90. package/src/app/components/Component/Preview.tsx +36 -50
  91. package/src/app/components/CopyToClipboard.tsx +27 -26
  92. package/src/app/components/Layout/Header.tsx +4 -12
  93. package/src/app/components/Layout/RuntimeModeBadge.tsx +18 -0
  94. package/src/app/components/Markdown/CodeHighlight.tsx +73 -70
  95. package/src/app/components/McpIntegration/McpConfigDialog.tsx +349 -0
  96. package/src/app/components/McpIntegration/McpIcon.tsx +10 -0
  97. package/src/app/components/Navigation/MobileNav.tsx +3 -1
  98. package/src/app/components/context/PreviewContext.tsx +5 -5
  99. package/src/app/components/ui/dialog.tsx +73 -0
  100. package/src/app/components/util/index.ts +7 -15
  101. package/src/app/lib/docs-api/backend.ts +5 -1
  102. package/src/app/lib/docs-api/page-discovery.ts +1 -6
  103. package/src/app/lib/docs-api/page-rendering.ts +21 -1
  104. package/src/app/lib/docs-api/records.ts +25 -10
  105. package/src/app/lib/docs-api/registry.ts +4 -2
  106. package/src/app/lib/docs-api/runtime-config.ts +5 -0
  107. package/src/app/lib/docs-api/search.ts +7 -2
  108. package/src/app/lib/mcp/auth.ts +64 -0
  109. package/src/app/lib/mcp/index.ts +2 -0
  110. package/src/app/lib/mcp/server.ts +343 -0
  111. package/src/app/lib/mcp/shape.ts +596 -0
  112. package/src/app/lib/registry-api/transfer.ts +7 -5
  113. package/src/app/next.config.mjs +3 -0
  114. package/src/app/pages/[...slug]/index.tsx +16 -30
  115. package/src/app/pages/api/mcp.ts +56 -0
  116. package/src/app/pages/index.tsx +10 -9
  117. package/src/app-builder/build.ts +12 -8
  118. package/src/app-builder/client-config.ts +2 -1
  119. package/src/app-builder/config-diff/strategies/pattern.ts +1 -1
  120. package/src/app-builder/watchers/component.ts +3 -3
  121. package/src/app-builder/watchers/utils.ts +2 -3
  122. package/src/app-builder/watchers.ts +46 -50
  123. package/src/cache/build-cache.ts +11 -14
  124. package/src/catalog/README.md +92 -0
  125. package/src/catalog/define.ts +79 -0
  126. package/src/catalog/implementation.ts +145 -0
  127. package/src/catalog/index.ts +31 -0
  128. package/src/catalog/normalize.ts +143 -0
  129. package/src/catalog/previews.ts +111 -0
  130. package/src/catalog/renderers.ts +94 -0
  131. package/src/catalog/types.ts +74 -0
  132. package/src/cli/README.md +1 -1
  133. package/src/cli/make.ts +20 -72
  134. package/src/cli/scaffold.ts +25 -31
  135. package/src/commands/README.md +1 -1
  136. package/src/commands/checkout/index.ts +17 -7
  137. package/src/commands/compat/push-args.ts +2 -2
  138. package/src/commands/index.ts +0 -2
  139. package/src/commands/publish/index.ts +19 -9
  140. package/src/commands/pull/index.ts +2 -2
  141. package/src/commands/push/index.ts +2 -2
  142. package/src/commands/utils.ts +22 -7
  143. package/src/config/README.md +2 -1
  144. package/src/config/catalog-include.ts +227 -0
  145. package/src/config/defaults.ts +3 -0
  146. package/src/config/index.ts +4 -4
  147. package/src/config/loader.ts +12 -0
  148. package/src/config/runtime.ts +186 -191
  149. package/src/handlebars.ts +18 -0
  150. package/src/index.ts +39 -26
  151. package/src/pattern.ts +14 -0
  152. package/src/react.ts +52 -0
  153. package/src/registry/asset-storage/define.ts +1 -1
  154. package/src/registry/checkout/index.ts +416 -152
  155. package/src/registry/db/schema.ts +2 -0
  156. package/src/registry/publish/index.ts +123 -26
  157. package/src/registry/publish/package.ts +14 -1
  158. package/src/registry/selection.ts +44 -0
  159. package/src/store/filesystem.ts +4 -4
  160. package/src/store/registry.ts +13 -2
  161. package/src/transformers/plugins/csf-render.ts +4 -2
  162. package/src/transformers/plugins/ssr-render.ts +15 -5
  163. package/src/transformers/preview/component/api.ts +13 -1
  164. package/src/transformers/preview/component/artifacts.ts +8 -4
  165. package/src/transformers/preview/component/builder.ts +17 -4
  166. package/src/transformers/preview/component/css.ts +6 -10
  167. package/src/transformers/preview/component/html.ts +30 -19
  168. package/src/transformers/preview/component/javascript.ts +1 -3
  169. package/src/transformers/preview/pattern/builder.ts +33 -20
  170. package/src/transformers/preview/types.ts +15 -1
  171. package/src/types/config.ts +38 -11
  172. package/templates/default/README.md.tpl +10 -0
  173. package/templates/default/components/button/button.react.handoff.js.tpl +19 -23
  174. package/templates/default/components/button/button.react.handoff.ts.tpl +22 -22
  175. package/templates/default/handoff.config.js.tpl +11 -18
  176. package/templates/default/handoff.config.ts.tpl +11 -18
  177. package/templates/default/handoff.config.with-examples.js.tpl +12 -16
  178. package/templates/default/handoff.config.with-examples.ts.tpl +12 -16
  179. package/config/templates/component/template.json +0 -49
  180. package/config/templates/template.html +0 -7
  181. package/dist/commands/make/template.d.ts +0 -8
  182. package/dist/commands/make/template.js +0 -43
  183. package/dist/config/entries.d.ts +0 -47
  184. package/dist/config/entries.js +0 -162
  185. package/dist/config/normalizers/declaration.d.ts +0 -11
  186. package/dist/config/normalizers/declaration.js +0 -122
  187. package/dist/config/normalizers/pattern.d.ts +0 -8
  188. package/dist/config/normalizers/pattern.js +0 -41
  189. package/dist/declarations/helpers.d.ts +0 -6
  190. package/dist/declarations/helpers.js +0 -19
  191. package/dist/declarations/index.d.ts +0 -2
  192. package/dist/declarations/index.js +0 -9
  193. package/dist/declarations/types.d.ts +0 -60
  194. package/src/commands/make/template.ts +0 -46
  195. package/src/config/entries.ts +0 -175
  196. package/src/config/normalizers/declaration.ts +0 -179
  197. package/src/config/normalizers/pattern.ts +0 -59
  198. package/src/declarations/helpers.ts +0 -36
  199. package/src/declarations/index.ts +0 -19
  200. package/src/declarations/types.ts +0 -70
  201. /package/dist/{declarations → catalog}/types.js +0 -0
@@ -40,7 +40,7 @@ const p = __importStar(require("@clack/prompts"));
40
40
  const chalk_1 = __importDefault(require("chalk"));
41
41
  const fs_extra_1 = __importDefault(require("fs-extra"));
42
42
  const path_1 = __importDefault(require("path"));
43
- const entries_1 = require("../config/entries");
43
+ const catalog_include_1 = require("../config/catalog-include");
44
44
  // Constants
45
45
  const COMPONENTS_DIR = 'components';
46
46
  const DEFAULT_GROUPS = [
@@ -63,49 +63,41 @@ const toTitleCase = (str) => {
63
63
  * Generate the component JS stub content
64
64
  */
65
65
  const generateComponentStub = (config) => {
66
+ // `implementation` names the source, so `entries` carries only supporting files.
66
67
  const entriesLines = [];
67
- if (config.generateTsx) {
68
- entriesLines.push(` component: './${config.name}.tsx',`);
69
- }
70
- else {
71
- entriesLines.push(` template: './${config.name}.hbs',`);
72
- }
73
68
  if (config.generateScss) {
74
69
  entriesLines.push(` scss: './${config.name}.scss',`);
75
70
  }
71
+ const entriesBlock = entriesLines.length ? `\n entries: {\n${entriesLines.join('\n')}\n },` : '';
76
72
  const commonMetadata = ` id: "${config.name}",
77
73
  name: "${config.title}",
78
74
  description: "${config.description}",
79
75
  group: "${config.group}",
80
76
  type: "element",
81
77
  figmaComponentId: "${config.name}",`;
78
+ const previewExport = `
79
+ exports.Default = {
80
+ args: {},
81
+ };
82
+ `;
82
83
  if (config.generateTsx) {
83
- return `const { defineReactComponent } = require('handoff-app');
84
- const ${toTitleCase(config.name).replace(/\s/g, '')} = require('./${config.name}').default;
84
+ const identifier = toTitleCase(config.name).replace(/\s/g, '');
85
+ return `const { defineCatalogItem } = require('handoff-app/react');
86
+ const ${identifier} = require('./${config.name}').default;
85
87
 
86
- module.exports = defineReactComponent(${toTitleCase(config.name).replace(/\s/g, '')}, {
88
+ exports.default = defineCatalogItem({
87
89
  ${commonMetadata}
88
- entries: {
89
- ${entriesLines.join('\n')}
90
- },
91
- previews: {
92
- default: { title: "Default", args: {} }
93
- }
90
+ implementation: ${identifier},${entriesBlock}
94
91
  });
95
- `;
92
+ ${previewExport}`;
96
93
  }
97
- return `const { defineHandlebarsComponent } = require('handoff-app');
94
+ return `const { defineCatalogItem } = require('handoff-app/handlebars');
98
95
 
99
- module.exports = defineHandlebarsComponent({
96
+ exports.default = defineCatalogItem({
100
97
  ${commonMetadata}
101
- entries: {
102
- ${entriesLines.join('\n')}
103
- },
104
- previews: {
105
- default: { title: "Default", args: {} }
106
- }
98
+ implementation: './${config.name}.hbs',${entriesBlock}
107
99
  });
108
- `;
100
+ ${previewExport}`;
109
101
  };
110
102
  /**
111
103
  * Generate a basic React component stub with variant props
@@ -179,8 +171,8 @@ const getFigmaComponents = (handoff) => __awaiter(void 0, void 0, void 0, functi
179
171
  * Get list of registered component IDs from runtime config
180
172
  */
181
173
  const getRegisteredComponentIds = (handoff) => {
182
- var _a, _b;
183
- const components = ((_b = (_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entries) === null || _b === void 0 ? void 0 : _b.components) || {};
174
+ var _a;
175
+ const components = ((_a = handoff.runtimeConfig) === null || _a === void 0 ? void 0 : _a.entities.components) || {};
184
176
  return Object.keys(components);
185
177
  };
186
178
  /**
@@ -385,22 +377,22 @@ const runScaffold = (handoff) => __awaiter(void 0, void 0, void 0, function* ()
385
377
  console.log(chalk_1.default.dim(` ${relativePath}`));
386
378
  }
387
379
  // Update config if requested. Components already covered by a collection directory auto-load,
388
- // so we only write the uncovered ones into entries.components.
380
+ // so we only write the unlisted ones into catalog.include.
389
381
  if (updateConfig) {
390
382
  const componentDirs = componentNames.map((name) => path_1.default.resolve(handoff.workingPath, COMPONENTS_DIR, name));
391
- const uncovered = componentDirs.filter((dir) => !(0, entries_1.isEntryCovered)(handoff, 'components', dir));
392
- if (uncovered.length === 0) {
383
+ const unlisted = componentDirs.filter((dir) => !(0, catalog_include_1.isIncluded)(handoff, dir));
384
+ if (unlisted.length === 0) {
393
385
  p.log.info(`Config already covers these components - they'll auto-load`);
394
386
  }
395
387
  else {
396
- const result = yield (0, entries_1.writeEntries)(handoff, 'components', uncovered);
388
+ const result = yield (0, catalog_include_1.addToCatalog)(handoff, unlisted);
397
389
  if (result.status === 'added') {
398
390
  const configFileName = result.configPath ? path_1.default.basename(result.configPath) : 'handoff.config.json';
399
391
  p.log.success(`Updated ${configFileName} with component paths`);
400
392
  }
401
393
  else {
402
394
  const where = result.configPath ? path_1.default.relative(handoff.workingPath, result.configPath) : 'handoff.config';
403
- p.log.warn(`Could not automatically update ${where}. Please manually add these paths to entries.components:`);
395
+ p.log.warn(`Could not automatically update ${where}. Please manually add these paths to catalog.include:`);
404
396
  for (const rel of result.pending) {
405
397
  console.log(chalk_1.default.yellow(` '${rel}'`));
406
398
  }
@@ -6,10 +6,13 @@ export interface CheckoutArgs extends SharedArgs {
6
6
  id?: string[];
7
7
  }
8
8
  /**
9
- * `handoff-app checkout <components|patterns|pages> [id...]` pulls entities from the connected
10
- * registry into this workspace, writing their source files in standard authoring form and
11
- * synthesizing local declarations. Pass ids to pull only those entities, or omit them for every
12
- * published entity of that kind.
9
+ * `handoff-app checkout <catalog|pages> [id...]` pulls entities from the connected registry into this
10
+ * workspace, writing their source files in standard authoring form and synthesizing local
11
+ * declarations. Pass ids to pull only those entities, or omit them for every published entity of that
12
+ * kind.
13
+ *
14
+ * `catalog` covers every published catalog item. The lane an item was published into is looked up in
15
+ * the registry, so an id is enough and no lane is named here.
13
16
  *
14
17
  * `handoff-app checkout tokens [setId...]` pulls every published token set, or only the named ones,
15
18
  * reconstructing `tokens.json` and restoring the generated token files.
@@ -2,10 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("../utils");
4
4
  /**
5
- * `handoff-app checkout <components|patterns|pages> [id...]` pulls entities from the connected
6
- * registry into this workspace, writing their source files in standard authoring form and
7
- * synthesizing local declarations. Pass ids to pull only those entities, or omit them for every
8
- * published entity of that kind.
5
+ * `handoff-app checkout <catalog|pages> [id...]` pulls entities from the connected registry into this
6
+ * workspace, writing their source files in standard authoring form and synthesizing local
7
+ * declarations. Pass ids to pull only those entities, or omit them for every published entity of that
8
+ * kind.
9
+ *
10
+ * `catalog` covers every published catalog item. The lane an item was published into is looked up in
11
+ * the registry, so an id is enough and no lane is named here.
9
12
  *
10
13
  * `handoff-app checkout tokens [setId...]` pulls every published token set, or only the named ones,
11
14
  * reconstructing `tokens.json` and restoring the generated token files.
@@ -21,8 +24,8 @@ const utils_1 = require("../utils");
21
24
  */
22
25
  const command = {
23
26
  command: 'checkout <type> [id..]',
24
- describe: 'Pull components, patterns, pages, design tokens, or assets from the connected registry into this workspace',
25
- builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getCheckoutOptions)(yargs), 'checkout'),
27
+ describe: 'Pull catalog items, pages, design tokens, or assets from the connected registry into this workspace',
28
+ builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getCheckoutOptions)(yargs), 'checkout', utils_1.REGISTRY_TARGET_KINDS),
26
29
  handler: (args) => (0, utils_1.runRegistryCommand)(args, (handoff) => (0, utils_1.runTarget)(handoff, args.type, args.id, 'checkout')),
27
30
  };
28
31
  exports.default = command;
@@ -7,11 +7,11 @@
7
7
  * {@link Handoff.publishAll}, so no orchestration lives here.
8
8
  */
9
9
  import { type RegistryEntityKind } from '../../registry/content-kinds';
10
- import type { RegistryTargetKind } from '../utils';
10
+ import type { CompatTargetKind } from '../utils';
11
11
  import type { ContentTarget } from '../../index';
12
12
  /** The documented `push` / `pull` arguments read here. */
13
13
  export interface CompatTargetArgs {
14
- type?: RegistryTargetKind;
14
+ type?: CompatTargetKind;
15
15
  id?: string[];
16
16
  components?: string[];
17
17
  patterns?: string[];
@@ -19,7 +19,6 @@ const login_1 = __importDefault(require("./login"));
19
19
  const logout_1 = __importDefault(require("./logout"));
20
20
  const component_1 = __importDefault(require("./make/component"));
21
21
  const page_1 = __importDefault(require("./make/page"));
22
- const template_1 = __importDefault(require("./make/template"));
23
22
  const pull_1 = __importDefault(require("./pull"));
24
23
  const publish_1 = __importDefault(require("./publish"));
25
24
  const push_1 = require("./push");
@@ -42,7 +41,6 @@ exports.commands = [
42
41
  logout_1.default,
43
42
  page_1.default,
44
43
  component_1.default,
45
- template_1.default,
46
44
  publish_1.default,
47
45
  pull_1.default,
48
46
  ...push_1.pushCommands,
@@ -6,10 +6,13 @@ export interface PublishArgs extends SharedArgs {
6
6
  id?: string[];
7
7
  }
8
8
  /**
9
- * `handoff-app publish <components|patterns|pages> [id...]` runs a fresh local build and uploads to
10
- * the connected registry. Pass ids to build and upload only those entities, or omit them to build the
11
- * kind once and upload every declared entity, skipping any whose content already matches the registry
12
- * (`--force` re-uploads everything).
9
+ * `handoff-app publish <catalog|pages> [id...]` runs a fresh local build and uploads to the connected
10
+ * registry. Pass ids to build and upload only those entities, or omit them to build the kind once and
11
+ * upload every declared entity, skipping any whose content already matches the registry (`--force`
12
+ * re-uploads everything).
13
+ *
14
+ * `catalog` covers every declared catalog item. Whether an item is stored as a component or as a
15
+ * pattern follows from its declaration, so an id is enough and no lane is named here.
13
16
  *
14
17
  * `handoff-app publish tokens [setId...]` does a fresh token build and uploads every logical token
15
18
  * set, or only the named ones (`foundation/colors`, `component/button`).
@@ -17,8 +20,8 @@ export interface PublishArgs extends SharedArgs {
17
20
  * `handoff-app publish assets [collection...]` runs a fresh build and uploads every asset collection,
18
21
  * or only the named ones (`icons`, `logos`, `fonts`).
19
22
  *
20
- * `handoff-app publish all` runs every kind in dependency order: tokens, assets, components,
21
- * patterns, then pages.
23
+ * `handoff-app publish all` runs every kind in dependency order: tokens, assets, catalog items, then
24
+ * pages.
22
25
  *
23
26
  * Available only from a connected workspace (`runtime.mode: workspace` + a configured
24
27
  * `registryConnection`), except under `--dry-run`, which reports what would be uploaded and needs no
@@ -2,10 +2,13 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  const utils_1 = require("../utils");
4
4
  /**
5
- * `handoff-app publish <components|patterns|pages> [id...]` runs a fresh local build and uploads to
6
- * the connected registry. Pass ids to build and upload only those entities, or omit them to build the
7
- * kind once and upload every declared entity, skipping any whose content already matches the registry
8
- * (`--force` re-uploads everything).
5
+ * `handoff-app publish <catalog|pages> [id...]` runs a fresh local build and uploads to the connected
6
+ * registry. Pass ids to build and upload only those entities, or omit them to build the kind once and
7
+ * upload every declared entity, skipping any whose content already matches the registry (`--force`
8
+ * re-uploads everything).
9
+ *
10
+ * `catalog` covers every declared catalog item. Whether an item is stored as a component or as a
11
+ * pattern follows from its declaration, so an id is enough and no lane is named here.
9
12
  *
10
13
  * `handoff-app publish tokens [setId...]` does a fresh token build and uploads every logical token
11
14
  * set, or only the named ones (`foundation/colors`, `component/button`).
@@ -13,8 +16,8 @@ const utils_1 = require("../utils");
13
16
  * `handoff-app publish assets [collection...]` runs a fresh build and uploads every asset collection,
14
17
  * or only the named ones (`icons`, `logos`, `fonts`).
15
18
  *
16
- * `handoff-app publish all` runs every kind in dependency order: tokens, assets, components,
17
- * patterns, then pages.
19
+ * `handoff-app publish all` runs every kind in dependency order: tokens, assets, catalog items, then
20
+ * pages.
18
21
  *
19
22
  * Available only from a connected workspace (`runtime.mode: workspace` + a configured
20
23
  * `registryConnection`), except under `--dry-run`, which reports what would be uploaded and needs no
@@ -22,8 +25,8 @@ const utils_1 = require("../utils");
22
25
  */
23
26
  const command = {
24
27
  command: 'publish <type> [id..]',
25
- describe: 'Build and publish components, patterns, pages, design tokens, or assets to the connected registry',
26
- builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getPublishOptions)(yargs), 'publish'),
28
+ describe: 'Build and publish catalog items, pages, design tokens, or assets to the connected registry',
29
+ builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getPublishOptions)(yargs), 'publish', utils_1.REGISTRY_TARGET_KINDS),
27
30
  handler: (args) => (0, utils_1.runRegistryCommand)(args, (handoff) => (0, utils_1.runTarget)(handoff, args.type, args.id, 'publish')),
28
31
  };
29
32
  exports.default = command;
@@ -7,7 +7,7 @@ const pull = {
7
7
  command: 'pull [type] [id..]',
8
8
  describe: 'Deprecated alias for checkout',
9
9
  deprecated: true,
10
- builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getCheckoutOptions)(yargs), 'checkout').options({
10
+ builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getCheckoutOptions)(yargs), 'checkout', utils_1.COMPAT_TARGET_KINDS).options({
11
11
  components: { type: 'array', string: true, description: 'Checkout only these component ids' },
12
12
  patterns: { type: 'array', string: true, description: 'Checkout only these pattern ids' },
13
13
  pages: { type: 'array', string: true, description: 'Checkout only these page slugs' },
@@ -9,7 +9,7 @@ const push = {
9
9
  command: 'push [type] [id..]',
10
10
  describe: 'Deprecated alias for publish',
11
11
  deprecated: true,
12
- builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getPublishOptions)(yargs), 'publish').options(Object.assign({ components: { type: 'array', string: true, description: 'Publish only these component ids' }, patterns: { type: 'array', string: true, description: 'Publish only these pattern ids' }, pages: { type: 'array', string: true, description: 'Publish only these page slugs' } }, (0, deprecations_1.hiddenOptions)(deprecations_1.UNSUPPORTED_PUSH_OPTIONS))),
12
+ builder: (yargs) => (0, utils_1.withTargetPositionals)((0, utils_1.getPublishOptions)(yargs), 'publish', utils_1.COMPAT_TARGET_KINDS).options(Object.assign({ components: { type: 'array', string: true, description: 'Publish only these component ids' }, patterns: { type: 'array', string: true, description: 'Publish only these pattern ids' }, pages: { type: 'array', string: true, description: 'Publish only these page slugs' } }, (0, deprecations_1.hiddenOptions)(deprecations_1.UNSUPPORTED_PUSH_OPTIONS))),
13
13
  handler: (args) => (0, utils_1.runRegistryCommand)(args, (handoff) => {
14
14
  (0, deprecations_1.warnDeprecatedCommand)('push', 'publish');
15
15
  (0, deprecations_1.warnUnsupportedOptions)(args, deprecations_1.UNSUPPORTED_PUSH_OPTIONS);
@@ -1,9 +1,20 @@
1
1
  import { Argv } from 'yargs';
2
2
  import Handoff from '../';
3
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"];
4
+ /**
5
+ * The `type` argument accepted by publish and checkout, or `all` for every kind. `catalog` covers
6
+ * every catalog item. An item's lane comes from its declaration, so the command line names items and
7
+ * never a lane.
8
+ */
9
+ export declare const REGISTRY_TARGET_KINDS: readonly ["catalog", "pages", "tokens", "assets", "all"];
6
10
  export type RegistryTargetKind = (typeof REGISTRY_TARGET_KINDS)[number];
11
+ /**
12
+ * The `type` argument accepted by the deprecated `push` / `pull` aliases: the plural content kinds the
13
+ * published docs name. This list keeps `components` and `patterns`, which the canonical commands do
14
+ * not take, and omits `catalog`, which the docs do not describe.
15
+ */
16
+ export declare const COMPAT_TARGET_KINDS: readonly ["components", "patterns", "pages", "tokens", "assets", "all"];
17
+ export type CompatTargetKind = (typeof COMPAT_TARGET_KINDS)[number];
7
18
  export declare const createHandoff: (args: SharedArgs) => Handoff;
8
19
  /**
9
20
  * Run a registry command against a fresh Handoff. Registry failures are the user's to act on, so they
@@ -83,8 +94,8 @@ export declare const getCheckoutOptions: (yargs: Argv) => Argv<import("yargs").O
83
94
  * `choices` is always declared: yargs allows an omitted optional positional while still rejecting an
84
95
  * unrecognized one, so the deprecated commands get the same guard as the canonical ones.
85
96
  */
86
- export declare const withTargetPositionals: (yargs: Argv, verb: "publish" | "checkout") => Argv<{
87
- type: "pages" | "components" | "patterns" | "assets" | "tokens" | "all";
97
+ export declare const withTargetPositionals: <TKind extends string>(yargs: Argv, verb: "publish" | "checkout", choices: readonly TKind[]) => Argv<{
98
+ type: (unknown extends TKind ? true : false) extends false ? TKind : unknown;
88
99
  } & {
89
100
  id: string[];
90
101
  }>;
@@ -12,12 +12,22 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
12
12
  return (mod && mod.__esModule) ? mod : { "default": mod };
13
13
  };
14
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;
15
+ exports.runTarget = exports.withTargetPositionals = exports.getCheckoutOptions = exports.getPublishOptions = exports.getSharedOptions = exports.runRegistryCommand = exports.createHandoff = exports.COMPAT_TARGET_KINDS = exports.REGISTRY_TARGET_KINDS = void 0;
16
16
  const __1 = __importDefault(require("../"));
17
17
  const content_kinds_1 = require("../registry/content-kinds");
18
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'];
19
+ /**
20
+ * The `type` argument accepted by publish and checkout, or `all` for every kind. `catalog` covers
21
+ * every catalog item. An item's lane comes from its declaration, so the command line names items and
22
+ * never a lane.
23
+ */
24
+ exports.REGISTRY_TARGET_KINDS = ['catalog', 'pages', 'tokens', 'assets', 'all'];
25
+ /**
26
+ * The `type` argument accepted by the deprecated `push` / `pull` aliases: the plural content kinds the
27
+ * published docs name. This list keeps `components` and `patterns`, which the canonical commands do
28
+ * not take, and omits `catalog`, which the docs do not describe.
29
+ */
30
+ exports.COMPAT_TARGET_KINDS = [...content_kinds_1.REGISTRY_ENTITY_KINDS, 'all'];
21
31
  const createHandoff = (args) => new __1.default({
22
32
  debug: args.debug,
23
33
  force: args.force,
@@ -88,14 +98,14 @@ exports.getCheckoutOptions = getCheckoutOptions;
88
98
  * `choices` is always declared: yargs allows an omitted optional positional while still rejecting an
89
99
  * unrecognized one, so the deprecated commands get the same guard as the canonical ones.
90
100
  */
91
- const withTargetPositionals = (yargs, verb) => yargs
101
+ const withTargetPositionals = (yargs, verb, choices) => yargs
92
102
  .positional('type', {
93
103
  describe: `The kind of content to ${verb}, or "all" for every kind`,
94
- choices: exports.REGISTRY_TARGET_KINDS,
104
+ choices,
95
105
  type: 'string',
96
106
  })
97
107
  .positional('id', {
98
- describe: `The stable id (component/pattern/page id, token set id, or asset collection); omit to ${verb} all of that kind`,
108
+ describe: `The stable id (catalog item id, page id, token set id, or asset collection); omit to ${verb} all of that kind`,
99
109
  type: 'string',
100
110
  array: true,
101
111
  });
@@ -105,6 +115,9 @@ const runTarget = (handoff, type, ids, verb) => {
105
115
  if (type === 'all') {
106
116
  return verb === 'publish' ? handoff.publishAll() : handoff.checkoutAll();
107
117
  }
118
+ if (type === 'catalog') {
119
+ return verb === 'publish' ? handoff.publishCatalog(ids) : handoff.checkoutCatalog(ids);
120
+ }
108
121
  return verb === 'publish' ? handoff.publishKind(type, ids) : handoff.checkoutKind(type, ids);
109
122
  };
110
123
  exports.runTarget = runTarget;
@@ -0,0 +1,43 @@
1
+ /**
2
+ * Registering catalog directories in the handoff config. Both scaffolding new item stubs and
3
+ * checking entities out of a registry need a freshly-written entity to be discoverable by the
4
+ * workspace build, so both have to handle every way a path can be declared:
5
+ *
6
+ * - a collection directory (e.g. `"components"`) whose subdirectories are entities: a new sibling
7
+ * is auto-discovered at runtime, so nothing needs writing to the config;
8
+ * - an individual entity directory (e.g. `"components/button"`): the entity stays invisible until
9
+ * its own path is added to the list.
10
+ *
11
+ * A workspace registers items under `catalog.include`. Discovery expands collection directories;
12
+ * the writer appends unlisted paths in JSON, TypeScript, JavaScript, and CommonJS project configs.
13
+ */
14
+ import { Config } from '../types/config';
15
+ /** Minimal handoff shape needed here; avoids importing the full Handoff class (circular dep). */
16
+ interface ConfigContext {
17
+ config?: Config;
18
+ workingPath: string;
19
+ }
20
+ /** Outcome of {@link addToCatalog}: `added` on success, `unsupported` when the config couldn't be edited. */
21
+ export interface AddToCatalogResult {
22
+ status: 'added' | 'unsupported';
23
+ /** The config file written (or that would need editing); null only when none exists and creation failed. */
24
+ configPath: string | null;
25
+ /** Workspace-relative POSIX paths written into the config. */
26
+ added: string[];
27
+ /** Workspace-relative POSIX paths the caller must add manually (`status: 'unsupported'`). */
28
+ pending: string[];
29
+ }
30
+ /**
31
+ * True when `targetDir` already loads through an existing declaration: listed directly, or sitting
32
+ * under a declared collection directory that runtime discovery expands. Reuses the same expansion
33
+ * the runtime uses, so every declaration style is covered.
34
+ */
35
+ export declare const isIncluded: (handoff: ConfigContext, targetDir: string) => boolean;
36
+ /**
37
+ * Add `targetDirs` to the config so the build discovers them. Callers should first drop
38
+ * already-loading dirs via {@link isIncluded}. Paths are stored workspace-relative; a `.json`
39
+ * config is edited losslessly, a code config best-effort. When no config file exists a minimal
40
+ * `handoff.config.json` is created.
41
+ */
42
+ export declare const addToCatalog: (handoff: ConfigContext, targetDirs: string[]) => Promise<AddToCatalogResult>;
43
+ export {};
@@ -0,0 +1,203 @@
1
+ "use strict";
2
+ /**
3
+ * Registering catalog directories in the handoff config. Both scaffolding new item stubs and
4
+ * checking entities out of a registry need a freshly-written entity to be discoverable by the
5
+ * workspace build, so both have to handle every way a path can be declared:
6
+ *
7
+ * - a collection directory (e.g. `"components"`) whose subdirectories are entities: a new sibling
8
+ * is auto-discovered at runtime, so nothing needs writing to the config;
9
+ * - an individual entity directory (e.g. `"components/button"`): the entity stays invisible until
10
+ * its own path is added to the list.
11
+ *
12
+ * A workspace registers items under `catalog.include`. Discovery expands collection directories;
13
+ * the writer appends unlisted paths in JSON, TypeScript, JavaScript, and CommonJS project configs.
14
+ */
15
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
16
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
17
+ return new (P || (P = Promise))(function (resolve, reject) {
18
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
19
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
20
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
21
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
22
+ });
23
+ };
24
+ var __importDefault = (this && this.__importDefault) || function (mod) {
25
+ return (mod && mod.__esModule) ? mod : { "default": mod };
26
+ };
27
+ Object.defineProperty(exports, "__esModule", { value: true });
28
+ exports.addToCatalog = exports.isIncluded = void 0;
29
+ const fs_extra_1 = __importDefault(require("fs-extra"));
30
+ const path_1 = __importDefault(require("path"));
31
+ const path_2 = require("../utils/path");
32
+ const runtime_1 = require("./runtime");
33
+ /** Config files in precedence order; the first that exists is the one we mutate. */
34
+ const CONFIG_FILES = ['handoff.config.ts', 'handoff.config.js', 'handoff.config.cjs', 'handoff.config.json'];
35
+ /** Workspace-relative, POSIX-separated path, as stored in `catalog.include`. */
36
+ const toIncludePath = (handoff, targetDir) => path_1.default.relative(handoff.workingPath, targetDir).split(path_1.default.sep).join('/');
37
+ const includedPaths = (handoff) => { var _a, _b, _c; return (_c = (_b = (_a = handoff.config) === null || _a === void 0 ? void 0 : _a.catalog) === null || _b === void 0 ? void 0 : _b.include) !== null && _c !== void 0 ? _c : []; };
38
+ /**
39
+ * True when `targetDir` already loads through an existing declaration: listed directly, or sitting
40
+ * under a declared collection directory that runtime discovery expands. Reuses the same expansion
41
+ * the runtime uses, so every declaration style is covered.
42
+ */
43
+ const isIncluded = (handoff, targetDir) => {
44
+ const configured = includedPaths(handoff);
45
+ if (!configured.length) {
46
+ return false;
47
+ }
48
+ return configured
49
+ .flatMap((included) => (0, runtime_1.getComponentsForPath)(path_1.default.resolve(handoff.workingPath, included)))
50
+ .some((dir) => (0, path_2.arePathsEqual)(dir, targetDir));
51
+ };
52
+ exports.isIncluded = isIncluded;
53
+ /** Format the path list as source, matching the surrounding indentation of a code config. */
54
+ const formatPathArray = (paths, indent) => {
55
+ if (paths.length === 0)
56
+ return '[]';
57
+ if (paths.length === 1)
58
+ return `['${paths[0]}']`;
59
+ return `[\n${paths.map((relPath) => `${indent}'${relPath}',`).join('\n')}\n${indent.slice(2)}]`;
60
+ };
61
+ /** Append paths to a structured `.json` config (lossless read/modify/write). */
62
+ const addToJsonConfig = (configPath, relPaths) => __awaiter(void 0, void 0, void 0, function* () {
63
+ var _a;
64
+ try {
65
+ const config = yield fs_extra_1.default.readJSON(configPath);
66
+ config.catalog = (_a = config.catalog) !== null && _a !== void 0 ? _a : {};
67
+ const parent = config.catalog;
68
+ const existing = Array.isArray(parent.include) ? parent.include : [];
69
+ const existingSet = new Set(existing);
70
+ for (const relPath of relPaths) {
71
+ if (!existingSet.has(relPath))
72
+ existing.push(relPath);
73
+ }
74
+ parent.include = existing;
75
+ yield fs_extra_1.default.writeJSON(configPath, config, { spaces: 2 });
76
+ return true;
77
+ }
78
+ catch (_b) {
79
+ return false;
80
+ }
81
+ });
82
+ /**
83
+ * Blanks out comment regions while keeping every index in place, so a match found here points at
84
+ * the same offset in the original source. A project config often carries a commented-out `catalog`
85
+ * example, and a plain search would rewrite that comment instead of the live code.
86
+ */
87
+ const maskComments = (content) => content
88
+ .replace(/\/\*[\s\S]*?\*\//g, (comment) => ' '.repeat(comment.length))
89
+ .replace(/(^|[^:])\/\/[^\n]*/g, (comment, prefix) => prefix + ' '.repeat(comment.length - prefix.length));
90
+ /** Index of the brace closing the one at `openIndex`, or -1. */
91
+ const findMatchingBrace = (source, openIndex) => {
92
+ let depth = 0;
93
+ for (let i = openIndex; i < source.length; i += 1) {
94
+ if (source[i] === '{')
95
+ depth += 1;
96
+ if (source[i] === '}') {
97
+ depth -= 1;
98
+ if (depth === 0)
99
+ return i;
100
+ }
101
+ }
102
+ return -1;
103
+ };
104
+ /** Locates `parent: { key: [ ... ] }` in a code config, ignoring commented-out examples. */
105
+ const locateList = (masked) => {
106
+ const parentMatch = new RegExp(`(^|[\\s{,;])catalog\\s*:\\s*\\{`, 'm').exec(masked);
107
+ if (!parentMatch)
108
+ return undefined;
109
+ const parentBrace = masked.indexOf('{', parentMatch.index + parentMatch[0].length - 1);
110
+ const parentClose = findMatchingBrace(masked, parentBrace);
111
+ if (parentClose < 0)
112
+ return { parentBrace };
113
+ const block = masked.slice(parentBrace, parentClose + 1);
114
+ const keyMatch = new RegExp(`(^|[\\s{,])include\\s*:\\s*\\[`).exec(block);
115
+ if (!keyMatch)
116
+ return { parentBrace };
117
+ const listStart = parentBrace + block.indexOf('[', keyMatch.index);
118
+ const listEnd = masked.indexOf(']', listStart);
119
+ if (listEnd < 0)
120
+ return { parentBrace };
121
+ return { parentBrace, listStart, listEnd };
122
+ };
123
+ /**
124
+ * Best-effort splice of paths into an executable `.ts` / `.js` / `.cjs` config. These are
125
+ * modules, not data, so there's no lossless structured write; if a computed or spread list can't be
126
+ * edited textually, the caller falls back to printing the paths for the user to add.
127
+ */
128
+ const addToCodeConfig = (configPath, relPaths) => __awaiter(void 0, void 0, void 0, function* () {
129
+ try {
130
+ const content = yield fs_extra_1.default.readFile(configPath, 'utf8');
131
+ const masked = maskComments(content);
132
+ const arrayBlock = formatPathArray(relPaths, ' ');
133
+ const location = locateList(masked);
134
+ // 1) The list already exists, so merge into it.
135
+ if ((location === null || location === void 0 ? void 0 : location.listStart) !== undefined && location.listEnd !== undefined) {
136
+ const existing = content
137
+ .slice(location.listStart + 1, location.listEnd)
138
+ .split(',')
139
+ .map((listed) => listed.trim().replace(/['"]/g, ''))
140
+ .filter(Boolean);
141
+ const existingSet = new Set(existing);
142
+ const toAdd = relPaths.filter((relPath) => !existingSet.has(relPath));
143
+ if (toAdd.length > 0) {
144
+ const indentMatch = /\[\s*\n(\s*)/.exec(content.slice(location.listStart));
145
+ const indent = indentMatch ? indentMatch[1] : ' ';
146
+ const merged = formatPathArray([...existing, ...toAdd], indent);
147
+ yield fs_extra_1.default.writeFile(configPath, content.slice(0, location.listStart) + merged + content.slice(location.listEnd + 1), 'utf8');
148
+ }
149
+ return true;
150
+ }
151
+ // 2) The parent object exists but not this key, so add the key.
152
+ if (location) {
153
+ const insertAt = location.parentBrace + 1;
154
+ yield fs_extra_1.default.writeFile(configPath, `${content.slice(0, insertAt)}\n include: ${arrayBlock},${content.slice(insertAt)}`, 'utf8');
155
+ return true;
156
+ }
157
+ // 3) No parent object, so insert one into the exported config object.
158
+ const parentBlock = ` catalog: {\n include: ${arrayBlock},\n },\n`;
159
+ for (const anchor of [/module\.exports\s*=\s*\{/, /export\s+default\s+\{/, /defineConfig\s*\(\s*\{/]) {
160
+ const anchorMatch = anchor.exec(masked);
161
+ if (anchorMatch) {
162
+ const insertAt = anchorMatch.index + anchorMatch[0].length;
163
+ yield fs_extra_1.default.writeFile(configPath, `${content.slice(0, insertAt)}\n${parentBlock}${content.slice(insertAt)}`, 'utf8');
164
+ return true;
165
+ }
166
+ }
167
+ return false;
168
+ }
169
+ catch (_a) {
170
+ return false;
171
+ }
172
+ });
173
+ /**
174
+ * Add `targetDirs` to the config so the build discovers them. Callers should first drop
175
+ * already-loading dirs via {@link isIncluded}. Paths are stored workspace-relative; a `.json`
176
+ * config is edited losslessly, a code config best-effort. When no config file exists a minimal
177
+ * `handoff.config.json` is created.
178
+ */
179
+ const addToCatalog = (handoff, targetDirs) => __awaiter(void 0, void 0, void 0, function* () {
180
+ const relPaths = [...new Set(targetDirs.map((dir) => toIncludePath(handoff, dir)))];
181
+ const configFile = CONFIG_FILES.find((file) => fs_extra_1.default.existsSync(path_1.default.resolve(handoff.workingPath, file)));
182
+ const configPath = configFile ? path_1.default.resolve(handoff.workingPath, configFile) : null;
183
+ if (relPaths.length === 0) {
184
+ return { status: 'added', configPath, added: [], pending: [] };
185
+ }
186
+ if (!configPath) {
187
+ const newConfigPath = path_1.default.resolve(handoff.workingPath, 'handoff.config.json');
188
+ try {
189
+ yield fs_extra_1.default.writeJSON(newConfigPath, { catalog: { include: relPaths } }, { spaces: 2 });
190
+ return { status: 'added', configPath: newConfigPath, added: relPaths, pending: [] };
191
+ }
192
+ catch (_a) {
193
+ return { status: 'unsupported', configPath: null, added: [], pending: relPaths };
194
+ }
195
+ }
196
+ const ok = configPath.endsWith('.json')
197
+ ? yield addToJsonConfig(configPath, relPaths)
198
+ : yield addToCodeConfig(configPath, relPaths);
199
+ return ok
200
+ ? { status: 'added', configPath, added: relPaths, pending: [] }
201
+ : { status: 'unsupported', configPath, added: [], pending: relPaths };
202
+ });
203
+ exports.addToCatalog = addToCatalog;
@@ -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.