@happier-dev/stack 0.1.0-preview.74.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 +138 -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 +74 -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
@@ -0,0 +1,322 @@
1
+ # Mobile app development (iOS)
2
+
3
+ This is optional. Most people can use the served web UI on mobile via Tailscale:
4
+ see the “Using Happier from your phone” section in the main README.
5
+
6
+ ## Prereqs (one-time)
7
+
8
+ - Xcode installed
9
+ - CocoaPods installed (`brew install cocoapods`)
10
+
11
+ ## Two supported modes
12
+
13
+ - **Shared dev-client app** (recommended for development):
14
+ - Install *one* hstack dev-client app on your phone.
15
+ - Run any stack with `--mobile`; scan the QR to open that stack inside the dev-client.
16
+ - Per-stack auth/storage is isolated via `EXPO_PUBLIC_HAPPY_STORAGE_SCOPE` (set automatically in stack mode).
17
+
18
+ - **Per-stack “release” app** (recommended for demos / strict isolation):
19
+ - Install a separate iOS app per stack (unique bundle id + scheme).
20
+ - Each stack app is isolated by iOS app container (no token collisions).
21
+
22
+ ## Shared dev-client app (install once)
23
+
24
+ If you ran `hstack setup --profile=dev`, the setup wizard can optionally offer to install the dev-client for you.
25
+
26
+ Install the dedicated hstack dev-client app on your iPhone (USB).
27
+
28
+ This command **runs a prebuild** (generates `ios/` + runs CocoaPods) and then installs a Debug build
29
+ without starting Metro:
30
+
31
+ ```bash
32
+ hstack mobile-dev-client --install
33
+ ```
34
+
35
+ If you want to ensure the dev-client is built from a specific stack’s active `happy` worktree
36
+ (e.g. to include upstream changes that aren’t merged into your default checkout yet), run:
37
+
38
+ ```bash
39
+ hstack stack mobile-dev-client <stack> --install
40
+ ```
41
+
42
+ Optional:
43
+
44
+ ```bash
45
+ hstack mobile-dev-client --install --device="Your iPhone"
46
+ hstack mobile-dev-client --install --clean
47
+ ```
48
+
49
+ Then run any stack with mobile enabled:
50
+
51
+ ```bash
52
+ hstack stack dev <stack> --mobile
53
+ # or:
54
+ hstack dev --mobile
55
+ ```
56
+
57
+ Notes:
58
+
59
+ - **LAN requirement**: for physical iPhones, Metro must be reachable over LAN.
60
+ - hstack defaults to `lan` for mobile, and will print a QR code + deep link.
61
+ - For simulators you can usually use `localhost` (see `HAPPIER_STACK_MOBILE_HOST` below).
62
+ - **If Expo is already running in web-only mode**: re-run with `--restart` and include `--mobile`.
63
+
64
+ ## Per-stack app install (isolated)
65
+
66
+ Install an isolated app for a specific stack (unique bundle id + scheme, Release config, no Metro):
67
+
68
+ ```bash
69
+ hstack stack mobile:install <stack> --name="Happier (<stack>)"
70
+ hstack stack mobile:install <stack> --name="Happier PR 272" --device="Your iPhone"
71
+ ```
72
+
73
+ The chosen app name is persisted in the stack env so you can re-run installs without re-typing it.
74
+
75
+ ## Native iOS regeneration / “prebuild” (critical)
76
+
77
+ You’ll need to regenerate the iOS native project + Pods when:
78
+
79
+ - you pull changes that affect native deps / Expo config
80
+ - `apps/ui/ios/` was deleted
81
+ - you hit CocoaPods / deployment-target mismatches after a dependency bump
82
+
83
+ Run:
84
+
85
+ ```bash
86
+ hstack mobile --prebuild
87
+ # (optional) fully regenerate ios/:
88
+ hstack mobile --prebuild --clean
89
+ ```
90
+
91
+ What this does today:
92
+
93
+ - runs `expo prebuild --no-install` (so we can patch before CocoaPods runs)
94
+ - patches `ios/Podfile.properties.json` to:
95
+ - set `ios.deploymentTarget` to `16.0`
96
+ - set `ios.buildReactNativeFromSource` to `true`
97
+ - patches the generated Xcode project deployment target (where applicable)
98
+ - runs `pod install`
99
+
100
+ Notes:
101
+
102
+ - **You usually don’t need to run this manually** because both:
103
+ - `hstack mobile-dev-client --install`
104
+ - `hstack stack mobile:install <stack>`
105
+ already include `--prebuild`.
106
+ - Legacy alias: `hstack mobile:prebuild` exists (hidden), but prefer `hstack mobile --prebuild`.
107
+
108
+ ## Manual `hstack mobile` usage (advanced)
109
+
110
+ If you want to work on the embedded Expo app directly (outside `hstack dev --mobile`), `hstack mobile` supports:
111
+
112
+ ```bash
113
+ # Start Metro (keeps running):
114
+ hstack mobile --host=lan
115
+
116
+ # Build + install on iOS (and exit). If you omit --device, it will try to auto-pick a connected iPhone over USB:
117
+ hstack mobile --prebuild --run-ios --device="Your iPhone"
118
+ hstack mobile --prebuild --run-ios --configuration=Release --no-metro
119
+ ```
120
+
121
+ ## Notes / troubleshooting
122
+
123
+ - **QR opens the wrong app**:
124
+ - The dev-client QR uses the `HAPPIER_STACK_DEV_CLIENT_SCHEME` (default: `hstack-dev`).
125
+ - Per-stack installs use a different per-stack scheme, so they should not intercept dev-client QR scans.
126
+
127
+ - **List connected devices** (for `--device=`):
128
+
129
+ ```bash
130
+ hstack mobile:devices
131
+ ```
132
+
133
+ - **Code signing weirdness on a real iPhone**:
134
+ - hstack will try to “un-pin” signing fields in the generated `.pbxproj` so Expo/Xcode can reconfigure signing
135
+ (this avoids failures where automatic signing is disabled because `DEVELOPMENT_TEAM`/profiles were pinned).
136
+ - If you want to manage signing manually, pass `--no-signing-fix` to `hstack mobile ...` / `hstack stack mobile <stack> ...`.
137
+
138
+ ## Bake the default server URL into the app (optional)
139
+
140
+ If you want the built app to default to your hstack server URL, set this **when building**:
141
+
142
+ ```bash
143
+ HAPPIER_STACK_SERVER_URL="https://<your-machine>.<tailnet>.ts.net" hstack mobile-dev-client --install
144
+ ```
145
+
146
+ Note: changing `HAPPIER_STACK_SERVER_URL` requires rebuilding/reinstalling the app you care about.
147
+
148
+ Important:
149
+
150
+ - For **non-main stacks**, `HAPPIER_STACK_SERVER_URL` is only respected if it’s set **in that stack’s env file**
151
+ (safety: we ignore “global” URLs for non-main stacks to avoid accidentally repointing other stacks).
152
+
153
+ ## Customizing the app identity (optional / advanced)
154
+
155
+ hstack uses these identities:
156
+
157
+ - **Dev-client**: defaults to `Happier Dev` + bundle id `dev.happier.stack.dev.<user>`
158
+ - **Per-stack release**: defaults to `Happier (<stack>)` + bundle id `dev.happier.stack.stack.<user>.<stack>`
159
+
160
+ If you want to build/install *manually* (instead of `mobile-dev-client` / `stack mobile:install`), you can override:
161
+
162
+ - **Bundle identifier (recommended for real iPhones)**:
163
+ - You may need this if the bundle id you’re using isn’t available/owned by your Apple team.
164
+
165
+ ```bash
166
+ HAPPIER_STACK_IOS_BUNDLE_ID="com.yourname.hstack.dev" hstack mobile --prebuild --run-ios --no-metro
167
+ ```
168
+
169
+ - **App name (what shows on the home screen)**:
170
+
171
+ ```bash
172
+ HAPPIER_STACK_IOS_APP_NAME="hstack" hstack mobile --prebuild --run-ios --no-metro
173
+ ```
174
+
175
+ ## Suggested env (recommended)
176
+
177
+ Add these to your main stack env file (`~/.happier/stacks/main/env`) (or `~/.happier-stack/env.local` for global overrides) so you don’t have to prefix every command:
178
+
179
+ ```bash
180
+ # How the phone reaches Metro:
181
+ # - lan: recommended for real devices
182
+ # - localhost: OK for simulators
183
+ HAPPIER_STACK_MOBILE_HOST="lan"
184
+
185
+ # (optional) default scheme used in the dev-client QR / deep link
186
+ # (must match your installed dev-client app):
187
+ HAPPIER_STACK_DEV_CLIENT_SCHEME="hstack-dev"
188
+
189
+ # Default public server URL for the stack (baked into the Expo app config):
190
+ HAPPIER_STACK_SERVER_URL="https://<your-machine>.<tailnet>.ts.net"
191
+
192
+ # Optional: home screen name:
193
+ HAPPIER_STACK_IOS_APP_NAME="Happier"
194
+ ```
195
+
196
+ ## EAS builds per stack (production / App Store-like)
197
+
198
+ This section documents the end-to-end workflow for producing a **fully working** EAS Build (cloud) for a stack,
199
+ with a **custom bundle id + app name** (example: `dev.happier.app` / `Happier`), while keeping upstream defaults unchanged when env vars are unset.
200
+
201
+ ### Overview
202
+
203
+ To get a reliable EAS build for a stack-specific app identity, you generally need:
204
+
205
+ - a **Happier monorepo worktree** that contains the app config hooks (dynamic `app.config.js`)
206
+ - a stack pinned to that worktree (`hstack stack wt <stack> -- use ...`)
207
+ - stack env vars describing the **app identity** (bundle id, name, scheme, etc.)
208
+ - EAS **environment variables** configured on Expo (so the cloud builder sees the same values)
209
+ - an initial **interactive** credentials setup (iOS signing) before non-interactive builds work
210
+ - for identity changes: run **prebuild** so `ios/` + `android/` native projects reflect the new id
211
+
212
+ ### 1) Create (or select) a stack + pin a worktree
213
+
214
+ Example stack name: `happier`.
215
+
216
+ Create a `happy` monorepo worktree from your fork branch (example):
217
+
218
+ ```bash
219
+ hstack wt new happy happier --from=origin --base=origin/happier
220
+ ```
221
+
222
+ Pin the `happier` stack to that worktree:
223
+
224
+ ```bash
225
+ hstack stack wt happier -- use happier-dev/happier
226
+ ```
227
+
228
+ ### 2) Set the app identity in the stack env (local + build-time config)
229
+
230
+ These are evaluated by `apps/ui/app.config.js` when building:
231
+
232
+ ```bash
233
+ hstack stack env happier set \
234
+ APP_ENV=production \
235
+ EXPO_APP_NAME="Happier" \
236
+ EXPO_APP_BUNDLE_ID="dev.happier.app" \
237
+ EXPO_APP_SCHEME="happier" \
238
+ EXPO_APP_SLUG="happier" \
239
+ EXPO_APP_OWNER="happier-dev"
240
+ ```
241
+
242
+ Notes:
243
+
244
+ - `APP_ENV` drives the built-in variant logic (development/preview/production).
245
+ - `EXPO_APP_*` overrides keep upstream defaults intact when unset.
246
+
247
+ ### 3) Regenerate native projects (“prebuild”) when changing identity
248
+
249
+ When changing bundle IDs / schemes / config plugins, you should run a clean prebuild so native projects match the config:
250
+
251
+ ```bash
252
+ hstack stack mobile happier --prebuild --platform=ios --clean --no-metro
253
+ # or:
254
+ hstack stack mobile happier --prebuild --platform=all --clean --no-metro
255
+ ```
256
+
257
+ ### 4) Make sure the cloud builder sees your env vars (EAS Environment Variables)
258
+
259
+ Cloud builds do **not** automatically inherit your local shell env.
260
+ You must configure EAS Environment Variables on Expo (project settings) and ensure your build profile selects an environment.
261
+
262
+ The EAS project env var workflow:
263
+
264
+ 1) Ensure your `eas.json` build profiles set `"environment": "production"` / `"preview"` / `"development"`.
265
+ 2) Create env vars in EAS for that environment (plain text or sensitive so config resolution can read them).
266
+
267
+ With hstack helpers (stack-scoped):
268
+
269
+ ```bash
270
+ # Inspect:
271
+ hstack stack eas happier env:list --environment production
272
+
273
+ # Create (use env:update if it already exists):
274
+ hstack stack eas happier env:create --name EXPO_APP_NAME --value "Happier" --environment production --visibility plainText
275
+ hstack stack eas happier env:create --name EXPO_APP_BUNDLE_ID --value "dev.happier.app" --environment production --visibility plainText
276
+ hstack stack eas happier env:create --name EXPO_APP_SCHEME --value "happier" --environment production --visibility plainText
277
+ hstack stack eas happier env:create --name EXPO_APP_OWNER --value "happier-dev" --environment production --visibility plainText
278
+ hstack stack eas happier env:create --name EXPO_APP_SLUG --value "happier" --environment production --visibility plainText
279
+ ```
280
+
281
+ Tip:
282
+
283
+ - If you see “No environment variables with visibility Plain text and Sensitive found…”, it means your EAS environment variables are missing (or set to `secret`).
284
+
285
+ ### 5) EAS project + account sanity checks
286
+
287
+ If you see permission errors, verify the Expo account:
288
+
289
+ ```bash
290
+ hstack stack eas happier whoami
291
+ hstack stack eas happier login
292
+ ```
293
+
294
+ If the project is not initialized/linked under your account yet:
295
+
296
+ ```bash
297
+ hstack stack eas happier project:init
298
+ ```
299
+
300
+ ### 6) Build (iOS / Android)
301
+
302
+ First-time iOS credential setup usually requires interactive mode:
303
+
304
+ ```bash
305
+ hstack stack eas happier ios --profile production --interactive
306
+ ```
307
+
308
+ After credentials are set up, you can run non-interactive builds:
309
+
310
+ ```bash
311
+ hstack stack eas happier ios --profile production --no-wait --non-interactive
312
+ hstack stack eas happier android --profile production --no-wait --non-interactive
313
+ ```
314
+
315
+ ### Common pitfalls
316
+
317
+ - **`eas.json is not valid` / `"build.base" must be of type object`**:
318
+ - your `eas.json` is using an old schema; update `build.base` to an object and use `"extends": "base"`.
319
+ - **`Credentials are not set up. Run this command again in interactive mode.`**:
320
+ - run the same build with `--interactive` once to configure iOS signing.
321
+ - **Cloud build doesn’t see stack env vars**:
322
+ - set EAS environment variables (project settings) and make sure your profile has `"environment": "production"`.
@@ -0,0 +1,20 @@
1
+ # Monorepo migration (legacy)
2
+
3
+ hstack is **monorepo-only** today, but it still ships a helper (`hstack monorepo port`) that can be used to port commits from legacy split repos into the Happier monorepo.
4
+
5
+ Current monorepo service layout:
6
+
7
+ - `apps/ui`
8
+ - `apps/cli`
9
+ - `apps/server`
10
+
11
+ If you’re migrating old work, start here:
12
+
13
+ ```bash
14
+ hstack monorepo port --help
15
+ ```
16
+
17
+ Notes:
18
+
19
+ - Prefer doing ports in a dedicated worktree (`hstack wt new ...`) and validating in an isolated stack (`hstack stack new ...`).
20
+ - If you don’t need this, you can ignore it; it exists only for historical migrations.
@@ -0,0 +1,154 @@
1
+ # Paths, folders, and env precedence
2
+
3
+ This doc explains the **directories** that hstack uses (home/workspace/runtime/stacks), and the **environment file precedence** used by `hstack`.
4
+
5
+ If you’re ever unsure what your machine is actually using, run:
6
+
7
+ ```bash
8
+ hstack where
9
+ ```
10
+
11
+ ---
12
+
13
+ ## Quick glossary
14
+
15
+ - **CLI root dir**
16
+ - The directory containing the `@happier-dev/stack` scripts (`scripts/*.mjs`) that your `hstack` command is currently executing.
17
+ - This is *not* necessarily your current shell `cwd`.
18
+ - It can be:
19
+ - a cloned repo checkout (e.g. `/Users/<you>/.../happier-dev`), or
20
+ - the installed runtime package under `~/.happier-stack/runtime/node_modules/@happier-dev/stack` (see “Runtime dir”).
21
+
22
+ - **Home dir** (`HAPPIER_STACK_HOME_DIR`)
23
+ - Default: `~/.happier-stack`
24
+ - Stores **global user config** + caches, and may include a runtime install.
25
+
26
+ - **Runtime dir** (`HAPPIER_STACK_RUNTIME_DIR`)
27
+ - Default: `~/.happier-stack/runtime`
28
+ - Used by `hstack self update` to install/upgrade a pinned `@happier-dev/stack` runtime package.
29
+
30
+ - **Workspace dir** (`HAPPIER_STACK_WORKSPACE_DIR`)
31
+ - Default: `~/.happier-stack/workspace` (when it exists).
32
+ - This is the **storage workspace for the Happier monorepo checkout + worktrees** used by hstack.
33
+ - It typically contains:
34
+ - `<workspace>/main` (stable monorepo checkout)
35
+ - `<workspace>/dev` (dev monorepo checkout; created by `hstack setup --profile=dev`)
36
+ - `<workspace>/pr/...` (PR worktrees)
37
+ - `<workspace>/local/<owner>/...` (local worktrees)
38
+ - `<workspace>/tmp/<owner>/...` (temporary worktrees)
39
+
40
+ - **Repo dir** (`HAPPIER_STACK_REPO_DIR`)
41
+ - Default: `<workspace>/main`
42
+ - This is the active Happier monorepo checkout (either `main`, `dev`, or a worktree).
43
+ - `hstack wt use ...` and `hstack stack wt <stack> -- use ...` update this value.
44
+
45
+ - **Worktrees**
46
+ - PRs: `<workspace>/pr/...`
47
+ - locals: `<workspace>/local/<owner>/...`
48
+ - tmp: `<workspace>/tmp/<owner>/...`
49
+
50
+ - **Stacks storage dir**
51
+ - Default: `~/.happier/stacks`
52
+ - Each stack lives under `~/.happier/stacks/<name>/...` and has its own env file:
53
+ - `~/.happier/stacks/<name>/env`
54
+
55
+ ---
56
+
57
+ ## “Where am I actually running from?”
58
+
59
+ `hstack` may **re-exec** to a different CLI root dir (for example, when you use an installed shim but want it to run a local checkout).
60
+
61
+ - Run `hstack where` to see:
62
+ - **rootDir** (CLI root dir)
63
+ - **homeDir** (stacks home dir)
64
+ - **runtimeDir**
65
+ - **workspaceDir**
66
+ - resolved env file paths
67
+
68
+ Tip: to pin the shim to a local checkout, use:
69
+
70
+ ```bash
71
+ hstack self use-cli dev
72
+ ```
73
+
74
+ Tip: `hstack where --json` is easier to parse.
75
+
76
+ ---
77
+
78
+ ## Env files + precedence (lowest → highest)
79
+
80
+ hstack loads env in `scripts/utils/env.mjs`.
81
+
82
+ ### 0) “Canonical pointer” env (discovery)
83
+
84
+ If `HAPPIER_STACK_HOME_DIR` is *not* set, we first try to read the **canonical pointer** env file to discover the intended home dir (useful for LaunchAgents / SwiftBar / minimal shells).
85
+
86
+ - Default canonical pointer path: `~/.happier-stack/.env`
87
+ - Override canonical pointer location:
88
+ - `HAPPIER_STACK_CANONICAL_HOME_DIR=/some/dir` (pointer becomes `<dir>/.env`)
89
+
90
+ ### 1) Global defaults (home config) OR cloned-repo defaults
91
+
92
+ If home config exists, we load:
93
+
94
+ - `~/.happier-stack/.env` (**defaults**)
95
+ - `~/.happier-stack/env.local` (**overrides**, prefix-aware for `HAPPIER_STACK_*`)
96
+
97
+ If home config does *not* exist (cloned repo usage before `hstack init`), we load:
98
+
99
+ - `<cliRootDir>/.env`
100
+ - `<cliRootDir>/env.local` (prefix-aware for `HAPPIER_STACK_*`)
101
+
102
+ ### 2) Repo `.env` fallback (dev convenience)
103
+
104
+ Even when home config exists, we also load:
105
+
106
+ - `<cliRootDir>/.env` (non-overriding fallback)
107
+
108
+ This exists so repo-local dev settings (example: `HAPPIER_CODEX_ACP_BIN`) can work without forcing everyone to duplicate them into `~/.happier-stack/env.local`.
109
+
110
+ Notes:
111
+ - This is a **fallback only** (`override: false`): it won’t stomp on values already provided by the environment or home config.
112
+ - We intentionally do **not** auto-load `<cliRootDir>/env.local` in this “home config exists” path, because it’s higher-precedence and can unexpectedly fight stack config.
113
+
114
+ ### 3) Stack env overlay (highest precedence)
115
+
116
+ Finally, we load the active stack env file (override = true):
117
+
118
+ - `HAPPIER_STACK_ENV_FILE`
119
+ - if neither is set, we auto-select the env file for the current stack (defaults to `main`) if it exists
120
+
121
+ Stack env files are allowed to contain **non-prefixed keys** (like `DATABASE_URL`) because that’s required for per-stack isolation.
122
+
123
+ ---
124
+
125
+ ## What should go where? (rules of thumb)
126
+
127
+ - Put **global, machine-wide defaults** in `~/.happier-stack/.env`.
128
+ - Put **your personal overrides** in `~/.happier-stack/env.local`.
129
+ - Put **per-stack isolation config** in the stack env file `~/.happier/stacks/<name>/env` (this is what `hstack stack edit` and `hstack stack wt` mutate).
130
+ - Put **repo-local dev-only defaults** in `<cliRootDir>/.env` (works best when you’re actually running from that checkout as the CLI root dir).
131
+
132
+ ---
133
+
134
+ ## Sandbox / test installs (fully isolated)
135
+
136
+ If you want to test the full install + setup flows without touching your real installation, run with:
137
+
138
+ ```bash
139
+ npx @happier-dev/stack@latest --sandbox-dir /tmp/hstack-sandbox where
140
+ ```
141
+
142
+ In sandbox mode, hstack redirects **home/workspace/runtime/storage** under the sandbox folder (so you can `rm -rf` it to reset).
143
+
144
+ Global OS side effects (PATH edits, SwiftBar plugin install, LaunchAgents/systemd services) are **disabled by default** in sandbox mode.
145
+ To explicitly allow them for testing, set:
146
+
147
+ - `HAPPIER_STACK_SANDBOX_ALLOW_GLOBAL=1`
148
+
149
+ ---
150
+
151
+ ## Related docs
152
+
153
+ - `docs/stacks.md` (stacks lifecycle + commands)
154
+ - `docs/worktrees-and-forks.md` (worktrees layout + upstream/fork workflows)
@@ -0,0 +1,43 @@
1
+ # Remote access (Tailscale + phone)
2
+
3
+ Happier relies on “secure context” browser features (WebCrypto). Browsers treat `http://localhost` as a secure context, but **not** `http://<lan-ip>:<port>` or `http://<tailscale-ip>:<port>`.
4
+
5
+ For remote access (phone, another laptop, etc) you should use **HTTPS**.
6
+
7
+ The recommended approach is **Tailscale Serve**, which gives you an `https://*.ts.net` URL for your machine that is only accessible inside your tailnet.
8
+
9
+ ## Quickstart
10
+
11
+ 1) Install Tailscale and sign in on your computer.
12
+
13
+ 2) Enable Serve:
14
+
15
+ ```bash
16
+ hstack tailscale enable
17
+ hstack tailscale url
18
+ ```
19
+
20
+ 3) Open the URL from `hstack tailscale url` on another device (also signed into Tailscale).
21
+
22
+ Tip: on iOS, you can “Add to Home Screen” from Safari to use it like an app.
23
+
24
+ ## Automation
25
+
26
+ If Serve is already configured, `hstack start` will automatically prefer the `https://*.ts.net` URL for “public” links unless you explicitly set `HAPPIER_STACK_SERVER_URL`.
27
+
28
+ You can also ask hstack to enable Serve automatically at boot:
29
+
30
+ ```bash
31
+ HAPPIER_STACK_TAILSCALE_SERVE=1 hstack start
32
+ ```
33
+
34
+ Useful knobs:
35
+ - `HAPPIER_STACK_TAILSCALE_WAIT_MS`
36
+ - `HAPPIER_STACK_TAILSCALE_BIN`
37
+
38
+ ## Using the native Happier mobile app (optional)
39
+
40
+ The native Happier mobile app has an “API Endpoint” setting (developer mode).
41
+ Point it at the same HTTPS `*.ts.net` URL to use your local server.
42
+
43
+ However, the simplest option is usually the **served web UI** (no app updates needed).
@@ -0,0 +1,147 @@
1
+ # Server flavors: `happier-server-light` vs `happier-server`
2
+
3
+ hstack supports two server “flavors”. You can switch between them globally (main stack) or per stack.
4
+
5
+ ## What’s the difference?
6
+
7
+ Both flavors use the **same server codebase** (the monorepo server package, typically `apps/server`), but run with different backends and storage assumptions.
8
+
9
+ ### `happier-server-light` (recommended default)
10
+
11
+ - **No Docker required**
12
+ - Uses **embedded Postgres via PGlite** (“PG_Light”) stored under the stack directory (per-stack isolation)
13
+ - Stores local public files under the stack directory
14
+ - Best choice for a stable “main” stack and quick local installs
15
+
16
+ Light stacks are isolated by default:
17
+
18
+ ```
19
+ ~/.happier/stacks/<stack>/server-light/files
20
+ ~/.happier/stacks/<stack>/server-light/pglite
21
+ ```
22
+
23
+ Key env vars (stored in the stack env file):
24
+
25
+ - `HAPPIER_SERVER_LIGHT_DATA_DIR`
26
+ - `HAPPIER_SERVER_LIGHT_FILES_DIR`
27
+ - `HAPPIER_SERVER_LIGHT_DB_DIR`
28
+
29
+ ### `happier-server` (full server)
30
+
31
+ - Docker-managed infra per stack (Postgres + Redis + Minio/S3)
32
+ - Closer to “production-like” behavior
33
+ - Useful when you need Redis/S3 semantics or want to reproduce full-server-only issues
34
+
35
+ ## Full server infra (no AWS required)
36
+
37
+ `happier-server` requires:
38
+
39
+ - Postgres (`DATABASE_URL`)
40
+ - Redis (`REDIS_URL`)
41
+ - S3-compatible object storage (`S3_*`)
42
+
43
+ hstack can **manage this for you automatically per stack** using Docker Compose (Postgres + Redis + Minio),
44
+ so you **do not need AWS S3**.
45
+
46
+ This happens automatically when you run `hstack start/dev --server=happier-server` (or when a stack uses `happier-server`),
47
+ unless you disable it with:
48
+
49
+ ```bash
50
+ export HAPPIER_STACK_MANAGED_INFRA=0
51
+ ```
52
+
53
+ If disabled, you must provide `DATABASE_URL`, `REDIS_URL`, and `S3_*` yourself.
54
+
55
+ ## UI serving with `happier-server`
56
+
57
+ The upstream `happier-server` does not serve the built UI itself.
58
+
59
+ For a “one URL” UX (especially with Tailscale), hstack starts a lightweight **UI gateway** that:
60
+
61
+ - serves the built UI at `/` (if a build exists)
62
+ - reverse-proxies API calls to the backend server
63
+ - reverse-proxies realtime websocket upgrades (`/v1/updates`)
64
+ - reverse-proxies public files (to local Minio)
65
+
66
+ This means `hstack start --server=happier-server` can still work end-to-end without requiring AWS S3 or a separate nginx setup.
67
+
68
+ ## Migrating between flavors (PG_Light ⇢ Postgres)
69
+
70
+ 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
+
73
+ ```bash
74
+ hstack migrate light-to-server --from-stack=main --to-stack=full1
75
+ ```
76
+
77
+ Optional: include local public files (server-light `files/`) by mirroring them into Minio:
78
+
79
+ ```bash
80
+ hstack migrate light-to-server --from-stack=main --to-stack=full1 --include-files
81
+ ```
82
+
83
+ Notes:
84
+ - This preserves IDs (session URLs remain valid on the target server).
85
+ - It also copies the `HANDY_MASTER_SECRET` from the source stack into the target stack’s secret file so auth tokens remain valid.
86
+
87
+ ## Prisma behavior (why start is safer under LaunchAgents)
88
+
89
+ - **`hstack start`** is “production-like”. It avoids running heavyweight schema sync loops under launchd KeepAlive.
90
+ - **`hstack dev`** is for rapid iteration:
91
+ - for `happier-server`: hstack runs `prisma migrate deploy` by default (configurable via `HAPPIER_STACK_PRISMA_MIGRATE`).
92
+ - 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
+
95
+ Important: for a given run (`hstack start` / `hstack dev`) you choose **one** flavor.
96
+
97
+ ## How to switch (main stack)
98
+
99
+ Use the `srv` helper (persisted in `~/.happier/stacks/main/env` by default, or in your stack env file when using `hstack stack ...`):
100
+
101
+ ```bash
102
+ hstack srv status
103
+ hstack srv use happier-server-light
104
+ hstack srv use happier-server
105
+ hstack srv use --interactive
106
+ ```
107
+
108
+ This persists `HAPPIER_STACK_SERVER_COMPONENT`.
109
+
110
+ ## How to switch for a specific stack
111
+
112
+ Use the stack wrapper:
113
+
114
+ ```bash
115
+ hstack stack srv exp1 -- status
116
+ hstack stack srv exp1 -- use happier-server-light
117
+ hstack stack srv exp1 -- use happier-server
118
+ hstack stack srv exp1 -- use --interactive
119
+ ```
120
+
121
+ This updates the stack env file (typically `~/.happier/stacks/<name>/env`).
122
+
123
+ ## One-off overrides (do not persist)
124
+
125
+ You can override the server flavor for a single run:
126
+
127
+ ```bash
128
+ hstack start --server=happier-server-light
129
+ hstack start --server=happier-server
130
+
131
+ hstack dev --server=happier-server-light
132
+ hstack dev --server=happier-server
133
+ ```
134
+
135
+ ## Flavor vs repo selection
136
+
137
+ There are two separate concepts:
138
+
139
+ - **Flavor selection**: which server flavor hstack runs
140
+ - controlled by `HAPPIER_STACK_SERVER_COMPONENT` (via `hstack srv use ...`)
141
+ - **Repo selection**: which monorepo checkout/worktree the stack runs from
142
+ - controlled by `HAPPIER_STACK_REPO_DIR` (via `hstack wt use ...` / `hstack stack wt <stack> -- use ...`)
143
+
144
+ ## SQLite note
145
+
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
+