@happier-dev/stack 0.1.0-preview.17.1 → 0.1.0-preview.21.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (119) hide show
  1. package/docs/server-flavors.md +6 -6
  2. package/node_modules/@happier-dev/cli-common/dist/index.d.ts +2 -0
  3. package/node_modules/@happier-dev/cli-common/dist/index.d.ts.map +1 -1
  4. package/node_modules/@happier-dev/cli-common/dist/index.js +2 -0
  5. package/node_modules/@happier-dev/cli-common/dist/index.js.map +1 -1
  6. package/node_modules/@happier-dev/cli-common/dist/providers/index.d.ts +51 -0
  7. package/node_modules/@happier-dev/cli-common/dist/providers/index.d.ts.map +1 -0
  8. package/node_modules/@happier-dev/cli-common/dist/providers/index.js +129 -0
  9. package/node_modules/@happier-dev/cli-common/dist/providers/index.js.map +1 -0
  10. package/node_modules/@happier-dev/cli-common/dist/service/index.d.ts +5 -0
  11. package/node_modules/@happier-dev/cli-common/dist/service/index.d.ts.map +1 -0
  12. package/node_modules/@happier-dev/cli-common/dist/service/index.js +5 -0
  13. package/node_modules/@happier-dev/cli-common/dist/service/index.js.map +1 -0
  14. package/node_modules/@happier-dev/cli-common/dist/service/launchd.d.ts +19 -0
  15. package/node_modules/@happier-dev/cli-common/dist/service/launchd.d.ts.map +1 -0
  16. package/node_modules/@happier-dev/cli-common/dist/service/launchd.js +117 -0
  17. package/node_modules/@happier-dev/cli-common/dist/service/launchd.js.map +1 -0
  18. package/node_modules/@happier-dev/cli-common/dist/service/manager.d.ts +55 -0
  19. package/node_modules/@happier-dev/cli-common/dist/service/manager.d.ts.map +1 -0
  20. package/node_modules/@happier-dev/cli-common/dist/service/manager.js +302 -0
  21. package/node_modules/@happier-dev/cli-common/dist/service/manager.js.map +1 -0
  22. package/node_modules/@happier-dev/cli-common/dist/service/systemd.d.ts +12 -0
  23. package/node_modules/@happier-dev/cli-common/dist/service/systemd.d.ts.map +1 -0
  24. package/node_modules/@happier-dev/cli-common/dist/service/systemd.js +75 -0
  25. package/node_modules/@happier-dev/cli-common/dist/service/systemd.js.map +1 -0
  26. package/node_modules/@happier-dev/cli-common/dist/service/windows.d.ts +8 -0
  27. package/node_modules/@happier-dev/cli-common/dist/service/windows.d.ts.map +1 -0
  28. package/node_modules/@happier-dev/cli-common/dist/service/windows.js +29 -0
  29. package/node_modules/@happier-dev/cli-common/dist/service/windows.js.map +1 -0
  30. package/node_modules/@happier-dev/cli-common/package.json +11 -0
  31. package/node_modules/@happier-dev/release-runtime/dist/assets.d.ts +22 -0
  32. package/node_modules/@happier-dev/release-runtime/dist/assets.d.ts.map +1 -0
  33. package/node_modules/@happier-dev/release-runtime/dist/assets.js +44 -0
  34. package/node_modules/@happier-dev/release-runtime/dist/assets.js.map +1 -0
  35. package/node_modules/@happier-dev/release-runtime/dist/checksums.d.ts +5 -0
  36. package/node_modules/@happier-dev/release-runtime/dist/checksums.d.ts.map +1 -0
  37. package/node_modules/@happier-dev/release-runtime/dist/checksums.js +21 -0
  38. package/node_modules/@happier-dev/release-runtime/dist/checksums.js.map +1 -0
  39. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.d.ts +14 -0
  40. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.d.ts.map +1 -0
  41. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.js +39 -0
  42. package/node_modules/@happier-dev/release-runtime/dist/extractPlan.js.map +1 -0
  43. package/node_modules/@happier-dev/release-runtime/dist/github.d.ts +20 -0
  44. package/node_modules/@happier-dev/release-runtime/dist/github.d.ts.map +1 -0
  45. package/node_modules/@happier-dev/release-runtime/dist/github.js +60 -0
  46. package/node_modules/@happier-dev/release-runtime/dist/github.js.map +1 -0
  47. package/node_modules/@happier-dev/release-runtime/dist/index.d.ts +7 -0
  48. package/node_modules/@happier-dev/release-runtime/dist/index.d.ts.map +1 -0
  49. package/node_modules/@happier-dev/release-runtime/dist/index.js +7 -0
  50. package/node_modules/@happier-dev/release-runtime/dist/index.js.map +1 -0
  51. package/node_modules/@happier-dev/release-runtime/dist/minisign.d.ts +7 -0
  52. package/node_modules/@happier-dev/release-runtime/dist/minisign.d.ts.map +1 -0
  53. package/node_modules/@happier-dev/release-runtime/dist/minisign.js +92 -0
  54. package/node_modules/@happier-dev/release-runtime/dist/minisign.js.map +1 -0
  55. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.d.ts +26 -0
  56. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.d.ts.map +1 -0
  57. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.js +53 -0
  58. package/node_modules/@happier-dev/release-runtime/dist/verifiedDownload.js.map +1 -0
  59. package/node_modules/@happier-dev/release-runtime/package.json +38 -0
  60. package/package.json +4 -2
  61. package/scripts/auth.mjs +3 -2
  62. package/scripts/auth_copy_from_pglite_lock_in_use.integration.test.mjs +1 -0
  63. package/scripts/auth_copy_from_runCapture.integration.test.mjs +8 -1
  64. package/scripts/auth_login_guided_server_no_expo.test.mjs +2 -0
  65. package/scripts/build.mjs +3 -18
  66. package/scripts/bundleWorkspaceDeps.mjs +5 -1
  67. package/scripts/bundleWorkspaceDeps.test.mjs +42 -1
  68. package/scripts/mobile.mjs +30 -2
  69. package/scripts/mobile_dev_client.mjs +7 -32
  70. package/scripts/mobile_dev_client_help_smoke.test.mjs +24 -0
  71. package/scripts/mobile_prebuild_happyDir_defined.test.mjs +47 -0
  72. package/scripts/mobile_prebuild_sets_rct_metro_port.test.mjs +81 -0
  73. package/scripts/mobile_run_ios_passes_port.integration.test.mjs +103 -0
  74. package/scripts/mobile_run_ios_uses_long_port_flag.test.mjs +106 -0
  75. package/scripts/providers_cmd.mjs +262 -0
  76. package/scripts/release_binary_smoke.integration.test.mjs +45 -37
  77. package/scripts/remote_cmd.mjs +352 -0
  78. package/scripts/self_host_daemon.real.integration.test.mjs +296 -0
  79. package/scripts/self_host_launchd.real.integration.test.mjs +211 -0
  80. package/scripts/self_host_runtime.mjs +1829 -327
  81. package/scripts/self_host_runtime.test.mjs +523 -1
  82. package/scripts/self_host_schtasks.real.integration.test.mjs +217 -0
  83. package/scripts/self_host_service_e2e_harness.mjs +93 -0
  84. package/scripts/self_host_systemd.real.integration.test.mjs +8 -86
  85. package/scripts/service.mjs +156 -26
  86. package/scripts/stack/command_arguments.mjs +1 -0
  87. package/scripts/stack/help_text.mjs +3 -1
  88. package/scripts/stack.mjs +2 -1
  89. package/scripts/stack_daemon_cmd.integration.test.mjs +37 -0
  90. package/scripts/stack_happy_cmd.integration.test.mjs +36 -0
  91. package/scripts/stack_pr_help_cmd.test.mjs +38 -0
  92. package/scripts/stop.mjs +2 -3
  93. package/scripts/utils/auth/credentials_paths.mjs +9 -9
  94. package/scripts/utils/auth/credentials_paths.test.mjs +8 -0
  95. package/scripts/utils/auth/orchestrated_stack_auth_flow.mjs +64 -3
  96. package/scripts/utils/auth/stable_scope_id.mjs +1 -1
  97. package/scripts/utils/cli/cli_registry.mjs +21 -0
  98. package/scripts/utils/cli/progress.mjs +8 -1
  99. package/scripts/utils/cli/progress.test.mjs +43 -0
  100. package/scripts/utils/dev/expo_dev.buildEnv.test.mjs +17 -0
  101. package/scripts/utils/dev/expo_dev.mjs +35 -5
  102. package/scripts/utils/dev/expo_dev_restart_port_reservation.test.mjs +180 -1
  103. package/scripts/utils/dev/expo_dev_runtime_metadata.test.mjs +126 -0
  104. package/scripts/utils/dev/expo_dev_verbose_logs.test.mjs +9 -2
  105. package/scripts/utils/mobile/dev_client_install_invocation.mjs +68 -0
  106. package/scripts/utils/mobile/dev_client_install_invocation.test.mjs +27 -0
  107. package/scripts/utils/server/port.mjs +20 -2
  108. package/scripts/utils/service/service_manager.definition.test.mjs +66 -0
  109. package/scripts/utils/service/service_manager.mjs +96 -0
  110. package/scripts/utils/service/service_manager.plan.test.mjs +37 -0
  111. package/scripts/utils/service/service_manager.test.mjs +20 -0
  112. package/scripts/utils/service/systemd_service_unit.mjs +1 -0
  113. package/scripts/utils/service/systemd_service_unit.test.mjs +42 -0
  114. package/scripts/utils/service/windows_schtasks_wrapper.mjs +1 -0
  115. package/scripts/utils/service/windows_schtasks_wrapper.test.mjs +25 -0
  116. package/scripts/utils/ui/ui_export_env.mjs +29 -0
  117. package/scripts/utils/ui/ui_export_env.test.mjs +25 -0
  118. package/scripts/worktrees.mjs +3 -0
  119. package/scripts/worktrees_status_default_target.test.mjs +56 -0
