@happier-dev/stack 0.1.0-preview.5.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 (439) hide show
  1. package/README.md +501 -0
  2. package/bin/hstack.mjs +348 -0
  3. package/docs/codex-mcp-resume.md +129 -0
  4. package/docs/edison.md +74 -0
  5. package/docs/forking-and-branding.md +189 -0
  6. package/docs/happy-development.md +22 -0
  7. package/docs/isolated-linux-vm.md +243 -0
  8. package/docs/menubar.md +244 -0
  9. package/docs/mobile-ios.md +322 -0
  10. package/docs/monorepo-migration.md +20 -0
  11. package/docs/paths-and-env.md +154 -0
  12. package/docs/remote-access.md +43 -0
  13. package/docs/server-flavors.md +147 -0
  14. package/docs/stacks.md +330 -0
  15. package/docs/tauri.md +60 -0
  16. package/docs/worktrees-and-forks.md +133 -0
  17. package/extras/swiftbar/auth-login.sh +29 -0
  18. package/extras/swiftbar/git-cache-refresh.sh +122 -0
  19. package/extras/swiftbar/hstack-term.sh +133 -0
  20. package/extras/swiftbar/hstack.5s.sh +296 -0
  21. package/extras/swiftbar/hstack.sh +35 -0
  22. package/extras/swiftbar/icons/happy-green.png +0 -0
  23. package/extras/swiftbar/icons/happy-orange.png +0 -0
  24. package/extras/swiftbar/icons/happy-red.png +0 -0
  25. package/extras/swiftbar/icons/logo-white.png +0 -0
  26. package/extras/swiftbar/install.sh +265 -0
  27. package/extras/swiftbar/lib/git.sh +629 -0
  28. package/extras/swiftbar/lib/icons.sh +92 -0
  29. package/extras/swiftbar/lib/render.sh +999 -0
  30. package/extras/swiftbar/lib/system.sh +244 -0
  31. package/extras/swiftbar/lib/utils.sh +717 -0
  32. package/extras/swiftbar/set-interval.sh +65 -0
  33. package/extras/swiftbar/set-server-flavor.sh +61 -0
  34. package/extras/swiftbar/wt-pr.sh +140 -0
  35. package/node_modules/@happier-dev/cli-common/README.md +6 -0
  36. package/node_modules/@happier-dev/cli-common/dist/index.d.ts +4 -0
  37. package/node_modules/@happier-dev/cli-common/dist/index.d.ts.map +1 -0
  38. package/node_modules/@happier-dev/cli-common/dist/index.js +4 -0
  39. package/node_modules/@happier-dev/cli-common/dist/index.js.map +1 -0
  40. package/node_modules/@happier-dev/cli-common/dist/links/index.d.ts +18 -0
  41. package/node_modules/@happier-dev/cli-common/dist/links/index.d.ts.map +1 -0
  42. package/node_modules/@happier-dev/cli-common/dist/links/index.js +25 -0
  43. package/node_modules/@happier-dev/cli-common/dist/links/index.js.map +1 -0
  44. package/node_modules/@happier-dev/cli-common/dist/links.d.ts +2 -0
  45. package/node_modules/@happier-dev/cli-common/dist/links.d.ts.map +1 -0
  46. package/node_modules/@happier-dev/cli-common/dist/links.js +2 -0
  47. package/node_modules/@happier-dev/cli-common/dist/links.js.map +1 -0
  48. package/node_modules/@happier-dev/cli-common/dist/update/index.d.ts +67 -0
  49. package/node_modules/@happier-dev/cli-common/dist/update/index.d.ts.map +1 -0
  50. package/node_modules/@happier-dev/cli-common/dist/update/index.js +259 -0
  51. package/node_modules/@happier-dev/cli-common/dist/update/index.js.map +1 -0
  52. package/node_modules/@happier-dev/cli-common/dist/workspaces/index.d.ts +17 -0
  53. package/node_modules/@happier-dev/cli-common/dist/workspaces/index.d.ts.map +1 -0
  54. package/node_modules/@happier-dev/cli-common/dist/workspaces/index.js +80 -0
  55. package/node_modules/@happier-dev/cli-common/dist/workspaces/index.js.map +1 -0
  56. package/node_modules/@happier-dev/cli-common/package.json +26 -0
  57. package/package.json +77 -0
  58. package/scripts/auth.mjs +1829 -0
  59. package/scripts/auth_copy_from_pglite_lock_in_use.integration.test.mjs +90 -0
  60. package/scripts/auth_copy_from_runCapture.integration.test.mjs +447 -0
  61. package/scripts/auth_help_cmd.test.mjs +28 -0
  62. package/scripts/auth_login_flow_in_tty.test.mjs +100 -0
  63. package/scripts/auth_login_force_default.test.mjs +66 -0
  64. package/scripts/auth_login_guided_server_no_expo.test.mjs +126 -0
  65. package/scripts/auth_login_method_override.test.mjs +67 -0
  66. package/scripts/auth_login_print_includes_configure_links.test.mjs +99 -0
  67. package/scripts/auth_status_server_validation.integration.test.mjs +140 -0
  68. package/scripts/build.mjs +266 -0
  69. package/scripts/bundleWorkspaceDeps.mjs +38 -0
  70. package/scripts/bundleWorkspaceDeps.test.mjs +77 -0
  71. package/scripts/ci.mjs +135 -0
  72. package/scripts/ci.test.mjs +50 -0
  73. package/scripts/cli-link.mjs +57 -0
  74. package/scripts/completion.mjs +395 -0
  75. package/scripts/contrib.mjs +333 -0
  76. package/scripts/daemon.mjs +1160 -0
  77. package/scripts/daemon.status_scope.test.mjs +51 -0
  78. package/scripts/daemon_cmd.mjs +26 -0
  79. package/scripts/daemon_dist_guard.test.mjs +171 -0
  80. package/scripts/daemon_invalid_auth_reseed_stack_name.integration.test.mjs +608 -0
  81. package/scripts/daemon_server_scoped_state.test.mjs +49 -0
  82. package/scripts/daemon_start_verification.integration.test.mjs +296 -0
  83. package/scripts/dev.mjs +545 -0
  84. package/scripts/doctor.mjs +340 -0
  85. package/scripts/doctor_cmd.test.mjs +22 -0
  86. package/scripts/doctor_ui_index_missing.test.mjs +37 -0
  87. package/scripts/eas.mjs +367 -0
  88. package/scripts/eas_platform_parsing.test.mjs +63 -0
  89. package/scripts/edison.mjs +1848 -0
  90. package/scripts/env.mjs +149 -0
  91. package/scripts/env_cmd.test.mjs +118 -0
  92. package/scripts/exit_cleanup_kills_detached_children_on_crash.integration.test.mjs +80 -0
  93. package/scripts/happier.mjs +82 -0
  94. package/scripts/import.mjs +1327 -0
  95. package/scripts/init.mjs +464 -0
  96. package/scripts/install.mjs +550 -0
  97. package/scripts/lint.mjs +177 -0
  98. package/scripts/menubar.mjs +202 -0
  99. package/scripts/migrate.mjs +318 -0
  100. package/scripts/mobile.mjs +353 -0
  101. package/scripts/mobile_dev_client.mjs +87 -0
  102. package/scripts/monorepo.mjs +2234 -0
  103. package/scripts/monorepo_port.apply.integration.test.mjs +680 -0
  104. package/scripts/monorepo_port.conflicts.integration.test.mjs +454 -0
  105. package/scripts/monorepo_port.validation.integration.test.mjs +486 -0
  106. package/scripts/orchestrated_stack_auth_flow.test.mjs +134 -0
  107. package/scripts/orchestrated_stack_auth_flow_resolve_port.test.mjs +98 -0
  108. package/scripts/orchestrated_stack_auth_flow_webapp_url.test.mjs +119 -0
  109. package/scripts/pack.mjs +257 -0
  110. package/scripts/pack.test.mjs +68 -0
  111. package/scripts/pglite_lock.integration.test.mjs +152 -0
  112. package/scripts/provision/linux-ubuntu-e2e.sh +132 -0
  113. package/scripts/provision/linux-ubuntu-review-pr.sh +66 -0
  114. package/scripts/provision/macos-lima-happy-vm.sh +192 -0
  115. package/scripts/provision/macos-lima-hstack-e2e.sh +100 -0
  116. package/scripts/release.mjs +53 -0
  117. package/scripts/release_binary_smoke.integration.test.mjs +159 -0
  118. package/scripts/review.mjs +1752 -0
  119. package/scripts/review_pr.mjs +435 -0
  120. package/scripts/run.mjs +561 -0
  121. package/scripts/run_script_with_stack_env.restart_port_reuse.test.mjs +30 -0
  122. package/scripts/self.mjs +465 -0
  123. package/scripts/self_host.mjs +9 -0
  124. package/scripts/self_host_binary_smoke.integration.test.mjs +94 -0
  125. package/scripts/self_host_runtime.mjs +883 -0
  126. package/scripts/self_host_runtime.test.mjs +82 -0
  127. package/scripts/self_host_systemd.real.integration.test.mjs +367 -0
  128. package/scripts/server_flavor.mjs +148 -0
  129. package/scripts/service.mjs +868 -0
  130. package/scripts/service_mode_help.test.mjs +27 -0
  131. package/scripts/setup.mjs +1324 -0
  132. package/scripts/setup_non_interactive_flag.test.mjs +60 -0
  133. package/scripts/setup_pr.mjs +605 -0
  134. package/scripts/setup_pr_orchestrated_auth_flow_util_import.test.mjs +117 -0
  135. package/scripts/stack/command_arguments.mjs +91 -0
  136. package/scripts/stack/copy_auth_from_stack.mjs +111 -0
  137. package/scripts/stack/delegated_script_commands.mjs +92 -0
  138. package/scripts/stack/help_text.mjs +110 -0
  139. package/scripts/stack/port_reservation.mjs +74 -0
  140. package/scripts/stack/repo_checkout_resolution.mjs +31 -0
  141. package/scripts/stack/run_script_with_stack_env.mjs +634 -0
  142. package/scripts/stack/stack_daemon_command.mjs +219 -0
  143. package/scripts/stack/stack_delegated_help.mjs +81 -0
  144. package/scripts/stack/stack_environment.mjs +151 -0
  145. package/scripts/stack/stack_environment.sanitization.test.mjs +75 -0
  146. package/scripts/stack/stack_happier_passthrough_command.mjs +63 -0
  147. package/scripts/stack/stack_info_snapshot.mjs +167 -0
  148. package/scripts/stack/stack_mobile_install_command.mjs +61 -0
  149. package/scripts/stack/stack_resume_command.mjs +76 -0
  150. package/scripts/stack/stack_stop_command.mjs +34 -0
  151. package/scripts/stack/stack_workspace_command.mjs +83 -0
  152. package/scripts/stack/transient_repo_overrides.mjs +29 -0
  153. package/scripts/stack.mjs +2388 -0
  154. package/scripts/stack_archive_cmd.integration.test.mjs +31 -0
  155. package/scripts/stack_audit_fix_light_env.test.mjs +129 -0
  156. package/scripts/stack_background_pinned_stack_json.test.mjs +81 -0
  157. package/scripts/stack_copy_auth_server_scoped.test.mjs +243 -0
  158. package/scripts/stack_daemon_cmd.integration.test.mjs +484 -0
  159. package/scripts/stack_eas_help.test.mjs +72 -0
  160. package/scripts/stack_editor_workspace_monorepo_root.test.mjs +102 -0
  161. package/scripts/stack_env_cmd.test.mjs +107 -0
  162. package/scripts/stack_guided_login_bundle_error_parse.test.mjs +20 -0
  163. package/scripts/stack_guided_login_inner_invocation.test.mjs +46 -0
  164. package/scripts/stack_happy_cmd.integration.test.mjs +263 -0
  165. package/scripts/stack_info_snapshot_running_status.test.mjs +186 -0
  166. package/scripts/stack_interactive_monorepo_group.test.mjs +128 -0
  167. package/scripts/stack_monorepo_defaults.test.mjs +31 -0
  168. package/scripts/stack_monorepo_repo_dev_token.test.mjs +32 -0
  169. package/scripts/stack_monorepo_server_light_from_happy_spec.test.mjs +37 -0
  170. package/scripts/stack_new_name_normalize_cmd.test.mjs +38 -0
  171. package/scripts/stack_pr_name_normalize_cmd.test.mjs +84 -0
  172. package/scripts/stack_resume_cmd.integration.test.mjs +134 -0
  173. package/scripts/stack_server_flavors_defaults.test.mjs +64 -0
  174. package/scripts/stack_shorthand_cmd.integration.test.mjs +74 -0
  175. package/scripts/stack_stop_sweeps_legacy_infra_without_kind.integration.test.mjs +44 -0
  176. package/scripts/stack_stop_sweeps_when_runtime_missing.integration.test.mjs +42 -0
  177. package/scripts/stack_stop_sweeps_when_runtime_stale.integration.test.mjs +50 -0
  178. package/scripts/stack_wt_list.test.mjs +117 -0
  179. package/scripts/start_ui_required_default.test.mjs +63 -0
  180. package/scripts/stop.mjs +190 -0
  181. package/scripts/stopStackWithEnv_no_autosweep_when_runtime_missing.integration.test.mjs +95 -0
  182. package/scripts/swiftbar_git_monorepo_cmd.test.mjs +75 -0
  183. package/scripts/swiftbar_render_monorepo_wt_actions.integration.test.mjs +116 -0
  184. package/scripts/swiftbar_utils_cmd.test.mjs +92 -0
  185. package/scripts/swiftbar_wt_pr_backcompat.test.mjs +162 -0
  186. package/scripts/systemd_unit_info.test.mjs +24 -0
  187. package/scripts/tailscale.mjs +490 -0
  188. package/scripts/test_ci.mjs +36 -0
  189. package/scripts/test_cmd.mjs +274 -0
  190. package/scripts/test_cmd.test.mjs +133 -0
  191. package/scripts/test_integration.mjs +33 -0
  192. package/scripts/testkit/auth_testkit.mjs +121 -0
  193. package/scripts/testkit/doctor_testkit.mjs +68 -0
  194. package/scripts/testkit/monorepo_port_testkit.mjs +157 -0
  195. package/scripts/testkit/stack_archive_command_testkit.mjs +55 -0
  196. package/scripts/testkit/stack_new_monorepo_testkit.mjs +83 -0
  197. package/scripts/testkit/stack_script_command_testkit.mjs +27 -0
  198. package/scripts/testkit/stack_stop_sweeps_testkit.mjs +172 -0
  199. package/scripts/testkit/worktrees_monorepo_testkit.mjs +53 -0
  200. package/scripts/tools.mjs +70 -0
  201. package/scripts/tui.mjs +914 -0
  202. package/scripts/tui_stopStackForTuiExit_no_autosweep.integration.test.mjs +95 -0
  203. package/scripts/typecheck.mjs +178 -0
  204. package/scripts/ui_gateway.mjs +247 -0
  205. package/scripts/uninstall.mjs +179 -0
  206. package/scripts/utils/auth/credentials_paths.mjs +181 -0
  207. package/scripts/utils/auth/credentials_paths.test.mjs +187 -0
  208. package/scripts/utils/auth/daemon_gate.mjs +66 -0
  209. package/scripts/utils/auth/daemon_gate.test.mjs +116 -0
  210. package/scripts/utils/auth/decode_jwt_payload_unsafe.mjs +16 -0
  211. package/scripts/utils/auth/dev_key.mjs +163 -0
  212. package/scripts/utils/auth/files.mjs +56 -0
  213. package/scripts/utils/auth/guided_pr_auth.mjs +86 -0
  214. package/scripts/utils/auth/guided_stack_web_login.mjs +56 -0
  215. package/scripts/utils/auth/handy_master_secret.mjs +42 -0
  216. package/scripts/utils/auth/interactive_stack_auth.mjs +70 -0
  217. package/scripts/utils/auth/login_ux.mjs +105 -0
  218. package/scripts/utils/auth/orchestrated_stack_auth_flow.mjs +291 -0
  219. package/scripts/utils/auth/sources.mjs +28 -0
  220. package/scripts/utils/auth/stable_scope_id.mjs +91 -0
  221. package/scripts/utils/auth/stable_scope_id.test.mjs +51 -0
  222. package/scripts/utils/auth/stack_guided_login.mjs +438 -0
  223. package/scripts/utils/cli/arg_values.mjs +23 -0
  224. package/scripts/utils/cli/arg_values.test.mjs +43 -0
  225. package/scripts/utils/cli/args.mjs +17 -0
  226. package/scripts/utils/cli/cli.mjs +24 -0
  227. package/scripts/utils/cli/cli_registry.mjs +440 -0
  228. package/scripts/utils/cli/cwd_scope.mjs +158 -0
  229. package/scripts/utils/cli/cwd_scope.test.mjs +154 -0
  230. package/scripts/utils/cli/flags.mjs +17 -0
  231. package/scripts/utils/cli/log_forwarder.mjs +157 -0
  232. package/scripts/utils/cli/normalize.mjs +16 -0
  233. package/scripts/utils/cli/prereqs.mjs +103 -0
  234. package/scripts/utils/cli/prereqs.test.mjs +33 -0
  235. package/scripts/utils/cli/progress.mjs +141 -0
  236. package/scripts/utils/cli/smoke_help.mjs +44 -0
  237. package/scripts/utils/cli/verbosity.mjs +11 -0
  238. package/scripts/utils/cli/wizard.mjs +139 -0
  239. package/scripts/utils/cli/wizard_promptSelect.test.mjs +44 -0
  240. package/scripts/utils/cli/wizard_prompt_worktree_source_lazy.test.mjs +132 -0
  241. package/scripts/utils/cli/wizard_worktree_slug.test.mjs +33 -0
  242. package/scripts/utils/crypto/tokens.mjs +14 -0
  243. package/scripts/utils/dev/daemon.mjs +232 -0
  244. package/scripts/utils/dev/daemon_watch_resilience.test.mjs +224 -0
  245. package/scripts/utils/dev/expo_dev.buildEnv.test.mjs +35 -0
  246. package/scripts/utils/dev/expo_dev.mjs +478 -0
  247. package/scripts/utils/dev/expo_dev.test.mjs +89 -0
  248. package/scripts/utils/dev/expo_dev_restart_port_reservation.test.mjs +120 -0
  249. package/scripts/utils/dev/expo_dev_verbose_logs.test.mjs +60 -0
  250. package/scripts/utils/dev/server.mjs +180 -0
  251. package/scripts/utils/dev_auth_key.mjs +7 -0
  252. package/scripts/utils/edison/git_roots.mjs +30 -0
  253. package/scripts/utils/edison/git_roots.test.mjs +49 -0
  254. package/scripts/utils/env/config.mjs +52 -0
  255. package/scripts/utils/env/dotenv.mjs +32 -0
  256. package/scripts/utils/env/dotenv.test.mjs +32 -0
  257. package/scripts/utils/env/env.mjs +130 -0
  258. package/scripts/utils/env/env_file.mjs +98 -0
  259. package/scripts/utils/env/env_file.test.mjs +49 -0
  260. package/scripts/utils/env/env_local.mjs +25 -0
  261. package/scripts/utils/env/load_env_file.mjs +34 -0
  262. package/scripts/utils/env/read.mjs +30 -0
  263. package/scripts/utils/env/sandbox.mjs +13 -0
  264. package/scripts/utils/env/scrub_env.mjs +69 -0
  265. package/scripts/utils/env/scrub_env.test.mjs +102 -0
  266. package/scripts/utils/env/values.mjs +13 -0
  267. package/scripts/utils/expo/command.mjs +65 -0
  268. package/scripts/utils/expo/expo.mjs +139 -0
  269. package/scripts/utils/expo/expo_state_running.test.mjs +48 -0
  270. package/scripts/utils/expo/metro_ports.mjs +101 -0
  271. package/scripts/utils/expo/metro_ports.test.mjs +35 -0
  272. package/scripts/utils/fs/atomic_dir_swap.mjs +55 -0
  273. package/scripts/utils/fs/atomic_dir_swap.test.mjs +54 -0
  274. package/scripts/utils/fs/file_has_content.mjs +10 -0
  275. package/scripts/utils/fs/fs.mjs +11 -0
  276. package/scripts/utils/fs/json.mjs +25 -0
  277. package/scripts/utils/fs/ops.mjs +29 -0
  278. package/scripts/utils/fs/package_json.mjs +8 -0
  279. package/scripts/utils/fs/tail.mjs +12 -0
  280. package/scripts/utils/git/dev_checkout.mjs +127 -0
  281. package/scripts/utils/git/dev_checkout.test.mjs +115 -0
  282. package/scripts/utils/git/git.mjs +67 -0
  283. package/scripts/utils/git/parse_name_status_z.mjs +21 -0
  284. package/scripts/utils/git/refs.mjs +26 -0
  285. package/scripts/utils/git/worktrees.mjs +323 -0
  286. package/scripts/utils/git/worktrees_monorepo.test.mjs +60 -0
  287. package/scripts/utils/git/worktrees_pathstyle.test.mjs +53 -0
  288. package/scripts/utils/llm/assist.mjs +260 -0
  289. package/scripts/utils/llm/codex_exec.mjs +61 -0
  290. package/scripts/utils/llm/codex_exec.test.mjs +46 -0
  291. package/scripts/utils/llm/hstack_runner.mjs +59 -0
  292. package/scripts/utils/llm/tools.mjs +56 -0
  293. package/scripts/utils/llm/tools.test.mjs +67 -0
  294. package/scripts/utils/menubar/swiftbar.mjs +121 -0
  295. package/scripts/utils/menubar/swiftbar.test.mjs +85 -0
  296. package/scripts/utils/mobile/config.mjs +35 -0
  297. package/scripts/utils/mobile/dev_client_links.mjs +59 -0
  298. package/scripts/utils/mobile/identifiers.mjs +46 -0
  299. package/scripts/utils/mobile/identifiers.test.mjs +41 -0
  300. package/scripts/utils/mobile/ios_xcodeproj_patch.mjs +128 -0
  301. package/scripts/utils/mobile/ios_xcodeproj_patch.test.mjs +131 -0
  302. package/scripts/utils/net/bind_mode.mjs +39 -0
  303. package/scripts/utils/net/dns.mjs +10 -0
  304. package/scripts/utils/net/lan_ip.mjs +24 -0
  305. package/scripts/utils/net/ports.mjs +110 -0
  306. package/scripts/utils/net/tcp_forward.mjs +162 -0
  307. package/scripts/utils/net/url.mjs +30 -0
  308. package/scripts/utils/net/url.test.mjs +29 -0
  309. package/scripts/utils/paths/canonical_home.mjs +15 -0
  310. package/scripts/utils/paths/canonical_home.test.mjs +28 -0
  311. package/scripts/utils/paths/localhost_host.mjs +112 -0
  312. package/scripts/utils/paths/localhost_host.test.mjs +58 -0
  313. package/scripts/utils/paths/paths.mjs +302 -0
  314. package/scripts/utils/paths/paths_env_win32.test.mjs +36 -0
  315. package/scripts/utils/paths/paths_monorepo.test.mjs +58 -0
  316. package/scripts/utils/paths/paths_server_flavors.test.mjs +50 -0
  317. package/scripts/utils/paths/runtime.mjs +41 -0
  318. package/scripts/utils/pglite_lock.mjs +107 -0
  319. package/scripts/utils/proc/commands.mjs +33 -0
  320. package/scripts/utils/proc/exit_cleanup.mjs +57 -0
  321. package/scripts/utils/proc/happy_monorepo_deps.mjs +37 -0
  322. package/scripts/utils/proc/happy_monorepo_deps.test.mjs +89 -0
  323. package/scripts/utils/proc/ownership.mjs +217 -0
  324. package/scripts/utils/proc/ownership_killProcessGroupOwnedByStack.test.mjs +216 -0
  325. package/scripts/utils/proc/ownership_listPidsWithEnvNeedles.test.mjs +88 -0
  326. package/scripts/utils/proc/package_scripts.mjs +38 -0
  327. package/scripts/utils/proc/package_scripts.test.mjs +58 -0
  328. package/scripts/utils/proc/parallel.mjs +25 -0
  329. package/scripts/utils/proc/pids.mjs +11 -0
  330. package/scripts/utils/proc/pm.mjs +478 -0
  331. package/scripts/utils/proc/pm_spawn.integration.test.mjs +131 -0
  332. package/scripts/utils/proc/pm_stack_cache_env.test.mjs +313 -0
  333. package/scripts/utils/proc/proc.mjs +331 -0
  334. package/scripts/utils/proc/proc.test.mjs +85 -0
  335. package/scripts/utils/proc/terminate.mjs +69 -0
  336. package/scripts/utils/proc/terminate.test.mjs +54 -0
  337. package/scripts/utils/proc/watch.mjs +63 -0
  338. package/scripts/utils/review/augment_runner_integration.test.mjs +105 -0
  339. package/scripts/utils/review/base_ref.mjs +82 -0
  340. package/scripts/utils/review/base_ref.test.mjs +89 -0
  341. package/scripts/utils/review/chunks.mjs +55 -0
  342. package/scripts/utils/review/chunks.test.mjs +107 -0
  343. package/scripts/utils/review/detached_worktree.mjs +61 -0
  344. package/scripts/utils/review/detached_worktree.test.mjs +61 -0
  345. package/scripts/utils/review/findings.mjs +278 -0
  346. package/scripts/utils/review/findings.test.mjs +203 -0
  347. package/scripts/utils/review/head_slice.mjs +132 -0
  348. package/scripts/utils/review/head_slice.test.mjs +117 -0
  349. package/scripts/utils/review/instructions/deep.md +20 -0
  350. package/scripts/utils/review/prompts.mjs +279 -0
  351. package/scripts/utils/review/prompts.test.mjs +77 -0
  352. package/scripts/utils/review/run_reviewers_safe.mjs +12 -0
  353. package/scripts/utils/review/run_reviewers_safe.test.mjs +45 -0
  354. package/scripts/utils/review/runners/augment.mjs +91 -0
  355. package/scripts/utils/review/runners/augment.test.mjs +64 -0
  356. package/scripts/utils/review/runners/claude.mjs +92 -0
  357. package/scripts/utils/review/runners/claude.test.mjs +47 -0
  358. package/scripts/utils/review/runners/coderabbit.mjs +105 -0
  359. package/scripts/utils/review/runners/coderabbit.test.mjs +32 -0
  360. package/scripts/utils/review/runners/codex.mjs +129 -0
  361. package/scripts/utils/review/runners/codex.test.mjs +115 -0
  362. package/scripts/utils/review/slice_mode.mjs +20 -0
  363. package/scripts/utils/review/slice_mode.test.mjs +69 -0
  364. package/scripts/utils/review/sliced_runner.mjs +39 -0
  365. package/scripts/utils/review/sliced_runner.test.mjs +57 -0
  366. package/scripts/utils/review/slices.mjs +140 -0
  367. package/scripts/utils/review/slices.test.mjs +41 -0
  368. package/scripts/utils/review/targets.mjs +23 -0
  369. package/scripts/utils/review/targets.test.mjs +31 -0
  370. package/scripts/utils/review/tool_home_seed.mjs +106 -0
  371. package/scripts/utils/review/tool_home_seed.test.mjs +124 -0
  372. package/scripts/utils/review/uncommitted_ops.mjs +77 -0
  373. package/scripts/utils/review/uncommitted_ops.test.mjs +117 -0
  374. package/scripts/utils/sandbox/review_pr_sandbox.mjs +105 -0
  375. package/scripts/utils/server/apply_server_light_env_defaults.mjs +14 -0
  376. package/scripts/utils/server/flavor_scripts.mjs +138 -0
  377. package/scripts/utils/server/flavor_scripts.test.mjs +115 -0
  378. package/scripts/utils/server/infra/happy_server_infra.mjs +444 -0
  379. package/scripts/utils/server/mobile_api_url.mjs +60 -0
  380. package/scripts/utils/server/mobile_api_url.test.mjs +58 -0
  381. package/scripts/utils/server/port.mjs +55 -0
  382. package/scripts/utils/server/prisma_import.mjs +36 -0
  383. package/scripts/utils/server/prisma_import.test.mjs +78 -0
  384. package/scripts/utils/server/server.mjs +109 -0
  385. package/scripts/utils/server/ui_build_check.mjs +37 -0
  386. package/scripts/utils/server/ui_build_check.test.mjs +70 -0
  387. package/scripts/utils/server/ui_env.mjs +13 -0
  388. package/scripts/utils/server/ui_env.test.mjs +57 -0
  389. package/scripts/utils/server/urls.mjs +100 -0
  390. package/scripts/utils/server/validate.mjs +60 -0
  391. package/scripts/utils/server/validate.test.mjs +76 -0
  392. package/scripts/utils/service/autostart_darwin.mjs +198 -0
  393. package/scripts/utils/service/autostart_darwin.test.mjs +49 -0
  394. package/scripts/utils/service/autostart_darwin_keepalive.test.mjs +19 -0
  395. package/scripts/utils/stack/cli_identities.mjs +29 -0
  396. package/scripts/utils/stack/context.mjs +19 -0
  397. package/scripts/utils/stack/dirs.mjs +26 -0
  398. package/scripts/utils/stack/editor_workspace.mjs +126 -0
  399. package/scripts/utils/stack/interactive_stack_config.mjs +266 -0
  400. package/scripts/utils/stack/interactive_stack_config.port_validation.test.mjs +93 -0
  401. package/scripts/utils/stack/interactive_stack_config.remote_validation.test.mjs +122 -0
  402. package/scripts/utils/stack/interactive_stack_config.stack_name_validation.test.mjs +76 -0
  403. package/scripts/utils/stack/interactive_stack_config_testkit.mjs +18 -0
  404. package/scripts/utils/stack/names.mjs +27 -0
  405. package/scripts/utils/stack/names.test.mjs +26 -0
  406. package/scripts/utils/stack/pr_stack_name.mjs +16 -0
  407. package/scripts/utils/stack/runtime_state.mjs +88 -0
  408. package/scripts/utils/stack/stacks.mjs +40 -0
  409. package/scripts/utils/stack/startup.mjs +370 -0
  410. package/scripts/utils/stack/startup_server_light_dirs.test.mjs +119 -0
  411. package/scripts/utils/stack/startup_server_light_generate.test.mjs +20 -0
  412. package/scripts/utils/stack/startup_server_light_legacy.test.mjs +79 -0
  413. package/scripts/utils/stack/startup_server_light_testkit.mjs +106 -0
  414. package/scripts/utils/stack/stop.mjs +284 -0
  415. package/scripts/utils/stack_context.mjs +1 -0
  416. package/scripts/utils/stack_runtime_state.mjs +1 -0
  417. package/scripts/utils/stacks.mjs +1 -0
  418. package/scripts/utils/tailscale/ip.mjs +116 -0
  419. package/scripts/utils/tauri/stack_overrides.mjs +22 -0
  420. package/scripts/utils/test/collect_test_files.mjs +29 -0
  421. package/scripts/utils/time/get_today_ymd.mjs +7 -0
  422. package/scripts/utils/tui/cleanup.mjs +38 -0
  423. package/scripts/utils/ui/ansi.mjs +47 -0
  424. package/scripts/utils/ui/browser.mjs +31 -0
  425. package/scripts/utils/ui/browser.test.mjs +56 -0
  426. package/scripts/utils/ui/clipboard.mjs +38 -0
  427. package/scripts/utils/ui/layout.mjs +44 -0
  428. package/scripts/utils/ui/qr.mjs +17 -0
  429. package/scripts/utils/ui/terminal_launcher.mjs +129 -0
  430. package/scripts/utils/ui/text.mjs +16 -0
  431. package/scripts/utils/update/auto_update_notice.mjs +93 -0
  432. package/scripts/utils/validate.mjs +5 -0
  433. package/scripts/where.mjs +138 -0
  434. package/scripts/worktrees.mjs +2174 -0
  435. package/scripts/worktrees_archive_cmd.integration.test.mjs +228 -0
  436. package/scripts/worktrees_cursor_monorepo_root.test.mjs +23 -0
  437. package/scripts/worktrees_list_specs_no_recurse.test.mjs +32 -0
  438. package/scripts/worktrees_monorepo_testkit.test.mjs +29 -0
  439. package/scripts/worktrees_monorepo_use_group.test.mjs +41 -0
