boxdown 1.2.0 → 1.3.0
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 +10 -0
- package/assets/devcontainer/README.md +29 -6
- package/assets/devcontainer/devcontainer.json +4 -9
- package/assets/devcontainer/hooks/initialize.sh +49 -27
- package/assets/devcontainer/hooks/post-create.sh +23 -1
- package/assets/devcontainer/hooks/post-start.sh +0 -10
- package/assets/devcontainer/utils/git-signing-bootstrap.sh +58 -5
- 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/dist/bin/cli.cjs +1 -1
- package/dist/bin/cli.mjs +1 -1
- package/dist/{main-Df4E8ARj.cjs → main-CT2n9qcb.cjs} +907 -266
- package/dist/{main-XMBsKjIK.mjs → main-O__JaiXe.mjs} +891 -268
- package/dist/main-O__JaiXe.mjs.map +1 -0
- package/dist/main.cjs +4 -1
- package/dist/main.d.cts +98 -26
- package/dist/main.d.cts.map +1 -1
- package/dist/main.d.mts +98 -26
- package/dist/main.d.mts.map +1 -1
- package/dist/main.mjs +2 -2
- package/docs/features/commit-signing.md +71 -0
- package/docs/features/generated-config-and-state.md +19 -4
- package/docs/features/github-auth-refresh.md +3 -2
- package/docs/features/lifecycle.md +19 -0
- package/docs/features/setup.md +5 -0
- package/docs/features/start-and-shell.md +10 -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/plans/2026-07-18-architecture-aware-1password-installer.md +163 -0
- package/docs/superpowers/plans/2026-07-18-devcontainer-node-image-digest.md +341 -0
- package/docs/superpowers/plans/2026-07-19-container-runtime-readiness.md +1536 -0
- package/docs/superpowers/specs/2026-07-11-default-commit-signing-design.md +20 -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/superpowers/specs/2026-07-18-architecture-aware-1password-installer-design.md +63 -0
- package/docs/superpowers/specs/2026-07-18-devcontainer-node-image-digest-design.md +108 -0
- package/docs/superpowers/specs/2026-07-19-container-runtime-readiness-design.md +353 -0
- package/package.json +1 -1
- package/src/config.ts +14 -2
- package/src/constants.ts +7 -0
- package/src/container-runtime.ts +295 -0
- package/src/devcontainer.ts +57 -30
- package/src/doctor.ts +169 -46
- package/src/git-signing.ts +205 -25
- package/src/logging.ts +11 -1
- package/src/main.ts +97 -12
- package/src/paths.ts +21 -1
- package/src/process.ts +50 -10
- package/src/progress.ts +63 -8
- package/src/purge.ts +8 -0
- package/src/shell.ts +6 -0
- package/dist/main-XMBsKjIK.mjs.map +0 -1
|
@@ -0,0 +1,353 @@
|
|
|
1
|
+
# Container Runtime Readiness and Lifecycle Preflight
|
|
2
|
+
|
|
3
|
+
## Goal
|
|
4
|
+
|
|
5
|
+
Make every Boxdown command that can create or start a devcontainer recover
|
|
6
|
+
cleanly when Docker has just been launched, while preserving `boxdown start` as
|
|
7
|
+
a standalone command after a missing or failed `boxdown setup`.
|
|
8
|
+
|
|
9
|
+
## Problem
|
|
10
|
+
|
|
11
|
+
`boxdown setup` currently runs required host-readiness checks before prompts,
|
|
12
|
+
workspace state, or Docker work. Other commands that can create a container do
|
|
13
|
+
not share that gate. A user can therefore run setup while Docker is stopped,
|
|
14
|
+
start Docker, and then run `boxdown start` while Docker Desktop or its selected
|
|
15
|
+
Buildx builder is still initializing. The Dev Containers CLI proceeds far
|
|
16
|
+
enough to invoke `docker buildx build`, then returns a generic JSON error
|
|
17
|
+
envelope that does not explain the lifecycle gap.
|
|
18
|
+
|
|
19
|
+
The existing checks also establish only that the Docker CLI exists and that the
|
|
20
|
+
daemon answers `docker info`. They do not distinguish these Buildx states:
|
|
21
|
+
|
|
22
|
+
- Buildx is unavailable and the Dev Containers CLI will use its supported
|
|
23
|
+
classic-build fallback.
|
|
24
|
+
- Buildx is discoverable but its selected builder is not operational yet.
|
|
25
|
+
- Buildx is operational and ready for a Feature image build.
|
|
26
|
+
|
|
27
|
+
## Decisions
|
|
28
|
+
|
|
29
|
+
- `boxdown start` remains valid without a successful prior setup.
|
|
30
|
+
- Start does not install setup-only SSH aliases or external app integrations.
|
|
31
|
+
- Commands that may create or start a container share one readiness gate.
|
|
32
|
+
- Transient Docker daemon and Buildx builder failures are polled once per second
|
|
33
|
+
for at most 60 seconds.
|
|
34
|
+
- A missing Docker executable is terminal and fails immediately.
|
|
35
|
+
- Missing Buildx is non-blocking because the bundled Dev Containers CLI already
|
|
36
|
+
supports a non-Buildx build path.
|
|
37
|
+
- Discoverable but unusable Buildx is transient until the readiness deadline,
|
|
38
|
+
then terminal with the last builder diagnostic.
|
|
39
|
+
- `devcontainer up` is invoked once after readiness succeeds. Boxdown does not
|
|
40
|
+
retry genuine image, Feature, Dockerfile, registry, or lifecycle failures.
|
|
41
|
+
- Workspace metadata remains inventory for a workspace Boxdown has touched; it
|
|
42
|
+
does not become a setup-completion record.
|
|
43
|
+
- No `setupCompleted` field or migration is introduced.
|
|
44
|
+
|
|
45
|
+
## Alternatives Considered
|
|
46
|
+
|
|
47
|
+
### Shared CLI lifecycle gate
|
|
48
|
+
|
|
49
|
+
This is the selected design. A focused container-runtime module owns probing
|
|
50
|
+
and bounded waiting. CLI lifecycle orchestration calls it before metadata or
|
|
51
|
+
container work, and `doctor` reuses the same single-attempt probe semantics.
|
|
52
|
+
|
|
53
|
+
This keeps host-runtime policy out of devcontainer configuration code, makes
|
|
54
|
+
the command scope explicit, and preserves setup's stronger ordering.
|
|
55
|
+
|
|
56
|
+
### Readiness inside `startDevcontainer`
|
|
57
|
+
|
|
58
|
+
Putting the gate in `startDevcontainer` would make it difficult for a caller to
|
|
59
|
+
forget the check. It would, however, run after setup has already entered its
|
|
60
|
+
workflow unless setup retained a second preflight. It would also couple Docker
|
|
61
|
+
host diagnostics and waiting policy to the lower-level devcontainer lifecycle
|
|
62
|
+
implementation.
|
|
63
|
+
|
|
64
|
+
### Retry `devcontainer up`
|
|
65
|
+
|
|
66
|
+
Retrying the failed Dev Containers command is too late and cannot reliably
|
|
67
|
+
distinguish runtime initialization from a real build failure. It could repeat
|
|
68
|
+
expensive work or obscure an actionable Feature, registry, or Dockerfile error.
|
|
69
|
+
|
|
70
|
+
## Architecture
|
|
71
|
+
|
|
72
|
+
### Container runtime module
|
|
73
|
+
|
|
74
|
+
Add `src/container-runtime.ts` as the single owner of Docker and Buildx
|
|
75
|
+
readiness semantics. It exposes two levels of behavior:
|
|
76
|
+
|
|
77
|
+
- A single-attempt probe used by `doctor` and by each waiter iteration.
|
|
78
|
+
- A bounded waiter used before container-creating lifecycle commands.
|
|
79
|
+
|
|
80
|
+
The module accepts an injected command runner, clock, and sleep function so its
|
|
81
|
+
tests do not use the real Docker daemon or wall-clock delays.
|
|
82
|
+
|
|
83
|
+
The probe returns a structured result rather than throwing. Its stable states
|
|
84
|
+
are:
|
|
85
|
+
|
|
86
|
+
- `ready`: Docker is reachable and Buildx is either operational or unavailable
|
|
87
|
+
with a supported fallback.
|
|
88
|
+
- `waiting`: Docker or a discoverable Buildx builder may still become ready.
|
|
89
|
+
- `failed`: a terminal prerequisite is missing.
|
|
90
|
+
|
|
91
|
+
The structured result includes:
|
|
92
|
+
|
|
93
|
+
- the high-level reason;
|
|
94
|
+
- whether the Dev Containers CLI will use Buildx or its fallback;
|
|
95
|
+
- the command whose last attempt failed;
|
|
96
|
+
- compact stdout/stderr detail suitable for an actionable error; and
|
|
97
|
+
- non-blocking warnings.
|
|
98
|
+
|
|
99
|
+
The stable terminal and transient reasons are:
|
|
100
|
+
|
|
101
|
+
- `docker-cli-unavailable`: terminal;
|
|
102
|
+
- `docker-daemon-unavailable`: transient until timeout;
|
|
103
|
+
- `buildx-builder-unavailable`: transient until timeout.
|
|
104
|
+
|
|
105
|
+
### Readiness commands
|
|
106
|
+
|
|
107
|
+
Each probe performs only the commands required by the state reached:
|
|
108
|
+
|
|
109
|
+
1. Run `docker --version`. A spawn failure or any nonzero exit produces the
|
|
110
|
+
terminal `docker-cli-unavailable` result.
|
|
111
|
+
2. Run `docker info`. A nonzero result produces the transient
|
|
112
|
+
`docker-daemon-unavailable` result.
|
|
113
|
+
3. Run `docker buildx version`. A nonzero result produces a ready result with a
|
|
114
|
+
fallback warning; it does not block container startup.
|
|
115
|
+
4. Run `docker buildx inspect --bootstrap`. A nonzero result produces the
|
|
116
|
+
transient `buildx-builder-unavailable` result. Success produces Buildx-ready
|
|
117
|
+
status.
|
|
118
|
+
|
|
119
|
+
`--bootstrap` is intentional: the selected builder is the builder the Dev
|
|
120
|
+
Containers CLI will use, and readiness must establish that it can start before
|
|
121
|
+
Boxdown begins the Feature build. The command may initialize a selected custom
|
|
122
|
+
builder, but Boxdown does not create, replace, select, or delete builders.
|
|
123
|
+
|
|
124
|
+
### Bounded waiter
|
|
125
|
+
|
|
126
|
+
The waiter uses these defaults:
|
|
127
|
+
|
|
128
|
+
- timeout: 60,000 milliseconds;
|
|
129
|
+
- poll interval: 1,000 milliseconds;
|
|
130
|
+
- first probe: immediate;
|
|
131
|
+
- deadline behavior: retain and report the final failed probe;
|
|
132
|
+
- terminal failure behavior: return immediately without sleeping.
|
|
133
|
+
|
|
134
|
+
The waiter never launches Docker Desktop or modifies Docker contexts. It gives
|
|
135
|
+
a daemon or builder that the user has already launched time to become ready.
|
|
136
|
+
|
|
137
|
+
## Command Scope and Data Flow
|
|
138
|
+
|
|
139
|
+
The readiness gate applies to commands that may create or start a container:
|
|
140
|
+
|
|
141
|
+
| Command path | Waits for readiness | May create/start |
|
|
142
|
+
| --- | --- | --- |
|
|
143
|
+
| `setup` | Yes | Yes |
|
|
144
|
+
| `start` / `shell` | Yes | Yes |
|
|
145
|
+
| `ssh-proxy` | Yes | Yes |
|
|
146
|
+
| `tunnel` | Yes | Yes |
|
|
147
|
+
| `refresh-gh-token` | Yes | Yes |
|
|
148
|
+
| `codex`, `claude`, `opencode`, `antigravity` | Yes | Yes |
|
|
149
|
+
| `refresh-gh-token-running` | No | No |
|
|
150
|
+
| `ssh install`, `ssh uninstall` | No | No |
|
|
151
|
+
| `doctor`, `status`, `list` | No wait | No |
|
|
152
|
+
| `stop`, `down`, `purge` | No bring-up wait | No |
|
|
153
|
+
|
|
154
|
+
`doctor` performs one readiness snapshot and reports it; it does not poll for
|
|
155
|
+
60 seconds.
|
|
156
|
+
|
|
157
|
+
For non-setup container lifecycle commands, the sequence is:
|
|
158
|
+
|
|
159
|
+
1. Resolve the workspace and alias.
|
|
160
|
+
2. Create the managed command logger so readiness details can be preserved.
|
|
161
|
+
3. Wait for container-runtime readiness.
|
|
162
|
+
4. Write workspace inventory metadata.
|
|
163
|
+
5. Generate runtime configuration and invoke the requested lifecycle.
|
|
164
|
+
|
|
165
|
+
A readiness failure may leave a diagnostic command log, but it does not create
|
|
166
|
+
workspace metadata, generated devcontainer configuration, an SSH identity, or a
|
|
167
|
+
container.
|
|
168
|
+
|
|
169
|
+
Setup retains stronger state-free ordering:
|
|
170
|
+
|
|
171
|
+
1. Wait for container-runtime readiness without creating a workspace logger.
|
|
172
|
+
2. Run the remaining required doctor checks.
|
|
173
|
+
3. Show optional-target prompts.
|
|
174
|
+
4. Write inventory metadata.
|
|
175
|
+
5. Start the container and install the SSH alias and selected integrations.
|
|
176
|
+
|
|
177
|
+
This preserves the existing contract that setup preflight failures do not
|
|
178
|
+
create workspace data. Setup reports its final readiness diagnostic directly
|
|
179
|
+
because no managed log exists yet.
|
|
180
|
+
|
|
181
|
+
## User Experience
|
|
182
|
+
|
|
183
|
+
Interactive mode adds one stable checklist step labelled `Checking container
|
|
184
|
+
runtime`. When a transient condition is observed, the detail changes to either
|
|
185
|
+
`Waiting for Docker daemon` or `Waiting for Docker Buildx builder`. Individual
|
|
186
|
+
poll attempts do not add terminal lines or restart the spinner.
|
|
187
|
+
|
|
188
|
+
Verbose mode prints the first transient observation, state transitions, and
|
|
189
|
+
final outcome. It does not print identical output once per second.
|
|
190
|
+
|
|
191
|
+
When Buildx is unavailable, Boxdown emits one warning that the Dev Containers
|
|
192
|
+
CLI will use its fallback. It then proceeds without a delay.
|
|
193
|
+
|
|
194
|
+
Timeout errors include:
|
|
195
|
+
|
|
196
|
+
- the failed capability;
|
|
197
|
+
- the 60-second timeout;
|
|
198
|
+
- the last compact command diagnostic;
|
|
199
|
+
- an appropriate manual check, `docker info` or `docker buildx inspect`; and
|
|
200
|
+
- the workspace command-log path when the command has an active logger.
|
|
201
|
+
|
|
202
|
+
Examples of error summaries are:
|
|
203
|
+
|
|
204
|
+
```text
|
|
205
|
+
Docker daemon did not become ready within 60 seconds.
|
|
206
|
+
Last check: docker info
|
|
207
|
+
Detail: Cannot connect to the Docker daemon ...
|
|
208
|
+
Check Docker with: docker info
|
|
209
|
+
Command log: /path/to/boxdown.log
|
|
210
|
+
```
|
|
211
|
+
|
|
212
|
+
```text
|
|
213
|
+
Docker Buildx builder did not become ready within 60 seconds.
|
|
214
|
+
Last check: docker buildx inspect --bootstrap
|
|
215
|
+
Detail: failed to initialize builder ...
|
|
216
|
+
Check Buildx with: docker buildx inspect
|
|
217
|
+
Command log: /path/to/boxdown.log
|
|
218
|
+
```
|
|
219
|
+
|
|
220
|
+
## Dev Containers Failure Reporting
|
|
221
|
+
|
|
222
|
+
Readiness success marks the boundary between runtime initialization and the
|
|
223
|
+
actual Dev Containers lifecycle. Any subsequent `devcontainer up` failure is
|
|
224
|
+
reported without an automatic retry.
|
|
225
|
+
|
|
226
|
+
The concise failure formatter will:
|
|
227
|
+
|
|
228
|
+
- handle a zero line budget as zero lines instead of using `.slice(-0)`;
|
|
229
|
+
- preserve stderr before allocating remaining space to stdout;
|
|
230
|
+
- recognize a Dev Containers JSON object with `outcome: "error"` as a wrapper;
|
|
231
|
+
- avoid presenting the wrapper's repeated build command as the root cause when
|
|
232
|
+
more specific stderr exists;
|
|
233
|
+
- state explicitly when the wrapper contains no nested Docker diagnostic;
|
|
234
|
+
- include the managed command-log path when available; and
|
|
235
|
+
- retain the `--verbose` recovery instruction.
|
|
236
|
+
|
|
237
|
+
The full redacted stdout and stderr streams continue to be stored by the
|
|
238
|
+
existing workspace command logger. The readiness work does not weaken current
|
|
239
|
+
secret redaction.
|
|
240
|
+
|
|
241
|
+
## Workspace State Semantics
|
|
242
|
+
|
|
243
|
+
`boxdown start` is a recovery-capable standalone command. It may create the
|
|
244
|
+
Boxdown SSH identity and generated devcontainer config required for container
|
|
245
|
+
operation, but it does not install an SSH host alias or modify Codex or Claude
|
|
246
|
+
application configuration.
|
|
247
|
+
|
|
248
|
+
Workspace metadata continues to mean that Boxdown reached a ready runtime and
|
|
249
|
+
attempted a lifecycle for that workspace. A build failure after readiness may
|
|
250
|
+
therefore leave metadata and a diagnostic log. A readiness failure leaves no
|
|
251
|
+
metadata. This distinction does not require a metadata schema change.
|
|
252
|
+
|
|
253
|
+
## Testing Strategy
|
|
254
|
+
|
|
255
|
+
### Container-runtime unit tests
|
|
256
|
+
|
|
257
|
+
Use an injected command runner to verify:
|
|
258
|
+
|
|
259
|
+
- missing Docker exits immediately with `docker-cli-unavailable`;
|
|
260
|
+
- an unavailable daemon returns `docker-daemon-unavailable` without probing
|
|
261
|
+
Buildx;
|
|
262
|
+
- missing Buildx returns ready fallback status and one warning;
|
|
263
|
+
- successful Buildx version plus failed bootstrap returns
|
|
264
|
+
`buildx-builder-unavailable`;
|
|
265
|
+
- successful Docker, Buildx version, and bootstrap returns Buildx-ready status;
|
|
266
|
+
- command output is compacted and retained in failure details.
|
|
267
|
+
|
|
268
|
+
Use injected clock and sleep functions to verify:
|
|
269
|
+
|
|
270
|
+
- the first probe happens without sleeping;
|
|
271
|
+
- two transient failures followed by success produce exactly two sleeps;
|
|
272
|
+
- terminal failures never sleep;
|
|
273
|
+
- polling stops at the 60-second deadline;
|
|
274
|
+
- the timeout reports the last probe rather than the first; and
|
|
275
|
+
- identical transient output does not create repeated user-facing messages.
|
|
276
|
+
|
|
277
|
+
### CLI lifecycle tests
|
|
278
|
+
|
|
279
|
+
Extend the existing CLI execution tests to verify:
|
|
280
|
+
|
|
281
|
+
- `start` after a failed setup can proceed when runtime readiness becomes
|
|
282
|
+
healthy;
|
|
283
|
+
- readiness runs before metadata for each container-creating command path;
|
|
284
|
+
- readiness failure creates no metadata, generated config, SSH key, or
|
|
285
|
+
container call;
|
|
286
|
+
- setup still performs readiness before prompts or state writes;
|
|
287
|
+
- `refresh-gh-token-running` and SSH-only commands do not wait;
|
|
288
|
+
- every coding-agent command shares the same gate; and
|
|
289
|
+
- a post-readiness `devcontainer up` failure is invoked once and not retried.
|
|
290
|
+
|
|
291
|
+
Command-scope coverage will use a table-driven test so adding a new
|
|
292
|
+
container-creating CLI command requires an explicit readiness decision.
|
|
293
|
+
|
|
294
|
+
### Failure-formatting tests
|
|
295
|
+
|
|
296
|
+
Verify that:
|
|
297
|
+
|
|
298
|
+
- a zero stdout line budget produces no stdout lines;
|
|
299
|
+
- specific stderr is retained ahead of the generic JSON wrapper;
|
|
300
|
+
- a wrapper-only failure explains that the nested diagnostic was unavailable;
|
|
301
|
+
- logged lifecycle failures show the exact command-log path; and
|
|
302
|
+
- secret redaction remains unchanged.
|
|
303
|
+
|
|
304
|
+
### Complete verification
|
|
305
|
+
|
|
306
|
+
After the focused tests pass, run:
|
|
307
|
+
|
|
308
|
+
```sh
|
|
309
|
+
pnpm test
|
|
310
|
+
pnpm lint
|
|
311
|
+
pnpm build
|
|
312
|
+
git diff --check
|
|
313
|
+
```
|
|
314
|
+
|
|
315
|
+
No automated test requires a real Docker daemon, Docker Desktop, registry
|
|
316
|
+
network access, or wall-clock waiting.
|
|
317
|
+
|
|
318
|
+
## Documentation
|
|
319
|
+
|
|
320
|
+
Update the README and lifecycle documentation to state that:
|
|
321
|
+
|
|
322
|
+
- `start` works without a completed setup;
|
|
323
|
+
- setup-only SSH and application integrations remain exclusive to setup;
|
|
324
|
+
- container-creating commands wait up to 60 seconds for Docker and an available
|
|
325
|
+
Buildx builder;
|
|
326
|
+
- missing Buildx uses the Dev Containers CLI fallback; and
|
|
327
|
+
- timeout errors point to `docker info`, `docker buildx inspect`, and the
|
|
328
|
+
workspace command log.
|
|
329
|
+
|
|
330
|
+
## Non-Goals
|
|
331
|
+
|
|
332
|
+
- Launching or restarting Docker Desktop automatically.
|
|
333
|
+
- Creating, selecting, repairing, or deleting Buildx builders.
|
|
334
|
+
- Retrying `devcontainer up` or individual Docker builds.
|
|
335
|
+
- Classifying every possible Docker, registry, Feature, or Dockerfile error.
|
|
336
|
+
- Adding setup-completion state or migrating workspace metadata.
|
|
337
|
+
- Changing the packaged Node base image or Dev Container Feature pins.
|
|
338
|
+
- Installing setup-only SSH or external app integrations from `start`.
|
|
339
|
+
|
|
340
|
+
## Success Criteria
|
|
341
|
+
|
|
342
|
+
- A user can run `start` after a failed setup and recover once Docker becomes
|
|
343
|
+
ready, without rerunning setup.
|
|
344
|
+
- Docker and Buildx startup races receive a bounded wait rather than an opaque
|
|
345
|
+
immediate build failure.
|
|
346
|
+
- Every current container-creating command uses the shared readiness contract.
|
|
347
|
+
- Readiness failures do not create workspace metadata, generated config, an SSH
|
|
348
|
+
identity, or a container. Non-setup lifecycle commands may retain only their
|
|
349
|
+
diagnostic command log.
|
|
350
|
+
- Genuine post-readiness build failures execute once and retain their useful
|
|
351
|
+
diagnostic context.
|
|
352
|
+
- Setup preserves its state-free preflight ordering.
|
|
353
|
+
- Existing workspaces require no metadata migration.
|
package/package.json
CHANGED
package/src/config.ts
CHANGED
|
@@ -8,6 +8,8 @@ import {
|
|
|
8
8
|
BOXDOWN_CONTAINER_DEVCONTAINER_DIR,
|
|
9
9
|
BOXDOWN_CONTAINER_GITCONFIG_PATH,
|
|
10
10
|
BOXDOWN_CONTAINER_HOST_GITCONFIG_DIR,
|
|
11
|
+
BOXDOWN_CONTAINER_SECRET_ENV_BOOTSTRAP,
|
|
12
|
+
BOXDOWN_CONTAINER_SECRET_ENV_DIR,
|
|
11
13
|
BOXDOWN_CONTAINER_SSH_DIR,
|
|
12
14
|
BOXDOWN_CONTAINER_SSH_PUBLIC_KEY_PATH
|
|
13
15
|
} from './constants.ts'
|
|
@@ -67,7 +69,8 @@ export function buildGeneratedDevcontainerConfig (context: WorkspaceContext, sig
|
|
|
67
69
|
const boxdownMounts = [
|
|
68
70
|
`type=bind,source=${context.assetsDevcontainerDir},target=${BOXDOWN_CONTAINER_DEVCONTAINER_DIR},readonly`,
|
|
69
71
|
`type=bind,source=${context.sshPublicKeyRuntimeDir},target=${BOXDOWN_CONTAINER_SSH_DIR},readonly`,
|
|
70
|
-
`type=bind,source=${context.hostGitconfigSnapshotDir},target=${BOXDOWN_CONTAINER_HOST_GITCONFIG_DIR},readonly
|
|
72
|
+
`type=bind,source=${context.hostGitconfigSnapshotDir},target=${BOXDOWN_CONTAINER_HOST_GITCONFIG_DIR},readonly`,
|
|
73
|
+
`type=bind,source=${context.workspaceSecretEnvDir},target=${BOXDOWN_CONTAINER_SECRET_ENV_DIR},readonly`
|
|
71
74
|
]
|
|
72
75
|
|
|
73
76
|
if (
|
|
@@ -98,6 +101,7 @@ export function buildGeneratedDevcontainerConfig (context: WorkspaceContext, sig
|
|
|
98
101
|
`BOXDOWN_WORKSPACE_FOLDER=${shellQuote(context.workspaceFolder)}`,
|
|
99
102
|
`BOXDOWN_HOST_GITCONFIG_PATH=${shellQuote(context.hostGitconfigPath)}`,
|
|
100
103
|
`BOXDOWN_HOST_GITCONFIG_SNAPSHOT_PATH=${shellQuote(context.hostGitconfigSnapshotPath)}`,
|
|
104
|
+
`BOXDOWN_SECRET_ENV_DIR=${shellQuote(context.workspaceSecretEnvDir)}`,
|
|
101
105
|
`BOXDOWN_PROGRESS=${shellQuote('${localEnv:BOXDOWN_PROGRESS}')}`,
|
|
102
106
|
`BOXDOWN_VERBOSE=${shellQuote('${localEnv:BOXDOWN_VERBOSE}')}`,
|
|
103
107
|
'bash',
|
|
@@ -119,10 +123,18 @@ export function buildGeneratedDevcontainerConfig (context: WorkspaceContext, sig
|
|
|
119
123
|
...(baseConfig.containerEnv ?? {}),
|
|
120
124
|
BOXDOWN_CONTAINER_WORKSPACE_FOLDER: '/workspaces/${localWorkspaceFolderBasename}',
|
|
121
125
|
BOXDOWN_WORKSPACE_BASENAME: '${localWorkspaceFolderBasename}',
|
|
126
|
+
BOXDOWN_SECRET_ENV_DIR: BOXDOWN_CONTAINER_SECRET_ENV_DIR,
|
|
127
|
+
BASH_ENV: BOXDOWN_CONTAINER_SECRET_ENV_BOOTSTRAP,
|
|
122
128
|
DEVCONTAINER_SSH_PUBLIC_KEY_FILE: BOXDOWN_CONTAINER_SSH_PUBLIC_KEY_PATH,
|
|
123
129
|
BOXDOWN_GIT_SIGNING_ENABLED: signing?.enabled === true ? '1' : '0',
|
|
124
130
|
BOXDOWN_GIT_SIGNING_KEY_PATH: '/opt/boxdown/state/git-signing/signing-key.pub',
|
|
125
|
-
...(signing?.enabled ===
|
|
131
|
+
...(signing?.enabled === false && signing.reason !== undefined ? { BOXDOWN_GIT_SIGNING_REASON: signing.reason } : {}),
|
|
132
|
+
...(signing?.enabled === true
|
|
133
|
+
? {
|
|
134
|
+
BOXDOWN_GIT_SIGNING_SOURCE_SOCKET: '/run/boxdown/ssh-agent.sock',
|
|
135
|
+
SSH_AUTH_SOCK: '/run/boxdown/ssh-agent-node.sock'
|
|
136
|
+
}
|
|
137
|
+
: {})
|
|
126
138
|
}
|
|
127
139
|
}
|
|
128
140
|
}
|
package/src/constants.ts
CHANGED
|
@@ -10,5 +10,12 @@ export const BOXDOWN_CONTAINER_AGENTS_DIR = '/home/node/.agents'
|
|
|
10
10
|
export const BOXDOWN_CONTAINER_GITCONFIG_PATH = '/home/node/.gitconfig'
|
|
11
11
|
export const BOXDOWN_CONTAINER_CODEX_DIR = '/home/node/.codex'
|
|
12
12
|
export const BOXDOWN_CONTAINER_CODEX_AUTH_PATH = `${BOXDOWN_CONTAINER_CODEX_DIR}/auth.json`
|
|
13
|
+
export const BOXDOWN_CONTAINER_SECRET_ENV_DIR = '/run/boxdown/secrets'
|
|
14
|
+
export const BOXDOWN_CONTAINER_SECRET_ENV_BOOTSTRAP = `${BOXDOWN_CONTAINER_DEVCONTAINER_DIR}/utils/secret-env-bootstrap.sh`
|
|
15
|
+
export const BOXDOWN_SECRET_ENV_NAMES = [
|
|
16
|
+
'ANTHROPIC_API_KEY',
|
|
17
|
+
'SNYK_TOKEN',
|
|
18
|
+
'OP_SERVICE_ACCOUNT_TOKEN'
|
|
19
|
+
] as const
|
|
13
20
|
|
|
14
21
|
export const PACKAGE_NAME = 'boxdown'
|