@@ -9,7 +9,7 @@ Both flavors use the **same server codebase** (the monorepo server package, typi
9
9
  ### `happier-server-light` (recommended default)
10
10
 
11
11
  - **No Docker required**
12
- - Uses **embedded Postgres via PGlite** (“PG_Light”) stored under the stack directory (per-stack isolation)
12
+ - Uses **SQLite by default** (stack-local file), with optional embedded Postgres via PGlite
13
13
  - Stores local public files under the stack directory
14
14
  - Best choice for a stable “main” stack and quick local installs
15
15
 
@@ -18,6 +18,7 @@ Light stacks are isolated by default:
18
18
  ```
19
19
  ~/.happier/stacks/<stack>/server-light/files
20
20
  ~/.happier/stacks/<stack>/server-light/pglite
21
+ ~/.happier/stacks/<stack>/server-light/happier-server-light.sqlite
21
22
  ```
22
23
 
23
24
  Key env vars (stored in the stack env file):
@@ -65,10 +66,10 @@ For a “one URL” UX (especially with Tailscale), hstack starts a lightweight
65
66
 
66
67
  This means `hstack start --server=happier-server` can still work end-to-end without requiring AWS S3 or a separate nginx setup.
67
68
 
68
- ## Migrating between flavors (PG_LightPostgres)
69
+ ## Migrating between flavors (lightfull)
69
70
 
70
71
  hstack includes an **experimental** migration helper that can copy core chat data from a
71
- `happier-server-light` stack (embedded PGlite) into a `happier-server` stack (Docker Postgres):
72
+ `happier-server-light` stack into a `happier-server` stack (Docker Postgres):
72
73
 
73
74
  ```bash
74
75
  hstack migrate light-to-server --from-stack=main --to-stack=full1
@@ -90,7 +91,7 @@ Notes:
90
91
  - **`hstack dev`** is for rapid iteration:
91
92
  - for `happier-server`: hstack runs `prisma migrate deploy` by default (configurable via `HAPPIER_STACK_PRISMA_MIGRATE`).
92
93
  - for `happier-server-light`:
93
- - hstack runs the server package’s `migrate:light:deploy` script, which applies `prisma migrate deploy` against the **embedded PGlite DB** using the standard Postgres schema (`prisma/schema.prisma`).
94
+ - hstack runs the server package’s `migrate:light:deploy` script, which applies provider-specific light migrations (SQLite by default, or PGlite when configured).
94
95
 
95
96
  Important: for a given run (`hstack start` / `hstack dev`) you choose **one** flavor.
96
97
 
@@ -143,5 +144,4 @@ There are two separate concepts:
143
144
 
144
145
  ## SQLite note
145
146
 
146
- SQLite is **not** used by `happier-server-light` today (it is PG_Light via embedded PGlite). SQLite may be reintroduced later as an additional light flavor, but it is not part of the current default stack.
147
-
147
+ SQLite is the default DB for `happier-server-light`. You can opt into embedded Postgres (PGlite) by setting `HAPPIER_DB_PROVIDER=pglite` in the stack env.
@@ -1,4 +1,6 @@
1
1
  export * as update from './update/index.js';
2
2
  export * as workspaces from './workspaces/index.js';
3
3
  export * as links from './links.js';
4
+ export * as service from './service/index.js';
5
+ export * as providers from './providers/index.js';
4
6
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC"}
@@ -1,4 +1,6 @@
1
1
  export * as update from './update/index.js';
2
2
  export * as workspaces from './workspaces/index.js';
3
3
  export * as links from './links.js';
4
+ export * as service from './service/index.js';
5
+ export * as providers from './providers/index.js';
4
6
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC;AAC5C,OAAO,KAAK,UAAU,MAAM,uBAAuB,CAAC;AACpD,OAAO,KAAK,KAAK,MAAM,YAAY,CAAC;AACpC,OAAO,KAAK,OAAO,MAAM,oBAAoB,CAAC;AAC9C,OAAO,KAAK,SAAS,MAAM,sBAAsB,CAAC"}
@@ -0,0 +1,51 @@
1
+ import type { AgentId, ProviderCliInstallPlatform, ProviderCliInstallSpec } from '@happier-dev/agents';
2
+ export type ProviderCliInstallPlan = Readonly<{
3
+ providerId: AgentId;
4
+ title: string;
5
+ binaries: ReadonlyArray<string>;
6
+ platform: ProviderCliInstallPlatform;
7
+ docsUrl: string | null;
8
+ commands: ReadonlyArray<Readonly<{
9
+ cmd: string;
10
+ args: ReadonlyArray<string>;
11
+ requiresAdmin: boolean;
12
+ note: string | null;
13
+ }>>;
14
+ requiresAdmin: boolean;
15
+ }>;
16
+ export type ProviderCliInstallPlanResult = Readonly<{
17
+ ok: true;
18
+ plan: ProviderCliInstallPlan;
19
+ spec: ProviderCliInstallSpec;
20
+ }> | Readonly<{
21
+ ok: false;
22
+ errorCode: 'no-recipe';
23
+ errorMessage: string;
24
+ spec: ProviderCliInstallSpec;
25
+ }>;
26
+ export declare function resolvePlatformFromNodePlatform(nodePlatform: string): ProviderCliInstallPlatform | null;
27
+ export declare function planProviderCliInstall(params: Readonly<{
28
+ providerId: AgentId;
29
+ platform: ProviderCliInstallPlatform;
30
+ }>): ProviderCliInstallPlanResult;
31
+ export type InstallProviderCliResult = Readonly<{
32
+ ok: true;
33
+ plan: ProviderCliInstallPlan;
34
+ alreadyInstalled: boolean;
35
+ logPath: string | null;
36
+ }> | Readonly<{
37
+ ok: false;
38
+ errorCode: 'no-recipe' | 'command-not-found' | 'command-exec-failed' | 'command-failed';
39
+ errorMessage: string;
40
+ plan: ProviderCliInstallPlan | null;
41
+ logPath: string | null;
42
+ }>;
43
+ export declare function installProviderCli(params: Readonly<{
44
+ providerId: AgentId;
45
+ platform: ProviderCliInstallPlatform;
46
+ env?: NodeJS.ProcessEnv;
47
+ logDir?: string | null;
48
+ dryRun?: boolean;
49
+ skipIfInstalled?: boolean;
50
+ }>): InstallProviderCliResult;
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,OAAO,EAAE,0BAA0B,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAGvG,MAAM,MAAM,sBAAsB,GAAG,QAAQ,CAAC;IAC5C,UAAU,EAAE,OAAO,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;IAChC,QAAQ,EAAE,0BAA0B,CAAC;IACrC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,QAAQ,EAAE,aAAa,CAAC,QAAQ,CAAC;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAAC,aAAa,EAAE,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;KAAE,CAAC,CAAC,CAAC;IAC7H,aAAa,EAAE,OAAO,CAAC;CACxB,CAAC,CAAC;AAEH,MAAM,MAAM,4BAA4B,GACpC,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC,GAClF,QAAQ,CAAC;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,SAAS,EAAE,WAAW,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAA;CAAE,CAAC,CAAC;AAExG,wBAAgB,+BAA+B,CAAC,YAAY,EAAE,MAAM,GAAG,0BAA0B,GAAG,IAAI,CAKvG;AA0BD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAE,UAAU,EAAE,OAAO,CAAC;IAAC,QAAQ,EAAE,0BAA0B,CAAA;CAAE,CAAC,GAAG,4BAA4B,CAqBpJ;AAwCD,MAAM,MAAM,wBAAwB,GAChC,QAAQ,CAAC;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,sBAAsB,CAAC;IAAC,gBAAgB,EAAE,OAAO,CAAC;IAAC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,GACvG,QAAQ,CAAC;IACP,EAAE,EAAE,KAAK,CAAC;IACV,SAAS,EAAE,WAAW,GAAG,mBAAmB,GAAG,qBAAqB,GAAG,gBAAgB,CAAC;IACxF,YAAY,EAAE,MAAM,CAAC;IACrB,IAAI,EAAE,sBAAsB,GAAG,IAAI,CAAC;IACpC,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB,CAAC,CAAC;AAEP,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAClD,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,0BAA0B,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,CAAC,UAAU,CAAC;IACxB,MAAM,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B,CAAC,GAAG,wBAAwB,CAiD5B"}
@@ -0,0 +1,129 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { mkdirSync, writeFileSync, appendFileSync } from 'node:fs';
3
+ import { tmpdir } from 'node:os';
4
+ import { join } from 'node:path';
5
+ import { getProviderCliInstallSpec } from '@happier-dev/agents';
6
+ export function resolvePlatformFromNodePlatform(nodePlatform) {
7
+ if (nodePlatform === 'darwin')
8
+ return 'darwin';
9
+ if (nodePlatform === 'linux')
10
+ return 'linux';
11
+ if (nodePlatform === 'win32')
12
+ return 'win32';
13
+ return null;
14
+ }
15
+ function commandExists(cmd, env) {
16
+ const name = String(cmd ?? '').trim();
17
+ if (!name)
18
+ return false;
19
+ const pathEnv = env.PATH ?? process.env.PATH;
20
+ if (process.platform === 'win32') {
21
+ const res = spawnSync('where', [name], { stdio: 'ignore', env: { ...process.env, ...env, PATH: pathEnv } });
22
+ return (res.status ?? 1) === 0;
23
+ }
24
+ const res = spawnSync('sh', ['-lc', `command -v ${name} >/dev/null 2>&1`], { stdio: 'ignore', env: { ...process.env, ...env, PATH: pathEnv } });
25
+ return (res.status ?? 1) === 0;
26
+ }
27
+ function resolveProviderInstallCommands(spec, platform) {
28
+ const commandsRaw = spec.install?.[platform] ?? null;
29
+ if (!commandsRaw || commandsRaw.length === 0)
30
+ return null;
31
+ return commandsRaw.map((c) => ({
32
+ cmd: c.cmd,
33
+ args: [...c.args],
34
+ requiresAdmin: Boolean(c.requiresAdmin),
35
+ note: typeof c.note === 'string' ? c.note : null,
36
+ }));
37
+ }
38
+ export function planProviderCliInstall(params) {
39
+ const spec = getProviderCliInstallSpec(params.providerId);
40
+ const commands = resolveProviderInstallCommands(spec, params.platform);
41
+ if (!commands) {
42
+ return { ok: false, errorCode: 'no-recipe', spec, errorMessage: `No auto-install recipe available for ${spec.id} on ${params.platform}.` };
43
+ }
44
+ const requiresAdmin = commands.some((c) => c.requiresAdmin);
45
+ return {
46
+ ok: true,
47
+ spec,
48
+ plan: {
49
+ providerId: spec.id,
50
+ title: spec.title,
51
+ binaries: spec.binaries,
52
+ platform: params.platform,
53
+ docsUrl: typeof spec.docsUrl === 'string' ? spec.docsUrl : null,
54
+ commands,
55
+ requiresAdmin,
56
+ },
57
+ };
58
+ }
59
+ function resolveLogPath(params) {
60
+ const base = typeof params.logDir === 'string' && params.logDir.trim() ? params.logDir.trim() : join(tmpdir(), 'happier-provider-installs');
61
+ mkdirSync(base, { recursive: true });
62
+ return join(base, `install-provider-${params.providerId}-${Date.now()}.log`);
63
+ }
64
+ function writeLogHeader(logPath, plan) {
65
+ writeFileSync(logPath, [
66
+ `# providerId: ${plan.providerId}`,
67
+ `# platform: ${plan.platform}`,
68
+ `# requiresAdmin: ${plan.requiresAdmin ? '1' : '0'}`,
69
+ '',
70
+ ].join('\n'), 'utf8');
71
+ }
72
+ function appendCommandLog(logPath, cmd, args, stdout, stderr, status) {
73
+ appendFileSync(logPath, [
74
+ '',
75
+ `## ${cmd} ${args.join(' ')}`.trim(),
76
+ `# exit: ${status ?? 'null'}`,
77
+ '',
78
+ '### stdout',
79
+ stdout || '',
80
+ '',
81
+ '### stderr',
82
+ stderr || '',
83
+ '',
84
+ ].join('\n'), 'utf8');
85
+ }
86
+ export function installProviderCli(params) {
87
+ const env = params.env ?? process.env;
88
+ const skipIfInstalled = params.skipIfInstalled !== false;
89
+ const planned = planProviderCliInstall({ providerId: params.providerId, platform: params.platform });
90
+ if (!planned.ok) {
91
+ return { ok: false, errorCode: planned.errorCode, errorMessage: planned.errorMessage, plan: null, logPath: null };
92
+ }
93
+ const plan = planned.plan;
94
+ if (skipIfInstalled) {
95
+ const allPresent = plan.binaries.every((b) => commandExists(b, env));
96
+ if (allPresent) {
97
+ return { ok: true, plan, alreadyInstalled: true, logPath: null };
98
+ }
99
+ }
100
+ if (params.dryRun) {
101
+ return { ok: true, plan, alreadyInstalled: false, logPath: null };
102
+ }
103
+ const logPath = resolveLogPath({ providerId: params.providerId, logDir: params.logDir });
104
+ writeLogHeader(logPath, plan);
105
+ for (const c of plan.commands) {
106
+ if (!commandExists(c.cmd, env)) {
107
+ return { ok: false, errorCode: 'command-not-found', errorMessage: `Command not found: ${c.cmd}`, plan, logPath };
108
+ }
109
+ const res = spawnSync(c.cmd, [...c.args], { encoding: 'utf8', env: { ...process.env, ...env } });
110
+ if (res.error) {
111
+ appendCommandLog(logPath, c.cmd, c.args, '', res.error.message, res.status ?? null);
112
+ return { ok: false, errorCode: 'command-exec-failed', errorMessage: res.error.message, plan, logPath };
113
+ }
114
+ const status = typeof res.status === 'number' ? res.status : null;
115
+ appendCommandLog(logPath, c.cmd, c.args, String(res.stdout ?? ''), String(res.stderr ?? ''), status);
116
+ if (status !== 0) {
117
+ const stderr = String(res.stderr ?? '').trim();
118
+ return {
119
+ ok: false,
120
+ errorCode: 'command-failed',
121
+ errorMessage: stderr || `Command failed (${status ?? 'unknown'}): ${c.cmd}`,
122
+ plan,
123
+ logPath,
124
+ };
125
+ }
126
+ }
127
+ return { ok: true, plan, alreadyInstalled: false, logPath };
128
+ }
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/providers/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export * from './launchd.js';
2
+ export * from './systemd.js';
3
+ export * from './windows.js';
4
+ export * from './manager.js';
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/service/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ export * from './launchd.js';
2
+ export * from './systemd.js';
3
+ export * from './windows.js';
4
+ export * from './manager.js';
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/service/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC;AAC7B,cAAc,cAAc,CAAC"}
@@ -0,0 +1,19 @@
1
+ export declare function buildLaunchdPath(params?: Readonly<{
2
+ execPath?: string;
3
+ basePath?: string;
4
+ }>): string;
5
+ export declare function buildLaunchdPlistXml(params: Readonly<{
6
+ label: string;
7
+ programArgs: readonly string[];
8
+ env?: Record<string, string>;
9
+ stdoutPath: string;
10
+ stderrPath: string;
11
+ workingDirectory?: string;
12
+ keepAliveOnFailure?: boolean;
13
+ startIntervalSec?: number;
14
+ startCalendarInterval?: Readonly<{
15
+ hour: number;
16
+ minute: number;
17
+ }>;
18
+ }>): string;
19
+ //# sourceMappingURL=launchd.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launchd.d.ts","sourceRoot":"","sources":["../../src/service/launchd.ts"],"names":[],"mappings":"AASA,wBAAgB,gBAAgB,CAAC,MAAM,GAAE,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAM,GAAG,MAAM,CAmBxG;AAWD,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,QAAQ,CAAC;IACpD,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qBAAqB,CAAC,EAAE,QAAQ,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACpE,CAAC,GAAG,MAAM,CA0FV"}
@@ -0,0 +1,117 @@
1
+ import { dirname } from 'node:path';
2
+ function splitPath(p) {
3
+ return String(p ?? '')
4
+ .split(':')
5
+ .map((s) => s.trim())
6
+ .filter(Boolean);
7
+ }
8
+ export function buildLaunchdPath(params = {}) {
9
+ // launchd starts with a minimal environment; ensure common tool paths exist,
10
+ // and include the current Node binary directory so shell shims that exec `node`
11
+ // still work (e.g. nvm-managed installs).
12
+ const execPath = String(params.execPath ?? '').trim();
13
+ const basePath = String(params.basePath ?? '').trim();
14
+ const nodeDir = execPath ? dirname(execPath) : '';
15
+ const defaults = splitPath('/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin');
16
+ const fromNode = nodeDir ? [nodeDir] : [];
17
+ const fromEnv = splitPath(basePath);
18
+ const seen = new Set();
19
+ const out = [];
20
+ for (const part of [...fromNode, ...fromEnv, ...defaults]) {
21
+ if (seen.has(part))
22
+ continue;
23
+ seen.add(part);
24
+ out.push(part);
25
+ }
26
+ return out.join(':') || '/usr/bin:/bin:/usr/sbin:/sbin';
27
+ }
28
+ function xmlEscape(s) {
29
+ return String(s ?? '')
30
+ .replaceAll('&', '&amp;')
31
+ .replaceAll('<', '&lt;')
32
+ .replaceAll('>', '&gt;')
33
+ .replaceAll('"', '&quot;')
34
+ .replaceAll("'", '&apos;');
35
+ }
36
+ export function buildLaunchdPlistXml(params) {
37
+ const label = String(params.label ?? '').trim();
38
+ if (!label)
39
+ throw new Error('label is required');
40
+ const programArgs = Array.isArray(params.programArgs)
41
+ ? params.programArgs.map((a) => String(a ?? '')).filter(Boolean)
42
+ : [];
43
+ if (programArgs.length === 0)
44
+ throw new Error('programArgs is required');
45
+ const envEntries = Object.entries(params.env ?? {}).filter(([k]) => String(k).trim());
46
+ const programArgsXml = programArgs.map((a) => ` <string>${xmlEscape(a)}</string>`).join('\n');
47
+ const envXml = envEntries
48
+ .map(([k, v]) => ` <key>${xmlEscape(k)}</key>\n <string>${xmlEscape(String(v ?? ''))}</string>`)
49
+ .join('\n');
50
+ const stdoutPath = String(params.stdoutPath ?? '').trim();
51
+ const stderrPath = String(params.stderrPath ?? '').trim();
52
+ const workingDirectory = String(params.workingDirectory ?? '').trim();
53
+ const workingDirXml = workingDirectory
54
+ ? `\n <key>WorkingDirectory</key>\n <string>${xmlEscape(workingDirectory)}</string>\n`
55
+ : '\n';
56
+ const keepAlive = params.keepAliveOnFailure === false
57
+ ? ''
58
+ : (`\n <key>KeepAlive</key>\n` +
59
+ ` <dict>\n` +
60
+ ` <key>SuccessfulExit</key>\n` +
61
+ ` <false/>\n` +
62
+ ` </dict>\n`);
63
+ const intervalRaw = Number(params.startIntervalSec);
64
+ const interval = Number.isFinite(intervalRaw) && intervalRaw > 0 ? Math.floor(intervalRaw) : 0;
65
+ const startInterval = interval
66
+ ? `\n <key>StartInterval</key>\n <integer>${interval}</integer>\n`
67
+ : '';
68
+ const calendar = params.startCalendarInterval;
69
+ const calHourRaw = Number(calendar?.hour);
70
+ const calMinuteRaw = Number(calendar?.minute);
71
+ const calHour = Number.isFinite(calHourRaw) ? Math.floor(calHourRaw) : NaN;
72
+ const calMinute = Number.isFinite(calMinuteRaw) ? Math.floor(calMinuteRaw) : NaN;
73
+ const hasCalendar = Number.isFinite(calHour)
74
+ && Number.isFinite(calMinute)
75
+ && calHour >= 0
76
+ && calHour <= 23
77
+ && calMinute >= 0
78
+ && calMinute <= 59;
79
+ const startCalendarInterval = hasCalendar
80
+ ? (`\n <key>StartCalendarInterval</key>\n` +
81
+ ` <dict>\n` +
82
+ ` <key>Hour</key>\n` +
83
+ ` <integer>${calHour}</integer>\n` +
84
+ ` <key>Minute</key>\n` +
85
+ ` <integer>${calMinute}</integer>\n` +
86
+ ` </dict>\n`)
87
+ : '';
88
+ return `<?xml version="1.0" encoding="UTF-8"?>
89
+ <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
90
+ <plist version="1.0">
91
+ <dict>
92
+ <key>Label</key>
93
+ <string>${xmlEscape(label)}</string>
94
+
95
+ <key>ProgramArguments</key>
96
+ <array>
97
+ ${programArgsXml}
98
+ </array>
99
+
100
+ <key>RunAtLoad</key>
101
+ <true/>
102
+ ${keepAlive}
103
+ ${startCalendarInterval || startInterval}
104
+ ${workingDirXml} <key>StandardOutPath</key>
105
+ <string>${xmlEscape(stdoutPath)}</string>
106
+ <key>StandardErrorPath</key>
107
+ <string>${xmlEscape(stderrPath)}</string>
108
+
109
+ <key>EnvironmentVariables</key>
110
+ <dict>
111
+ ${envXml}
112
+ </dict>
113
+ </dict>
114
+ </plist>
115
+ `;
116
+ }
117
+ //# sourceMappingURL=launchd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"launchd.js","sourceRoot":"","sources":["../../src/service/launchd.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,55 @@
1
+ export type ServiceMode = 'user' | 'system';
2
+ export type ServiceBackend = 'systemd-user' | 'systemd-system' | 'launchd-user' | 'launchd-system' | 'schtasks-user' | 'schtasks-system';
3
+ export type ServiceSpec = Readonly<{
4
+ label: string;
5
+ description?: string;
6
+ programArgs: readonly string[];
7
+ workingDirectory?: string;
8
+ env?: Record<string, string>;
9
+ runAsUser?: string;
10
+ stdoutPath?: string;
11
+ stderrPath?: string;
12
+ }>;
13
+ export type ServiceDefinition = Readonly<{
14
+ kind: 'systemd-service' | 'launchd-plist' | 'windows-wrapper-ps1';
15
+ path: string;
16
+ contents: string;
17
+ mode: number;
18
+ }>;
19
+ export type PlannedWrite = Readonly<{
20
+ path: string;
21
+ contents: string;
22
+ mode?: number;
23
+ }>;
24
+ export type PlannedCommand = Readonly<{
25
+ cmd: string;
26
+ args: readonly string[];
27
+ allowFail?: boolean;
28
+ }>;
29
+ export type ServicePlan = Readonly<{
30
+ writes: PlannedWrite[];
31
+ commands: PlannedCommand[];
32
+ }>;
33
+ export declare function resolveServiceBackend(params?: Readonly<{
34
+ platform?: NodeJS.Platform;
35
+ mode?: ServiceMode;
36
+ }>): ServiceBackend;
37
+ export declare function buildServiceDefinition(params: Readonly<{
38
+ backend: ServiceBackend;
39
+ homeDir: string;
40
+ spec: ServiceSpec;
41
+ }>): ServiceDefinition;
42
+ export declare function planServiceAction(params: Readonly<{
43
+ backend: ServiceBackend;
44
+ action: 'install' | 'uninstall' | 'start' | 'stop' | 'restart';
45
+ label: string;
46
+ definitionPath?: string;
47
+ definitionContents?: string;
48
+ taskName?: string;
49
+ persistent?: boolean;
50
+ uid?: number | null;
51
+ }>): ServicePlan;
52
+ export declare function applyServicePlan(plan: ServicePlan, options?: Readonly<{
53
+ runCommands?: boolean;
54
+ }>): Promise<void>;
55
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/service/manager.ts"],"names":[],"mappings":"AAQA,MAAM,MAAM,WAAW,GAAG,MAAM,GAAG,QAAQ,CAAC;AAE5C,MAAM,MAAM,cAAc,GACtB,cAAc,GACd,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,eAAe,GACf,iBAAiB,CAAC;AAEtB,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IACjC,KAAK,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,SAAS,MAAM,EAAE,CAAC;IAC/B,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,GAAG,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7B,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB,CAAC,CAAC;AAEH,MAAM,MAAM,iBAAiB,GAAG,QAAQ,CAAC;IACvC,IAAI,EAAE,iBAAiB,GAAG,eAAe,GAAG,qBAAqB,CAAC;IAClE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;CACd,CAAC,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,QAAQ,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AACvF,MAAM,MAAM,cAAc,GAAG,QAAQ,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,MAAM,EAAE,CAAC;IAAC,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,CAAC;AACrG,MAAM,MAAM,WAAW,GAAG,QAAQ,CAAC;IAAE,MAAM,EAAE,YAAY,EAAE,CAAC;IAAC,QAAQ,EAAE,cAAc,EAAE,CAAA;CAAE,CAAC,CAAC;AAE3F,wBAAgB,qBAAqB,CAAC,MAAM,GAAE,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC;IAAC,IAAI,CAAC,EAAE,WAAW,CAAA;CAAE,CAAM,GAAG,cAAc,CAQ/H;AAwCD,wBAAgB,sBAAsB,CAAC,MAAM,EAAE,QAAQ,CAAC;IAAE,OAAO,EAAE,cAAc,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,WAAW,CAAA;CAAE,CAAC,GAAG,iBAAiB,CAsD3I;AAQD,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,QAAQ,CAAC;IACjD,OAAO,EAAE,cAAc,CAAC;IACxB,MAAM,EAAE,SAAS,GAAG,WAAW,GAAG,OAAO,GAAG,MAAM,GAAG,SAAS,CAAC;IAC/D,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;CACrB,CAAC,GAAG,WAAW,CAyIf;AAaD,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,OAAO,GAAE,QAAQ,CAAC;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAE,CAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAsB1H"}