@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.
- package/README.md +501 -0
- package/bin/hstack.mjs +348 -0
- package/docs/codex-mcp-resume.md +129 -0
- package/docs/edison.md +74 -0
- package/docs/forking-and-branding.md +189 -0
- package/docs/happy-development.md +22 -0
- package/docs/isolated-linux-vm.md +243 -0
- package/docs/menubar.md +244 -0
- package/docs/mobile-ios.md +322 -0
- package/docs/monorepo-migration.md +20 -0
- package/docs/paths-and-env.md +154 -0
- package/docs/remote-access.md +43 -0
- package/docs/server-flavors.md +147 -0
- package/docs/stacks.md +330 -0
- package/docs/tauri.md +60 -0
- package/docs/worktrees-and-forks.md +133 -0
- package/extras/swiftbar/auth-login.sh +29 -0
- package/extras/swiftbar/git-cache-refresh.sh +122 -0
- package/extras/swiftbar/hstack-term.sh +133 -0
- package/extras/swiftbar/hstack.5s.sh +296 -0
- package/extras/swiftbar/hstack.sh +35 -0
- package/extras/swiftbar/icons/happy-green.png +0 -0
- package/extras/swiftbar/icons/happy-orange.png +0 -0
- package/extras/swiftbar/icons/happy-red.png +0 -0
- package/extras/swiftbar/icons/logo-white.png +0 -0
- package/extras/swiftbar/install.sh +265 -0
- package/extras/swiftbar/lib/git.sh +629 -0
- package/extras/swiftbar/lib/icons.sh +92 -0
- package/extras/swiftbar/lib/render.sh +999 -0
- package/extras/swiftbar/lib/system.sh +244 -0
- package/extras/swiftbar/lib/utils.sh +717 -0
- package/extras/swiftbar/set-interval.sh +65 -0
- package/extras/swiftbar/set-server-flavor.sh +61 -0
- package/extras/swiftbar/wt-pr.sh +140 -0
- package/node_modules/@happier-dev/cli-common/README.md +6 -0
- package/node_modules/@happier-dev/cli-common/dist/index.d.ts +4 -0
- package/node_modules/@happier-dev/cli-common/dist/index.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/index.js +4 -0
- package/node_modules/@happier-dev/cli-common/dist/index.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/links/index.d.ts +18 -0
- package/node_modules/@happier-dev/cli-common/dist/links/index.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/links/index.js +25 -0
- package/node_modules/@happier-dev/cli-common/dist/links/index.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/links.d.ts +2 -0
- package/node_modules/@happier-dev/cli-common/dist/links.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/links.js +2 -0
- package/node_modules/@happier-dev/cli-common/dist/links.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/update/index.d.ts +67 -0
- package/node_modules/@happier-dev/cli-common/dist/update/index.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/update/index.js +259 -0
- package/node_modules/@happier-dev/cli-common/dist/update/index.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/workspaces/index.d.ts +17 -0
- package/node_modules/@happier-dev/cli-common/dist/workspaces/index.d.ts.map +1 -0
- package/node_modules/@happier-dev/cli-common/dist/workspaces/index.js +80 -0
- package/node_modules/@happier-dev/cli-common/dist/workspaces/index.js.map +1 -0
- package/node_modules/@happier-dev/cli-common/package.json +26 -0
- package/package.json +77 -0
- package/scripts/auth.mjs +1829 -0
- package/scripts/auth_copy_from_pglite_lock_in_use.integration.test.mjs +90 -0
- package/scripts/auth_copy_from_runCapture.integration.test.mjs +447 -0
- package/scripts/auth_help_cmd.test.mjs +28 -0
- package/scripts/auth_login_flow_in_tty.test.mjs +100 -0
- package/scripts/auth_login_force_default.test.mjs +66 -0
- package/scripts/auth_login_guided_server_no_expo.test.mjs +126 -0
- package/scripts/auth_login_method_override.test.mjs +67 -0
- package/scripts/auth_login_print_includes_configure_links.test.mjs +99 -0
- package/scripts/auth_status_server_validation.integration.test.mjs +140 -0
- package/scripts/build.mjs +266 -0
- package/scripts/bundleWorkspaceDeps.mjs +38 -0
- package/scripts/bundleWorkspaceDeps.test.mjs +77 -0
- package/scripts/ci.mjs +135 -0
- package/scripts/ci.test.mjs +50 -0
- package/scripts/cli-link.mjs +57 -0
- package/scripts/completion.mjs +395 -0
- package/scripts/contrib.mjs +333 -0
- package/scripts/daemon.mjs +1160 -0
- package/scripts/daemon.status_scope.test.mjs +51 -0
- package/scripts/daemon_cmd.mjs +26 -0
- package/scripts/daemon_dist_guard.test.mjs +171 -0
- package/scripts/daemon_invalid_auth_reseed_stack_name.integration.test.mjs +608 -0
- package/scripts/daemon_server_scoped_state.test.mjs +49 -0
- package/scripts/daemon_start_verification.integration.test.mjs +296 -0
- package/scripts/dev.mjs +545 -0
- package/scripts/doctor.mjs +340 -0
- package/scripts/doctor_cmd.test.mjs +22 -0
- package/scripts/doctor_ui_index_missing.test.mjs +37 -0
- package/scripts/eas.mjs +367 -0
- package/scripts/eas_platform_parsing.test.mjs +63 -0
- package/scripts/edison.mjs +1848 -0
- package/scripts/env.mjs +149 -0
- package/scripts/env_cmd.test.mjs +118 -0
- package/scripts/exit_cleanup_kills_detached_children_on_crash.integration.test.mjs +80 -0
- package/scripts/happier.mjs +82 -0
- package/scripts/import.mjs +1327 -0
- package/scripts/init.mjs +464 -0
- package/scripts/install.mjs +550 -0
- package/scripts/lint.mjs +177 -0
- package/scripts/menubar.mjs +202 -0
- package/scripts/migrate.mjs +318 -0
- package/scripts/mobile.mjs +353 -0
- package/scripts/mobile_dev_client.mjs +87 -0
- package/scripts/monorepo.mjs +2234 -0
- package/scripts/monorepo_port.apply.integration.test.mjs +680 -0
- package/scripts/monorepo_port.conflicts.integration.test.mjs +454 -0
- package/scripts/monorepo_port.validation.integration.test.mjs +486 -0
- package/scripts/orchestrated_stack_auth_flow.test.mjs +134 -0
- package/scripts/orchestrated_stack_auth_flow_resolve_port.test.mjs +98 -0
- package/scripts/orchestrated_stack_auth_flow_webapp_url.test.mjs +119 -0
- package/scripts/pack.mjs +257 -0
- package/scripts/pack.test.mjs +68 -0
- package/scripts/pglite_lock.integration.test.mjs +152 -0
- package/scripts/provision/linux-ubuntu-e2e.sh +132 -0
- package/scripts/provision/linux-ubuntu-review-pr.sh +66 -0
- package/scripts/provision/macos-lima-happy-vm.sh +192 -0
- package/scripts/provision/macos-lima-hstack-e2e.sh +100 -0
- package/scripts/release.mjs +53 -0
- package/scripts/release_binary_smoke.integration.test.mjs +159 -0
- package/scripts/review.mjs +1752 -0
- package/scripts/review_pr.mjs +435 -0
- package/scripts/run.mjs +561 -0
- package/scripts/run_script_with_stack_env.restart_port_reuse.test.mjs +30 -0
- package/scripts/self.mjs +465 -0
- package/scripts/self_host.mjs +9 -0
- package/scripts/self_host_binary_smoke.integration.test.mjs +94 -0
- package/scripts/self_host_runtime.mjs +883 -0
- package/scripts/self_host_runtime.test.mjs +82 -0
- package/scripts/self_host_systemd.real.integration.test.mjs +367 -0
- package/scripts/server_flavor.mjs +148 -0
- package/scripts/service.mjs +868 -0
- package/scripts/service_mode_help.test.mjs +27 -0
- package/scripts/setup.mjs +1324 -0
- package/scripts/setup_non_interactive_flag.test.mjs +60 -0
- package/scripts/setup_pr.mjs +605 -0
- package/scripts/setup_pr_orchestrated_auth_flow_util_import.test.mjs +117 -0
- package/scripts/stack/command_arguments.mjs +91 -0
- package/scripts/stack/copy_auth_from_stack.mjs +111 -0
- package/scripts/stack/delegated_script_commands.mjs +92 -0
- package/scripts/stack/help_text.mjs +110 -0
- package/scripts/stack/port_reservation.mjs +74 -0
- package/scripts/stack/repo_checkout_resolution.mjs +31 -0
- package/scripts/stack/run_script_with_stack_env.mjs +634 -0
- package/scripts/stack/stack_daemon_command.mjs +219 -0
- package/scripts/stack/stack_delegated_help.mjs +81 -0
- package/scripts/stack/stack_environment.mjs +151 -0
- package/scripts/stack/stack_environment.sanitization.test.mjs +75 -0
- package/scripts/stack/stack_happier_passthrough_command.mjs +63 -0
- package/scripts/stack/stack_info_snapshot.mjs +167 -0
- package/scripts/stack/stack_mobile_install_command.mjs +61 -0
- package/scripts/stack/stack_resume_command.mjs +76 -0
- package/scripts/stack/stack_stop_command.mjs +34 -0
- package/scripts/stack/stack_workspace_command.mjs +83 -0
- package/scripts/stack/transient_repo_overrides.mjs +29 -0
- package/scripts/stack.mjs +2388 -0
- package/scripts/stack_archive_cmd.integration.test.mjs +31 -0
- package/scripts/stack_audit_fix_light_env.test.mjs +129 -0
- package/scripts/stack_background_pinned_stack_json.test.mjs +81 -0
- package/scripts/stack_copy_auth_server_scoped.test.mjs +243 -0
- package/scripts/stack_daemon_cmd.integration.test.mjs +484 -0
- package/scripts/stack_eas_help.test.mjs +72 -0
- package/scripts/stack_editor_workspace_monorepo_root.test.mjs +102 -0
- package/scripts/stack_env_cmd.test.mjs +107 -0
- package/scripts/stack_guided_login_bundle_error_parse.test.mjs +20 -0
- package/scripts/stack_guided_login_inner_invocation.test.mjs +46 -0
- package/scripts/stack_happy_cmd.integration.test.mjs +263 -0
- package/scripts/stack_info_snapshot_running_status.test.mjs +186 -0
- package/scripts/stack_interactive_monorepo_group.test.mjs +128 -0
- package/scripts/stack_monorepo_defaults.test.mjs +31 -0
- package/scripts/stack_monorepo_repo_dev_token.test.mjs +32 -0
- package/scripts/stack_monorepo_server_light_from_happy_spec.test.mjs +37 -0
- package/scripts/stack_new_name_normalize_cmd.test.mjs +38 -0
- package/scripts/stack_pr_name_normalize_cmd.test.mjs +84 -0
- package/scripts/stack_resume_cmd.integration.test.mjs +134 -0
- package/scripts/stack_server_flavors_defaults.test.mjs +64 -0
- package/scripts/stack_shorthand_cmd.integration.test.mjs +74 -0
- package/scripts/stack_stop_sweeps_legacy_infra_without_kind.integration.test.mjs +44 -0
- package/scripts/stack_stop_sweeps_when_runtime_missing.integration.test.mjs +42 -0
- package/scripts/stack_stop_sweeps_when_runtime_stale.integration.test.mjs +50 -0
- package/scripts/stack_wt_list.test.mjs +117 -0
- package/scripts/start_ui_required_default.test.mjs +63 -0
- package/scripts/stop.mjs +190 -0
- package/scripts/stopStackWithEnv_no_autosweep_when_runtime_missing.integration.test.mjs +95 -0
- package/scripts/swiftbar_git_monorepo_cmd.test.mjs +75 -0
- package/scripts/swiftbar_render_monorepo_wt_actions.integration.test.mjs +116 -0
- package/scripts/swiftbar_utils_cmd.test.mjs +92 -0
- package/scripts/swiftbar_wt_pr_backcompat.test.mjs +162 -0
- package/scripts/systemd_unit_info.test.mjs +24 -0
- package/scripts/tailscale.mjs +490 -0
- package/scripts/test_ci.mjs +36 -0
- package/scripts/test_cmd.mjs +274 -0
- package/scripts/test_cmd.test.mjs +133 -0
- package/scripts/test_integration.mjs +33 -0
- package/scripts/testkit/auth_testkit.mjs +121 -0
- package/scripts/testkit/doctor_testkit.mjs +68 -0
- package/scripts/testkit/monorepo_port_testkit.mjs +157 -0
- package/scripts/testkit/stack_archive_command_testkit.mjs +55 -0
- package/scripts/testkit/stack_new_monorepo_testkit.mjs +83 -0
- package/scripts/testkit/stack_script_command_testkit.mjs +27 -0
- package/scripts/testkit/stack_stop_sweeps_testkit.mjs +172 -0
- package/scripts/testkit/worktrees_monorepo_testkit.mjs +53 -0
- package/scripts/tools.mjs +70 -0
- package/scripts/tui.mjs +914 -0
- package/scripts/tui_stopStackForTuiExit_no_autosweep.integration.test.mjs +95 -0
- package/scripts/typecheck.mjs +178 -0
- package/scripts/ui_gateway.mjs +247 -0
- package/scripts/uninstall.mjs +179 -0
- package/scripts/utils/auth/credentials_paths.mjs +181 -0
- package/scripts/utils/auth/credentials_paths.test.mjs +187 -0
- package/scripts/utils/auth/daemon_gate.mjs +66 -0
- package/scripts/utils/auth/daemon_gate.test.mjs +116 -0
- package/scripts/utils/auth/decode_jwt_payload_unsafe.mjs +16 -0
- package/scripts/utils/auth/dev_key.mjs +163 -0
- package/scripts/utils/auth/files.mjs +56 -0
- package/scripts/utils/auth/guided_pr_auth.mjs +86 -0
- package/scripts/utils/auth/guided_stack_web_login.mjs +56 -0
- package/scripts/utils/auth/handy_master_secret.mjs +42 -0
- package/scripts/utils/auth/interactive_stack_auth.mjs +70 -0
- package/scripts/utils/auth/login_ux.mjs +105 -0
- package/scripts/utils/auth/orchestrated_stack_auth_flow.mjs +291 -0
- package/scripts/utils/auth/sources.mjs +28 -0
- package/scripts/utils/auth/stable_scope_id.mjs +91 -0
- package/scripts/utils/auth/stable_scope_id.test.mjs +51 -0
- package/scripts/utils/auth/stack_guided_login.mjs +438 -0
- package/scripts/utils/cli/arg_values.mjs +23 -0
- package/scripts/utils/cli/arg_values.test.mjs +43 -0
- package/scripts/utils/cli/args.mjs +17 -0
- package/scripts/utils/cli/cli.mjs +24 -0
- package/scripts/utils/cli/cli_registry.mjs +440 -0
- package/scripts/utils/cli/cwd_scope.mjs +158 -0
- package/scripts/utils/cli/cwd_scope.test.mjs +154 -0
- package/scripts/utils/cli/flags.mjs +17 -0
- package/scripts/utils/cli/log_forwarder.mjs +157 -0
- package/scripts/utils/cli/normalize.mjs +16 -0
- package/scripts/utils/cli/prereqs.mjs +103 -0
- package/scripts/utils/cli/prereqs.test.mjs +33 -0
- package/scripts/utils/cli/progress.mjs +141 -0
- package/scripts/utils/cli/smoke_help.mjs +44 -0
- package/scripts/utils/cli/verbosity.mjs +11 -0
- package/scripts/utils/cli/wizard.mjs +139 -0
- package/scripts/utils/cli/wizard_promptSelect.test.mjs +44 -0
- package/scripts/utils/cli/wizard_prompt_worktree_source_lazy.test.mjs +132 -0
- package/scripts/utils/cli/wizard_worktree_slug.test.mjs +33 -0
- package/scripts/utils/crypto/tokens.mjs +14 -0
- package/scripts/utils/dev/daemon.mjs +232 -0
- package/scripts/utils/dev/daemon_watch_resilience.test.mjs +224 -0
- package/scripts/utils/dev/expo_dev.buildEnv.test.mjs +35 -0
- package/scripts/utils/dev/expo_dev.mjs +478 -0
- package/scripts/utils/dev/expo_dev.test.mjs +89 -0
- package/scripts/utils/dev/expo_dev_restart_port_reservation.test.mjs +120 -0
- package/scripts/utils/dev/expo_dev_verbose_logs.test.mjs +60 -0
- package/scripts/utils/dev/server.mjs +180 -0
- package/scripts/utils/dev_auth_key.mjs +7 -0
- package/scripts/utils/edison/git_roots.mjs +30 -0
- package/scripts/utils/edison/git_roots.test.mjs +49 -0
- package/scripts/utils/env/config.mjs +52 -0
- package/scripts/utils/env/dotenv.mjs +32 -0
- package/scripts/utils/env/dotenv.test.mjs +32 -0
- package/scripts/utils/env/env.mjs +130 -0
- package/scripts/utils/env/env_file.mjs +98 -0
- package/scripts/utils/env/env_file.test.mjs +49 -0
- package/scripts/utils/env/env_local.mjs +25 -0
- package/scripts/utils/env/load_env_file.mjs +34 -0
- package/scripts/utils/env/read.mjs +30 -0
- package/scripts/utils/env/sandbox.mjs +13 -0
- package/scripts/utils/env/scrub_env.mjs +69 -0
- package/scripts/utils/env/scrub_env.test.mjs +102 -0
- package/scripts/utils/env/values.mjs +13 -0
- package/scripts/utils/expo/command.mjs +65 -0
- package/scripts/utils/expo/expo.mjs +139 -0
- package/scripts/utils/expo/expo_state_running.test.mjs +48 -0
- package/scripts/utils/expo/metro_ports.mjs +101 -0
- package/scripts/utils/expo/metro_ports.test.mjs +35 -0
- package/scripts/utils/fs/atomic_dir_swap.mjs +55 -0
- package/scripts/utils/fs/atomic_dir_swap.test.mjs +54 -0
- package/scripts/utils/fs/file_has_content.mjs +10 -0
- package/scripts/utils/fs/fs.mjs +11 -0
- package/scripts/utils/fs/json.mjs +25 -0
- package/scripts/utils/fs/ops.mjs +29 -0
- package/scripts/utils/fs/package_json.mjs +8 -0
- package/scripts/utils/fs/tail.mjs +12 -0
- package/scripts/utils/git/dev_checkout.mjs +127 -0
- package/scripts/utils/git/dev_checkout.test.mjs +115 -0
- package/scripts/utils/git/git.mjs +67 -0
- package/scripts/utils/git/parse_name_status_z.mjs +21 -0
- package/scripts/utils/git/refs.mjs +26 -0
- package/scripts/utils/git/worktrees.mjs +323 -0
- package/scripts/utils/git/worktrees_monorepo.test.mjs +60 -0
- package/scripts/utils/git/worktrees_pathstyle.test.mjs +53 -0
- package/scripts/utils/llm/assist.mjs +260 -0
- package/scripts/utils/llm/codex_exec.mjs +61 -0
- package/scripts/utils/llm/codex_exec.test.mjs +46 -0
- package/scripts/utils/llm/hstack_runner.mjs +59 -0
- package/scripts/utils/llm/tools.mjs +56 -0
- package/scripts/utils/llm/tools.test.mjs +67 -0
- package/scripts/utils/menubar/swiftbar.mjs +121 -0
- package/scripts/utils/menubar/swiftbar.test.mjs +85 -0
- package/scripts/utils/mobile/config.mjs +35 -0
- package/scripts/utils/mobile/dev_client_links.mjs +59 -0
- package/scripts/utils/mobile/identifiers.mjs +46 -0
- package/scripts/utils/mobile/identifiers.test.mjs +41 -0
- package/scripts/utils/mobile/ios_xcodeproj_patch.mjs +128 -0
- package/scripts/utils/mobile/ios_xcodeproj_patch.test.mjs +131 -0
- package/scripts/utils/net/bind_mode.mjs +39 -0
- package/scripts/utils/net/dns.mjs +10 -0
- package/scripts/utils/net/lan_ip.mjs +24 -0
- package/scripts/utils/net/ports.mjs +110 -0
- package/scripts/utils/net/tcp_forward.mjs +162 -0
- package/scripts/utils/net/url.mjs +30 -0
- package/scripts/utils/net/url.test.mjs +29 -0
- package/scripts/utils/paths/canonical_home.mjs +15 -0
- package/scripts/utils/paths/canonical_home.test.mjs +28 -0
- package/scripts/utils/paths/localhost_host.mjs +112 -0
- package/scripts/utils/paths/localhost_host.test.mjs +58 -0
- package/scripts/utils/paths/paths.mjs +302 -0
- package/scripts/utils/paths/paths_env_win32.test.mjs +36 -0
- package/scripts/utils/paths/paths_monorepo.test.mjs +58 -0
- package/scripts/utils/paths/paths_server_flavors.test.mjs +50 -0
- package/scripts/utils/paths/runtime.mjs +41 -0
- package/scripts/utils/pglite_lock.mjs +107 -0
- package/scripts/utils/proc/commands.mjs +33 -0
- package/scripts/utils/proc/exit_cleanup.mjs +57 -0
- package/scripts/utils/proc/happy_monorepo_deps.mjs +37 -0
- package/scripts/utils/proc/happy_monorepo_deps.test.mjs +89 -0
- package/scripts/utils/proc/ownership.mjs +217 -0
- package/scripts/utils/proc/ownership_killProcessGroupOwnedByStack.test.mjs +216 -0
- package/scripts/utils/proc/ownership_listPidsWithEnvNeedles.test.mjs +88 -0
- package/scripts/utils/proc/package_scripts.mjs +38 -0
- package/scripts/utils/proc/package_scripts.test.mjs +58 -0
- package/scripts/utils/proc/parallel.mjs +25 -0
- package/scripts/utils/proc/pids.mjs +11 -0
- package/scripts/utils/proc/pm.mjs +478 -0
- package/scripts/utils/proc/pm_spawn.integration.test.mjs +131 -0
- package/scripts/utils/proc/pm_stack_cache_env.test.mjs +313 -0
- package/scripts/utils/proc/proc.mjs +331 -0
- package/scripts/utils/proc/proc.test.mjs +85 -0
- package/scripts/utils/proc/terminate.mjs +69 -0
- package/scripts/utils/proc/terminate.test.mjs +54 -0
- package/scripts/utils/proc/watch.mjs +63 -0
- package/scripts/utils/review/augment_runner_integration.test.mjs +105 -0
- package/scripts/utils/review/base_ref.mjs +82 -0
- package/scripts/utils/review/base_ref.test.mjs +89 -0
- package/scripts/utils/review/chunks.mjs +55 -0
- package/scripts/utils/review/chunks.test.mjs +107 -0
- package/scripts/utils/review/detached_worktree.mjs +61 -0
- package/scripts/utils/review/detached_worktree.test.mjs +61 -0
- package/scripts/utils/review/findings.mjs +278 -0
- package/scripts/utils/review/findings.test.mjs +203 -0
- package/scripts/utils/review/head_slice.mjs +132 -0
- package/scripts/utils/review/head_slice.test.mjs +117 -0
- package/scripts/utils/review/instructions/deep.md +20 -0
- package/scripts/utils/review/prompts.mjs +279 -0
- package/scripts/utils/review/prompts.test.mjs +77 -0
- package/scripts/utils/review/run_reviewers_safe.mjs +12 -0
- package/scripts/utils/review/run_reviewers_safe.test.mjs +45 -0
- package/scripts/utils/review/runners/augment.mjs +91 -0
- package/scripts/utils/review/runners/augment.test.mjs +64 -0
- package/scripts/utils/review/runners/claude.mjs +92 -0
- package/scripts/utils/review/runners/claude.test.mjs +47 -0
- package/scripts/utils/review/runners/coderabbit.mjs +105 -0
- package/scripts/utils/review/runners/coderabbit.test.mjs +32 -0
- package/scripts/utils/review/runners/codex.mjs +129 -0
- package/scripts/utils/review/runners/codex.test.mjs +115 -0
- package/scripts/utils/review/slice_mode.mjs +20 -0
- package/scripts/utils/review/slice_mode.test.mjs +69 -0
- package/scripts/utils/review/sliced_runner.mjs +39 -0
- package/scripts/utils/review/sliced_runner.test.mjs +57 -0
- package/scripts/utils/review/slices.mjs +140 -0
- package/scripts/utils/review/slices.test.mjs +41 -0
- package/scripts/utils/review/targets.mjs +23 -0
- package/scripts/utils/review/targets.test.mjs +31 -0
- package/scripts/utils/review/tool_home_seed.mjs +106 -0
- package/scripts/utils/review/tool_home_seed.test.mjs +124 -0
- package/scripts/utils/review/uncommitted_ops.mjs +77 -0
- package/scripts/utils/review/uncommitted_ops.test.mjs +117 -0
- package/scripts/utils/sandbox/review_pr_sandbox.mjs +105 -0
- package/scripts/utils/server/apply_server_light_env_defaults.mjs +14 -0
- package/scripts/utils/server/flavor_scripts.mjs +138 -0
- package/scripts/utils/server/flavor_scripts.test.mjs +115 -0
- package/scripts/utils/server/infra/happy_server_infra.mjs +444 -0
- package/scripts/utils/server/mobile_api_url.mjs +60 -0
- package/scripts/utils/server/mobile_api_url.test.mjs +58 -0
- package/scripts/utils/server/port.mjs +55 -0
- package/scripts/utils/server/prisma_import.mjs +36 -0
- package/scripts/utils/server/prisma_import.test.mjs +78 -0
- package/scripts/utils/server/server.mjs +109 -0
- package/scripts/utils/server/ui_build_check.mjs +37 -0
- package/scripts/utils/server/ui_build_check.test.mjs +70 -0
- package/scripts/utils/server/ui_env.mjs +13 -0
- package/scripts/utils/server/ui_env.test.mjs +57 -0
- package/scripts/utils/server/urls.mjs +100 -0
- package/scripts/utils/server/validate.mjs +60 -0
- package/scripts/utils/server/validate.test.mjs +76 -0
- package/scripts/utils/service/autostart_darwin.mjs +198 -0
- package/scripts/utils/service/autostart_darwin.test.mjs +49 -0
- package/scripts/utils/service/autostart_darwin_keepalive.test.mjs +19 -0
- package/scripts/utils/stack/cli_identities.mjs +29 -0
- package/scripts/utils/stack/context.mjs +19 -0
- package/scripts/utils/stack/dirs.mjs +26 -0
- package/scripts/utils/stack/editor_workspace.mjs +126 -0
- package/scripts/utils/stack/interactive_stack_config.mjs +266 -0
- package/scripts/utils/stack/interactive_stack_config.port_validation.test.mjs +93 -0
- package/scripts/utils/stack/interactive_stack_config.remote_validation.test.mjs +122 -0
- package/scripts/utils/stack/interactive_stack_config.stack_name_validation.test.mjs +76 -0
- package/scripts/utils/stack/interactive_stack_config_testkit.mjs +18 -0
- package/scripts/utils/stack/names.mjs +27 -0
- package/scripts/utils/stack/names.test.mjs +26 -0
- package/scripts/utils/stack/pr_stack_name.mjs +16 -0
- package/scripts/utils/stack/runtime_state.mjs +88 -0
- package/scripts/utils/stack/stacks.mjs +40 -0
- package/scripts/utils/stack/startup.mjs +370 -0
- package/scripts/utils/stack/startup_server_light_dirs.test.mjs +119 -0
- package/scripts/utils/stack/startup_server_light_generate.test.mjs +20 -0
- package/scripts/utils/stack/startup_server_light_legacy.test.mjs +79 -0
- package/scripts/utils/stack/startup_server_light_testkit.mjs +106 -0
- package/scripts/utils/stack/stop.mjs +284 -0
- package/scripts/utils/stack_context.mjs +1 -0
- package/scripts/utils/stack_runtime_state.mjs +1 -0
- package/scripts/utils/stacks.mjs +1 -0
- package/scripts/utils/tailscale/ip.mjs +116 -0
- package/scripts/utils/tauri/stack_overrides.mjs +22 -0
- package/scripts/utils/test/collect_test_files.mjs +29 -0
- package/scripts/utils/time/get_today_ymd.mjs +7 -0
- package/scripts/utils/tui/cleanup.mjs +38 -0
- package/scripts/utils/ui/ansi.mjs +47 -0
- package/scripts/utils/ui/browser.mjs +31 -0
- package/scripts/utils/ui/browser.test.mjs +56 -0
- package/scripts/utils/ui/clipboard.mjs +38 -0
- package/scripts/utils/ui/layout.mjs +44 -0
- package/scripts/utils/ui/qr.mjs +17 -0
- package/scripts/utils/ui/terminal_launcher.mjs +129 -0
- package/scripts/utils/ui/text.mjs +16 -0
- package/scripts/utils/update/auto_update_notice.mjs +93 -0
- package/scripts/utils/validate.mjs +5 -0
- package/scripts/where.mjs +138 -0
- package/scripts/worktrees.mjs +2174 -0
- package/scripts/worktrees_archive_cmd.integration.test.mjs +228 -0
- package/scripts/worktrees_cursor_monorepo_root.test.mjs +23 -0
- package/scripts/worktrees_list_specs_no_recurse.test.mjs +32 -0
- package/scripts/worktrees_monorepo_testkit.test.mjs +29 -0
- 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
|
+
|