package/README.md ADDED
@@ -0,0 +1,501 @@
1
+ # hstack (Happier Stack)
2
+
3
+ Run [**Happier**](https://app.happier.dev) locally and access it remotely and securely (using Tailscale).
4
+
5
+ ## What is Happier?
6
+
7
+ Happier is an UI/CLI stack (server + web UI + CLI + daemon) who let you monitor and interact with Claude Code, Codex and Gemini sessions from your mobile, from a web UI and/or from a desktop app.
8
+
9
+ ## What is hstack?
10
+
11
+ hstack is a guided installer + local orchestration CLI for Happier.
12
+
13
+ If you only want to **use Happier** and self-host it on your computer, start with the **Self-host** section below.
14
+ If you want to **develop Happier** (worktrees, multiple stacks, upstream PR workflows), see the **Development** section further down.
15
+
16
+ ## Self-host Happier (install + run)
17
+
18
+ ### Quickstart
19
+
20
+ ```bash
21
+ curl -fsSL https://happier.dev/self-host | bash
22
+ ```
23
+
24
+ Direct hstack flow:
25
+
26
+ ```bash
27
+ hstack self-host install
28
+ ```
29
+
30
+ Follow the guided instructions to install Happier and launch it.
31
+
32
+ ### Daily use
33
+
34
+ #### Configure provider API keys for the daemon
35
+
36
+ If you want the daemon to have access to provider API keys (for example OpenAI), you can set them so they are automatically loaded when the daemon starts:
37
+
38
+ ```bash
39
+ hstack env set OPENAI_API_KEY=sk-...
40
+ ```
41
+
42
+ Then restart so the daemon picks up the new environment:
43
+
44
+ ```bash
45
+ hstack start --restart
46
+ ```
47
+
48
+ ### Start Happier
49
+
50
+ Starts the local server, CLI daemon, and serves the pre-built UI.
51
+
52
+ ```bash
53
+ hstack start
54
+ ```
55
+
56
+ ### Authentication
57
+
58
+ On a **fresh machine**, the daemon needs to authenticate once before it can register a “machine”.
59
+
60
+ ```bash
61
+ hstack auth login
62
+ ```
63
+
64
+ By default (in a TTY), `hstack auth login` is **local-first**: it guides you through authenticating against your **local stack UI**
65
+ instead of the hosted Happier web app. Advanced targeting:
66
+
67
+ ```bash
68
+ hstack auth login --webapp=auto|stack|expo|public|hosted
69
+ hstack auth login --webapp-url=http://localhost:8081
70
+ hstack auth login --start-if-needed
71
+ ```
72
+
73
+ If you want a quick diagnosis:
74
+
75
+ ```bash
76
+ hstack auth status
77
+ ```
78
+
79
+ ### Enable Tailscale Serve (recommended for mobile/remote)
80
+
81
+ ```bash
82
+ hstack tailscale enable
83
+ hstack tailscale url
84
+ ```
85
+
86
+ ### Mobile access
87
+
88
+ Make sure Tailscale is [installed and running](https://tailscale.com/kb/1347/installation) on your
89
+ phone, then either:
90
+
91
+ - Open the URL from `hstack tailscale url` on your phone and “Add to Home Screen”, or
92
+ - [Download the Happier mobile app]
93
+ ([https://app.happier.dev](https://app.happier.dev)) and [configure it to use
94
+ your local server](docs/remote-access.md).
95
+
96
+ Details (secure context, phone instructions, automation knobs): `[docs/remote-access.md](docs/remote-access.md)`.
97
+
98
+ ## Development (worktrees, stacks, contributor workflows)
99
+
100
+ If you want to **develop Happier** (worktrees, multiple stacks, upstream PR workflows), you can install hstack for development with:
101
+
102
+ ### Setup (guided)
103
+
104
+ ```bash
105
+ npx --yes -p @happier-dev/stack hstack setup --profile=dev
106
+ ```
107
+
108
+ During setup, you’ll be guided through:
109
+
110
+ - where to store your **workspace** (the folder that will contain `main/`, `dev/`, `pr/`, `local/`, `tmp/`)
111
+ - bootstrapping/cloning the Happier monorepo
112
+ - **recommended**: setting up a dedicated `dev-auth` seed stack (authenticate once, then new stacks can reuse it)
113
+ - **recommended**: creating a dedicated dev stack (keep `main` stable)
114
+ - optional: installing the iOS dev-client app (for phone testing)
115
+
116
+ Manual shortcuts (if you want to do it yourself):
117
+
118
+ ```bash
119
+ # Create the dev-auth seed stack (recommended) and do the guided login now:
120
+ hstack auth seed
121
+
122
+ # Create a dev stack and pin it to the dev checkout:
123
+ hstack stack new dev
124
+ hstack stack wt dev -- use dev
125
+ ```
126
+
127
+ You can also set it non-interactively:
128
+
129
+ ```bash
130
+ npx --yes -p @happier-dev/stack hstack setup --profile=dev --workspace-dir=~/Documents/Development/happier
131
+ ```
132
+
133
+ ### Why this exists
134
+
135
+ - **Automated setup**: `hstack setup` + `hstack start` gets the whole stack up and running.
136
+ - **No hosted dependency**: run the full stack on your own computer.
137
+ - **Lower latency**: localhost/LAN is typically much faster than remote hosted servers.
138
+ - **Custom forks**: easily use forks while still contributing upstream to `happier-dev/happier`.
139
+ - **Worktrees**: clean upstream PR branches without mixing fork-only patches.
140
+ - **Stacks**: run multiple isolated instances in parallel (ports + dirs + repo pinning).
141
+ - **Remote access**: `hstack tailscale ...` helps you get an HTTPS URL for mobile/remote devices.
142
+
143
+ ### How hstack wires “local” URLs
144
+
145
+ There are two “URLs” to understand:
146
+
147
+ - **Internal URL**: used by local processes on this machine (server/daemon/CLI)
148
+ - typically `http://127.0.0.1:<port>`
149
+ - **Public URL**: used by other devices (phone/laptop) and embedded links/QR codes
150
+ - recommended: `https://<machine>.<tailnet>.ts.net` via Tailscale Serve
151
+
152
+ Diagram:
153
+
154
+ ```text
155
+ other device (phone/laptop)
156
+ |
157
+ | HTTPS (secure context)
158
+ v
159
+ https://<machine>.<tailnet>.ts.net
160
+ |
161
+ | (tailscale serve)
162
+ v
163
+ local machine (this repo)
164
+ +--------------------------------+
165
+ | happier-server-light OR |
166
+ | happier-server (via UI gateway) |
167
+ | - listens on :PORT |
168
+ | - serves UI at / |
169
+ +--------------------------------+
170
+ ^
171
+ | internal loopback
172
+ |
173
+ http://127.0.0.1:<port>
174
+ (daemon / CLI)
175
+ ```
176
+
177
+ More details + automation: `[docs/remote-access.md](docs/remote-access.md)`.
178
+
179
+ ### How it’s organized
180
+
181
+ - **Scripts**: `scripts/*.mjs` (bootstrap/dev/start/build/stacks/worktrees/service/tailscale/mobile)
182
+ - **Stable checkout**: `<workspace>/main` (the monorepo clone; treated as read-only)
183
+ - **Dev checkout**: `<workspace>/dev` (created by `hstack setup --profile=dev`)
184
+ - **Worktrees**:
185
+ - PRs: `<workspace>/pr/...`
186
+ - locals: `<workspace>/local/<owner>/...`
187
+ - tmp: `<workspace>/tmp/<owner>/...`
188
+ - **CWD-scoped commands**: if you run `hstack test/typecheck/lint` from inside `apps/ui` / `apps/cli` / `apps/server` and omit a target, hstack infers the “service” automatically; `hstack build/dev/start` also prefer the checkout you’re currently inside.
189
+
190
+ ### Quickstarts (feature-focused)
191
+
192
+ #### Remote access (Tailscale Serve)
193
+
194
+ ```bash
195
+ hstack tailscale enable
196
+ hstack tailscale url
197
+ ```
198
+
199
+ Details: `[docs/remote-access.md](docs/remote-access.md)`.
200
+
201
+ #### Worktrees + forks (clean upstream PRs)
202
+
203
+ Create a clean local worktree:
204
+
205
+ ```bash
206
+ hstack wt new my-feature --use
207
+ hstack wt push active --remote=origin
208
+ ```
209
+
210
+ Test an upstream PR locally:
211
+
212
+ ```bash
213
+ hstack wt pr https://github.com/happier-dev/happier/pull/123 --use
214
+ hstack wt pr 123 --update --stash
215
+ ```
216
+
217
+ ##### Developer quickstart: create a PR stack (isolated ports/dirs; idempotent updates)
218
+
219
+ This creates (or reuses) a named stack, checks out the monorepo PR worktree, optionally seeds auth, and starts the stack.
220
+ Re-run with `--reuse` to update the existing worktrees when the PR changes.
221
+
222
+ ```bash
223
+ hstack stack pr pr123 \
224
+ --repo=https://github.com/happier-dev/happier/pull/123 \
225
+ --seed-auth --copy-auth-from=dev-auth --link-auth \
226
+ --dev
227
+ ```
228
+
229
+ Optional: enable Expo dev-client for mobile reviewers (reuses the same Expo dev server; no second Metro process):
230
+
231
+ ```bash
232
+ hstack stack pr pr123 --repo=123 --dev --mobile
233
+ ```
234
+
235
+ Optional: run it in a self-contained sandbox folder (delete it to uninstall completely):
236
+
237
+ ```bash
238
+ SANDBOX="$(mktemp -d /tmp/hstack-sandbox.XXXXXX)"
239
+ hstack --sandbox-dir "$SANDBOX" stack pr pr123 --repo=123 --dev
240
+ rm -rf "$SANDBOX"
241
+ ```
242
+
243
+ Update when the PR changes:
244
+
245
+ - Re-run with `--reuse` to fast-forward worktrees when possible.
246
+ - If the PR was force-pushed, add `--force`.
247
+
248
+ ```bash
249
+ hstack stack pr pr123 --repo=123 --reuse
250
+ hstack stack pr pr123 --repo=123 --reuse --force
251
+ ```
252
+
253
+ ##### Maintainer quickstart: one-shot “install + run PR stack” (idempotent)
254
+
255
+ This is the maintainer-friendly entrypoint. It is safe to re-run and will keep the PR stack wiring intact.
256
+
257
+ ```bash
258
+ npx --yes -p @happier-dev/stack hstack tools setup-pr \
259
+ --repo=https://github.com/happier-dev/happier/pull/123 \
260
+ --dev
261
+ ```
262
+
263
+ Optional: enable Expo dev-client for mobile reviewers (works with both default `--dev` and `--start`):
264
+
265
+ ```bash
266
+ npx --yes -p @happier-dev/stack hstack tools setup-pr --repo=123 --dev --mobile
267
+ ```
268
+
269
+ Optional: run it in a self-contained sandbox folder (auto-cleaned):
270
+
271
+ ```bash
272
+ SANDBOX="$(mktemp -d /tmp/hstack-review-pr.XXXXXX)"
273
+ npx --yes -p @happier-dev/stack hstack tools review-pr --repo=123 --dev --sandbox-dir "$SANDBOX"
274
+ rm -rf "$SANDBOX"
275
+ ```
276
+
277
+ Short form (PR numbers):
278
+
279
+ ```bash
280
+ npx --yes -p @happier-dev/stack hstack tools setup-pr --repo=123 --dev
281
+ ```
282
+
283
+ Override stack name (optional):
284
+
285
+ ```bash
286
+ npx --yes -p @happier-dev/stack hstack tools setup-pr --name=pr123 --repo=123 --dev
287
+ ```
288
+
289
+ Update when the PR changes:
290
+
291
+ - Re-run the same command to fast-forward the PR worktrees.
292
+ - If the PR was force-pushed, add `--force`.
293
+
294
+ ```bash
295
+ npx --yes -p @happier-dev/stack hstack tools setup-pr --repo=123 --dev
296
+ npx --yes -p @happier-dev/stack hstack tools setup-pr --repo=123 --dev --force
297
+ ```
298
+
299
+ Details: `[docs/worktrees-and-forks.md](docs/worktrees-and-forks.md)`.
300
+
301
+ #### Server flavor (server-light vs full server)
302
+
303
+ - Use `happier-server-light` for a light local stack (no Redis, no Postgres, no Docker), and UI serving via server-light.
304
+ - Use `happier-server` when you need a more production-like server (Postgres + Redis + S3-compatible storage) or want to develop server changes for upstream.
305
+ - hstack can **manage the required infra automatically per stack** (via Docker Compose) and runs a **UI gateway** so you still get a single `https://...ts.net` URL that serves the UI + proxies API/websockets/files.
306
+
307
+ Switch globally:
308
+
309
+ ```bash
310
+ hstack srv status
311
+ hstack srv use --interactive
312
+ ```
313
+
314
+ Switch per-stack:
315
+
316
+ ```bash
317
+ hstack stack srv exp1 -- use --interactive
318
+ ```
319
+
320
+ Details: `[docs/server-flavors.md](docs/server-flavors.md)`.
321
+
322
+ #### Stacks (multiple isolated instances)
323
+
324
+ ```bash
325
+ hstack stack new exp1 --interactive
326
+ hstack stack dev exp1
327
+ ```
328
+
329
+ Point a stack at a PR worktree:
330
+
331
+ ```bash
332
+ hstack wt pr 123 --use
333
+ hstack stack wt exp1 -- use pr/123-fix-thing
334
+ hstack stack dev exp1
335
+ ```
336
+
337
+ Details: `[docs/stacks.md](docs/stacks.md)`.
338
+
339
+ #### Dev stacks: browser origin isolation (IMPORTANT)
340
+
341
+ Non-main stacks use a stack-specific localhost hostname (no `/etc/hosts` changes required):
342
+
343
+ - `http://happier-<stack>.localhost:<uiPort>` (default; set `HAPPIER_STACK_LOCALHOST_SUBDOMAIN_PREFIX=happy` for legacy)
344
+
345
+ This avoids browser auth/session collisions between stacks (separate origin per stack).
346
+
347
+ #### Menu bar (SwiftBar)
348
+
349
+ ```bash
350
+ hstack menubar install
351
+ hstack menubar open
352
+ ```
353
+
354
+ Details: `[docs/menubar.md](docs/menubar.md)`.
355
+
356
+ #### Mobile iOS dev (optional)
357
+
358
+ ```bash
359
+ # Install the shared hstack dev-client app on your iPhone:
360
+ hstack mobile-dev-client --install
361
+
362
+ # Install an isolated per-stack app (Release config, unique bundle id + scheme):
363
+ hstack stack mobile:install <stack> --name="Happier (<stack>)"
364
+ ```
365
+
366
+ Details: `[docs/mobile-ios.md](docs/mobile-ios.md)`.
367
+
368
+ #### Reviewing PRs in an isolated sandbox
369
+
370
+ - **Unique hostname per run (default)**: `hstack tools review-pr` generates a unique stack name by default, which results in a unique `happier-<stack>.localhost` hostname. This prevents browser storage collisions when the sandbox is deleted between runs.
371
+ - **Reuse an existing sandbox**: if a previous run preserved a sandbox (e.g. `--keep-sandbox` or a failure in verbose mode), re-running `hstack tools review-pr` offers an interactive choice to reuse it (keeping the same hostname + on-disk auth), or create a fresh sandbox.
372
+
373
+ #### Tauri desktop app (optional)
374
+
375
+ ```bash
376
+ hstack build --tauri
377
+ ```
378
+
379
+ Details: `[docs/tauri.md](docs/tauri.md)`.
380
+
381
+ ### Commands (high-signal)
382
+
383
+ - **Setup**:
384
+ - `hstack setup` (guided; selfhost or dev)
385
+ - (advanced) `hstack init` (plumbing: shims/runtime/pointer env)
386
+ - (advanced) `hstack bootstrap --interactive` (workspace bootstrap wizard)
387
+ - **Run**:
388
+ - `hstack start` (production-like; serves built UI via server-light)
389
+ - `hstack dev` (dev; Expo dev server for UI, optional dev-client via `--mobile`)
390
+ - **Server flavor**:
391
+ - `hstack srv status`
392
+ - `hstack srv use --interactive`
393
+ - **Worktrees**:
394
+ - `hstack wt use --interactive`
395
+ - `hstack wt pr <pr-url|number> --use [--update] [--stash] [--force]`
396
+ - `hstack wt sync-all`
397
+ - `hstack wt update-all --dry-run` / `hstack wt update-all --stash`
398
+ - **Stacks**:
399
+ - `hstack stack new --interactive`
400
+ - `hstack stack dev <name>` / `hstack stack start <name>`
401
+ - `hstack stack edit <name> --interactive`
402
+ - `hstack stack wt <name> -- use --interactive`
403
+ - `hstack stack happier <name> -- <happier-cli args...>`
404
+ - **Tools (maintainer / automation)**:
405
+ - `hstack tools setup-pr --repo=<pr-url|number> [--dev|--start]`
406
+ - `hstack tools review-pr --repo=<pr-url|number> [--dev|--start]`
407
+ - `hstack tools review` (local diff review)
408
+ - `hstack tools import` (split repos → monorepo porting helpers)
409
+ - `hstack tools edison`
410
+ - **Menu bar (SwiftBar)**:
411
+ - `hstack menubar install`
412
+
413
+ ### Docs (deep dives)
414
+
415
+ - **Remote access (Tailscale + phone)**: `[docs/remote-access.md](docs/remote-access.md)`
416
+ - **Server flavors (server-light vs server)**: `[docs/server-flavors.md](docs/server-flavors.md)`
417
+ - **Worktrees + forks workflow**: `[docs/worktrees-and-forks.md](docs/worktrees-and-forks.md)`
418
+ - **Stacks (multiple instances)**: `[docs/stacks.md](docs/stacks.md)`
419
+ - **Paths + env precedence (home/workspace/runtime/stacks)**: `[docs/paths-and-env.md](docs/paths-and-env.md)`
420
+ - **Menu bar (SwiftBar)**: `[docs/menubar.md](docs/menubar.md)`
421
+ - **Mobile iOS dev**: `[docs/mobile-ios.md](docs/mobile-ios.md)`
422
+ - **Tauri desktop app**: `[docs/tauri.md](docs/tauri.md)`
423
+
424
+ ### Configuration
425
+
426
+ Where config lives by default:
427
+
428
+ - `~/.happier-stack/.env`: stable “pointer” file (home/workspace/runtime)
429
+ - `~/.happier-stack/env.local`: optional global overrides
430
+ - `~/.happier/stacks/main/env`: main stack config (port, server flavor, repo/worktree override)
431
+
432
+ Notes:
433
+
434
+ - Canonical env prefix is `HAPPIER_STACK_*` (no legacy aliases).
435
+ - Canonical stack storage is `~/.happier/stacks`.
436
+ - To edit per-stack environment variables (including provider keys like `OPENAI_API_KEY`), use:
437
+
438
+ ```bash
439
+ hstack stack env <stack> set KEY=VALUE
440
+ hstack stack env <stack> unset KEY
441
+ hstack stack env <stack> get KEY
442
+ hstack stack env <stack> list
443
+ ```
444
+
445
+ - **Repo env templates**:
446
+ - **Use `.env.example` as the canonical template** (copy it to `.env` if you’re running this repo directly).
447
+ - If an LLM tool refuses to read/edit `.env.example` due to safety restrictions, **do not create an `env.example` workaround**—instead, ask the user to apply the change manually.
448
+
449
+ ### Breaking changes (vs “Happy Stacks”)
450
+
451
+ - No compatibility/migration for previous installs: uninstall old setups and run `hstack setup` again.
452
+ - Env prefix is now `HAPPIER_STACK_*` (no legacy aliases like `HAPPY_STACKS_*` / `HAPPY_LOCAL_*`).
453
+ - Workspace/worktrees are monorepo-first (default workspace: `~/.happier-stack/workspace`, with `main/`, `dev/`, `pr/`, `local/`, `tmp/`).
454
+ - Yarn-only (no pnpm support).
455
+
456
+ ### Sandbox / test installs (fully isolated)
457
+
458
+ If you want to test the full setup flow (including PR stacks) without impacting your “real” install, run everything with `--sandbox-dir`.
459
+ To fully uninstall the test run, stop the sandbox stacks and delete the sandbox folder.
460
+
461
+ ```bash
462
+ SANDBOX="$(mktemp -d /tmp/hstack-sandbox.XXXXXX)"
463
+
464
+ # Run a PR stack (fully isolated install)
465
+ npx --yes -p @happier-dev/stack hstack --sandbox-dir "$SANDBOX" tools setup-pr --repo=123 --dev
466
+
467
+ # Tear down + uninstall
468
+ npx --yes -p @happier-dev/stack hstack --sandbox-dir "$SANDBOX" stop --yes --no-service
469
+ rm -rf "$SANDBOX"
470
+ ```
471
+
472
+ Notes:
473
+
474
+ - Sandbox mode disables global OS side effects (**PATH edits**, **SwiftBar plugin install**, **LaunchAgents/systemd services**, **Tailscale Serve enable/disable**) by default.
475
+ - To explicitly allow those for testing, set `HAPPIER_STACK_SANDBOX_ALLOW_GLOBAL=1` (still recommended to clean up after).
476
+
477
+ For contributor/LLM workflow expectations: `[AGENTS.md](AGENTS.md)`.
478
+
479
+ ### Developing hstack itself
480
+
481
+ ```bash
482
+ git clone https://github.com/happier-dev/happier.git
483
+ cd happier-dev
484
+
485
+ node ./apps/stack/bin/hstack.mjs setup --profile=dev
486
+ ```
487
+
488
+ Notes:
489
+
490
+ - For local dev, prefer running stack commands via the `hstack` entrypoint (it applies stack-scoped env and safety gates).
491
+ - To make the installed `~/.happier-stack/bin/hstack` shim (LaunchAgents / SwiftBar) run your local checkout without publishing to npm, set:
492
+
493
+ ```bash
494
+ echo 'HAPPIER_STACK_CLI_ROOT_DIR=/path/to/your/happier-dev-checkout' >> ~/.happier-stack/.env
495
+ ```
496
+
497
+ Or (recommended) persist it via init:
498
+
499
+ ```bash
500
+ hstack init --cli-root-dir=/path/to/your/happier-dev-checkout
501
+ ```