@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,133 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# Open preferred terminal and run a hstack command.
|
|
5
|
+
#
|
|
6
|
+
# Preference order follows wt shell semantics:
|
|
7
|
+
# - HAPPIER_STACK_WT_TERMINAL=ghostty|iterm|terminal|current
|
|
8
|
+
# (also accepts "auto" which tries ghostty->iterm->terminal->current)
|
|
9
|
+
#
|
|
10
|
+
# Notes:
|
|
11
|
+
# - iTerm / Terminal: we run the command automatically via AppleScript.
|
|
12
|
+
# - Ghostty: best-effort; if we can't run the command, we open Ghostty in the dir and copy the command to clipboard.
|
|
13
|
+
|
|
14
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
15
|
+
DEFAULT_HOME_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
16
|
+
|
|
17
|
+
# Prefer explicit env vars, but default to the install location inferred from this script path.
|
|
18
|
+
CANONICAL_HOME_DIR="${HAPPIER_STACK_CANONICAL_HOME_DIR:-$DEFAULT_HOME_DIR}"
|
|
19
|
+
HOME_DIR="${HAPPIER_STACK_HOME_DIR:-$DEFAULT_HOME_DIR}"
|
|
20
|
+
|
|
21
|
+
export HAPPIER_STACK_HOME_DIR="$HOME_DIR"
|
|
22
|
+
export HAPPIER_STACK_CANONICAL_HOME_DIR="$CANONICAL_HOME_DIR"
|
|
23
|
+
|
|
24
|
+
# Prefer running against an explicit repo checkout if provided.
|
|
25
|
+
ROOT_DIR="${HAPPIER_STACK_CLI_ROOT_DIR:-$HOME_DIR}"
|
|
26
|
+
|
|
27
|
+
LIB_DIR="$ROOT_DIR/extras/swiftbar/lib"
|
|
28
|
+
if [[ -f "$LIB_DIR/utils.sh" ]]; then
|
|
29
|
+
# shellcheck source=/dev/null
|
|
30
|
+
source "$LIB_DIR/utils.sh"
|
|
31
|
+
fi
|
|
32
|
+
|
|
33
|
+
WORKDIR="${HAPPIER_STACK_WORKSPACE_DIR:-$(resolve_workspace_dir 2>/dev/null || true)}"
|
|
34
|
+
[[ -z "$WORKDIR" ]] && WORKDIR="$HOME_DIR/workspace"
|
|
35
|
+
if [[ ! -d "$WORKDIR" ]]; then
|
|
36
|
+
WORKDIR="$HOME"
|
|
37
|
+
fi
|
|
38
|
+
|
|
39
|
+
hstack_SH="$ROOT_DIR/extras/swiftbar/hstack.sh"
|
|
40
|
+
if [[ ! -x "$hstack_SH" ]]; then
|
|
41
|
+
echo "missing hstack wrapper: $hstack_SH" >&2
|
|
42
|
+
exit 1
|
|
43
|
+
fi
|
|
44
|
+
|
|
45
|
+
pref_raw="$(echo "${HAPPIER_STACK_WT_TERMINAL:-auto}" | tr '[:upper:]' '[:lower:]')"
|
|
46
|
+
pref="$pref_raw"
|
|
47
|
+
if [[ "$pref" == "" ]]; then pref="auto"; fi
|
|
48
|
+
|
|
49
|
+
cmd=( "$hstack_SH" "$@" )
|
|
50
|
+
|
|
51
|
+
escape_for_osascript_string() {
|
|
52
|
+
local s="$1"
|
|
53
|
+
s="${s//\\/\\\\}"
|
|
54
|
+
s="${s//\"/\\\"}"
|
|
55
|
+
echo "$s"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
shell_cmd() {
|
|
59
|
+
local joined=""
|
|
60
|
+
local q
|
|
61
|
+
joined="cd \"${WORKDIR//\"/\\\"}\"; "
|
|
62
|
+
for q in "${cmd[@]}"; do
|
|
63
|
+
local escaped
|
|
64
|
+
escaped="$(printf "%s" "$q" | sed "s/'/'\\\\''/g")"
|
|
65
|
+
joined+="'${escaped}' "
|
|
66
|
+
done
|
|
67
|
+
joined+="; echo; echo \"[hstack] done\"; exec /bin/zsh -i"
|
|
68
|
+
echo "$joined"
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
run_iterm() {
|
|
72
|
+
if ! command -v osascript >/dev/null 2>&1; then
|
|
73
|
+
return 1
|
|
74
|
+
fi
|
|
75
|
+
local s
|
|
76
|
+
s="$(shell_cmd)"
|
|
77
|
+
s="$(escape_for_osascript_string "$s")"
|
|
78
|
+
osascript \
|
|
79
|
+
-e 'tell application "iTerm" to activate' \
|
|
80
|
+
-e 'tell application "iTerm" to create window with default profile' \
|
|
81
|
+
-e "tell application \"iTerm\" to tell current session of current window to write text \"${s}\"" >/dev/null
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
run_terminal_app() {
|
|
85
|
+
if ! command -v osascript >/dev/null 2>&1; then
|
|
86
|
+
return 1
|
|
87
|
+
fi
|
|
88
|
+
local s
|
|
89
|
+
s="$(shell_cmd)"
|
|
90
|
+
s="$(escape_for_osascript_string "$s")"
|
|
91
|
+
osascript \
|
|
92
|
+
-e 'tell application "Terminal" to activate' \
|
|
93
|
+
-e "tell application \"Terminal\" to do script \"${s}\"" >/dev/null
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
run_ghostty() {
|
|
97
|
+
if ! command -v ghostty >/dev/null 2>&1; then
|
|
98
|
+
return 1
|
|
99
|
+
fi
|
|
100
|
+
|
|
101
|
+
local s
|
|
102
|
+
s="$(shell_cmd)"
|
|
103
|
+
if ghostty --working-directory "$WORKDIR" -e /bin/zsh -lc "$s" >/dev/null 2>&1; then
|
|
104
|
+
return 0
|
|
105
|
+
fi
|
|
106
|
+
|
|
107
|
+
echo -n "$s" | pbcopy 2>/dev/null || true
|
|
108
|
+
ghostty --working-directory "$WORKDIR" >/dev/null 2>&1 || true
|
|
109
|
+
return 0
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
try_one() {
|
|
113
|
+
local t="$1"
|
|
114
|
+
case "$t" in
|
|
115
|
+
ghostty) run_ghostty ;;
|
|
116
|
+
iterm) run_iterm ;;
|
|
117
|
+
terminal) run_terminal_app ;;
|
|
118
|
+
current) ( cd "$WORKDIR"; exec "${cmd[@]}" ) ;;
|
|
119
|
+
*) return 1 ;;
|
|
120
|
+
esac
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
if [[ "$pref" == "auto" ]]; then
|
|
124
|
+
for t in ghostty iterm terminal current; do
|
|
125
|
+
if try_one "$t"; then
|
|
126
|
+
exit 0
|
|
127
|
+
fi
|
|
128
|
+
done
|
|
129
|
+
exit 1
|
|
130
|
+
fi
|
|
131
|
+
|
|
132
|
+
try_one "$pref"
|
|
133
|
+
|
|
@@ -0,0 +1,296 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
|
|
3
|
+
# <xbar.title>hstack</xbar.title>
|
|
4
|
+
# <xbar.version>1.0.0</xbar.version>
|
|
5
|
+
# <xbar.author>hstack</xbar.author>
|
|
6
|
+
# <xbar.author.github>happier-dev</xbar.author.github>
|
|
7
|
+
# <xbar.desc>Monitor and control your Happier stacks from the menu bar</xbar.desc>
|
|
8
|
+
# <xbar.dependencies>node</xbar.dependencies>
|
|
9
|
+
# <swiftbar.hideAbout>true</swiftbar.hideAbout>
|
|
10
|
+
# <swiftbar.hideRunInTerminal>true</swiftbar.hideRunInTerminal>
|
|
11
|
+
# <swiftbar.hideLastUpdated>false</swiftbar.hideLastUpdated>
|
|
12
|
+
# <swiftbar.hideDisablePlugin>true</swiftbar.hideDisablePlugin>
|
|
13
|
+
# <swiftbar.hideSwiftBar>true</swiftbar.hideSwiftBar>
|
|
14
|
+
# <swiftbar.refreshOnOpen>false</swiftbar.refreshOnOpen>
|
|
15
|
+
|
|
16
|
+
# ============================================================================
|
|
17
|
+
# Configuration
|
|
18
|
+
# ============================================================================
|
|
19
|
+
|
|
20
|
+
# SwiftBar runs with a minimal environment, so users often won't have
|
|
21
|
+
# HAPPIER_STACK_HOME_DIR / HAPPIER_STACK_WORKSPACE_DIR exported.
|
|
22
|
+
# Treat <canonicalHomeDir>/.env as the canonical pointer file (written by `hstack init`).
|
|
23
|
+
# Default: ~/.happier-stack/.env
|
|
24
|
+
CANONICAL_HOME_DIR="${HAPPIER_STACK_CANONICAL_HOME_DIR:-$HOME/.happier-stack}"
|
|
25
|
+
CANONICAL_ENV_FILE="$CANONICAL_HOME_DIR/.env"
|
|
26
|
+
|
|
27
|
+
_dotenv_get_quick() {
|
|
28
|
+
# Usage: _dotenv_get_quick /path/to/env KEY
|
|
29
|
+
local file="$1"
|
|
30
|
+
local key="$2"
|
|
31
|
+
[[ -n "$file" && -n "$key" && -f "$file" ]] || return 0
|
|
32
|
+
local line
|
|
33
|
+
line="$(grep -E "^${key}=" "$file" 2>/dev/null | head -n 1 || true)"
|
|
34
|
+
[[ -n "$line" ]] || return 0
|
|
35
|
+
local v="${line#*=}"
|
|
36
|
+
v="${v%$'\r'}"
|
|
37
|
+
# Strip simple surrounding quotes.
|
|
38
|
+
if [[ "$v" == \"*\" && "$v" == *\" ]]; then v="${v#\"}"; v="${v%\"}"; fi
|
|
39
|
+
if [[ "$v" == \'*\' && "$v" == *\' ]]; then v="${v#\'}"; v="${v%\'}"; fi
|
|
40
|
+
echo "$v"
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
_expand_home_quick() {
|
|
44
|
+
local p="$1"
|
|
45
|
+
if [[ "$p" == "~/"* ]]; then
|
|
46
|
+
echo "$HOME/${p#~/}"
|
|
47
|
+
else
|
|
48
|
+
echo "$p"
|
|
49
|
+
fi
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
_home_from_canonical=""
|
|
53
|
+
if [[ -f "$CANONICAL_ENV_FILE" ]]; then
|
|
54
|
+
_home_from_canonical="$(_dotenv_get_quick "$CANONICAL_ENV_FILE" "HAPPIER_STACK_HOME_DIR")"
|
|
55
|
+
fi
|
|
56
|
+
_home_from_canonical="$(_expand_home_quick "${_home_from_canonical:-}")"
|
|
57
|
+
|
|
58
|
+
export HAPPIER_STACK_HOME_DIR="${HAPPIER_STACK_HOME_DIR:-${_home_from_canonical:-$CANONICAL_HOME_DIR}}"
|
|
59
|
+
export HAPPIER_STACK_CANONICAL_HOME_DIR="$CANONICAL_HOME_DIR"
|
|
60
|
+
|
|
61
|
+
# Colors
|
|
62
|
+
GREEN="#34C759"
|
|
63
|
+
RED="#FF3B30"
|
|
64
|
+
YELLOW="#FFCC00"
|
|
65
|
+
GRAY="#8E8E93"
|
|
66
|
+
BLUE="#007AFF"
|
|
67
|
+
|
|
68
|
+
# ============================================================================
|
|
69
|
+
# Load libs
|
|
70
|
+
# ============================================================================
|
|
71
|
+
|
|
72
|
+
hstack_ROOT_DIR="${HAPPIER_STACK_CLI_ROOT_DIR:-$HAPPIER_STACK_HOME_DIR}"
|
|
73
|
+
LIB_DIR="$hstack_ROOT_DIR/extras/swiftbar/lib"
|
|
74
|
+
if [[ ! -f "$LIB_DIR/utils.sh" ]]; then
|
|
75
|
+
echo "hstack"
|
|
76
|
+
echo "---"
|
|
77
|
+
echo "SwiftBar libs missing at: $LIB_DIR"
|
|
78
|
+
echo "↪ run: hstack menubar install"
|
|
79
|
+
exit 0
|
|
80
|
+
fi
|
|
81
|
+
|
|
82
|
+
# shellcheck source=/dev/null
|
|
83
|
+
source "$LIB_DIR/utils.sh"
|
|
84
|
+
hstack_ROOT_DIR="$(resolve_hstack_root_dir)"
|
|
85
|
+
LIB_DIR="$hstack_ROOT_DIR/extras/swiftbar/lib"
|
|
86
|
+
# shellcheck source=/dev/null
|
|
87
|
+
source "$LIB_DIR/icons.sh"
|
|
88
|
+
# shellcheck source=/dev/null
|
|
89
|
+
source "$LIB_DIR/system.sh"
|
|
90
|
+
# shellcheck source=/dev/null
|
|
91
|
+
source "$LIB_DIR/git.sh"
|
|
92
|
+
# shellcheck source=/dev/null
|
|
93
|
+
source "$LIB_DIR/render.sh"
|
|
94
|
+
|
|
95
|
+
# ============================================================================
|
|
96
|
+
# Menu
|
|
97
|
+
# ============================================================================
|
|
98
|
+
|
|
99
|
+
hstack_BIN="$(resolve_hstack_bin)"
|
|
100
|
+
hstack_TERM="$hstack_ROOT_DIR/extras/swiftbar/hstack-term.sh"
|
|
101
|
+
MAIN_PORT="$(resolve_main_port)"
|
|
102
|
+
MAIN_SERVER_COMPONENT="$(resolve_main_server_component)"
|
|
103
|
+
TAILSCALE_URL="$(get_tailscale_url)"
|
|
104
|
+
if swiftbar_is_sandboxed; then
|
|
105
|
+
# Never probe Tailscale (global machine state) when sandboxing.
|
|
106
|
+
TAILSCALE_URL=""
|
|
107
|
+
fi
|
|
108
|
+
MAIN_ENV_FILE="$(resolve_main_env_file)"
|
|
109
|
+
MENUBAR_MODE="$(resolve_menubar_mode)"
|
|
110
|
+
|
|
111
|
+
ensure_launchctl_cache
|
|
112
|
+
|
|
113
|
+
if [[ -z "$MAIN_ENV_FILE" ]]; then
|
|
114
|
+
MAIN_ENV_FILE="$(resolve_stack_env_file main)"
|
|
115
|
+
fi
|
|
116
|
+
HAPPIER_HOME_DIR="$(resolve_stack_base_dir main "$MAIN_ENV_FILE")"
|
|
117
|
+
CLI_HOME_DIR="$(resolve_stack_cli_home_dir main "$MAIN_ENV_FILE")"
|
|
118
|
+
LOGS_DIR="$HAPPIER_HOME_DIR/logs"
|
|
119
|
+
MAIN_LABEL="$(resolve_stack_label main)"
|
|
120
|
+
|
|
121
|
+
MAIN_COLLECT="$(collect_stack_status "$MAIN_PORT" "$CLI_HOME_DIR" "$MAIN_LABEL" "$HAPPIER_HOME_DIR")"
|
|
122
|
+
IFS=$'\t' read -r MAIN_LEVEL MAIN_SERVER_STATUS MAIN_SERVER_PID MAIN_SERVER_METRICS MAIN_DAEMON_STATUS MAIN_DAEMON_PID MAIN_DAEMON_METRICS MAIN_DAEMON_UPTIME MAIN_LAST_HEARTBEAT MAIN_LAUNCHAGENT_STATUS MAIN_AUTOSTART_PID MAIN_AUTOSTART_METRICS <<<"$MAIN_COLLECT"
|
|
123
|
+
for v in MAIN_SERVER_PID MAIN_SERVER_METRICS MAIN_DAEMON_PID MAIN_DAEMON_METRICS MAIN_DAEMON_UPTIME MAIN_LAST_HEARTBEAT MAIN_AUTOSTART_PID MAIN_AUTOSTART_METRICS; do
|
|
124
|
+
if [[ "${!v}" == "-" ]]; then
|
|
125
|
+
printf -v "$v" '%s' ""
|
|
126
|
+
fi
|
|
127
|
+
done
|
|
128
|
+
|
|
129
|
+
# Menu bar icon
|
|
130
|
+
MENU_STATUS_ICON_B64="$(status_icon_b64 "$MAIN_LEVEL" 18)"
|
|
131
|
+
if [[ -n "$MENU_STATUS_ICON_B64" ]]; then
|
|
132
|
+
echo " | image=$MENU_STATUS_ICON_B64"
|
|
133
|
+
else
|
|
134
|
+
STATUS_COLOR="$(color_for_level "$MAIN_LEVEL")"
|
|
135
|
+
ICON_B64="$(get_menu_icon_b64)"
|
|
136
|
+
if [[ -n "$ICON_B64" ]]; then
|
|
137
|
+
echo "● | templateImage=$ICON_B64 color=$STATUS_COLOR"
|
|
138
|
+
else
|
|
139
|
+
echo "hstack"
|
|
140
|
+
fi
|
|
141
|
+
fi
|
|
142
|
+
|
|
143
|
+
echo "---"
|
|
144
|
+
echo "hstack | size=14 font=SF Pro Display"
|
|
145
|
+
echo "---"
|
|
146
|
+
|
|
147
|
+
# Mode (selfhost vs dev)
|
|
148
|
+
if [[ "$MENUBAR_MODE" == "selfhost" ]]; then
|
|
149
|
+
echo "Mode: Selfhost | sfimage=house"
|
|
150
|
+
else
|
|
151
|
+
echo "Mode: Dev | sfimage=hammer"
|
|
152
|
+
fi
|
|
153
|
+
if [[ -n "$hstack_BIN" ]]; then
|
|
154
|
+
if [[ "$MENUBAR_MODE" == "selfhost" ]]; then
|
|
155
|
+
echo "--Switch to Dev mode | bash=$hstack_BIN param1=menubar param2=mode param3=dev dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
156
|
+
else
|
|
157
|
+
echo "--Switch to Selfhost mode | bash=$hstack_BIN param1=menubar param2=mode param3=selfhost dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
158
|
+
fi
|
|
159
|
+
fi
|
|
160
|
+
echo "---"
|
|
161
|
+
|
|
162
|
+
# Main stack (inline)
|
|
163
|
+
echo "Main stack"
|
|
164
|
+
echo "---"
|
|
165
|
+
export MAIN_LEVEL="$MAIN_LEVEL"
|
|
166
|
+
render_stack_info "" "main" "$MAIN_PORT" "$MAIN_SERVER_COMPONENT" "$HAPPIER_HOME_DIR" "$CLI_HOME_DIR" "$MAIN_LABEL" "$MAIN_ENV_FILE" "$TAILSCALE_URL" "$MAIN_SERVER_METRICS" "$MAIN_DAEMON_METRICS" "$MAIN_AUTOSTART_METRICS"
|
|
167
|
+
render_component_server "" "main" "$MAIN_PORT" "$MAIN_SERVER_COMPONENT" "$MAIN_SERVER_STATUS" "$MAIN_SERVER_PID" "$MAIN_SERVER_METRICS" "$TAILSCALE_URL" "$MAIN_LABEL"
|
|
168
|
+
render_component_daemon "" "$MAIN_DAEMON_STATUS" "$MAIN_DAEMON_PID" "$MAIN_DAEMON_METRICS" "$MAIN_DAEMON_UPTIME" "$MAIN_LAST_HEARTBEAT" "$CLI_HOME_DIR/daemon.state.json" "main"
|
|
169
|
+
render_component_autostart "" "main" "$MAIN_LABEL" "$MAIN_LAUNCHAGENT_STATUS" "$MAIN_AUTOSTART_PID" "$MAIN_AUTOSTART_METRICS" "$LOGS_DIR"
|
|
170
|
+
render_component_tailscale "" "main" "$TAILSCALE_URL"
|
|
171
|
+
|
|
172
|
+
echo "---"
|
|
173
|
+
if [[ "$MENUBAR_MODE" == "selfhost" ]]; then
|
|
174
|
+
echo "Maintenance | sfimage=wrench.and.screwdriver"
|
|
175
|
+
if [[ -n "$hstack_BIN" ]]; then
|
|
176
|
+
UPDATE_JSON="${hstack_ROOT_DIR}/cache/update.json"
|
|
177
|
+
update_available=""
|
|
178
|
+
latest=""
|
|
179
|
+
current=""
|
|
180
|
+
if [[ -f "$UPDATE_JSON" ]]; then
|
|
181
|
+
update_available="$(grep -oE '\"updateAvailable\"[[:space:]]*:[[:space:]]*(true|false)' "$UPDATE_JSON" 2>/dev/null | head -1 | grep -oE '(true|false)' || true)"
|
|
182
|
+
latest="$(grep -oE '\"latest\"[[:space:]]*:[[:space:]]*\"[^\"]+\"' "$UPDATE_JSON" 2>/dev/null | head -1 | sed -E 's/.*\"latest\"[[:space:]]*:[[:space:]]*\"([^\"]+)\".*/\\1/' || true)"
|
|
183
|
+
current="$(grep -oE '\"current\"[[:space:]]*:[[:space:]]*\"[^\"]+\"' "$UPDATE_JSON" 2>/dev/null | head -1 | sed -E 's/.*\"current\"[[:space:]]*:[[:space:]]*\"([^\"]+)\".*/\\1/' || true)"
|
|
184
|
+
fi
|
|
185
|
+
if [[ "$update_available" == "true" && -n "$latest" ]]; then
|
|
186
|
+
echo "--Update available: ${current:-current} → ${latest} | color=$YELLOW"
|
|
187
|
+
else
|
|
188
|
+
echo "--Updates: up to date | color=$GRAY"
|
|
189
|
+
fi
|
|
190
|
+
echo "--Check for updates | bash=$hstack_BIN param1=self param2=check dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
191
|
+
echo "--Update hstack runtime | bash=$hstack_BIN param1=self param2=update dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
192
|
+
echo "--Doctor | bash=$hstack_BIN param1=doctor dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
193
|
+
else
|
|
194
|
+
echo "--⚠️ hstack not found (run: npx @happier-dev/stack@latest init)"
|
|
195
|
+
fi
|
|
196
|
+
else
|
|
197
|
+
echo "Stacks | sfimage=server.rack"
|
|
198
|
+
STACKS_PREFIX="--"
|
|
199
|
+
|
|
200
|
+
if [[ -n "$hstack_BIN" ]]; then
|
|
201
|
+
echo "${STACKS_PREFIX}New stack (interactive) | bash=$hstack_TERM param1=stack param2=new param3=--interactive dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
202
|
+
echo "${STACKS_PREFIX}List stacks | bash=$hstack_TERM param1=stack param2=list dir=$hstack_ROOT_DIR terminal=false"
|
|
203
|
+
print_sep "$STACKS_PREFIX"
|
|
204
|
+
fi
|
|
205
|
+
|
|
206
|
+
STACKS_DIR="$(resolve_stacks_storage_root)"
|
|
207
|
+
if [[ -d "$STACKS_DIR" ]]; then
|
|
208
|
+
STACK_NAMES="$(
|
|
209
|
+
{
|
|
210
|
+
ls -1 "$STACKS_DIR" 2>/dev/null || true
|
|
211
|
+
} | sort -u
|
|
212
|
+
)"
|
|
213
|
+
if [[ -z "$STACK_NAMES" ]]; then
|
|
214
|
+
echo "${STACKS_PREFIX}No stacks found | color=$GRAY"
|
|
215
|
+
fi
|
|
216
|
+
for s in $STACK_NAMES; do
|
|
217
|
+
env_file="$(resolve_stack_env_file "$s")"
|
|
218
|
+
[[ -f "$env_file" ]] || continue
|
|
219
|
+
|
|
220
|
+
# Ports may be ephemeral (runtime-only). Do not skip stacks if the env file does not pin a port.
|
|
221
|
+
port="$(resolve_stack_server_port "$s" "$env_file")"
|
|
222
|
+
|
|
223
|
+
server_component="$(dotenv_get "$env_file" "HAPPIER_STACK_SERVER_COMPONENT")"
|
|
224
|
+
[[ -n "$server_component" ]] || server_component="happier-server-light"
|
|
225
|
+
|
|
226
|
+
base_dir="$(resolve_stack_base_dir "$s" "$env_file")"
|
|
227
|
+
cli_home_dir="$(resolve_stack_cli_home_dir "$s" "$env_file")"
|
|
228
|
+
label="$(resolve_stack_label "$s")"
|
|
229
|
+
|
|
230
|
+
COLLECT="$(collect_stack_status "$port" "$cli_home_dir" "$label" "$base_dir")"
|
|
231
|
+
IFS=$'\t' read -r LEVEL SERVER_STATUS SERVER_PID SERVER_METRICS DAEMON_STATUS DAEMON_PID DAEMON_METRICS DAEMON_UPTIME LAST_HEARTBEAT LAUNCHAGENT_STATUS AUTOSTART_PID AUTOSTART_METRICS <<<"$COLLECT"
|
|
232
|
+
for v in SERVER_PID SERVER_METRICS DAEMON_PID DAEMON_METRICS DAEMON_UPTIME LAST_HEARTBEAT AUTOSTART_PID AUTOSTART_METRICS; do
|
|
233
|
+
if [[ "${!v}" == "-" ]]; then
|
|
234
|
+
printf -v "$v" '%s' ""
|
|
235
|
+
fi
|
|
236
|
+
done
|
|
237
|
+
|
|
238
|
+
render_stack_overview_item "Stack: $s" "$LEVEL" "$STACKS_PREFIX"
|
|
239
|
+
export STACK_LEVEL="$LEVEL"
|
|
240
|
+
render_stack_info "${STACKS_PREFIX}--" "$s" "$port" "$server_component" "$base_dir" "$cli_home_dir" "$label" "$env_file" "" "$SERVER_METRICS" "$DAEMON_METRICS" "$AUTOSTART_METRICS"
|
|
241
|
+
render_component_server "${STACKS_PREFIX}--" "$s" "$port" "$server_component" "$SERVER_STATUS" "$SERVER_PID" "$SERVER_METRICS" "" "$label"
|
|
242
|
+
render_component_daemon "${STACKS_PREFIX}--" "$DAEMON_STATUS" "$DAEMON_PID" "$DAEMON_METRICS" "$DAEMON_UPTIME" "$LAST_HEARTBEAT" "$cli_home_dir/daemon.state.json" "$s"
|
|
243
|
+
render_component_autostart "${STACKS_PREFIX}--" "$s" "$label" "$LAUNCHAGENT_STATUS" "$AUTOSTART_PID" "$AUTOSTART_METRICS" "$base_dir/logs"
|
|
244
|
+
render_component_tailscale "${STACKS_PREFIX}--" "$s" ""
|
|
245
|
+
render_components_menu "${STACKS_PREFIX}--" "stack" "$s" "$env_file"
|
|
246
|
+
done
|
|
247
|
+
else
|
|
248
|
+
echo "${STACKS_PREFIX}No stacks dir found at: $(shorten_path "$STACKS_DIR" 52) | color=$GRAY"
|
|
249
|
+
fi
|
|
250
|
+
|
|
251
|
+
echo "---"
|
|
252
|
+
render_components_menu "" "main" "main" "$MAIN_ENV_FILE"
|
|
253
|
+
|
|
254
|
+
echo "Worktrees | sfimage=arrow.triangle.branch"
|
|
255
|
+
if [[ -z "$hstack_BIN" ]]; then
|
|
256
|
+
echo "--⚠️ hstack not found (run: npx @happier-dev/stack@latest init)"
|
|
257
|
+
else
|
|
258
|
+
echo "--Use (interactive) | bash=$hstack_TERM param1=wt param2=use param3=--interactive dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
259
|
+
echo "--New (interactive) | bash=$hstack_TERM param1=wt param2=new param3=--interactive dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
260
|
+
echo "--PR worktree (prompt) | bash=$hstack_ROOT_DIR/extras/swiftbar/wt-pr.sh dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
261
|
+
echo "--Sync mirrors (all) | bash=$hstack_BIN param1=wt param2=sync-all dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
262
|
+
echo "--Update all (dry-run) | bash=$hstack_TERM param1=wt param2=update-all param3=--dry-run dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
263
|
+
echo "--Update all (apply) | bash=$hstack_BIN param1=wt param2=update-all dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
264
|
+
fi
|
|
265
|
+
|
|
266
|
+
echo "---"
|
|
267
|
+
echo "Setup / Tools"
|
|
268
|
+
if [[ -z "$hstack_BIN" ]]; then
|
|
269
|
+
echo "--⚠️ hstack not found (run: npx @happier-dev/stack@latest init)"
|
|
270
|
+
else
|
|
271
|
+
echo "--Setup (guided) | bash=$hstack_TERM param1=setup dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
272
|
+
echo "--Bootstrap (clone/install) | bash=$hstack_TERM param1=bootstrap dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
273
|
+
echo "--CLI link (install happier wrapper) | bash=$hstack_TERM param1=cli:link dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
274
|
+
echo "--Mobile dev helper | bash=$hstack_TERM param1=mobile dir=$hstack_ROOT_DIR terminal=false"
|
|
275
|
+
fi
|
|
276
|
+
fi
|
|
277
|
+
|
|
278
|
+
echo "---"
|
|
279
|
+
echo "Refresh | sfimage=arrow.clockwise refresh=true"
|
|
280
|
+
echo "---"
|
|
281
|
+
echo "Refresh interval | sfimage=timer"
|
|
282
|
+
SET_INTERVAL="$hstack_ROOT_DIR/extras/swiftbar/set-interval.sh"
|
|
283
|
+
echo "--10s | bash=$SET_INTERVAL param1=10s dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
284
|
+
echo "--30s | bash=$SET_INTERVAL param1=30s dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
285
|
+
echo "--1m | bash=$SET_INTERVAL param1=1m dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
286
|
+
echo "--5m (recommended) | bash=$SET_INTERVAL param1=5m dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
287
|
+
echo "--10m | bash=$SET_INTERVAL param1=10m dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
288
|
+
echo "--15m | bash=$SET_INTERVAL param1=15m dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
289
|
+
echo "--30m | bash=$SET_INTERVAL param1=30m dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
290
|
+
echo "--1h | bash=$SET_INTERVAL param1=1h dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
291
|
+
echo "--2h | bash=$SET_INTERVAL param1=2h dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
292
|
+
echo "--6h | bash=$SET_INTERVAL param1=6h dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
293
|
+
echo "--12h | bash=$SET_INTERVAL param1=12h dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
294
|
+
echo "--1d | bash=$SET_INTERVAL param1=1d dir=$hstack_ROOT_DIR terminal=false refresh=true"
|
|
295
|
+
|
|
296
|
+
exit 0
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
#!/bin/bash
|
|
2
|
+
set -euo pipefail
|
|
3
|
+
|
|
4
|
+
# SwiftBar menu action wrapper.
|
|
5
|
+
# Runs `hstack` using the stable shim installed under <homeDir>/bin.
|
|
6
|
+
|
|
7
|
+
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
8
|
+
DEFAULT_HOME_DIR="$(cd "$SCRIPT_DIR/../.." && pwd)"
|
|
9
|
+
|
|
10
|
+
# Prefer explicit env vars, but default to the install location inferred from this script path.
|
|
11
|
+
CANONICAL_HOME_DIR="${HAPPIER_STACK_CANONICAL_HOME_DIR:-$DEFAULT_HOME_DIR}"
|
|
12
|
+
CANONICAL_ENV_FILE="${CANONICAL_HOME_DIR%/}/.env"
|
|
13
|
+
|
|
14
|
+
HOME_DIR="${HAPPIER_STACK_HOME_DIR:-}"
|
|
15
|
+
if [[ -z "$HOME_DIR" && -f "$CANONICAL_ENV_FILE" ]]; then
|
|
16
|
+
HOME_DIR="$(grep -E '^HAPPIER_STACK_HOME_DIR=' "$CANONICAL_ENV_FILE" 2>/dev/null | head -n 1 | sed 's/^HAPPIER_STACK_HOME_DIR=//' || true)"
|
|
17
|
+
fi
|
|
18
|
+
HOME_DIR="${HOME_DIR:-$DEFAULT_HOME_DIR}"
|
|
19
|
+
|
|
20
|
+
export HAPPIER_STACK_HOME_DIR="$HOME_DIR"
|
|
21
|
+
export HAPPIER_STACK_CANONICAL_HOME_DIR="$CANONICAL_HOME_DIR"
|
|
22
|
+
|
|
23
|
+
hstack_BIN="$HOME_DIR/bin/hstack"
|
|
24
|
+
|
|
25
|
+
if [[ ! -x "$hstack_BIN" ]]; then
|
|
26
|
+
# Fall back to PATH (best-effort).
|
|
27
|
+
hstack_BIN="$(command -v hstack 2>/dev/null || true)"
|
|
28
|
+
fi
|
|
29
|
+
|
|
30
|
+
if [[ -z "${hstack_BIN:-}" ]]; then
|
|
31
|
+
echo "hstack not found. Run: npx @happier-dev/stack@latest init" >&2
|
|
32
|
+
exit 1
|
|
33
|
+
fi
|
|
34
|
+
|
|
35
|
+
exec "$hstack_BIN" "$@"
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|