@powerhousedao/shared 6.2.3-dev.24 → 6.2.3-dev.26
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/analytics/index.d.ts +4 -4
- package/dist/analytics/index.d.ts.map +1 -1
- package/dist/analytics/index.js +25 -24
- package/dist/analytics/index.js.map +1 -1
- package/dist/clis/args/{access-token-l4ne3id6.mjs → access-token-3Hqv_U8I.mjs} +2 -2
- package/dist/clis/args/{access-token-l4ne3id6.mjs.map → access-token-3Hqv_U8I.mjs.map} +1 -1
- package/dist/clis/args/access-token-C5sKsH2O.d.mts +16 -0
- package/dist/clis/args/access-token-C5sKsH2O.d.mts.map +1 -0
- package/dist/clis/args/access-token.d.mts +3 -2
- package/dist/clis/args/access-token.mjs +1 -1
- package/dist/clis/args/{common-BnSmBXOm.mjs → common-BXabdhiO.mjs} +3 -2
- package/dist/clis/args/{common-BnSmBXOm.mjs.map → common-BXabdhiO.mjs.map} +1 -1
- package/dist/clis/args/common-Bnm859xU.d.mts +186 -0
- package/dist/clis/args/common-Bnm859xU.d.mts.map +1 -0
- package/dist/clis/args/common.d.mts +3 -2
- package/dist/clis/args/common.mjs +1 -1
- package/dist/clis/args/{connect-CkPZNzui.mjs → connect-B6xK4YI_.mjs} +2 -2
- package/dist/clis/args/{connect-CkPZNzui.mjs.map → connect-B6xK4YI_.mjs.map} +1 -1
- package/dist/clis/args/connect-DjeiqXus.d.mts +450 -0
- package/dist/clis/args/connect-DjeiqXus.d.mts.map +1 -0
- package/dist/clis/args/connect.d.mts +3 -2
- package/dist/clis/args/connect.mjs +1 -1
- package/dist/clis/args/{generate-BzRnsIbV.mjs → generate-10dooJ-D.mjs} +2 -2
- package/dist/clis/args/{generate-BzRnsIbV.mjs.map → generate-10dooJ-D.mjs.map} +1 -1
- package/dist/clis/args/generate-DmgiCzuf.d.mts +106 -0
- package/dist/clis/args/generate-DmgiCzuf.d.mts.map +1 -0
- package/dist/clis/args/generate.d.mts +3 -2
- package/dist/clis/args/generate.mjs +1 -1
- package/dist/clis/args/help-DVPTARGn.d.mts +190 -0
- package/dist/clis/args/help-DVPTARGn.d.mts.map +1 -0
- package/dist/clis/args/{help-DnzLlEb7.mjs → help-yRmplJjW.mjs} +15 -15
- package/dist/clis/args/{help-DnzLlEb7.mjs.map → help-yRmplJjW.mjs.map} +1 -1
- package/dist/clis/args/help.d.mts +3 -2
- package/dist/clis/args/help.mjs +1 -1
- package/dist/clis/args/index.d.mts +20 -19
- package/dist/clis/args/index.mjs +18 -18
- package/dist/clis/args/init-CFeTq4Cq.d.mts +52 -0
- package/dist/clis/args/init-CFeTq4Cq.d.mts.map +1 -0
- package/dist/clis/args/{init-Q3FOdRyY.mjs → init-Dvb42Y87.mjs} +2 -2
- package/dist/clis/args/{init-Q3FOdRyY.mjs.map → init-Dvb42Y87.mjs.map} +1 -1
- package/dist/clis/args/init.d.mts +3 -2
- package/dist/clis/args/init.mjs +1 -1
- package/dist/clis/args/inspect-BjRmtB86.d.mts +13 -0
- package/dist/clis/args/inspect-BjRmtB86.d.mts.map +1 -0
- package/dist/clis/args/{inspect-99GSVTTt.mjs → inspect-UNQgtuR0.mjs} +2 -2
- package/dist/clis/args/{inspect-99GSVTTt.mjs.map → inspect-UNQgtuR0.mjs.map} +1 -1
- package/dist/clis/args/inspect.d.mts +3 -2
- package/dist/clis/args/inspect.mjs +1 -1
- package/dist/clis/args/install-B0tMyUMw.d.mts +37 -0
- package/dist/clis/args/install-B0tMyUMw.d.mts.map +1 -0
- package/dist/clis/args/{install-Dcal76Iq.mjs → install-F-27kF6m.mjs} +2 -2
- package/dist/clis/args/{install-Dcal76Iq.mjs.map → install-F-27kF6m.mjs.map} +1 -1
- package/dist/clis/args/install.d.mts +3 -2
- package/dist/clis/args/install.mjs +1 -1
- package/dist/clis/args/{list-BFbHTSf3.mjs → list-Bkfn8Yuo.mjs} +2 -2
- package/dist/clis/args/{list-BFbHTSf3.mjs.map → list-Bkfn8Yuo.mjs.map} +1 -1
- package/dist/clis/args/list-DrbxA7JJ.d.mts +10 -0
- package/dist/clis/args/list-DrbxA7JJ.d.mts.map +1 -0
- package/dist/clis/args/list.d.mts +3 -2
- package/dist/clis/args/list.mjs +1 -1
- package/dist/clis/args/{login-BB0WTY2n.mjs → login-CIFkQExi.mjs} +2 -2
- package/dist/clis/args/{login-BB0WTY2n.mjs.map → login-CIFkQExi.mjs.map} +1 -1
- package/dist/clis/args/login-CXRJXg71.d.mts +25 -0
- package/dist/clis/args/login-CXRJXg71.d.mts.map +1 -0
- package/dist/clis/args/login.d.mts +3 -2
- package/dist/clis/args/login.mjs +1 -1
- package/dist/clis/args/{magic-string.es-h_0HDQBQ.mjs → magic-string.es-BWtG0AyA.mjs} +33 -27
- package/dist/clis/args/magic-string.es-BWtG0AyA.mjs.map +1 -0
- package/dist/clis/args/migrate-DkCQRL2D.d.mts +19 -0
- package/dist/clis/args/migrate-DkCQRL2D.d.mts.map +1 -0
- package/dist/clis/args/{migrate-0xLgeOxh.mjs → migrate-DwJGhc2d.mjs} +2 -2
- package/dist/clis/args/{migrate-0xLgeOxh.mjs.map → migrate-DwJGhc2d.mjs.map} +1 -1
- package/dist/clis/args/migrate.d.mts +3 -2
- package/dist/clis/args/migrate.mjs +1 -1
- package/dist/clis/args/publish-CeW4bOrl.d.mts +16 -0
- package/dist/clis/args/publish-CeW4bOrl.d.mts.map +1 -0
- package/dist/clis/args/{publish-BJF3ET2v.mjs → publish-DHqlGWmL.mjs} +2 -2
- package/dist/clis/args/{publish-BJF3ET2v.mjs.map → publish-DHqlGWmL.mjs.map} +1 -1
- package/dist/clis/args/publish.d.mts +3 -2
- package/dist/clis/args/publish.mjs +1 -1
- package/dist/clis/args/{registry-CbORgFD8.mjs → registry-DIwES3l2.mjs} +2 -2
- package/dist/clis/args/{registry-CbORgFD8.mjs.map → registry-DIwES3l2.mjs.map} +1 -1
- package/dist/clis/args/registry-DNH8xuaE.d.mts +17 -0
- package/dist/clis/args/registry-DNH8xuaE.d.mts.map +1 -0
- package/dist/clis/args/registry.d.mts +3 -2
- package/dist/clis/args/registry.mjs +1 -1
- package/dist/clis/args/service-BBx5GDTc.d.mts +27 -0
- package/dist/clis/args/service-BBx5GDTc.d.mts.map +1 -0
- package/dist/clis/args/{service-BfDN3YBu.mjs → service-Cpjlyeu5.mjs} +2 -2
- package/dist/clis/args/{service-BfDN3YBu.mjs.map → service-Cpjlyeu5.mjs.map} +1 -1
- package/dist/clis/args/service.d.mts +3 -2
- package/dist/clis/args/service.mjs +1 -1
- package/dist/clis/args/{switchboard-tj30Z45Y.mjs → switchboard-CCaAtU56.mjs} +2 -2
- package/dist/clis/args/{switchboard-tj30Z45Y.mjs.map → switchboard-CCaAtU56.mjs.map} +1 -1
- package/dist/clis/args/switchboard-RrNb1fUH.d.mts +70 -0
- package/dist/clis/args/switchboard-RrNb1fUH.d.mts.map +1 -0
- package/dist/clis/args/switchboard.d.mts +3 -2
- package/dist/clis/args/switchboard.mjs +1 -1
- package/dist/clis/args/{uninstall-CjVkOmXN.mjs → uninstall-3U0B8g5c.mjs} +2 -2
- package/dist/clis/args/{uninstall-CjVkOmXN.mjs.map → uninstall-3U0B8g5c.mjs.map} +1 -1
- package/dist/clis/args/uninstall-CDx7lwxn.d.mts +28 -0
- package/dist/clis/args/uninstall-CDx7lwxn.d.mts.map +1 -0
- package/dist/clis/args/uninstall.d.mts +3 -2
- package/dist/clis/args/uninstall.mjs +1 -1
- package/dist/clis/args/unpublish-CEDsk6uv.d.mts +22 -0
- package/dist/clis/args/unpublish-CEDsk6uv.d.mts.map +1 -0
- package/dist/clis/args/{unpublish-DSvGNHhr.mjs → unpublish-s9zUh6Gw.mjs} +2 -2
- package/dist/clis/args/{unpublish-DSvGNHhr.mjs.map → unpublish-s9zUh6Gw.mjs.map} +1 -1
- package/dist/clis/args/unpublish.d.mts +3 -2
- package/dist/clis/args/unpublish.mjs +1 -1
- package/dist/clis/args/{vetra-CMIe5hyF.mjs → vetra-BUNlAAPp.mjs} +2 -2
- package/dist/clis/args/{vetra-CMIe5hyF.mjs.map → vetra-BUNlAAPp.mjs.map} +1 -1
- package/dist/clis/args/vetra-DkDaWFPi.d.mts +111 -0
- package/dist/clis/args/vetra-DkDaWFPi.d.mts.map +1 -0
- package/dist/clis/args/vetra-ports.test.d.mts +2 -1
- package/dist/clis/args/vetra-ports.test.mjs +285 -180
- package/dist/clis/args/vetra-ports.test.mjs.map +1 -1
- package/dist/clis/args/vetra.d.mts +3 -2
- package/dist/clis/args/vetra.mjs +1 -1
- package/dist/clis/{build-config-BkfXtfV8.mjs → build-config-CmdMi_wu.mjs} +3 -3
- package/dist/clis/{build-config-BkfXtfV8.mjs.map → build-config-CmdMi_wu.mjs.map} +1 -1
- package/dist/clis/build-config.d.mts +20 -17
- package/dist/clis/build-config.d.mts.map +1 -1
- package/dist/clis/build-config.mjs +1 -1
- package/dist/clis/build-pieces.d.mts +43 -37
- package/dist/clis/build-pieces.d.mts.map +1 -1
- package/dist/clis/build-pieces.mjs +3 -2
- package/dist/clis/build-pieces.mjs.map +1 -1
- package/dist/clis/command-names.d.mts +2 -2
- package/dist/clis/command-names.d.mts.map +1 -1
- package/dist/clis/command-names.mjs.map +1 -1
- package/dist/clis/constants.d.mts +3 -2
- package/dist/clis/constants.mjs +2 -2
- package/dist/clis/constants.mjs.map +1 -1
- package/dist/clis/{index-CyAv0ucZ.d.mts → index-6CZwrmQi.d.mts} +1800 -1265
- package/dist/clis/index-6CZwrmQi.d.mts.map +1 -0
- package/dist/clis/index.d.mts +1288 -1257
- package/dist/clis/index.d.mts.map +1 -1
- package/dist/clis/index.mjs +51 -29
- package/dist/clis/index.mjs.map +1 -1
- package/dist/clis/project-env.d.mts +4 -4
- package/dist/clis/project-env.d.mts.map +1 -1
- package/dist/clis/project-env.mjs.map +1 -1
- package/dist/clis/project-ports.d.mts +5 -5
- package/dist/clis/project-ports.d.mts.map +1 -1
- package/dist/clis/project-ports.mjs +1 -1
- package/dist/clis/project-ports.mjs.map +1 -1
- package/dist/clis/services/telemetry.d.mts +7 -7
- package/dist/clis/services/telemetry.d.mts.map +1 -1
- package/dist/clis/services/telemetry.mjs.map +1 -1
- package/dist/clis/{types-B-Il50oC.d.mts → types-CMFHKrgv.d.mts} +66 -29
- package/dist/clis/types-CMFHKrgv.d.mts.map +1 -0
- package/dist/clis/utils.d.mts +4 -4
- package/dist/clis/utils.d.mts.map +1 -1
- package/dist/clis/utils.mjs.map +1 -1
- package/dist/{config-loader-DcwNJiBB.js → config-loader-SYDWHtqk.js} +3 -1
- package/dist/{config-loader-DcwNJiBB.js.map → config-loader-SYDWHtqk.js.map} +1 -1
- package/dist/connect/config-loader.d.ts +7 -8
- package/dist/connect/config-loader.d.ts.map +1 -1
- package/dist/connect/config-loader.js +1 -1
- package/dist/connect/index.d.ts +69 -68
- package/dist/connect/index.d.ts.map +1 -1
- package/dist/connect/index.js +55 -5
- package/dist/connect/index.js.map +1 -1
- package/dist/connect/json-adapter.d.ts +3 -4
- package/dist/connect/json-adapter.d.ts.map +1 -1
- package/dist/connect/json-adapter.js.map +1 -1
- package/dist/{constants-BP_gjn8g.d.ts → constants-DO4IYxuR.d.ts} +2 -1
- package/dist/constants-DO4IYxuR.d.ts.map +1 -0
- package/dist/constants.d.ts +3 -2
- package/dist/constants.js.map +1 -1
- package/dist/document-drive/index.d.ts +101 -99
- package/dist/document-drive/index.d.ts.map +1 -1
- package/dist/document-drive/index.js.map +1 -1
- package/dist/document-model/index.d.ts +5 -4
- package/dist/document-model/index.js +51 -45
- package/dist/document-model/index.js.map +1 -1
- package/dist/document-model/mock.d.ts +2 -3
- package/dist/document-model/mock.d.ts.map +1 -1
- package/dist/document-model/mock.js +2 -1
- package/dist/document-model/mock.js.map +1 -1
- package/dist/document-model/utils.d.ts +3 -2
- package/dist/document-model/utils.js +1 -1
- package/dist/{index-BmL07S5O.d.ts → index-CDDyUSHE.d.ts} +17 -14
- package/dist/index-CDDyUSHE.d.ts.map +1 -0
- package/dist/index-D0JljlgO.d.ts +36 -0
- package/dist/index-D0JljlgO.d.ts.map +1 -0
- package/dist/index.d.ts +7 -6
- package/dist/index.js.map +1 -1
- package/dist/processors/index.d.ts +3 -2
- package/dist/processors/index.js +5 -1
- package/dist/processors/index.js.map +1 -1
- package/dist/registry/index.d.ts +15 -15
- package/dist/registry/index.d.ts.map +1 -1
- package/dist/registry/index.js +2 -1
- package/dist/registry/index.js.map +1 -1
- package/dist/registry/manifest-slim.d.ts +4 -3
- package/dist/registry/manifest-slim.d.ts.map +1 -1
- package/dist/registry/manifest-slim.js.map +1 -1
- package/dist/registry/updates.d.ts +3 -3
- package/dist/registry/updates.d.ts.map +1 -1
- package/dist/registry/updates.js.map +1 -1
- package/dist/registry/urls.d.ts +2 -2
- package/dist/registry/urls.d.ts.map +1 -1
- package/dist/registry/urls.js.map +1 -1
- package/dist/{types-C1in4fl3.d.ts → types-Bsp8VL2y.d.ts} +2 -2
- package/dist/types-Bsp8VL2y.d.ts.map +1 -0
- package/dist/{types-DhOXIQ4c.d.ts → types-VDHUeQnm.d.ts} +17 -40
- package/dist/types-VDHUeQnm.d.ts.map +1 -0
- package/dist/{types-COsoOK42.d.ts → types-xLPOHE23.d.ts} +281 -196
- package/dist/types-xLPOHE23.d.ts.map +1 -0
- package/dist/{utils-DP122OSS.d.ts → utils-BrKxCmKx.d.ts} +2 -2
- package/dist/utils-BrKxCmKx.d.ts.map +1 -0
- package/dist/{utils-aaTmfxFW.js → utils-XotexSsQ.js} +3 -2
- package/dist/{utils-aaTmfxFW.js.map → utils-XotexSsQ.js.map} +1 -1
- package/package.json +5 -5
- package/dist/clis/args/access-token--9H57y8J.d.mts +0 -18
- package/dist/clis/args/access-token--9H57y8J.d.mts.map +0 -1
- package/dist/clis/args/common-Bc6Phg3O.d.mts +0 -189
- package/dist/clis/args/common-Bc6Phg3O.d.mts.map +0 -1
- package/dist/clis/args/connect-BD-C5BkE.d.mts +0 -452
- package/dist/clis/args/connect-BD-C5BkE.d.mts.map +0 -1
- package/dist/clis/args/generate-rd5SAYho.d.mts +0 -108
- package/dist/clis/args/generate-rd5SAYho.d.mts.map +0 -1
- package/dist/clis/args/help-CjAsudUn.d.mts +0 -193
- package/dist/clis/args/help-CjAsudUn.d.mts.map +0 -1
- package/dist/clis/args/init-CUXyfquF.d.mts +0 -55
- package/dist/clis/args/init-CUXyfquF.d.mts.map +0 -1
- package/dist/clis/args/inspect-DtZeoA5c.d.mts +0 -15
- package/dist/clis/args/inspect-DtZeoA5c.d.mts.map +0 -1
- package/dist/clis/args/install-CkP8zcHb.d.mts +0 -40
- package/dist/clis/args/install-CkP8zcHb.d.mts.map +0 -1
- package/dist/clis/args/list-BGf8s_gj.d.mts +0 -12
- package/dist/clis/args/list-BGf8s_gj.d.mts.map +0 -1
- package/dist/clis/args/login-DNsHwvqk.d.mts +0 -27
- package/dist/clis/args/login-DNsHwvqk.d.mts.map +0 -1
- package/dist/clis/args/magic-string.es-h_0HDQBQ.mjs.map +0 -1
- package/dist/clis/args/migrate-sixkWhxm.d.mts +0 -21
- package/dist/clis/args/migrate-sixkWhxm.d.mts.map +0 -1
- package/dist/clis/args/publish-Dqe5DUst.d.mts +0 -18
- package/dist/clis/args/publish-Dqe5DUst.d.mts.map +0 -1
- package/dist/clis/args/registry-C_RfTsKB.d.mts +0 -19
- package/dist/clis/args/registry-C_RfTsKB.d.mts.map +0 -1
- package/dist/clis/args/service-DhIkf8-O.d.mts +0 -22
- package/dist/clis/args/service-DhIkf8-O.d.mts.map +0 -1
- package/dist/clis/args/switchboard-BlPaq2at.d.mts +0 -72
- package/dist/clis/args/switchboard-BlPaq2at.d.mts.map +0 -1
- package/dist/clis/args/uninstall-BpA3YYbw.d.mts +0 -31
- package/dist/clis/args/uninstall-BpA3YYbw.d.mts.map +0 -1
- package/dist/clis/args/unpublish-CvwaIimG.d.mts +0 -24
- package/dist/clis/args/unpublish-CvwaIimG.d.mts.map +0 -1
- package/dist/clis/args/vetra-CoMvTJK7.d.mts +0 -113
- package/dist/clis/args/vetra-CoMvTJK7.d.mts.map +0 -1
- package/dist/clis/index-CyAv0ucZ.d.mts.map +0 -1
- package/dist/clis/types-B-Il50oC.d.mts.map +0 -1
- package/dist/constants-BP_gjn8g.d.ts.map +0 -1
- package/dist/index-BmL07S5O.d.ts.map +0 -1
- package/dist/index-C_iVZe7f.d.ts +0 -7
- package/dist/index-C_iVZe7f.d.ts.map +0 -1
- package/dist/types-C1in4fl3.d.ts.map +0 -1
- package/dist/types-COsoOK42.d.ts.map +0 -1
- package/dist/types-DhOXIQ4c.d.ts.map +0 -1
- package/dist/utils-DP122OSS.d.ts.map +0 -1
|
@@ -11,9 +11,9 @@
|
|
|
11
11
|
* Idempotent per directory — CLI argument defaults call it lazily and may
|
|
12
12
|
* call it more than once per process.
|
|
13
13
|
*/
|
|
14
|
-
declare function loadProjectEnv(cwd?: string): void;
|
|
14
|
+
export declare function loadProjectEnv(cwd?: string): void;
|
|
15
15
|
/** Test seam: forget which directory has already been loaded. */
|
|
16
|
-
declare function resetProjectEnvForTests(): void;
|
|
16
|
+
export declare function resetProjectEnvForTests(): void;
|
|
17
17
|
/**
|
|
18
18
|
* Read an environment variable as a TCP port.
|
|
19
19
|
*
|
|
@@ -21,7 +21,7 @@ declare function resetProjectEnvForTests(): void;
|
|
|
21
21
|
* throwing: a typo in `.env` should fall through to the next source in the
|
|
22
22
|
* precedence chain, not break the CLI.
|
|
23
23
|
*/
|
|
24
|
-
declare function readPortEnv(name: string): number | undefined;
|
|
24
|
+
export declare function readPortEnv(name: string): number | undefined;
|
|
25
25
|
//#endregion
|
|
26
|
-
export {
|
|
26
|
+
export {};
|
|
27
27
|
//# sourceMappingURL=project-env.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-env.d.mts","names":[],"sources":["../../clis/project-env.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"project-env.d.mts","names":[],"sources":["../../clis/project-env.ts"],"mappings":";;;;;;;;;;;;;wBAiBgB,eAAe;;wBAUf;;;;;;;;wBAWA,YAAY"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-env.mjs","names":[],"sources":["../../clis/project-env.ts"],"sourcesContent":["import dotenv from \"dotenv\";\nimport { join } from \"node:path\";\n\nlet loadedFor: string | undefined;\n\n/**\n * Load the project's `.env.local` and `.env` into `process.env`.\n *\n * `dotenv` never overwrites a variable that is already set, so loading\n * `.env.local` first and `.env` second produces the precedence the CLI\n * documents: a real `process.env` value beats `.env.local`, which beats\n * `.env`. One `process.env` lookup afterwards therefore covers all three\n * sources.\n *\n * Idempotent per directory — CLI argument defaults call it lazily and may\n * call it more than once per process.\n */\nexport function loadProjectEnv(cwd: string = process.cwd()): void {\n if (loadedFor === cwd) return;\n loadedFor = cwd;\n // dotenv 16 logs nothing for a missing file, so no suppression option is\n // needed here (and none exists before dotenv 17).\n dotenv.config({ path: join(cwd, \".env.local\") });\n dotenv.config({ path: join(cwd, \".env\") });\n}\n\n/** Test seam: forget which directory has already been loaded. */\nexport function resetProjectEnvForTests(): void {\n loadedFor = undefined;\n}\n\n/**\n * Read an environment variable as a TCP port.\n *\n * Anything that is not a plain integer in 1-65535 is ignored rather than\n * throwing: a typo in `.env` should fall through to the next source in the\n * precedence chain, not break the CLI.\n */\nexport function readPortEnv(name: string): number | undefined {\n const raw = process.env[name]?.trim();\n if (!raw || !/^\\d+$/.test(raw)) return undefined;\n const port = Number(raw);\n if (port < 1 || port > 65535) return undefined;\n return port;\n}\n"],"mappings":";;;AAGA,IAAI;;;;;;;;;;;;;AAcJ,SAAgB,eAAe,MAAc,QAAQ,
|
|
1
|
+
{"version":3,"file":"project-env.mjs","names":[],"sources":["../../clis/project-env.ts"],"sourcesContent":["import dotenv from \"dotenv\";\nimport { join } from \"node:path\";\n\nlet loadedFor: string | undefined;\n\n/**\n * Load the project's `.env.local` and `.env` into `process.env`.\n *\n * `dotenv` never overwrites a variable that is already set, so loading\n * `.env.local` first and `.env` second produces the precedence the CLI\n * documents: a real `process.env` value beats `.env.local`, which beats\n * `.env`. One `process.env` lookup afterwards therefore covers all three\n * sources.\n *\n * Idempotent per directory — CLI argument defaults call it lazily and may\n * call it more than once per process.\n */\nexport function loadProjectEnv(cwd: string = process.cwd()): void {\n if (loadedFor === cwd) return;\n loadedFor = cwd;\n // dotenv 16 logs nothing for a missing file, so no suppression option is\n // needed here (and none exists before dotenv 17).\n dotenv.config({ path: join(cwd, \".env.local\") });\n dotenv.config({ path: join(cwd, \".env\") });\n}\n\n/** Test seam: forget which directory has already been loaded. */\nexport function resetProjectEnvForTests(): void {\n loadedFor = undefined;\n}\n\n/**\n * Read an environment variable as a TCP port.\n *\n * Anything that is not a plain integer in 1-65535 is ignored rather than\n * throwing: a typo in `.env` should fall through to the next source in the\n * precedence chain, not break the CLI.\n */\nexport function readPortEnv(name: string): number | undefined {\n const raw = process.env[name]?.trim();\n if (!raw || !/^\\d+$/.test(raw)) return undefined;\n const port = Number(raw);\n if (port < 1 || port > 65535) return undefined;\n return port;\n}\n"],"mappings":";;;AAGA,IAAI;;;;;;;;;;;;;AAcJ,SAAgB,eAAe,MAAc,QAAQ,IAAI,GAAS;CAChE,IAAI,cAAc,KAAK;CACvB,YAAY;CAGZ,OAAO,OAAO,EAAE,MAAM,KAAK,KAAK,YAAY,EAAE,CAAC;CAC/C,OAAO,OAAO,EAAE,MAAM,KAAK,KAAK,MAAM,EAAE,CAAC;AAC3C;;AAGA,SAAgB,0BAAgC;CAC9C,YAAY,KAAA;AACd;;;;;;;;AASA,SAAgB,YAAY,MAAkC;CAC5D,MAAM,MAAM,QAAQ,IAAI,KAAK,EAAE,KAAK;CACpC,IAAI,CAAC,OAAO,CAAC,QAAQ,KAAK,GAAG,GAAG,OAAO,KAAA;CACvC,MAAM,OAAO,OAAO,GAAG;CACvB,IAAI,OAAO,KAAK,OAAO,OAAO,OAAO,KAAA;CACrC,OAAO;AACT"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
//#region clis/project-ports.d.ts
|
|
2
|
-
type ProjectPorts = {
|
|
2
|
+
export type ProjectPorts = {
|
|
3
3
|
switchboardPort: number;
|
|
4
4
|
studioPort: number;
|
|
5
5
|
vetraConnectPort: number;
|
|
@@ -13,7 +13,7 @@ type ProjectPorts = {
|
|
|
13
13
|
* bands, and well-known services. Being generous here is nearly free — the
|
|
14
14
|
* whole list costs 83 of 1000 offsets.
|
|
15
15
|
*/
|
|
16
|
-
declare const PROJECT_PORT_DENYLIST: ReadonlySet<number>;
|
|
16
|
+
export declare const PROJECT_PORT_DENYLIST: ReadonlySet<number>;
|
|
17
17
|
/**
|
|
18
18
|
* Derive a project's dev-server port triple from its package name.
|
|
19
19
|
*
|
|
@@ -29,12 +29,12 @@ declare const PROJECT_PORT_DENYLIST: ReadonlySet<number>;
|
|
|
29
29
|
* until all three are clear — so the result stays reproducible from the name
|
|
30
30
|
* alone.
|
|
31
31
|
*/
|
|
32
|
-
declare function deriveProjectPorts(projectName: string): ProjectPorts;
|
|
32
|
+
export declare function deriveProjectPorts(projectName: string): ProjectPorts;
|
|
33
33
|
/** Every port this scheme can hand out, for cross-checking against other tools. */
|
|
34
|
-
declare function projectPortBands(): {
|
|
34
|
+
export declare function projectPortBands(): {
|
|
35
35
|
from: number;
|
|
36
36
|
to: number;
|
|
37
37
|
}[];
|
|
38
38
|
//#endregion
|
|
39
|
-
export {
|
|
39
|
+
export {};
|
|
40
40
|
//# sourceMappingURL=project-ports.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-ports.d.mts","names":[],"sources":["../../clis/project-ports.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"project-ports.d.mts","names":[],"sources":["../../clis/project-ports.ts"],"mappings":";YAQY;EACV;EACA;EACA;;;;;;;;;;;qBAsBW,uBAAuB;;;;;;;;;;;;;;;;wBAuDpB,mBAAmB,sBAAsB;;wBAsBzC;EAAsB;EAAc"}
|
|
@@ -18,7 +18,7 @@ function inclusive(from, to) {
|
|
|
18
18
|
* bands, and well-known services. Being generous here is nearly free — the
|
|
19
19
|
* whole list costs 83 of 1000 offsets.
|
|
20
20
|
*/
|
|
21
|
-
const PROJECT_PORT_DENYLIST = new Set([
|
|
21
|
+
const PROJECT_PORT_DENYLIST = /* @__PURE__ */ new Set([
|
|
22
22
|
2e3,
|
|
23
23
|
2049,
|
|
24
24
|
2181,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project-ports.mjs","names":[],"sources":["../../clis/project-ports.ts"],"sourcesContent":["import fnv1a from \"@sindresorhus/fnv1a\";\nimport {\n PROJECT_PORT_BAND_SIZE,\n PROJECT_PORT_BAND_STUDIO,\n PROJECT_PORT_BAND_SWITCHBOARD,\n PROJECT_PORT_BAND_VETRA_CONNECT,\n} from \"./constants.js\";\n\nexport type ProjectPorts = {\n switchboardPort: number;\n studioPort: number;\n vetraConnectPort: number;\n};\n\nconst BANDS = [\n PROJECT_PORT_BAND_SWITCHBOARD,\n PROJECT_PORT_BAND_STUDIO,\n PROJECT_PORT_BAND_VETRA_CONNECT,\n] as const;\n\nfunction inclusive(from: number, to: number): number[] {\n return Array.from({ length: to - from + 1 }, (_, i) => from + i);\n}\n\n/**\n * Offsets whose derived port would land on something a developer machine\n * plausibly already holds. Skipped rather than assigned, so a project never\n * starts life needing a port override.\n *\n * Two sources: ports the Powerhouse repos themselves reference inside these\n * bands, and well-known services. Being generous here is nearly free — the\n * whole list costs 83 of 1000 offsets.\n */\nexport const PROJECT_PORT_DENYLIST: ReadonlySet<number> = new Set<number>([\n // 2000 band\n 2000, // Cisco SCCP\n 2049, // NFS\n 2181, // ZooKeeper\n 2222, // alternate SSH\n 2375,\n 2376,\n 2377, // Docker daemon and Swarm\n 2483,\n 2484, // Oracle DB\n // 6000 band\n ...inclusive(6000, 6063), // X11 TCP listeners\n 6006, // Storybook / TensorBoard\n 6060, // Go pprof\n 6100,\n 6200,\n 6300,\n 6500, // referenced elsewhere in the Powerhouse repos\n 6379, // Redis\n 6443, // Kubernetes API server\n 6666,\n 6667, // IRC\n // 7000 band\n 7000,\n 7001, // macOS AirPlay receiver / Cassandra\n 7077, // Spark\n 7474,\n 7687, // Neo4j HTTP and Bolt\n 7777, // referenced elsewhere in the Powerhouse repos\n]);\n\nfunction portsForOffset(offset: number): ProjectPorts {\n return {\n switchboardPort: PROJECT_PORT_BAND_SWITCHBOARD + offset,\n studioPort: PROJECT_PORT_BAND_STUDIO + offset,\n vetraConnectPort: PROJECT_PORT_BAND_VETRA_CONNECT + offset,\n };\n}\n\n/**\n * Derive a project's dev-server port triple from its package name.\n *\n * Name-derived rather than path-derived on purpose: the switchboard port is\n * written literally into the project's committed `.mcp.json`, because an MCP\n * client resolves that file at session start and cannot read the project\n * config or `.env`. A path-derived value would differ on every machine that\n * clones the repo.\n *\n * The three ports share one offset, so a project's numbers end in the same\n * three digits (`my-package` gets 7834 / 6834 / 2834). When any of the three\n * would hit {@link PROJECT_PORT_DENYLIST}, the offset advances deterministically\n * until all three are clear — so the result stays reproducible from the name\n * alone.\n */\nexport function deriveProjectPorts(projectName: string): ProjectPorts {\n if (!projectName.trim()) {\n throw new Error(\"A project name is required to derive project ports.\");\n }\n const start = Number(\n fnv1a(projectName, { size: 32 }) % BigInt(PROJECT_PORT_BAND_SIZE),\n );\n for (let step = 0; step < PROJECT_PORT_BAND_SIZE; step++) {\n const offset = (start + step) % PROJECT_PORT_BAND_SIZE;\n const ports = portsForOffset(offset);\n if (!Object.values(ports).some((port) => PROJECT_PORT_DENYLIST.has(port))) {\n return ports;\n }\n }\n // Unreachable: the denylist covers far fewer offsets than the band holds.\n throw new Error(\n `No free port offset for project \"${projectName}\" — every offset in the ` +\n `${PROJECT_PORT_BAND_SIZE}-wide band is denied.`,\n );\n}\n\n/** Every port this scheme can hand out, for cross-checking against other tools. */\nexport function projectPortBands(): { from: number; to: number }[] {\n return BANDS.map((base) => ({\n from: base,\n to: base + PROJECT_PORT_BAND_SIZE - 1,\n }));\n}\n"],"mappings":";;;AAcA,MAAM,QAAQ;CACZ;CACA;CACA;
|
|
1
|
+
{"version":3,"file":"project-ports.mjs","names":[],"sources":["../../clis/project-ports.ts"],"sourcesContent":["import fnv1a from \"@sindresorhus/fnv1a\";\nimport {\n PROJECT_PORT_BAND_SIZE,\n PROJECT_PORT_BAND_STUDIO,\n PROJECT_PORT_BAND_SWITCHBOARD,\n PROJECT_PORT_BAND_VETRA_CONNECT,\n} from \"./constants.js\";\n\nexport type ProjectPorts = {\n switchboardPort: number;\n studioPort: number;\n vetraConnectPort: number;\n};\n\nconst BANDS = [\n PROJECT_PORT_BAND_SWITCHBOARD,\n PROJECT_PORT_BAND_STUDIO,\n PROJECT_PORT_BAND_VETRA_CONNECT,\n] as const;\n\nfunction inclusive(from: number, to: number): number[] {\n return Array.from({ length: to - from + 1 }, (_, i) => from + i);\n}\n\n/**\n * Offsets whose derived port would land on something a developer machine\n * plausibly already holds. Skipped rather than assigned, so a project never\n * starts life needing a port override.\n *\n * Two sources: ports the Powerhouse repos themselves reference inside these\n * bands, and well-known services. Being generous here is nearly free — the\n * whole list costs 83 of 1000 offsets.\n */\nexport const PROJECT_PORT_DENYLIST: ReadonlySet<number> = new Set<number>([\n // 2000 band\n 2000, // Cisco SCCP\n 2049, // NFS\n 2181, // ZooKeeper\n 2222, // alternate SSH\n 2375,\n 2376,\n 2377, // Docker daemon and Swarm\n 2483,\n 2484, // Oracle DB\n // 6000 band\n ...inclusive(6000, 6063), // X11 TCP listeners\n 6006, // Storybook / TensorBoard\n 6060, // Go pprof\n 6100,\n 6200,\n 6300,\n 6500, // referenced elsewhere in the Powerhouse repos\n 6379, // Redis\n 6443, // Kubernetes API server\n 6666,\n 6667, // IRC\n // 7000 band\n 7000,\n 7001, // macOS AirPlay receiver / Cassandra\n 7077, // Spark\n 7474,\n 7687, // Neo4j HTTP and Bolt\n 7777, // referenced elsewhere in the Powerhouse repos\n]);\n\nfunction portsForOffset(offset: number): ProjectPorts {\n return {\n switchboardPort: PROJECT_PORT_BAND_SWITCHBOARD + offset,\n studioPort: PROJECT_PORT_BAND_STUDIO + offset,\n vetraConnectPort: PROJECT_PORT_BAND_VETRA_CONNECT + offset,\n };\n}\n\n/**\n * Derive a project's dev-server port triple from its package name.\n *\n * Name-derived rather than path-derived on purpose: the switchboard port is\n * written literally into the project's committed `.mcp.json`, because an MCP\n * client resolves that file at session start and cannot read the project\n * config or `.env`. A path-derived value would differ on every machine that\n * clones the repo.\n *\n * The three ports share one offset, so a project's numbers end in the same\n * three digits (`my-package` gets 7834 / 6834 / 2834). When any of the three\n * would hit {@link PROJECT_PORT_DENYLIST}, the offset advances deterministically\n * until all three are clear — so the result stays reproducible from the name\n * alone.\n */\nexport function deriveProjectPorts(projectName: string): ProjectPorts {\n if (!projectName.trim()) {\n throw new Error(\"A project name is required to derive project ports.\");\n }\n const start = Number(\n fnv1a(projectName, { size: 32 }) % BigInt(PROJECT_PORT_BAND_SIZE),\n );\n for (let step = 0; step < PROJECT_PORT_BAND_SIZE; step++) {\n const offset = (start + step) % PROJECT_PORT_BAND_SIZE;\n const ports = portsForOffset(offset);\n if (!Object.values(ports).some((port) => PROJECT_PORT_DENYLIST.has(port))) {\n return ports;\n }\n }\n // Unreachable: the denylist covers far fewer offsets than the band holds.\n throw new Error(\n `No free port offset for project \"${projectName}\" — every offset in the ` +\n `${PROJECT_PORT_BAND_SIZE}-wide band is denied.`,\n );\n}\n\n/** Every port this scheme can hand out, for cross-checking against other tools. */\nexport function projectPortBands(): { from: number; to: number }[] {\n return BANDS.map((base) => ({\n from: base,\n to: base + PROJECT_PORT_BAND_SIZE - 1,\n }));\n}\n"],"mappings":";;;AAcA,MAAM,QAAQ;CACZ;CACA;CACA;AACF;AAEA,SAAS,UAAU,MAAc,IAAsB;CACrD,OAAO,MAAM,KAAK,EAAE,QAAQ,KAAK,OAAO,EAAE,IAAI,GAAG,MAAM,OAAO,CAAC;AACjE;;;;;;;;;;AAWA,MAAa,wCAA6C,IAAI,IAAY;CAExE;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,GAAG,UAAU,KAAM,IAAI;CACvB;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA;CACA;CACA;CACA;CACA;CACA;AACF,CAAC;AAED,SAAS,eAAe,QAA8B;CACpD,OAAO;EACL,iBAAiB,gCAAgC;EACjD,YAAY,2BAA2B;EACvC,kBAAkB,kCAAkC;CACtD;AACF;;;;;;;;;;;;;;;;AAiBA,SAAgB,mBAAmB,aAAmC;CACpE,IAAI,CAAC,YAAY,KAAK,GACpB,MAAM,IAAI,MAAM,qDAAqD;CAEvE,MAAM,QAAQ,OACZ,MAAM,aAAa,EAAE,MAAM,GAAG,CAAC,IAAI,OAAO,sBAAsB,CAClE;CACA,KAAK,IAAI,OAAO,GAAG,OAAO,wBAAwB,QAAQ;EAExD,MAAM,QAAQ,gBADE,QAAQ,QAAQ,sBACG;EACnC,IAAI,CAAC,OAAO,OAAO,KAAK,CAAC,CAAC,MAAM,SAAS,sBAAsB,IAAI,IAAI,CAAC,GACtE,OAAO;CAEX;CAEA,MAAM,IAAI,MACR,oCAAoC,YAAY,0BAC3C,uBAAuB,sBAC9B;AACF;;AAGA,SAAgB,mBAAmD;CACjE,OAAO,MAAM,KAAK,UAAU;EAC1B,MAAM;EACN,IAAI,OAAO,yBAAyB;CACtC,EAAE;AACJ"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
//#region clis/services/telemetry.d.ts
|
|
2
|
-
type CliInvocationInfo = {
|
|
2
|
+
export type CliInvocationInfo = {
|
|
3
3
|
command?: string;
|
|
4
4
|
subcommand?: string;
|
|
5
5
|
pm?: string;
|
|
6
6
|
argv: string[];
|
|
7
7
|
cwd?: string;
|
|
8
8
|
};
|
|
9
|
-
type TelemetryClient = {
|
|
9
|
+
export type TelemetryClient = {
|
|
10
10
|
/**
|
|
11
11
|
* Attaches per-invocation context (command, sanitized argv, package
|
|
12
12
|
* manager) as Sentry tags + a `invocation` context block, plus a single
|
|
@@ -25,23 +25,23 @@ type TelemetryClient = {
|
|
|
25
25
|
* Prompts the user once, caches the answer. Must be called before init.
|
|
26
26
|
* Returns `true` if telemetry should be enabled, `false` otherwise.
|
|
27
27
|
*/
|
|
28
|
-
declare function resolveTelemetryConsent(): Promise<boolean>;
|
|
28
|
+
export declare function resolveTelemetryConsent(): Promise<boolean>;
|
|
29
29
|
/**
|
|
30
30
|
* Initializes Sentry for CLI error reporting if telemetry is enabled.
|
|
31
31
|
* Safe to call multiple times; only the first call takes effect.
|
|
32
32
|
*/
|
|
33
|
-
declare function initCliTelemetry(opts: {
|
|
33
|
+
export declare function initCliTelemetry(opts: {
|
|
34
34
|
cliName: "ph-cli" | "ph-cmd";
|
|
35
35
|
release?: string;
|
|
36
36
|
}): Promise<TelemetryClient | undefined>;
|
|
37
37
|
/**
|
|
38
38
|
* Explicitly set telemetry consent (used by `ph telemetry on|off`).
|
|
39
39
|
*/
|
|
40
|
-
declare function setTelemetryConsent(enabled: boolean): void;
|
|
40
|
+
export declare function setTelemetryConsent(enabled: boolean): void;
|
|
41
41
|
/**
|
|
42
42
|
* Returns the current telemetry state — useful for `ph telemetry status`.
|
|
43
43
|
*/
|
|
44
|
-
declare function getTelemetryStatus(): {
|
|
44
|
+
export declare function getTelemetryStatus(): {
|
|
45
45
|
source: "env";
|
|
46
46
|
enabled: boolean;
|
|
47
47
|
} | {
|
|
@@ -53,5 +53,5 @@ declare function getTelemetryStatus(): {
|
|
|
53
53
|
enabled: false;
|
|
54
54
|
};
|
|
55
55
|
//#endregion
|
|
56
|
-
export {
|
|
56
|
+
export {};
|
|
57
57
|
//# sourceMappingURL=telemetry.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.d.mts","names":[],"sources":["../../../clis/services/telemetry.ts"],"mappings":";
|
|
1
|
+
{"version":3,"file":"telemetry.d.mts","names":[],"sources":["../../../clis/services/telemetry.ts"],"mappings":";YAmCY;EACV;EACA;EACA;EACA;EACA;;YAGU;;;;;;EAMV,0BAA0B,MAAM;;;;;EAKhC,kBACE,cACA;IAAS;QACN;;;;;;wBA8Ce,2BAA2B;;;;;wBAgH3B,iBAAiB;EACrC;EACA;IACE,QAAQ;;;;wBAgGI,oBAAoB;;;;wBAOpB;EACV;EAAe;;EACf;EAAkB;EAAkB;;EACpC;EAAmB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"telemetry.mjs","names":[],"sources":["../../../clis/services/telemetry.ts"],"sourcesContent":["/**\n * CLI telemetry (error reporting via Sentry).\n *\n * Design:\n * - Opt-out by default, asked once on first interactive run.\n * - Stores consent in ~/.ph/telemetry.json so we never ask twice.\n * - Respects PH_NO_TELEMETRY=1 and DO_NOT_TRACK=1 as immediate kill switches.\n * - Non-interactive (TTY missing, CI, piped) defaults to DISABLED — we don't\n * want to hang a CI pipeline on an unanswered prompt, and we don't want to\n * capture errors without informed consent.\n * - DSN is published in the CLI binary; Sentry DSNs accept events but grant\n * no read access, so this is safe. Hardcoded so users can't accidentally\n * misroute events.\n *\n * PII scrubbing in beforeSend hook:\n * - Home-directory paths collapsed to ~\n * - Flag/arg values that look like secrets (tokens, keys) stripped\n * - No source-context from user files\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n// Sentry project \"ph-cli\" on the powerhouse-hosted Sentry instance.\n// Public DSNs are safe to ship — they grant write-only ingest access.\nconst SENTRY_DSN =\n \"https://0e7793802288589b4923896118374462@sentry.monitoring.vetra.io/3\";\n\nconst TELEMETRY_FILE = join(homedir(), \".ph\", \"telemetry.json\");\n\ntype TelemetryConfig = {\n enabled: boolean;\n askedAt: string;\n};\n\nexport type CliInvocationInfo = {\n command?: string;\n subcommand?: string;\n pm?: string;\n argv: string[];\n cwd?: string;\n};\n\nexport type TelemetryClient = {\n /**\n * Attaches per-invocation context (command, sanitized argv, package\n * manager) as Sentry tags + a `invocation` context block, plus a single\n * \"cli invoked\" breadcrumb. Safe to call once per process.\n */\n attachInvocationContext: (info: CliInvocationInfo) => void;\n /**\n * Captures an error (if telemetry is initialized) and flushes before the\n * caller calls process.exit(). Safe no-op when telemetry is disabled.\n */\n captureCliError: (\n err: unknown,\n opts?: { kind?: \"crash\" | \"user\" },\n ) => Promise<void>;\n};\n\nfunction isExplicitlyDisabled(): boolean {\n // Standard opt-out signals respected by most OSS CLIs.\n return (\n process.env.PH_NO_TELEMETRY === \"1\" ||\n process.env.PH_NO_TELEMETRY === \"true\" ||\n process.env.DO_NOT_TRACK === \"1\" ||\n process.env.DO_NOT_TRACK === \"true\"\n );\n}\n\nfunction isExplicitlyEnabled(): boolean {\n return (\n process.env.PH_TELEMETRY === \"1\" || process.env.PH_TELEMETRY === \"true\"\n );\n}\n\nfunction isInteractive(): boolean {\n // Only ask if stdin is a TTY and CI env isn't set.\n return Boolean(process.stdin.isTTY) && !process.env.CI;\n}\n\nfunction readConfig(): TelemetryConfig | null {\n try {\n if (!existsSync(TELEMETRY_FILE)) return null;\n return JSON.parse(readFileSync(TELEMETRY_FILE, \"utf8\")) as TelemetryConfig;\n } catch {\n return null;\n }\n}\n\nfunction writeConfig(cfg: TelemetryConfig): void {\n try {\n mkdirSync(join(homedir(), \".ph\"), { recursive: true });\n writeFileSync(TELEMETRY_FILE, JSON.stringify(cfg, null, 2));\n } catch {\n // non-fatal; we'll just ask again next time\n }\n}\n\n/**\n * Prompts the user once, caches the answer. Must be called before init.\n * Returns `true` if telemetry should be enabled, `false` otherwise.\n */\nexport async function resolveTelemetryConsent(): Promise<boolean> {\n if (isExplicitlyDisabled()) return false;\n if (isExplicitlyEnabled()) return true;\n\n const cached = readConfig();\n if (cached) return cached.enabled;\n\n if (!isInteractive()) {\n // Non-interactive first run: stay silent, don't ask, don't send. User can\n // opt in later with `ph telemetry on` or PH_TELEMETRY=1.\n return false;\n }\n\n const enquirer = await import(\"enquirer\");\n try {\n const { enabled } = await enquirer.default.prompt<{ enabled: boolean }>({\n type: \"confirm\",\n name: \"enabled\",\n message:\n \"Help improve Powerhouse by sending anonymous error reports? \" +\n \"(stack traces only, paths and secrets are scrubbed)\",\n initial: true,\n });\n writeConfig({ enabled, askedAt: new Date().toISOString() });\n return enabled;\n } catch {\n // user hit Ctrl-C during prompt — treat as no, but don't persist so we\n // ask again next time\n return false;\n }\n}\n\nfunction scrubString(input: string): string {\n if (!input) return input;\n const home = homedir();\n let out = input;\n // Collapse home dir to ~\n if (home && out.includes(home)) {\n out = out.split(home).join(\"~\");\n }\n // Strip common secret-shaped flag values: --token=XYZ, --api-key XYZ, etc.\n out = out.replace(\n /(--?(?:token|api[-_]?key|password|secret|auth)[=\\s])([^\\s]+)/gi,\n \"$1<redacted>\",\n );\n return out;\n}\n\ntype ScrubbableFrame = {\n filename?: string;\n abs_path?: string;\n pre_context?: unknown;\n context_line?: unknown;\n post_context?: unknown;\n vars?: unknown;\n};\n\ntype ScrubbableException = {\n value?: string;\n stacktrace?: { frames?: ScrubbableFrame[] };\n};\n\ntype ScrubbableEvent = {\n message?: string;\n logentry?: { message?: string };\n exception?: { values?: ScrubbableException[] };\n server_name?: string;\n extra?: Record<string, unknown>;\n};\n\nfunction scrubEvent<T>(event: T): T {\n const e = event as ScrubbableEvent;\n try {\n if (e.message) e.message = scrubString(e.message);\n if (e.logentry?.message) {\n e.logentry.message = scrubString(e.logentry.message);\n }\n const values = e.exception?.values;\n if (Array.isArray(values)) {\n for (const ex of values) {\n if (ex.value) ex.value = scrubString(ex.value);\n const frames = ex.stacktrace?.frames;\n if (Array.isArray(frames)) {\n for (const f of frames) {\n if (f.filename) f.filename = scrubString(f.filename);\n if (f.abs_path) f.abs_path = scrubString(f.abs_path);\n // Drop captured source context from user machines — privacy.\n delete f.pre_context;\n delete f.context_line;\n delete f.post_context;\n delete f.vars;\n }\n }\n }\n }\n // Server name can leak the user's machine hostname; drop it.\n delete e.server_name;\n // Strip raw argv from extra context.\n if (e.extra) {\n delete e.extra.argv;\n delete e.extra.env;\n }\n } catch {\n // Never let scrubbing throw — worst case we drop the event below.\n }\n return event;\n}\n\n/**\n * Initializes Sentry for CLI error reporting if telemetry is enabled.\n * Safe to call multiple times; only the first call takes effect.\n */\nexport async function initCliTelemetry(opts: {\n cliName: \"ph-cli\" | \"ph-cmd\";\n release?: string;\n}): Promise<TelemetryClient | undefined> {\n const enabled = await resolveTelemetryConsent();\n if (!enabled) return;\n\n const Sentry = await import(\"@sentry/node-core/light\");\n const os = await import(\"node:os\");\n const sentryClient = Sentry.init({\n dsn: SENTRY_DSN,\n release: opts.release,\n environment: process.env.NODE_ENV || \"production\",\n sendDefaultPii: false,\n defaultIntegrations: false,\n integrations: [\n // Only the bare minimum — no automatic HTTP/FS instrumentation.\n ],\n beforeSend(event) {\n return scrubEvent(event);\n },\n beforeBreadcrumb(breadcrumb) {\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message);\n }\n return breadcrumb;\n },\n });\n Sentry.setTag(\"cli_name\", opts.cliName);\n if (opts.release) Sentry.setTag(\"cli_version\", opts.release);\n // Environment tags — `defaultIntegrations: false` strips Sentry's auto\n // node-context, so attach the bits we care about manually (and keep\n // hostname out of it).\n Sentry.setTag(\"os\", process.platform);\n Sentry.setTag(\"arch\", process.arch);\n Sentry.setTag(\"node_version\", process.version);\n Sentry.setTag(\"ci\", String(Boolean(process.env.CI)));\n Sentry.setTag(\"tty\", String(Boolean(process.stdin.isTTY)));\n Sentry.setContext(\"runtime\", {\n name: \"node\",\n version: process.version,\n });\n Sentry.setContext(\"os\", {\n name: process.platform,\n version: os.release(),\n });\n Sentry.setContext(\"device\", {\n arch: process.arch,\n });\n if (!sentryClient) {\n return;\n }\n return {\n attachInvocationContext(info: CliInvocationInfo) {\n const argv = info.argv.map(scrubString);\n const flagNames = info.argv\n .filter((a) => a.startsWith(\"-\"))\n .map((a) => a.split(\"=\")[0]);\n if (info.command) Sentry.setTag(\"command\", info.command);\n if (info.subcommand) Sentry.setTag(\"subcommand\", info.subcommand);\n if (info.pm) Sentry.setTag(\"pm\", info.pm);\n Sentry.setContext(\"invocation\", {\n command: info.command,\n subcommand: info.subcommand,\n argv,\n flag_names: flagNames,\n argv_count: argv.length,\n cwd: info.cwd ? scrubString(info.cwd) : undefined,\n });\n Sentry.addBreadcrumb({\n category: \"cli\",\n level: \"info\",\n message: \"cli invoked\",\n data: {\n command: info.command,\n pm: info.pm,\n tty: Boolean(process.stdin.isTTY),\n ci: Boolean(process.env.CI),\n },\n });\n },\n captureCliError: async (\n err: unknown,\n captureOpts?: { kind?: \"crash\" | \"user\" },\n ) => {\n try {\n Sentry.setTag(\"error_kind\", captureOpts?.kind ?? \"crash\");\n sentryClient.captureException(err);\n await sentryClient.flush(2000);\n } catch {\n // Reporting must never mask the real error.\n }\n },\n };\n}\n\n/**\n * Explicitly set telemetry consent (used by `ph telemetry on|off`).\n */\nexport function setTelemetryConsent(enabled: boolean): void {\n writeConfig({ enabled, askedAt: new Date().toISOString() });\n}\n\n/**\n * Returns the current telemetry state — useful for `ph telemetry status`.\n */\nexport function getTelemetryStatus():\n | { source: \"env\"; enabled: boolean }\n | { source: \"config\"; enabled: boolean; askedAt: string }\n | { source: \"default\"; enabled: false } {\n if (isExplicitlyDisabled()) return { source: \"env\", enabled: false };\n if (isExplicitlyEnabled()) return { source: \"env\", enabled: true };\n const cached = readConfig();\n if (cached)\n return {\n source: \"config\",\n enabled: cached.enabled,\n askedAt: cached.askedAt,\n };\n return { source: \"default\", enabled: false };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"telemetry.mjs","names":[],"sources":["../../../clis/services/telemetry.ts"],"sourcesContent":["/**\n * CLI telemetry (error reporting via Sentry).\n *\n * Design:\n * - Opt-out by default, asked once on first interactive run.\n * - Stores consent in ~/.ph/telemetry.json so we never ask twice.\n * - Respects PH_NO_TELEMETRY=1 and DO_NOT_TRACK=1 as immediate kill switches.\n * - Non-interactive (TTY missing, CI, piped) defaults to DISABLED — we don't\n * want to hang a CI pipeline on an unanswered prompt, and we don't want to\n * capture errors without informed consent.\n * - DSN is published in the CLI binary; Sentry DSNs accept events but grant\n * no read access, so this is safe. Hardcoded so users can't accidentally\n * misroute events.\n *\n * PII scrubbing in beforeSend hook:\n * - Home-directory paths collapsed to ~\n * - Flag/arg values that look like secrets (tokens, keys) stripped\n * - No source-context from user files\n */\nimport { existsSync, mkdirSync, readFileSync, writeFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\n// Sentry project \"ph-cli\" on the powerhouse-hosted Sentry instance.\n// Public DSNs are safe to ship — they grant write-only ingest access.\nconst SENTRY_DSN =\n \"https://0e7793802288589b4923896118374462@sentry.monitoring.vetra.io/3\";\n\nconst TELEMETRY_FILE = join(homedir(), \".ph\", \"telemetry.json\");\n\ntype TelemetryConfig = {\n enabled: boolean;\n askedAt: string;\n};\n\nexport type CliInvocationInfo = {\n command?: string;\n subcommand?: string;\n pm?: string;\n argv: string[];\n cwd?: string;\n};\n\nexport type TelemetryClient = {\n /**\n * Attaches per-invocation context (command, sanitized argv, package\n * manager) as Sentry tags + a `invocation` context block, plus a single\n * \"cli invoked\" breadcrumb. Safe to call once per process.\n */\n attachInvocationContext: (info: CliInvocationInfo) => void;\n /**\n * Captures an error (if telemetry is initialized) and flushes before the\n * caller calls process.exit(). Safe no-op when telemetry is disabled.\n */\n captureCliError: (\n err: unknown,\n opts?: { kind?: \"crash\" | \"user\" },\n ) => Promise<void>;\n};\n\nfunction isExplicitlyDisabled(): boolean {\n // Standard opt-out signals respected by most OSS CLIs.\n return (\n process.env.PH_NO_TELEMETRY === \"1\" ||\n process.env.PH_NO_TELEMETRY === \"true\" ||\n process.env.DO_NOT_TRACK === \"1\" ||\n process.env.DO_NOT_TRACK === \"true\"\n );\n}\n\nfunction isExplicitlyEnabled(): boolean {\n return (\n process.env.PH_TELEMETRY === \"1\" || process.env.PH_TELEMETRY === \"true\"\n );\n}\n\nfunction isInteractive(): boolean {\n // Only ask if stdin is a TTY and CI env isn't set.\n return Boolean(process.stdin.isTTY) && !process.env.CI;\n}\n\nfunction readConfig(): TelemetryConfig | null {\n try {\n if (!existsSync(TELEMETRY_FILE)) return null;\n return JSON.parse(readFileSync(TELEMETRY_FILE, \"utf8\")) as TelemetryConfig;\n } catch {\n return null;\n }\n}\n\nfunction writeConfig(cfg: TelemetryConfig): void {\n try {\n mkdirSync(join(homedir(), \".ph\"), { recursive: true });\n writeFileSync(TELEMETRY_FILE, JSON.stringify(cfg, null, 2));\n } catch {\n // non-fatal; we'll just ask again next time\n }\n}\n\n/**\n * Prompts the user once, caches the answer. Must be called before init.\n * Returns `true` if telemetry should be enabled, `false` otherwise.\n */\nexport async function resolveTelemetryConsent(): Promise<boolean> {\n if (isExplicitlyDisabled()) return false;\n if (isExplicitlyEnabled()) return true;\n\n const cached = readConfig();\n if (cached) return cached.enabled;\n\n if (!isInteractive()) {\n // Non-interactive first run: stay silent, don't ask, don't send. User can\n // opt in later with `ph telemetry on` or PH_TELEMETRY=1.\n return false;\n }\n\n const enquirer = await import(\"enquirer\");\n try {\n const { enabled } = await enquirer.default.prompt<{ enabled: boolean }>({\n type: \"confirm\",\n name: \"enabled\",\n message:\n \"Help improve Powerhouse by sending anonymous error reports? \" +\n \"(stack traces only, paths and secrets are scrubbed)\",\n initial: true,\n });\n writeConfig({ enabled, askedAt: new Date().toISOString() });\n return enabled;\n } catch {\n // user hit Ctrl-C during prompt — treat as no, but don't persist so we\n // ask again next time\n return false;\n }\n}\n\nfunction scrubString(input: string): string {\n if (!input) return input;\n const home = homedir();\n let out = input;\n // Collapse home dir to ~\n if (home && out.includes(home)) {\n out = out.split(home).join(\"~\");\n }\n // Strip common secret-shaped flag values: --token=XYZ, --api-key XYZ, etc.\n out = out.replace(\n /(--?(?:token|api[-_]?key|password|secret|auth)[=\\s])([^\\s]+)/gi,\n \"$1<redacted>\",\n );\n return out;\n}\n\ntype ScrubbableFrame = {\n filename?: string;\n abs_path?: string;\n pre_context?: unknown;\n context_line?: unknown;\n post_context?: unknown;\n vars?: unknown;\n};\n\ntype ScrubbableException = {\n value?: string;\n stacktrace?: { frames?: ScrubbableFrame[] };\n};\n\ntype ScrubbableEvent = {\n message?: string;\n logentry?: { message?: string };\n exception?: { values?: ScrubbableException[] };\n server_name?: string;\n extra?: Record<string, unknown>;\n};\n\nfunction scrubEvent<T>(event: T): T {\n const e = event as ScrubbableEvent;\n try {\n if (e.message) e.message = scrubString(e.message);\n if (e.logentry?.message) {\n e.logentry.message = scrubString(e.logentry.message);\n }\n const values = e.exception?.values;\n if (Array.isArray(values)) {\n for (const ex of values) {\n if (ex.value) ex.value = scrubString(ex.value);\n const frames = ex.stacktrace?.frames;\n if (Array.isArray(frames)) {\n for (const f of frames) {\n if (f.filename) f.filename = scrubString(f.filename);\n if (f.abs_path) f.abs_path = scrubString(f.abs_path);\n // Drop captured source context from user machines — privacy.\n delete f.pre_context;\n delete f.context_line;\n delete f.post_context;\n delete f.vars;\n }\n }\n }\n }\n // Server name can leak the user's machine hostname; drop it.\n delete e.server_name;\n // Strip raw argv from extra context.\n if (e.extra) {\n delete e.extra.argv;\n delete e.extra.env;\n }\n } catch {\n // Never let scrubbing throw — worst case we drop the event below.\n }\n return event;\n}\n\n/**\n * Initializes Sentry for CLI error reporting if telemetry is enabled.\n * Safe to call multiple times; only the first call takes effect.\n */\nexport async function initCliTelemetry(opts: {\n cliName: \"ph-cli\" | \"ph-cmd\";\n release?: string;\n}): Promise<TelemetryClient | undefined> {\n const enabled = await resolveTelemetryConsent();\n if (!enabled) return;\n\n const Sentry = await import(\"@sentry/node-core/light\");\n const os = await import(\"node:os\");\n const sentryClient = Sentry.init({\n dsn: SENTRY_DSN,\n release: opts.release,\n environment: process.env.NODE_ENV || \"production\",\n sendDefaultPii: false,\n defaultIntegrations: false,\n integrations: [\n // Only the bare minimum — no automatic HTTP/FS instrumentation.\n ],\n beforeSend(event) {\n return scrubEvent(event);\n },\n beforeBreadcrumb(breadcrumb) {\n if (breadcrumb.message) {\n breadcrumb.message = scrubString(breadcrumb.message);\n }\n return breadcrumb;\n },\n });\n Sentry.setTag(\"cli_name\", opts.cliName);\n if (opts.release) Sentry.setTag(\"cli_version\", opts.release);\n // Environment tags — `defaultIntegrations: false` strips Sentry's auto\n // node-context, so attach the bits we care about manually (and keep\n // hostname out of it).\n Sentry.setTag(\"os\", process.platform);\n Sentry.setTag(\"arch\", process.arch);\n Sentry.setTag(\"node_version\", process.version);\n Sentry.setTag(\"ci\", String(Boolean(process.env.CI)));\n Sentry.setTag(\"tty\", String(Boolean(process.stdin.isTTY)));\n Sentry.setContext(\"runtime\", {\n name: \"node\",\n version: process.version,\n });\n Sentry.setContext(\"os\", {\n name: process.platform,\n version: os.release(),\n });\n Sentry.setContext(\"device\", {\n arch: process.arch,\n });\n if (!sentryClient) {\n return;\n }\n return {\n attachInvocationContext(info: CliInvocationInfo) {\n const argv = info.argv.map(scrubString);\n const flagNames = info.argv\n .filter((a) => a.startsWith(\"-\"))\n .map((a) => a.split(\"=\")[0]);\n if (info.command) Sentry.setTag(\"command\", info.command);\n if (info.subcommand) Sentry.setTag(\"subcommand\", info.subcommand);\n if (info.pm) Sentry.setTag(\"pm\", info.pm);\n Sentry.setContext(\"invocation\", {\n command: info.command,\n subcommand: info.subcommand,\n argv,\n flag_names: flagNames,\n argv_count: argv.length,\n cwd: info.cwd ? scrubString(info.cwd) : undefined,\n });\n Sentry.addBreadcrumb({\n category: \"cli\",\n level: \"info\",\n message: \"cli invoked\",\n data: {\n command: info.command,\n pm: info.pm,\n tty: Boolean(process.stdin.isTTY),\n ci: Boolean(process.env.CI),\n },\n });\n },\n captureCliError: async (\n err: unknown,\n captureOpts?: { kind?: \"crash\" | \"user\" },\n ) => {\n try {\n Sentry.setTag(\"error_kind\", captureOpts?.kind ?? \"crash\");\n sentryClient.captureException(err);\n await sentryClient.flush(2000);\n } catch {\n // Reporting must never mask the real error.\n }\n },\n };\n}\n\n/**\n * Explicitly set telemetry consent (used by `ph telemetry on|off`).\n */\nexport function setTelemetryConsent(enabled: boolean): void {\n writeConfig({ enabled, askedAt: new Date().toISOString() });\n}\n\n/**\n * Returns the current telemetry state — useful for `ph telemetry status`.\n */\nexport function getTelemetryStatus():\n | { source: \"env\"; enabled: boolean }\n | { source: \"config\"; enabled: boolean; askedAt: string }\n | { source: \"default\"; enabled: false } {\n if (isExplicitlyDisabled()) return { source: \"env\", enabled: false };\n if (isExplicitlyEnabled()) return { source: \"env\", enabled: true };\n const cached = readConfig();\n if (cached)\n return {\n source: \"config\",\n enabled: cached.enabled,\n askedAt: cached.askedAt,\n };\n return { source: \"default\", enabled: false };\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;AAyBA,MAAM,aACJ;AAEF,MAAM,iBAAiB,KAAK,QAAQ,GAAG,OAAO,gBAAgB;AAgC9D,SAAS,uBAAgC;CAEvC,OACE,QAAQ,IAAI,oBAAoB,OAChC,QAAQ,IAAI,oBAAoB,UAChC,QAAQ,IAAI,iBAAiB,OAC7B,QAAQ,IAAI,iBAAiB;AAEjC;AAEA,SAAS,sBAA+B;CACtC,OACE,QAAQ,IAAI,iBAAiB,OAAO,QAAQ,IAAI,iBAAiB;AAErE;AAEA,SAAS,gBAAyB;CAEhC,OAAO,QAAQ,QAAQ,MAAM,KAAK,KAAK,CAAC,QAAQ,IAAI;AACtD;AAEA,SAAS,aAAqC;CAC5C,IAAI;EACF,IAAI,CAAC,WAAW,cAAc,GAAG,OAAO;EACxC,OAAO,KAAK,MAAM,aAAa,gBAAgB,MAAM,CAAC;CACxD,QAAQ;EACN,OAAO;CACT;AACF;AAEA,SAAS,YAAY,KAA4B;CAC/C,IAAI;EACF,UAAU,KAAK,QAAQ,GAAG,KAAK,GAAG,EAAE,WAAW,KAAK,CAAC;EACrD,cAAc,gBAAgB,KAAK,UAAU,KAAK,MAAM,CAAC,CAAC;CAC5D,QAAQ,CAER;AACF;;;;;AAMA,eAAsB,0BAA4C;CAChE,IAAI,qBAAqB,GAAG,OAAO;CACnC,IAAI,oBAAoB,GAAG,OAAO;CAElC,MAAM,SAAS,WAAW;CAC1B,IAAI,QAAQ,OAAO,OAAO;CAE1B,IAAI,CAAC,cAAc,GAGjB,OAAO;CAGT,MAAM,WAAW,MAAM,OAAO;CAC9B,IAAI;EACF,MAAM,EAAE,YAAY,MAAM,SAAS,QAAQ,OAA6B;GACtE,MAAM;GACN,MAAM;GACN,SACE;GAEF,SAAS;EACX,CAAC;EACD,YAAY;GAAE;GAAS,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;EAAE,CAAC;EAC1D,OAAO;CACT,QAAQ;EAGN,OAAO;CACT;AACF;AAEA,SAAS,YAAY,OAAuB;CAC1C,IAAI,CAAC,OAAO,OAAO;CACnB,MAAM,OAAO,QAAQ;CACrB,IAAI,MAAM;CAEV,IAAI,QAAQ,IAAI,SAAS,IAAI,GAC3B,MAAM,IAAI,MAAM,IAAI,CAAC,CAAC,KAAK,GAAG;CAGhC,MAAM,IAAI,QACR,kEACA,cACF;CACA,OAAO;AACT;AAwBA,SAAS,WAAc,OAAa;CAClC,MAAM,IAAI;CACV,IAAI;EACF,IAAI,EAAE,SAAS,EAAE,UAAU,YAAY,EAAE,OAAO;EAChD,IAAI,EAAE,UAAU,SACd,EAAE,SAAS,UAAU,YAAY,EAAE,SAAS,OAAO;EAErD,MAAM,SAAS,EAAE,WAAW;EAC5B,IAAI,MAAM,QAAQ,MAAM,GACtB,KAAK,MAAM,MAAM,QAAQ;GACvB,IAAI,GAAG,OAAO,GAAG,QAAQ,YAAY,GAAG,KAAK;GAC7C,MAAM,SAAS,GAAG,YAAY;GAC9B,IAAI,MAAM,QAAQ,MAAM,GACtB,KAAK,MAAM,KAAK,QAAQ;IACtB,IAAI,EAAE,UAAU,EAAE,WAAW,YAAY,EAAE,QAAQ;IACnD,IAAI,EAAE,UAAU,EAAE,WAAW,YAAY,EAAE,QAAQ;IAEnD,OAAO,EAAE;IACT,OAAO,EAAE;IACT,OAAO,EAAE;IACT,OAAO,EAAE;GACX;EAEJ;EAGF,OAAO,EAAE;EAET,IAAI,EAAE,OAAO;GACX,OAAO,EAAE,MAAM;GACf,OAAO,EAAE,MAAM;EACjB;CACF,QAAQ,CAER;CACA,OAAO;AACT;;;;;AAMA,eAAsB,iBAAiB,MAGE;CAEvC,IAAI,CAAC,MADiB,wBAAwB,GAChC;CAEd,MAAM,SAAS,MAAM,OAAO;CAC5B,MAAM,KAAK,MAAM,OAAO;CACxB,MAAM,eAAe,OAAO,KAAK;EAC/B,KAAK;EACL,SAAS,KAAK;EACd,aAAa,QAAQ,IAAI,YAAY;EACrC,gBAAgB;EAChB,qBAAqB;EACrB,cAAc,CAEd;EACA,WAAW,OAAO;GAChB,OAAO,WAAW,KAAK;EACzB;EACA,iBAAiB,YAAY;GAC3B,IAAI,WAAW,SACb,WAAW,UAAU,YAAY,WAAW,OAAO;GAErD,OAAO;EACT;CACF,CAAC;CACD,OAAO,OAAO,YAAY,KAAK,OAAO;CACtC,IAAI,KAAK,SAAS,OAAO,OAAO,eAAe,KAAK,OAAO;CAI3D,OAAO,OAAO,MAAM,QAAQ,QAAQ;CACpC,OAAO,OAAO,QAAQ,QAAQ,IAAI;CAClC,OAAO,OAAO,gBAAgB,QAAQ,OAAO;CAC7C,OAAO,OAAO,MAAM,OAAO,QAAQ,QAAQ,IAAI,EAAE,CAAC,CAAC;CACnD,OAAO,OAAO,OAAO,OAAO,QAAQ,QAAQ,MAAM,KAAK,CAAC,CAAC;CACzD,OAAO,WAAW,WAAW;EAC3B,MAAM;EACN,SAAS,QAAQ;CACnB,CAAC;CACD,OAAO,WAAW,MAAM;EACtB,MAAM,QAAQ;EACd,SAAS,GAAG,QAAQ;CACtB,CAAC;CACD,OAAO,WAAW,UAAU,EAC1B,MAAM,QAAQ,KAChB,CAAC;CACD,IAAI,CAAC,cACH;CAEF,OAAO;EACL,wBAAwB,MAAyB;GAC/C,MAAM,OAAO,KAAK,KAAK,IAAI,WAAW;GACtC,MAAM,YAAY,KAAK,KACpB,QAAQ,MAAM,EAAE,WAAW,GAAG,CAAC,CAAC,CAChC,KAAK,MAAM,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE;GAC7B,IAAI,KAAK,SAAS,OAAO,OAAO,WAAW,KAAK,OAAO;GACvD,IAAI,KAAK,YAAY,OAAO,OAAO,cAAc,KAAK,UAAU;GAChE,IAAI,KAAK,IAAI,OAAO,OAAO,MAAM,KAAK,EAAE;GACxC,OAAO,WAAW,cAAc;IAC9B,SAAS,KAAK;IACd,YAAY,KAAK;IACjB;IACA,YAAY;IACZ,YAAY,KAAK;IACjB,KAAK,KAAK,MAAM,YAAY,KAAK,GAAG,IAAI,KAAA;GAC1C,CAAC;GACD,OAAO,cAAc;IACnB,UAAU;IACV,OAAO;IACP,SAAS;IACT,MAAM;KACJ,SAAS,KAAK;KACd,IAAI,KAAK;KACT,KAAK,QAAQ,QAAQ,MAAM,KAAK;KAChC,IAAI,QAAQ,QAAQ,IAAI,EAAE;IAC5B;GACF,CAAC;EACH;EACA,iBAAiB,OACf,KACA,gBACG;GACH,IAAI;IACF,OAAO,OAAO,cAAc,aAAa,QAAQ,OAAO;IACxD,aAAa,iBAAiB,GAAG;IACjC,MAAM,aAAa,MAAM,GAAI;GAC/B,QAAQ,CAER;EACF;CACF;AACF;;;;AAKA,SAAgB,oBAAoB,SAAwB;CAC1D,YAAY;EAAE;EAAS,0BAAS,IAAI,KAAK,EAAA,CAAE,YAAY;CAAE,CAAC;AAC5D;;;;AAKA,SAAgB,qBAG0B;CACxC,IAAI,qBAAqB,GAAG,OAAO;EAAE,QAAQ;EAAO,SAAS;CAAM;CACnE,IAAI,oBAAoB,GAAG,OAAO;EAAE,QAAQ;EAAO,SAAS;CAAK;CACjE,MAAM,SAAS,WAAW;CAC1B,IAAI,QACF,OAAO;EACL,QAAQ;EACR,SAAS,OAAO;EAChB,SAAS,OAAO;CAClB;CACF,OAAO;EAAE,QAAQ;EAAW,SAAS;CAAM;AAC7C"}
|
|
@@ -1,5 +1,9 @@
|
|
|
1
|
+
import "mutative";
|
|
2
|
+
import "luxon";
|
|
1
3
|
import { z } from "zod";
|
|
2
|
-
|
|
4
|
+
import "cmd-ts/dist/cjs/argparser.js";
|
|
5
|
+
import "package-manager-detector";
|
|
6
|
+
import "kysely";
|
|
3
7
|
//#region clis/constants.d.ts
|
|
4
8
|
declare const SERVICE_ACTIONS: readonly ["start", "stop", "status", "setup", "restart"];
|
|
5
9
|
declare const SECONDS_IN_DAY: number;
|
|
@@ -161,7 +165,7 @@ declare const externalDevDependencies: {
|
|
|
161
165
|
readonly oxlint: "1.70.0";
|
|
162
166
|
readonly "oxlint-tsgolint": "0.23.0";
|
|
163
167
|
readonly tailwindcss: "^4.1.16";
|
|
164
|
-
readonly typescript: "
|
|
168
|
+
readonly typescript: "~7.0.2";
|
|
165
169
|
readonly vite: "^8.0.10";
|
|
166
170
|
readonly "vite-tsconfig-paths": "6.1.1";
|
|
167
171
|
readonly vitest: "4.1.1";
|
|
@@ -191,10 +195,13 @@ type PHConnectDefaultDriveRemote = {
|
|
|
191
195
|
icon?: string | null;
|
|
192
196
|
};
|
|
193
197
|
type PHConnectDefaultDriveLocal = {
|
|
194
|
-
/** Discriminator: this entry is a local drive created on first boot. */
|
|
198
|
+
/** Discriminator: this entry is a local drive created on first boot. */
|
|
199
|
+
local: true;
|
|
200
|
+
/** Stable drive id; the drive is not re-created on later boots. */
|
|
195
201
|
id: string;
|
|
196
202
|
name?: string | null;
|
|
197
|
-
icon?: string | null;
|
|
203
|
+
icon?: string | null;
|
|
204
|
+
/** Drive app (preferred editor) to open on the drive. */
|
|
198
205
|
app?: string;
|
|
199
206
|
};
|
|
200
207
|
type PHConnectDefaultDrive = PHConnectDefaultDriveRemote | PHConnectDefaultDriveLocal;
|
|
@@ -221,19 +228,26 @@ type PHConnectApp = {
|
|
|
221
228
|
workflowsEnabled?: boolean;
|
|
222
229
|
};
|
|
223
230
|
type PHConnectAi = {
|
|
224
|
-
/** Enables the in-browser AI assistant (chat FAB + window). Off by default. */
|
|
231
|
+
/** Enables the in-browser AI assistant (chat FAB + window). Off by default. */
|
|
232
|
+
assistantEnabled?: boolean;
|
|
225
233
|
};
|
|
226
234
|
type PHConnectPackages = {
|
|
227
|
-
externalEnabled?: boolean;
|
|
235
|
+
externalEnabled?: boolean;
|
|
236
|
+
/** Subscribe to the static-mode `/__packages` SSE channel for live reload. */
|
|
228
237
|
liveReload?: boolean;
|
|
229
238
|
};
|
|
230
239
|
type PHRenownRainbowAdapterConfig = {
|
|
231
|
-
/** WalletConnect project id; required for the rainbow adapter to function. */
|
|
240
|
+
/** WalletConnect project id; required for the rainbow adapter to function. */
|
|
241
|
+
walletConnectProjectId?: string;
|
|
242
|
+
/** Optional Infura project id used to build RPC transports. */
|
|
232
243
|
infuraProjectId?: string;
|
|
233
244
|
};
|
|
234
245
|
type PHRenownPrivyAdapterConfig = {
|
|
235
|
-
/** Privy application id; required for the privy adapter to function. */
|
|
236
|
-
|
|
246
|
+
/** Privy application id; required for the privy adapter to function. */
|
|
247
|
+
appId?: string;
|
|
248
|
+
/** Optional Privy client id. */
|
|
249
|
+
clientId?: string;
|
|
250
|
+
/** Login methods this adapter offers; defaults per adapter when omitted. */
|
|
237
251
|
methods?: string[];
|
|
238
252
|
};
|
|
239
253
|
type PHConnectRenownAdapters = {
|
|
@@ -243,14 +257,20 @@ type PHConnectRenownAdapters = {
|
|
|
243
257
|
type PHConnectRenown = {
|
|
244
258
|
url?: string;
|
|
245
259
|
networkId?: string;
|
|
246
|
-
chainId?: number;
|
|
247
|
-
|
|
248
|
-
|
|
260
|
+
chainId?: number;
|
|
261
|
+
/** Renown localStorage namespace; share it across Connects to share login. */
|
|
262
|
+
namespace?: string;
|
|
263
|
+
/** Switchboard GraphQL URL; when set, enables in-page (no-redirect) auth. */
|
|
264
|
+
switchboardUrl?: string;
|
|
265
|
+
/** Per-adapter wallet config; presence of a key enables that adapter. */
|
|
249
266
|
adapters?: PHConnectRenownAdapters;
|
|
250
267
|
};
|
|
251
268
|
type PHConnectSentry = {
|
|
252
|
-
/** Sentry DSN URL. `null` disables Sentry entirely. */
|
|
253
|
-
|
|
269
|
+
/** Sentry DSN URL. `null` disables Sentry entirely. */
|
|
270
|
+
dsn?: string | null;
|
|
271
|
+
/** Sentry environment label. */
|
|
272
|
+
env?: string;
|
|
273
|
+
/** Enable Sentry performance tracing. */
|
|
254
274
|
tracing?: boolean;
|
|
255
275
|
};
|
|
256
276
|
type PHConnectInstance = {
|
|
@@ -260,13 +280,18 @@ type PHConnectInstance = {
|
|
|
260
280
|
/** Each flag implies its predecessors, and must match the fleet Connect syncs
|
|
261
281
|
* with or the two compute different replay outcomes. */
|
|
262
282
|
type PHConnectReactorFeatureFlags = {
|
|
263
|
-
/** Decide writes from the document stream instead of the meta cache. */
|
|
264
|
-
|
|
265
|
-
|
|
283
|
+
/** Decide writes from the document stream instead of the meta cache. */
|
|
284
|
+
documentDecisions?: boolean;
|
|
285
|
+
/** Enforce the auth scope's policy at admission, replay, and read. */
|
|
286
|
+
authEnforcement?: boolean;
|
|
287
|
+
/** Let `{ group }` principals match, via the group documents' rosters. */
|
|
288
|
+
authGroups?: boolean;
|
|
289
|
+
/** Evaluate `where` / `match` conditions on grants. */
|
|
266
290
|
authConditions?: boolean;
|
|
267
291
|
};
|
|
268
292
|
type PHConnectReactor = {
|
|
269
|
-
featureFlags?: PHConnectReactorFeatureFlags;
|
|
293
|
+
featureFlags?: PHConnectReactorFeatureFlags;
|
|
294
|
+
/** What new documents are created as; `legacy` while peers predate v2-required documents. */
|
|
270
295
|
createSignaturePolicy?: "legacy" | "v2-required";
|
|
271
296
|
};
|
|
272
297
|
/**
|
|
@@ -316,7 +341,9 @@ type PHConnectPwaIcon = {
|
|
|
316
341
|
* at Connect's app root, injected at build time.
|
|
317
342
|
*/
|
|
318
343
|
type PHConnectPwaFileHandler = {
|
|
319
|
-
/** MIME type → file extensions (each must start with "."). */
|
|
344
|
+
/** MIME type → file extensions (each must start with "."). */
|
|
345
|
+
accept: Record<string, string[]>;
|
|
346
|
+
/** OS-level file-type icons. */
|
|
320
347
|
icons?: PHConnectPwaIcon[];
|
|
321
348
|
launch_type?: "single-client" | "multiple-clients";
|
|
322
349
|
};
|
|
@@ -330,8 +357,10 @@ type PHConnectPwaManifest = {
|
|
|
330
357
|
display?: "fullscreen" | "standalone" | "minimal-ui" | "browser";
|
|
331
358
|
start_url?: string;
|
|
332
359
|
scope?: string;
|
|
333
|
-
icons?: PHConnectPwaIcon[];
|
|
334
|
-
|
|
360
|
+
icons?: PHConnectPwaIcon[];
|
|
361
|
+
/** Extra file associations, appended after Connect's built-in `.phd`/`.phdm` handler. */
|
|
362
|
+
file_handlers?: PHConnectPwaFileHandler[];
|
|
363
|
+
/** How the OS launches the app for handled files/links. */
|
|
335
364
|
launch_handler?: {
|
|
336
365
|
client_mode: "auto" | "focus-existing" | "navigate-existing" | "navigate-new";
|
|
337
366
|
};
|
|
@@ -351,11 +380,16 @@ type PHConnectPwaManifest = {
|
|
|
351
380
|
* Precedence: defaults < package fragments < project config.
|
|
352
381
|
*/
|
|
353
382
|
type PHConnectPwa = {
|
|
354
|
-
manifest?: PHConnectPwaManifest;
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
383
|
+
manifest?: PHConnectPwaManifest;
|
|
384
|
+
/** Extra Workbox precache globs, unioned with the built-in patterns. */
|
|
385
|
+
globPatterns?: string[];
|
|
386
|
+
/** Extra Workbox precache ignore globs, unioned with the built-in list. */
|
|
387
|
+
globIgnores?: string[];
|
|
388
|
+
/** Raise the precache file-size ceiling; the max across contributors wins. */
|
|
389
|
+
maximumFileSizeToCacheInBytes?: number;
|
|
390
|
+
/** Additional runtime-caching rules, appended after the built-in rules. */
|
|
391
|
+
runtimeCaching?: PHConnectPwaRuntimeCaching[];
|
|
392
|
+
/** Extra SPA-fallback denylist patterns, unioned with the built-in list. */
|
|
359
393
|
navigateFallbackDenylist?: PHConnectPwaUrlPattern[];
|
|
360
394
|
};
|
|
361
395
|
type PHConnectRuntimeConfig = {
|
|
@@ -374,8 +408,10 @@ type PHConnectRuntimeConfig = {
|
|
|
374
408
|
type PHReactorRenown = {
|
|
375
409
|
/** "self" reads this reactor's own renown read model; "remote" (default)
|
|
376
410
|
* queries a Renown or Switchboard instance. */
|
|
377
|
-
source?: "remote" | "self";
|
|
378
|
-
|
|
411
|
+
source?: "remote" | "self";
|
|
412
|
+
/** Renown base URL; also the instance this reactor's own identity uses. */
|
|
413
|
+
url?: string;
|
|
414
|
+
/** Switchboard GraphQL endpoint to read credentials from directly. */
|
|
379
415
|
switchboardUrl?: string;
|
|
380
416
|
};
|
|
381
417
|
type PowerhouseConfig = {
|
|
@@ -488,4 +524,5 @@ declare const ManifestSchema: z.ZodObject<{
|
|
|
488
524
|
type Manifest = z.infer<typeof ManifestSchema>;
|
|
489
525
|
//#endregion
|
|
490
526
|
export { PIECES_FRAMEWORK_PACKAGE as A, VERSIONED_DEPENDENCIES as B, LEGACY_LINT_FORMAT_FILES as C, PH_BIN as D, PEER_EXTERNAL_DEPENDENCIES as E, PROJECT_PORT_BAND_SWITCHBOARD as F, externalDevDependencies as G, VERSIONED_PEER_DEPENDENCIES as H, PROJECT_PORT_BAND_VETRA_CONNECT as I, packageJsonExports as K, REACTOR_API_PACKAGE as L, POWERHOUSE_GLOBAL_DIR as M, PROJECT_PORT_BAND_SIZE as N, PH_GLOBAL_DIR_NAME as O, PROJECT_PORT_BAND_STUDIO as P, SECONDS_IN_DAY as R, LEGACY_LINT_FORMAT_DEPENDENCIES as S, MINIMUM_NODE_VERSION as T, defaultManifest as U, VERSIONED_DEV_DEPENDENCIES as V, externalDependencies as W, DRIVES_PRESERVE_STRATEGIES as _, DEFAULT_CONFIG as a, GRAPHQL_TAG_PACKAGE as b, DEFAULT_CONNECT_STUDIO_PORT as c, DEFAULT_REGISTRY_URL as d, DEFAULT_RENOWN_URL as f, DEFAULT_VETRA_DRIVE_ID as g, DEFAULT_VETRA_CONNECT_PORT as h, BOILERPLATE_DEPENDENCY_OVERRIDES as i, POWERHOUSE_CONFIG_FILE as j, PH_GLOBAL_PROJECT_NAME as k, DEFAULT_EXPIRY_DAYS as l, DEFAULT_TIMEOUT as m, ANALYTICS_ENGINE_CORE_PACKAGE as n, DEFAULT_CONNECT_OUTDIR as o, DEFAULT_SWITCHBOARD_PORT as p, packageScripts as q, BOILERPLATE_ALLOWED_BUILDS as r, DEFAULT_CONNECT_PREVIEW_PORT as s, Manifest as t, DEFAULT_EXPIRY_SECONDS as u, FEATURE_DEPENDENCIES as v, LOG_LEVELS as w, HOME_DIR as x, GRAPHQL_PACKAGE as y, SERVICE_ACTIONS as z };
|
|
491
|
-
|
|
527
|
+
export {};
|
|
528
|
+
//# sourceMappingURL=types-CMFHKrgv.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types-CMFHKrgv.d.mts","names":[],"sources":["../../clis/constants.ts","../../clis/types.ts","../../document-model/schemas.ts","../../document-model/types.ts"],"mappings":";;;;;;;cAKa;cAQA;cACA;cACA;cAEA;cAKA;cAQA;cAEA;cAEA;cAEA;cAEA;cAEA;cAEA;cAEA;cAqBA;cACA;cACA;cACA;cAEA;cAEA;cACA;cACA;cACA;cAEA;cAEA;cAEA;cAGA;cAOA;cACA;cAEA;cACA;cACA;cAQA;;aACU;aAAa;;;aACT;aAAY;;;aAC5B;aAAa;;;aACP;aAAa;;;aACrB;aAAY;;;cAKR;;aAET;aACA;aACA;;;aAKA;aACA;aACA;;;cAWS;cAUA;cAiBA;WACC;WACN;WACI;;cAGC;cAQA;WACX;aACE;aACA;aACA;;WAEF;aACE;aACA;;WAEF;aACE;aACA;aACA;;WAEF;aACE;aACA;aACA;;WAEF;aACE;aACA;aACA;;WAEF;aACE;aACA;aACA;;WAEF;aACE;aACA;aACA;;WAEF;aACE;aACA;aACA;;WAKF;aACE;aACA;;WAEF;aACE;aACA;;WAEF;WACA;;cAGW;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WAEA;;cAIW;cAIA;cAcA;cAwBA;WACX;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;WACA;;cAGW,iBAAiB;cAuBjB,gBAAgB;;;KCxUjB,iCAAiC;KACjC,wBAAwB;KACxB,mBAAmB;KACnB,WAAW;KAOX;KAGA;EACV;EACA;EACA,WAAW;EACX;;KAGU;EACV;EACA;;KAGU;EACV;EACA;EACA;;KAGU;;EAEV;;EAEA;EACA;EACA;;EAEA;;KAGU,wBACR,8BACA;KAEQ;EACV;EACA;EACA;;KAGU;EACV,SAAS;EACT,QAAQ;;KAGE;EACV;EACA,gBAAgB;EAChB,mBAAmB;EACnB,WAAW;;KAGD;EACV;EACA;EACA;EAGA;EAMA;;KAGU;;EAEV;;KAGU;EACV;;EAEA;;KAGU;;EAEV;;EAEA;;KAGU;;EAEV;;EAEA;;EAEA;;KAGU;EACV,UAAU;EACV,QAAQ;;KAGE;EACV;EACA;EACA;;EAEA;;EAEA;;EAEA,WAAW;;KAGD;;EAEV;;EAEA;;EAEA;;KAGU;EACV;EACA;;;;KAKU;;EAEV;;EAEA;;EAEA;;EAEA;;KAGU;EACV,eAAe;;EAEf;;;;;;;;;;KAWU;EAEN;EAAgB;;KAEV;;KAQA;EACV,YAAY;EACZ,SAAS;EACT;EACA;IACE;;;IAGA;IACA;MAAe;MAAqB;;IACpC;MACE;MACA,UAAU;;;;KAKJ;EACV;EACA;EACA;EACA;;;;;;;;;KAUU;;EAEV,QAAQ;;EAER,QAAQ;EACR;;;KAIU;EACV;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA,QAAQ;;EAER,gBAAgB;;EAEhB;IACE;;;;;EASF;;;;;;;;;;;;KAaU;EACV,WAAW;;EAEX;;EAEA;;EAEA;;EAEA,iBAAiB;;EAEjB,2BAA2B;;KAGjB;EACV,WAAW;EACX,MAAM;EACN,KAAK;EACL,WAAW;EACX,SAAS;EACT,SAAS;EACT,SAAS;EACT,WAAW;EACX,UAAU;EACV,MAAM;;;KAII;;;EAGV;;EAEA;;EAEA;;KAGU;EAEV,UAAU;EACV;EACA;EACA;EACA;EACA;EACA;EAGA;EACA;EACA;IACE;IACA;MAIM;MACA;;IAEN;MACE;MACA;MACA;;;EAGJ;IACE;IACA;IACA,SAAS;;EAEX;IACE;MACE;;IAEF;;EAEF;IACE;IACA;IACA;IACA;;EAEF,WAAW;EACX;IACE;IACA;IACA;;EAIF;IACE;;EAEF;EACA,UAAU;;;;cC0fC,gBAAc,EAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiBzB,EAAA,KAAA;;;KC+zBU,WAAW,EAAE,aAAa"}
|
package/dist/clis/utils.d.mts
CHANGED
|
@@ -5,15 +5,15 @@
|
|
|
5
5
|
* `strict-dep-builds=true` default doesn't prompt for approval during the
|
|
6
6
|
* outer dlx download. No-op for other package managers or non-dlx commands.
|
|
7
7
|
*/
|
|
8
|
-
declare function injectPnpmAllowBuilds(pm: string, resolved: {
|
|
8
|
+
export declare function injectPnpmAllowBuilds(pm: string, resolved: {
|
|
9
9
|
command: string;
|
|
10
10
|
args: string[];
|
|
11
11
|
}): void;
|
|
12
|
-
declare class NodeVersionError extends Error {
|
|
12
|
+
export declare class NodeVersionError extends Error {
|
|
13
13
|
constructor(currentVersion: string, minimumVersion: string);
|
|
14
14
|
static isError(error: unknown): error is NodeVersionError;
|
|
15
15
|
}
|
|
16
|
-
declare function assertNodeVersion(nodeVersion?: string): void;
|
|
16
|
+
export declare function assertNodeVersion(nodeVersion?: string): void;
|
|
17
17
|
//#endregion
|
|
18
|
-
export {
|
|
18
|
+
export {};
|
|
19
19
|
//# sourceMappingURL=utils.d.mts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../clis/utils.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"utils.d.mts","names":[],"sources":["../../clis/utils.ts"],"mappings":";;;;;;;wBAagB,sBACd,YACA;EAAY;EAAiB;;qBAOlB,yBAAyB;EACpC,YAAY,wBAAwB;SAO7B,QAAQ,iBAAiB,SAAS;;wBAK3B,kBAAkB"}
|
package/dist/clis/utils.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"utils.mjs","names":[],"sources":["../../clis/utils.ts"],"sourcesContent":["// Sub-path: this module loads on the cold path of every CLI invocation.\nimport lt from \"semver/functions/lt.js\";\nimport {\n BOILERPLATE_ALLOWED_BUILDS,\n MINIMUM_NODE_VERSION,\n} from \"./constants.js\";\n\n/**\n * Mutates a resolved `pnpm dlx ...` command to add one `--allow-build=<pkg>`\n * flag per package in {@link BOILERPLATE_ALLOWED_BUILDS}, so pnpm 11's\n * `strict-dep-builds=true` default doesn't prompt for approval during the\n * outer dlx download. No-op for other package managers or non-dlx commands.\n */\nexport function injectPnpmAllowBuilds(\n pm: string,\n resolved: { command: string; args: string[] },\n): void {\n if (pm !== \"pnpm\" || resolved.args[0] !== \"dlx\") return;\n const flags = BOILERPLATE_ALLOWED_BUILDS.map((pkg) => `--allow-build=${pkg}`);\n resolved.args = [resolved.args[0], ...flags, ...resolved.args.slice(1)];\n}\n\nexport class NodeVersionError extends Error {\n constructor(currentVersion: string, minimumVersion: string) {\n super(\n `Node version ${minimumVersion} or higher is required. Current version: ${currentVersion}`,\n );\n this.name = \"NodeVersionError\";\n }\n\n static isError(error: unknown): error is NodeVersionError {\n return error instanceof Error && error.name === \"NodeVersionError\";\n }\n}\n\nexport function assertNodeVersion(nodeVersion = process.versions.node) {\n if (!nodeVersion) return;\n\n if (lt(nodeVersion, MINIMUM_NODE_VERSION)) {\n throw new NodeVersionError(nodeVersion, MINIMUM_NODE_VERSION);\n }\n}\n"],"mappings":";;;;;;;;;AAaA,SAAgB,sBACd,IACA,UACM;
|
|
1
|
+
{"version":3,"file":"utils.mjs","names":[],"sources":["../../clis/utils.ts"],"sourcesContent":["// Sub-path: this module loads on the cold path of every CLI invocation.\nimport lt from \"semver/functions/lt.js\";\nimport {\n BOILERPLATE_ALLOWED_BUILDS,\n MINIMUM_NODE_VERSION,\n} from \"./constants.js\";\n\n/**\n * Mutates a resolved `pnpm dlx ...` command to add one `--allow-build=<pkg>`\n * flag per package in {@link BOILERPLATE_ALLOWED_BUILDS}, so pnpm 11's\n * `strict-dep-builds=true` default doesn't prompt for approval during the\n * outer dlx download. No-op for other package managers or non-dlx commands.\n */\nexport function injectPnpmAllowBuilds(\n pm: string,\n resolved: { command: string; args: string[] },\n): void {\n if (pm !== \"pnpm\" || resolved.args[0] !== \"dlx\") return;\n const flags = BOILERPLATE_ALLOWED_BUILDS.map((pkg) => `--allow-build=${pkg}`);\n resolved.args = [resolved.args[0], ...flags, ...resolved.args.slice(1)];\n}\n\nexport class NodeVersionError extends Error {\n constructor(currentVersion: string, minimumVersion: string) {\n super(\n `Node version ${minimumVersion} or higher is required. Current version: ${currentVersion}`,\n );\n this.name = \"NodeVersionError\";\n }\n\n static isError(error: unknown): error is NodeVersionError {\n return error instanceof Error && error.name === \"NodeVersionError\";\n }\n}\n\nexport function assertNodeVersion(nodeVersion = process.versions.node) {\n if (!nodeVersion) return;\n\n if (lt(nodeVersion, MINIMUM_NODE_VERSION)) {\n throw new NodeVersionError(nodeVersion, MINIMUM_NODE_VERSION);\n }\n}\n"],"mappings":";;;;;;;;;AAaA,SAAgB,sBACd,IACA,UACM;CACN,IAAI,OAAO,UAAU,SAAS,KAAK,OAAO,OAAO;CACjD,MAAM,QAAQ,2BAA2B,KAAK,QAAQ,iBAAiB,KAAK;CAC5E,SAAS,OAAO;EAAC,SAAS,KAAK;EAAI,GAAG;EAAO,GAAG,SAAS,KAAK,MAAM,CAAC;CAAC;AACxE;AAEA,IAAa,mBAAb,cAAsC,MAAM;CAC1C,YAAY,gBAAwB,gBAAwB;EAC1D,MACE,gBAAgB,eAAe,2CAA2C,gBAC5E;EACA,KAAK,OAAO;CACd;CAEA,OAAO,QAAQ,OAA2C;EACxD,OAAO,iBAAiB,SAAS,MAAM,SAAS;CAClD;AACF;AAEA,SAAgB,kBAAkB,cAAc,QAAQ,SAAS,MAAM;CACrE,IAAI,CAAC,aAAa;CAElB,IAAI,GAAG,aAAA,QAAiC,GACtC,MAAM,IAAI,iBAAiB,aAAa,oBAAoB;AAEhE"}
|
|
@@ -103,6 +103,8 @@ function deepMerge(base, patch) {
|
|
|
103
103
|
* CLI typically constructs a fresh loader per command.
|
|
104
104
|
*/
|
|
105
105
|
var ConfigLoader = class {
|
|
106
|
+
adapter;
|
|
107
|
+
defaults;
|
|
106
108
|
cache;
|
|
107
109
|
constructor(adapter, defaults = DEFAULT_CONNECT_CONFIG) {
|
|
108
110
|
this.adapter = adapter;
|
|
@@ -148,4 +150,4 @@ var ConfigLoader = class {
|
|
|
148
150
|
//#endregion
|
|
149
151
|
export { buildRuntimeConfig as i, deepMerge as n, DEFAULT_CONNECT_CONFIG as r, ConfigLoader as t };
|
|
150
152
|
|
|
151
|
-
//# sourceMappingURL=config-loader-
|
|
153
|
+
//# sourceMappingURL=config-loader-SYDWHtqk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader-
|
|
1
|
+
{"version":3,"file":"config-loader-SYDWHtqk.js","names":[],"sources":["../connect/runtime-config.ts","../connect/config-loader.ts"],"sourcesContent":["import type {\n PHConnectRuntimeConfig,\n PowerhouseConfig,\n PowerhousePackage,\n} from \"../clis/types.js\";\n\nexport type RuntimePowerhouseConfig = {\n schemaVersion: 2;\n packages: PowerhousePackage[];\n packageRegistryUrl?: string;\n localPackage: { name: string; version: string } | null;\n connect: PHConnectRuntimeConfig;\n};\n\n/** Defaults for every field Connect reads at runtime, merged into the\n * `connect.*` block at boot; also the dist emitter's and the scaffold's base. */\nexport const DEFAULT_CONNECT_CONFIG: PHConnectRuntimeConfig = {\n branding: {\n appName: \"Powerhouse Connect\",\n homeBackground: null,\n },\n app: {\n logLevel: \"info\",\n basePath: \"/\",\n offline: true,\n studioMode: false,\n workflowsEnabled: false,\n },\n ai: {\n assistantEnabled: false,\n },\n packages: {\n externalEnabled: true,\n liveReload: false,\n },\n drives: {\n allowAddDrive: true,\n defaultDrives: [],\n sections: {\n remote: { enabled: true, allowAdd: true, allowDelete: true },\n local: { enabled: true, allowAdd: true, allowDelete: true },\n },\n },\n renown: {\n url: \"https://www.renown.id\",\n networkId: \"eip155\",\n chainId: 1,\n },\n sentry: {\n // `dsn: null` is the disabled-Sentry state — the SPA never loads the\n // Sentry SDK chunk. Override via `ph connect config --sentry-dsn ...`\n // or by including `connect.sentry.dsn` in PH_CONNECT_CONFIG_JSON.\n dsn: null,\n env: \"dev\",\n tracing: false,\n },\n instance: {\n namespace: null,\n reactorWorker: false,\n },\n reactor: {\n featureFlags: {\n documentDecisions: false,\n authEnforcement: false,\n authGroups: false,\n authConditions: false,\n },\n createSignaturePolicy: \"v2-required\",\n },\n};\n\nexport function buildRuntimeConfig(\n source: Pick<PowerhouseConfig, \"packages\" | \"connect\" | \"packageRegistryUrl\">,\n projectInfo: { name: string; version: string } | null,\n): RuntimePowerhouseConfig {\n const result: RuntimePowerhouseConfig = {\n schemaVersion: 2,\n packages: source.packages ?? [],\n localPackage: projectInfo,\n connect: source.connect ?? {},\n };\n if (\n typeof source.packageRegistryUrl === \"string\" &&\n source.packageRegistryUrl !== \"\"\n ) {\n result.packageRegistryUrl = source.packageRegistryUrl;\n }\n return result;\n}\n","// Environment-neutral config loader. Wraps a `ConfigAdapter` (the IO layer)\n// with in-process caching and deep-merge-with-defaults reads.\n//\n// No validation. The loader trusts that whatever bytes the adapter returns\n// can be merged into the default Connect config; missing or partial fields\n// fall back to DEFAULT_CONNECT_CONFIG, so the SPA always sees a complete\n// `connect.*` block.\n//\n// Top-level fields outside `connect.*` (e.g. `studio.port` in the source\n// powerhouse.config.json) pass through untouched on both read and write.\n// They're not Connect's concern, but a write-back round-trip preserves\n// them so editing tools don't accidentally drop them.\n\nimport { isPlainObject } from \"remeda\";\nimport type { PHConnectRuntimeConfig } from \"../clis/types.js\";\nimport { DEFAULT_CONNECT_CONFIG } from \"./runtime-config.js\";\n\n/** Recursive Partial. Arrays are leaves — `write({ packages: [...] })`\n * replaces the array, it doesn't merge. */\nexport type DeepPartial<T> =\n T extends Array<infer U>\n ? Array<U>\n : T extends object\n ? { [K in keyof T]?: DeepPartial<T[K]> }\n : T;\n\n/**\n * Shape returned by `ConfigLoader.read()`. The loader is Connect-scoped:\n * it guarantees `connect` is present and fully populated from\n * DEFAULT_CONNECT_CONFIG, but lets any other top-level fields pass\n * through unchanged so source-config-only fields (studio, reactor, auth,\n * documentModelsDir, etc.) survive a read+write round-trip.\n */\nexport type ConfigShape = Record<string, unknown> & {\n connect: PHConnectRuntimeConfig;\n};\n\n/**\n * Abstract IO layer for `powerhouse.config.json`.\n *\n * Implementations decide where bytes come from and go to. The shipped\n * adapter is `JsonConfigAdapter` (reads via fetch in the browser, fs in\n * Node; writes via fs in Node, throws in the browser). Future adapters\n * (remote-JSON, GraphQL) plug in without changing the loader or any\n * consumer.\n */\nexport interface ConfigAdapter {\n /** Read raw JSON-parsed payload from the backing store. */\n read(): Promise<unknown>;\n /** Persist a fully-formed config. */\n write(next: ConfigShape): Promise<void>;\n /** Human-readable description used in errors and logs. */\n readonly source: string;\n}\n\n/**\n * Deep-merge `patch` into `base`. Object fields recurse; arrays and\n * primitives replace. `undefined` in patch leaves the base value\n * untouched (no unset). `null` in patch overwrites with null.\n *\n * Exported for unit tests; consumers use ConfigLoader.write() which\n * applies this internally.\n */\nexport function deepMerge<T>(base: T, patch: DeepPartial<T>): T {\n if (!isPlainObject(base) || !isPlainObject(patch)) {\n return patch as T;\n }\n const result: Record<string, unknown> = { ...base };\n for (const [key, patchValue] of Object.entries(patch)) {\n if (patchValue === undefined) continue;\n const baseValue = result[key];\n if (isPlainObject(baseValue) && isPlainObject(patchValue)) {\n result[key] = deepMerge(\n baseValue,\n patchValue as DeepPartial<typeof baseValue>,\n );\n } else {\n result[key] = patchValue;\n }\n }\n return result as T;\n}\n\n/**\n * Pluggable loader on top of a `ConfigAdapter`.\n *\n * Responsibilities:\n * - merge-with-defaults on read (so consumers never see a partial connect block)\n * - in-process caching (call `invalidate()` to force re-read)\n * - deep-merge for partial writes; writes the merged whole back through the adapter\n *\n * The cache is module-instance scoped — every `new ConfigLoader(...)` has\n * its own cache. The browser SPA constructs the loader once at boot; the\n * CLI typically constructs a fresh loader per command.\n */\nexport class ConfigLoader {\n private cache: ConfigShape | undefined;\n\n constructor(\n private readonly adapter: ConfigAdapter,\n private readonly defaults: PHConnectRuntimeConfig = DEFAULT_CONNECT_CONFIG,\n ) {}\n\n /** Returns the config with the default connect block merged in.\n * Cached after the first successful call. */\n async read(): Promise<ConfigShape> {\n if (this.cache) return this.cache;\n const raw = await this.adapter.read();\n const obj = isPlainObject(raw) ? raw : {};\n const connectRaw = isPlainObject(obj.connect) ? obj.connect : {};\n this.cache = {\n ...obj,\n connect: deepMerge(\n this.defaults,\n connectRaw as DeepPartial<PHConnectRuntimeConfig>,\n ),\n };\n return this.cache;\n }\n\n /**\n * Returns the cached config synchronously. Throws if `read()` has not\n * resolved yet — matches Connect's `getRuntimeConfig()` shape.\n */\n getCached(): ConfigShape {\n if (!this.cache) {\n throw new Error(\n `ConfigLoader (${this.adapter.source}): cache empty; call read() first.`,\n );\n }\n return this.cache;\n }\n\n /** Drop the in-memory cache. Next `read()` re-fetches from the adapter. */\n invalidate(): void {\n this.cache = undefined;\n }\n\n /**\n * Deep-merge `patch` into the current config and persist via the adapter.\n * Returns the new full config (also updates the cache). Arrays in `patch`\n * replace — they do NOT append.\n */\n async write(patch: DeepPartial<ConfigShape>): Promise<ConfigShape> {\n const current = await this.read();\n const next = deepMerge(current, patch);\n await this.adapter.write(next);\n this.cache = next;\n return next;\n }\n}\n"],"mappings":";;;;AAgBA,MAAa,yBAAiD;CAC5D,UAAU;EACR,SAAS;EACT,gBAAgB;CAClB;CACA,KAAK;EACH,UAAU;EACV,UAAU;EACV,SAAS;EACT,YAAY;EACZ,kBAAkB;CACpB;CACA,IAAI,EACF,kBAAkB,MACpB;CACA,UAAU;EACR,iBAAiB;EACjB,YAAY;CACd;CACA,QAAQ;EACN,eAAe;EACf,eAAe,CAAC;EAChB,UAAU;GACR,QAAQ;IAAE,SAAS;IAAM,UAAU;IAAM,aAAa;GAAK;GAC3D,OAAO;IAAE,SAAS;IAAM,UAAU;IAAM,aAAa;GAAK;EAC5D;CACF;CACA,QAAQ;EACN,KAAK;EACL,WAAW;EACX,SAAS;CACX;CACA,QAAQ;EAIN,KAAK;EACL,KAAK;EACL,SAAS;CACX;CACA,UAAU;EACR,WAAW;EACX,eAAe;CACjB;CACA,SAAS;EACP,cAAc;GACZ,mBAAmB;GACnB,iBAAiB;GACjB,YAAY;GACZ,gBAAgB;EAClB;EACA,uBAAuB;CACzB;AACF;AAEA,SAAgB,mBACd,QACA,aACyB;CACzB,MAAM,SAAkC;EACtC,eAAe;EACf,UAAU,OAAO,YAAY,CAAC;EAC9B,cAAc;EACd,SAAS,OAAO,WAAW,CAAC;CAC9B;CACA,IACE,OAAO,OAAO,uBAAuB,YACrC,OAAO,uBAAuB,IAE9B,OAAO,qBAAqB,OAAO;CAErC,OAAO;AACT;;;;;;;;;;;ACzBA,SAAgB,UAAa,MAAS,OAA0B;CAC9D,IAAI,CAAC,cAAc,IAAI,KAAK,CAAC,cAAc,KAAK,GAC9C,OAAO;CAET,MAAM,SAAkC,EAAE,GAAG,KAAK;CAClD,KAAK,MAAM,CAAC,KAAK,eAAe,OAAO,QAAQ,KAAK,GAAG;EACrD,IAAI,eAAe,KAAA,GAAW;EAC9B,MAAM,YAAY,OAAO;EACzB,IAAI,cAAc,SAAS,KAAK,cAAc,UAAU,GACtD,OAAO,OAAO,UACZ,WACA,UACF;OAEA,OAAO,OAAO;CAElB;CACA,OAAO;AACT;;;;;;;;;;;;;AAcA,IAAa,eAAb,MAA0B;CAIL;CACA;CAJnB;CAEA,YACE,SACA,WAAoD,wBACpD;EAFiB,KAAA,UAAA;EACA,KAAA,WAAA;CAChB;;;CAIH,MAAM,OAA6B;EACjC,IAAI,KAAK,OAAO,OAAO,KAAK;EAC5B,MAAM,MAAM,MAAM,KAAK,QAAQ,KAAK;EACpC,MAAM,MAAM,cAAc,GAAG,IAAI,MAAM,CAAC;EACxC,MAAM,aAAa,cAAc,IAAI,OAAO,IAAI,IAAI,UAAU,CAAC;EAC/D,KAAK,QAAQ;GACX,GAAG;GACH,SAAS,UACP,KAAK,UACL,UACF;EACF;EACA,OAAO,KAAK;CACd;;;;;CAMA,YAAyB;EACvB,IAAI,CAAC,KAAK,OACR,MAAM,IAAI,MACR,iBAAiB,KAAK,QAAQ,OAAO,mCACvC;EAEF,OAAO,KAAK;CACd;;CAGA,aAAmB;EACjB,KAAK,QAAQ,KAAA;CACf;;;;;;CAOA,MAAM,MAAM,OAAuD;EAEjE,MAAM,OAAO,UAAU,MADD,KAAK,KAAK,GACA,KAAK;EACrC,MAAM,KAAK,QAAQ,MAAM,IAAI;EAC7B,KAAK,QAAQ;EACb,OAAO;CACT;AACF"}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { D as PHConnectRuntimeConfig } from "../types-
|
|
2
|
-
|
|
1
|
+
import { D as PHConnectRuntimeConfig } from "../types-xLPOHE23.js";
|
|
3
2
|
//#region connect/config-loader.d.ts
|
|
4
3
|
/** Recursive Partial. Arrays are leaves — `write({ packages: [...] })`
|
|
5
4
|
* replaces the array, it doesn't merge. */
|
|
6
|
-
type DeepPartial<T> = T extends Array<infer U> ? Array<U> : T extends object ? { [K in keyof T]?: DeepPartial<T[K]
|
|
5
|
+
export type DeepPartial<T> = T extends Array<infer U> ? Array<U> : T extends object ? { [K in keyof T]?: DeepPartial<T[K]>; } : T;
|
|
7
6
|
/**
|
|
8
7
|
* Shape returned by `ConfigLoader.read()`. The loader is Connect-scoped:
|
|
9
8
|
* it guarantees `connect` is present and fully populated from
|
|
@@ -11,7 +10,7 @@ type DeepPartial<T> = T extends Array<infer U> ? Array<U> : T extends object ? {
|
|
|
11
10
|
* through unchanged so source-config-only fields (studio, reactor, auth,
|
|
12
11
|
* documentModelsDir, etc.) survive a read+write round-trip.
|
|
13
12
|
*/
|
|
14
|
-
type ConfigShape = Record<string, unknown> & {
|
|
13
|
+
export type ConfigShape = Record<string, unknown> & {
|
|
15
14
|
connect: PHConnectRuntimeConfig;
|
|
16
15
|
};
|
|
17
16
|
/**
|
|
@@ -23,7 +22,7 @@ type ConfigShape = Record<string, unknown> & {
|
|
|
23
22
|
* (remote-JSON, GraphQL) plug in without changing the loader or any
|
|
24
23
|
* consumer.
|
|
25
24
|
*/
|
|
26
|
-
interface ConfigAdapter {
|
|
25
|
+
export interface ConfigAdapter {
|
|
27
26
|
/** Read raw JSON-parsed payload from the backing store. */
|
|
28
27
|
read(): Promise<unknown>;
|
|
29
28
|
/** Persist a fully-formed config. */
|
|
@@ -39,7 +38,7 @@ interface ConfigAdapter {
|
|
|
39
38
|
* Exported for unit tests; consumers use ConfigLoader.write() which
|
|
40
39
|
* applies this internally.
|
|
41
40
|
*/
|
|
42
|
-
declare function deepMerge<T>(base: T, patch: DeepPartial<T>): T;
|
|
41
|
+
export declare function deepMerge<T>(base: T, patch: DeepPartial<T>): T;
|
|
43
42
|
/**
|
|
44
43
|
* Pluggable loader on top of a `ConfigAdapter`.
|
|
45
44
|
*
|
|
@@ -52,7 +51,7 @@ declare function deepMerge<T>(base: T, patch: DeepPartial<T>): T;
|
|
|
52
51
|
* its own cache. The browser SPA constructs the loader once at boot; the
|
|
53
52
|
* CLI typically constructs a fresh loader per command.
|
|
54
53
|
*/
|
|
55
|
-
declare class ConfigLoader {
|
|
54
|
+
export declare class ConfigLoader {
|
|
56
55
|
private readonly adapter;
|
|
57
56
|
private readonly defaults;
|
|
58
57
|
private cache;
|
|
@@ -75,5 +74,5 @@ declare class ConfigLoader {
|
|
|
75
74
|
write(patch: DeepPartial<ConfigShape>): Promise<ConfigShape>;
|
|
76
75
|
}
|
|
77
76
|
//#endregion
|
|
78
|
-
export {
|
|
77
|
+
export {};
|
|
79
78
|
//# sourceMappingURL=config-loader.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config-loader.d.ts","names":[],"sources":["../../connect/config-loader.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"config-loader.d.ts","names":[],"sources":["../../connect/config-loader.ts"],"mappings":";;;;YAmBY,YAAY,KACtB,UAAU,YAAY,KAClB,MAAM,KACN,sBACK,WAAW,KAAK,YAAY,EAAE,SACjC;;;;;;;;YASI,cAAc;EACxB,SAAS;;;;;;;;;;;iBAYM;;EAEf,QAAQ;;EAER,MAAM,MAAM,cAAc;;WAEjB;;;;;;;;;;wBAWK,UAAU,GAAG,MAAM,GAAG,OAAO,YAAY,KAAK;;;;;;;;;;;;;qBAgCjD;mBAIQ;mBACA;UAJX;EAER,YACmB,SAAS,eACT,WAAU;;;EAKvB,QAAQ,QAAQ;;;;;EAmBtB,aAAa;;EAUb;;;;;;EASM,MAAM,OAAO,YAAY,eAAe,QAAQ"}
|