@powerhousedao/shared 6.2.3-dev.30 → 6.2.3-dev.31

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 (38) hide show
  1. package/dist/clis/args/{connect-B6xK4YI_.mjs → connect-BG3HkYBk.mjs} +2 -2
  2. package/dist/clis/args/connect-BG3HkYBk.mjs.map +1 -0
  3. package/dist/clis/args/connect.mjs +1 -1
  4. package/dist/clis/args/{generate-10dooJ-D.mjs → generate-BOItUNvP.mjs} +2 -7
  5. package/dist/clis/args/generate-BOItUNvP.mjs.map +1 -0
  6. package/dist/clis/args/{generate-DmgiCzuf.d.mts → generate-BPBBLeUD.d.mts} +1 -4
  7. package/dist/clis/args/generate-BPBBLeUD.d.mts.map +1 -0
  8. package/dist/clis/args/generate.d.mts +1 -1
  9. package/dist/clis/args/generate.mjs +1 -1
  10. package/dist/clis/args/{help-yRmplJjW.mjs → help-DS1NlcJQ.mjs} +3 -3
  11. package/dist/clis/args/{help-yRmplJjW.mjs.map → help-DS1NlcJQ.mjs.map} +1 -1
  12. package/dist/clis/args/help.mjs +1 -1
  13. package/dist/clis/args/index.d.mts +1 -1
  14. package/dist/clis/args/index.mjs +3 -3
  15. package/dist/clis/build-pieces.d.mts +3 -4
  16. package/dist/clis/build-pieces.d.mts.map +1 -1
  17. package/dist/clis/build-pieces.mjs +18 -11
  18. package/dist/clis/build-pieces.mjs.map +1 -1
  19. package/dist/clis/index.d.mts +2 -6
  20. package/dist/clis/index.d.mts.map +1 -1
  21. package/dist/clis/index.mjs +4 -10
  22. package/dist/clis/index.mjs.map +1 -1
  23. package/dist/clis/types-CMFHKrgv.d.mts.map +1 -1
  24. package/dist/{config-loader-SYDWHtqk.js → config-loader-CWQxMERh.js} +12 -4
  25. package/dist/config-loader-CWQxMERh.js.map +1 -0
  26. package/dist/connect/config-loader.d.ts +8 -1
  27. package/dist/connect/config-loader.d.ts.map +1 -1
  28. package/dist/connect/config-loader.js +2 -2
  29. package/dist/connect/index.d.ts +3 -4
  30. package/dist/connect/index.d.ts.map +1 -1
  31. package/dist/connect/index.js +3 -4
  32. package/dist/connect/index.js.map +1 -1
  33. package/dist/types-xLPOHE23.d.ts.map +1 -1
  34. package/package.json +1 -1
  35. package/dist/clis/args/connect-B6xK4YI_.mjs.map +0 -1
  36. package/dist/clis/args/generate-10dooJ-D.mjs.map +0 -1
  37. package/dist/clis/args/generate-DmgiCzuf.d.mts.map +0 -1
  38. package/dist/config-loader-SYDWHtqk.js.map +0 -1
