hack.foo
Reference

Command reference

This reference omits the retired agent instruction-management commands (hack setup sync, standalone hack setup exports and hack agent prime), which refuse in v5. See Agent integrations for the opt-in plugin and MCP setup.

Run hack help <command> for the same content in the terminal. Global options: --no-interactive (or HACK_NO_INTERACTIVE=1); JSON shapes vary by command and backend. See Command and output contracts for envelopes, bare reports and streamed records.

Project

hack project

Inspect or manage project metadata

Usage

hack project <subcommand> [options]

Subcommands

CommandSummary
hack project ownerInspect project ownership
hack project targetInspect the exact project, checkout, instance and service a command would target (read-only, provisional)
hack project taskDiscover reviewed task recipes without running them (read-only, provisional)

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack project owner

Inspect project ownership

Usage

hack project owner <subcommand> [options]

Subcommands

CommandSummary
hack project owner showShow the local ownership metadata for the current project

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack project target

Inspect the exact project, checkout, instance and service a command would target (read-only, provisional)

Usage

hack project target [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--service <service>Also resolve one Compose service of the target
`--env <namebase
--expect-generation <id>Refuse unless the project's config generation still equals this id
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack project task

Discover reviewed task recipes without running them (read-only, provisional)

Usage

hack project task <subcommand> [options]

Subcommands

CommandSummary
hack project task listList reviewed task recipes and refusals for the target (read-only, provisional; runs nothing)
hack project task inspect <task>Show one reviewed task recipe: argv, service, env scope, effects and pins (read-only, provisional; runs nothing)

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack init

Initialize a repo (generate .hack/ with compose + config)

Usage

hack init [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--manualSkip discovery and define services manually (or generate a minimal compose in --auto)
--autoRun non-interactive init with sensible defaults
--name <slug>Project slug (default: repo name)
--dev-host <host>DEV_HOST override (new projects use global default_domain, or hack.local)
--oauthEnable OAuth-safe alias host
--oauth-tld <tld>OAuth alias TLD override (default: gy)
--no-discoverySkip discovery and generate a minimal compose
`--with <claudecodex>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack up [services...]

Start project services (docker compose up)

Usage

hack up [services...] [options]

Arguments

ArgDescription
services

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--detach, -dRun in background (docker compose up -d)
--profile <name[,name...]>Enable one or more compose profiles (comma-separated)
`--target <autolocal
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack down

Stop project services (docker compose down)

Usage

hack down [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--profile <name[,name...]>Enable one or more compose profiles (comma-separated)
`--target <autolocal
--prune-cachesAfter down, remove confirmed Compose-owned disposable cache volumes
--remove-dataNative backend: delete a stopped project's owned data volumes so the next up starts fresh (asks first)
--yesConfirm --prune-caches or --remove-data without prompting
--jsonOutput JSON (machine-readable)
--recoverExplicitly reconcile an interrupted native stop, or stop the services of a native run whose foreground owner exited, while retaining data
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack restart [services...]

Restart the project or selected services

Usage

hack restart [services...] [options]

Arguments

ArgDescription
services

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--profile <name[,name...]>Enable one or more compose profiles (comma-separated)
`--target <autolocal
--jsonOutput JSON (machine-readable)
--recover-frontendRecover an interrupted native frontend after proving its owner and effects are gone
--expect-finalization-attempt <32-hex>Require this exact interrupted native frontend attempt
--expect-frontend-pid <pid>Previously observed frontend PID (required only for legacy v1 state)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack ps

Show project status (docker compose ps)

Usage

hack ps [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--profile <name[,name...]>Enable one or more compose profiles (comma-separated)
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack tui

Open the project TUI (services + logs)

Usage

hack tui [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack run <service> [cmd...]

Run a one-off command in a service container (docker compose run --rm)

Usage

hack run [options] <service> [cmd...]

Everything from <cmd> on is passed to the command unchanged, including flags such as --version or --help. Put Hack options before it; a leading -- is optional.

Arguments

ArgDescription
service
cmd

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--workdir <path>Working directory inside the container (docker compose run -w)
--profile <name[,name...]>Enable one or more compose profiles (comma-separated)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack exec <service> [cmd...]

Run a command in an already-running service container (docker compose exec)

Usage

hack exec [options] <service> [cmd...]

Everything from <cmd> on is passed to the command unchanged, including flags such as --version or --help. Put Hack options before it; a leading -- is optional.

Arguments

ArgDescription
service
cmd

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--workdir <path>Working directory inside the container (docker compose run -w)
--profile <name[,name...]>Enable one or more compose profiles (comma-separated)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack logs [service]

Tail logs (compose by default; Loki for queries/history via --loki/--query)

Usage

hack logs [service] [options]

Arguments

ArgDescription
service

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--follow, -fFollow logs (default for hack logs)
--no-followPrint logs and exit (do not follow)
--tail <n>Tail last N log lines (default: 200)
--prettyPretty-print logs (best-effort JSON parsing + formatting)
--jsonOutput JSON (machine-readable)
--profile <name[,name...]>Enable one or more compose profiles (comma-separated)
--composeRead logs directly from docker compose (bypass Loki)
--lokiForce Loki backend (do not fall back to docker compose logs)
--services <csv>Filter Loki logs by service(s), comma-separated (e.g. api,www)
--query <logql>Raw LogQL selector/query (overrides auto selector built from project + services)
--since <time>Start time for Loki logs (RFC3339 or duration like 15m)
--until <time>End time for Loki logs (RFC3339 or duration like 15m)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack open [target]

Open a project URL (OAuth alias by default when enabled; otherwise dev host)

Usage

hack open [target] [options]

Arguments

ArgDescription
target

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--branch <name>Run against a branch-specific instance (compose name + hostnames)
`--prefer <autoalias
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack branch

Manage branch aliases for a project

Usage

hack branch <subcommand> [options]

Subcommands

CommandSummary
hack branch add <name>Register a branch alias for this project
hack branch listList registered branch aliases for this project
hack branch remove <name>Remove a branch alias for this project
hack branch open <name>Open the branch host in a browser

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack branch add <name>

Register a branch alias for this project

Usage

hack branch add <name> [options]

Arguments

ArgDescription
name

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--note <text>Optional note for the branch entry
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack branch list

List registered branch aliases for this project

Usage

hack branch list [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack branch remove <name>

Remove a branch alias for this project

Usage

hack branch remove <name> [options]

Arguments

ArgDescription
name

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack branch open <name>

Open the branch host in a browser

Usage

hack branch open <name> [options]

Arguments

ArgDescription
name

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--prefer <autoalias
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack config

Read/write legacy config or validate native project configuration

Usage

hack config <subcommand> [options]

Subcommands

CommandSummary
hack config get <key>Read a value from hack.config.json
hack config set <key> <value>Update a value in hack.config.json
hack config validateValidate native configuration and selected local overlays without starting workloads
hack config planInspect native environment binding completeness without decrypting or starting workloads
hack config importPreview a bounded legacy config and Compose conversion without writes
hack config adoptExplicitly adopt a stopped, verified existing Compose instance

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack config get <key>

Read a value from hack.config.json

Usage

hack config get <key> [options]

Arguments

ArgDescription
key

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--globalRead/write global ~/.hack/hack.config.json
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack config set <key> <value>

Update a value in hack.config.json

Usage

hack config set <key> <value> [options]

Arguments

ArgDescription
key
value

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--globalRead/write global ~/.hack/hack.config.json
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack config validate

Validate native configuration and selected local overlays without starting workloads

Usage

hack config validate [options]

Uses the matching bundled Rust compiler. Without --file, discovers a native project and resolves permitted worktree-local overlay and routing settings. --file validates only the explicit document. With HACK_RUNTIME_BACKEND=native, a selected workload image that is not a sha256: content ID refuses with the native consumer's native_graph_admission code. Neither mode reads env values, writes state, or starts workloads.

Options

OptionDescription
--file <path>Validate only this native project JSON file, without discovery or local overrides
--profile <names>Comma-separated declared native profiles
--domain <suffix>Select the generated native routing domain suffix
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
`--env <namebase
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack config plan

Inspect native environment binding completeness without decrypting or starting workloads

Usage

hack config plan [options]

Resolves the native project, permitted local env selection and routing preview, then inspects managed-env names, winning scopes and secret flags. Managed YAML is parsed by its existing owner; keys and values are never decrypted or returned. Required unresolved refs return a nonzero exit. This experimental report does not establish runtime admission or enable native execution; use config validate for validation without managed-document reads.

Options

OptionDescription
--profile <names>Comma-separated declared native profiles
--domain <suffix>Select the generated native routing domain suffix
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
`--env <namebase
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack config import

Preview a bounded legacy config and Compose conversion without writes

Usage

hack config import [options]

Requires --dry-run. Inspects the exact .hack/hack.config.json and docker-compose.yml pair, reports field mappings/refusals, and validates complete private candidates in memory. Does not export a draft, adopt resources, read keys or change project selection.

Options

OptionDescription
--dry-runPreview only; adoption and draft export are unavailable
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack config adopt

Explicitly adopt a stopped, verified existing Compose instance

Usage

hack config adopt [options]

Qualifies a strict static legacy subset with exact existing data volumes. --dry-run reports fields without writes. Adoption journals the stopped format switch and holds original files for rollback; retained-container commands never create replacement data. Requires an upgraded launcher and the Compose backend, also for --dry-run; on another backend, rerun with HACK_RUNTIME_BACKEND=compose. Verified linked Git checkouts retain explicit existing identities. Local inheritance, generated overrides and container recreation remain unsupported.

Options

OptionDescription
--stopExplicitly journal and stop the exact original containers before adopting; never removes data anchors
--dry-runRead-only field, compiler and existing-resource preview
--rollbackRestore the exact held legacy inputs after the original containers are stopped
--recoverExplicitly repair interrupted adoption or rollback using the saved original binding
--branch <value>Select the exact existing branch instance
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session

Manage persistent project workspaces with tmux-first onboarding

Usage

hack session <subcommand> [options]

Sessions keep a project workspace alive across terminal restarts, SSH reconnects, and long-running agent work. The guided default is tmux, including hack setup tmux for a popup picker. Other mux backends such as zellij still exist through sessions.mux, but the interactive session tooling is tmux-first today.

Subcommands

CommandSummary
hack session listList active workspaces
hack session start [project]Reuse the default project workspace or create an isolated one
hack session stop <workspace>Stop a workspace
hack session attach <workspace>Attach to an existing workspace
hack session exec <workspace> <command>Send a command to a running workspace
hack session panes <workspace>List panes in a tmux workspace
hack session capture <workspace>Capture recent output from a tmux workspace
hack session tail <workspace>Tail output from a tmux workspace

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session list

List active workspaces

Usage

hack session list [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session start [project]

Reuse the default project workspace or create an isolated one

Usage

hack session start [project] [options]

Reuse the default project workspace when it already exists, or create an isolated long-running workspace with --new or --name. Use --detach when another tool should keep the workspace alive without attaching your terminal.

Arguments

ArgDescription
projectProject name or path

Options

OptionDescription
--upRun hack up -d before creating or attaching
--newCreate an isolated workspace instead of reusing the default project workspace
--name <value>Suffix for an isolated workspace name (for example: agent-1 -> project--agent-1)
--detach, -dCreate or reuse the workspace without attaching (for GUI/non-TTY use)
`--env <namebase
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session stop <workspace>

Stop a workspace

Usage

hack session stop <workspace> [options]

Arguments

ArgDescription
workspaceWorkspace name

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session attach <workspace>

Attach to an existing workspace

Usage

hack session attach <workspace> [options]

Attach to a running workspace by name. Tmux switches clients instead of nesting tmux inside tmux, while zellij attaches to the named session directly.

Arguments

ArgDescription
workspaceWorkspace name

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session exec <workspace> <command>

Send a command to a running workspace

Usage

hack session exec [options] <workspace> <command>

<command> is one argument: quote a command that has its own arguments or flags, as in "npm --version". Put Hack options before it; a leading -- is optional.

Queue a command in the workspace without opening a new interactive attach flow. Tmux sends it to the active pane; zellij opens a new pane for the command. This is useful for long-running agents, background checks, or remote follow-up work.

Arguments

ArgDescription
workspaceWorkspace name
commandCommand to execute in workspace

Options

OptionDescription
`--env <namebase
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session panes <workspace>

List panes in a tmux workspace

Usage

hack session panes <workspace> [options]

Arguments

ArgDescription
workspaceWorkspace name

Options

OptionDescription
--jsonOutput JSON (machine-readable)
--prettyPretty-print logs (best-effort JSON parsing + formatting)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session capture <workspace>

Capture recent output from a tmux workspace

Usage

hack session capture <workspace> [options]

Arguments

ArgDescription
workspaceWorkspace name

Options

OptionDescription
--target <target>Tmux pane target (default: active pane)
--lines <n>Number of lines to capture (default: 200)
--jsonOutput JSON (machine-readable)
--prettyPretty-print logs (best-effort JSON parsing + formatting)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack session tail <workspace>

Tail output from a tmux workspace

Usage

hack session tail <workspace> [options]

Arguments

ArgDescription
workspaceWorkspace name

Options

OptionDescription
--target <target>Tmux pane target (default: active pane)
--lines <n>Number of lines to capture (default: 200)
--interval-ms <ms>Polling interval in milliseconds (default: 500)
--max-ms <ms>Stop tailing after N milliseconds (default: 5000)
--jsonOutput JSON (machine-readable)
--prettyPretty-print logs (best-effort JSON parsing + formatting)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

Global infrastructure

hack global

Manage machine-wide infra (DNS/TLS, Caddy proxy, logs)

Usage

hack global <subcommand> [options]

Subcommands

CommandSummary
hack global installBootstrap ~/.hack and start Caddy + Grafana/Loki/Alloy
hack global dnsManage scoped native custom-domain DNS
hack global upStart global infra containers
hack global downStop global infra containers
hack global statusShow status for global infra (containers + networks)
hack global logs [service]Tail global infra logs (caddy|grafana|loki|alloy)
hack global caExport Caddy Local CA cert (print path or PEM)
hack global cert <hosts...>Generate local TLS certs via mkcert (for non-Caddy services)
hack global trustTrust Caddy Local CA (macOS) so https://*.hack is trusted
hack global logs-resetWipe Loki, Grafana and Alloy volumes (fresh logs, dashboards and Alloy read positions)
hack global authorizeAuthorize passwordless DNS recovery commands on macOS

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global install

Bootstrap ~/.hack and start Caddy + Grafana/Loki/Alloy

Usage

hack global install [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global dns

Manage scoped native custom-domain DNS

Usage

hack global dns <subcommand> [options]

Subcommands

CommandSummary
hack global dns previewPreview a scoped native custom-domain DNS claim or the hack.local relay repair without changing the host
hack global dns activateActivate only the selected native custom-domain DNS suffix
hack global dns deactivateRemove an owned native custom-domain DNS suffix, or undo the hack.local relay repair

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global up

Start global infra containers

Usage

hack global up [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global down

Stop global infra containers

Usage

hack global down [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global status

Show status for global infra (containers + networks)

Usage

hack global status [options]

Options

OptionDescription
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global logs [service]

Tail global infra logs (caddy|grafana|loki|alloy)

Usage

hack global logs [service] [options]

Arguments

ArgDescription
service

Options

OptionDescription
--follow, -fFollow logs (default for hack logs)
--no-followPrint logs and exit (do not follow)
--tail <n>Tail last N log lines (default: 200)
--prettyPretty-print logs (best-effort JSON parsing + formatting)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global ca

Export Caddy Local CA cert (print path or PEM)

Usage

hack global ca [options]

Options

OptionDescription
--printPrint the CA cert PEM to stdout (instead of printing its path)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global cert <hosts...>

Generate local TLS certs via mkcert (for non-Caddy services)

Usage

hack global cert <hosts...> [options]

Uses mkcert to generate a cert/key pair under ~/.hack/certs (or --out).

Arguments

ArgDescription
hosts

Options

OptionDescription
--installRun mkcert -install before generating certs
--out <dir>Directory for generated cert/key (default: ~/.hack/certs)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global trust

Trust Caddy Local CA (macOS) so https://*.hack is trusted

Usage

hack global trust [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global logs-reset

Wipe Loki, Grafana and Alloy volumes (fresh logs, dashboards and Alloy read positions)

Usage

hack global logs-reset [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack global authorize

Authorize passwordless DNS recovery commands on macOS

Usage

hack global authorize [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack status

Show project status (shortcut for hack projects --details)

Usage

hack status [options]

Options

OptionDescription
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--include-globalInclude global infra projects under ~/.hack (e.g. logging stack)
--allInclude unregistered docker compose projects (best-effort)
--metaInclude git/worktree/session/env metadata (implies --details)
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack usage

Show resource usage across running projects

Usage

hack usage [options]

Options

OptionDescription
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--detailsShow per-container usage and mount types
--include-globalInclude global infra projects under ~/.hack (e.g. logging stack)
--watchRefresh usage continuously
--interval <value>Refresh interval (ms) for --watch
--no-hostSkip host process metrics
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack projects

Show all projects (registry + running docker compose)

Usage

hack projects <subcommand> [options]

Subcommands

CommandSummary
hack projects pruneRemove stale registry entries and stop orphaned containers

Options

OptionDescription
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--detailsShow per-project service tables
--summaryReturn compact project counts with --json; load details with --project
--timingsWrite numeric listing phase timings to stderr (requires --json)
--no-daemonRead runtime directly instead of the daemon cache
--metaInclude git/worktree/session/env metadata (implies --details)
--include-globalInclude global infra projects under ~/.hack (e.g. logging stack)
--allInclude unregistered docker compose projects (best-effort)
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack projects prune

Remove stale registry entries and stop orphaned containers

Usage

hack projects prune [options]

Options

OptionDescription
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--include-globalInclude global infra projects under ~/.hack (e.g. logging stack)
--dry-runReport prune candidates without changing registry entries or containers
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

Diagnostics

hack log-pipe

Read log lines from stdin and pretty-print them (best-effort JSON parsing)

Usage

hack log-pipe [options]

Options

OptionDescription
`--format <autodocker-compose
`--stream <stdoutstderr>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack doctor

Validate local setup for the selected runtime, routing, trust and project

Usage

hack doctor [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--fixAttempt safe auto-remediations (network + CoreDNS + CA)
--migrate-env-configMigrate legacy hack.env.json/.env state to the new env config files
--accept-tracked-env-changesWith --migrate-env-config and no prompt, allow deleting or editing git-tracked files (hack.env.json, the Compose file)
`--domain-migration previewapply
--jsonOutput JSON (machine-readable)
--browser-url https://app.hackHTTPS origin manually tested in the browser (no path or credentials)
`--browser-result unknownworks
--branch <name>Run against a branch-specific instance (compose name + hostnames)
--native-cleanup inspectInspect one mapped native graph's pending cleanup without recovery or stop replay
`--native-run-mapping inspectrepair
--expect-selection <64-hex>Require the exact run-mapping recovery inspection selection
--accept-legacy-device-rebindExplicitly accept legacy migration without proof of original filesystem volume continuity
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack crash-capture

Capture OrbStack/system/docker diagnostics into .tmp for post-failure triage

Usage

hack crash-capture [options]

Collects structured snapshots after a runtime failure: hack status/logs, docker state, OrbStack process details, and filtered macOS unified logs.

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--since <duration>Look-back window for system logs (for example: 30m, 2h)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon

Manage the local hack daemon (hackd)

Usage

hack daemon <subcommand> [options]

Subcommands

CommandSummary
hack daemon startStart hackd (local daemon)
hack daemon stopStop hackd
hack daemon restartRestart hackd
hack daemon statusShow hackd status
hack daemon metricsShow hackd metrics
hack daemon logsShow hackd logs
hack daemon clearClear stale hackd pid/socket files
hack daemon installInstall hackd as a launchd service (macOS)
hack daemon uninstallUninstall hackd launchd service (macOS)

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon start

Start hackd (local daemon)

Usage

hack daemon start [options]

Options

OptionDescription
--foregroundRun hackd in the foreground (debug)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon stop

Stop hackd

Usage

hack daemon stop [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon restart

Restart hackd

Usage

hack daemon restart [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon status

Show hackd status

Usage

hack daemon status [options]

Options

OptionDescription
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon metrics

Show hackd metrics

Usage

hack daemon metrics [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon logs

Show hackd logs

Usage

hack daemon logs [options]

Options

OptionDescription
--tail <n>Tail last N log lines (default: 200)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon clear

Clear stale hackd pid/socket files

Usage

hack daemon clear [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon install

Install hackd as a launchd service (macOS)

Usage

hack daemon install [options]

Options

OptionDescription
--run-at-loadStart hackd automatically on login
--no-run-at-loadDo not start hackd automatically on login
--gui-onlyOnly run in GUI sessions (default)
--no-gui-onlyRun in all session types (including SSH)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack daemon uninstall

Uninstall hackd launchd service (macOS)

Usage

hack daemon uninstall [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack update

Update hack to the latest release

Usage

hack update [options]

Downloads and installs the latest stable hack release from GitHub.

Notes:

  • Refuses to self-update when running from a Homebrew install, local dev wrapper, or symlink install.
  • Updates the current hack binary and refreshes assets.

Options

OptionDescription
--checkCheck for updates (do not install)
--yesApply update without prompting
--tag <tag>Update to a specific release tag (e.g. v1.4.0)
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack version

Print version

Usage

hack version [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack help [path...]

Show help for a command (e.g. hack help global logs)

Usage

hack help [path...] [options]

Arguments

ArgDescription
path

Options

OptionDescription
--allInclude experimental (unsupported) commands in help output
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

Agents

hack mcp

Manage MCP server integrations for coding agents

Usage

hack mcp <subcommand> [options]

Subcommands

CommandSummary
hack mcp serveRun the MCP server over stdio
hack mcp printPrint MCP config snippets

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack mcp serve

Run the MCP server over stdio

Usage

hack mcp serve [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack mcp print

Print MCP config snippets

Usage

hack mcp print [options]

Options

OptionDescription
--bundle <directory>Select a verified candidate MCP bundle (requires --cli)
--cli <executable>Pin the Hack executable used by candidate MCP tools
--runtime-directory <directory>Select a private candidate MCP socket directory
`--scope <userproject>`
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--allTarget all supported clients
--cursorTarget Cursor MCP config
--claudeTarget Claude CLI MCP config
--codexTarget Codex MCP config
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack setup

Explicit opt-in skills and MCP; legacy automation is retired

Usage

hack setup <subcommand> [options]

Subcommands

CommandSummary
hack setup tmuxInstall the recommended tmux binding for hack workspaces
hack setup migrateMigrate standalone skills to the hack plugin; preserve Cursor rules

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack setup tmux

Install the recommended tmux binding for hack workspaces

Usage

hack setup tmux [options]

Options

OptionDescription
--checkCheck whether integration is installed
--removeRemove integration files/config
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack setup migrate

Migrate standalone skills to the hack plugin; preserve Cursor rules

Usage

hack setup migrate [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--globalMigrate user-scope files under HOME instead of the project
--all-scopesMigrate both project and user-scope files
--claudeLimit to Claude Code files (default: all clients)
--codexLimit to Codex files (default: all clients)
--cursorLimit to Cursor files (default: all clients)
--skip-plugin-check <clients>Treat the plugin as verified for these comma-separated clients (claude, codex, cursor, or all) after checking it loads yourself
--applyRemove the previewed Hack-owned standalone files after backing them up (default: read-only preview)
--rollback-manifest <manifest>Restore the exact files recorded in a migration backup manifest
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack agent

Agent utilities

Usage

hack agent <subcommand> [options]

Subcommands

CommandSummary
hack agent patternsPrint agent init patterns guide
hack agent initPrint agent init prompt
hack agent onboardPrint the project onboarding prompt (agent-assisted setup)

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack agent patterns

Print agent init patterns guide

Usage

hack agent patterns [options]

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack agent init

Print agent init prompt

Usage

hack agent init [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
`--client, -c <cursorclaude
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack agent onboard

Print the project onboarding prompt (agent-assisted setup)

Usage

hack agent onboard [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

Secrets & env

hack secrets

Manage secrets in OS keychain (Bun.secrets)

Usage

hack secrets <subcommand> [options]

Subcommands

CommandSummary
hack secrets set [name]Store a secret
hack secrets get [name]Print a secret (exit 1 if missing)
hack secrets delete [name]Delete a stored secret

Options

OptionDescription
--service <service>Override Bun.secrets service name (default: hack-cli)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack secrets set [name]

Store a secret

Usage

hack secrets set [name] [options]

Arguments

ArgDescription
name

Options

OptionDescription
--service <service>Override Bun.secrets service name (default: hack-cli)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack secrets get [name]

Print a secret (exit 1 if missing)

Usage

hack secrets get [name] [options]

Arguments

ArgDescription
name

Options

OptionDescription
--service <service>Override Bun.secrets service name (default: hack-cli)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack secrets delete [name]

Delete a stored secret

Usage

hack secrets delete [name] [options]

Asks for confirmation before deleting. Without a TTY (or with HACK_NO_INTERACTIVE / --no-interactive) the deletion is refused with E_INTERACTIVE_REQUIRED unless --yes is passed.

Arguments

ArgDescription
name

Options

OptionDescription
--service <service>Override Bun.secrets service name (default: hack-cli)
--yesConfirm the deletion without prompting (required without a TTY or with HACK_NO_INTERACTIVE)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

Integrations

hack env

Set project env vars and local secrets

Usage

hack env <subcommand> [options]

Subcommands

CommandSummary
hack env listList resolved env values for the selected overlay
hack env get <key>Print one resolved env value without an added newline
hack env explain <key>Explain a resolved env value without revealing it
hack env applyRecreate one service with its resolved env
hack env add [key] [value]Add or update an env value
hack env set [key] [value]Alias for env add
hack env hydrateImport many values into the machine-local env layer at once
hack env materializeWrite a compatibility .env file from the selected overlay
hack env exec [command...]Run a host command with project env injected
hack env shellOpen a host shell with project env injected
hack env unset [key]Remove an env value from the canonical config
hack env backendManage env/secret storage backend strategy

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env list

List resolved env values for the selected overlay

Usage

hack env list [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--jsonOutput JSON (machine-readable)
--show-secretsPrint secret values (keychain) in plaintext
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env get <key>

Print one resolved env value without an added newline

Usage

hack env get <key> [options]

Read one global or service value without starting a runtime. Empty values succeed; missing values fail. Omit --env to use the configured default, or use --env default for base layers. Plaintext is written only to stdout; errors go to stderr.

Arguments

ArgDescription
key

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env explain <key>

Explain a resolved env value without revealing it

Usage

hack env explain <key> [options]

Arguments

ArgDescription
key

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--jsonOutput JSON (machine-readable)
`--service <globalservice>`
`--target <hostcompose>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env apply

Recreate one service with its resolved env

Usage

hack env apply [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--jsonOutput JSON (machine-readable)
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env add [key] [value]

Add or update an env value

Usage

hack env add [key] [value] [options]

Non-secret values may be passed as arguments. For secrets, pipe the value with --value-stdin (for example <secret-source> \| hack env add API_TOKEN --secret --value-stdin) or omit the value in a terminal to use the hidden prompt, so the value never appears in argv, shell history, or process listings.

Arguments

ArgDescription
key
value

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--secretStore value as an encrypted secure entry
--value-stdinRead the value from piped stdin (max 64 KiB, one trailing newline stripped) so it never appears in argv or shell history
--localWrite to the worktree-local env override file instead of the shared repo env file
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env set [key] [value]

Alias for env add

Usage

hack env set [key] [value] [options]

Same value rules as hack env add: pipe secrets with --value-stdin or use the hidden prompt instead of passing them as arguments.

Arguments

ArgDescription
key
value

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--secretStore value as an encrypted secure entry
--value-stdinRead the value from piped stdin (max 64 KiB, one trailing newline stripped) so it never appears in argv or shell history
--localWrite to the worktree-local env override file instead of the shared repo env file
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env hydrate

Import many values into the machine-local env layer at once

Usage

hack env hydrate [options]

Reads KEY=value entries from piped stdin or --file (never from arguments) and writes them, in one atomic commit, to the worktree-local env file (hack.env.local.yaml, or hack.env.<overlay>.local.yaml with --env). Tracked env files are never written. Repeating an import with the same values changes nothing; other local entries are kept. Values are never printed.

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--jsonOutput JSON (machine-readable)
--secretStore value as an encrypted secure entry
`--service <globalservice>`
--file <path>Read entries from this file (or a pipe such as <(producer)) instead of stdin
`--format <envjson>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env materialize

Write a compatibility .env file from the selected overlay

Usage

hack env materialize [options]

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env exec [command...]

Run a host command with project env injected

Usage

hack env exec [options] [command...]

Everything from <command> on is passed to the command unchanged, including flags such as --version or --help. Put Hack options before it; a leading -- is optional.

Inject the selected Hack env overlay directly into a one-off host command without materializing .hack/.env. To inspect a value, prefer printenv KEY or sh -lc 'printf "%s\n" "$KEY"'; echo $KEY expands in your current shell before Hack injects env.

Arguments

ArgDescription
command

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
`--service <globalservice>`
`--target <hostcompose>`
--shell <command>Run a shell command string via /bin/sh -lc after env injection so $VAR expansion happens inside the child shell
--timeout <seconds>Bound a non-TTY host command; terminate its process group and return 124 on expiry
`--lifetime <commandpersistent>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env shell

Open a host shell with project env injected

Usage

hack env shell [options]

Start an interactive host shell with the selected Hack env overlay injected into the process environment.

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
`--service <globalservice>`
`--target <hostcompose>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env unset [key]

Remove an env value from the canonical config

Usage

hack env unset [key] [options]

Arguments

ArgDescription
key

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
--localWrite to the worktree-local env override file instead of the shared repo env file
`--service <globalservice>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack env backend

Manage env/secret storage backend strategy

Usage

hack env backend <subcommand> [options]

Subcommands

CommandSummary
hack env backend statusShow configured env/secret backend strategy
hack env backend use <backend>Select env/secret backend strategy

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack host

Run host-side commands with project env injected

Usage

hack host <subcommand> [options]

Use hack host when a command should run on your host machine, not inside the compose network, but still needs Hack-resolved env and host-local rewrites.

Subcommands

CommandSummary
hack host psInspect host command lifetimes, CPU and lifecycle ownership (read-only)
hack host exec [command...]Run a host command with project env injected
hack host shellOpen a host shell with project env injected

Options

OptionDescription
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack host ps

Inspect host command lifetimes, CPU and lifecycle ownership (read-only)

Usage

hack host ps [options]

Options

OptionDescription
--project <name>Target a registered project by name (from ~/.hack/projects.json)
--jsonOutput JSON (machine-readable)
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack host exec [command...]

Run a host command with project env injected

Usage

hack host exec [options] [command...]

Everything from <command> on is passed to the command unchanged, including flags such as --version or --help. Put Hack options before it; a leading -- is optional.

Run a one-off command on the host with the selected Hack env overlay injected. Use --scope when you want service-scoped values without running inside that service container. To inspect a value, prefer printenv KEY or sh -lc 'printf "%s\n" "$KEY"'; echo $KEY expands in your current shell before Hack injects env.

Arguments

ArgDescription
command

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
`--scope <globalservice>`
`--target <hostcompose>`
--shell <command>Run a shell command string via /bin/sh -lc after env injection so $VAR expansion happens inside the child shell
--timeout <seconds>Bound a non-TTY host command; terminate its process group and return 124 on expiry
`--lifetime <commandpersistent>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

hack host shell

Open a host shell with project env injected

Usage

hack host shell [options]

Start an interactive host shell with the selected Hack env overlay injected. Use --scope when you want service-scoped values without running inside that service container.

Options

OptionDescription
--path, -p <dir>Run a project command against a repo path (overrides cwd search)
--project <name>Target a registered project by name (from ~/.hack/projects.json)
`--env <namebase
`--scope <globalservice>`
`--target <hostcompose>`
--no-interactiveNever prompt: apply documented defaults or fail with E_INTERACTIVE_REQUIRED (also via HACK_NO_INTERACTIVE=1)
--help, -hShow help
--version, -vShow version

Source: v5 (next.12) · docs/reference/cli.md.

On this page

Projecthack projectUsageSubcommandsOptionshack project ownerUsageSubcommandsOptionshack project targetUsageOptionshack project taskUsageSubcommandsOptionshack initUsageOptionshack up [services...]UsageArgumentsOptionshack downUsageOptionshack restart [services...]UsageArgumentsOptionshack psUsageOptionshack tuiUsageOptionshack run <service> [cmd...]UsageArgumentsOptionshack exec <service> [cmd...]UsageArgumentsOptionshack logs [service]UsageArgumentsOptionshack open [target]UsageArgumentsOptionshack branchUsageSubcommandsOptionshack branch add <name>UsageArgumentsOptionshack branch listUsageOptionshack branch remove <name>UsageArgumentsOptionshack branch open <name>UsageArgumentsOptionshack configUsageSubcommandsOptionshack config get <key>UsageArgumentsOptionshack config set <key> <value>UsageArgumentsOptionshack config validateUsageOptionshack config planUsageOptionshack config importUsageOptionshack config adoptUsageOptionshack sessionUsageSubcommandsOptionshack session listUsageOptionshack session start [project]UsageArgumentsOptionshack session stop <workspace>UsageArgumentsOptionshack session attach <workspace>UsageArgumentsOptionshack session exec <workspace> <command>UsageArgumentsOptionshack session panes <workspace>UsageArgumentsOptionshack session capture <workspace>UsageArgumentsOptionshack session tail <workspace>UsageArgumentsOptionsGlobal infrastructurehack globalUsageSubcommandsOptionshack global installUsageOptionshack global dnsUsageSubcommandsOptionshack global upUsageOptionshack global downUsageOptionshack global statusUsageOptionshack global logs [service]UsageArgumentsOptionshack global caUsageOptionshack global cert <hosts...>UsageArgumentsOptionshack global trustUsageOptionshack global logs-resetUsageOptionshack global authorizeUsageOptionshack statusUsageOptionshack usageUsageOptionshack projectsUsageSubcommandsOptionshack projects pruneUsageOptionsDiagnosticshack log-pipeUsageOptionshack doctorUsageOptionshack crash-captureUsageOptionshack daemonUsageSubcommandsOptionshack daemon startUsageOptionshack daemon stopUsageOptionshack daemon restartUsageOptionshack daemon statusUsageOptionshack daemon metricsUsageOptionshack daemon logsUsageOptionshack daemon clearUsageOptionshack daemon installUsageOptionshack daemon uninstallUsageOptionshack updateUsageOptionshack versionUsageOptionshack help [path...]UsageArgumentsOptionsAgentshack mcpUsageSubcommandsOptionshack mcp serveUsageOptionshack mcp printUsageOptionshack setupUsageSubcommandsOptionshack setup tmuxUsageOptionshack setup migrateUsageOptionshack agentUsageSubcommandsOptionshack agent patternsUsageOptionshack agent initUsageOptionshack agent onboardUsageOptionsSecrets & envhack secretsUsageSubcommandsOptionshack secrets set [name]UsageArgumentsOptionshack secrets get [name]UsageArgumentsOptionshack secrets delete [name]UsageArgumentsOptionsIntegrationshack envUsageSubcommandsOptionshack env listUsageOptionshack env get <key>UsageArgumentsOptionshack env explain <key>UsageArgumentsOptionshack env applyUsageOptionshack env add [key] [value]UsageArgumentsOptionshack env set [key] [value]UsageArgumentsOptionshack env hydrateUsageOptionshack env materializeUsageOptionshack env exec [command...]UsageArgumentsOptionshack env shellUsageOptionshack env unset [key]UsageArgumentsOptionshack env backendUsageSubcommandsOptionshack hostUsageSubcommandsOptionshack host psUsageOptionshack host exec [command...]UsageArgumentsOptionshack host shellUsageOptions