boxdown 1.0.0 → 1.2.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 +135 -12
- package/assets/devcontainer/README.md +65 -21
- package/assets/devcontainer/devcontainer.json +27 -15
- package/assets/devcontainer/hooks/initialize.sh +76 -22
- package/assets/devcontainer/hooks/post-create.sh +70 -12
- package/assets/devcontainer/hooks/post-start.sh +20 -13
- package/assets/devcontainer/ssh-config-install.sh +12 -3
- package/assets/devcontainer/start.sh +721 -44
- package/assets/devcontainer/utils/coding-agent-cli-update.sh +267 -3
- package/assets/devcontainer/utils/deps-install.sh +68 -0
- package/assets/devcontainer/utils/git-config-bootstrap.sh +128 -0
- package/assets/devcontainer/utils/git-signing-bootstrap.sh +109 -0
- package/assets/devcontainer/utils/python-bootstrap.sh +69 -0
- package/assets/devcontainer/utils/secret-env-bootstrap.sh +22 -0
- package/assets/devcontainer/utils/ssh-agent-proxy-bootstrap.sh +27 -0
- package/assets/devcontainer/utils/ssh-agent-proxy.mjs +39 -0
- package/assets/devcontainer/utils/ssh-bootstrap.sh +9 -0
- package/dist/bin/cli.cjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/main-BDgyf2t5.cjs +5758 -0
- package/dist/main-J4_2Up3o.mjs +5718 -0
- package/dist/main-J4_2Up3o.mjs.map +1 -0
- package/dist/main.cjs +5 -2
- package/dist/main.d.cts +501 -4
- package/dist/main.d.cts.map +1 -1
- package/dist/main.d.mts +501 -4
- package/dist/main.d.mts.map +1 -1
- package/dist/main.mjs +2 -2
- package/docs/README.md +1 -0
- package/docs/architecture.md +32 -0
- package/docs/development.md +13 -6
- package/docs/features/README.md +2 -0
- package/docs/features/commit-signing.md +94 -0
- package/docs/features/generated-config-and-state.md +73 -5
- package/docs/features/github-auth-refresh.md +15 -2
- package/docs/features/lifecycle.md +103 -11
- package/docs/features/setup.md +66 -0
- package/docs/features/ssh-config-and-proxy.md +228 -7
- package/docs/features/start-and-shell.md +45 -5
- package/docs/superpowers/plans/2026-07-11-default-commit-signing.md +110 -0
- package/docs/superpowers/plans/2026-07-11-progress-ci-regression.md +125 -0
- package/docs/superpowers/plans/2026-07-17-node-ssh-agent-proxy-signing.md +132 -0
- package/docs/superpowers/plans/2026-07-17-runtime-secret-environment.md +174 -0
- package/docs/superpowers/specs/2026-07-11-default-commit-signing-design.md +416 -0
- package/docs/superpowers/specs/2026-07-11-progress-ci-regression-design.md +43 -0
- package/docs/superpowers/specs/2026-07-17-node-ssh-agent-proxy-design.md +63 -0
- package/docs/superpowers/specs/2026-07-17-runtime-secret-environment-design.md +194 -0
- package/docs/testing.md +35 -2
- package/docs/todo.md +2 -2
- package/package.json +1 -1
- package/src/claude-app-config.ts +304 -0
- package/src/cli-style.ts +43 -0
- package/src/codex-app-config.ts +656 -0
- package/src/config.ts +80 -10
- package/src/constants.ts +12 -0
- package/src/devcontainer.ts +511 -64
- package/src/doctor.ts +292 -30
- package/src/git-signing.ts +267 -0
- package/src/interactive-prompts.ts +692 -0
- package/src/list.ts +16 -2
- package/src/logging.ts +164 -0
- package/src/main.ts +1214 -63
- package/src/metadata.ts +52 -3
- package/src/package-info.ts +18 -0
- package/src/paths.ts +71 -11
- package/src/process.ts +80 -2
- package/src/progress.ts +593 -0
- package/src/purge.ts +216 -0
- package/src/shell.ts +25 -0
- package/src/ssh-config.ts +134 -16
- package/src/ssh-install-targets.ts +111 -0
- package/src/ssh-key.ts +53 -13
- package/src/status.ts +5 -0
- package/dist/main-BuEptwlL.cjs +0 -1707
- package/dist/main-ZFTrSVgt.mjs +0 -1685
- package/dist/main-ZFTrSVgt.mjs.map +0 -1
package/docs/features/README.md
CHANGED
|
@@ -4,10 +4,12 @@ This directory explains Boxdown's user-facing capabilities and the main internal
|
|
|
4
4
|
flows behind them.
|
|
5
5
|
|
|
6
6
|
- [Start command](./start-and-shell.md)
|
|
7
|
+
- [Setup command](./setup.md)
|
|
7
8
|
- [Lifecycle commands](./lifecycle.md)
|
|
8
9
|
- [SSH config and proxy workflow](./ssh-config-and-proxy.md)
|
|
9
10
|
- [GitHub auth refresh](./github-auth-refresh.md)
|
|
10
11
|
- [Generated config and state](./generated-config-and-state.md)
|
|
12
|
+
- [Commit signing](./commit-signing.md)
|
|
11
13
|
|
|
12
14
|
Most features share the same first step: resolve a target workspace, derive
|
|
13
15
|
workspace-specific state paths, generate a devcontainer override config, and
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
# Commit signing
|
|
2
|
+
|
|
3
|
+
New Boxdown environments attempt SSH commit signing by default. Boxdown forwards
|
|
4
|
+
the host SSH agent, selects a signing identity only when there is one
|
|
5
|
+
unambiguous candidate, and keeps the private key on the host.
|
|
6
|
+
|
|
7
|
+
If the agent is unavailable, has no identities, or has multiple identities
|
|
8
|
+
that Boxdown cannot distinguish, Boxdown warns and configures unsigned commits.
|
|
9
|
+
It never guesses a key and does not block setup or commits.
|
|
10
|
+
|
|
11
|
+
Signing readiness is resolved when generated devcontainer configuration is
|
|
12
|
+
written. A container created while readiness is unavailable does not gain an
|
|
13
|
+
SSH-agent mount later; recreate it after correcting the warning:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
boxdown setup --workspace /path/to/project --recreate
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
The container can request operations from identities exposed by the forwarded
|
|
20
|
+
agent. Use a dedicated signing identity or an agent that confirms sensitive
|
|
21
|
+
operations when that exposure is unacceptable.
|
|
22
|
+
|
|
23
|
+
On Docker Desktop, Boxdown places a small root-owned relay between the
|
|
24
|
+
host-facing agent socket and the non-root container user. The relay exposes no
|
|
25
|
+
private-key material and lets normal `node`-user Git commits reach the host
|
|
26
|
+
agent.
|
|
27
|
+
|
|
28
|
+
GitHub verification is separate from signing. Upload the selected public key as
|
|
29
|
+
a GitHub SSH signing key once to receive the Verified badge:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
gh ssh-key add /path/to/signing-key.pub --type signing --title "Boxdown commit signing"
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
The same key may already be registered for GitHub SSH authentication; GitHub
|
|
36
|
+
requires a second registration with type `signing`.
|
|
37
|
+
|
|
38
|
+
## Optional: configure SSH signing on the host
|
|
39
|
+
|
|
40
|
+
Boxdown can sign commits without changing the host Git configuration. The
|
|
41
|
+
container uses the selected identity from the host SSH agent directly. Configure
|
|
42
|
+
the host as well when you also make commits outside Boxdown, or when you want
|
|
43
|
+
to make the selected Boxdown identity explicit.
|
|
44
|
+
|
|
45
|
+
First, verify the intended identity is loaded in the SSH agent. `ssh-add -l`
|
|
46
|
+
prints loaded key fingerprints:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
ssh-add -l
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Then configure Git to use that public key for SSH signing:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git config --global gpg.format ssh
|
|
56
|
+
git config --global user.signingkey ~/.ssh/id_ed25519.pub
|
|
57
|
+
git config --global --unset-all gpg.program || true
|
|
58
|
+
git config --global commit.gpgsign true
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Replace `~/.ssh/id_ed25519.pub` with the selected public key when you use a
|
|
62
|
+
different identity. The public key must also be registered with GitHub as a
|
|
63
|
+
Signing key for pushed commits to display the Verified badge.
|
|
64
|
+
|
|
65
|
+
Boxdown accepts `user.signingkey` as an inline SSH public key, a `key::` public
|
|
66
|
+
key, an absolute path, a `~/` path, or a path relative to the workspace. Only
|
|
67
|
+
public-key files are read. An explicitly configured key is authoritative: if
|
|
68
|
+
it is unreadable, invalid, or absent from the SSH agent, Boxdown disables
|
|
69
|
+
signing instead of selecting another identity.
|
|
70
|
+
|
|
71
|
+
## User configuration precedence
|
|
72
|
+
|
|
73
|
+
Boxdown defaults to SSH signing only when Git has no explicit signing
|
|
74
|
+
preference. A repository-local `commit.gpgsign=false`, a non-SSH `gpg.format`,
|
|
75
|
+
or an explicit `gpg.program` is preserved. Explicit SSH signing remains
|
|
76
|
+
supported; Boxdown maps an inaccessible host public-key path to the selected
|
|
77
|
+
public-key snapshot inside the container. This policy is intentional and may
|
|
78
|
+
be revisited in a future release if Boxdown becomes authoritative.
|
|
79
|
+
|
|
80
|
+
Git can require `gpg.ssh.allowedSignersFile` for trust-aware local verification
|
|
81
|
+
such as `git log --show-signature`. It is not required to create SSH signatures
|
|
82
|
+
or for GitHub to verify a commit.
|
|
83
|
+
|
|
84
|
+
## Troubleshooting
|
|
85
|
+
|
|
86
|
+
Signing failures remain non-blocking. User-facing lifecycle commands print a
|
|
87
|
+
concise reason, while the workspace `boxdown.log` records a stable reason code
|
|
88
|
+
and sanitized diagnostic detail. Container validation further distinguishes a
|
|
89
|
+
missing mounted public key, an unavailable forwarded agent, a selected key that
|
|
90
|
+
is not loaded, and a failed disposable signed-commit probe.
|
|
91
|
+
|
|
92
|
+
Run `boxdown doctor --workspace /path/to/project` to recheck host identity
|
|
93
|
+
selection and GitHub signing-key registration. After fixing the reported
|
|
94
|
+
condition, use `--recreate`; existing unsigned commits are not rewritten.
|
|
@@ -35,6 +35,21 @@ Boxdown-specific override is not set.
|
|
|
35
35
|
SSH private keys live in persistent data. A public-key-only runtime directory is
|
|
36
36
|
used for the container mount.
|
|
37
37
|
|
|
38
|
+
Boxdown-managed lifecycle command output is appended to one per-workspace log
|
|
39
|
+
file:
|
|
40
|
+
|
|
41
|
+
```text
|
|
42
|
+
~/.local/share/boxdown/workspaces/<workspace-hash>/boxdown.log
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
The log is append-only across lifecycle runs. Each run starts a timestamped
|
|
46
|
+
section and records Boxdown-managed command output, Docker/devcontainer child
|
|
47
|
+
process output, and command exit codes. Full interactive shell, agent, and
|
|
48
|
+
tunnel session bytes are not tee'd into the log.
|
|
49
|
+
|
|
50
|
+
The log lives with the workspace's persistent data so `boxdown status` can show
|
|
51
|
+
its path and `boxdown purge` removes it with the rest of the workspace data.
|
|
52
|
+
|
|
38
53
|
Each touched workspace also records inventory metadata at:
|
|
39
54
|
|
|
40
55
|
```text
|
|
@@ -44,21 +59,74 @@ Each touched workspace also records inventory metadata at:
|
|
|
44
59
|
`boxdown list` reads these metadata files as its source of truth, then enriches
|
|
45
60
|
entries with best-effort Docker state.
|
|
46
61
|
|
|
62
|
+
Metadata may also record the last inspected Docker image ID for the workspace so
|
|
63
|
+
`boxdown purge` can remove that exact image even after the container is gone.
|
|
64
|
+
|
|
65
|
+
## Runtime Secret State
|
|
66
|
+
|
|
67
|
+
`ANTHROPIC_API_KEY`, `SNYK_TOKEN`, and the optional 1Password service-account
|
|
68
|
+
token are written to owner-only files in a per-workspace runtime directory,
|
|
69
|
+
separate from persistent workspace data. Boxdown mounts that directory
|
|
70
|
+
read-only at `/run/boxdown/secrets`; only non-secret mount and Bash-bootstrap
|
|
71
|
+
paths appear in generated Docker configuration.
|
|
72
|
+
|
|
73
|
+
Bash sessions load available files as ordinary environment variables. Missing
|
|
74
|
+
host values and failed 1Password lookup are non-blocking. `boxdown down` and
|
|
75
|
+
`boxdown purge` remove the workspace runtime directory after container removal.
|
|
76
|
+
Boxdown does not use or modify project `.env.development` files.
|
|
77
|
+
|
|
78
|
+
## External App Config
|
|
79
|
+
|
|
80
|
+
External app integration config is not Boxdown workspace state. Boxdown writes
|
|
81
|
+
it only when an SSH install target is selected from an interactive
|
|
82
|
+
`boxdown setup` or `boxdown ssh install` prompt, or requested explicitly with
|
|
83
|
+
`boxdown setup --target <name>` or `boxdown ssh install --target <name>`.
|
|
84
|
+
Non-interactive runs without `--target` install only the SSH alias and leave
|
|
85
|
+
external app config unchanged.
|
|
86
|
+
|
|
87
|
+
When requested, Boxdown writes Codex's app config at:
|
|
88
|
+
|
|
89
|
+
```text
|
|
90
|
+
~/.codex/codex-app/config.json
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
`BOXDOWN_CODEX_APP_CONFIG` overrides this path for tests and local development.
|
|
94
|
+
The Codex entry refers to the Boxdown-managed SSH alias and the canonical
|
|
95
|
+
container-side workspace path `/workspaces/<repo-name>`. Codex owns later
|
|
96
|
+
global-state records and sidebar entries it creates from that config, but
|
|
97
|
+
`boxdown ssh uninstall` removes the matching Codex sidebar cache entry when
|
|
98
|
+
unregistering the project.
|
|
99
|
+
|
|
100
|
+
When requested, Boxdown writes Claude's SSH remote config at:
|
|
101
|
+
|
|
102
|
+
```text
|
|
103
|
+
~/Library/Application Support/Claude/ssh_configs.json
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
`BOXDOWN_CLAUDE_SSH_CONFIGS` overrides this path for tests and local
|
|
107
|
+
development. The Claude entry refers to the Boxdown-managed SSH alias and adds
|
|
108
|
+
that alias to Claude's trusted host list.
|
|
109
|
+
|
|
47
110
|
## Generated Changes
|
|
48
111
|
|
|
49
112
|
Boxdown starts from `assets/devcontainer/devcontainer.json` and rewrites:
|
|
50
113
|
|
|
51
114
|
- `name`, to include the workspace basename.
|
|
52
|
-
- `initializeCommand`, to call the host asset script with the target workspace
|
|
115
|
+
- `initializeCommand`, to call the host asset script with the target workspace
|
|
116
|
+
and host Git config snapshot paths.
|
|
53
117
|
- `postCreateCommand`, to call mounted container assets.
|
|
54
118
|
- `postStartCommand`, to call mounted container assets.
|
|
55
|
-
- `mounts`, to add the read-only asset mount, public-key mount,
|
|
56
|
-
`~/.agents` mount when that
|
|
119
|
+
- `mounts`, to add the read-only asset mount, public-key mount, host Git config
|
|
120
|
+
snapshot mount, runtime secret mount, host `~/.agents` mount when that
|
|
121
|
+
directory exists, and host `~/.codex/auth.json` read-only mount when that
|
|
122
|
+
file exists.
|
|
57
123
|
- `containerEnv`, to point SSH bootstrap at the mounted public key and actual
|
|
58
124
|
container workspace.
|
|
59
125
|
|
|
60
126
|
The target repository is still the Dev Container workspace via
|
|
61
127
|
`--workspace-folder`.
|
|
62
128
|
|
|
63
|
-
Mounts are create-time container settings.
|
|
64
|
-
|
|
129
|
+
Mounts are create-time container settings. Existing containers created before
|
|
130
|
+
runtime-mounted secrets require `boxdown start --recreate`. The same applies
|
|
131
|
+
after creating or removing host `~/.agents` or `~/.codex/auth.json` so Docker
|
|
132
|
+
receives the updated mount set.
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
```sh
|
|
6
6
|
boxdown refresh-gh-token
|
|
7
7
|
boxdown refresh-gh-token-running
|
|
8
|
+
boxdown refresh-gh-token --verbose
|
|
8
9
|
```
|
|
9
10
|
|
|
10
11
|
Both commands copy host GitHub CLI auth into the container using the host token
|
|
@@ -16,6 +17,9 @@ gh auth token
|
|
|
16
17
|
|
|
17
18
|
They do not start a browser login or device-code flow.
|
|
18
19
|
|
|
20
|
+
The startup and refresh work uses concise progress output by default. Pass
|
|
21
|
+
`--verbose` to stream raw devcontainer and auth command output while debugging.
|
|
22
|
+
|
|
19
23
|
These commands are explicit on purpose. Normal `boxdown start`, coding-agent
|
|
20
24
|
launches, and SSH proxy connections do not copy GitHub credentials into the
|
|
21
25
|
container.
|
|
@@ -48,6 +52,8 @@ container's authenticated `gh` for `git fetch`, `git pull`, and `git push`.
|
|
|
48
52
|
For GitHub remotes, Boxdown:
|
|
49
53
|
|
|
50
54
|
- rewrites fetch and push URLs to `https://github.com/<owner>/<repo>.git`
|
|
55
|
+
- configures container-global GitHub HTTPS credentials through the container's
|
|
56
|
+
`gh` auth store
|
|
51
57
|
- resets inherited `credential.https://github.com.helper` entries locally
|
|
52
58
|
- adds `!gh auth git-credential` as the local GitHub credential helper
|
|
53
59
|
- adds a repository-specific HTTPS self-rewrite so broader host rewrites like
|
|
@@ -57,8 +63,15 @@ For GitHub remotes, Boxdown:
|
|
|
57
63
|
The local Git config changes are written to the workspace repository because the
|
|
58
64
|
host checkout is mounted into the devcontainer.
|
|
59
65
|
|
|
66
|
+
Separately, Boxdown snapshots the host `.gitconfig` into workspace state and
|
|
67
|
+
copies it to a writable `/home/node/.gitconfig` during container creation. That
|
|
68
|
+
container copy is sanitized so tools cloning from directories such as `/tmp` use
|
|
69
|
+
HTTPS GitHub auth and do not inherit host-only helpers, GitHub SSH rewrites, or
|
|
70
|
+
signing programs that are unavailable inside Linux.
|
|
71
|
+
|
|
60
72
|
If host `gh` is missing, logged out, or cannot return a token, the refresh is a
|
|
61
73
|
no-op.
|
|
62
74
|
|
|
63
|
-
`OP_SERVICE_ACCOUNT_TOKEN`, when
|
|
64
|
-
|
|
75
|
+
`OP_SERVICE_ACCOUNT_TOKEN`, when available through Boxdown's runtime secret
|
|
76
|
+
mount, is a 1Password service account token. It is not a GitHub token and is
|
|
77
|
+
not used by `gh` or GitHub Git operations.
|
|
@@ -4,33 +4,48 @@
|
|
|
4
4
|
|
|
5
5
|
```sh
|
|
6
6
|
boxdown list
|
|
7
|
+
boxdown list --details
|
|
7
8
|
boxdown list --json
|
|
9
|
+
boxdown list --format json
|
|
8
10
|
boxdown status
|
|
9
11
|
boxdown status --json
|
|
12
|
+
boxdown status --format json
|
|
10
13
|
boxdown stop
|
|
11
14
|
boxdown down
|
|
15
|
+
boxdown purge
|
|
12
16
|
boxdown doctor
|
|
13
17
|
```
|
|
14
18
|
|
|
15
|
-
Workspace-targeting commands accept `--workspace <path>`. `
|
|
16
|
-
`--
|
|
19
|
+
Workspace-targeting commands accept `--workspace <path>`. `down` also accepts
|
|
20
|
+
repeated `--workspace` flags to remove multiple workspace containers in order.
|
|
21
|
+
`purge --workspace` also accepts the `PATH`, `SSH ALIAS`, or unambiguous `REPO`
|
|
22
|
+
value shown by `boxdown list`. `purge` does not accept repeated `--workspace`
|
|
23
|
+
flags. `status` accepts `--alias <name>` so its output can match a custom SSH
|
|
24
|
+
host alias.
|
|
17
25
|
|
|
18
26
|
## List
|
|
19
27
|
|
|
20
28
|
`list` shows every workspace with Boxdown metadata under the data root,
|
|
21
29
|
regardless of the directory where the command is run. Human output includes
|
|
22
|
-
`STATE`, `REPO`, `PATH`,
|
|
30
|
+
`STATE`, `REPO`, `PATH`, and `CONTAINER` columns.
|
|
23
31
|
|
|
24
|
-
`list --
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
32
|
+
`list --details` prints one workspace per block with full copyable `path`,
|
|
33
|
+
`ssh alias`, and `container` values.
|
|
34
|
+
|
|
35
|
+
`list --json` and `list --format json` print the same inventory as structured
|
|
36
|
+
JSON. Docker state is best-effort and includes recorded SSH aliases: if Docker
|
|
37
|
+
is unavailable, entries still print and their container state is `unknown`. If a
|
|
38
|
+
recorded repository path no longer exists, the entry is shown as `missing`.
|
|
39
|
+
Container states come from Docker, so active containers usually show `running`,
|
|
40
|
+
stopped containers can show `exited`, and workspaces with no matching container
|
|
41
|
+
show `absent`.
|
|
28
42
|
|
|
29
43
|
## Status
|
|
30
44
|
|
|
31
45
|
`status` is read-only. It reports the resolved workspace, intended cache/data
|
|
32
|
-
paths, generated config path, SSH key paths, SSH alias, and
|
|
33
|
-
container state without recording the workspace in Boxdown
|
|
46
|
+
paths, generated config path, command log path, SSH key paths, SSH alias, and
|
|
47
|
+
the matching Docker container state without recording the workspace in Boxdown
|
|
48
|
+
metadata.
|
|
34
49
|
|
|
35
50
|
Human output distinguishes intended values from detected state. For example, an
|
|
36
51
|
SSH alias can be shown as a computed default even when the matching Boxdown SSH
|
|
@@ -46,7 +61,7 @@ workspace container is running. Missing setup or a stopped/absent container is
|
|
|
46
61
|
reported in the output and exits nonzero. Installing an SSH alias is optional
|
|
47
62
|
and is not required for a healthy status exit.
|
|
48
63
|
|
|
49
|
-
## Stop and
|
|
64
|
+
## Stop, Down, and Purge
|
|
50
65
|
|
|
51
66
|
`stop` stops the workspace devcontainer when it is running. If the container is
|
|
52
67
|
already stopped or absent, it prints a short message and exits 0.
|
|
@@ -54,11 +69,88 @@ already stopped or absent, it prints a short message and exits 0.
|
|
|
54
69
|
`down` removes the workspace devcontainer with Docker. It does not remove
|
|
55
70
|
Boxdown cache, generated config, data directories, or SSH keys.
|
|
56
71
|
|
|
72
|
+
Lifecycle commands append managed output to the workspace command log under the
|
|
73
|
+
workspace data directory. `--verbose` only controls terminal streaming; it does
|
|
74
|
+
not disable or enable log persistence. Foreground interactive shell, agent, and
|
|
75
|
+
tunnel session bytes are not tee'd into the log.
|
|
76
|
+
|
|
77
|
+
`purge` removes the workspace devcontainer with Docker, force-removes the exact
|
|
78
|
+
Docker image ID Boxdown can inspect or has recorded for the workspace, removes
|
|
79
|
+
Boxdown-managed SSH/Codex/Claude entries for the computed, recorded, and
|
|
80
|
+
provided aliases, and deletes the workspace's Boxdown cache/data directories,
|
|
81
|
+
including the per-workspace command log. It does not delete the target
|
|
82
|
+
repository directory or files inside it.
|
|
83
|
+
|
|
84
|
+
`purge --workspace <value>` first treats `<value>` as a filesystem path. If that
|
|
85
|
+
path does not exist, it looks for an exact `PATH`, then `SSH ALIAS`, then `REPO`
|
|
86
|
+
match in Boxdown metadata. `PATH` and `REPO` are shown by `boxdown list`; use
|
|
87
|
+
`boxdown status`, `boxdown list --details`, or JSON list output for SSH aliases.
|
|
88
|
+
`REPO` must match exactly one workspace; if multiple known workspaces share the
|
|
89
|
+
same repo basename, use `PATH` or `SSH ALIAS`.
|
|
90
|
+
|
|
91
|
+
```sh
|
|
92
|
+
boxdown purge
|
|
93
|
+
boxdown purge --workspace my-repo-devcontainer
|
|
94
|
+
boxdown purge --workspace my-repo
|
|
95
|
+
boxdown purge --workspace /path/to/my-repo
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
To remove multiple workspace containers, repeat `--workspace`:
|
|
99
|
+
|
|
100
|
+
```sh
|
|
101
|
+
boxdown down --workspace /path/to/repo-a --workspace /path/to/repo-b
|
|
102
|
+
```
|
|
103
|
+
|
|
104
|
+
When `down` runs without `--workspace` from a directory that is not a known
|
|
105
|
+
Boxdown workspace, interactive terminals show a multi-select list of known
|
|
106
|
+
workspaces with existing repository paths. Non-interactive runs keep the
|
|
107
|
+
current-directory behavior.
|
|
108
|
+
|
|
109
|
+
Batch `down` continues after individual workspace failures, but exits nonzero if
|
|
110
|
+
any requested workspace cannot be resolved or removed.
|
|
111
|
+
|
|
112
|
+
When `purge` runs without `--workspace` from a tracked Boxdown workspace, it
|
|
113
|
+
purges that workspace after confirmation. When it runs without `--workspace`
|
|
114
|
+
from an untracked directory, interactive terminals show a multi-select list of
|
|
115
|
+
all tracked workspaces from `boxdown list`, including `running`, `exited`,
|
|
116
|
+
`absent`, `missing`, and `unknown` states. After selection, `purge` asks for one
|
|
117
|
+
destructive confirmation for the selected batch, then purges each selected
|
|
118
|
+
workspace in order. Batch purge continues after individual workspace failures,
|
|
119
|
+
but exits nonzero if any selected workspace fails.
|
|
120
|
+
|
|
121
|
+
In the interactive purge selector, the focused row color-codes only the state
|
|
122
|
+
token: `running` is green, `exited` is yellow, and `absent`, `missing`, or
|
|
123
|
+
`unknown` are red. These colors are terminal UI affordances only; scripts should
|
|
124
|
+
rely on text or JSON state values.
|
|
125
|
+
|
|
126
|
+
Interactive `purge` runs ask for confirmation before removing devcontainer,
|
|
127
|
+
image, SSH/Codex integration, cache, and data state. Non-interactive purge runs
|
|
128
|
+
do not prompt so existing targeted scripts keep working. Non-interactive
|
|
129
|
+
`purge` from an untracked directory fails safely instead of treating the current
|
|
130
|
+
directory as a workspace.
|
|
131
|
+
|
|
57
132
|
## Doctor
|
|
58
133
|
|
|
59
134
|
`doctor` validates required host prerequisites: Node, Docker CLI, Docker
|
|
60
135
|
daemon access, SSH tools, packaged devcontainer assets, and Boxdown's packaged
|
|
61
|
-
`@devcontainers/cli` dependency.
|
|
136
|
+
`@devcontainers/cli` dependency. It also uses a local Docker image, when one is
|
|
137
|
+
available, to create and immediately remove disposable containers that verify
|
|
138
|
+
Docker can bind-mount the workspace, Boxdown assets, and Boxdown runtime-state
|
|
139
|
+
paths. The probe never pulls an image or starts container code.
|
|
140
|
+
|
|
141
|
+
Known bind-mount/share failures are errors with the affected host path and
|
|
142
|
+
Docker Desktop remediation guidance. If Docker has no local image or the probe
|
|
143
|
+
cannot complete for another reason, doctor reports a warning instead.
|
|
144
|
+
|
|
145
|
+
`boxdown setup` runs the required doctor checks before it prompts, writes
|
|
146
|
+
workspace metadata, creates SSH keys, generates devcontainer configuration, or
|
|
147
|
+
starts Docker. Required failures stop setup; warnings remain non-blocking.
|
|
62
148
|
|
|
63
149
|
GitHub CLI auth is optional. Missing or unauthenticated `gh` is reported as a
|
|
64
150
|
warning rather than a failure.
|
|
151
|
+
|
|
152
|
+
Doctor uses the same SSH signing identity precedence as environment creation.
|
|
153
|
+
It honors an explicit `user.signingkey` public-key value or path, can select a
|
|
154
|
+
single GitHub authentication-key match from multiple loaded identities, and
|
|
155
|
+
checks the selected key's GitHub signing registration when available. Signing
|
|
156
|
+
readiness warnings never fail setup.
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
# Setup Command
|
|
2
|
+
|
|
3
|
+
## Command
|
|
4
|
+
|
|
5
|
+
```sh
|
|
6
|
+
boxdown setup
|
|
7
|
+
boxdown setup --target codex
|
|
8
|
+
boxdown setup --target claude
|
|
9
|
+
boxdown setup --recreate
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
`setup` prepares the current workspace for remote tools without opening an
|
|
13
|
+
interactive shell. It accepts:
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
--workspace <path>
|
|
17
|
+
--alias <name>
|
|
18
|
+
--recreate
|
|
19
|
+
--target <name>
|
|
20
|
+
--verbose
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Flow
|
|
24
|
+
|
|
25
|
+
1. Resolve the workspace to a real absolute path.
|
|
26
|
+
2. Ensure per-workspace SSH key material exists.
|
|
27
|
+
3. Generate a Boxdown-owned devcontainer config.
|
|
28
|
+
4. Run `devcontainer up --workspace-folder <repo> --override-config <config>`.
|
|
29
|
+
5. Install or update the Boxdown-managed SSH alias.
|
|
30
|
+
6. Optionally install selected SSH targets such as Codex or Claude.
|
|
31
|
+
|
|
32
|
+
`setup` prints plain progress sections by default. Docker, Dev Containers CLI,
|
|
33
|
+
and lifecycle hook output is captured and only summarized if a command fails.
|
|
34
|
+
Pass `--verbose` to stream the raw build and hook logs to the terminal.
|
|
35
|
+
|
|
36
|
+
Boxdown also appends the managed setup output to the workspace command log at:
|
|
37
|
+
|
|
38
|
+
```text
|
|
39
|
+
~/.local/share/boxdown/workspaces/<workspace-hash>/boxdown.log
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The log is written regardless of `--verbose`; the flag only changes terminal
|
|
43
|
+
streaming.
|
|
44
|
+
|
|
45
|
+
When `--target codex` is provided, Boxdown writes the Codex app config entry for
|
|
46
|
+
the same alias and container-side project path used by:
|
|
47
|
+
|
|
48
|
+
```sh
|
|
49
|
+
boxdown ssh install --target codex
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
When `--target claude` is provided, Boxdown writes the Claude app SSH remote
|
|
53
|
+
entry for the same alias used by:
|
|
54
|
+
|
|
55
|
+
```sh
|
|
56
|
+
boxdown ssh install --target claude
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
When no target is provided, Boxdown uses the same optional target prompt as
|
|
60
|
+
`boxdown ssh install`. In non-interactive shells, setup skips target
|
|
61
|
+
registration unless `--target` is provided.
|
|
62
|
+
|
|
63
|
+
`setup` does not open a shell, launch a coding-agent CLI, or keep a tunnel in the
|
|
64
|
+
foreground. Use `boxdown start`, `boxdown codex`, or `boxdown tunnel` for those
|
|
65
|
+
foreground workflows. Those commands log Boxdown-managed startup steps, but do
|
|
66
|
+
not tee full interactive shell, agent, or tunnel session bytes into the log.
|