Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -293,8 +293,9 @@ Workspaces (mux-managed, tmux-first by default):
- Stop workspace: `hack session stop <workspace>`

Host-side env helpers:
- One-off host command with injected env: `hack env exec --env qa --service api -- bun db:migrate`
- Interactive host shell with injected env: `hack env shell --env qa --service api`
- One-off host command with injected env: `hack host exec --env qa --scope api -- bun db:migrate`
- `--scope` selects which env scope to inject; it does not move execution into that service container.
- Interactive host shell with injected env: `hack host shell --env qa --scope api`

Tickets (git-backed):
- Create: `hack tickets create --title "..." --body-stdin`
Expand Down
12 changes: 7 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,13 +78,15 @@ Core commands:
hack env list
hack env add AWS_PROFILE dev
hack env add --secret DATABASE_URL postgres://...
hack env exec --env qa --service api -- bun db:migrate
hack env exec --env qa --service api --target compose -- bun test
hack env shell --env qa --service api
hack host exec --env qa --scope api -- bun db:migrate
hack host exec --env qa --scope api --target compose -- bun test
hack host shell --env qa --scope api
```

`hack env exec` and `hack env shell` now default to a host-local env view for host commands. Use
`--target compose` when you explicitly want the container-oriented addresses from the compose view.
`hack host exec` and `hack host shell` run on your host machine with Hack-resolved env injected.
Use `--scope` when you want service-scoped values without running inside that service container.
Use `--target compose` when you explicitly want the container-oriented addresses from the compose
view instead of the default host-local rewrites.

Docs:

Expand Down
56 changes: 56 additions & 0 deletions docs/cli.md
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ Current practical rule:
| `hack auth` | Manage Hack account sign-in | Collaboration & integrations |
| `hack linear` | Connect Linear and sync repo work with Linear projects/issues | Collaboration & integrations |
| `hack env` | Set project env vars and local secrets | Collaboration & integrations |
| `hack host` | Run host-side commands with project env injected | Collaboration & integrations |
| `hack session` | Manage persistent project workspaces with tmux-first onboarding | Collaboration & integrations |
| `hack ssh` | Show SSH connection info for remote access to this machine | Collaboration & integrations |
| `hack tickets` | Track repo-local work without leaving git | Collaboration & integrations |
Expand Down Expand Up @@ -1664,6 +1665,61 @@ Options:
| `--service <name>` | string | - | Resolve values for one service scope |
| `--target <host\|compose>` | string | `host` | Host-local env view for host commands, or raw compose view |

### hack host

Usage: `hack host <subcommand>`

Use `hack host` when a command should run on the host machine, not inside the compose network, but
still needs Hack-resolved env. `--scope` selects which env scope to inject; it does not choose a
container execution target.

If you need a one-off command in the compose network, use `hack run <service> ...` instead.
If you need to run inside an already-running container, use `docker compose exec <service> ...`
today.

Subcommands:

| Subcommand | Summary |
| --- | --- |
| `exec` | Run a host command with project env injected |
| `shell` | Open a host shell with project env injected |

#### hack host exec

Usage: `hack host exec [options] <command...>`

Runs a host command with injected env. Default target is `host`, which applies the host-local env
view and any `host` scope overrides. Use `--target compose` to preserve the container-oriented
compose view while still running on the host.

Options:

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `-p`, `--path <dir>` | string | - | Run against a repo path (overrides cwd search) |
| `--project <name>` | string | - | Target a registered project by name |
| `--env <name\|base>` | string | - | Apply an optional env overlay by name |
| `--scope <name>` | string | - | Resolve values for one env scope while still running on the host |
| `--target <host\|compose>` | string | `host` | Host-local env view for host commands, or raw compose view |

#### hack host shell

Usage: `hack host shell [options]`

Starts an interactive host shell with injected env. Default target is `host`, which applies the
host-local env view and any `host` scope overrides. Use `--target compose` to preserve the
container-oriented compose view while still running on the host.

Options:

| Flag | Type | Default | Description |
| --- | --- | --- | --- |
| `-p`, `--path <dir>` | string | - | Run against a repo path (overrides cwd search) |
| `--project <name>` | string | - | Target a registered project by name |
| `--env <name\|base>` | string | - | Apply an optional env overlay by name |
| `--scope <name>` | string | - | Resolve values for one env scope while still running on the host |
| `--target <host\|compose>` | string | `host` | Host-local env view for host commands, or raw compose view |

#### hack env unset

Usage: `hack env unset [key] [options]`
Expand Down
29 changes: 20 additions & 9 deletions docs/env.md
Original file line number Diff line number Diff line change
Expand Up @@ -97,6 +97,8 @@ Hack reads the canonical YAML files and injects the resolved env directly into:
- `hack run`
- `hack restart`
- lifecycle host processes
- `hack host exec`
- `hack host shell`
- `hack env exec`
- `hack env shell`
- `hack session start --env ... --service ...`
Expand All @@ -106,14 +108,23 @@ That means `.hack/.env` is no longer the primary runtime source of truth.

`hack env materialize` is manual by design. Use it only when you need a compatibility file for an external tool that expects `.env` on disk.

For host commands, `hack env exec` and `hack env shell` default to a host-local view. That means
Hack prefers host-usable values when it can:
For host commands, `hack host exec`, `hack host shell`, `hack env exec`, and `hack env shell`
default to a host-local view. That means Hack prefers host-usable values when it can:

- explicit `host` scope values override the normal `global` + `<service>` merge
- common container-only hostnames such as `host.docker.internal` and compose service hosts are rewritten to `127.0.0.1`

Use `--target compose` if you explicitly want the container-oriented compose view instead.

## Choosing the right execution surface

- `hack host exec` / `hack host shell`: run on your host machine with Hack-resolved env injected.
- `hack run <service> ...`: run a one-off command in the compose network with an ephemeral service container.
- `docker compose exec <service> ...`: run inside an already-running container when you specifically need that container's live filesystem or process context.

For host execution, `--scope` means "which env scope should Hack inject", not "where should this run."
For example, `hack host exec --scope api -- bun db:migrate` still runs on the host.

## Common commands

Inspect resolved env:
Expand Down Expand Up @@ -153,17 +164,17 @@ hack env materialize --env qa --service api
Run a host command with injected env:

```bash
hack env exec -- bun db:migrate
hack env exec --env qa --service api -- bun db:migrate
hack env exec --env qa --service api --target compose -- bun test
hack host exec -- bun db:migrate
hack host exec --env qa --scope api -- bun db:migrate
hack host exec --env qa --scope api --target compose -- bun test
```

Open a host shell with injected env:

```bash
hack env shell
hack env shell --env qa --service api
hack env shell --env qa --service api --target compose
hack host shell
hack host shell --env qa --scope api
hack host shell --env qa --scope api --target compose
```

Example with an explicit host override:
Expand Down Expand Up @@ -252,7 +263,7 @@ If you are writing new docs or new project setup flows, document the YAML overla
- Never commit `.hack.secret.key`
- Prefer `hack env add` over hand-editing encrypted values
- Prefer direct runtime injection over materializing `.hack/.env`
- Use `hack env exec` or env-aware sessions for host-side scripts like migrations, generators, and admin tasks
- Use `hack host exec` or env-aware sessions for host-side scripts like migrations, generators, and admin tasks

## Related docs

Expand Down
11 changes: 6 additions & 5 deletions docs/guides/codex-managed-environments.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,8 @@ bash scripts/maintain-codex-slim.sh
- `hack linear`
- `hack x github`
- `hack env list`
- `hack env exec`
- `hack env shell`
- `hack host exec`
- `hack host shell`
- repo-local docs, specs, and agent setup
- command and config surfaces that do not require the machine-wide runtime stack

Expand All @@ -88,11 +88,12 @@ If the repo uses the modern env overlay model, provide secret decryption materia

```bash
export HACK_ENV_SECRET_KEY="..."
hack env exec --env qa --service api -- bun db:migrate
hack env exec --env qa --service api --target compose -- bun test
hack host exec --env qa --scope api -- bun db:migrate
hack host exec --env qa --scope api --target compose -- bun test
```

`hack env exec` and `hack env shell` default to a host-local env view for host commands. Use
`hack host exec` and `hack host shell` default to a host-local env view for host commands. Use
`--scope` when you want service-scoped values without running inside that service container. Use
`--target compose` when you explicitly want the container-oriented compose view instead.

## Not available in slim mode
Expand Down
8 changes: 6 additions & 2 deletions docs/integrations.md
Original file line number Diff line number Diff line change
Expand Up @@ -122,13 +122,17 @@ Main surface:

- `hack env list`
- `hack env add`
- `hack host exec`
- `hack host shell`
- `hack env exec`
- `hack env shell`
- `hack env unset`
- `hack env materialize`

`hack env exec` and `hack env shell` default to a host-local env view for host-side commands. Use
`--target compose` when you explicitly want the raw compose/container-oriented values.
Prefer `hack host exec` and `hack host shell` when a command should run on your host machine but
still needs Hack-resolved env. They default to a host-local env view and accept `--scope` when you
want service-scoped values without running inside that container. Use `--target compose` when you
explicitly want the raw compose/container-oriented values.

Reference:

Expand Down
3 changes: 2 additions & 1 deletion src/cli/spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { crashCaptureCommand } from "../commands/crash-capture.ts";
import { daemonCommand } from "../commands/daemon.ts";
import { dispatchCommand } from "../commands/dispatch.ts";
import { doctorCommand } from "../commands/doctor.ts";
import { envCommand } from "../commands/env.ts";
import { envCommand, hostCommand } from "../commands/env.ts";
import { gatewayCommand } from "../commands/gateway.ts";
import { globalCommand } from "../commands/global.ts";
import { helpCommand } from "../commands/help.ts";
Expand Down Expand Up @@ -88,6 +88,7 @@ export const CLI_SPEC = defineCli({
theCommand,
secretsCommand,
envCommand,
hostCommand,
configCommand,
mcpCommand,
setupCommand,
Expand Down
Loading
Loading