ph-cmd 6.2.3-dev.1 → 6.2.3-dev.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.mjs +11 -5
- package/dist/cli.mjs.map +1 -1
- package/dist/{delegate-init-CGpBcDwe.mjs → delegate-init-BiHdTmaF.mjs} +3 -3
- package/dist/{delegate-init-CGpBcDwe.mjs.map → delegate-init-BiHdTmaF.mjs.map} +1 -1
- package/dist/delegate-init-DwTgkpW-.mjs +4 -0
- package/dist/{get-version-Bxtapiq5.mjs → get-version-CKWHzzHh.mjs} +4 -4
- package/dist/{get-version-Bxtapiq5.mjs.map → get-version-CKWHzzHh.mjs.map} +1 -1
- package/dist/{ph-cli-DwyaWW70.mjs → ph-cli-BxlV6SZ2.mjs} +6 -6
- package/dist/{ph-cli-DwyaWW70.mjs.map → ph-cli-BxlV6SZ2.mjs.map} +1 -1
- package/dist/{run-C0dHDeMT.mjs → run-0gjMNmbN.mjs} +194 -8
- package/dist/run-0gjMNmbN.mjs.map +1 -0
- package/dist/{update-packages-C5uE2aoa.mjs → update-packages-BTDhXqEj.mjs} +4 -4
- package/dist/{update-packages-C5uE2aoa.mjs.map → update-packages-BTDhXqEj.mjs.map} +1 -1
- package/dist/version-check-BxMITre2.mjs +173 -0
- package/dist/version-check-BxMITre2.mjs.map +1 -0
- package/package.json +3 -3
- package/dist/delegate-init-DPz_LBCQ.mjs +0 -4
- package/dist/run-C0dHDeMT.mjs.map +0 -1
package/dist/cli.mjs
CHANGED
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
4
|
-
import { t as getVersion } from "./get-version-
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="3c343493-d1c1-53be-8105-8600810b1670")}catch(e){}}();
|
|
4
|
+
import { t as getVersion } from "./get-version-CKWHzzHh.mjs";
|
|
5
|
+
import { r as maybeNotifyOutdated } from "./version-check-BxMITre2.mjs";
|
|
5
6
|
import { phCliCommandNames } from "@powerhousedao/shared/clis/command-names";
|
|
6
7
|
import { initCliTelemetry } from "@powerhousedao/shared/clis/telemetry";
|
|
7
8
|
import { assertNodeVersion } from "@powerhousedao/shared/clis/utils";
|
|
@@ -17,11 +18,11 @@ function detectPackageManager() {
|
|
|
17
18
|
* any code is parsed to avoid errors on startup due to unsupported dependencies.
|
|
18
19
|
*/
|
|
19
20
|
async function runPhCliCommand(phCliCommand) {
|
|
20
|
-
const { executePhCliCommand } = await import("./ph-cli-
|
|
21
|
+
const { executePhCliCommand } = await import("./ph-cli-BxlV6SZ2.mjs");
|
|
21
22
|
return await executePhCliCommand(phCliCommand);
|
|
22
23
|
}
|
|
23
24
|
async function runPhCmdCommand(args) {
|
|
24
|
-
const { run } = await import("./run-
|
|
25
|
+
const { run } = await import("./run-0gjMNmbN.mjs");
|
|
25
26
|
return await run(args);
|
|
26
27
|
}
|
|
27
28
|
let sentryClient = void 0;
|
|
@@ -46,6 +47,11 @@ async function main() {
|
|
|
46
47
|
console.log(await getPhCmdVersionInfo(getVersion()));
|
|
47
48
|
process.exit(0);
|
|
48
49
|
}
|
|
50
|
+
await maybeNotifyOutdated({
|
|
51
|
+
args,
|
|
52
|
+
currentVersion: getVersion(),
|
|
53
|
+
stderrIsTty: Boolean(process.stderr.isTTY)
|
|
54
|
+
});
|
|
49
55
|
if (command === "connect" && !args.some((arg) => [
|
|
50
56
|
"studio",
|
|
51
57
|
"build",
|
|
@@ -74,4 +80,4 @@ await main().catch(async (error) => {
|
|
|
74
80
|
export {};
|
|
75
81
|
|
|
76
82
|
//# sourceMappingURL=cli.mjs.map
|
|
77
|
-
//# debugId=
|
|
83
|
+
//# debugId=3c343493-d1c1-53be-8105-8600810b1670
|
package/dist/cli.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.mjs","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { phCliCommandNames } from \"@powerhousedao/shared/clis/command-names\";\nimport {\n initCliTelemetry,\n type TelemetryClient,\n} from \"@powerhousedao/shared/clis/telemetry\";\nimport { assertNodeVersion } from \"@powerhousedao/shared/clis/utils\";\nimport { getVersion } from \"./get-version.js\";\n\n// Commands whose second positional is itself a subcommand (vs. a project\n// name / file path). Keeping this explicit avoids high-cardinality tag\n// values like `subcommand:my-package` polluting Sentry.\nconst COMMANDS_WITH_SUBCOMMANDS = new Set([\"connect\", \"vetra\"]);\n\nfunction detectPackageManager(): string | undefined {\n // npm, pnpm, yarn and bun all set npm_config_user_agent like\n // \"pnpm/8.5.0 npm/? node/v20.11.1 darwin arm64\". When the user invokes\n // `ph` directly (not via dlx/exec) it's typically unset — skip the tag\n // in that case rather than mislabel.\n const ua = process.env.npm_config_user_agent;\n if (!ua) return undefined;\n return ua.split(\" \")[0]?.split(\"/\")[0] || undefined;\n}\n\n/**\n * ph-cli and ph-cmd are loaded lazily so that the node version is checked before\n * any code is parsed to avoid errors on startup due to unsupported dependencies.\n */\n\nasync function runPhCliCommand(phCliCommand: string) {\n const { executePhCliCommand } = await import(\"./ph-cli.js\");\n return await executePhCliCommand(phCliCommand);\n}\nasync function runPhCmdCommand(args: string[]) {\n const { run } = await import(\"./run.js\");\n return await run(args);\n}\n\nlet sentryClient: TelemetryClient | undefined = undefined;\n\nasync function main() {\n assertNodeVersion();\n // Opt-out telemetry; asked once on first interactive run. No-op under\n // PH_NO_TELEMETRY / DO_NOT_TRACK / CI.\n sentryClient = await initCliTelemetry({\n cliName: \"ph-cmd\",\n release: getVersion(),\n });\n const args = process.argv.slice(2);\n const command = args[0];\n const subcommand =\n command &&\n COMMANDS_WITH_SUBCOMMANDS.has(command) &&\n args[1] &&\n !args[1].startsWith(\"-\")\n ? args[1]\n : undefined;\n sentryClient?.attachInvocationContext({\n command,\n subcommand,\n pm: detectPackageManager(),\n argv: args,\n cwd: process.cwd(),\n });\n\n // Short-circuit `ph --version` / `ph -v` so we don't pay for the full\n // cmd-ts subcommand tree (which dynamic-imports the heavy clis bundle\n // just to populate the `version` field). `ph use --version 1.2.3` and\n // similar are unaffected because they have a subcommand first.\n if (args.length === 1 && (command === \"--version\" || command === \"-v\")) {\n const { getPhCmdVersionInfo } = await import(\"@powerhousedao/shared/clis\");\n console.log(await getPhCmdVersionInfo(getVersion()));\n process.exit(0);\n }\n\n // handle the special case where running `connect` with no positional argument\n // defaults to `connect studio`\n if (\n command === \"connect\" &&\n !args.some((arg) => [\"studio\", \"build\", \"preview\"].includes(arg)) &&\n // do not default to `connect studio` when help is present, instead show general help\n // for the `connect` command\n !args.some((arg) => [\"--help\", \"-h\"].includes(arg))\n ) {\n await runPhCliCommand(\"connect\");\n process.exit(0);\n }\n\n // forward command to the local ph-cli installation if it exists\n if (\n phCliCommandNames.includes(command as (typeof phCliCommandNames)[number])\n ) {\n await runPhCliCommand(command);\n process.exit(0);\n }\n\n await runPhCmdCommand(args);\n process.exit(0);\n}\n\nawait main().catch(async (error) => {\n const isDebug = process.argv.slice(2).includes(\"--debug\");\n // No-op when telemetry is disabled; flushes before we exit otherwise.\n await sentryClient?.captureCliError(error);\n if (isDebug) {\n throw error;\n }\n if (error instanceof Error) {\n console.error(error.message);\n process.exit(1);\n } else {\n throw error;\n }\n});\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"cli.mjs","sources":["../src/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { phCliCommandNames } from \"@powerhousedao/shared/clis/command-names\";\nimport {\n initCliTelemetry,\n type TelemetryClient,\n} from \"@powerhousedao/shared/clis/telemetry\";\nimport { assertNodeVersion } from \"@powerhousedao/shared/clis/utils\";\nimport { getVersion } from \"./get-version.js\";\nimport { maybeNotifyOutdated } from \"./utils/version-check.js\";\n\n// Commands whose second positional is itself a subcommand (vs. a project\n// name / file path). Keeping this explicit avoids high-cardinality tag\n// values like `subcommand:my-package` polluting Sentry.\nconst COMMANDS_WITH_SUBCOMMANDS = new Set([\"connect\", \"vetra\"]);\n\nfunction detectPackageManager(): string | undefined {\n // npm, pnpm, yarn and bun all set npm_config_user_agent like\n // \"pnpm/8.5.0 npm/? node/v20.11.1 darwin arm64\". When the user invokes\n // `ph` directly (not via dlx/exec) it's typically unset — skip the tag\n // in that case rather than mislabel.\n const ua = process.env.npm_config_user_agent;\n if (!ua) return undefined;\n return ua.split(\" \")[0]?.split(\"/\")[0] || undefined;\n}\n\n/**\n * ph-cli and ph-cmd are loaded lazily so that the node version is checked before\n * any code is parsed to avoid errors on startup due to unsupported dependencies.\n */\n\nasync function runPhCliCommand(phCliCommand: string) {\n const { executePhCliCommand } = await import(\"./ph-cli.js\");\n return await executePhCliCommand(phCliCommand);\n}\nasync function runPhCmdCommand(args: string[]) {\n const { run } = await import(\"./run.js\");\n return await run(args);\n}\n\nlet sentryClient: TelemetryClient | undefined = undefined;\n\nasync function main() {\n assertNodeVersion();\n // Opt-out telemetry; asked once on first interactive run. No-op under\n // PH_NO_TELEMETRY / DO_NOT_TRACK / CI.\n sentryClient = await initCliTelemetry({\n cliName: \"ph-cmd\",\n release: getVersion(),\n });\n const args = process.argv.slice(2);\n const command = args[0];\n const subcommand =\n command &&\n COMMANDS_WITH_SUBCOMMANDS.has(command) &&\n args[1] &&\n !args[1].startsWith(\"-\")\n ? args[1]\n : undefined;\n sentryClient?.attachInvocationContext({\n command,\n subcommand,\n pm: detectPackageManager(),\n argv: args,\n cwd: process.cwd(),\n });\n\n // Short-circuit `ph --version` / `ph -v` so we don't pay for the full\n // cmd-ts subcommand tree (which dynamic-imports the heavy clis bundle\n // just to populate the `version` field). `ph use --version 1.2.3` and\n // similar are unaffected because they have a subcommand first.\n if (args.length === 1 && (command === \"--version\" || command === \"-v\")) {\n const { getPhCmdVersionInfo } = await import(\"@powerhousedao/shared/clis\");\n console.log(await getPhCmdVersionInfo(getVersion()));\n process.exit(0);\n }\n\n // Outdated-build notice: a stream-aware version check against the\n // registry, cached for 24 hours and shown only on a TTY. It never\n // blocks or breaks the command — every failure is swallowed inside\n // `maybeNotifyOutdated`.\n await maybeNotifyOutdated({\n args,\n currentVersion: getVersion(),\n stderrIsTty: Boolean(process.stderr.isTTY),\n });\n\n // handle the special case where running `connect` with no positional argument\n // defaults to `connect studio`\n if (\n command === \"connect\" &&\n !args.some((arg) => [\"studio\", \"build\", \"preview\"].includes(arg)) &&\n // do not default to `connect studio` when help is present, instead show general help\n // for the `connect` command\n !args.some((arg) => [\"--help\", \"-h\"].includes(arg))\n ) {\n await runPhCliCommand(\"connect\");\n process.exit(0);\n }\n\n // forward command to the local ph-cli installation if it exists\n if (\n phCliCommandNames.includes(command as (typeof phCliCommandNames)[number])\n ) {\n await runPhCliCommand(command);\n process.exit(0);\n }\n\n await runPhCmdCommand(args);\n process.exit(0);\n}\n\nawait main().catch(async (error) => {\n const isDebug = process.argv.slice(2).includes(\"--debug\");\n // No-op when telemetry is disabled; flushes before we exit otherwise.\n await sentryClient?.captureCliError(error);\n if (isDebug) {\n throw error;\n }\n if (error instanceof Error) {\n console.error(error.message);\n process.exit(1);\n } else {\n throw error;\n }\n});\n"],"names":[],"mappings":";;;;;;;;;AAaA,MAAM,4BAA4B,IAAI,IAAI,CAAC,WAAW,QAAQ,CAAC;AAE/D,SAAS,uBAA2C;CAKlD,MAAM,KAAK,QAAQ,IAAI;AACvB,KAAI,CAAC,GAAI,QAAO,KAAA;AAChB,QAAO,GAAG,MAAM,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,MAAM,KAAA;;;;;;AAQ5C,eAAe,gBAAgB,cAAsB;CACnD,MAAM,EAAE,wBAAwB,MAAM,OAAO;AAC7C,QAAO,MAAM,oBAAoB,aAAa;;AAEhD,eAAe,gBAAgB,MAAgB;CAC7C,MAAM,EAAE,QAAQ,MAAM,OAAO;AAC7B,QAAO,MAAM,IAAI,KAAK;;AAGxB,IAAI,eAA4C,KAAA;AAEhD,eAAe,OAAO;AACpB,oBAAmB;AAGnB,gBAAe,MAAM,iBAAiB;EACpC,SAAS;EACT,SAAS,YAAY;EACtB,CAAC;CACF,MAAM,OAAO,QAAQ,KAAK,MAAM,EAAE;CAClC,MAAM,UAAU,KAAK;CACrB,MAAM,aACJ,WACA,0BAA0B,IAAI,QAAQ,IACtC,KAAK,MACL,CAAC,KAAK,GAAG,WAAW,IAAI,GACpB,KAAK,KACL,KAAA;AACN,eAAc,wBAAwB;EACpC;EACA;EACA,IAAI,sBAAsB;EAC1B,MAAM;EACN,KAAK,QAAQ,KAAK;EACnB,CAAC;AAMF,KAAI,KAAK,WAAW,MAAM,YAAY,eAAe,YAAY,OAAO;EACtE,MAAM,EAAE,wBAAwB,MAAM,OAAO;AAC7C,UAAQ,IAAI,MAAM,oBAAoB,YAAY,CAAC,CAAC;AACpD,UAAQ,KAAK,EAAE;;AAOjB,OAAM,oBAAoB;EACxB;EACA,gBAAgB,YAAY;EAC5B,aAAa,QAAQ,QAAQ,OAAO,MAAM;EAC3C,CAAC;AAIF,KACE,YAAY,aACZ,CAAC,KAAK,MAAM,QAAQ;EAAC;EAAU;EAAS;EAAU,CAAC,SAAS,IAAI,CAAC,IAGjE,CAAC,KAAK,MAAM,QAAQ,CAAC,UAAU,KAAK,CAAC,SAAS,IAAI,CAAC,EACnD;AACA,QAAM,gBAAgB,UAAU;AAChC,UAAQ,KAAK,EAAE;;AAIjB,KACE,kBAAkB,SAAS,QAA8C,EACzE;AACA,QAAM,gBAAgB,QAAQ;AAC9B,UAAQ,KAAK,EAAE;;AAGjB,OAAM,gBAAgB,KAAK;AAC3B,SAAQ,KAAK,EAAE;;AAGjB,MAAM,MAAM,CAAC,MAAM,OAAO,UAAU;CAClC,MAAM,UAAU,QAAQ,KAAK,MAAM,EAAE,CAAC,SAAS,UAAU;AAEzD,OAAM,cAAc,gBAAgB,MAAM;AAC1C,KAAI,QACF,OAAM;AAER,KAAI,iBAAiB,OAAO;AAC1B,UAAQ,MAAM,MAAM,QAAQ;AAC5B,UAAQ,KAAK,EAAE;OAEf,OAAM;EAER","debug_id":"3c343493-d1c1-53be-8105-8600810b1670"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a8fa3f98-459c-513d-a52e-b2e156cfb207")}catch(e){}}();
|
|
3
3
|
import { execSync } from "node:child_process";
|
|
4
4
|
//#region src/utils/delegate-init.ts
|
|
5
5
|
const PH_CLI_PACKAGE = "@powerhousedao/ph-cli";
|
|
@@ -69,5 +69,5 @@ async function delegateInit(args, extraForwardedArgs = []) {
|
|
|
69
69
|
//#endregion
|
|
70
70
|
export { delegateInit as t };
|
|
71
71
|
|
|
72
|
-
//# sourceMappingURL=delegate-init-
|
|
73
|
-
//# debugId=
|
|
72
|
+
//# sourceMappingURL=delegate-init-BiHdTmaF.mjs.map
|
|
73
|
+
//# debugId=a8fa3f98-459c-513d-a52e-b2e156cfb207
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"delegate-init-
|
|
1
|
+
{"version":3,"file":"delegate-init-BiHdTmaF.mjs","sources":["../src/utils/delegate-init.ts"],"sourcesContent":["import type { Agent } from \"package-manager-detector\";\nimport { execSync } from \"node:child_process\";\n\nconst PH_CLI_PACKAGE = \"@powerhousedao/ph-cli\";\n// `init` was added to ph-cli in the 6.x rewrite. Older versions (still on\n// the `latest` tag at time of writing) shell out via commander and bail with\n// a confusing \"unknown command 'init'\" error after a 90-second dlx install.\n// This floor lets us fail fast with an actionable message instead.\nconst MIN_PH_CLI_MAJOR = 6;\n\n/**\n * Subset of `initArgs` the delegator actually inspects. Keeping this loose\n * lets `setup-globals` reuse the helper without an extra type import dance.\n */\nexport interface DelegateInitArgs {\n packageManager?: Agent;\n npm?: boolean;\n pnpm?: boolean;\n yarn?: boolean;\n bun?: boolean;\n tag?: string;\n version?: string;\n dev?: boolean;\n staging?: boolean;\n rc?: boolean;\n debug?: boolean;\n}\n\n/**\n * Resolves a concrete `@powerhousedao/ph-cli` version, verifies it's >= 6.x,\n * and shells out via the user's package manager (npx / pnpm dlx / etc.) to\n * run `ph-cli init`. Used by both `ph init` (forwards verbatim) and\n * `ph setup-globals` (forwards with `--name .ph` injected after chdir to ~).\n *\n * Does NOT call `process.exit`: callers are responsible for any post-init\n * fix-up + exit.\n */\nexport async function delegateInit(\n args: DelegateInitArgs,\n extraForwardedArgs: string[] = [],\n): Promise<void> {\n const {\n fetchNpmVersionFromRegistryForTag,\n handleMutuallyExclusiveOptions,\n parsePackageManager,\n parseTag,\n } = await import(\"@powerhousedao/shared/clis\");\n\n handleMutuallyExclusiveOptions(\n {\n tag: args.tag,\n version: args.version,\n dev: args.dev,\n staging: args.staging,\n rc: args.rc,\n },\n \"versioning strategy\",\n );\n\n handleMutuallyExclusiveOptions(\n {\n npm: args.npm,\n pnpm: args.pnpm,\n yarn: args.yarn,\n bun: args.bun,\n packageManager: args.packageManager,\n },\n \"package manager\",\n );\n\n const tag = parseTag(args);\n const phCliVersionOrTag = args.version ?? tag;\n const pm = parsePackageManager(args) ?? \"npm\";\n // `process.argv` here is `[node, ph-cmd-bin, <subcommand>, ...userArgs]`.\n // Forward everything from the user, prepending caller-supplied flags.\n const forwardedArgs = [...extraForwardedArgs, ...process.argv.slice(3)];\n\n // Resolve the tag to a concrete version up front and verify it's >= 6.x.\n // `--version` is user-supplied so we trust it and only resolve when a tag\n // (latest/staging/dev) is in play.\n let resolvedVersion = args.version;\n try {\n if (!resolvedVersion) {\n resolvedVersion = await fetchNpmVersionFromRegistryForTag(\n PH_CLI_PACKAGE,\n tag,\n );\n }\n } catch (err) {\n // Network/registry hiccup — fall through to the dlx so a flaky\n // connection doesn't block the user. The dlx will surface its own\n // error if the version genuinely can't be installed.\n if (args.debug) {\n console.error(\">>> ph-cli version resolution skipped:\", err);\n }\n }\n const { coerce } = await import(\"semver\");\n const parsed = resolvedVersion ? coerce(resolvedVersion) : null;\n if (parsed && parsed.major < MIN_PH_CLI_MAJOR) {\n // Print + exit (rather than throw) to avoid the cli.ts catch handler\n // shipping this expected user-input error to Sentry.\n console.error(\n `${PH_CLI_PACKAGE}@${phCliVersionOrTag} resolves to ${resolvedVersion}, ` +\n `which doesn't support 'init' (requires >= ${MIN_PH_CLI_MAJOR}.0.0).\\n` +\n `Try: ph init --dev <args> or ph init --version <${MIN_PH_CLI_MAJOR}.x.x> <args>`,\n );\n process.exit(1);\n }\n\n const phCliPackage = `${PH_CLI_PACKAGE}@${resolvedVersion ?? phCliVersionOrTag}`;\n const { resolveCommand } = await import(\"package-manager-detector\");\n const resolved = resolveCommand(pm, \"execute\", [\n phCliPackage,\n \"init\",\n ...forwardedArgs,\n ]);\n\n if (!resolved) {\n throw new Error(\n `Could not resolve execute command for package manager \"${pm}\".`,\n );\n }\n\n const { injectPnpmAllowBuilds } = await import(\"@powerhousedao/shared/clis\");\n injectPnpmAllowBuilds(pm, resolved);\n\n const { command: cmd, args: cmdArgs } = resolved;\n const fullCmd = `${cmd} ${cmdArgs.join(\" \")}`;\n\n if (args.debug) {\n console.log(\">>> Delegating to ph-cli:\", fullCmd);\n }\n\n try {\n execSync(fullCmd, { stdio: \"inherit\" });\n } catch (err) {\n // Propagate normal non-zero exits but throw on abnormal exits to ensure\n // the error is reported.\n const e = err as {\n status?: number | null;\n signal?: NodeJS.Signals | null;\n };\n if (typeof e.status === \"number\" && !e.signal) {\n process.exit(e.status);\n }\n throw err;\n }\n}\n"],"names":[],"mappings":";;;;AAGA,MAAM,iBAAiB;AAKvB,MAAM,mBAAmB;;;;;;;;;;AA6BzB,eAAsB,aACpB,MACA,qBAA+B,EAAE,EAClB;CACf,MAAM,EACJ,mCACA,gCACA,qBACA,aACE,MAAM,OAAO;AAEjB,gCACE;EACE,KAAK,KAAK;EACV,SAAS,KAAK;EACd,KAAK,KAAK;EACV,SAAS,KAAK;EACd,IAAI,KAAK;EACV,EACD,sBACD;AAED,gCACE;EACE,KAAK,KAAK;EACV,MAAM,KAAK;EACX,MAAM,KAAK;EACX,KAAK,KAAK;EACV,gBAAgB,KAAK;EACtB,EACD,kBACD;CAED,MAAM,MAAM,SAAS,KAAK;CAC1B,MAAM,oBAAoB,KAAK,WAAW;CAC1C,MAAM,KAAK,oBAAoB,KAAK,IAAI;CAGxC,MAAM,gBAAgB,CAAC,GAAG,oBAAoB,GAAG,QAAQ,KAAK,MAAM,EAAE,CAAC;CAKvE,IAAI,kBAAkB,KAAK;AAC3B,KAAI;AACF,MAAI,CAAC,gBACH,mBAAkB,MAAM,kCACtB,gBACA,IACD;UAEI,KAAK;AAIZ,MAAI,KAAK,MACP,SAAQ,MAAM,0CAA0C,IAAI;;CAGhE,MAAM,EAAE,WAAW,MAAM,OAAO;CAChC,MAAM,SAAS,kBAAkB,OAAO,gBAAgB,GAAG;AAC3D,KAAI,UAAU,OAAO,QAAQ,kBAAkB;AAG7C,UAAQ,MACN,GAAG,eAAe,GAAG,kBAAkB,eAAe,gBAAgB,8CACvB,iBAAiB,+DACN,iBAAiB,cAC5E;AACD,UAAQ,KAAK,EAAE;;CAGjB,MAAM,eAAe,GAAG,eAAe,GAAG,mBAAmB;CAC7D,MAAM,EAAE,mBAAmB,MAAM,OAAO;CACxC,MAAM,WAAW,eAAe,IAAI,WAAW;EAC7C;EACA;EACA,GAAG;EACJ,CAAC;AAEF,KAAI,CAAC,SACH,OAAM,IAAI,MACR,0DAA0D,GAAG,IAC9D;CAGH,MAAM,EAAE,0BAA0B,MAAM,OAAO;AAC/C,uBAAsB,IAAI,SAAS;CAEnC,MAAM,EAAE,SAAS,KAAK,MAAM,YAAY;CACxC,MAAM,UAAU,GAAG,IAAI,GAAG,QAAQ,KAAK,IAAI;AAE3C,KAAI,KAAK,MACP,SAAQ,IAAI,6BAA6B,QAAQ;AAGnD,KAAI;AACF,WAAS,SAAS,EAAE,OAAO,WAAW,CAAC;UAChC,KAAK;EAGZ,MAAM,IAAI;AAIV,MAAI,OAAO,EAAE,WAAW,YAAY,CAAC,EAAE,OACrC,SAAQ,KAAK,EAAE,OAAO;AAExB,QAAM","debug_id":"a8fa3f98-459c-513d-a52e-b2e156cfb207"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import { t as delegateInit } from "./delegate-init-BiHdTmaF.mjs";
|
|
2
|
+
export { delegateInit };
|
|
3
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="fda490f2-c9df-5061-a8af-11fd881c2df9")}catch(e){}}();
|
|
4
|
+
//# debugId=fda490f2-c9df-5061-a8af-11fd881c2df9
|
|
@@ -5,12 +5,12 @@
|
|
|
5
5
|
* `bun run scripts/generate-commands-docs.ts` or `bun run src/cli.ts`).
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
8
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="e2358f09-76ed-53a8-80d6-3ca98286552c")}catch(e){}}();
|
|
9
9
|
function getVersion() {
|
|
10
|
-
return "6.2.3-dev.
|
|
10
|
+
return "6.2.3-dev.2";
|
|
11
11
|
}
|
|
12
12
|
//#endregion
|
|
13
13
|
export { getVersion as t };
|
|
14
14
|
|
|
15
|
-
//# sourceMappingURL=get-version-
|
|
16
|
-
//# debugId=
|
|
15
|
+
//# sourceMappingURL=get-version-CKWHzzHh.mjs.map
|
|
16
|
+
//# debugId=e2358f09-76ed-53a8-80d6-3ca98286552c
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-version-
|
|
1
|
+
{"version":3,"file":"get-version-CKWHzzHh.mjs","sources":["../src/get-version.ts"],"sourcesContent":["declare const CLI_VERSION: string | undefined;\ndeclare const CLI_GIT_SHA: string | undefined;\n\n/**\n * Returns the CLI version string. Replaced inline by tsdown's `define` at\n * build time; falls back to env vars when running un-bundled (e.g. via\n * `bun run scripts/generate-commands-docs.ts` or `bun run src/cli.ts`).\n */\nexport function getVersion() {\n if (typeof CLI_VERSION !== \"undefined\") return CLI_VERSION;\n return (\n process.env.WORKSPACE_VERSION ||\n process.env.npm_package_version ||\n \"unknown\"\n );\n}\n\nexport function getGitHash() {\n if (typeof CLI_GIT_SHA !== \"undefined\") return CLI_GIT_SHA;\n return process.env.WORKSPACE_GIT_SHA || \"unknown\";\n}\n"],"names":[],"mappings":";;;;;;;;AAQA,SAAgB,aAAa;AACa,QAAA","debug_id":"e2358f09-76ed-53a8-80d6-3ca98286552c"}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { t as getVersion } from "./get-version-
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="c314f2ec-070a-5cb6-ad21-e712b3eaa232")}catch(e){}}();
|
|
3
|
+
import { t as getVersion } from "./get-version-CKWHzzHh.mjs";
|
|
4
4
|
import { getPowerhouseProjectInfo } from "@powerhousedao/shared/clis";
|
|
5
|
-
import spawn from "cross-spawn";
|
|
5
|
+
import spawn$1 from "cross-spawn";
|
|
6
6
|
import { resolveCommand } from "package-manager-detector";
|
|
7
7
|
//#region src/ph-cli.ts
|
|
8
8
|
const PH_CLI_PACKAGE = "@powerhousedao/ph-cli";
|
|
@@ -29,7 +29,7 @@ async function executePhCliCommand(phCliCommand) {
|
|
|
29
29
|
injectPnpmAllowBuilds(packageManager, resolved);
|
|
30
30
|
}
|
|
31
31
|
const { command, args } = resolved;
|
|
32
|
-
const result = spawn.sync(command, args, {
|
|
32
|
+
const result = spawn$1.sync(command, args, {
|
|
33
33
|
stdio: "inherit",
|
|
34
34
|
cwd: projectPath ?? process.cwd()
|
|
35
35
|
});
|
|
@@ -40,5 +40,5 @@ async function executePhCliCommand(phCliCommand) {
|
|
|
40
40
|
//#endregion
|
|
41
41
|
export { executePhCliCommand };
|
|
42
42
|
|
|
43
|
-
//# sourceMappingURL=ph-cli-
|
|
44
|
-
//# debugId=
|
|
43
|
+
//# sourceMappingURL=ph-cli-BxlV6SZ2.mjs.map
|
|
44
|
+
//# debugId=c314f2ec-070a-5cb6-ad21-e712b3eaa232
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ph-cli-
|
|
1
|
+
{"version":3,"file":"ph-cli-BxlV6SZ2.mjs","sources":["../src/ph-cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { getPowerhouseProjectInfo } from \"@powerhousedao/shared/clis\";\nimport spawn from \"cross-spawn\";\nimport { resolveCommand } from \"package-manager-detector\";\nimport { getVersion } from \"./get-version.js\";\n\nconst PH_CLI_PACKAGE = \"@powerhousedao/ph-cli\";\n\n// Auth/identity commands write global state (~/.renown.json, ~/.npmrc), not a\n// project, so they run outside a project via dlx when no ph-cli is installed.\nconst PROJECT_OPTIONAL_COMMANDS = new Set([\n \"login\",\n \"logout\",\n \"registry-login\",\n]);\n\nexport async function executePhCliCommand(phCliCommand: string) {\n const forwardedArgs = process.argv.slice(3);\n const { projectPath, packageManager } = await getPowerhouseProjectInfo(\n undefined,\n { silent: true },\n );\n\n if (!projectPath && !PROJECT_OPTIONAL_COMMANDS.has(phCliCommand)) {\n throw new Error(\n `No Powerhouse project directory found, cannot run \\`ph ${phCliCommand}\\`.\\nTo create a local project, run \\`ph init\\`.\\nTo create a global project, run \\`ph setup-globals\\`.`,\n );\n }\n\n // In a project run the installed binary; otherwise dlx ph-cli pinned to this\n // ph-cmd version, falling back to `latest` when the version is unknown.\n const version = getVersion();\n const phCliTarget = projectPath\n ? \"ph-cli\"\n : `${PH_CLI_PACKAGE}@${version === \"unknown\" ? \"latest\" : version}`;\n const action = projectPath ? \"execute-local\" : \"execute\";\n\n const resolved = resolveCommand(packageManager, action, [\n phCliTarget,\n phCliCommand,\n ...forwardedArgs,\n ]);\n if (!resolved) {\n throw new Error(\n `Could not resolve a \"${action}\" command for package manager \"${packageManager}\" to run ph-cli. Supported package managers: npm, pnpm, yarn, bun.`,\n );\n }\n\n if (!projectPath) {\n const { injectPnpmAllowBuilds } =\n await import(\"@powerhousedao/shared/clis\");\n injectPnpmAllowBuilds(packageManager, resolved);\n }\n\n const { command, args } = resolved;\n // spawn (not a shell-joined string) so args with shell metacharacters — e.g.\n // `connect build --json '{\"a\":\"b\"}'` — survive intact. cross-spawn keeps that\n // guarantee on Windows too: `command` here is an npx/pnpm/yarn `.cmd` shim,\n // which node:child_process refuses to run without `shell: true` (spawn\n // EINVAL), and `shell: true` is exactly what would break those arguments.\n const result = spawn.sync(command, args, {\n stdio: \"inherit\",\n cwd: projectPath ?? process.cwd(),\n });\n if (result.error) throw result.error;\n if (result.signal) {\n throw new Error(`${command} terminated by signal ${result.signal}`);\n }\n if (typeof result.status === \"number\" && result.status !== 0) {\n process.exit(result.status);\n }\n}\n"],"names":["spawn"],"mappings":";;;;;;;AAMA,MAAM,iBAAiB;AAIvB,MAAM,4BAA4B,IAAI,IAAI;CACxC;CACA;CACA;CACD,CAAC;AAEF,eAAsB,oBAAoB,cAAsB;CAC9D,MAAM,gBAAgB,QAAQ,KAAK,MAAM,EAAE;CAC3C,MAAM,EAAE,aAAa,mBAAmB,MAAM,yBAC5C,KAAA,GACA,EAAE,QAAQ,MAAM,CACjB;AAED,KAAI,CAAC,eAAe,CAAC,0BAA0B,IAAI,aAAa,CAC9D,OAAM,IAAI,MACR,0DAA0D,aAAa,yGACxE;CAKH,MAAM,UAAU,YAAY;CAC5B,MAAM,cAAc,cAChB,WACA,GAAG,eAAe,GAAG,YAAY,YAAY,WAAW;CAC5D,MAAM,SAAS,cAAc,kBAAkB;CAE/C,MAAM,WAAW,eAAe,gBAAgB,QAAQ;EACtD;EACA;EACA,GAAG;EACJ,CAAC;AACF,KAAI,CAAC,SACH,OAAM,IAAI,MACR,wBAAwB,OAAO,iCAAiC,eAAe,oEAChF;AAGH,KAAI,CAAC,aAAa;EAChB,MAAM,EAAE,0BACN,MAAM,OAAO;AACf,wBAAsB,gBAAgB,SAAS;;CAGjD,MAAM,EAAE,SAAS,SAAS;CAM1B,MAAM,SAASA,QAAM,KAAK,SAAS,MAAM;EACvC,OAAO;EACP,KAAK,eAAe,QAAQ,KAAK;EAClC,CAAC;AACF,KAAI,OAAO,MAAO,OAAM,OAAO;AAC/B,KAAI,OAAO,OACT,OAAM,IAAI,MAAM,GAAG,QAAQ,wBAAwB,OAAO,SAAS;AAErE,KAAI,OAAO,OAAO,WAAW,YAAY,OAAO,WAAW,EACzD,SAAQ,KAAK,OAAO,OAAO","debug_id":"c314f2ec-070a-5cb6-ad21-e712b3eaa232"}
|
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { t as getVersion } from "./get-version-
|
|
4
|
-
import { t as
|
|
5
|
-
import {
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="83556561-3410-5523-ae16-bd17b5ed604c")}catch(e){}}();
|
|
3
|
+
import { t as getVersion } from "./get-version-CKWHzzHh.mjs";
|
|
4
|
+
import { i as setCacheCurrent, n as getStream, t as PH_CMD_STREAMS } from "./version-check-BxMITre2.mjs";
|
|
5
|
+
import { t as delegateInit } from "./delegate-init-BiHdTmaF.mjs";
|
|
6
|
+
import { readFile, realpath } from "node:fs/promises";
|
|
6
7
|
import path from "node:path";
|
|
8
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
9
|
+
import { spawn } from "cross-spawn";
|
|
7
10
|
import { boolean, command, flag, oneOf, option, optional, positional, run as run$1, string, subcommands } from "cmd-ts";
|
|
8
11
|
import { debugArgs, initArgs, phCliHelpCommands } from "@powerhousedao/shared/clis/args";
|
|
9
12
|
import { ALL_POWERHOUSE_DEPENDENCIES } from "@powerhousedao/shared/constants";
|
|
@@ -24,6 +27,188 @@ const init = command({
|
|
|
24
27
|
}
|
|
25
28
|
});
|
|
26
29
|
//#endregion
|
|
30
|
+
//#region src/utils/self-update.ts
|
|
31
|
+
const PACKAGE_NAME = "ph-cmd";
|
|
32
|
+
function normalizePath(p) {
|
|
33
|
+
return p.replace(/\\/g, "/").replace(/\/+$/, "");
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* Which package manager owns the running global install, resolved from the
|
|
37
|
+
* real path of the running bundle (the bin entry is a symlink; the ESM
|
|
38
|
+
* loader resolves it). Path signatures:
|
|
39
|
+
* pnpm: <global>/node_modules/.pnpm/ph-cmd@<v>/node_modules/ph-cmd/...
|
|
40
|
+
* bun: <home>/.bun/install/global/node_modules/ph-cmd/...
|
|
41
|
+
* yarn: <global>/yarn/global/node_modules/ph-cmd/... (yarn classic)
|
|
42
|
+
* npm: <prefix>/lib/node_modules/ph-cmd/... (any plain node_modules)
|
|
43
|
+
* A source checkout (<repo>/clis/ph-cmd/dist/cli.mjs) and any unrecognized
|
|
44
|
+
* layout are refused with a reason instead of guessing.
|
|
45
|
+
*/
|
|
46
|
+
function detectGlobalInstall(rawPath) {
|
|
47
|
+
const real = normalizePath(rawPath);
|
|
48
|
+
if (real.includes("/clis/ph-cmd/")) return {
|
|
49
|
+
pm: null,
|
|
50
|
+
reason: "source-checkout"
|
|
51
|
+
};
|
|
52
|
+
const pkgDir = real.endsWith(`/dist/cli.mjs`) ? real.slice(0, -13) : null;
|
|
53
|
+
if (!pkgDir || !pkgDir.endsWith(`/${PACKAGE_NAME}`)) return {
|
|
54
|
+
pm: null,
|
|
55
|
+
reason: "unknown"
|
|
56
|
+
};
|
|
57
|
+
if (real.includes(`/node_modules/.pnpm/${PACKAGE_NAME}@`)) return {
|
|
58
|
+
pm: "pnpm",
|
|
59
|
+
pkgRoot: pkgDir
|
|
60
|
+
};
|
|
61
|
+
if (real.includes("/.bun/install/global/node_modules/")) return {
|
|
62
|
+
pm: "bun",
|
|
63
|
+
pkgRoot: pkgDir
|
|
64
|
+
};
|
|
65
|
+
if (real.includes("/yarn/global/node_modules/")) return {
|
|
66
|
+
pm: "yarn",
|
|
67
|
+
pkgRoot: pkgDir
|
|
68
|
+
};
|
|
69
|
+
if (real.includes("/node_modules/")) return {
|
|
70
|
+
pm: "npm",
|
|
71
|
+
pkgRoot: pkgDir
|
|
72
|
+
};
|
|
73
|
+
return {
|
|
74
|
+
pm: null,
|
|
75
|
+
reason: "unknown"
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
const UPDATE_COMMANDS = {
|
|
79
|
+
npm: {
|
|
80
|
+
command: (spec) => `npm install -g ${spec}`,
|
|
81
|
+
argv: (spec) => [
|
|
82
|
+
"npm",
|
|
83
|
+
"install",
|
|
84
|
+
"-g",
|
|
85
|
+
spec
|
|
86
|
+
]
|
|
87
|
+
},
|
|
88
|
+
pnpm: {
|
|
89
|
+
command: (spec) => `pnpm add -g ${spec}`,
|
|
90
|
+
argv: (spec) => [
|
|
91
|
+
"pnpm",
|
|
92
|
+
"add",
|
|
93
|
+
"-g",
|
|
94
|
+
spec
|
|
95
|
+
]
|
|
96
|
+
},
|
|
97
|
+
bun: {
|
|
98
|
+
command: (spec) => `bun add -g ${spec}`,
|
|
99
|
+
argv: (spec) => [
|
|
100
|
+
"bun",
|
|
101
|
+
"add",
|
|
102
|
+
"-g",
|
|
103
|
+
spec
|
|
104
|
+
]
|
|
105
|
+
},
|
|
106
|
+
yarn: {
|
|
107
|
+
command: (spec) => `yarn global add ${spec}`,
|
|
108
|
+
argv: (spec) => [
|
|
109
|
+
"yarn",
|
|
110
|
+
"global",
|
|
111
|
+
"add",
|
|
112
|
+
spec
|
|
113
|
+
]
|
|
114
|
+
}
|
|
115
|
+
};
|
|
116
|
+
/** Human-readable update command (for error hints). */
|
|
117
|
+
function updateCommand(pm, tag) {
|
|
118
|
+
return UPDATE_COMMANDS[pm].command(`${PACKAGE_NAME}@${tag}`);
|
|
119
|
+
}
|
|
120
|
+
/** Exact argv used to spawn the package manager. */
|
|
121
|
+
function updateArgv(pm, tag) {
|
|
122
|
+
return UPDATE_COMMANDS[pm].argv(`${PACKAGE_NAME}@${tag}`);
|
|
123
|
+
}
|
|
124
|
+
function defaultSpawner(argv, opts) {
|
|
125
|
+
const { promise, resolve, reject } = Promise.withResolvers();
|
|
126
|
+
const child = spawn(argv[0], argv.slice(1), opts);
|
|
127
|
+
child.on("close", (code) => code === 0 ? resolve() : reject(/* @__PURE__ */ new Error(`${argv[0]} exited with code ${code}`)));
|
|
128
|
+
child.on("error", reject);
|
|
129
|
+
return promise;
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Upgrade the global ph-cmd install to `tag` (default: the running build's
|
|
133
|
+
* stream) using the owning package manager, then report the new version.
|
|
134
|
+
* Never throws: refusals and failures come back as `{ ok: false }` so the
|
|
135
|
+
* command layer owns the exit code.
|
|
136
|
+
*/
|
|
137
|
+
async function runSelfUpdate(opts) {
|
|
138
|
+
const { spawner = defaultSpawner, readFile: readFile$1 = (p) => readFile(p, "utf-8"), stdout = (line) => console.log(line), stderr = (line) => console.error(line), refreshCache } = opts.deps ?? {};
|
|
139
|
+
const detection = detectGlobalInstall(opts.realPath);
|
|
140
|
+
if (detection.pm === null) {
|
|
141
|
+
if (detection.reason === "source-checkout") {
|
|
142
|
+
const message = "ph is running from a source checkout; self-update only applies to global installs.";
|
|
143
|
+
stderr(message);
|
|
144
|
+
return {
|
|
145
|
+
ok: false,
|
|
146
|
+
message
|
|
147
|
+
};
|
|
148
|
+
}
|
|
149
|
+
const manual = Object.keys(UPDATE_COMMANDS).map((pm) => ` ${updateCommand(pm, "latest")}`).join("\n");
|
|
150
|
+
const message = `Couldn't determine how ph was installed (${opts.realPath}). Update manually:\n${manual}`;
|
|
151
|
+
stderr(message);
|
|
152
|
+
return {
|
|
153
|
+
ok: false,
|
|
154
|
+
message
|
|
155
|
+
};
|
|
156
|
+
}
|
|
157
|
+
const tag = opts.tag ?? getStream(opts.currentVersion);
|
|
158
|
+
stdout(`Updating ph-cmd via ${detection.pm} (${updateCommand(detection.pm, tag)})...`);
|
|
159
|
+
try {
|
|
160
|
+
await spawner(updateArgv(detection.pm, tag), { stdio: "inherit" });
|
|
161
|
+
} catch (error) {
|
|
162
|
+
const message = `ph-cmd update failed via ${detection.pm}. Try manually: ${updateCommand(detection.pm, tag)}`;
|
|
163
|
+
stderr(message);
|
|
164
|
+
if (error instanceof Error) stderr(error.message);
|
|
165
|
+
return {
|
|
166
|
+
ok: false,
|
|
167
|
+
message
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
let to = "unknown";
|
|
171
|
+
try {
|
|
172
|
+
const pkg = JSON.parse(await readFile$1(`${detection.pkgRoot}/package.json`));
|
|
173
|
+
if (typeof pkg.version === "string") to = pkg.version;
|
|
174
|
+
} catch {}
|
|
175
|
+
stdout(`Updated ph-cmd from ${opts.currentVersion} to ${to}. The new version takes effect on your next 'ph' run.`);
|
|
176
|
+
await refreshCache?.(to).catch(() => {});
|
|
177
|
+
return {
|
|
178
|
+
ok: true,
|
|
179
|
+
from: opts.currentVersion,
|
|
180
|
+
to
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
//#endregion
|
|
184
|
+
//#region src/commands/self-update.ts
|
|
185
|
+
const selfUpdate = command({
|
|
186
|
+
name: "self-update",
|
|
187
|
+
description: "Update the globally installed ph to the newest version of its release stream",
|
|
188
|
+
args: {
|
|
189
|
+
tag: option({
|
|
190
|
+
type: optional(string),
|
|
191
|
+
long: "tag",
|
|
192
|
+
short: "t",
|
|
193
|
+
description: `dist-tag to install (defaults to the running build's stream; e.g. ${PH_CMD_STREAMS.join(", ")})`
|
|
194
|
+
}),
|
|
195
|
+
...debugArgs
|
|
196
|
+
},
|
|
197
|
+
handler: async (args) => {
|
|
198
|
+
if (args.debug) console.log({ args });
|
|
199
|
+
const entry = process.argv[1];
|
|
200
|
+
const realPath = entry ? await realpath(entry) : import.meta.url.replace(/^file:\/\//, "");
|
|
201
|
+
const result = await runSelfUpdate({
|
|
202
|
+
currentVersion: getVersion(),
|
|
203
|
+
tag: args.tag,
|
|
204
|
+
realPath
|
|
205
|
+
});
|
|
206
|
+
if (!result.ok) process.exit(1);
|
|
207
|
+
await setCacheCurrent(result.to);
|
|
208
|
+
process.exit(0);
|
|
209
|
+
}
|
|
210
|
+
});
|
|
211
|
+
//#endregion
|
|
27
212
|
//#region src/commands/setup-globals.ts
|
|
28
213
|
const PH_GLOBAL_PACKAGE_NAME = "ph-global";
|
|
29
214
|
/**
|
|
@@ -63,7 +248,7 @@ const setupGlobals = command({
|
|
|
63
248
|
}
|
|
64
249
|
console.log("📦 Initializing global project...");
|
|
65
250
|
process.chdir(HOME_DIR);
|
|
66
|
-
const { delegateInit } = await import("./delegate-init-
|
|
251
|
+
const { delegateInit } = await import("./delegate-init-DwTgkpW-.mjs");
|
|
67
252
|
await delegateInit(args, ["--name", PH_GLOBAL_DIR_NAME]);
|
|
68
253
|
fixGlobalPackageName();
|
|
69
254
|
console.log(`🚀 Global project initialized successfully: ${POWERHOUSE_GLOBAL_DIR}`);
|
|
@@ -99,7 +284,7 @@ const update = command({
|
|
|
99
284
|
import("write-package"),
|
|
100
285
|
import("@powerhousedao/shared/clis"),
|
|
101
286
|
import("@powerhousedao/shared/registry"),
|
|
102
|
-
import("./update-packages-
|
|
287
|
+
import("./update-packages-BTDhXqEj.mjs")
|
|
103
288
|
]);
|
|
104
289
|
const registryUrl = resolveRegistryUrl({ projectPath: process.cwd() });
|
|
105
290
|
const packageJson = await readPackage();
|
|
@@ -353,6 +538,7 @@ const ph = subcommands({
|
|
|
353
538
|
init,
|
|
354
539
|
use,
|
|
355
540
|
update,
|
|
541
|
+
"self-update": selfUpdate,
|
|
356
542
|
"setup-globals": setupGlobals,
|
|
357
543
|
"use-local": useLocal,
|
|
358
544
|
...phCliHelpCommands
|
|
@@ -366,5 +552,5 @@ async function run(args) {
|
|
|
366
552
|
//#endregion
|
|
367
553
|
export { run };
|
|
368
554
|
|
|
369
|
-
//# sourceMappingURL=run-
|
|
370
|
-
//# debugId=
|
|
555
|
+
//# sourceMappingURL=run-0gjMNmbN.mjs.map
|
|
556
|
+
//# debugId=83556561-3410-5523-ae16-bd17b5ed604c
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-0gjMNmbN.mjs","sources":["../src/commands/init.ts","../src/utils/self-update.ts","../src/commands/self-update.ts","../src/commands/setup-globals.ts","../src/commands/update.ts","../src/commands/use-local.ts","../src/commands/use.ts","../src/commands/ph.ts","../src/run.ts"],"sourcesContent":["import { initArgs } from \"@powerhousedao/shared/clis/args\";\nimport { command } from \"cmd-ts\";\nimport { delegateInit } from \"../utils/delegate-init.js\";\n\n/**\n * Delegates `ph init` to the appropriate version of `@powerhousedao/ph-cli`.\n * This ensures the init logic (boilerplate, codegen) always matches the\n * ph-cli version being installed in the new project.\n */\nexport const init = command({\n name: \"init\",\n description: \"Initialize a new project\",\n args: initArgs,\n handler: async (args) => {\n if (args.debug) {\n console.log({ args });\n }\n await delegateInit(args);\n process.exit(0);\n },\n});\n","import { spawn as spawnChild } from \"cross-spawn\";\nimport { readFile as readFileAsync } from \"node:fs/promises\";\n\nimport { getStream } from \"./version-check.js\";\n\nexport type GlobalPackageManager = \"npm\" | \"pnpm\" | \"bun\" | \"yarn\";\n\nexport type InstallDetection =\n | { pm: GlobalPackageManager; pkgRoot: string }\n | { pm: null; reason: \"source-checkout\" | \"unknown\" };\n\nconst PACKAGE_NAME = \"ph-cmd\";\n\nfunction normalizePath(p: string): string {\n return p.replace(/\\\\/g, \"/\").replace(/\\/+$/, \"\");\n}\n\n/**\n * Which package manager owns the running global install, resolved from the\n * real path of the running bundle (the bin entry is a symlink; the ESM\n * loader resolves it). Path signatures:\n * pnpm: <global>/node_modules/.pnpm/ph-cmd@<v>/node_modules/ph-cmd/...\n * bun: <home>/.bun/install/global/node_modules/ph-cmd/...\n * yarn: <global>/yarn/global/node_modules/ph-cmd/... (yarn classic)\n * npm: <prefix>/lib/node_modules/ph-cmd/... (any plain node_modules)\n * A source checkout (<repo>/clis/ph-cmd/dist/cli.mjs) and any unrecognized\n * layout are refused with a reason instead of guessing.\n */\nexport function detectGlobalInstall(rawPath: string): InstallDetection {\n const real = normalizePath(rawPath);\n if (real.includes(\"/clis/ph-cmd/\")) {\n return { pm: null, reason: \"source-checkout\" };\n }\n const pkgDir = real.endsWith(`/dist/cli.mjs`)\n ? real.slice(0, -\"/dist/cli.mjs\".length)\n : null;\n if (!pkgDir || !pkgDir.endsWith(`/${PACKAGE_NAME}`)) {\n return { pm: null, reason: \"unknown\" };\n }\n if (real.includes(`/node_modules/.pnpm/${PACKAGE_NAME}@`)) {\n return { pm: \"pnpm\", pkgRoot: pkgDir };\n }\n if (real.includes(\"/.bun/install/global/node_modules/\")) {\n return { pm: \"bun\", pkgRoot: pkgDir };\n }\n if (real.includes(\"/yarn/global/node_modules/\")) {\n return { pm: \"yarn\", pkgRoot: pkgDir };\n }\n if (real.includes(\"/node_modules/\")) {\n return { pm: \"npm\", pkgRoot: pkgDir };\n }\n return { pm: null, reason: \"unknown\" };\n}\n\nconst UPDATE_COMMANDS: Record<\n GlobalPackageManager,\n { command: (spec: string) => string; argv: (spec: string) => string[] }\n> = {\n npm: {\n command: (spec) => `npm install -g ${spec}`,\n argv: (spec) => [\"npm\", \"install\", \"-g\", spec],\n },\n pnpm: {\n command: (spec) => `pnpm add -g ${spec}`,\n argv: (spec) => [\"pnpm\", \"add\", \"-g\", spec],\n },\n bun: {\n command: (spec) => `bun add -g ${spec}`,\n argv: (spec) => [\"bun\", \"add\", \"-g\", spec],\n },\n yarn: {\n command: (spec) => `yarn global add ${spec}`,\n argv: (spec) => [\"yarn\", \"global\", \"add\", spec],\n },\n};\n\n/** Human-readable update command (for error hints). */\nexport function updateCommand(pm: GlobalPackageManager, tag: string): string {\n return UPDATE_COMMANDS[pm].command(`${PACKAGE_NAME}@${tag}`);\n}\n\n/** Exact argv used to spawn the package manager. */\nexport function updateArgv(pm: GlobalPackageManager, tag: string): string[] {\n return UPDATE_COMMANDS[pm].argv(`${PACKAGE_NAME}@${tag}`);\n}\n\nexport type SelfUpdateDeps = {\n /** Runs a full argv (program first); rejects on non-zero exit. */\n spawner?: (argv: string[], opts: { stdio: \"inherit\" }) => Promise<void>;\n readFile?: (path: string) => Promise<string>;\n stdout?: (line: string) => void;\n stderr?: (line: string) => void;\n /** called with the new version after a successful update (clears the notice). */\n refreshCache?: (newVersion: string) => Promise<void>;\n};\n\nexport type SelfUpdateResult =\n | { ok: true; from: string; to: string }\n | { ok: false; message: string };\n\nfunction defaultSpawner(\n argv: string[],\n opts: { stdio: \"inherit\" },\n): Promise<void> {\n const { promise, resolve, reject } = Promise.withResolvers<void>();\n const child = spawnChild(argv[0], argv.slice(1), opts);\n child.on(\"close\", (code) =>\n code === 0\n ? resolve()\n : reject(new Error(`${argv[0]} exited with code ${code}`)),\n );\n child.on(\"error\", reject);\n return promise;\n}\n\n/**\n * Upgrade the global ph-cmd install to `tag` (default: the running build's\n * stream) using the owning package manager, then report the new version.\n * Never throws: refusals and failures come back as `{ ok: false }` so the\n * command layer owns the exit code.\n */\nexport async function runSelfUpdate(opts: {\n currentVersion: string;\n tag?: string;\n realPath: string;\n deps?: SelfUpdateDeps;\n}): Promise<SelfUpdateResult> {\n const {\n spawner = defaultSpawner,\n readFile = (p: string) => readFileAsync(p, \"utf-8\"),\n stdout = (line: string) => console.log(line),\n stderr = (line: string) => console.error(line),\n refreshCache,\n } = opts.deps ?? {};\n\n const detection = detectGlobalInstall(opts.realPath);\n if (detection.pm === null) {\n if (detection.reason === \"source-checkout\") {\n const message =\n \"ph is running from a source checkout; self-update only applies to global installs.\";\n stderr(message);\n return { ok: false, message };\n }\n const manual = (Object.keys(UPDATE_COMMANDS) as GlobalPackageManager[])\n .map((pm) => ` ${updateCommand(pm, \"latest\")}`)\n .join(\"\\n\");\n const message = `Couldn't determine how ph was installed (${opts.realPath}). Update manually:\\n${manual}`;\n stderr(message);\n return { ok: false, message };\n }\n\n const tag = opts.tag ?? getStream(opts.currentVersion);\n stdout(\n `Updating ph-cmd via ${detection.pm} (${updateCommand(detection.pm, tag)})...`,\n );\n try {\n await spawner(updateArgv(detection.pm, tag), { stdio: \"inherit\" });\n } catch (error: unknown) {\n const message = `ph-cmd update failed via ${detection.pm}. Try manually: ${updateCommand(detection.pm, tag)}`;\n stderr(message);\n if (error instanceof Error) stderr(error.message);\n return { ok: false, message };\n }\n\n let to = \"unknown\";\n try {\n const pkg = JSON.parse(\n await readFile(`${detection.pkgRoot}/package.json`),\n ) as { version?: unknown };\n if (typeof pkg.version === \"string\") to = pkg.version;\n } catch {\n // leave \"unknown\" — the PM already printed its own result\n }\n stdout(\n `Updated ph-cmd from ${opts.currentVersion} to ${to}. The new version takes effect on your next 'ph' run.`,\n );\n await refreshCache?.(to).catch(() => {});\n return { ok: true, from: opts.currentVersion, to };\n}\n","import { debugArgs } from \"@powerhousedao/shared/clis/args\";\nimport { command, optional, option, string } from \"cmd-ts\";\nimport { realpath } from \"node:fs/promises\";\nimport { PH_CMD_STREAMS, setCacheCurrent } from \"../utils/version-check.js\";\nimport { runSelfUpdate } from \"../utils/self-update.js\";\nimport { getVersion } from \"../get-version.js\";\n\nexport const selfUpdate = command({\n name: \"self-update\",\n description:\n \"Update the globally installed ph to the newest version of its release stream\",\n args: {\n tag: option({\n type: optional(string),\n long: \"tag\",\n short: \"t\",\n description: `dist-tag to install (defaults to the running build's stream; e.g. ${PH_CMD_STREAMS.join(\n \", \",\n )})`,\n }),\n ...debugArgs,\n },\n handler: async (args) => {\n if (args.debug) {\n console.log({ args });\n }\n // The real path of the running bundle identifies the global install\n // (and its package manager). argv[1] is the entry script; the ESM\n // loader already resolved symlinks, realpath is belt-and-braces.\n const entry = process.argv[1];\n const realPath = entry\n ? await realpath(entry)\n : import.meta.url.replace(/^file:\\/\\//, \"\");\n const result = await runSelfUpdate({\n currentVersion: getVersion(),\n tag: args.tag,\n realPath,\n });\n if (!result.ok) {\n process.exit(1);\n }\n // Quiet the notice on the next run: the new version is now current.\n await setCacheCurrent(result.to);\n process.exit(0);\n },\n});\n","import { initArgs } from \"@powerhousedao/shared/clis/args\";\nimport { command } from \"cmd-ts\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst PH_GLOBAL_PACKAGE_NAME = \"ph-global\";\n\n/**\n * `ph setup-globals` bootstraps the `~/.ph` project. It's the same flow as\n * `ph init` with `--name .ph` from the user's home directory, plus a\n * post-step that renames the package.json to `ph-global` (since `.ph` is\n * an invalid npm name).\n */\nexport const setupGlobals = command({\n name: \"setup-globals\",\n description: \"Initialize a new global project\",\n args: initArgs,\n handler: async (args) => {\n if (args.debug) {\n console.log({ args });\n }\n\n const { HOME_DIR, PH_GLOBAL_DIR_NAME, POWERHOUSE_GLOBAL_DIR } =\n await import(\"@powerhousedao/shared/clis\");\n\n /**\n * Fix the package.json `name` field for the global project — `.ph` is a\n * valid directory name but not a valid npm package name (vite + npm\n * reject names starting with a dot). We let `ph init` create the project\n * as `.ph` and then rename it here to `ph-global`.\n */\n const fixGlobalPackageName = (): void => {\n const packageJsonPath = path.join(POWERHOUSE_GLOBAL_DIR, \"package.json\");\n if (!existsSync(packageJsonPath)) return;\n try {\n const packageJson = JSON.parse(\n readFileSync(packageJsonPath, \"utf-8\"),\n ) as { name?: string };\n if (packageJson.name?.startsWith(\".\")) {\n packageJson.name = PH_GLOBAL_PACKAGE_NAME;\n writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));\n }\n } catch {\n // Ignore parse/write failures — leaves the file untouched.\n }\n };\n\n // The directory itself can exist without the project being bootstrapped —\n // telemetry writes `~/.ph/telemetry.json` early on. Use the presence of\n // `package.json` as the real \"is initialized\" signal.\n const globalPackageJson = path.join(POWERHOUSE_GLOBAL_DIR, \"package.json\");\n if (existsSync(globalPackageJson)) {\n // Repair-in-place: an older bootstrap may have left `name: \".ph\"` in\n // package.json, which breaks vite/npm. Fix it on every invocation.\n fixGlobalPackageName();\n console.log(`📦 Using global project: ${POWERHOUSE_GLOBAL_DIR}`);\n process.exit(0);\n }\n\n console.log(\"📦 Initializing global project...\");\n process.chdir(HOME_DIR);\n const { delegateInit } = await import(\"../utils/delegate-init.js\");\n await delegateInit(args, [\"--name\", PH_GLOBAL_DIR_NAME]);\n fixGlobalPackageName();\n console.log(\n `🚀 Global project initialized successfully: ${POWERHOUSE_GLOBAL_DIR}`,\n );\n process.exit(0);\n },\n});\n","import { debugArgs } from \"@powerhousedao/shared/clis/args\";\nimport { ALL_POWERHOUSE_DEPENDENCIES } from \"@powerhousedao/shared/constants\";\nimport { boolean, command, flag, optional } from \"cmd-ts\";\n\nexport const update = command({\n name: \"update\",\n description:\n \"Update your Powerhouse dependencies and installed packages to their latest versions\",\n args: {\n skipInstall: flag({\n type: optional(boolean),\n long: \"skip-install\",\n short: \"s\",\n description: \"Skip running `install` with your package manager\",\n }),\n updatePackages: flag({\n type: optional(boolean),\n long: \"update-packages\",\n description:\n \"Auto-update installed packages (powerhouse.config.json) to their newest same-major version\",\n }),\n ...debugArgs,\n },\n handler: async (args) => {\n const { skipInstall, updatePackages, debug } = args;\n if (debug) {\n console.log({ args });\n }\n console.log(`\\n▶️ Updating Powerhouse dependencies...\\n`);\n const [\n { default: chalk },\n { readPackage },\n { writePackage },\n { getTagFromVersion, logVersionUpdate, parsePackageVersion, runCmd },\n { resolveRegistryUrl },\n { updateInstalledPackages },\n ] = await Promise.all([\n import(\"chalk\"),\n import(\"read-pkg\"),\n import(\"write-package\"),\n import(\"@powerhousedao/shared/clis\"),\n import(\"@powerhousedao/shared/registry\"),\n import(\"./update-packages.js\"),\n ]);\n const registryUrl = resolveRegistryUrl({ projectPath: process.cwd() });\n const packageJson = await readPackage();\n\n if (packageJson.dependencies) {\n for (const [name, version] of Object.entries(packageJson.dependencies)) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.dependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, version] of Object.entries(\n packageJson.devDependencies,\n )) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.devDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.optionalDependencies) {\n for (const [name, version] of Object.entries(\n packageJson.optionalDependencies,\n )) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.optionalDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.peerDependencies) {\n for (const [name, version] of Object.entries(\n packageJson.peerDependencies,\n )) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.peerDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n await writePackage(packageJson);\n\n console.log(chalk.green(`\\n✅ Project updated successfully\\n`));\n\n // Detect the package manager once; it backs the install below and the\n // update of `local` (node_modules) installed packages.\n const { detect } = await import(\"package-manager-detector/detect\");\n const packageManager = await detect();\n\n await updateInstalledPackages({\n registryUrl,\n auto: updatePackages ?? false,\n skipInstall: skipInstall ?? false,\n packageManager,\n });\n\n if (skipInstall) return;\n\n if (!packageManager) {\n throw new Error(\n `❌ Failed to detect your package manager. Run install manually.`,\n );\n }\n console.log(\n `▶️ Installing updated dependencies with \\`${packageManager.agent}\\`\\n`,\n );\n runCmd(`${packageManager.agent} install`);\n process.exit(0);\n },\n});\n","import { debugArgs } from \"@powerhousedao/shared/clis/args\";\nimport {\n boolean,\n command,\n flag,\n option,\n optional,\n positional,\n string,\n} from \"cmd-ts\";\n\nexport const useLocal = command({\n name: \"use-local\",\n description:\n \"Use your local `powerhouse` monorepo dependencies the current project.\",\n args: {\n monorepoPathPositional: positional({\n type: optional(string),\n displayName: \"monorepo path\",\n description:\n \"Path to your local powerhouse monorepo relative to this project\",\n }),\n monorepoPathOption: option({\n type: optional(string),\n long: \"path\",\n short: \"p\",\n description:\n \"Path to your local powerhouse monorepo relative to this project\",\n }),\n skipInstall: flag({\n type: optional(boolean),\n long: \"skip-install\",\n short: \"s\",\n description: \"Skip running `install` with `pnpm`\",\n }),\n ...debugArgs,\n },\n handler: async (args) => {\n const { monorepoPathPositional, monorepoPathOption, skipInstall, debug } =\n args;\n if (debug) {\n console.log({ args });\n }\n const monorepoPath = monorepoPathPositional ?? monorepoPathOption;\n\n if (!monorepoPath) {\n throw new Error(\n \"❌ Please provide the path to your local powerhouse monorepo.\",\n );\n }\n\n const { runUseLocal } = await import(\"@powerhousedao/shared/clis\");\n await runUseLocal(monorepoPath, skipInstall);\n process.exit(0);\n },\n});\n","import { debugArgs } from \"@powerhousedao/shared/clis/args\";\nimport { ALL_POWERHOUSE_DEPENDENCIES } from \"@powerhousedao/shared/constants\";\nimport {\n boolean,\n command,\n flag,\n oneOf,\n option,\n optional,\n positional,\n run,\n string,\n} from \"cmd-ts\";\n\nexport const use = command({\n name: \"use\",\n description: \"Specify the release version of Powerhouse dependencies to use.\",\n args: {\n tagPositional: positional({\n type: optional(oneOf([\"latest\", \"staging\", \"dev\", \"rc\"])),\n displayName: \"tag\",\n description: `Specify the release tag to use for your project. Can be one of: \"latest\", \"staging\", \"dev\", or \"rc\".`,\n }),\n tagOption: option({\n type: optional(oneOf([\"latest\", \"staging\", \"dev\", \"rc\"])),\n long: \"tag\",\n short: \"t\",\n description: `Specify the release tag to use for your project. Can be one of: \"latest\", \"staging\", \"dev\", or \"rc\".`,\n }),\n version: option({\n type: optional(string),\n long: \"version\",\n short: \"v\",\n description:\n \"Specify the exact semver release version to use for your project.\",\n }),\n skipInstall: flag({\n type: optional(boolean),\n long: \"skip-install\",\n short: \"s\",\n description: \"Skip running `install` with your package manager\",\n }),\n ...debugArgs,\n },\n handler: async (args) => {\n const { tagPositional, tagOption, version, skipInstall, debug } = args;\n if (debug) {\n console.log({ args });\n }\n const tag = tagPositional ?? tagOption;\n const {\n handleMutuallyExclusiveOptions,\n logVersionUpdate,\n parsePackageVersion,\n runCmd,\n } = await import(\"@powerhousedao/shared/clis\");\n handleMutuallyExclusiveOptions({ tag, version }, \"versioning strategy\");\n\n if (!tag && !version) {\n throw new Error(\n \"Please specify either a release tag or a version to use.\",\n );\n }\n\n const [\n { default: chalk },\n { readPackage },\n { writePackage },\n { clean, valid },\n ] = await Promise.all([\n import(\"chalk\"),\n import(\"read-pkg\"),\n import(\"write-package\"),\n import(\"semver\"),\n ]);\n\n if (version && !valid(clean(version))) {\n throw new Error(`❌ Invalid version: ${chalk.bold(version)}`);\n }\n\n console.log(\n `▶️ Updating project to use ${chalk.bold(version ?? tag)}...\\n`,\n );\n\n const packageJson = await readPackage();\n\n if (packageJson.dependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.dependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.dependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.devDependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.devDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.optionalDependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.optionalDependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.optionalDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.peerDependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.peerDependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.peerDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n await writePackage(packageJson);\n\n console.log(\n chalk.green(\n `\\n✅ Project updated to use ${chalk.bold(version ?? tag)}\\n`,\n ),\n );\n\n if (!skipInstall) {\n const { detect } = await import(\"package-manager-detector/detect\");\n const packageManager = await detect();\n if (!packageManager) {\n throw new Error(\n `❌ Failed to detect your package manager. Run install manually.`,\n );\n }\n console.log(\n `▶️ Installing updated dependencies with \\`${packageManager.agent}\\`\\n`,\n );\n runCmd(`${packageManager.agent} install`);\n }\n\n process.exit(0);\n },\n});\n\nexport async function runUse(args: string[]) {\n await run(use, args);\n}\n","import { phCliHelpCommands } from \"@powerhousedao/shared/clis/args\";\nimport { subcommands } from \"cmd-ts\";\nimport { getVersion } from \"../get-version.js\";\nimport { init } from \"./init.js\";\nimport { selfUpdate } from \"./self-update.js\";\nimport { setupGlobals } from \"./setup-globals.js\";\nimport { update } from \"./update.js\";\nimport { useLocal } from \"./use-local.js\";\nimport { use } from \"./use.js\";\n\n// `--version` is intercepted in cli.ts before the subcommand tree is\n// constructed, so cmd-ts only needs the bare version string here. The\n// rich version output (with project info, package manager, etc.) is\n// produced by `getPhCmdVersionInfo` along that short-circuit path.\nexport const ph = subcommands({\n name: \"ph\",\n version: getVersion(),\n description:\n \"The Powerhouse CLI (ph-cmd) is a command-line interface tool that provides essential commands for managing Powerhouse projects.\\nThe tool and it's commands are fundamental for creating, building, and running Document Models as a builder in studio mode.\",\n cmds: {\n init,\n use,\n update,\n \"self-update\": selfUpdate,\n \"setup-globals\": setupGlobals,\n \"use-local\": useLocal,\n ...phCliHelpCommands,\n },\n});\n","import { run as runCmdTs } from \"cmd-ts\";\nimport { ph } from \"./commands/ph.js\";\n\nexport async function run(args: string[]) {\n return await runCmdTs(ph, args);\n}\n"],"names":["spawnChild","readFileAsync","readFile","runCmdTs"],"mappings":"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","debug_id":"83556561-3410-5523-ae16-bd17b5ed604c"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
3
|
-
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="9f4ee2ee-1b16-5029-9264-fd743423f35c")}catch(e){}}();
|
|
4
3
|
import { join } from "node:path";
|
|
4
|
+
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
5
5
|
import { cwd } from "node:process";
|
|
6
6
|
import { createInterface } from "node:readline/promises";
|
|
7
7
|
//#region src/commands/update-packages.ts
|
|
@@ -137,5 +137,5 @@ async function updateInstalledPackages(args) {
|
|
|
137
137
|
//#endregion
|
|
138
138
|
export { applyVersionBumps, fetchNpmVersions, findOutdatedPackages, isDistTag, promptForUpdates, resolveLatestSameMajor, updateInstalledPackages };
|
|
139
139
|
|
|
140
|
-
//# sourceMappingURL=update-packages-
|
|
141
|
-
//# debugId=
|
|
140
|
+
//# sourceMappingURL=update-packages-BTDhXqEj.mjs.map
|
|
141
|
+
//# debugId=9f4ee2ee-1b16-5029-9264-fd743423f35c
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update-packages-C5uE2aoa.mjs","sources":["../src/commands/update-packages.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\n\nexport interface ConfigPackage {\n packageName: string;\n version: string;\n provider?: \"registry\" | \"local\";\n [key: string]: unknown;\n}\n\nexport interface OutdatedPackage {\n name: string;\n currentVersion: string;\n newVersion: string;\n provider: \"registry\" | \"local\";\n}\n\nexport type ResolveLatest = (\n name: string,\n currentVersion: string,\n) => Promise<string | null>;\n\n/**\n * The slice of `semver` this module uses. It is injected (rather than\n * statically imported) because the CLI cold-path rule forbids static imports\n * of heavy modules in command files — the caller lazy-loads `semver` and\n * passes it in.\n */\nexport interface SemverFns {\n valid: (v: string | null) => unknown;\n clean: (v: string) => string | null;\n major: (v: string) => number;\n gt: (a: string, b: string) => boolean;\n compare: (a: string, b: string) => number;\n}\n\n/**\n * True when the stored value is a dist-tag (dev/staging/rc/latest) rather than\n * a concrete semver version. Dist-tags are re-resolved against the registry at\n * load time, so they self-update and must not be bumped.\n */\nexport function isDistTag(version: string, semver: SemverFns): boolean {\n return !semver.valid(semver.clean(version));\n}\n\n/**\n * Pure: decide which pinned packages have a newer release. Dist-tags are\n * skipped (they self-update via the tag). `resolveLatest` is injected so this\n * decision logic is testable without a network; `semver` is lazy-loaded.\n */\nexport async function findOutdatedPackages(\n packages: ConfigPackage[],\n resolveLatest: ResolveLatest,\n): Promise<OutdatedPackage[]> {\n const semver = await import(\"semver\");\n const outdated: OutdatedPackage[] = [];\n for (const pkg of packages) {\n if (!pkg.version || isDistTag(pkg.version, semver)) continue;\n const newVersion = await resolveLatest(pkg.packageName, pkg.version);\n if (newVersion && newVersion !== pkg.version) {\n outdated.push({\n name: pkg.packageName,\n currentVersion: pkg.version,\n newVersion,\n provider: pkg.provider === \"local\" ? \"local\" : \"registry\",\n });\n }\n }\n return outdated;\n}\n\n/**\n * Pure: bump the given packages' versions in place, preserving each entry's\n * provider and any other fields. Only the listed packages are touched.\n */\nexport function applyVersionBumps(\n config: { packages?: ConfigPackage[] },\n updates: Pick<OutdatedPackage, \"name\" | \"newVersion\">[],\n): void {\n const byName = new Map(updates.map((u) => [u.name, u.newVersion]));\n for (const pkg of config.packages ?? []) {\n const next = byName.get(pkg.packageName);\n if (next !== undefined) pkg.version = next;\n }\n}\n\n/** Fetch every published version string for a package from the registry. */\nexport async function fetchNpmVersions(\n name: string,\n registryUrl?: string,\n): Promise<string[]> {\n const { spawnAsync } = await import(\"@powerhousedao/shared/clis\");\n const args = [\"view\", name, \"versions\", \"--json\"];\n if (registryUrl) args.push(\"--registry\", registryUrl);\n try {\n const parsed: unknown = JSON.parse(await spawnAsync(\"npm\", args));\n return Array.isArray(parsed) ? (parsed as string[]) : [];\n } catch {\n return [];\n }\n}\n\n/**\n * The newest published version within the same major as `currentVersion`, or\n * null when the current version is already the newest in that major.\n */\nexport async function resolveLatestSameMajor(\n name: string,\n currentVersion: string,\n registryUrl?: string,\n): Promise<string | null> {\n const semver = await import(\"semver\");\n const current = semver.clean(currentVersion);\n if (!current || !semver.valid(current)) return null;\n const currentMajor = semver.major(current);\n const candidates = (await fetchNpmVersions(name, registryUrl))\n .map((v) => semver.clean(v))\n .filter((v): v is string => v !== null && semver.valid(v) !== null)\n .filter((v) => semver.major(v) === currentMajor && semver.gt(v, current));\n if (candidates.length === 0) return null;\n candidates.sort(semver.compare);\n return candidates[candidates.length - 1];\n}\n\n/** Interactive prompt; returns the subset of `outdated` the user accepts. */\nexport async function promptForUpdates(\n outdated: OutdatedPackage[],\n): Promise<OutdatedPackage[]> {\n const chosen: OutdatedPackage[] = [];\n for (const pkg of outdated) {\n const answer = await confirm(\n `${pkg.name} ${pkg.currentVersion} → ${pkg.newVersion} — update? [y/N]`,\n );\n if (answer) chosen.push(pkg);\n }\n return chosen;\n}\n\nasync function confirm(prompt: string): Promise<boolean> {\n const { default: chalk } = await import(\"chalk\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await rl.question(chalk.cyan(prompt))).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n } finally {\n rl.close();\n }\n}\n\nexport interface UpdateInstalledArgs {\n registryUrl?: string;\n /** true for `--update-packages`: apply automatically, no prompt. */\n auto: boolean;\n skipInstall: boolean;\n packageManager?: { agent: string } | null;\n /** Config file path; defaults to the cwd's powerhouse.config.json. */\n configPath?: string;\n /** Command runner; defaults to the shared `runCmd`. */\n runCommand?: (command: string) => void;\n /** Version resolver; defaults to `resolveLatestSameMajor`. */\n resolveLatest?: ResolveLatest;\n /** Interactive prompt; defaults to `promptForUpdates`. */\n prompt?: (outdated: OutdatedPackage[]) => Promise<OutdatedPackage[]>;\n}\n\n/**\n * The `ph update` step that keeps installed (powerhouse.config.json) packages\n * current. Bumps each outdated pinned package's version, writes the config,\n * and, for `local`-provider packages, runs the package manager's update.\n * Returns the names of the local packages it bumped.\n *\n * `chalk` and the shared CLI helpers are lazy-imported (CLI cold-path rule).\n * `runCommand`, `resolveLatest` and `prompt` are injectable for tests; they\n * default to the shared module's behavior.\n */\nexport async function updateInstalledPackages(\n args: UpdateInstalledArgs,\n): Promise<string[]> {\n const [chalkMod, { runCmd, POWERHOUSE_CONFIG_FILE }] = await Promise.all([\n import(\"chalk\"),\n import(\"@powerhousedao/shared/clis\"),\n ]);\n const chalk = chalkMod.default;\n const {\n registryUrl,\n auto,\n skipInstall,\n packageManager,\n resolveLatest,\n prompt,\n } = args;\n const run = args.runCommand ?? runCmd;\n const configPath = args.configPath ?? join(cwd(), POWERHOUSE_CONFIG_FILE);\n\n if (!existsSync(configPath)) return [];\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as {\n packages?: ConfigPackage[];\n };\n if (!config.packages?.length) return [];\n\n const resolve =\n resolveLatest ??\n ((name, version) => resolveLatestSameMajor(name, version, registryUrl));\n const outdated = await findOutdatedPackages(config.packages, resolve);\n if (outdated.length === 0) {\n console.log(chalk.dim(\"\\nInstalled packages are up to date.\"));\n return [];\n }\n\n const toUpdate = auto\n ? outdated\n : await (prompt ?? promptForUpdates)(outdated);\n if (toUpdate.length === 0) {\n console.log(chalk.dim(\"No packages updated.\"));\n return [];\n }\n\n for (const pkg of toUpdate) {\n console.log(\n chalk.green(` ↻ ${pkg.name} ${pkg.currentVersion} → ${pkg.newVersion}`),\n );\n }\n\n applyVersionBumps(config, toUpdate);\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n\n const localBumped = toUpdate\n .filter((pkg) => pkg.provider === \"local\")\n .map((pkg) => pkg.name);\n if (localBumped.length > 0 && !skipInstall && packageManager) {\n console.log(\n chalk.cyan(\n `\\nUpdating local package(s) with \\`${packageManager.agent}\\`...`,\n ),\n );\n run(`${packageManager.agent} update ${localBumped.join(\" \")}`);\n }\n\n return localBumped;\n}\n"],"names":[],"mappings":"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","debug_id":"9f9e24a7-bafe-520f-8956-eb7c8b328933"}
|
|
1
|
+
{"version":3,"file":"update-packages-BTDhXqEj.mjs","sources":["../src/commands/update-packages.ts"],"sourcesContent":["import { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { join } from \"node:path\";\nimport { cwd } from \"node:process\";\nimport { createInterface } from \"node:readline/promises\";\n\nexport interface ConfigPackage {\n packageName: string;\n version: string;\n provider?: \"registry\" | \"local\";\n [key: string]: unknown;\n}\n\nexport interface OutdatedPackage {\n name: string;\n currentVersion: string;\n newVersion: string;\n provider: \"registry\" | \"local\";\n}\n\nexport type ResolveLatest = (\n name: string,\n currentVersion: string,\n) => Promise<string | null>;\n\n/**\n * The slice of `semver` this module uses. It is injected (rather than\n * statically imported) because the CLI cold-path rule forbids static imports\n * of heavy modules in command files — the caller lazy-loads `semver` and\n * passes it in.\n */\nexport interface SemverFns {\n valid: (v: string | null) => unknown;\n clean: (v: string) => string | null;\n major: (v: string) => number;\n gt: (a: string, b: string) => boolean;\n compare: (a: string, b: string) => number;\n}\n\n/**\n * True when the stored value is a dist-tag (dev/staging/rc/latest) rather than\n * a concrete semver version. Dist-tags are re-resolved against the registry at\n * load time, so they self-update and must not be bumped.\n */\nexport function isDistTag(version: string, semver: SemverFns): boolean {\n return !semver.valid(semver.clean(version));\n}\n\n/**\n * Pure: decide which pinned packages have a newer release. Dist-tags are\n * skipped (they self-update via the tag). `resolveLatest` is injected so this\n * decision logic is testable without a network; `semver` is lazy-loaded.\n */\nexport async function findOutdatedPackages(\n packages: ConfigPackage[],\n resolveLatest: ResolveLatest,\n): Promise<OutdatedPackage[]> {\n const semver = await import(\"semver\");\n const outdated: OutdatedPackage[] = [];\n for (const pkg of packages) {\n if (!pkg.version || isDistTag(pkg.version, semver)) continue;\n const newVersion = await resolveLatest(pkg.packageName, pkg.version);\n if (newVersion && newVersion !== pkg.version) {\n outdated.push({\n name: pkg.packageName,\n currentVersion: pkg.version,\n newVersion,\n provider: pkg.provider === \"local\" ? \"local\" : \"registry\",\n });\n }\n }\n return outdated;\n}\n\n/**\n * Pure: bump the given packages' versions in place, preserving each entry's\n * provider and any other fields. Only the listed packages are touched.\n */\nexport function applyVersionBumps(\n config: { packages?: ConfigPackage[] },\n updates: Pick<OutdatedPackage, \"name\" | \"newVersion\">[],\n): void {\n const byName = new Map(updates.map((u) => [u.name, u.newVersion]));\n for (const pkg of config.packages ?? []) {\n const next = byName.get(pkg.packageName);\n if (next !== undefined) pkg.version = next;\n }\n}\n\n/** Fetch every published version string for a package from the registry. */\nexport async function fetchNpmVersions(\n name: string,\n registryUrl?: string,\n): Promise<string[]> {\n const { spawnAsync } = await import(\"@powerhousedao/shared/clis\");\n const args = [\"view\", name, \"versions\", \"--json\"];\n if (registryUrl) args.push(\"--registry\", registryUrl);\n try {\n const parsed: unknown = JSON.parse(await spawnAsync(\"npm\", args));\n return Array.isArray(parsed) ? (parsed as string[]) : [];\n } catch {\n return [];\n }\n}\n\n/**\n * The newest published version within the same major as `currentVersion`, or\n * null when the current version is already the newest in that major.\n */\nexport async function resolveLatestSameMajor(\n name: string,\n currentVersion: string,\n registryUrl?: string,\n): Promise<string | null> {\n const semver = await import(\"semver\");\n const current = semver.clean(currentVersion);\n if (!current || !semver.valid(current)) return null;\n const currentMajor = semver.major(current);\n const candidates = (await fetchNpmVersions(name, registryUrl))\n .map((v) => semver.clean(v))\n .filter((v): v is string => v !== null && semver.valid(v) !== null)\n .filter((v) => semver.major(v) === currentMajor && semver.gt(v, current));\n if (candidates.length === 0) return null;\n candidates.sort(semver.compare);\n return candidates[candidates.length - 1];\n}\n\n/** Interactive prompt; returns the subset of `outdated` the user accepts. */\nexport async function promptForUpdates(\n outdated: OutdatedPackage[],\n): Promise<OutdatedPackage[]> {\n const chosen: OutdatedPackage[] = [];\n for (const pkg of outdated) {\n const answer = await confirm(\n `${pkg.name} ${pkg.currentVersion} → ${pkg.newVersion} — update? [y/N]`,\n );\n if (answer) chosen.push(pkg);\n }\n return chosen;\n}\n\nasync function confirm(prompt: string): Promise<boolean> {\n const { default: chalk } = await import(\"chalk\");\n const rl = createInterface({ input: process.stdin, output: process.stdout });\n try {\n const answer = (await rl.question(chalk.cyan(prompt))).trim().toLowerCase();\n return answer === \"y\" || answer === \"yes\";\n } finally {\n rl.close();\n }\n}\n\nexport interface UpdateInstalledArgs {\n registryUrl?: string;\n /** true for `--update-packages`: apply automatically, no prompt. */\n auto: boolean;\n skipInstall: boolean;\n packageManager?: { agent: string } | null;\n /** Config file path; defaults to the cwd's powerhouse.config.json. */\n configPath?: string;\n /** Command runner; defaults to the shared `runCmd`. */\n runCommand?: (command: string) => void;\n /** Version resolver; defaults to `resolveLatestSameMajor`. */\n resolveLatest?: ResolveLatest;\n /** Interactive prompt; defaults to `promptForUpdates`. */\n prompt?: (outdated: OutdatedPackage[]) => Promise<OutdatedPackage[]>;\n}\n\n/**\n * The `ph update` step that keeps installed (powerhouse.config.json) packages\n * current. Bumps each outdated pinned package's version, writes the config,\n * and, for `local`-provider packages, runs the package manager's update.\n * Returns the names of the local packages it bumped.\n *\n * `chalk` and the shared CLI helpers are lazy-imported (CLI cold-path rule).\n * `runCommand`, `resolveLatest` and `prompt` are injectable for tests; they\n * default to the shared module's behavior.\n */\nexport async function updateInstalledPackages(\n args: UpdateInstalledArgs,\n): Promise<string[]> {\n const [chalkMod, { runCmd, POWERHOUSE_CONFIG_FILE }] = await Promise.all([\n import(\"chalk\"),\n import(\"@powerhousedao/shared/clis\"),\n ]);\n const chalk = chalkMod.default;\n const {\n registryUrl,\n auto,\n skipInstall,\n packageManager,\n resolveLatest,\n prompt,\n } = args;\n const run = args.runCommand ?? runCmd;\n const configPath = args.configPath ?? join(cwd(), POWERHOUSE_CONFIG_FILE);\n\n if (!existsSync(configPath)) return [];\n const config = JSON.parse(readFileSync(configPath, \"utf-8\")) as {\n packages?: ConfigPackage[];\n };\n if (!config.packages?.length) return [];\n\n const resolve =\n resolveLatest ??\n ((name, version) => resolveLatestSameMajor(name, version, registryUrl));\n const outdated = await findOutdatedPackages(config.packages, resolve);\n if (outdated.length === 0) {\n console.log(chalk.dim(\"\\nInstalled packages are up to date.\"));\n return [];\n }\n\n const toUpdate = auto\n ? outdated\n : await (prompt ?? promptForUpdates)(outdated);\n if (toUpdate.length === 0) {\n console.log(chalk.dim(\"No packages updated.\"));\n return [];\n }\n\n for (const pkg of toUpdate) {\n console.log(\n chalk.green(` ↻ ${pkg.name} ${pkg.currentVersion} → ${pkg.newVersion}`),\n );\n }\n\n applyVersionBumps(config, toUpdate);\n writeFileSync(configPath, JSON.stringify(config, null, 2));\n\n const localBumped = toUpdate\n .filter((pkg) => pkg.provider === \"local\")\n .map((pkg) => pkg.name);\n if (localBumped.length > 0 && !skipInstall && packageManager) {\n console.log(\n chalk.cyan(\n `\\nUpdating local package(s) with \\`${packageManager.agent}\\`...`,\n ),\n );\n run(`${packageManager.agent} update ${localBumped.join(\" \")}`);\n }\n\n return localBumped;\n}\n"],"names":[],"mappings":"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","debug_id":"9f4ee2ee-1b16-5029-9264-fd743423f35c"}
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="467e2f81-5d30-5dda-8f13-1fab828d106d")}catch(e){}}();
|
|
3
|
+
import semver from "semver";
|
|
4
|
+
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
5
|
+
import { homedir } from "node:os";
|
|
6
|
+
import { dirname, join } from "node:path";
|
|
7
|
+
//#region src/utils/version-check.ts
|
|
8
|
+
/**
|
|
9
|
+
* The release streams `ph self-update` knows about. The running build's
|
|
10
|
+
* stream is derived from its own version (see `getStream`); users can
|
|
11
|
+
* override it with `--tag`.
|
|
12
|
+
*/
|
|
13
|
+
const PH_CMD_STREAMS = ["latest", "dev"];
|
|
14
|
+
/**
|
|
15
|
+
* Which release stream a version belongs to: stable versions (no semver
|
|
16
|
+
* prerelease tag) live on `latest`, everything else (dev, staging, rc,
|
|
17
|
+
* test builds) on `dev` — the active development stream. A dev build must
|
|
18
|
+
* not be nagged toward an older stable release. Unparseable versions fall
|
|
19
|
+
* back to `latest` so a broken version string can never trigger a dev
|
|
20
|
+
* target.
|
|
21
|
+
*/
|
|
22
|
+
function getStream(version) {
|
|
23
|
+
const parsed = semver.parse(version);
|
|
24
|
+
if (!parsed) return "latest";
|
|
25
|
+
return parsed.prerelease.length > 0 ? "dev" : "latest";
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Whether the user should be nudged: true only when both versions parse
|
|
29
|
+
* AND the stream target sorts strictly above the running version (semver
|
|
30
|
+
* ordering, so a dev build correctly compares below its own release and
|
|
31
|
+
* below newer dev builds). Never nags on broken data or downgrades.
|
|
32
|
+
*/
|
|
33
|
+
function isOutdated(current, target) {
|
|
34
|
+
const currentParsed = semver.parse(current);
|
|
35
|
+
const targetParsed = semver.parse(target);
|
|
36
|
+
if (!currentParsed || !targetParsed) return false;
|
|
37
|
+
return semver.gt(targetParsed, currentParsed);
|
|
38
|
+
}
|
|
39
|
+
const NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
40
|
+
const PACKAGE_NAME = "ph-cmd";
|
|
41
|
+
const FETCH_TIMEOUT_MS = 2e3;
|
|
42
|
+
function parseCache(raw) {
|
|
43
|
+
if (typeof raw !== "object" || raw === null) return null;
|
|
44
|
+
const obj = raw;
|
|
45
|
+
if (typeof obj.checkedAt !== "string" || !Number.isFinite(Date.parse(obj.checkedAt))) return null;
|
|
46
|
+
if (typeof obj.target !== "string" || !semver.valid(obj.target)) return null;
|
|
47
|
+
if (obj.stream !== "latest" && obj.stream !== "dev") return null;
|
|
48
|
+
return {
|
|
49
|
+
checkedAt: obj.checkedAt,
|
|
50
|
+
stream: obj.stream,
|
|
51
|
+
target: obj.target
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
async function readCache(deps) {
|
|
55
|
+
let raw;
|
|
56
|
+
try {
|
|
57
|
+
raw = await deps.readFile(deps.cachePath);
|
|
58
|
+
} catch {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
try {
|
|
62
|
+
return parseCache(JSON.parse(raw));
|
|
63
|
+
} catch {
|
|
64
|
+
return null;
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Resolve the newest published version on the running build's release
|
|
69
|
+
* stream, using a 24 h on-disk cache. Never throws: a missing/corrupt
|
|
70
|
+
* cache or a failed fetch degrades to the stale value (or no result), so
|
|
71
|
+
* the check can never break the wrapped command.
|
|
72
|
+
*/
|
|
73
|
+
async function checkForNewerVersion(opts) {
|
|
74
|
+
const { deps } = opts;
|
|
75
|
+
const stream = getStream(opts.currentVersion);
|
|
76
|
+
const cached = await readCache(deps);
|
|
77
|
+
if (cached && cached.stream === stream && deps.now() - Date.parse(cached.checkedAt) < 864e5) return cached;
|
|
78
|
+
let target = null;
|
|
79
|
+
try {
|
|
80
|
+
const res = await deps.fetch(`${NPM_REGISTRY_URL}/${PACKAGE_NAME}/${stream}`, { signal: AbortSignal.timeout(FETCH_TIMEOUT_MS) });
|
|
81
|
+
if (res.ok) {
|
|
82
|
+
const body = await res.json();
|
|
83
|
+
if (typeof body.version === "string" && semver.valid(body.version)) target = body.version;
|
|
84
|
+
}
|
|
85
|
+
} catch {}
|
|
86
|
+
if (target) {
|
|
87
|
+
const checkedAt = new Date(deps.now()).toISOString();
|
|
88
|
+
try {
|
|
89
|
+
await deps.writeFile(deps.cachePath, JSON.stringify({
|
|
90
|
+
checkedAt,
|
|
91
|
+
stream,
|
|
92
|
+
target
|
|
93
|
+
}, null, 2));
|
|
94
|
+
} catch {}
|
|
95
|
+
return {
|
|
96
|
+
stream,
|
|
97
|
+
target,
|
|
98
|
+
checkedAt
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return cached && cached.stream === stream ? cached : null;
|
|
102
|
+
}
|
|
103
|
+
/** The exact one-line notice printed to stderr when the CLI is outdated. */
|
|
104
|
+
function formatOutdatedNotice(current, target, stream) {
|
|
105
|
+
return `A new version of ${PACKAGE_NAME} is available: ${target} (you have ${current} — ${stream} stream). Run 'ph self-update' to update.`;
|
|
106
|
+
}
|
|
107
|
+
/**
|
|
108
|
+
* Default deps for the bundled CLI: real registry fetch, wall clock, and
|
|
109
|
+
* the `~/.ph` cache file (the same directory telemetry bootstraps). Tests
|
|
110
|
+
* inject everything in `VersionCheckDeps` instead.
|
|
111
|
+
*/
|
|
112
|
+
function defaultDeps() {
|
|
113
|
+
return {
|
|
114
|
+
fetch: (url, init) => globalThis.fetch(url, init),
|
|
115
|
+
now: () => Date.now(),
|
|
116
|
+
readFile: (p) => readFile(p, "utf-8"),
|
|
117
|
+
writeFile: async (p, contents) => {
|
|
118
|
+
await mkdir(dirname(p), { recursive: true });
|
|
119
|
+
await writeFile(p, contents, "utf-8");
|
|
120
|
+
},
|
|
121
|
+
cachePath: join(homedir(), ".ph", "ph-cmd-self-update.json")
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
/**
|
|
125
|
+
* The single entry point `cli.ts` calls on every invocation, before
|
|
126
|
+
* dispatch. Skips help/version/self-update invocations, CI, and an
|
|
127
|
+
* explicit `PH_NO_UPDATE_CHECK=1` opt-out; refreshes the 24 h cache when
|
|
128
|
+
* stale; and prints the one-line notice to stderr only when the running
|
|
129
|
+
* build is outdated AND stderr is a TTY. Never throws and never blocks
|
|
130
|
+
* the wrapped command for more than the bounded fetch timeout.
|
|
131
|
+
*/
|
|
132
|
+
async function maybeNotifyOutdated(opts) {
|
|
133
|
+
const env = opts.env ?? process.env;
|
|
134
|
+
const first = opts.args[0];
|
|
135
|
+
if (opts.args.length === 0) return;
|
|
136
|
+
if (first === "--help" || first === "-h" || first === "--version" || first === "-v") return;
|
|
137
|
+
if (first === "self-update") return;
|
|
138
|
+
if (env.CI === "1" || env.PH_NO_UPDATE_CHECK === "1") return;
|
|
139
|
+
const deps = {
|
|
140
|
+
...defaultDeps(),
|
|
141
|
+
...opts.deps
|
|
142
|
+
};
|
|
143
|
+
const result = await checkForNewerVersion({
|
|
144
|
+
currentVersion: opts.currentVersion,
|
|
145
|
+
deps
|
|
146
|
+
}).catch(() => null);
|
|
147
|
+
if (!result || !isOutdated(opts.currentVersion, result.target)) return;
|
|
148
|
+
if (opts.stderrIsTty !== true) return;
|
|
149
|
+
(opts.writeStderr ?? ((line) => process.stderr.write(`${line}\n`)))(formatOutdatedNotice(opts.currentVersion, result.target, result.stream));
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Record a version as current so the next run's check is quiet (used by
|
|
153
|
+
* `ph self-update` right after a successful update: target == new current,
|
|
154
|
+
* so the outdated notice stops).
|
|
155
|
+
*/
|
|
156
|
+
async function setCacheCurrent(version, deps) {
|
|
157
|
+
const full = {
|
|
158
|
+
...defaultDeps(),
|
|
159
|
+
...deps
|
|
160
|
+
};
|
|
161
|
+
try {
|
|
162
|
+
await full.writeFile(full.cachePath, JSON.stringify({
|
|
163
|
+
checkedAt: new Date(full.now()).toISOString(),
|
|
164
|
+
stream: getStream(version),
|
|
165
|
+
target: version
|
|
166
|
+
}, null, 2));
|
|
167
|
+
} catch {}
|
|
168
|
+
}
|
|
169
|
+
//#endregion
|
|
170
|
+
export { setCacheCurrent as i, getStream as n, maybeNotifyOutdated as r, PH_CMD_STREAMS as t };
|
|
171
|
+
|
|
172
|
+
//# sourceMappingURL=version-check-BxMITre2.mjs.map
|
|
173
|
+
//# debugId=467e2f81-5d30-5dda-8f13-1fab828d106d
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"version-check-BxMITre2.mjs","sources":["../src/utils/version-check.ts"],"sourcesContent":["import semver from \"semver\";\nimport {\n mkdir,\n readFile as readFileAsync,\n writeFile as writeFileAsync,\n} from \"node:fs/promises\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\n\n/**\n * The release streams `ph self-update` knows about. The running build's\n * stream is derived from its own version (see `getStream`); users can\n * override it with `--tag`.\n */\nexport const PH_CMD_STREAMS = [\"latest\", \"dev\"] as const;\nexport type PhCmdStream = (typeof PH_CMD_STREAMS)[number];\n\n/**\n * Which release stream a version belongs to: stable versions (no semver\n * prerelease tag) live on `latest`, everything else (dev, staging, rc,\n * test builds) on `dev` — the active development stream. A dev build must\n * not be nagged toward an older stable release. Unparseable versions fall\n * back to `latest` so a broken version string can never trigger a dev\n * target.\n */\nexport function getStream(version: string): PhCmdStream {\n const parsed = semver.parse(version);\n if (!parsed) return \"latest\";\n return parsed.prerelease.length > 0 ? \"dev\" : \"latest\";\n}\n\n/**\n * Whether the user should be nudged: true only when both versions parse\n * AND the stream target sorts strictly above the running version (semver\n * ordering, so a dev build correctly compares below its own release and\n * below newer dev builds). Never nags on broken data or downgrades.\n */\nexport function isOutdated(current: string, target: string): boolean {\n const currentParsed = semver.parse(current);\n const targetParsed = semver.parse(target);\n if (!currentParsed || !targetParsed) return false;\n return semver.gt(targetParsed, currentParsed);\n}\n\nconst NPM_REGISTRY_URL = \"https://registry.npmjs.org\";\nconst PACKAGE_NAME = \"ph-cmd\";\nexport const CACHE_TTL_MS = 24 * 60 * 60 * 1000;\nconst FETCH_TIMEOUT_MS = 2000;\n\n/**\n * Injected for tests; the defaults below use the real registry, clock and\n * `~/.ph` cache file.\n */\nexport type VersionCheckDeps = {\n fetch: (url: string, init?: { signal?: AbortSignal }) => Promise<Response>;\n now: () => number;\n readFile: (path: string) => Promise<string>;\n writeFile: (path: string, contents: string) => Promise<void>;\n cachePath: string;\n};\n\nexport type VersionCheckResult = {\n stream: PhCmdStream;\n target: string;\n checkedAt: string;\n};\n\nfunction parseCache(raw: unknown): VersionCheckResult | null {\n if (typeof raw !== \"object\" || raw === null) return null;\n const obj = raw as Record<string, unknown>;\n if (\n typeof obj.checkedAt !== \"string\" ||\n !Number.isFinite(Date.parse(obj.checkedAt))\n )\n return null;\n if (typeof obj.target !== \"string\" || !semver.valid(obj.target)) return null;\n if (obj.stream !== \"latest\" && obj.stream !== \"dev\") return null;\n return { checkedAt: obj.checkedAt, stream: obj.stream, target: obj.target };\n}\n\nasync function readCache(\n deps: VersionCheckDeps,\n): Promise<VersionCheckResult | null> {\n let raw: string;\n try {\n raw = await deps.readFile(deps.cachePath);\n } catch {\n return null;\n }\n try {\n return parseCache(JSON.parse(raw));\n } catch {\n return null;\n }\n}\n\n/**\n * Resolve the newest published version on the running build's release\n * stream, using a 24 h on-disk cache. Never throws: a missing/corrupt\n * cache or a failed fetch degrades to the stale value (or no result), so\n * the check can never break the wrapped command.\n */\nexport async function checkForNewerVersion(opts: {\n currentVersion: string;\n deps: VersionCheckDeps;\n}): Promise<VersionCheckResult | null> {\n const { deps } = opts;\n const stream = getStream(opts.currentVersion);\n const cached = await readCache(deps);\n if (\n cached &&\n cached.stream === stream &&\n deps.now() - Date.parse(cached.checkedAt) < CACHE_TTL_MS\n ) {\n return cached;\n }\n let target: string | null = null;\n try {\n const res = await deps.fetch(\n `${NPM_REGISTRY_URL}/${PACKAGE_NAME}/${stream}`,\n {\n signal: AbortSignal.timeout(FETCH_TIMEOUT_MS),\n },\n );\n if (res.ok) {\n const body = (await res.json()) as { version?: unknown };\n if (typeof body.version === \"string\" && semver.valid(body.version)) {\n target = body.version;\n }\n }\n } catch {\n // offline / timeout — keep whatever we had\n }\n if (target) {\n const checkedAt = new Date(deps.now()).toISOString();\n try {\n await deps.writeFile(\n deps.cachePath,\n JSON.stringify({ checkedAt, stream, target }, null, 2),\n );\n } catch {\n // a failed cache write must not fail the check\n }\n return { stream, target, checkedAt };\n }\n return cached && cached.stream === stream ? cached : null;\n}\n\n/** The exact one-line notice printed to stderr when the CLI is outdated. */\nexport function formatOutdatedNotice(\n current: string,\n target: string,\n stream: PhCmdStream,\n): string {\n return `A new version of ${PACKAGE_NAME} is available: ${target} (you have ${current} — ${stream} stream). Run 'ph self-update' to update.`;\n}\n\n/**\n * Default deps for the bundled CLI: real registry fetch, wall clock, and\n * the `~/.ph` cache file (the same directory telemetry bootstraps). Tests\n * inject everything in `VersionCheckDeps` instead.\n */\nfunction defaultDeps(): VersionCheckDeps {\n return {\n fetch: (url, init) => globalThis.fetch(url, init),\n now: () => Date.now(),\n readFile: (p) => readFileAsync(p, \"utf-8\"),\n writeFile: async (p, contents) => {\n await mkdir(dirname(p), { recursive: true });\n await writeFileAsync(p, contents, \"utf-8\");\n },\n cachePath: join(homedir(), \".ph\", \"ph-cmd-self-update.json\"),\n };\n}\n\nexport type MaybeNotifyOptions = {\n /** process argv without the node + script entries. */\n args: string[];\n /** the running build's version (getVersion()). */\n currentVersion: string;\n /** true when stderr is interactive; non-TTY runs refresh but stay silent. */\n stderrIsTty?: boolean;\n /** injected for tests; defaults to process.env. */\n env?: Record<string, string | undefined>;\n /** partial deps for tests; defaults to the real registry + `~/.ph`. */\n deps?: Partial<VersionCheckDeps>;\n /** stderr sink for tests; defaults to process.stderr. */\n writeStderr?: (line: string) => void;\n};\n\n/**\n * The single entry point `cli.ts` calls on every invocation, before\n * dispatch. Skips help/version/self-update invocations, CI, and an\n * explicit `PH_NO_UPDATE_CHECK=1` opt-out; refreshes the 24 h cache when\n * stale; and prints the one-line notice to stderr only when the running\n * build is outdated AND stderr is a TTY. Never throws and never blocks\n * the wrapped command for more than the bounded fetch timeout.\n */\nexport async function maybeNotifyOutdated(\n opts: MaybeNotifyOptions,\n): Promise<void> {\n const env = opts.env ?? process.env;\n const first = opts.args[0];\n if (opts.args.length === 0) return;\n if (\n first === \"--help\" ||\n first === \"-h\" ||\n first === \"--version\" ||\n first === \"-v\"\n )\n return;\n if (first === \"self-update\") return;\n if (env.CI === \"1\" || env.PH_NO_UPDATE_CHECK === \"1\") return;\n\n const deps: VersionCheckDeps = { ...defaultDeps(), ...opts.deps };\n const result = await checkForNewerVersion({\n currentVersion: opts.currentVersion,\n deps,\n }).catch(() => null);\n if (!result || !isOutdated(opts.currentVersion, result.target)) return;\n if (opts.stderrIsTty !== true) return;\n const writeStderr =\n opts.writeStderr ?? ((line: string) => process.stderr.write(`${line}\\n`));\n writeStderr(\n formatOutdatedNotice(opts.currentVersion, result.target, result.stream),\n );\n}\n\n/**\n * Record a version as current so the next run's check is quiet (used by\n * `ph self-update` right after a successful update: target == new current,\n * so the outdated notice stops).\n */\nexport async function setCacheCurrent(\n version: string,\n deps?: Partial<VersionCheckDeps>,\n): Promise<void> {\n const full: VersionCheckDeps = { ...defaultDeps(), ...deps };\n try {\n await full.writeFile(\n full.cachePath,\n JSON.stringify(\n {\n checkedAt: new Date(full.now()).toISOString(),\n stream: getStream(version),\n target: version,\n },\n null,\n 2,\n ),\n );\n } catch {\n // best effort — the notice logic tolerates a missing cache\n }\n}\n"],"names":["readFileAsync","writeFileAsync"],"mappings":"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","debug_id":"467e2f81-5d30-5dda-8f13-1fab828d106d"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ph-cmd",
|
|
3
|
-
"version": "6.2.3-dev.
|
|
3
|
+
"version": "6.2.3-dev.2",
|
|
4
4
|
"description": "Powerhouse CLI — create Vetra projects, generate document models and editors, run local dev environments, and publish packages.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"type": "module",
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"author": "",
|
|
36
36
|
"dependencies": {
|
|
37
37
|
"cross-spawn": "7.0.6",
|
|
38
|
-
"@powerhousedao/shared": "6.2.3-dev.
|
|
38
|
+
"@powerhousedao/shared": "6.2.3-dev.2",
|
|
39
39
|
"@sentry/node-core": "^10.52.0",
|
|
40
40
|
"chalk": "5.6.2",
|
|
41
41
|
"cmd-ts": "0.15.0",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
48
|
"@types/cross-spawn": "6.0.6",
|
|
49
|
-
"@powerhousedao/codegen": "6.2.3-dev.
|
|
49
|
+
"@powerhousedao/codegen": "6.2.3-dev.2",
|
|
50
50
|
"tsdown": "0.21.1",
|
|
51
51
|
"vitest": "4.1.1"
|
|
52
52
|
},
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
import { t as delegateInit } from "./delegate-init-CGpBcDwe.mjs";
|
|
2
|
-
export { delegateInit };
|
|
3
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="f8902dca-8224-54b1-953d-5ab70d2effbf")}catch(e){}}();
|
|
4
|
-
//# debugId=f8902dca-8224-54b1-953d-5ab70d2effbf
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"run-C0dHDeMT.mjs","sources":["../src/commands/init.ts","../src/commands/setup-globals.ts","../src/commands/update.ts","../src/commands/use-local.ts","../src/commands/use.ts","../src/commands/ph.ts","../src/run.ts"],"sourcesContent":["import { initArgs } from \"@powerhousedao/shared/clis/args\";\nimport { command } from \"cmd-ts\";\nimport { delegateInit } from \"../utils/delegate-init.js\";\n\n/**\n * Delegates `ph init` to the appropriate version of `@powerhousedao/ph-cli`.\n * This ensures the init logic (boilerplate, codegen) always matches the\n * ph-cli version being installed in the new project.\n */\nexport const init = command({\n name: \"init\",\n description: \"Initialize a new project\",\n args: initArgs,\n handler: async (args) => {\n if (args.debug) {\n console.log({ args });\n }\n await delegateInit(args);\n process.exit(0);\n },\n});\n","import { initArgs } from \"@powerhousedao/shared/clis/args\";\nimport { command } from \"cmd-ts\";\nimport { existsSync, readFileSync, writeFileSync } from \"node:fs\";\nimport path from \"node:path\";\n\nconst PH_GLOBAL_PACKAGE_NAME = \"ph-global\";\n\n/**\n * `ph setup-globals` bootstraps the `~/.ph` project. It's the same flow as\n * `ph init` with `--name .ph` from the user's home directory, plus a\n * post-step that renames the package.json to `ph-global` (since `.ph` is\n * an invalid npm name).\n */\nexport const setupGlobals = command({\n name: \"setup-globals\",\n description: \"Initialize a new global project\",\n args: initArgs,\n handler: async (args) => {\n if (args.debug) {\n console.log({ args });\n }\n\n const { HOME_DIR, PH_GLOBAL_DIR_NAME, POWERHOUSE_GLOBAL_DIR } =\n await import(\"@powerhousedao/shared/clis\");\n\n /**\n * Fix the package.json `name` field for the global project — `.ph` is a\n * valid directory name but not a valid npm package name (vite + npm\n * reject names starting with a dot). We let `ph init` create the project\n * as `.ph` and then rename it here to `ph-global`.\n */\n const fixGlobalPackageName = (): void => {\n const packageJsonPath = path.join(POWERHOUSE_GLOBAL_DIR, \"package.json\");\n if (!existsSync(packageJsonPath)) return;\n try {\n const packageJson = JSON.parse(\n readFileSync(packageJsonPath, \"utf-8\"),\n ) as { name?: string };\n if (packageJson.name?.startsWith(\".\")) {\n packageJson.name = PH_GLOBAL_PACKAGE_NAME;\n writeFileSync(packageJsonPath, JSON.stringify(packageJson, null, 2));\n }\n } catch {\n // Ignore parse/write failures — leaves the file untouched.\n }\n };\n\n // The directory itself can exist without the project being bootstrapped —\n // telemetry writes `~/.ph/telemetry.json` early on. Use the presence of\n // `package.json` as the real \"is initialized\" signal.\n const globalPackageJson = path.join(POWERHOUSE_GLOBAL_DIR, \"package.json\");\n if (existsSync(globalPackageJson)) {\n // Repair-in-place: an older bootstrap may have left `name: \".ph\"` in\n // package.json, which breaks vite/npm. Fix it on every invocation.\n fixGlobalPackageName();\n console.log(`📦 Using global project: ${POWERHOUSE_GLOBAL_DIR}`);\n process.exit(0);\n }\n\n console.log(\"📦 Initializing global project...\");\n process.chdir(HOME_DIR);\n const { delegateInit } = await import(\"../utils/delegate-init.js\");\n await delegateInit(args, [\"--name\", PH_GLOBAL_DIR_NAME]);\n fixGlobalPackageName();\n console.log(\n `🚀 Global project initialized successfully: ${POWERHOUSE_GLOBAL_DIR}`,\n );\n process.exit(0);\n },\n});\n","import { debugArgs } from \"@powerhousedao/shared/clis/args\";\nimport { ALL_POWERHOUSE_DEPENDENCIES } from \"@powerhousedao/shared/constants\";\nimport { boolean, command, flag, optional } from \"cmd-ts\";\n\nexport const update = command({\n name: \"update\",\n description:\n \"Update your Powerhouse dependencies and installed packages to their latest versions\",\n args: {\n skipInstall: flag({\n type: optional(boolean),\n long: \"skip-install\",\n short: \"s\",\n description: \"Skip running `install` with your package manager\",\n }),\n updatePackages: flag({\n type: optional(boolean),\n long: \"update-packages\",\n description:\n \"Auto-update installed packages (powerhouse.config.json) to their newest same-major version\",\n }),\n ...debugArgs,\n },\n handler: async (args) => {\n const { skipInstall, updatePackages, debug } = args;\n if (debug) {\n console.log({ args });\n }\n console.log(`\\n▶️ Updating Powerhouse dependencies...\\n`);\n const [\n { default: chalk },\n { readPackage },\n { writePackage },\n { getTagFromVersion, logVersionUpdate, parsePackageVersion, runCmd },\n { resolveRegistryUrl },\n { updateInstalledPackages },\n ] = await Promise.all([\n import(\"chalk\"),\n import(\"read-pkg\"),\n import(\"write-package\"),\n import(\"@powerhousedao/shared/clis\"),\n import(\"@powerhousedao/shared/registry\"),\n import(\"./update-packages.js\"),\n ]);\n const registryUrl = resolveRegistryUrl({ projectPath: process.cwd() });\n const packageJson = await readPackage();\n\n if (packageJson.dependencies) {\n for (const [name, version] of Object.entries(packageJson.dependencies)) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.dependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, version] of Object.entries(\n packageJson.devDependencies,\n )) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.devDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.optionalDependencies) {\n for (const [name, version] of Object.entries(\n packageJson.optionalDependencies,\n )) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.optionalDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.peerDependencies) {\n for (const [name, version] of Object.entries(\n packageJson.peerDependencies,\n )) {\n if (version && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const tag = getTagFromVersion(version);\n const newVersion = await parsePackageVersion({ name, tag });\n packageJson.peerDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version,\n newVersion,\n });\n }\n }\n }\n\n await writePackage(packageJson);\n\n console.log(chalk.green(`\\n✅ Project updated successfully\\n`));\n\n // Detect the package manager once; it backs the install below and the\n // update of `local` (node_modules) installed packages.\n const { detect } = await import(\"package-manager-detector/detect\");\n const packageManager = await detect();\n\n await updateInstalledPackages({\n registryUrl,\n auto: updatePackages ?? false,\n skipInstall: skipInstall ?? false,\n packageManager,\n });\n\n if (skipInstall) return;\n\n if (!packageManager) {\n throw new Error(\n `❌ Failed to detect your package manager. Run install manually.`,\n );\n }\n console.log(\n `▶️ Installing updated dependencies with \\`${packageManager.agent}\\`\\n`,\n );\n runCmd(`${packageManager.agent} install`);\n process.exit(0);\n },\n});\n","import { debugArgs } from \"@powerhousedao/shared/clis/args\";\nimport {\n boolean,\n command,\n flag,\n option,\n optional,\n positional,\n string,\n} from \"cmd-ts\";\n\nexport const useLocal = command({\n name: \"use-local\",\n description:\n \"Use your local `powerhouse` monorepo dependencies the current project.\",\n args: {\n monorepoPathPositional: positional({\n type: optional(string),\n displayName: \"monorepo path\",\n description:\n \"Path to your local powerhouse monorepo relative to this project\",\n }),\n monorepoPathOption: option({\n type: optional(string),\n long: \"path\",\n short: \"p\",\n description:\n \"Path to your local powerhouse monorepo relative to this project\",\n }),\n skipInstall: flag({\n type: optional(boolean),\n long: \"skip-install\",\n short: \"s\",\n description: \"Skip running `install` with `pnpm`\",\n }),\n ...debugArgs,\n },\n handler: async (args) => {\n const { monorepoPathPositional, monorepoPathOption, skipInstall, debug } =\n args;\n if (debug) {\n console.log({ args });\n }\n const monorepoPath = monorepoPathPositional ?? monorepoPathOption;\n\n if (!monorepoPath) {\n throw new Error(\n \"❌ Please provide the path to your local powerhouse monorepo.\",\n );\n }\n\n const { runUseLocal } = await import(\"@powerhousedao/shared/clis\");\n await runUseLocal(monorepoPath, skipInstall);\n process.exit(0);\n },\n});\n","import { debugArgs } from \"@powerhousedao/shared/clis/args\";\nimport { ALL_POWERHOUSE_DEPENDENCIES } from \"@powerhousedao/shared/constants\";\nimport {\n boolean,\n command,\n flag,\n oneOf,\n option,\n optional,\n positional,\n run,\n string,\n} from \"cmd-ts\";\n\nexport const use = command({\n name: \"use\",\n description: \"Specify the release version of Powerhouse dependencies to use.\",\n args: {\n tagPositional: positional({\n type: optional(oneOf([\"latest\", \"staging\", \"dev\", \"rc\"])),\n displayName: \"tag\",\n description: `Specify the release tag to use for your project. Can be one of: \"latest\", \"staging\", \"dev\", or \"rc\".`,\n }),\n tagOption: option({\n type: optional(oneOf([\"latest\", \"staging\", \"dev\", \"rc\"])),\n long: \"tag\",\n short: \"t\",\n description: `Specify the release tag to use for your project. Can be one of: \"latest\", \"staging\", \"dev\", or \"rc\".`,\n }),\n version: option({\n type: optional(string),\n long: \"version\",\n short: \"v\",\n description:\n \"Specify the exact semver release version to use for your project.\",\n }),\n skipInstall: flag({\n type: optional(boolean),\n long: \"skip-install\",\n short: \"s\",\n description: \"Skip running `install` with your package manager\",\n }),\n ...debugArgs,\n },\n handler: async (args) => {\n const { tagPositional, tagOption, version, skipInstall, debug } = args;\n if (debug) {\n console.log({ args });\n }\n const tag = tagPositional ?? tagOption;\n const {\n handleMutuallyExclusiveOptions,\n logVersionUpdate,\n parsePackageVersion,\n runCmd,\n } = await import(\"@powerhousedao/shared/clis\");\n handleMutuallyExclusiveOptions({ tag, version }, \"versioning strategy\");\n\n if (!tag && !version) {\n throw new Error(\n \"Please specify either a release tag or a version to use.\",\n );\n }\n\n const [\n { default: chalk },\n { readPackage },\n { writePackage },\n { clean, valid },\n ] = await Promise.all([\n import(\"chalk\"),\n import(\"read-pkg\"),\n import(\"write-package\"),\n import(\"semver\"),\n ]);\n\n if (version && !valid(clean(version))) {\n throw new Error(`❌ Invalid version: ${chalk.bold(version)}`);\n }\n\n console.log(\n `▶️ Updating project to use ${chalk.bold(version ?? tag)}...\\n`,\n );\n\n const packageJson = await readPackage();\n\n if (packageJson.dependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.dependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.dependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.devDependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.devDependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.devDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.optionalDependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.optionalDependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.optionalDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n if (packageJson.peerDependencies) {\n for (const [name, existingVersion] of Object.entries(\n packageJson.peerDependencies,\n )) {\n if (existingVersion && ALL_POWERHOUSE_DEPENDENCIES.includes(name)) {\n const newVersion = await parsePackageVersion({ name, tag, version });\n packageJson.peerDependencies[name] = newVersion;\n logVersionUpdate({\n name,\n version: existingVersion,\n newVersion,\n });\n }\n }\n }\n\n await writePackage(packageJson);\n\n console.log(\n chalk.green(\n `\\n✅ Project updated to use ${chalk.bold(version ?? tag)}\\n`,\n ),\n );\n\n if (!skipInstall) {\n const { detect } = await import(\"package-manager-detector/detect\");\n const packageManager = await detect();\n if (!packageManager) {\n throw new Error(\n `❌ Failed to detect your package manager. Run install manually.`,\n );\n }\n console.log(\n `▶️ Installing updated dependencies with \\`${packageManager.agent}\\`\\n`,\n );\n runCmd(`${packageManager.agent} install`);\n }\n\n process.exit(0);\n },\n});\n\nexport async function runUse(args: string[]) {\n await run(use, args);\n}\n","import { phCliHelpCommands } from \"@powerhousedao/shared/clis/args\";\nimport { subcommands } from \"cmd-ts\";\nimport { getVersion } from \"../get-version.js\";\nimport { init } from \"./init.js\";\nimport { setupGlobals } from \"./setup-globals.js\";\nimport { update } from \"./update.js\";\nimport { useLocal } from \"./use-local.js\";\nimport { use } from \"./use.js\";\n\n// `--version` is intercepted in cli.ts before the subcommand tree is\n// constructed, so cmd-ts only needs the bare version string here. The\n// rich version output (with project info, package manager, etc.) is\n// produced by `getPhCmdVersionInfo` along that short-circuit path.\nexport const ph = subcommands({\n name: \"ph\",\n version: getVersion(),\n description:\n \"The Powerhouse CLI (ph-cmd) is a command-line interface tool that provides essential commands for managing Powerhouse projects.\\nThe tool and it's commands are fundamental for creating, building, and running Document Models as a builder in studio mode.\",\n cmds: {\n init,\n use,\n update,\n \"setup-globals\": setupGlobals,\n \"use-local\": useLocal,\n ...phCliHelpCommands,\n },\n});\n","import { run as runCmdTs } from \"cmd-ts\";\nimport { ph } from \"./commands/ph.js\";\n\nexport async function run(args: string[]) {\n return await runCmdTs(ph, args);\n}\n"],"names":["runCmdTs"],"mappings":"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","debug_id":"4e867ab2-f396-59cf-b416-30847523c980"}
|