@@ -26,7 +26,7 @@ const connectRuntimeOverrideArgs = {
26
26
  json: option({
27
27
  type: optional(string),
28
28
  long: "json",
29
- description: "Inline JSON override for the runtime connect.* block, e.g. '{\"renown\":{\"url\":\"...\"}}'. Validated against the runtime schema; deep-merged on top of env seeds and source powerhouse.config.json. Individual --flag values beat --json on collision."
29
+ description: "Inline JSON override for the runtime connect.* block, without the \"connect\" wrapper, e.g. '{\"app\":{\"workflowsEnabled\":true},\"renown\":{\"url\":\"...\"}}'. A top-level packageRegistryUrl is also accepted. Validated against the runtime schema (unknown keys fail); deep-merged on top of source powerhouse.config.json. Individual --flag values beat --json on collision."
30
30
  }),
31
31
  renownUrl: option({
32
32
  type: optional(string),
@@ -200,4 +200,4 @@ const connectArgs = {
200
200
  //#endregion
201
201
  export { connectStudioArgs as a, connectPreviewArgs as i, connectBuildArgs as n, connectConfigArgs as r, connectArgs as t };
202
202
 
203
- //# sourceMappingURL=connect-B6xK4YI_.mjs.map
203
+ //# sourceMappingURL=connect-BG3HkYBk.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connect-BG3HkYBk.mjs","names":[],"sources":["../../../clis/args/connect.ts"],"sourcesContent":["import type { Type } from \"cmd-ts\";\nimport {\n boolean,\n flag,\n number,\n option,\n optional,\n positional,\n string,\n} from \"cmd-ts\";\nimport {\n DEFAULT_CONNECT_OUTDIR,\n DEFAULT_CONNECT_PREVIEW_PORT,\n DEFAULT_CONNECT_STUDIO_PORT,\n} from \"../constants.js\";\nimport {\n commonArgs,\n commonServerArgs,\n connectBasePath,\n defaultDrivesUrl,\n drivesPreserveStrategy,\n logLevel,\n renownNamespace,\n renownSwitchboardUrl,\n} from \"./common.js\";\n\n// cmd-ts's built-in `boolean` is intended for `flag()` (presence/absence). With\n// `option()` we need to parse the next argv as a value, but cmd-ts's `boolean`\n// does not coerce the string. This custom Type does.\nconst cliBoolean: Type<string, boolean> = {\n from: (input) => {\n const v = input.toLowerCase();\n if (v === \"true\") return Promise.resolve(true);\n if (v === \"false\") return Promise.resolve(false);\n return Promise.reject(\n new Error(\n `Expected 'true' or 'false' (case-insensitive), got '${input}'.`,\n ),\n );\n },\n description: \"true | false\",\n};\n\nexport const connectStudioArgs = {\n port: option({\n type: number,\n long: \"port\",\n description: \"Port to run the dev server on.\",\n defaultValue: () => DEFAULT_CONNECT_STUDIO_PORT,\n defaultValueIsSerializable: true,\n }),\n renownNamespace,\n ...commonArgs,\n ...commonServerArgs,\n};\n\n// Runtime-config override flags. Each is optional with no default — undefined\n// means \"user did not pass this flag\", so runConnectBuild can include only\n// explicitly-set values in `cliConnectOverride` and avoid clobbering source\n// `powerhouse.config.json` values when no override was intended.\n//\n// These flags occupy the top of the precedence ladder for the runtime config\n// emitted into `dist/powerhouse.config.json`:\n//\n// DEFAULT_CONNECT_CONFIG < source connect.* < --json < individual --flag\n//\n// `--json` accepts a partial `connect.*` blob (e.g. `{\"renown\":{\"url\":\"...\"}}`).\n// Individual flags merge on top of `--json` inside the same CLI layer, so they\n// win on collision. Env vars are NOT part of this build-time merge;\n// PH_CONNECT_CONFIG_JSON is applied to the dist file at container start by\n// the Docker entrypoint (operator-wins: concrete values override the baked\n// file, null/omitted keep it; connect.app.basePath excluded).\nconst connectRuntimeOverrideArgs = {\n json: option({\n type: optional(string),\n long: \"json\",\n description:\n 'Inline JSON override for the runtime connect.* block, without the \"connect\" wrapper, e.g. \\'{\"app\":{\"workflowsEnabled\":true},\"renown\":{\"url\":\"...\"}}\\'. A top-level packageRegistryUrl is also accepted. Validated against the runtime schema (unknown keys fail); deep-merged on top of source powerhouse.config.json. Individual --flag values beat --json on collision.',\n }),\n renownUrl: option({\n type: optional(string),\n long: \"renown-url\",\n description: \"Override connect.renown.url.\",\n }),\n renownNetworkId: option({\n type: optional(string),\n long: \"renown-network-id\",\n description: \"Override connect.renown.networkId.\",\n }),\n renownChainId: option({\n type: optional(number),\n long: \"renown-chain-id\",\n description: \"Override connect.renown.chainId.\",\n }),\n renownNamespace,\n renownSwitchboardUrl,\n allowAddDrive: option({\n type: optional(cliBoolean),\n long: \"allow-add-drive\",\n description:\n \"Override connect.drives.allowAddDrive (top-level add-drive toggle).\",\n }),\n externalPackages: option({\n type: optional(cliBoolean),\n long: \"external-packages\",\n description: \"Override connect.packages.externalEnabled.\",\n }),\n workflows: option({\n type: optional(cliBoolean),\n long: \"workflows\",\n description:\n \"Override connect.app.workflowsEnabled (load the @powerhousedao/workflow package: workflow + connection documents, their editors and Workflow Studio).\",\n }),\n remoteDrivesEnabled: option({\n type: optional(cliBoolean),\n long: \"remote-drives-enabled\",\n description:\n \"Override connect.drives.sections.remote.enabled (the unified cloud+public section).\",\n }),\n remoteDrivesAllowAdd: option({\n type: optional(cliBoolean),\n long: \"remote-drives-allow-add\",\n description: \"Override connect.drives.sections.remote.allowAdd.\",\n }),\n remoteDrivesAllowDelete: option({\n type: optional(cliBoolean),\n long: \"remote-drives-allow-delete\",\n description: \"Override connect.drives.sections.remote.allowDelete.\",\n }),\n localDrivesEnabled: option({\n type: optional(cliBoolean),\n long: \"local-drives-enabled\",\n description: \"Override connect.drives.sections.local.enabled.\",\n }),\n localDrivesAllowAdd: option({\n type: optional(cliBoolean),\n long: \"local-drives-allow-add\",\n description: \"Override connect.drives.sections.local.allowAdd.\",\n }),\n localDrivesAllowDelete: option({\n type: optional(cliBoolean),\n long: \"local-drives-allow-delete\",\n description: \"Override connect.drives.sections.local.allowDelete.\",\n }),\n packagesRegistry: option({\n type: optional(string),\n long: \"packages-registry\",\n description: \"Override the top-level packageRegistryUrl.\",\n }),\n appName: option({\n type: optional(string),\n long: \"app-name\",\n description: \"Override connect.branding.appName.\",\n }),\n homeBackground: option({\n type: optional(string),\n long: \"home-background\",\n description:\n 'Override connect.branding.homeBackground. URL or path to an image; pass an empty string (\"\") to reset to the bundled default.',\n }),\n sentryDsn: option({\n type: optional(string),\n long: \"sentry-dsn\",\n description:\n 'Override connect.sentry.dsn (Sentry DSN URL). Pass an empty string (\"\") to set null and disable Sentry.',\n }),\n sentryEnv: option({\n type: optional(string),\n long: \"sentry-env\",\n description: \"Override connect.sentry.env (Sentry environment label).\",\n }),\n sentryTracingEnabled: option({\n type: optional(cliBoolean),\n long: \"sentry-tracing-enabled\",\n description:\n \"Override connect.sentry.tracing (Sentry performance tracing).\",\n }),\n};\n\n// Positional pair shared by `ph connect build` and `ph connect config`. Both\n// commands accept `<key> <value>` to set a single runtime-config field; `config`\n// additionally accepts `<key>` alone for read-mode (`build` rejects the\n// 1-positional case because it has no read semantics). Both are optional in the\n// parser; the handler enforces the per-command shape.\nconst connectPositionalArgs = {\n keyPositional: positional({\n type: optional(string),\n displayName: \"key\",\n description:\n \"Dotted path inside the runtime config (e.g. connect.renown.url). Pair with <value> to set; pass alone to `ph connect config` to read.\",\n }),\n valuePositional: positional({\n type: optional(string),\n displayName: \"value\",\n description:\n \"Value to set at <key>. Coerced against the runtime schema (string, bool, number, enum). Arrays and objects require --json instead.\",\n }),\n};\n\nexport const connectBuildArgs = {\n outDir: option({\n type: string,\n long: \"outDir\",\n description: \"Output directory\",\n defaultValue: () => DEFAULT_CONNECT_OUTDIR,\n defaultValueIsSerializable: true,\n }),\n ...connectRuntimeOverrideArgs,\n ...connectPositionalArgs,\n dynamicBase: flag({\n type: optional(boolean),\n long: \"dynamic-base\",\n description:\n \"Build one bundle that serves under any subpath; base resolved at serve time from a runtime global. Overrides --base.\",\n }),\n favicon: option({\n type: optional(string),\n long: \"favicon\",\n description:\n \"Path to a favicon file (e.g. .ico) to bundle in place of the default Connect icon. Emitted as icon.ico; resolved relative to the build cwd.\",\n }),\n ...commonArgs,\n};\n\nexport const connectPreviewArgs = {\n port: option({\n type: number,\n long: \"port\",\n description: \"Port to run the preview server on.\",\n defaultValue: () => DEFAULT_CONNECT_PREVIEW_PORT,\n defaultValueIsSerializable: true,\n }),\n outDir: option({\n type: string,\n long: \"outDir\",\n description: \"Output directory\",\n defaultValue: () => DEFAULT_CONNECT_OUTDIR,\n defaultValueIsSerializable: true,\n }),\n ...commonArgs,\n ...commonServerArgs,\n};\n\n// `ph connect config` — read, set, or list the runtime config under the\n// `connect.*` block of the dist `powerhouse.config.json`.\n//\n// Mode matrix (exactly one mode per invocation; mutex enforced in\n// `runConnectConfig`):\n//\n// ph connect config → list (print effective merged config)\n// ph connect config <key> → get one value at the dotted key (positional)\n// ph connect config --get <dotted.path> → same as positional <key> (kept for backward compat)\n// ph connect config <key> <value> → set + dual-write to source + dist (positional)\n// ph connect config --<field> <value> → set + dual-write via per-field flag\n// ph connect config --json '{\"…\":\"…\"}' → bulk set + dual-write\n//\n// The 16 field flags below come from `connectRuntimeOverrideArgs`, so\n// `config` and `build` share an identical surface for runtime fields. The 4\n// flags imported individually from `common.ts` (`connectBasePath` /\n// `logLevel` / `defaultDrivesUrl` / `drivesPreserveStrategy`) extend that to\n// 20-flag coverage. The positional `<key>`/`<value>` pair is also shared with\n// `ph connect build` so both commands accept the same set-mode grammar.\n// `--dist-dir` lets Docker / non-default deployments point at a custom dist\n// location; falls back to PH_CONNECT_OUTDIR env, then to the standard\n// `.ph/connect-build/dist/` path.\n//\n// NOTE: the 4 commonArgs flags have built-in cmd-ts defaults\n// (e.g. logLevel=\"info\"), so always parse as defined. The service detects\n// \"user explicitly passed this flag\" via process.argv inspection — see\n// `clis/ph-cli/src/utils/cli-connect-override.ts:wasFlagExplicitlyPassed`.\nexport const connectConfigArgs = {\n get: option({\n type: optional(string),\n long: \"get\",\n description:\n 'Dotted path inside connect.* (e.g. \"connect.renown.url\") to read the effective value. Mutually exclusive with the set modes. Equivalent to `ph connect config <key>` (positional).',\n }),\n distDir: option({\n type: optional(string),\n long: \"dist-dir\",\n description:\n \"Path to the directory containing the dist powerhouse.config.json. Defaults to the PH_CONNECT_OUTDIR env or `.ph/connect-build/dist/`.\",\n }),\n ...connectRuntimeOverrideArgs,\n ...connectPositionalArgs,\n connectBasePath,\n logLevel,\n defaultDrivesUrl,\n drivesPreserveStrategy,\n};\n\nexport const connectArgs = {\n ...connectStudioArgs,\n ...connectBuildArgs,\n ...connectPreviewArgs,\n ...connectConfigArgs,\n};\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import { a as connectStudioArgs, i as connectPreviewArgs, n as connectBuildArgs, r as connectConfigArgs, t as connectArgs } from "./connect-B6xK4YI_.mjs";
1
+ import { a as connectStudioArgs, i as connectPreviewArgs, n as connectBuildArgs, r as connectConfigArgs, t as connectArgs } from "./connect-BG3HkYBk.mjs";
2
2
  export { connectArgs, connectBuildArgs, connectConfigArgs, connectPreviewArgs, connectStudioArgs };
@@ -91,12 +91,7 @@ const generateArgs = {
91
91
  pieceId: option({
92
92
  type: optional(string),
93
93
  long: "piece-id",
94
- description: "Piece id a workflow block type names, e.g. @acme/piece-crm. Defaults to one derived from the package name."
95
- }),
96
- pieceVersion: option({
97
- type: optional(string),
98
- long: "piece-version",
99
- description: "Version the pieces list declares for the generated piece. Defaults to the package version when the piece is named after the package."
94
+ description: "Piece id, the pieceName a workflow step holds, e.g. @acme/piece-crm. Defaults to one derived from the package name."
100
95
  }),
101
96
  pieceAuth: option({
102
97
  type: oneOf([
@@ -193,4 +188,4 @@ const generateArgs = {
193
188
  //#endregion
194
189
  export { generateArgs as t };
195
190
 
196
- //# sourceMappingURL=generate-10dooJ-D.mjs.map
191
+ //# sourceMappingURL=generate-BOItUNvP.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-BOItUNvP.mjs","names":[],"sources":["../../../processors/constants.ts","../../../clis/args/generate.ts"],"sourcesContent":["export const PROCESSOR_APPS = [\"connect\", \"switchboard\"] as const;\nexport const DEFAULT_RELATIONAL_PROCESSOR_DB_NAME = \"relational-db\";\nexport const DEFAULT_ANALYTICS_PROCESSOR_DB_NAME = \"analytics-db\";\n","import type { Type } from \"cmd-ts\";\nimport {\n array,\n boolean,\n flag,\n multioption,\n oneOf,\n option,\n optional,\n positional,\n string,\n} from \"cmd-ts\";\nimport { PROCESSOR_APPS } from \"processors\";\nimport { debugArgs } from \"./common.js\";\n\nconst ProcessorAppType: Type<string[], (\"connect\" | \"switchboard\")[]> = {\n from(processorApps) {\n if (processorApps.length === 0) {\n throw new Error(\n `No arguments provided for processor apps. Must be \"connect\" and/or \"switchboard\"`,\n );\n }\n if (processorApps.length > 2) {\n throw new Error(\n `Too many arguments provided for processor apps. Must be \"connect\" and/or \"switchboard\"`,\n );\n }\n const allowed = new Set(PROCESSOR_APPS);\n if (\n !processorApps.every((p) => allowed.has(p as \"connect\" | \"switchboard\"))\n ) {\n throw new Error(\n `Processor apps can only be \"connect\" and/or \"switchboard\".`,\n );\n }\n return Promise.resolve(processorApps as (\"connect\" | \"switchboard\")[]);\n },\n};\n\nexport const generateArgs = {\n documentModelFilePositional: positional({\n type: optional(string),\n displayName: \"document model file path\",\n description: \"Path to the document model file.\",\n }),\n documentModelFileOption: option({\n type: optional(string),\n long: \"file\",\n description: \"Path to the document model file.\",\n }),\n editorName: option({\n type: optional(string),\n long: \"editor\",\n description: \"Editor name.\",\n }),\n editorId: option({\n type: optional(string),\n long: \"editor-id\",\n description: \"Editor ID\",\n }),\n editorDirName: option({\n type: optional(string),\n long: \"editor-dir-name\",\n description:\n \"Use a different directory name for the generated editor. Default is the editor name in kebab case.\",\n }),\n documentType: option({\n type: optional(string),\n long: \"document-type\",\n description: \"Document type for the generated document editor.\",\n }),\n documentTypes: option({\n type: optional(string),\n long: \"document-types\",\n description:\n \"[DEPRECATED] Comma separated list of document types for the generated document editor. [WARNING] Generated editor code is not set up to handle multiple document types.\",\n }),\n appName: option({\n type: optional(string),\n long: \"app\",\n description: \"App name.\",\n }),\n appId: option({\n type: optional(string),\n long: \"app-id\",\n description: \"App ID.\",\n }),\n appDirName: option({\n type: optional(string),\n long: \"app-dir-name\",\n description:\n \"Use a different directory name for the generated app. Default is the app name in kebab case.\",\n }),\n processorName: option({\n type: optional(string),\n long: \"processor\",\n description: \"Processor name.\",\n }),\n processorType: option({\n type: oneOf([\"relationalDb\", \"analytics\"] as const),\n long: \"processor-type\",\n description:\n \"Whether to generate an analytics processor or a relational DB processor. Default is analytics.\",\n defaultValue: () => \"analytics\" as const,\n defaultValueIsSerializable: true,\n }),\n processorApps: multioption({\n long: \"processor-apps\",\n type: ProcessorAppType,\n description: \"The apps where the generated processor will run\",\n defaultValue: () => [\"switchboard\" as const],\n defaultValueIsSerializable: true,\n }),\n subgraphName: option({\n type: optional(string),\n long: \"subgraph\",\n description: \"Subgraph name.\",\n }),\n pieceName: option({\n type: optional(string),\n long: \"piece\",\n description: \"Piece name.\",\n }),\n pieceId: option({\n type: optional(string),\n long: \"piece-id\",\n description:\n \"Piece id, the pieceName a workflow step holds, e.g. @acme/piece-crm. Defaults to one derived from the package name.\",\n }),\n pieceAuth: option({\n type: oneOf([\"none\", \"secret\", \"custom\"] as const),\n long: \"piece-auth\",\n description:\n \"The kind of connection the generated piece asks for. Default is custom.\",\n defaultValue: () => \"custom\" as const,\n defaultValueIsSerializable: true,\n }),\n pieceActionName: option({\n type: optional(string),\n long: \"piece-action\",\n description: \"Name of an action to generate inside a piece.\",\n }),\n pieceTriggerName: option({\n type: optional(string),\n long: \"piece-trigger\",\n description: \"Name of a trigger to generate inside a piece.\",\n }),\n pieceTriggerStrategy: option({\n type: oneOf([\"polling\", \"webhook\"] as const),\n long: \"piece-trigger-strategy\",\n description: \"How a generated trigger fires. Default is polling.\",\n defaultValue: () => \"polling\" as const,\n defaultValueIsSerializable: true,\n }),\n importScriptName: option({\n type: optional(string),\n long: \"import-script\",\n description: \"Import script name.\",\n }),\n allowedDocumentTypes: multioption({\n type: optional(array(string)),\n long: \"allowed-document-types\",\n description: \"Supported document types for a app.\",\n }),\n migrationFile: option({\n type: optional(string),\n long: \"migration-file\",\n description: \"Path to the migration file.\",\n }),\n schemaFile: option({\n type: optional(string),\n long: \"schema-file\",\n description: \"Path to the output file. Defaults to './schema.ts'\",\n }),\n disableDragAndDrop: flag({\n type: optional(boolean),\n long: \"disable-drag-and-drop\",\n description: \"Disable drag and drop in the generated app.\",\n }),\n force: flag({\n type: optional(boolean),\n long: \"force\",\n short: \"f\",\n description: \"Overwrite operation reducers.\",\n }),\n verbose: flag({\n type: optional(boolean),\n long: \"logs\",\n description: \"Show additional logging information.\",\n }),\n watch: flag({\n type: optional(boolean),\n long: \"watch\",\n short: \"w\",\n description: \"Watch the generated code.\",\n }),\n skipFormat: flag({\n type: optional(boolean),\n long: \"skip-format\",\n short: \"sf\",\n description: \"Skip formatting the generated code.\",\n }),\n useVersioning: flag({\n type: boolean,\n long: \"use-versioning\",\n description: \"Allow upgrading document models with versioning.\",\n defaultValue: () => true,\n defaultValueIsSerializable: true,\n }),\n migrateLegacy: flag({\n type: boolean,\n long: \"migrate-legacy\",\n description:\n \"Migrate existing legacy document model code to versioned structure. Implies --use-versioning.\",\n defaultValue: () => false,\n defaultValueIsSerializable: true,\n }),\n ...debugArgs,\n};\n"],"mappings":"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"}
@@ -51,9 +51,6 @@ declare const generateArgs: {
51
51
  pieceId: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
52
52
  parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<string | undefined>>;
53
53
  } & import("cmd-ts/dist/cjs/helpdoc.js").ProvidesHelp & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Descriptive>;
54
- pieceVersion: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
55
- parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<string | undefined>>;
56
- } & import("cmd-ts/dist/cjs/helpdoc.js").ProvidesHelp & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Descriptive>;
57
54
  pieceAuth: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
58
55
  parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<"custom" | "none" | "secret">>;
59
56
  } & import("cmd-ts/dist/cjs/helpdoc.js").ProvidesHelp & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Descriptive>;
@@ -103,4 +100,4 @@ declare const generateArgs: {
103
100
  //#endregion
104
101
  export { generateArgs as t };
105
102
  export {};
106
- //# sourceMappingURL=generate-DmgiCzuf.d.mts.map
103
+ //# sourceMappingURL=generate-BPBBLeUD.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-BPBBLeUD.d.mts","names":[],"sources":["../../../clis/args/generate.ts"],"mappings":";cAuCa"}
@@ -1,3 +1,3 @@
1
- import { t as generateArgs } from "./generate-DmgiCzuf.mjs";
1
+ import { t as generateArgs } from "./generate-BPBBLeUD.mjs";
2
2
  export { generateArgs };
3
3
  export {};
@@ -1,2 +1,2 @@
1
- import { t as generateArgs } from "./generate-10dooJ-D.mjs";
1
+ import { t as generateArgs } from "./generate-BOItUNvP.mjs";
2
2
  export { generateArgs };
@@ -1,7 +1,7 @@
1
1
  import { o as debugArgs } from "./common-BXabdhiO.mjs";
2
2
  import { t as accessTokenArgs } from "./access-token-3Hqv_U8I.mjs";
3
- import { t as connectArgs } from "./connect-B6xK4YI_.mjs";
4
- import { t as generateArgs } from "./generate-10dooJ-D.mjs";
3
+ import { t as connectArgs } from "./connect-BG3HkYBk.mjs";
4
+ import { t as generateArgs } from "./generate-BOItUNvP.mjs";
5
5
  import { t as inspectArgs } from "./inspect-UNQgtuR0.mjs";
6
6
  import { t as installArgs } from "./install-F-27kF6m.mjs";
7
7
  import { t as listArgs } from "./list-Bkfn8Yuo.mjs";
@@ -149,4 +149,4 @@ const phCliHelpCommands = {
149
149
  //#endregion
150
150
  export { phCliCommandNames as n, phCliHelpCommands as t };
151
151
 
152
- //# sourceMappingURL=help-yRmplJjW.mjs.map
152
+ //# sourceMappingURL=help-DS1NlcJQ.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"help-yRmplJjW.mjs","names":[],"sources":["../../../clis/command-names.ts","../../../clis/args/help.ts"],"sourcesContent":["// Hardcoded so ph-cmd's dispatch doesn't have to evaluate phCliHelpCommands.\n// The compile-time guard in args/help.ts catches drift.\nexport const phCliCommandNames = [\n \"generate\",\n \"vetra\",\n \"connect\",\n \"build\",\n \"publish\",\n \"list\",\n \"l\",\n \"access-token\",\n \"registry-login\",\n \"inspect\",\n \"is\",\n \"migrate\",\n \"switchboard\",\n \"reactor\",\n \"login\",\n \"logout\",\n \"install\",\n \"add\",\n \"i\",\n \"uninstall\",\n \"remove\",\n] as const;\n","import { command } from \"cmd-ts\";\nimport type { phCliCommandNames } from \"../command-names.js\";\nimport { accessTokenArgs } from \"./access-token.js\";\nimport { debugArgs } from \"./common.js\";\nimport { connectArgs } from \"./connect.js\";\nimport { generateArgs } from \"./generate.js\";\nimport { inspectArgs } from \"./inspect.js\";\nimport { installArgs } from \"./install.js\";\nimport { listArgs } from \"./list.js\";\nimport { loginArgs } from \"./login.js\";\nimport { migrateArgs } from \"./migrate.js\";\nimport { publishArgs } from \"./publish.js\";\nimport { registryLoginArgs } from \"./registry.js\";\nimport { switchboardArgs } from \"./switchboard.js\";\nimport { uninstallArgs } from \"./uninstall.js\";\nimport { vetraArgs } from \"./vetra.js\";\n\n// Thin wrapper around `command()` that preserves the literal types of\n// `name` and `aliases` on the return value.\nfunction helpCommand<\n const N extends string,\n const A extends readonly string[] = readonly [],\n>(\n config: Parameters<typeof command>[0] & { name: N; aliases?: A },\n): ReturnType<typeof command> & { readonly name: N; readonly aliases: A } {\n const aliases = (config.aliases ?? ([] as readonly string[])) as A;\n // Forward the original config (with the normalized aliases) through cmd-ts\n // and re-attach the literal types via a localized cast.\n return Object.assign(command({ ...config, aliases: [...aliases] }), {\n name: config.name,\n aliases,\n }) as ReturnType<typeof command> & {\n readonly name: N;\n readonly aliases: A;\n };\n}\n\nexport const phCliHelpCommands = {\n generate: helpCommand({\n name: \"generate\",\n args: generateArgs,\n description: \"Generate powerhouse code\",\n handler: () => {},\n }),\n vetra: helpCommand({\n name: \"vetra\",\n args: vetraArgs,\n description:\n \"Starts Vetra development environment with switchboard, reactor, and connect\",\n handler: () => {},\n }),\n connect: helpCommand({\n name: \"connect\",\n args: connectArgs,\n description: \"Powerhouse Connect commands\",\n handler: () => {},\n }),\n build: helpCommand({\n name: \"build\",\n args: debugArgs,\n description: \"Build your project for publishing to the registry\",\n handler: () => {},\n }),\n publish: helpCommand({\n name: \"publish\",\n args: publishArgs,\n description: \"Publish a package to the Powerhouse registry\",\n handler: () => {},\n }),\n list: helpCommand({\n name: \"list\",\n aliases: [\"l\"],\n args: listArgs,\n description: \"List installed packages\",\n handler: () => {},\n }),\n \"access-token\": helpCommand({\n name: \"access-token\",\n args: accessTokenArgs,\n description: \"Generate a bearer token for API authentication\",\n handler: () => {},\n }),\n \"registry-login\": helpCommand({\n name: \"registry-login\",\n args: registryLoginArgs,\n description:\n \"Log in to a Powerhouse registry (writes a Renown bearer token to ~/.npmrc)\",\n handler: () => {},\n }),\n inspect: helpCommand({\n name: \"inspect\",\n aliases: [\"is\"],\n args: inspectArgs,\n description: \"Inspect a package\",\n handler: () => {},\n }),\n migrate: helpCommand({\n name: \"migrate\",\n args: migrateArgs,\n description: \"Run migrations\",\n handler: () => {},\n }),\n switchboard: helpCommand({\n name: \"switchboard\",\n aliases: [\"reactor\"],\n args: switchboardArgs,\n description: \"Starts local Switchboard\",\n handler: () => {},\n }),\n login: helpCommand({\n name: \"login\",\n args: loginArgs,\n description: \"Authenticate with Renown using your Ethereum wallet\",\n handler: () => {},\n }),\n logout: helpCommand({\n name: \"logout\",\n args: loginArgs,\n description: \"Deletes an existing session created with 'ph login'\",\n handler: () => {},\n }),\n install: helpCommand({\n name: \"install\",\n aliases: [\"add\", \"i\"],\n args: installArgs,\n description: \"Install a Powerhouse dependency\",\n handler: () => {},\n }),\n uninstall: helpCommand({\n name: \"uninstall\",\n aliases: [\"remove\"],\n args: uninstallArgs,\n description: \"Uninstall a Powerhouse dependency\",\n handler: () => {},\n }),\n};\n\nexport { phCliCommandNames } from \"../command-names.js\";\n\n// Compile-time drift guard: phCliCommandNames must match the names+aliases\n// declared above. If you add or rename a command/alias, the type of\n// `_DerivedNames` changes and the assignment below errors until\n// `command-names.ts` is updated to match. Costs nothing at runtime.\ntype _DerivedNames = {\n [K in keyof typeof phCliHelpCommands]:\n | (typeof phCliHelpCommands)[K][\"name\"]\n | (typeof phCliHelpCommands)[K][\"aliases\"][number];\n}[keyof typeof phCliHelpCommands];\n\ntype _Names = (typeof phCliCommandNames)[number];\n\ntype _Equal<A, B> =\n (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2\n ? true\n : false;\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst _phCliCommandNamesInSync: _Equal<_DerivedNames, _Names> extends true\n ? true\n : never = true;\n"],"mappings":";;;;;;;;;;;;;;;;AAEA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;ACLA,SAAS,YAIP,QACwE;CACxE,MAAM,UAAW,OAAO,WAAY,CAAC;CAGrC,OAAO,OAAO,OAAO,QAAQ;EAAE,GAAG;EAAQ,SAAS,CAAC,GAAG,OAAO;CAAE,CAAC,GAAG;EAClE,MAAM,OAAO;EACb;CACF,CAAC;AAIH;AAEA,MAAa,oBAAoB;CAC/B,UAAU,YAAY;EACpB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,OAAO,YAAY;EACjB,MAAM;EACN,MAAM;EACN,aACE;EACF,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,OAAO,YAAY;EACjB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,MAAM,YAAY;EAChB,MAAM;EACN,SAAS,CAAC,GAAG;EACb,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,kBAAkB,YAAY;EAC5B,MAAM;EACN,MAAM;EACN,aACE;EACF,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,SAAS,CAAC,IAAI;EACd,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS,CAAC,SAAS;EACnB,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,OAAO,YAAY;EACjB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,QAAQ,YAAY;EAClB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,SAAS,CAAC,OAAO,GAAG;EACpB,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,WAAW,YAAY;EACrB,MAAM;EACN,SAAS,CAAC,QAAQ;EAClB,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;AACH"}
1
+ {"version":3,"file":"help-DS1NlcJQ.mjs","names":[],"sources":["../../../clis/command-names.ts","../../../clis/args/help.ts"],"sourcesContent":["// Hardcoded so ph-cmd's dispatch doesn't have to evaluate phCliHelpCommands.\n// The compile-time guard in args/help.ts catches drift.\nexport const phCliCommandNames = [\n \"generate\",\n \"vetra\",\n \"connect\",\n \"build\",\n \"publish\",\n \"list\",\n \"l\",\n \"access-token\",\n \"registry-login\",\n \"inspect\",\n \"is\",\n \"migrate\",\n \"switchboard\",\n \"reactor\",\n \"login\",\n \"logout\",\n \"install\",\n \"add\",\n \"i\",\n \"uninstall\",\n \"remove\",\n] as const;\n","import { command } from \"cmd-ts\";\nimport type { phCliCommandNames } from \"../command-names.js\";\nimport { accessTokenArgs } from \"./access-token.js\";\nimport { debugArgs } from \"./common.js\";\nimport { connectArgs } from \"./connect.js\";\nimport { generateArgs } from \"./generate.js\";\nimport { inspectArgs } from \"./inspect.js\";\nimport { installArgs } from \"./install.js\";\nimport { listArgs } from \"./list.js\";\nimport { loginArgs } from \"./login.js\";\nimport { migrateArgs } from \"./migrate.js\";\nimport { publishArgs } from \"./publish.js\";\nimport { registryLoginArgs } from \"./registry.js\";\nimport { switchboardArgs } from \"./switchboard.js\";\nimport { uninstallArgs } from \"./uninstall.js\";\nimport { vetraArgs } from \"./vetra.js\";\n\n// Thin wrapper around `command()` that preserves the literal types of\n// `name` and `aliases` on the return value.\nfunction helpCommand<\n const N extends string,\n const A extends readonly string[] = readonly [],\n>(\n config: Parameters<typeof command>[0] & { name: N; aliases?: A },\n): ReturnType<typeof command> & { readonly name: N; readonly aliases: A } {\n const aliases = (config.aliases ?? ([] as readonly string[])) as A;\n // Forward the original config (with the normalized aliases) through cmd-ts\n // and re-attach the literal types via a localized cast.\n return Object.assign(command({ ...config, aliases: [...aliases] }), {\n name: config.name,\n aliases,\n }) as ReturnType<typeof command> & {\n readonly name: N;\n readonly aliases: A;\n };\n}\n\nexport const phCliHelpCommands = {\n generate: helpCommand({\n name: \"generate\",\n args: generateArgs,\n description: \"Generate powerhouse code\",\n handler: () => {},\n }),\n vetra: helpCommand({\n name: \"vetra\",\n args: vetraArgs,\n description:\n \"Starts Vetra development environment with switchboard, reactor, and connect\",\n handler: () => {},\n }),\n connect: helpCommand({\n name: \"connect\",\n args: connectArgs,\n description: \"Powerhouse Connect commands\",\n handler: () => {},\n }),\n build: helpCommand({\n name: \"build\",\n args: debugArgs,\n description: \"Build your project for publishing to the registry\",\n handler: () => {},\n }),\n publish: helpCommand({\n name: \"publish\",\n args: publishArgs,\n description: \"Publish a package to the Powerhouse registry\",\n handler: () => {},\n }),\n list: helpCommand({\n name: \"list\",\n aliases: [\"l\"],\n args: listArgs,\n description: \"List installed packages\",\n handler: () => {},\n }),\n \"access-token\": helpCommand({\n name: \"access-token\",\n args: accessTokenArgs,\n description: \"Generate a bearer token for API authentication\",\n handler: () => {},\n }),\n \"registry-login\": helpCommand({\n name: \"registry-login\",\n args: registryLoginArgs,\n description:\n \"Log in to a Powerhouse registry (writes a Renown bearer token to ~/.npmrc)\",\n handler: () => {},\n }),\n inspect: helpCommand({\n name: \"inspect\",\n aliases: [\"is\"],\n args: inspectArgs,\n description: \"Inspect a package\",\n handler: () => {},\n }),\n migrate: helpCommand({\n name: \"migrate\",\n args: migrateArgs,\n description: \"Run migrations\",\n handler: () => {},\n }),\n switchboard: helpCommand({\n name: \"switchboard\",\n aliases: [\"reactor\"],\n args: switchboardArgs,\n description: \"Starts local Switchboard\",\n handler: () => {},\n }),\n login: helpCommand({\n name: \"login\",\n args: loginArgs,\n description: \"Authenticate with Renown using your Ethereum wallet\",\n handler: () => {},\n }),\n logout: helpCommand({\n name: \"logout\",\n args: loginArgs,\n description: \"Deletes an existing session created with 'ph login'\",\n handler: () => {},\n }),\n install: helpCommand({\n name: \"install\",\n aliases: [\"add\", \"i\"],\n args: installArgs,\n description: \"Install a Powerhouse dependency\",\n handler: () => {},\n }),\n uninstall: helpCommand({\n name: \"uninstall\",\n aliases: [\"remove\"],\n args: uninstallArgs,\n description: \"Uninstall a Powerhouse dependency\",\n handler: () => {},\n }),\n};\n\nexport { phCliCommandNames } from \"../command-names.js\";\n\n// Compile-time drift guard: phCliCommandNames must match the names+aliases\n// declared above. If you add or rename a command/alias, the type of\n// `_DerivedNames` changes and the assignment below errors until\n// `command-names.ts` is updated to match. Costs nothing at runtime.\ntype _DerivedNames = {\n [K in keyof typeof phCliHelpCommands]:\n | (typeof phCliHelpCommands)[K][\"name\"]\n | (typeof phCliHelpCommands)[K][\"aliases\"][number];\n}[keyof typeof phCliHelpCommands];\n\ntype _Names = (typeof phCliCommandNames)[number];\n\ntype _Equal<A, B> =\n (<T>() => T extends A ? 1 : 2) extends <T>() => T extends B ? 1 : 2\n ? true\n : false;\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nconst _phCliCommandNamesInSync: _Equal<_DerivedNames, _Names> extends true\n ? true\n : never = true;\n"],"mappings":";;;;;;;;;;;;;;;;AAEA,MAAa,oBAAoB;CAC/B;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;AACF;;;ACLA,SAAS,YAIP,QACwE;CACxE,MAAM,UAAW,OAAO,WAAY,CAAC;CAGrC,OAAO,OAAO,OAAO,QAAQ;EAAE,GAAG;EAAQ,SAAS,CAAC,GAAG,OAAO;CAAE,CAAC,GAAG;EAClE,MAAM,OAAO;EACb;CACF,CAAC;AAIH;AAEA,MAAa,oBAAoB;CAC/B,UAAU,YAAY;EACpB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,OAAO,YAAY;EACjB,MAAM;EACN,MAAM;EACN,aACE;EACF,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,OAAO,YAAY;EACjB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,MAAM,YAAY;EAChB,MAAM;EACN,SAAS,CAAC,GAAG;EACb,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,gBAAgB,YAAY;EAC1B,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,kBAAkB,YAAY;EAC5B,MAAM;EACN,MAAM;EACN,aACE;EACF,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,SAAS,CAAC,IAAI;EACd,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,aAAa,YAAY;EACvB,MAAM;EACN,SAAS,CAAC,SAAS;EACnB,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,OAAO,YAAY;EACjB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,QAAQ,YAAY;EAClB,MAAM;EACN,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,SAAS,YAAY;EACnB,MAAM;EACN,SAAS,CAAC,OAAO,GAAG;EACpB,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;CACD,WAAW,YAAY;EACrB,MAAM;EACN,SAAS,CAAC,QAAQ;EAClB,MAAM;EACN,aAAa;EACb,eAAe,CAAC;CAClB,CAAC;AACH"}
@@ -1,2 +1,2 @@
1
- import { n as phCliCommandNames, t as phCliHelpCommands } from "./help-yRmplJjW.mjs";
1
+ import { n as phCliCommandNames, t as phCliHelpCommands } from "./help-DS1NlcJQ.mjs";
2
2
  export { phCliCommandNames, phCliHelpCommands };
@@ -1,7 +1,7 @@
1
1
  import { t as accessTokenArgs } from "./access-token-C5sKsH2O.mjs";
2
2
  import { _ as packageManagerArgs, a as connectBasePath, b as renownSwitchboardUrl, c as disableLocalPackages, d as getPackageManagerCommand, f as https, g as logLevel, h as localPackage, i as commonServerArgs, l as drivesPreserveStrategy, m as httpsKeyFile, n as buildArgs, o as debugArgs, p as httpsCertFile, r as commonArgs, s as defaultDrivesUrl, t as AGENTS, u as force, v as packages, x as vetraSwitchboardArgs, y as renownNamespace } from "./common-Bnm859xU.mjs";
3
3
  import { a as connectStudioArgs, i as connectPreviewArgs, n as connectBuildArgs, r as connectConfigArgs, t as connectArgs } from "./connect-DjeiqXus.mjs";
4
- import { t as generateArgs } from "./generate-DmgiCzuf.mjs";
4
+ import { t as generateArgs } from "./generate-BPBBLeUD.mjs";
5
5
  import { n as phCliCommandNames, t as phCliHelpCommands } from "./help-DVPTARGn.mjs";
6
6
  import { t as initArgs } from "./init-CFeTq4Cq.mjs";
7
7
  import { t as inspectArgs } from "./inspect-BjRmtB86.mjs";
@@ -1,7 +1,7 @@
1
1
  import { _ as packageManagerArgs, a as connectBasePath, b as renownSwitchboardUrl, c as disableLocalPackages, d as getPackageManagerCommand, f as https, g as logLevel, h as localPackage, i as commonServerArgs, l as drivesPreserveStrategy, m as httpsKeyFile, n as buildArgs, o as debugArgs, p as httpsCertFile, r as commonArgs, s as defaultDrivesUrl, t as AGENTS, u as force, v as packages, x as vetraSwitchboardArgs, y as renownNamespace } from "./common-BXabdhiO.mjs";
2
2
  import { t as accessTokenArgs } from "./access-token-3Hqv_U8I.mjs";
3
- import { a as connectStudioArgs, i as connectPreviewArgs, n as connectBuildArgs, r as connectConfigArgs, t as connectArgs } from "./connect-B6xK4YI_.mjs";
4
- import { t as generateArgs } from "./generate-10dooJ-D.mjs";
3
+ import { a as connectStudioArgs, i as connectPreviewArgs, n as connectBuildArgs, r as connectConfigArgs, t as connectArgs } from "./connect-BG3HkYBk.mjs";
4
+ import { t as generateArgs } from "./generate-BOItUNvP.mjs";
5
5
  import { t as inspectArgs } from "./inspect-UNQgtuR0.mjs";
6
6
  import { t as installArgs } from "./install-F-27kF6m.mjs";
7
7
  import { t as listArgs } from "./list-Bkfn8Yuo.mjs";
@@ -12,7 +12,7 @@ import { n as registryLoginArgs, t as DEFAULT_REGISTRY_LOGIN_EXPIRY } from "./re
12
12
  import { t as switchboardArgs } from "./switchboard-CCaAtU56.mjs";
13
13
  import { t as uninstallArgs } from "./uninstall-3U0B8g5c.mjs";
14
14
  import { n as resolveSwitchboardPortDefault, r as vetraArgs, t as resolveConnectPortDefault } from "./vetra-BUNlAAPp.mjs";
15
- import { n as phCliCommandNames, t as phCliHelpCommands } from "./help-yRmplJjW.mjs";
15
+ import { n as phCliCommandNames, t as phCliHelpCommands } from "./help-DS1NlcJQ.mjs";
16
16
  import { t as initArgs } from "./init-Dvb42Y87.mjs";
17
17
  import { t as serviceArgs } from "./service-Cpjlyeu5.mjs";
18
18
  import { t as unpublishArgs } from "./unpublish-s9zUh6Gw.mjs";
@@ -16,7 +16,6 @@ export type PieceBuildTarget = {
16
16
  };
17
17
  export type PackagePiece = {
18
18
  name: string;
19
- version: string;
20
19
  entry?: string;
21
20
  bundle?: string;
22
21
  };
@@ -28,7 +27,6 @@ export type PieceMetadata = Record<string, unknown> & {
28
27
  };
29
28
  export type DescribedPiece = {
30
29
  name: string;
31
- version: string;
32
30
  metadata: PieceMetadata;
33
31
  };
34
32
  export type DescribeResult = {
@@ -63,7 +61,7 @@ export declare function expandEntryGlobs(root: string, globs: string[]): string[
63
61
  export declare function planPieces(projectRoot: string, outDir: string): PiecePlan[];
64
62
  export declare function createJsonReplacer(): (this: unknown, _key: string, value: unknown) => {} | null | undefined;
65
63
  export declare const DESCRIBE_HELPERS = "\nconst isRecord = (value) => typeof value === \"object\" && value !== null;\n\nfunction findPiece(mod) {\n const candidates = [\n ...Object.values(mod),\n ...(isRecord(mod.default) ? Object.values(mod.default) : []),\n mod.default,\n ];\n for (const candidate of candidates) {\n if (isRecord(candidate) && candidate.constructor?.name === \"Piece\") {\n return candidate;\n }\n }\n for (const candidate of candidates) {\n if (\n isRecord(candidate) &&\n typeof candidate.displayName === \"string\" &&\n (isRecord(candidate.actions) ||\n typeof candidate.actions === \"function\" ||\n typeof candidate.getAction === \"function\")\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction describePiece(piece) {\n if (typeof piece.metadata === \"function\") return piece.metadata();\n const call = (value) => (typeof value === \"function\" ? value.call(piece) : value);\n return {\n displayName: piece.displayName,\n logoUrl: piece.logoUrl,\n description: piece.description,\n authors: piece.authors,\n categories: piece.categories,\n auth: piece.auth,\n minimumSupportedRelease: piece.minimumSupportedRelease,\n maximumSupportedRelease: piece.maximumSupportedRelease,\n deprecated: piece.deprecated,\n actions: call(piece.actions) ?? {},\n triggers: call(piece.triggers) ?? {},\n };\n}\n\nfunction createJsonReplacer() {\n const ancestors = [];\n return function replace(_key, value) {\n if (typeof value === \"function\" || value === undefined) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value !== \"object\" || value === null) return value;\n while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop();\n if (ancestors.includes(value)) return undefined;\n ancestors.push(value);\n return value;\n };\n}\n";
66
- export declare const DESCRIBE_SCRIPT = "\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst job = JSON.parse(readFileSync(process.argv[2], \"utf8\"));\n\nconst isRecord = (value) => typeof value === \"object\" && value !== null;\n\nfunction findPiece(mod) {\n const candidates = [\n ...Object.values(mod),\n ...(isRecord(mod.default) ? Object.values(mod.default) : []),\n mod.default,\n ];\n for (const candidate of candidates) {\n if (isRecord(candidate) && candidate.constructor?.name === \"Piece\") {\n return candidate;\n }\n }\n for (const candidate of candidates) {\n if (\n isRecord(candidate) &&\n typeof candidate.displayName === \"string\" &&\n (isRecord(candidate.actions) ||\n typeof candidate.actions === \"function\" ||\n typeof candidate.getAction === \"function\")\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction describePiece(piece) {\n if (typeof piece.metadata === \"function\") return piece.metadata();\n const call = (value) => (typeof value === \"function\" ? value.call(piece) : value);\n return {\n displayName: piece.displayName,\n logoUrl: piece.logoUrl,\n description: piece.description,\n authors: piece.authors,\n categories: piece.categories,\n auth: piece.auth,\n minimumSupportedRelease: piece.minimumSupportedRelease,\n maximumSupportedRelease: piece.maximumSupportedRelease,\n deprecated: piece.deprecated,\n actions: call(piece.actions) ?? {},\n triggers: call(piece.triggers) ?? {},\n };\n}\n\nfunction createJsonReplacer() {\n const ancestors = [];\n return function replace(_key, value) {\n if (typeof value === \"function\" || value === undefined) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value !== \"object\" || value === null) return value;\n while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop();\n if (ancestors.includes(value)) return undefined;\n ancestors.push(value);\n return value;\n };\n}\n\n// Says why the child gave up in the one place the parent always reads, so a\n// failure reports the cause and never the text of this script.\nfunction fail(message) {\n writeFileSync(job.outFile, JSON.stringify({ fatal: message }));\n process.exit(1);\n}\n\n// The module to load for a list entry; a bundle names its own main.\nfunction entryFile(piece) {\n const declared = piece.entry ?? piece.bundle;\n if (typeof declared !== \"string\") return undefined;\n const path = isAbsolute(declared) ? declared : join(job.projectRoot, declared);\n if (piece.entry) return path;\n const pkgFile = join(path, \"package.json\");\n if (!existsSync(pkgFile)) return undefined;\n const pkg = JSON.parse(readFileSync(pkgFile, \"utf8\"));\n return join(path, typeof pkg.main === \"string\" ? pkg.main : \"index.mjs\");\n}\n\nlet listModule;\ntry {\n listModule = await import(pathToFileURL(job.listPath).href);\n} catch (error) {\n fail(job.listPath + \" threw on import: \" + (error instanceof Error ? error.message : String(error)));\n}\nconst list = listModule.pieces ?? listModule.default;\nif (!Array.isArray(list)) {\n fail(job.listPath + ' exports no \"pieces\" array');\n}\n\nconst out = { list, pieces: [], errors: [] };\nfor (const piece of list) {\n const file = entryFile(piece);\n // A missing file is the parent's to report, with the message it owns.\n if (!file || !existsSync(file)) continue;\n try {\n const mod = await import(pathToFileURL(file).href);\n const found = findPiece(mod);\n if (!found) {\n throw new Error(\n \"no Piece export found in \" + file + \"; exports: \" + Object.keys(mod).join(\", \"),\n );\n }\n const metadata = JSON.parse(JSON.stringify(describePiece(found), createJsonReplacer()));\n out.pieces.push({ name: piece.name, version: piece.version, metadata });\n } catch (error) {\n out.errors.push({\n name: piece.name,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n}\nwriteFileSync(job.outFile, JSON.stringify(out, createJsonReplacer()));\n";
64
+ export declare const DESCRIBE_SCRIPT = "\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst job = JSON.parse(readFileSync(process.argv[2], \"utf8\"));\n\nconst isRecord = (value) => typeof value === \"object\" && value !== null;\n\nfunction findPiece(mod) {\n const candidates = [\n ...Object.values(mod),\n ...(isRecord(mod.default) ? Object.values(mod.default) : []),\n mod.default,\n ];\n for (const candidate of candidates) {\n if (isRecord(candidate) && candidate.constructor?.name === \"Piece\") {\n return candidate;\n }\n }\n for (const candidate of candidates) {\n if (\n isRecord(candidate) &&\n typeof candidate.displayName === \"string\" &&\n (isRecord(candidate.actions) ||\n typeof candidate.actions === \"function\" ||\n typeof candidate.getAction === \"function\")\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction describePiece(piece) {\n if (typeof piece.metadata === \"function\") return piece.metadata();\n const call = (value) => (typeof value === \"function\" ? value.call(piece) : value);\n return {\n displayName: piece.displayName,\n logoUrl: piece.logoUrl,\n description: piece.description,\n authors: piece.authors,\n categories: piece.categories,\n auth: piece.auth,\n minimumSupportedRelease: piece.minimumSupportedRelease,\n maximumSupportedRelease: piece.maximumSupportedRelease,\n deprecated: piece.deprecated,\n actions: call(piece.actions) ?? {},\n triggers: call(piece.triggers) ?? {},\n };\n}\n\nfunction createJsonReplacer() {\n const ancestors = [];\n return function replace(_key, value) {\n if (typeof value === \"function\" || value === undefined) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value !== \"object\" || value === null) return value;\n while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop();\n if (ancestors.includes(value)) return undefined;\n ancestors.push(value);\n return value;\n };\n}\n\n// Says why the child gave up in the one place the parent always reads, so a\n// failure reports the cause and never the text of this script.\nfunction fail(message) {\n writeFileSync(job.outFile, JSON.stringify({ fatal: message }));\n process.exit(1);\n}\n\n// The module to load for a list entry; a bundle names its own main.\nfunction entryFile(piece) {\n const declared = piece.entry ?? piece.bundle;\n if (typeof declared !== \"string\") return undefined;\n const path = isAbsolute(declared) ? declared : join(job.projectRoot, declared);\n if (piece.entry) return path;\n const pkgFile = join(path, \"package.json\");\n if (!existsSync(pkgFile)) return undefined;\n const pkg = JSON.parse(readFileSync(pkgFile, \"utf8\"));\n return join(path, typeof pkg.main === \"string\" ? pkg.main : \"index.mjs\");\n}\n\nlet listModule;\ntry {\n listModule = await import(pathToFileURL(job.listPath).href);\n} catch (error) {\n fail(job.listPath + \" threw on import: \" + (error instanceof Error ? error.message : String(error)));\n}\nconst list = listModule.pieces ?? listModule.default;\nif (!Array.isArray(list)) {\n fail(job.listPath + ' exports no \"pieces\" array');\n}\n\nconst out = { list, pieces: [], errors: [] };\nfor (const piece of list) {\n const file = entryFile(piece);\n // A missing file is the parent's to report, with the message it owns.\n if (!file || !existsSync(file)) continue;\n try {\n const mod = await import(pathToFileURL(file).href);\n const found = findPiece(mod);\n if (!found) {\n throw new Error(\n \"no Piece export found in \" + file + \"; exports: \" + Object.keys(mod).join(\", \"),\n );\n }\n const metadata = JSON.parse(JSON.stringify(describePiece(found), createJsonReplacer()));\n out.pieces.push({ name: piece.name, metadata });\n } catch (error) {\n out.errors.push({\n name: piece.name,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n}\nwriteFileSync(job.outFile, JSON.stringify(out, createJsonReplacer()));\n";
67
65
  export declare function describePieces(projectRoot: string, listPath: string): DescribeResult;
68
66
  export type PieceLocation = {
69
67
  /** The piece directory, absolute. */
@@ -89,7 +87,8 @@ export declare function piecePackageJson(options: {
89
87
  main: string;
90
88
  license?: string;
91
89
  }): Record<string, unknown>;
92
- export declare function pieceDescriptor(piece: PackagePiece, metadata: PieceMetadata): Record<string, unknown>;
90
+ export declare function bundlePackageJson(dir: string, version: string): Record<string, unknown>;
91
+ export declare function pieceDescriptor(piece: PackagePiece, version: string, metadata: PieceMetadata): Record<string, unknown>;
93
92
  export declare function enrichManifestPieces(manifest: Manifest, built: BuiltPiece[]): {
94
93
  manifest: Manifest;
95
94
  unbuilt: string[];
@@ -1 +1 @@
1
- {"version":3,"file":"build-pieces.d.mts","names":[],"sources":["../../clis/build-pieces.mts"],"mappings":";;;YA4BY;;EAEV;;EAEA;;EAEA;;YAKU;EACV;EACA;EACA,QAAQ;;YAKE;EACV;EACA;EACA;EACA;;YAKU,gBAAgB;EAC1B;EACA;EACA,UAAU;EACV,WAAW;;YAGD;EACV;EACA;EACA,UAAU;;YAGA;EACV,MAAM;EACN,QAAQ;EACR;IAAU;IAAc;;;YAGd;EACV;EACA;EACA;EACA;;EAEA;;EAEA;;YAGU;EACV;EACA;EACA;;YAGU;;EAEV,SAAS,QAAQ,iBAAiB;;wBAKpB,SAAS,8BAAS;wBAUlB,iBAAiB,cAAc;wBA4B/B,WAAW,qBAAqB,iBAAiB;wBAejD,uBAAkB,eAEK,cAAc;qBAiBxC;qBAiEA;wBAsFG,eACd,qBACA,mBACC;YA0BS;;EAEV;;EAEA;EACA;;wBAKc,qBACd,OAAO,cACP,qBACA,iBACC;wBAmCa,cAAc;EAC5B;EACA;;wBAac,mBAAmB;EACjC;EACA,QAAQ;;wBAWM,mBACd,OAAO,cACP,KAAK;wBAWS,iBAAiB;EAC/B;EACA;EACA;EACA;EACA;IACE;wBAgBY,gBACd,OAAO,cACP,UAAU,gBACT;wBAUa,qBACd,UAAU,UACV,OAAO;EACJ,UAAU;EAAU;;wBAkCH,YACpB,QAAQ,kBACR,KAAK,iBACL,SAAS,oBACR,QAAQ;wBA4GK,iBACd,QAAQ,kBACR,OAAO"}
1
+ {"version":3,"file":"build-pieces.d.mts","names":[],"sources":["../../clis/build-pieces.mts"],"mappings":";;;YA4BY;;EAEV;;EAEA;;EAEA;;YAKU;EACV;EACA;EACA,QAAQ;;YAKE;EACV;EACA;EACA;;YAKU,gBAAgB;EAC1B;EACA;EACA,UAAU;EACV,WAAW;;YAGD;EACV;EACA,UAAU;;YAGA;EACV,MAAM;EACN,QAAQ;EACR;IAAU;IAAc;;;YAGd;EACV;EACA;EACA;EACA;;EAEA;;EAEA;;YAGU;EACV;EACA;EACA;;YAGU;;EAEV,SAAS,QAAQ,iBAAiB;;wBAKpB,SAAS,8BAAS;wBAUlB,iBAAiB,cAAc;wBA4B/B,WAAW,qBAAqB,iBAAiB;wBAejD,uBAAkB,eAEK,cAAc;qBAiBxC;qBAiEA;wBAsFG,eACd,qBACA,mBACC;YA0BS;;EAEV;;EAEA;EACA;;wBAKc,qBACd,OAAO,cACP,qBACA,iBACC;wBAmCa,cAAc;EAC5B;EACA;;wBAac,mBAAmB;EACjC;EACA,QAAQ;;wBAWM,mBACd,OAAO,cACP,KAAK;wBAWS,iBAAiB;EAC/B;EACA;EACA;EACA;EACA;IACE;wBAeY,kBACd,aACA,kBACC;wBASa,gBACd,OAAO,cACP,iBACA,UAAU,gBACT;wBAUa,qBACd,UAAU,UACV,OAAO;EACJ,UAAU;EAAU;;wBAkCH,YACpB,QAAQ,kBACR,KAAK,iBACL,SAAS,oBACR,QAAQ;wBA0GK,iBACd,QAAQ,kBACR,OAAO"}
@@ -162,7 +162,7 @@ for (const piece of list) {
162
162
  );
163
163
  }
164
164
  const metadata = JSON.parse(JSON.stringify(describePiece(found), createJsonReplacer()));
165
- out.pieces.push({ name: piece.name, version: piece.version, metadata });
165
+ out.pieces.push({ name: piece.name, metadata });
166
166
  } catch (error) {
167
167
  out.errors.push({
168
168
  name: piece.name,
@@ -240,7 +240,7 @@ function assertPiecesOutDir(target) {
240
240
  throw new Error(`pieces: --out-dir ${target.outDir} cannot hold pieces; a piece is loaded from dist/node/pieces/<name> by the host, so a package that ships pieces builds to dist`);
241
241
  }
242
242
  function assertPieceVersion(piece, pkg) {
243
- if (piece.name === pkg.name && piece.version !== pkg.version) throw new Error(`pieces: "${piece.name}" declares version ${piece.version}, package.json says ${pkg.version}`);
243
+ if ("version" in piece) throw new Error(`pieces: "${piece.name}" declares version ${String(piece.version)}; a piece takes its package's version (${pkg.version}), so remove "version" from pieces/index.ts`);
244
244
  }
245
245
  function piecePackageJson(options) {
246
246
  return {
@@ -253,11 +253,17 @@ function piecePackageJson(options) {
253
253
  dependencies: {}
254
254
  };
255
255
  }
256
- function pieceDescriptor(piece, metadata) {
256
+ function bundlePackageJson(dir, version) {
257
+ return {
258
+ ...JSON.parse(readFileSync(join(dir, "package.json"), "utf8")),
259
+ version
260
+ };
261
+ }
262
+ function pieceDescriptor(piece, version, metadata) {
257
263
  const { name: _name, version: _version, ...rest } = metadata;
258
264
  return {
259
265
  name: piece.name,
260
- version: piece.version,
266
+ version,
261
267
  ...rest
262
268
  };
263
269
  }
@@ -317,18 +323,19 @@ async function buildPieces(target, pkg, options) {
317
323
  const metadata = found.metadata;
318
324
  const relDir = toPosix(relative(projectRoot, location.dir));
319
325
  listedDirs.add(relDir);
320
- writeFileSync(join(location.dir, "descriptor.json"), JSON.stringify(pieceDescriptor(piece, metadata), createJsonReplacer(), 2) + "\n");
321
- if (location.form === "entry" && location.entryFile) writeFileSync(join(location.dir, "package.json"), JSON.stringify(piecePackageJson({
326
+ writeFileSync(join(location.dir, "descriptor.json"), JSON.stringify(pieceDescriptor(piece, pkg.version, metadata), createJsonReplacer(), 2) + "\n");
327
+ const piecePackage = location.form === "entry" && location.entryFile ? piecePackageJson({
322
328
  name: piece.name,
323
- version: piece.version,
329
+ version: pkg.version,
324
330
  description: metadata.description,
325
331
  main: relative(location.dir, location.entryFile),
326
332
  license: pkg.license
327
- }), null, 2) + "\n");
328
- console.log(`piece: ${piece.name}@${piece.version} -> ${relDir} (${count(metadata.actions)} actions, ${count(metadata.triggers)} triggers)`);
333
+ }) : bundlePackageJson(location.dir, pkg.version);
334
+ writeFileSync(join(location.dir, "package.json"), JSON.stringify(piecePackage, null, 2) + "\n");
335
+ console.log(`piece: ${piece.name}@${pkg.version} -> ${relDir} (${count(metadata.actions)} actions, ${count(metadata.triggers)} triggers)`);
329
336
  built.push({
330
337
  name: piece.name,
331
- version: piece.version,
338
+ version: pkg.version,
332
339
  displayName: metadata.displayName,
333
340
  description: metadata.description,
334
341
  bundle: relDir,
@@ -359,6 +366,6 @@ function syncDistManifest(target, built) {
359
366
  return copy;
360
367
  }
361
368
  //#endregion
362
- export { DESCRIBE_HELPERS, DESCRIBE_SCRIPT, assertPieceVersion, assertPiecesOutDir, buildPieces, createJsonReplacer, describePieces, enrichManifestPieces, expandEntryGlobs, pieceDescriptor, pieceListPath, piecePackageJson, planPieces, resolvePieceLocation, statSafe, syncDistManifest };
369
+ export { DESCRIBE_HELPERS, DESCRIBE_SCRIPT, assertPieceVersion, assertPiecesOutDir, buildPieces, bundlePackageJson, createJsonReplacer, describePieces, enrichManifestPieces, expandEntryGlobs, pieceDescriptor, pieceListPath, piecePackageJson, planPieces, resolvePieceLocation, statSafe, syncDistManifest };
363
370
 
364
371
  //# sourceMappingURL=build-pieces.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"build-pieces.mjs","names":[],"sources":["../../clis/build-pieces.mts"],"sourcesContent":["// The pieces half of a package build: find and bundle each piece whole, load\n// it once in a child process to learn what it is, and write what a host reads.\nimport { execFileSync } from \"node:child_process\";\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n sep,\n} from \"node:path\";\nimport type { InlineConfig } from \"tsdown\";\nimport type { Manifest, PieceModule } from \"../document-model/types.js\";\nimport { buildPieceBuildConfig, PIECE_ENTRY_GLOB } from \"./build-config.mjs\";\n\nexport type PiecePlan = {\n /** The directory under pieces/, and so under <outDir>/node/pieces. */\n dir: string;\n /** Source entry, relative to the project root: pieces/<dir>/index.ts. */\n entry: string;\n /** Where the piece lands, relative to the project root. */\n outDir: string;\n};\n\n// What buildPieces needs to know about the package it works in: where it is,\n// where it builds to, and which pieces the plan found.\nexport type PieceBuildTarget = {\n projectRoot: string;\n outDir: string;\n pieces: PiecePlan[];\n};\n\n// One entry of pieces/index.ts, as @powerhousedao/pieces-framework declares it.\n// Declared here so the build needs no dependency on a package meant for pieces.\nexport type PackagePiece = {\n name: string;\n version: string;\n entry?: string;\n bundle?: string;\n};\n\n// What a piece says about itself, in the framework's PieceMetadata shape.\n// Read from the built piece, so nothing in the build has to know the framework.\nexport type PieceMetadata = Record<string, unknown> & {\n displayName?: string;\n description?: string;\n actions?: Record<string, unknown>;\n triggers?: Record<string, unknown>;\n};\n\nexport type DescribedPiece = {\n name: string;\n version: string;\n metadata: PieceMetadata;\n};\n\nexport type DescribeResult = {\n list: PackagePiece[];\n pieces: DescribedPiece[];\n errors: { name: string; message: string }[];\n};\n\nexport type BuiltPiece = {\n name: string;\n version: string;\n displayName?: string;\n description?: string;\n /** Piece directory, relative to the project root, `/` separated. */\n bundle: string;\n /** The descriptor inside it, relative to the project root, `/` separated. */\n descriptor: string;\n};\n\nexport type PackageIdentity = {\n name: string;\n version: string;\n license?: string;\n};\n\nexport type PieceBuildOptions = {\n /** The bundler: tsdown's `build`, handed in so this module never loads it. */\n bundle: (config: InlineConfig) => Promise<unknown>;\n};\n\nconst toPosix = (p: string) => p.split(sep).join(\"/\");\n\nexport function statSafe(p: string) {\n try {\n return statSync(p);\n } catch {\n return null;\n }\n}\n\n// Expand entry globs (single-`*` segments only — the shape `browserEntry`\n// uses) against files on disk, resolving against `root`.\nexport function expandEntryGlobs(root: string, globs: string[]): string[] {\n const files = new Set<string>();\n for (const pattern of globs) {\n const segments = pattern.split(\"/\").filter(Boolean);\n let dirs = [root];\n for (const seg of segments) {\n const next: string[] = [];\n for (const d of dirs) {\n if (!statSafe(d)?.isDirectory()) continue;\n if (seg === \"*\") {\n for (const e of readdirSync(d, { withFileTypes: true })) {\n next.push(join(d, e.name));\n }\n } else {\n next.push(join(d, seg));\n }\n }\n dirs = next;\n }\n for (const f of dirs) {\n if (statSafe(f)?.isFile()) files.add(f);\n }\n }\n return [...files];\n}\n\n// The pieces a project holds, one per pieces/<dir>/index.ts, sorted by dir so\n// a build log and a manifest read the same from one run to the next.\nexport function planPieces(projectRoot: string, outDir: string): PiecePlan[] {\n return expandEntryGlobs(projectRoot, [PIECE_ENTRY_GLOB])\n .map((file) => {\n const dir = basename(dirname(file));\n return {\n dir,\n entry: relative(projectRoot, file),\n outDir: join(outDir, \"node\", \"pieces\", dir),\n };\n })\n .sort((a, b) => (a.dir < b.dir ? -1 : a.dir > b.dir ? 1 : 0));\n}\n\n// A JSON.stringify replacer that makes a piece's metadata serializable: props\n// carry resolvers, defaults may be class instances, and a schema may cycle.\nexport function createJsonReplacer() {\n const ancestors: object[] = [];\n return function replace(this: unknown, _key: string, value: unknown) {\n if (typeof value === \"function\" || value === undefined) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value !== \"object\" || value === null) return value;\n // `this` is the holder, so popping back to it leaves the current path.\n while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop();\n if (ancestors.includes(value)) return undefined;\n ancestors.push(value);\n return value;\n };\n}\n\n// The half of the child script that needs nothing from the job: a test\n// evaluates this text on its own, so neither copy can drift from the other.\n\n// `constructor?.name`: a module may export an Object.create(null), and the\n// real piece is usually beside it in the same module.\nexport const DESCRIBE_HELPERS = `\nconst isRecord = (value) => typeof value === \"object\" && value !== null;\n\nfunction findPiece(mod) {\n const candidates = [\n ...Object.values(mod),\n ...(isRecord(mod.default) ? Object.values(mod.default) : []),\n mod.default,\n ];\n for (const candidate of candidates) {\n if (isRecord(candidate) && candidate.constructor?.name === \"Piece\") {\n return candidate;\n }\n }\n for (const candidate of candidates) {\n if (\n isRecord(candidate) &&\n typeof candidate.displayName === \"string\" &&\n (isRecord(candidate.actions) ||\n typeof candidate.actions === \"function\" ||\n typeof candidate.getAction === \"function\")\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction describePiece(piece) {\n if (typeof piece.metadata === \"function\") return piece.metadata();\n const call = (value) => (typeof value === \"function\" ? value.call(piece) : value);\n return {\n displayName: piece.displayName,\n logoUrl: piece.logoUrl,\n description: piece.description,\n authors: piece.authors,\n categories: piece.categories,\n auth: piece.auth,\n minimumSupportedRelease: piece.minimumSupportedRelease,\n maximumSupportedRelease: piece.maximumSupportedRelease,\n deprecated: piece.deprecated,\n actions: call(piece.actions) ?? {},\n triggers: call(piece.triggers) ?? {},\n };\n}\n\nfunction createJsonReplacer() {\n const ancestors = [];\n return function replace(_key, value) {\n if (typeof value === \"function\" || value === undefined) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value !== \"object\" || value === null) return value;\n while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop();\n if (ancestors.includes(value)) return undefined;\n ancestors.push(value);\n return value;\n };\n}\n`;\n\n// Runs in a child node process: loading a piece runs piece-authored top-level\n// code, and the runtime describes pieces in a worker for the same reason.\n\n// A string so it works from `src` under bun or tsx as well as from `dist`. It\n// answers through a file, leaving both its streams to the piece.\nexport const DESCRIBE_SCRIPT = `\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst job = JSON.parse(readFileSync(process.argv[2], \"utf8\"));\n${DESCRIBE_HELPERS}\n// Says why the child gave up in the one place the parent always reads, so a\n// failure reports the cause and never the text of this script.\nfunction fail(message) {\n writeFileSync(job.outFile, JSON.stringify({ fatal: message }));\n process.exit(1);\n}\n\n// The module to load for a list entry; a bundle names its own main.\nfunction entryFile(piece) {\n const declared = piece.entry ?? piece.bundle;\n if (typeof declared !== \"string\") return undefined;\n const path = isAbsolute(declared) ? declared : join(job.projectRoot, declared);\n if (piece.entry) return path;\n const pkgFile = join(path, \"package.json\");\n if (!existsSync(pkgFile)) return undefined;\n const pkg = JSON.parse(readFileSync(pkgFile, \"utf8\"));\n return join(path, typeof pkg.main === \"string\" ? pkg.main : \"index.mjs\");\n}\n\nlet listModule;\ntry {\n listModule = await import(pathToFileURL(job.listPath).href);\n} catch (error) {\n fail(job.listPath + \" threw on import: \" + (error instanceof Error ? error.message : String(error)));\n}\nconst list = listModule.pieces ?? listModule.default;\nif (!Array.isArray(list)) {\n fail(job.listPath + ' exports no \"pieces\" array');\n}\n\nconst out = { list, pieces: [], errors: [] };\nfor (const piece of list) {\n const file = entryFile(piece);\n // A missing file is the parent's to report, with the message it owns.\n if (!file || !existsSync(file)) continue;\n try {\n const mod = await import(pathToFileURL(file).href);\n const found = findPiece(mod);\n if (!found) {\n throw new Error(\n \"no Piece export found in \" + file + \"; exports: \" + Object.keys(mod).join(\", \"),\n );\n }\n const metadata = JSON.parse(JSON.stringify(describePiece(found), createJsonReplacer()));\n out.pieces.push({ name: piece.name, version: piece.version, metadata });\n } catch (error) {\n out.errors.push({\n name: piece.name,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n}\nwriteFileSync(job.outFile, JSON.stringify(out, createJsonReplacer()));\n`;\n\n// What the child said went wrong, if it got that far, and otherwise how it\n// died: an exit status, never the whole script an `Error.message` carries.\nfunction childFailure(error: unknown, outFile: string): string {\n try {\n const answer = JSON.parse(readFileSync(outFile, \"utf8\")) as {\n fatal?: unknown;\n };\n if (typeof answer.fatal === \"string\") return answer.fatal;\n } catch {\n // no answer on disk: fall through to the exit status\n }\n const { status, signal } = error as {\n status?: number | null;\n signal?: string | null;\n };\n if (signal) return `the describe child was killed by ${signal}`;\n return `the describe child exited with code ${status ?? \"unknown\"}`;\n}\n\n// Load the built list and every piece it names in a child process and return\n// what they say about themselves. Throws when the list itself cannot be read.\n\n// Both of the child's streams are the parent's, so a piece that prints at\n// import time is heard rather than mixed into the answer.\nexport function describePieces(\n projectRoot: string,\n listPath: string,\n): DescribeResult {\n const dir = mkdtempSync(join(tmpdir(), \"ph-build-pieces-\"));\n const rel = toPosix(relative(projectRoot, listPath));\n try {\n const jobFile = join(dir, \"job.json\");\n const scriptFile = join(dir, \"describe.mjs\");\n const outFile = join(dir, \"describe.json\");\n writeFileSync(scriptFile, DESCRIBE_SCRIPT);\n writeFileSync(jobFile, JSON.stringify({ projectRoot, listPath, outFile }));\n try {\n execFileSync(process.execPath, [scriptFile, jobFile], {\n timeout: 60_000,\n stdio: \"inherit\",\n });\n } catch (error) {\n throw new Error(\n `pieces: could not load ${rel}: ${childFailure(error, outFile)}`,\n { cause: error },\n );\n }\n return JSON.parse(readFileSync(outFile, \"utf8\")) as DescribeResult;\n } finally {\n rmSync(dir, { recursive: true, force: true });\n }\n}\n\nexport type PieceLocation = {\n /** The piece directory, absolute. */\n dir: string;\n /** The module file, absolute; unset for a bundle, whose package.json names it. */\n entryFile?: string;\n form: \"entry\" | \"bundle\";\n};\n\n// Where a list entry says its built piece is, checked against the disk: a\n// listed piece nobody built would otherwise fail much later, in a host.\nexport function resolvePieceLocation(\n piece: PackagePiece,\n projectRoot: string,\n outDir: string,\n): PieceLocation {\n const declared = piece.entry ?? piece.bundle;\n if (typeof declared !== \"string\" || declared === \"\") {\n throw new Error(\n `pieces: \"${piece.name}\" declares neither an entry nor a bundle`,\n );\n }\n const path = isAbsolute(declared) ? declared : join(projectRoot, declared);\n const form = piece.entry ? \"entry\" : \"bundle\";\n const present =\n form === \"entry\"\n ? statSafe(path)?.isFile()\n : statSafe(join(path, \"package.json\"))?.isFile();\n if (!present) {\n throw new Error(\n `pieces: \"${piece.name}\" declares ${declared}, which is missing`,\n );\n }\n const dir = form === \"entry\" ? dirname(path) : path;\n // Both forms, not just `entry`: a descriptor.json is written into this\n // directory, and outside outDir that lands in tracked source.\n const piecesRoot = resolve(projectRoot, outDir, \"node\", \"pieces\");\n const inside = relative(piecesRoot, dir);\n if (inside === \"\" || inside.startsWith(\"..\") || isAbsolute(inside)) {\n const expected = toPosix(join(outDir, \"node\", \"pieces\"));\n throw new Error(\n `pieces: \"${piece.name}\" declares ${declared}, which is outside ${expected}/; ` +\n `a piece is built to ${expected}/<dir>/index.mjs and its entry must point there`,\n );\n }\n return form === \"entry\" ? { dir, entryFile: path, form } : { dir, form };\n}\n\n// Where the node build leaves the list of pieces a package ships. Its presence\n// on disk, not a pieces/<dir> in the source, is what says a package has them.\nexport function pieceListPath(target: {\n projectRoot: string;\n outDir: string;\n}): string {\n return resolve(\n target.projectRoot,\n target.outDir,\n \"node\",\n \"pieces\",\n \"index.mjs\",\n );\n}\n\n// `dist` is not a default here but a contract: a host reads a piece from\n// dist/node/pieces/<name>, and a list entry names that path literally.\nexport function assertPiecesOutDir(target: {\n outDir: string;\n pieces: PiecePlan[];\n}): void {\n if (target.pieces.length === 0 || target.outDir === \"dist\") return;\n throw new Error(\n `pieces: --out-dir ${target.outDir} cannot hold pieces; a piece is loaded from ` +\n `dist/node/pieces/<name> by the host, so a package that ships pieces builds to dist`,\n );\n}\n\n// A piece named after its package must carry the package's version: once\n// published, a drifted version resolves to the wrong tarball.\nexport function assertPieceVersion(\n piece: PackagePiece,\n pkg: PackageIdentity,\n): void {\n if (piece.name === pkg.name && piece.version !== pkg.version) {\n throw new Error(\n `pieces: \"${piece.name}\" declares version ${piece.version}, package.json says ${pkg.version}`,\n );\n }\n}\n\n// The package.json written beside a piece built from an `entry`, giving the\n// directory npm-bundle shape so a registry can serve it on its own.\nexport function piecePackageJson(options: {\n name: string;\n version: string;\n description?: string;\n main: string;\n license?: string;\n}): Record<string, unknown> {\n return {\n name: options.name,\n version: options.version,\n description: options.description ?? \"\",\n type: \"module\",\n main: options.main,\n ...(options.license ? { license: options.license } : {}),\n // Empty on purpose: the runtime treats a bundle that declares dependencies\n // as not self-contained, and everything a piece needs is inlined already.\n dependencies: {},\n };\n}\n\n// The descriptor written beside a piece: the list's name and version, then\n// whatever the piece said about itself, in the framework's PieceMetadata shape.\nexport function pieceDescriptor(\n piece: PackagePiece,\n metadata: PieceMetadata,\n): Record<string, unknown> {\n const { name: _name, version: _version, ...rest } = metadata;\n return { name: piece.name, version: piece.version, ...rest };\n}\n\n// The manifest's `pieces` with what the build learned: a built piece replaces\n// the source entry with its id in place, or is appended at the end.\n\n// A source entry nothing built is kept as it is and returned as `unbuilt`,\n// for the caller to warn about.\nexport function enrichManifestPieces(\n manifest: Manifest,\n built: BuiltPiece[],\n): { manifest: Manifest; unbuilt: string[] } {\n const byId = new Map(built.map((piece) => [piece.name, piece]));\n const toModule = (piece: BuiltPiece): PieceModule => ({\n id: piece.name,\n name: piece.displayName ?? piece.name,\n version: piece.version,\n ...(piece.description ? { description: piece.description } : {}),\n bundle: piece.bundle,\n descriptor: piece.descriptor,\n });\n const unbuilt: string[] = [];\n const seen = new Set<string>();\n const pieces: PieceModule[] = (manifest.pieces ?? []).map((entry) => {\n const hit = byId.get(entry.id);\n if (!hit) {\n unbuilt.push(entry.id);\n return entry;\n }\n seen.add(entry.id);\n return toModule(hit);\n });\n for (const piece of built) {\n if (!seen.has(piece.name)) pieces.push(toModule(piece));\n }\n return { manifest: { ...manifest, pieces }, unbuilt };\n}\n\nconst count = (record: unknown) =>\n typeof record === \"object\" && record !== null\n ? Object.keys(record).length\n : 0;\n\n// Build every planned piece, then read the built list and describe what it\n// names. Returns what was built, for the manifest.\nexport async function buildPieces(\n target: PieceBuildTarget,\n pkg: PackageIdentity,\n options: PieceBuildOptions,\n): Promise<BuiltPiece[]> {\n const { projectRoot, outDir } = target;\n assertPiecesOutDir(target);\n // resolve, not join: an absolute --out-dir is what the browser and node\n // steps hand tsdown, and joining it onto the project root mangles it.\n for (const piece of target.pieces) {\n console.log(`\\n▶ Building piece ${piece.dir}...`);\n await options.bundle(\n buildPieceBuildConfig({\n entry: resolve(projectRoot, piece.entry),\n outDir: resolve(projectRoot, piece.outDir),\n }),\n );\n }\n\n // The list is the source of truth for names and versions; a package that\n // built pieces without a list has nothing a host could read.\n const listPath = pieceListPath(target);\n if (!existsSync(listPath)) {\n throw new Error(\n `pieces: ${toPosix(relative(projectRoot, listPath))} was not built; ` +\n `pieces/index.ts must export the list of pieces this package ships`,\n );\n }\n const described = describePieces(projectRoot, listPath);\n\n const built: BuiltPiece[] = [];\n const listedDirs = new Set<string>();\n for (const piece of described.list) {\n const location = resolvePieceLocation(piece, projectRoot, outDir);\n assertPieceVersion(piece, pkg);\n const failure = described.errors.find((e) => e.name === piece.name);\n if (failure) {\n throw new Error(\n `pieces: \"${piece.name}\" could not be described: ${failure.message}`,\n );\n }\n const found = described.pieces.find((p) => p.name === piece.name);\n if (!found) {\n throw new Error(`pieces: \"${piece.name}\" was not described`);\n }\n const metadata = found.metadata;\n const relDir = toPosix(relative(projectRoot, location.dir));\n listedDirs.add(relDir);\n\n writeFileSync(\n join(location.dir, \"descriptor.json\"),\n JSON.stringify(\n pieceDescriptor(piece, metadata),\n createJsonReplacer(),\n 2,\n ) + \"\\n\",\n );\n if (location.form === \"entry\" && location.entryFile) {\n writeFileSync(\n join(location.dir, \"package.json\"),\n JSON.stringify(\n piecePackageJson({\n name: piece.name,\n version: piece.version,\n description: metadata.description,\n main: relative(location.dir, location.entryFile),\n license: pkg.license,\n }),\n null,\n 2,\n ) + \"\\n\",\n );\n }\n console.log(\n `piece: ${piece.name}@${piece.version} -> ${relDir} ` +\n `(${count(metadata.actions)} actions, ${count(metadata.triggers)} triggers)`,\n );\n built.push({\n name: piece.name,\n version: piece.version,\n displayName: metadata.displayName,\n description: metadata.description,\n bundle: relDir,\n descriptor: `${relDir}/descriptor.json`,\n });\n }\n\n warnUnlistedPieces(target.pieces, listedDirs);\n return built;\n}\n\n// A built piece no list entry points into ships without a host ever finding it.\nfunction warnUnlistedPieces(\n planned: PiecePlan[],\n listedDirs: Set<string>,\n): void {\n for (const piece of planned) {\n if (!listedDirs.has(toPosix(piece.outDir))) {\n console.warn(\n `⚠ pieces: pieces/${piece.dir} was built but pieces/index.ts does not list it; a host will not find it`,\n );\n }\n }\n}\n\n// Make sure the manifest ships under outDir (tsdown copies it only in the\n// browser build) and, when pieces were built, list them in that copy.\n\n// Always copied afresh: only <outDir>/node is cleaned by the builds, so a copy\n// left by the last build would otherwise outlive an edit to the source.\n\n// The source file is never written. Returns the path of the copy, if any.\nexport function syncDistManifest(\n target: PieceBuildTarget,\n built: BuiltPiece[],\n): string | undefined {\n const { projectRoot, outDir } = target;\n const source = join(projectRoot, \"powerhouse.manifest.json\");\n // resolve, not join: an absolute --out-dir is a location, not a suffix.\n const copy = resolve(projectRoot, outDir, \"powerhouse.manifest.json\");\n // The built list, not the source plan: a package whose pieces are all\n // `bundle:` entries has no pieces/<dir> and still ships pieces.\n const shipsPieces = existsSync(pieceListPath(target));\n if (!existsSync(source)) {\n if (shipsPieces) {\n console.warn(\"⚠ no powerhouse.manifest.json; pieces will not be listed\");\n }\n return undefined;\n }\n mkdirSync(dirname(copy), { recursive: true });\n copyFileSync(source, copy);\n if (!shipsPieces) return copy;\n\n const manifest = JSON.parse(readFileSync(copy, \"utf8\")) as Manifest;\n const enriched = enrichManifestPieces(manifest, built);\n for (const id of enriched.unbuilt) {\n console.warn(`⚠ manifest lists piece \"${id}\" but nothing built it`);\n }\n writeFileSync(copy, JSON.stringify(enriched.manifest, null, 2) + \"\\n\");\n return copy;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"build-pieces.mjs","names":[],"sources":["../../clis/build-pieces.mts"],"sourcesContent":["// The pieces half of a package build: find and bundle each piece whole, load\n// it once in a child process to learn what it is, and write what a host reads.\nimport { execFileSync } from \"node:child_process\";\nimport {\n copyFileSync,\n existsSync,\n mkdirSync,\n mkdtempSync,\n readdirSync,\n readFileSync,\n rmSync,\n statSync,\n writeFileSync,\n} from \"node:fs\";\nimport { tmpdir } from \"node:os\";\nimport {\n basename,\n dirname,\n isAbsolute,\n join,\n relative,\n resolve,\n sep,\n} from \"node:path\";\nimport type { InlineConfig } from \"tsdown\";\nimport type { Manifest, PieceModule } from \"../document-model/types.js\";\nimport { buildPieceBuildConfig, PIECE_ENTRY_GLOB } from \"./build-config.mjs\";\n\nexport type PiecePlan = {\n /** The directory under pieces/, and so under <outDir>/node/pieces. */\n dir: string;\n /** Source entry, relative to the project root: pieces/<dir>/index.ts. */\n entry: string;\n /** Where the piece lands, relative to the project root. */\n outDir: string;\n};\n\n// What buildPieces needs to know about the package it works in: where it is,\n// where it builds to, and which pieces the plan found.\nexport type PieceBuildTarget = {\n projectRoot: string;\n outDir: string;\n pieces: PiecePlan[];\n};\n\n// One entry of pieces/index.ts, as @powerhousedao/pieces-framework declares it.\n// Declared here so the build needs no dependency on a package meant for pieces.\nexport type PackagePiece = {\n name: string;\n entry?: string;\n bundle?: string;\n};\n\n// What a piece says about itself, in the framework's PieceMetadata shape.\n// Read from the built piece, so nothing in the build has to know the framework.\nexport type PieceMetadata = Record<string, unknown> & {\n displayName?: string;\n description?: string;\n actions?: Record<string, unknown>;\n triggers?: Record<string, unknown>;\n};\n\nexport type DescribedPiece = {\n name: string;\n metadata: PieceMetadata;\n};\n\nexport type DescribeResult = {\n list: PackagePiece[];\n pieces: DescribedPiece[];\n errors: { name: string; message: string }[];\n};\n\nexport type BuiltPiece = {\n name: string;\n version: string;\n displayName?: string;\n description?: string;\n /** Piece directory, relative to the project root, `/` separated. */\n bundle: string;\n /** The descriptor inside it, relative to the project root, `/` separated. */\n descriptor: string;\n};\n\nexport type PackageIdentity = {\n name: string;\n version: string;\n license?: string;\n};\n\nexport type PieceBuildOptions = {\n /** The bundler: tsdown's `build`, handed in so this module never loads it. */\n bundle: (config: InlineConfig) => Promise<unknown>;\n};\n\nconst toPosix = (p: string) => p.split(sep).join(\"/\");\n\nexport function statSafe(p: string) {\n try {\n return statSync(p);\n } catch {\n return null;\n }\n}\n\n// Expand entry globs (single-`*` segments only — the shape `browserEntry`\n// uses) against files on disk, resolving against `root`.\nexport function expandEntryGlobs(root: string, globs: string[]): string[] {\n const files = new Set<string>();\n for (const pattern of globs) {\n const segments = pattern.split(\"/\").filter(Boolean);\n let dirs = [root];\n for (const seg of segments) {\n const next: string[] = [];\n for (const d of dirs) {\n if (!statSafe(d)?.isDirectory()) continue;\n if (seg === \"*\") {\n for (const e of readdirSync(d, { withFileTypes: true })) {\n next.push(join(d, e.name));\n }\n } else {\n next.push(join(d, seg));\n }\n }\n dirs = next;\n }\n for (const f of dirs) {\n if (statSafe(f)?.isFile()) files.add(f);\n }\n }\n return [...files];\n}\n\n// The pieces a project holds, one per pieces/<dir>/index.ts, sorted by dir so\n// a build log and a manifest read the same from one run to the next.\nexport function planPieces(projectRoot: string, outDir: string): PiecePlan[] {\n return expandEntryGlobs(projectRoot, [PIECE_ENTRY_GLOB])\n .map((file) => {\n const dir = basename(dirname(file));\n return {\n dir,\n entry: relative(projectRoot, file),\n outDir: join(outDir, \"node\", \"pieces\", dir),\n };\n })\n .sort((a, b) => (a.dir < b.dir ? -1 : a.dir > b.dir ? 1 : 0));\n}\n\n// A JSON.stringify replacer that makes a piece's metadata serializable: props\n// carry resolvers, defaults may be class instances, and a schema may cycle.\nexport function createJsonReplacer() {\n const ancestors: object[] = [];\n return function replace(this: unknown, _key: string, value: unknown) {\n if (typeof value === \"function\" || value === undefined) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value !== \"object\" || value === null) return value;\n // `this` is the holder, so popping back to it leaves the current path.\n while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop();\n if (ancestors.includes(value)) return undefined;\n ancestors.push(value);\n return value;\n };\n}\n\n// The half of the child script that needs nothing from the job: a test\n// evaluates this text on its own, so neither copy can drift from the other.\n\n// `constructor?.name`: a module may export an Object.create(null), and the\n// real piece is usually beside it in the same module.\nexport const DESCRIBE_HELPERS = `\nconst isRecord = (value) => typeof value === \"object\" && value !== null;\n\nfunction findPiece(mod) {\n const candidates = [\n ...Object.values(mod),\n ...(isRecord(mod.default) ? Object.values(mod.default) : []),\n mod.default,\n ];\n for (const candidate of candidates) {\n if (isRecord(candidate) && candidate.constructor?.name === \"Piece\") {\n return candidate;\n }\n }\n for (const candidate of candidates) {\n if (\n isRecord(candidate) &&\n typeof candidate.displayName === \"string\" &&\n (isRecord(candidate.actions) ||\n typeof candidate.actions === \"function\" ||\n typeof candidate.getAction === \"function\")\n ) {\n return candidate;\n }\n }\n return undefined;\n}\n\nfunction describePiece(piece) {\n if (typeof piece.metadata === \"function\") return piece.metadata();\n const call = (value) => (typeof value === \"function\" ? value.call(piece) : value);\n return {\n displayName: piece.displayName,\n logoUrl: piece.logoUrl,\n description: piece.description,\n authors: piece.authors,\n categories: piece.categories,\n auth: piece.auth,\n minimumSupportedRelease: piece.minimumSupportedRelease,\n maximumSupportedRelease: piece.maximumSupportedRelease,\n deprecated: piece.deprecated,\n actions: call(piece.actions) ?? {},\n triggers: call(piece.triggers) ?? {},\n };\n}\n\nfunction createJsonReplacer() {\n const ancestors = [];\n return function replace(_key, value) {\n if (typeof value === \"function\" || value === undefined) return undefined;\n if (typeof value === \"bigint\") return value.toString();\n if (typeof value !== \"object\" || value === null) return value;\n while (ancestors.length > 0 && ancestors.at(-1) !== this) ancestors.pop();\n if (ancestors.includes(value)) return undefined;\n ancestors.push(value);\n return value;\n };\n}\n`;\n\n// Runs in a child node process: loading a piece runs piece-authored top-level\n// code, and the runtime describes pieces in a worker for the same reason.\n\n// A string so it works from `src` under bun or tsx as well as from `dist`. It\n// answers through a file, leaving both its streams to the piece.\nexport const DESCRIBE_SCRIPT = `\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { isAbsolute, join } from \"node:path\";\nimport { pathToFileURL } from \"node:url\";\n\nconst job = JSON.parse(readFileSync(process.argv[2], \"utf8\"));\n${DESCRIBE_HELPERS}\n// Says why the child gave up in the one place the parent always reads, so a\n// failure reports the cause and never the text of this script.\nfunction fail(message) {\n writeFileSync(job.outFile, JSON.stringify({ fatal: message }));\n process.exit(1);\n}\n\n// The module to load for a list entry; a bundle names its own main.\nfunction entryFile(piece) {\n const declared = piece.entry ?? piece.bundle;\n if (typeof declared !== \"string\") return undefined;\n const path = isAbsolute(declared) ? declared : join(job.projectRoot, declared);\n if (piece.entry) return path;\n const pkgFile = join(path, \"package.json\");\n if (!existsSync(pkgFile)) return undefined;\n const pkg = JSON.parse(readFileSync(pkgFile, \"utf8\"));\n return join(path, typeof pkg.main === \"string\" ? pkg.main : \"index.mjs\");\n}\n\nlet listModule;\ntry {\n listModule = await import(pathToFileURL(job.listPath).href);\n} catch (error) {\n fail(job.listPath + \" threw on import: \" + (error instanceof Error ? error.message : String(error)));\n}\nconst list = listModule.pieces ?? listModule.default;\nif (!Array.isArray(list)) {\n fail(job.listPath + ' exports no \"pieces\" array');\n}\n\nconst out = { list, pieces: [], errors: [] };\nfor (const piece of list) {\n const file = entryFile(piece);\n // A missing file is the parent's to report, with the message it owns.\n if (!file || !existsSync(file)) continue;\n try {\n const mod = await import(pathToFileURL(file).href);\n const found = findPiece(mod);\n if (!found) {\n throw new Error(\n \"no Piece export found in \" + file + \"; exports: \" + Object.keys(mod).join(\", \"),\n );\n }\n const metadata = JSON.parse(JSON.stringify(describePiece(found), createJsonReplacer()));\n out.pieces.push({ name: piece.name, metadata });\n } catch (error) {\n out.errors.push({\n name: piece.name,\n message: error instanceof Error ? error.message : String(error),\n });\n }\n}\nwriteFileSync(job.outFile, JSON.stringify(out, createJsonReplacer()));\n`;\n\n// What the child said went wrong, if it got that far, and otherwise how it\n// died: an exit status, never the whole script an `Error.message` carries.\nfunction childFailure(error: unknown, outFile: string): string {\n try {\n const answer = JSON.parse(readFileSync(outFile, \"utf8\")) as {\n fatal?: unknown;\n };\n if (typeof answer.fatal === \"string\") return answer.fatal;\n } catch {\n // no answer on disk: fall through to the exit status\n }\n const { status, signal } = error as {\n status?: number | null;\n signal?: string | null;\n };\n if (signal) return `the describe child was killed by ${signal}`;\n return `the describe child exited with code ${status ?? \"unknown\"}`;\n}\n\n// Load the built list and every piece it names in a child process and return\n// what they say about themselves. Throws when the list itself cannot be read.\n\n// Both of the child's streams are the parent's, so a piece that prints at\n// import time is heard rather than mixed into the answer.\nexport function describePieces(\n projectRoot: string,\n listPath: string,\n): DescribeResult {\n const dir = mkdtempSync(join(tmpdir(), \"ph-build-pieces-\"));\n const rel = toPosix(relative(projectRoot, listPath));\n try {\n const jobFile = join(dir, \"job.json\");\n const scriptFile = join(dir, \"describe.mjs\");\n const outFile = join(dir, \"describe.json\");\n writeFileSync(scriptFile, DESCRIBE_SCRIPT);\n writeFileSync(jobFile, JSON.stringify({ projectRoot, listPath, outFile }));\n try {\n execFileSync(process.execPath, [scriptFile, jobFile], {\n timeout: 60_000,\n stdio: \"inherit\",\n });\n } catch (error) {\n throw new Error(\n `pieces: could not load ${rel}: ${childFailure(error, outFile)}`,\n { cause: error },\n );\n }\n return JSON.parse(readFileSync(outFile, \"utf8\")) as DescribeResult;\n } finally {\n rmSync(dir, { recursive: true, force: true });\n }\n}\n\nexport type PieceLocation = {\n /** The piece directory, absolute. */\n dir: string;\n /** The module file, absolute; unset for a bundle, whose package.json names it. */\n entryFile?: string;\n form: \"entry\" | \"bundle\";\n};\n\n// Where a list entry says its built piece is, checked against the disk: a\n// listed piece nobody built would otherwise fail much later, in a host.\nexport function resolvePieceLocation(\n piece: PackagePiece,\n projectRoot: string,\n outDir: string,\n): PieceLocation {\n const declared = piece.entry ?? piece.bundle;\n if (typeof declared !== \"string\" || declared === \"\") {\n throw new Error(\n `pieces: \"${piece.name}\" declares neither an entry nor a bundle`,\n );\n }\n const path = isAbsolute(declared) ? declared : join(projectRoot, declared);\n const form = piece.entry ? \"entry\" : \"bundle\";\n const present =\n form === \"entry\"\n ? statSafe(path)?.isFile()\n : statSafe(join(path, \"package.json\"))?.isFile();\n if (!present) {\n throw new Error(\n `pieces: \"${piece.name}\" declares ${declared}, which is missing`,\n );\n }\n const dir = form === \"entry\" ? dirname(path) : path;\n // Both forms, not just `entry`: a descriptor.json is written into this\n // directory, and outside outDir that lands in tracked source.\n const piecesRoot = resolve(projectRoot, outDir, \"node\", \"pieces\");\n const inside = relative(piecesRoot, dir);\n if (inside === \"\" || inside.startsWith(\"..\") || isAbsolute(inside)) {\n const expected = toPosix(join(outDir, \"node\", \"pieces\"));\n throw new Error(\n `pieces: \"${piece.name}\" declares ${declared}, which is outside ${expected}/; ` +\n `a piece is built to ${expected}/<dir>/index.mjs and its entry must point there`,\n );\n }\n return form === \"entry\" ? { dir, entryFile: path, form } : { dir, form };\n}\n\n// Where the node build leaves the list of pieces a package ships. Its presence\n// on disk, not a pieces/<dir> in the source, is what says a package has them.\nexport function pieceListPath(target: {\n projectRoot: string;\n outDir: string;\n}): string {\n return resolve(\n target.projectRoot,\n target.outDir,\n \"node\",\n \"pieces\",\n \"index.mjs\",\n );\n}\n\n// `dist` is not a default here but a contract: a host reads a piece from\n// dist/node/pieces/<name>, and a list entry names that path literally.\nexport function assertPiecesOutDir(target: {\n outDir: string;\n pieces: PiecePlan[];\n}): void {\n if (target.pieces.length === 0 || target.outDir === \"dist\") return;\n throw new Error(\n `pieces: --out-dir ${target.outDir} cannot hold pieces; a piece is loaded from ` +\n `dist/node/pieces/<name> by the host, so a package that ships pieces builds to dist`,\n );\n}\n\n// A piece's version is its package's, written by the build; a list entry that\n// declares one is refused, so `name@version` always names one tarball.\nexport function assertPieceVersion(\n piece: PackagePiece,\n pkg: PackageIdentity,\n): void {\n if (\"version\" in piece) {\n throw new Error(\n `pieces: \"${piece.name}\" declares version ${String(piece.version)}; a piece takes its package's version (${pkg.version}), so remove \"version\" from pieces/index.ts`,\n );\n }\n}\n\n// The package.json written beside a piece built from an `entry`, giving the\n// directory npm-bundle shape so a registry can serve it on its own.\nexport function piecePackageJson(options: {\n name: string;\n version: string;\n description?: string;\n main: string;\n license?: string;\n}): Record<string, unknown> {\n return {\n name: options.name,\n version: options.version,\n description: options.description ?? \"\",\n type: \"module\",\n main: options.main,\n ...(options.license ? { license: options.license } : {}),\n // Empty on purpose: the runtime treats a bundle that declares dependencies\n // as not self-contained, and everything a piece needs is inlined already.\n dependencies: {},\n };\n}\n\n// A prebuilt bundle's own package.json, restamped with the package's version.\nexport function bundlePackageJson(\n dir: string,\n version: string,\n): Record<string, unknown> {\n const current = JSON.parse(\n readFileSync(join(dir, \"package.json\"), \"utf8\"),\n ) as Record<string, unknown>;\n return { ...current, version };\n}\n\n// The descriptor written beside a piece: the list's name, the package's version,\n// then whatever the piece said about itself, in the framework's PieceMetadata shape.\nexport function pieceDescriptor(\n piece: PackagePiece,\n version: string,\n metadata: PieceMetadata,\n): Record<string, unknown> {\n const { name: _name, version: _version, ...rest } = metadata;\n return { name: piece.name, version, ...rest };\n}\n\n// The manifest's `pieces` with what the build learned: a built piece replaces\n// the source entry with its id in place, or is appended at the end.\n\n// A source entry nothing built is kept as it is and returned as `unbuilt`,\n// for the caller to warn about.\nexport function enrichManifestPieces(\n manifest: Manifest,\n built: BuiltPiece[],\n): { manifest: Manifest; unbuilt: string[] } {\n const byId = new Map(built.map((piece) => [piece.name, piece]));\n const toModule = (piece: BuiltPiece): PieceModule => ({\n id: piece.name,\n name: piece.displayName ?? piece.name,\n version: piece.version,\n ...(piece.description ? { description: piece.description } : {}),\n bundle: piece.bundle,\n descriptor: piece.descriptor,\n });\n const unbuilt: string[] = [];\n const seen = new Set<string>();\n const pieces: PieceModule[] = (manifest.pieces ?? []).map((entry) => {\n const hit = byId.get(entry.id);\n if (!hit) {\n unbuilt.push(entry.id);\n return entry;\n }\n seen.add(entry.id);\n return toModule(hit);\n });\n for (const piece of built) {\n if (!seen.has(piece.name)) pieces.push(toModule(piece));\n }\n return { manifest: { ...manifest, pieces }, unbuilt };\n}\n\nconst count = (record: unknown) =>\n typeof record === \"object\" && record !== null\n ? Object.keys(record).length\n : 0;\n\n// Build every planned piece, then read the built list and describe what it\n// names. Returns what was built, for the manifest.\nexport async function buildPieces(\n target: PieceBuildTarget,\n pkg: PackageIdentity,\n options: PieceBuildOptions,\n): Promise<BuiltPiece[]> {\n const { projectRoot, outDir } = target;\n assertPiecesOutDir(target);\n // resolve, not join: an absolute --out-dir is what the browser and node\n // steps hand tsdown, and joining it onto the project root mangles it.\n for (const piece of target.pieces) {\n console.log(`\\n▶ Building piece ${piece.dir}...`);\n await options.bundle(\n buildPieceBuildConfig({\n entry: resolve(projectRoot, piece.entry),\n outDir: resolve(projectRoot, piece.outDir),\n }),\n );\n }\n\n // The list is the source of truth for names; a package that\n // built pieces without a list has nothing a host could read.\n const listPath = pieceListPath(target);\n if (!existsSync(listPath)) {\n throw new Error(\n `pieces: ${toPosix(relative(projectRoot, listPath))} was not built; ` +\n `pieces/index.ts must export the list of pieces this package ships`,\n );\n }\n const described = describePieces(projectRoot, listPath);\n\n const built: BuiltPiece[] = [];\n const listedDirs = new Set<string>();\n for (const piece of described.list) {\n const location = resolvePieceLocation(piece, projectRoot, outDir);\n assertPieceVersion(piece, pkg);\n const failure = described.errors.find((e) => e.name === piece.name);\n if (failure) {\n throw new Error(\n `pieces: \"${piece.name}\" could not be described: ${failure.message}`,\n );\n }\n const found = described.pieces.find((p) => p.name === piece.name);\n if (!found) {\n throw new Error(`pieces: \"${piece.name}\" was not described`);\n }\n const metadata = found.metadata;\n const relDir = toPosix(relative(projectRoot, location.dir));\n listedDirs.add(relDir);\n\n writeFileSync(\n join(location.dir, \"descriptor.json\"),\n JSON.stringify(\n pieceDescriptor(piece, pkg.version, metadata),\n createJsonReplacer(),\n 2,\n ) + \"\\n\",\n );\n const piecePackage =\n location.form === \"entry\" && location.entryFile\n ? piecePackageJson({\n name: piece.name,\n version: pkg.version,\n description: metadata.description,\n main: relative(location.dir, location.entryFile),\n license: pkg.license,\n })\n : bundlePackageJson(location.dir, pkg.version);\n writeFileSync(\n join(location.dir, \"package.json\"),\n JSON.stringify(piecePackage, null, 2) + \"\\n\",\n );\n console.log(\n `piece: ${piece.name}@${pkg.version} -> ${relDir} ` +\n `(${count(metadata.actions)} actions, ${count(metadata.triggers)} triggers)`,\n );\n built.push({\n name: piece.name,\n version: pkg.version,\n displayName: metadata.displayName,\n description: metadata.description,\n bundle: relDir,\n descriptor: `${relDir}/descriptor.json`,\n });\n }\n\n warnUnlistedPieces(target.pieces, listedDirs);\n return built;\n}\n\n// A built piece no list entry points into ships without a host ever finding it.\nfunction warnUnlistedPieces(\n planned: PiecePlan[],\n listedDirs: Set<string>,\n): void {\n for (const piece of planned) {\n if (!listedDirs.has(toPosix(piece.outDir))) {\n console.warn(\n `⚠ pieces: pieces/${piece.dir} was built but pieces/index.ts does not list it; a host will not find it`,\n );\n }\n }\n}\n\n// Make sure the manifest ships under outDir (tsdown copies it only in the\n// browser build) and, when pieces were built, list them in that copy.\n\n// Always copied afresh: only <outDir>/node is cleaned by the builds, so a copy\n// left by the last build would otherwise outlive an edit to the source.\n\n// The source file is never written. Returns the path of the copy, if any.\nexport function syncDistManifest(\n target: PieceBuildTarget,\n built: BuiltPiece[],\n): string | undefined {\n const { projectRoot, outDir } = target;\n const source = join(projectRoot, \"powerhouse.manifest.json\");\n // resolve, not join: an absolute --out-dir is a location, not a suffix.\n const copy = resolve(projectRoot, outDir, \"powerhouse.manifest.json\");\n // The built list, not the source plan: a package whose pieces are all\n // `bundle:` entries has no pieces/<dir> and still ships pieces.\n const shipsPieces = existsSync(pieceListPath(target));\n if (!existsSync(source)) {\n if (shipsPieces) {\n console.warn(\"⚠ no powerhouse.manifest.json; pieces will not be listed\");\n }\n return undefined;\n }\n mkdirSync(dirname(copy), { recursive: true });\n copyFileSync(source, copy);\n if (!shipsPieces) return copy;\n\n const manifest = JSON.parse(readFileSync(copy, \"utf8\")) as Manifest;\n const enriched = enrichManifestPieces(manifest, built);\n for (const id of enriched.unbuilt) {\n console.warn(`⚠ manifest lists piece \"${id}\" but nothing built it`);\n }\n writeFileSync(copy, JSON.stringify(enriched.manifest, null, 2) + \"\\n\");\n return copy;\n}\n"],"mappings":"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"}
@@ -700,9 +700,6 @@ export declare const generateArgs: {
700
700
  pieceId: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
701
701
  parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<string | undefined>>;
702
702
  } & import("cmd-ts/dist/cjs/helpdoc.js").ProvidesHelp & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Descriptive>;
703
- pieceVersion: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
704
- parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<string | undefined>>;
705
- } & import("cmd-ts/dist/cjs/helpdoc.js").ProvidesHelp & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Descriptive>;
706
703
  pieceAuth: Partial<import("cmd-ts/dist/cjs/argparser.js").Register> & {
707
704
  parse(context: import("cmd-ts/dist/cjs/argparser.js").ParseContext): Promise<import("cmd-ts/dist/cjs/argparser.js").ParsingResult<"custom" | "none" | "secret">>;
708
705
  } & import("cmd-ts/dist/cjs/helpdoc.js").ProvidesHelp & Partial<import("cmd-ts/dist/cjs/helpdoc.js").Descriptive>;
@@ -2246,7 +2243,7 @@ export declare const sourceConfigSchema: {
2246
2243
  readonly properties: {
2247
2244
  readonly enabled: {
2248
2245
  readonly type: "boolean";
2249
- readonly description: "Register the workflow document models and run workflows. Overridden by PH_WORKFLOWS_ENABLED.";
2246
+ readonly description: "Register the workflow document models and run workflows, on the reactor and in Connect. PH_WORKFLOWS_ENABLED overrides it for the reactor, and connect.app.workflowsEnabled for Connect.";
2250
2247
  };
2251
2248
  };
2252
2249
  };
@@ -2301,8 +2298,7 @@ export declare const sourceConfigSchema: {
2301
2298
  };
2302
2299
  readonly workflowsEnabled: {
2303
2300
  readonly type: "boolean";
2304
- readonly description: "Powerhouse workflows in Connect. When true the tab loads the @powerhousedao/workflow package (workflow + connection documents, their editors and Workflow Studio) and the reactor worker registers its document models. Connect's counterpart to the reactor-side `workflows.enabled` / PH_WORKFLOWS_ENABLED; independent of studioMode. False by default.";
2305
- readonly default: false;
2301
+ readonly description: "Powerhouse workflows in Connect. When true the tab loads the @powerhousedao/workflow package (workflow + connection documents, their editors and Workflow Studio) and the reactor worker registers its document models. Falls back to the top-level `workflows.enabled`; set it to override that for Connect. Independent of studioMode. False when neither is set.";
2306
2302
  };
2307
2303
  };
2308
2304
  };