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
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
# @options
|
|
18
18
|
# --shell Start the dev container and attach an interactive shell (default).
|
|
19
19
|
# --ssh-proxy Start/reuse the dev container and proxy SSH over docker exec.
|
|
20
|
-
# ssh
|
|
20
|
+
# ssh install
|
|
21
21
|
# Install/update the host SSH config alias and exit.
|
|
22
22
|
# --refresh-gh-token
|
|
23
23
|
# Start/reuse the dev container, then refresh container GitHub CLI
|
|
@@ -27,11 +27,12 @@
|
|
|
27
27
|
# when the dev container is already running.
|
|
28
28
|
# --recreate Remove the existing dev container for this workspace before `up`, so
|
|
29
29
|
# changes to runArgs (or other create-time settings) take effect.
|
|
30
|
+
# --verbose Stream raw devcontainer, Docker, and hook output.
|
|
30
31
|
# --help, -h Print usage and exit.
|
|
31
32
|
#
|
|
32
33
|
# @example
|
|
33
34
|
# .devcontainer/start.sh
|
|
34
|
-
# .devcontainer/start.sh ssh
|
|
35
|
+
# .devcontainer/start.sh ssh install
|
|
35
36
|
# .devcontainer/start.sh --ssh-proxy
|
|
36
37
|
# .devcontainer/start.sh --refresh-gh-token
|
|
37
38
|
# .devcontainer/start.sh --refresh-gh-token-running
|
|
@@ -51,7 +52,13 @@ SSH_KEY_DIR="${DEVCONTAINER_SSH_KEY_DIR:-${SCRIPT_DIR}/.ssh}"
|
|
|
51
52
|
SSH_KEY_PATH="${DEVCONTAINER_SSH_KEY_PATH:-${SSH_KEY_DIR}/id_ed25519}"
|
|
52
53
|
MODE="shell"
|
|
53
54
|
RECREATE=false
|
|
55
|
+
VERBOSE=false
|
|
54
56
|
CONTAINER_ID=""
|
|
57
|
+
PROGRESS_STEP_IDS=()
|
|
58
|
+
PROGRESS_STEP_LABELS=()
|
|
59
|
+
PROGRESS_STEP_STATES=()
|
|
60
|
+
PROGRESS_RENDERED_STEP_LINE_COUNT=0
|
|
61
|
+
PROGRESS_CHECKLIST_PID=""
|
|
55
62
|
|
|
56
63
|
usage() {
|
|
57
64
|
cat <<EOF
|
|
@@ -74,10 +81,11 @@ Options:
|
|
|
74
81
|
when the dev container is already running.
|
|
75
82
|
--recreate Remove the existing dev container for this workspace before starting,
|
|
76
83
|
so Docker picks up new settings (e.g. runArgs / port mappings).
|
|
84
|
+
--verbose Stream raw devcontainer, Docker, and hook output.
|
|
77
85
|
--help, -h Show this help and exit.
|
|
78
86
|
|
|
79
87
|
Commands:
|
|
80
|
-
ssh
|
|
88
|
+
ssh install
|
|
81
89
|
Install/update the host SSH config alias and exit.
|
|
82
90
|
|
|
83
91
|
Notes:
|
|
@@ -100,6 +108,382 @@ log() {
|
|
|
100
108
|
fi
|
|
101
109
|
}
|
|
102
110
|
|
|
111
|
+
log_raw() {
|
|
112
|
+
if [ "$MODE" = "ssh-proxy" ]; then
|
|
113
|
+
printf '%b' "$*" >&2
|
|
114
|
+
else
|
|
115
|
+
printf '%b' "$*"
|
|
116
|
+
fi
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
supports_progress_tty() {
|
|
120
|
+
if [ "$MODE" = "ssh-proxy" ]; then
|
|
121
|
+
[ -t 2 ]
|
|
122
|
+
else
|
|
123
|
+
[ -t 1 ]
|
|
124
|
+
fi
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
style() {
|
|
128
|
+
local code="$1"
|
|
129
|
+
local text="$2"
|
|
130
|
+
|
|
131
|
+
if supports_progress_tty; then
|
|
132
|
+
printf '\033[%sm%s\033[0m' "$code" "$text"
|
|
133
|
+
else
|
|
134
|
+
printf '%s' "$text"
|
|
135
|
+
fi
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
style_bold() { style 1 "$1"; }
|
|
139
|
+
style_cyan() { style 36 "$1"; }
|
|
140
|
+
style_dim() { style 2 "$1"; }
|
|
141
|
+
style_green() { style 32 "$1"; }
|
|
142
|
+
progress_rail() { style_cyan "│"; }
|
|
143
|
+
|
|
144
|
+
progress_section() {
|
|
145
|
+
if [ "$VERBOSE" = true ]; then
|
|
146
|
+
return 0
|
|
147
|
+
fi
|
|
148
|
+
|
|
149
|
+
log "$(style_cyan "◆") $(style_bold "$*")"
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
progress_end() {
|
|
153
|
+
if [ "$VERBOSE" = true ]; then
|
|
154
|
+
return 0
|
|
155
|
+
fi
|
|
156
|
+
|
|
157
|
+
stop_spinner clear
|
|
158
|
+
progress_stop_checklist_timer
|
|
159
|
+
log "$(style_cyan "└")"
|
|
160
|
+
PROGRESS_STEP_IDS=()
|
|
161
|
+
PROGRESS_STEP_LABELS=()
|
|
162
|
+
PROGRESS_STEP_STATES=()
|
|
163
|
+
PROGRESS_RENDERED_STEP_LINE_COUNT=0
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
progress_item() {
|
|
167
|
+
if [ "$VERBOSE" = true ]; then
|
|
168
|
+
return 0
|
|
169
|
+
fi
|
|
170
|
+
|
|
171
|
+
log "$(progress_rail) $(style_green "■") $*"
|
|
172
|
+
}
|
|
173
|
+
|
|
174
|
+
progress_running() {
|
|
175
|
+
if [ "$VERBOSE" = true ]; then
|
|
176
|
+
return 0
|
|
177
|
+
fi
|
|
178
|
+
|
|
179
|
+
log "$(progress_rail) $(style_cyan "◒") $*"
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
progress_detail() {
|
|
183
|
+
if [ "$VERBOSE" = true ]; then
|
|
184
|
+
return 0
|
|
185
|
+
fi
|
|
186
|
+
|
|
187
|
+
log "$(progress_rail) $(style_dim "$*")"
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
progress_warn() {
|
|
191
|
+
if [ "$VERBOSE" = true ]; then
|
|
192
|
+
return 0
|
|
193
|
+
fi
|
|
194
|
+
|
|
195
|
+
log "$(progress_rail) $(style_dim "!") $*"
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
progress_has_steps() {
|
|
199
|
+
[ "${#PROGRESS_STEP_IDS[@]}" -gt 0 ]
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
progress_step_index() {
|
|
203
|
+
local id="$1"
|
|
204
|
+
local index
|
|
205
|
+
|
|
206
|
+
for index in "${!PROGRESS_STEP_IDS[@]}"; do
|
|
207
|
+
if [ "${PROGRESS_STEP_IDS[$index]}" = "$id" ]; then
|
|
208
|
+
printf '%s\n' "$index"
|
|
209
|
+
return 0
|
|
210
|
+
fi
|
|
211
|
+
done
|
|
212
|
+
|
|
213
|
+
return 1
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
progress_has_step() {
|
|
217
|
+
progress_step_index "$1" >/dev/null 2>&1
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
progress_set_steps() {
|
|
221
|
+
local step
|
|
222
|
+
local id
|
|
223
|
+
local label
|
|
224
|
+
|
|
225
|
+
if [ "$VERBOSE" = true ]; then
|
|
226
|
+
return 0
|
|
227
|
+
fi
|
|
228
|
+
|
|
229
|
+
progress_stop_checklist_timer
|
|
230
|
+
PROGRESS_STEP_IDS=()
|
|
231
|
+
PROGRESS_STEP_LABELS=()
|
|
232
|
+
PROGRESS_STEP_STATES=()
|
|
233
|
+
PROGRESS_RENDERED_STEP_LINE_COUNT=0
|
|
234
|
+
|
|
235
|
+
for step in "$@"; do
|
|
236
|
+
id="${step%%:*}"
|
|
237
|
+
label="${step#*:}"
|
|
238
|
+
PROGRESS_STEP_IDS+=("$id")
|
|
239
|
+
PROGRESS_STEP_LABELS+=("$label")
|
|
240
|
+
PROGRESS_STEP_STATES+=("pending")
|
|
241
|
+
done
|
|
242
|
+
|
|
243
|
+
progress_render_checklist
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
progress_step_mark() {
|
|
247
|
+
local state="$1"
|
|
248
|
+
local frame="$2"
|
|
249
|
+
|
|
250
|
+
case "$state" in
|
|
251
|
+
running)
|
|
252
|
+
style_cyan "$frame"
|
|
253
|
+
;;
|
|
254
|
+
complete)
|
|
255
|
+
style_green "✔"
|
|
256
|
+
;;
|
|
257
|
+
failed)
|
|
258
|
+
style_dim "!"
|
|
259
|
+
;;
|
|
260
|
+
*)
|
|
261
|
+
style_dim "□"
|
|
262
|
+
;;
|
|
263
|
+
esac
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
progress_step_line() {
|
|
267
|
+
local index="$1"
|
|
268
|
+
local frame="$2"
|
|
269
|
+
local state="${PROGRESS_STEP_STATES[$index]}"
|
|
270
|
+
local label="${PROGRESS_STEP_LABELS[$index]}"
|
|
271
|
+
|
|
272
|
+
if [ "$state" = "skipped" ]; then
|
|
273
|
+
label="$(style_dim "$label")"
|
|
274
|
+
fi
|
|
275
|
+
|
|
276
|
+
printf '%s %s %s' "$(progress_rail)" "$(progress_step_mark "$state" "$frame")" "$label"
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
progress_render_checklist_frame() {
|
|
280
|
+
local frame="$1"
|
|
281
|
+
local index
|
|
282
|
+
|
|
283
|
+
if [ "$VERBOSE" = true ] || ! progress_has_steps; then
|
|
284
|
+
return 0
|
|
285
|
+
fi
|
|
286
|
+
|
|
287
|
+
if supports_progress_tty; then
|
|
288
|
+
if [ "$PROGRESS_RENDERED_STEP_LINE_COUNT" -gt 0 ]; then
|
|
289
|
+
log_raw "\033[${PROGRESS_RENDERED_STEP_LINE_COUNT}A"
|
|
290
|
+
fi
|
|
291
|
+
|
|
292
|
+
for index in "${!PROGRESS_STEP_IDS[@]}"; do
|
|
293
|
+
log_raw "\033[2K\r$(progress_step_line "$index" "$frame")\n"
|
|
294
|
+
done
|
|
295
|
+
|
|
296
|
+
PROGRESS_RENDERED_STEP_LINE_COUNT="${#PROGRESS_STEP_IDS[@]}"
|
|
297
|
+
return 0
|
|
298
|
+
fi
|
|
299
|
+
|
|
300
|
+
if [ "$PROGRESS_RENDERED_STEP_LINE_COUNT" -eq 0 ]; then
|
|
301
|
+
for index in "${!PROGRESS_STEP_IDS[@]}"; do
|
|
302
|
+
log "$(progress_step_line "$index" "$frame")"
|
|
303
|
+
done
|
|
304
|
+
PROGRESS_RENDERED_STEP_LINE_COUNT="${#PROGRESS_STEP_IDS[@]}"
|
|
305
|
+
fi
|
|
306
|
+
}
|
|
307
|
+
|
|
308
|
+
progress_render_checklist() {
|
|
309
|
+
progress_render_checklist_frame "◐"
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
progress_update_step() {
|
|
313
|
+
local id="$1"
|
|
314
|
+
local state="$2"
|
|
315
|
+
local index
|
|
316
|
+
|
|
317
|
+
index="$(progress_step_index "$id")" || return 0
|
|
318
|
+
PROGRESS_STEP_STATES[$index]="$state"
|
|
319
|
+
progress_render_checklist
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
progress_start_step() {
|
|
323
|
+
progress_update_step "$1" "running"
|
|
324
|
+
progress_start_checklist_timer
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
progress_complete_step() {
|
|
328
|
+
progress_stop_checklist_timer
|
|
329
|
+
progress_update_step "$1" "complete"
|
|
330
|
+
}
|
|
331
|
+
|
|
332
|
+
progress_fail_step() {
|
|
333
|
+
progress_stop_checklist_timer
|
|
334
|
+
progress_update_step "$1" "failed"
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
progress_skip_step() {
|
|
338
|
+
progress_stop_checklist_timer
|
|
339
|
+
progress_update_step "$1" "skipped"
|
|
340
|
+
}
|
|
341
|
+
|
|
342
|
+
progress_any_running_step() {
|
|
343
|
+
local state
|
|
344
|
+
|
|
345
|
+
for state in "${PROGRESS_STEP_STATES[@]}"; do
|
|
346
|
+
if [ "$state" = "running" ]; then
|
|
347
|
+
return 0
|
|
348
|
+
fi
|
|
349
|
+
done
|
|
350
|
+
|
|
351
|
+
return 1
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
progress_start_checklist_timer() {
|
|
355
|
+
if [ "$VERBOSE" = true ] || ! supports_progress_tty || [ -n "$PROGRESS_CHECKLIST_PID" ]; then
|
|
356
|
+
return 0
|
|
357
|
+
fi
|
|
358
|
+
|
|
359
|
+
if ! progress_any_running_step; then
|
|
360
|
+
return 0
|
|
361
|
+
fi
|
|
362
|
+
|
|
363
|
+
(
|
|
364
|
+
frames=("◒" "◐" "◓" "◑")
|
|
365
|
+
index=0
|
|
366
|
+
while true; do
|
|
367
|
+
progress_render_checklist_frame "${frames[$index]}"
|
|
368
|
+
index=$(( (index + 1) % ${#frames[@]} ))
|
|
369
|
+
sleep 0.12
|
|
370
|
+
done
|
|
371
|
+
) &
|
|
372
|
+
PROGRESS_CHECKLIST_PID="$!"
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
progress_stop_checklist_timer() {
|
|
376
|
+
if [ -z "$PROGRESS_CHECKLIST_PID" ]; then
|
|
377
|
+
return 0
|
|
378
|
+
fi
|
|
379
|
+
|
|
380
|
+
kill "$PROGRESS_CHECKLIST_PID" >/dev/null 2>&1 || true
|
|
381
|
+
wait "$PROGRESS_CHECKLIST_PID" 2>/dev/null || true
|
|
382
|
+
PROGRESS_CHECKLIST_PID=""
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
SPINNER_PID=""
|
|
386
|
+
SPINNER_LABEL=""
|
|
387
|
+
SPINNER_TTY=false
|
|
388
|
+
|
|
389
|
+
start_spinner() {
|
|
390
|
+
local label="$*"
|
|
391
|
+
|
|
392
|
+
if [ "$VERBOSE" = true ]; then
|
|
393
|
+
return 0
|
|
394
|
+
fi
|
|
395
|
+
|
|
396
|
+
stop_spinner clear
|
|
397
|
+
SPINNER_LABEL="$label"
|
|
398
|
+
|
|
399
|
+
if ! supports_progress_tty; then
|
|
400
|
+
SPINNER_TTY=false
|
|
401
|
+
progress_running "$label"
|
|
402
|
+
return 0
|
|
403
|
+
fi
|
|
404
|
+
|
|
405
|
+
SPINNER_TTY=true
|
|
406
|
+
(
|
|
407
|
+
frames=("◒" "◐" "◓" "◑")
|
|
408
|
+
index=0
|
|
409
|
+
while true; do
|
|
410
|
+
log_raw "\r\033[2K$(progress_rail) $(style_cyan "${frames[$index]}") ${label}"
|
|
411
|
+
index=$(( (index + 1) % ${#frames[@]} ))
|
|
412
|
+
sleep 0.12
|
|
413
|
+
done
|
|
414
|
+
) &
|
|
415
|
+
SPINNER_PID="$!"
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
stop_spinner() {
|
|
419
|
+
local status="${1:-clear}"
|
|
420
|
+
local label="$SPINNER_LABEL"
|
|
421
|
+
|
|
422
|
+
if [ -n "$SPINNER_PID" ]; then
|
|
423
|
+
kill "$SPINNER_PID" >/dev/null 2>&1 || true
|
|
424
|
+
wait "$SPINNER_PID" 2>/dev/null || true
|
|
425
|
+
fi
|
|
426
|
+
|
|
427
|
+
if [ "$SPINNER_TTY" = true ]; then
|
|
428
|
+
log_raw "\r\033[2K"
|
|
429
|
+
fi
|
|
430
|
+
|
|
431
|
+
SPINNER_PID=""
|
|
432
|
+
SPINNER_LABEL=""
|
|
433
|
+
SPINNER_TTY=false
|
|
434
|
+
|
|
435
|
+
if [ "$status" = "complete" ] && [ -n "$label" ]; then
|
|
436
|
+
progress_item "$label"
|
|
437
|
+
fi
|
|
438
|
+
}
|
|
439
|
+
|
|
440
|
+
trap 'stop_spinner clear; progress_stop_checklist_timer' EXIT
|
|
441
|
+
|
|
442
|
+
export_progress_env() {
|
|
443
|
+
if [ "$VERBOSE" = true ]; then
|
|
444
|
+
export BOXDOWN_VERBOSE=1
|
|
445
|
+
export BOXDOWN_PROGRESS=0
|
|
446
|
+
else
|
|
447
|
+
export BOXDOWN_VERBOSE=0
|
|
448
|
+
export BOXDOWN_PROGRESS=1
|
|
449
|
+
fi
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
print_progress_markers() {
|
|
453
|
+
local output="$1"
|
|
454
|
+
local line
|
|
455
|
+
|
|
456
|
+
if progress_has_steps; then
|
|
457
|
+
return 0
|
|
458
|
+
fi
|
|
459
|
+
|
|
460
|
+
while IFS= read -r line; do
|
|
461
|
+
case "$line" in
|
|
462
|
+
BOXDOWN_PROGRESS:*)
|
|
463
|
+
progress_item "${line#BOXDOWN_PROGRESS: }"
|
|
464
|
+
;;
|
|
465
|
+
esac
|
|
466
|
+
done <<< "$output"
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
print_command_failure() {
|
|
470
|
+
local label="$1"
|
|
471
|
+
local code="$2"
|
|
472
|
+
local output="$3"
|
|
473
|
+
local filtered
|
|
474
|
+
|
|
475
|
+
progress_warn "${label} failed with exit code ${code}."
|
|
476
|
+
log "$(progress_rail) $(style_dim "Rerun with --verbose to see full command output.")"
|
|
477
|
+
|
|
478
|
+
filtered="$(printf '%s\n' "$output" | sed '/^[[:space:]]*BOXDOWN_PROGRESS:/d' | sed '/^[[:space:]]*$/d' | tail -n 20)"
|
|
479
|
+
if [ -n "$filtered" ]; then
|
|
480
|
+
log "$(progress_rail) $(style_dim "output tail:")"
|
|
481
|
+
while IFS= read -r line; do
|
|
482
|
+
progress_detail "$line"
|
|
483
|
+
done <<< "$filtered"
|
|
484
|
+
fi
|
|
485
|
+
}
|
|
486
|
+
|
|
103
487
|
die() {
|
|
104
488
|
printf '%s\n' "$*" >&2
|
|
105
489
|
exit 1
|
|
@@ -160,12 +544,32 @@ ensure_host_ssh_key() {
|
|
|
160
544
|
chmod 0700 "$SSH_KEY_DIR"
|
|
161
545
|
|
|
162
546
|
if [ ! -f "$SSH_KEY_PATH" ]; then
|
|
163
|
-
|
|
164
|
-
|
|
547
|
+
if [ "$VERBOSE" = true ]; then
|
|
548
|
+
log "Generating devcontainer SSH identity: $SSH_KEY_PATH"
|
|
549
|
+
ssh-keygen -t ed25519 -f "$SSH_KEY_PATH" -N "" -C "${REPO_NAME}-devcontainer" >/dev/null
|
|
550
|
+
elif progress_has_step "ssh-identity"; then
|
|
551
|
+
ssh-keygen -t ed25519 -f "$SSH_KEY_PATH" -N "" -C "${REPO_NAME}-devcontainer" >/dev/null 2>&1 || return $?
|
|
552
|
+
else
|
|
553
|
+
progress_detail "$SSH_KEY_PATH"
|
|
554
|
+
start_spinner "Generating devcontainer SSH identity"
|
|
555
|
+
if ssh-keygen -t ed25519 -f "$SSH_KEY_PATH" -N "" -C "${REPO_NAME}-devcontainer" >/dev/null 2>&1; then
|
|
556
|
+
stop_spinner complete
|
|
557
|
+
else
|
|
558
|
+
code=$?
|
|
559
|
+
stop_spinner clear
|
|
560
|
+
return "$code"
|
|
561
|
+
fi
|
|
562
|
+
fi
|
|
165
563
|
fi
|
|
166
564
|
|
|
167
565
|
if [ ! -f "${SSH_KEY_PATH}.pub" ]; then
|
|
168
|
-
|
|
566
|
+
if [ "$VERBOSE" = true ]; then
|
|
567
|
+
ssh-keygen -y -f "$SSH_KEY_PATH" > "${SSH_KEY_PATH}.pub"
|
|
568
|
+
elif progress_has_step "ssh-identity"; then
|
|
569
|
+
ssh-keygen -y -f "$SSH_KEY_PATH" > "${SSH_KEY_PATH}.pub" 2>/dev/null || return $?
|
|
570
|
+
else
|
|
571
|
+
ssh-keygen -y -f "$SSH_KEY_PATH" > "${SSH_KEY_PATH}.pub"
|
|
572
|
+
fi
|
|
169
573
|
fi
|
|
170
574
|
|
|
171
575
|
chmod 0600 "$SSH_KEY_PATH"
|
|
@@ -184,34 +588,94 @@ install_ssh_config_alias() {
|
|
|
184
588
|
start_devcontainer() {
|
|
185
589
|
local up_output
|
|
186
590
|
local up_args
|
|
591
|
+
local up_code
|
|
187
592
|
|
|
188
593
|
if [ "$MODE" = "ssh-proxy" ] && [ "$RECREATE" = false ]; then
|
|
189
594
|
CONTAINER_ID="$(find_running_container_id)"
|
|
190
595
|
if [ -n "$CONTAINER_ID" ]; then
|
|
191
|
-
|
|
596
|
+
if [ "$VERBOSE" = true ]; then
|
|
597
|
+
log "Using running devcontainer for: $WORKSPACE_FOLDER"
|
|
598
|
+
elif progress_has_step "devcontainer-start"; then
|
|
599
|
+
progress_start_step "devcontainer-start"
|
|
600
|
+
progress_complete_step "devcontainer-start"
|
|
601
|
+
else
|
|
602
|
+
progress_item "Using running devcontainer"
|
|
603
|
+
progress_detail "$CONTAINER_ID"
|
|
604
|
+
fi
|
|
192
605
|
return 0
|
|
193
606
|
fi
|
|
194
607
|
fi
|
|
195
608
|
|
|
196
|
-
|
|
609
|
+
if [ "$VERBOSE" = true ]; then
|
|
610
|
+
log "Starting devcontainer for: $WORKSPACE_FOLDER"
|
|
611
|
+
elif progress_has_step "devcontainer-start"; then
|
|
612
|
+
progress_start_step "devcontainer-start"
|
|
613
|
+
else
|
|
614
|
+
start_spinner "Starting devcontainer"
|
|
615
|
+
fi
|
|
197
616
|
|
|
198
617
|
up_args=(--workspace-folder "$WORKSPACE_FOLDER")
|
|
199
618
|
if [ "$RECREATE" = true ]; then
|
|
200
619
|
up_args+=(--remove-existing-container)
|
|
201
|
-
|
|
620
|
+
if [ "$VERBOSE" = true ]; then
|
|
621
|
+
log "Removing existing dev container so create-time settings (e.g. runArgs) apply."
|
|
622
|
+
elif progress_has_step "devcontainer-start"; then
|
|
623
|
+
:
|
|
624
|
+
else
|
|
625
|
+
stop_spinner clear
|
|
626
|
+
progress_item "Removing existing devcontainer before start"
|
|
627
|
+
start_spinner "Starting devcontainer"
|
|
628
|
+
fi
|
|
202
629
|
fi
|
|
203
630
|
|
|
631
|
+
export_progress_env
|
|
632
|
+
|
|
204
633
|
if [ "$MODE" = "ssh-proxy" ]; then
|
|
205
|
-
if
|
|
634
|
+
if up_output="$(devcontainer_cli up "${up_args[@]}" </dev/null 2>&1)"; then
|
|
635
|
+
:
|
|
636
|
+
else
|
|
637
|
+
up_code=$?
|
|
638
|
+
if [ "$VERBOSE" = true ]; then
|
|
639
|
+
[ -z "$up_output" ] || log "$up_output"
|
|
640
|
+
else
|
|
641
|
+
if progress_has_step "devcontainer-start"; then
|
|
642
|
+
progress_fail_step "devcontainer-start"
|
|
643
|
+
else
|
|
644
|
+
stop_spinner clear
|
|
645
|
+
fi
|
|
646
|
+
print_progress_markers "$up_output"
|
|
647
|
+
print_command_failure "devcontainer up" "$up_code" "$up_output"
|
|
648
|
+
fi
|
|
649
|
+
return "$up_code"
|
|
650
|
+
fi
|
|
651
|
+
elif up_output="$(devcontainer_cli up "${up_args[@]}" 2>&1)"; then
|
|
652
|
+
:
|
|
653
|
+
else
|
|
654
|
+
up_code=$?
|
|
655
|
+
if [ "$VERBOSE" = true ]; then
|
|
206
656
|
[ -z "$up_output" ] || log "$up_output"
|
|
207
|
-
|
|
657
|
+
else
|
|
658
|
+
if progress_has_step "devcontainer-start"; then
|
|
659
|
+
progress_fail_step "devcontainer-start"
|
|
660
|
+
else
|
|
661
|
+
stop_spinner clear
|
|
662
|
+
fi
|
|
663
|
+
print_progress_markers "$up_output"
|
|
664
|
+
print_command_failure "devcontainer up" "$up_code" "$up_output"
|
|
208
665
|
fi
|
|
209
|
-
|
|
210
|
-
[ -z "$up_output" ] || log "$up_output"
|
|
211
|
-
return 1
|
|
666
|
+
return "$up_code"
|
|
212
667
|
fi
|
|
213
668
|
|
|
214
|
-
|
|
669
|
+
if [ "$VERBOSE" = true ]; then
|
|
670
|
+
log "$up_output"
|
|
671
|
+
elif progress_has_step "devcontainer-start"; then
|
|
672
|
+
print_progress_markers "$up_output"
|
|
673
|
+
progress_complete_step "devcontainer-start"
|
|
674
|
+
else
|
|
675
|
+
stop_spinner clear
|
|
676
|
+
print_progress_markers "$up_output"
|
|
677
|
+
progress_item "Starting devcontainer"
|
|
678
|
+
fi
|
|
215
679
|
|
|
216
680
|
CONTAINER_ID="$(printf '%s\n' "$up_output" | parse_container_id_from_up_output)"
|
|
217
681
|
if [ -z "$CONTAINER_ID" ]; then
|
|
@@ -219,6 +683,9 @@ start_devcontainer() {
|
|
|
219
683
|
fi
|
|
220
684
|
|
|
221
685
|
if [ -z "$CONTAINER_ID" ]; then
|
|
686
|
+
if progress_has_step "devcontainer-start"; then
|
|
687
|
+
progress_fail_step "devcontainer-start"
|
|
688
|
+
fi
|
|
222
689
|
die "Could not resolve devcontainer ID for: $WORKSPACE_FOLDER"
|
|
223
690
|
fi
|
|
224
691
|
}
|
|
@@ -244,28 +711,109 @@ host_gh_token_or_empty() {
|
|
|
244
711
|
refresh_container_gh_auth() {
|
|
245
712
|
local token
|
|
246
713
|
|
|
714
|
+
if progress_has_step "gh-token-read"; then
|
|
715
|
+
progress_start_step "gh-token-read"
|
|
716
|
+
fi
|
|
717
|
+
|
|
247
718
|
token="$(host_gh_token_or_empty)"
|
|
719
|
+
if progress_has_step "gh-token-read"; then
|
|
720
|
+
progress_complete_step "gh-token-read"
|
|
721
|
+
fi
|
|
722
|
+
|
|
248
723
|
if [ -z "$token" ]; then
|
|
724
|
+
progress_skip_step "gh-auth-refresh"
|
|
725
|
+
progress_skip_step "gh-git-auth"
|
|
726
|
+
progress_skip_step "gh-auth-verify"
|
|
727
|
+
if [ "$VERBOSE" = false ]; then
|
|
728
|
+
progress_warn "Host GitHub CLI token unavailable; skipping container auth refresh."
|
|
729
|
+
fi
|
|
249
730
|
return 0
|
|
250
731
|
fi
|
|
251
732
|
|
|
252
|
-
if
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
733
|
+
if [ "$VERBOSE" = true ]; then
|
|
734
|
+
if ! printf '%s\n' "$token" | devcontainer_cli exec \
|
|
735
|
+
--workspace-folder "$WORKSPACE_FOLDER" \
|
|
736
|
+
-- gh auth login --hostname github.com --git-protocol https --with-token --insecure-storage >/dev/null 2>&1; then
|
|
737
|
+
log "Warning: could not refresh GitHub CLI auth inside the devcontainer."
|
|
738
|
+
return 0
|
|
739
|
+
fi
|
|
740
|
+
else
|
|
741
|
+
if progress_has_step "gh-auth-refresh"; then
|
|
742
|
+
progress_start_step "gh-auth-refresh"
|
|
743
|
+
else
|
|
744
|
+
start_spinner "Refreshing GitHub CLI auth inside the devcontainer"
|
|
745
|
+
fi
|
|
746
|
+
|
|
747
|
+
if printf '%s\n' "$token" | devcontainer_cli exec \
|
|
748
|
+
--workspace-folder "$WORKSPACE_FOLDER" \
|
|
749
|
+
-- gh auth login --hostname github.com --git-protocol https --with-token --insecure-storage >/dev/null 2>&1; then
|
|
750
|
+
if progress_has_step "gh-auth-refresh"; then
|
|
751
|
+
progress_complete_step "gh-auth-refresh"
|
|
752
|
+
else
|
|
753
|
+
stop_spinner complete
|
|
754
|
+
fi
|
|
755
|
+
else
|
|
756
|
+
if progress_has_step "gh-auth-refresh"; then
|
|
757
|
+
progress_fail_step "gh-auth-refresh"
|
|
758
|
+
else
|
|
759
|
+
stop_spinner clear
|
|
760
|
+
fi
|
|
761
|
+
progress_skip_step "gh-git-auth"
|
|
762
|
+
progress_skip_step "gh-auth-verify"
|
|
763
|
+
progress_warn "Could not refresh GitHub CLI auth inside the devcontainer."
|
|
764
|
+
return 0
|
|
765
|
+
fi
|
|
766
|
+
fi
|
|
767
|
+
|
|
768
|
+
if progress_has_step "gh-git-auth"; then
|
|
769
|
+
progress_start_step "gh-git-auth"
|
|
770
|
+
else
|
|
771
|
+
progress_item "Configuring workspace GitHub Git auth"
|
|
257
772
|
fi
|
|
258
773
|
|
|
259
774
|
if ! configure_container_github_git_auth; then
|
|
260
|
-
|
|
775
|
+
progress_fail_step "gh-git-auth"
|
|
776
|
+
if [ "$VERBOSE" = true ]; then
|
|
777
|
+
log "Warning: GitHub CLI auth refreshed, but GitHub Git auth was not configured for this workspace."
|
|
778
|
+
else
|
|
779
|
+
progress_warn "GitHub CLI auth refreshed, but GitHub Git auth was not configured for this workspace."
|
|
780
|
+
fi
|
|
781
|
+
elif progress_has_step "gh-git-auth"; then
|
|
782
|
+
progress_complete_step "gh-git-auth"
|
|
261
783
|
fi
|
|
262
784
|
|
|
263
|
-
if
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
785
|
+
if [ "$VERBOSE" = true ]; then
|
|
786
|
+
if devcontainer_cli exec \
|
|
787
|
+
--workspace-folder "$WORKSPACE_FOLDER" \
|
|
788
|
+
-- gh auth status --hostname github.com >/dev/null 2>&1; then
|
|
789
|
+
log "GitHub CLI auth refreshed inside the devcontainer."
|
|
790
|
+
else
|
|
791
|
+
log "Warning: GitHub CLI auth refresh completed, but verification failed."
|
|
792
|
+
fi
|
|
267
793
|
else
|
|
268
|
-
|
|
794
|
+
if progress_has_step "gh-auth-verify"; then
|
|
795
|
+
progress_start_step "gh-auth-verify"
|
|
796
|
+
else
|
|
797
|
+
start_spinner "Verifying GitHub CLI auth inside the devcontainer"
|
|
798
|
+
fi
|
|
799
|
+
|
|
800
|
+
if devcontainer_cli exec \
|
|
801
|
+
--workspace-folder "$WORKSPACE_FOLDER" \
|
|
802
|
+
-- gh auth status --hostname github.com >/dev/null 2>&1; then
|
|
803
|
+
if progress_has_step "gh-auth-verify"; then
|
|
804
|
+
progress_complete_step "gh-auth-verify"
|
|
805
|
+
else
|
|
806
|
+
stop_spinner complete
|
|
807
|
+
progress_item "GitHub CLI auth refreshed inside the devcontainer"
|
|
808
|
+
fi
|
|
809
|
+
else
|
|
810
|
+
if progress_has_step "gh-auth-verify"; then
|
|
811
|
+
progress_fail_step "gh-auth-verify"
|
|
812
|
+
else
|
|
813
|
+
stop_spinner clear
|
|
814
|
+
fi
|
|
815
|
+
progress_warn "GitHub CLI auth refresh completed, but verification failed."
|
|
816
|
+
fi
|
|
269
817
|
fi
|
|
270
818
|
}
|
|
271
819
|
|
|
@@ -353,17 +901,51 @@ EOF
|
|
|
353
901
|
}
|
|
354
902
|
|
|
355
903
|
run_refresh_gh_token() {
|
|
356
|
-
|
|
357
|
-
|
|
904
|
+
progress_section "Boxdown GitHub auth refresh"
|
|
905
|
+
progress_detail "Workspace: $WORKSPACE_FOLDER"
|
|
906
|
+
progress_set_steps \
|
|
907
|
+
"devcontainer-start:Starting devcontainer" \
|
|
908
|
+
"gh-token-read:Reading host GitHub CLI token" \
|
|
909
|
+
"gh-auth-refresh:Refreshing GitHub CLI auth inside the devcontainer" \
|
|
910
|
+
"gh-git-auth:Configuring workspace GitHub Git auth" \
|
|
911
|
+
"gh-auth-verify:Verifying GitHub CLI auth inside the devcontainer"
|
|
912
|
+
start_devcontainer || {
|
|
913
|
+
code=$?
|
|
914
|
+
progress_end
|
|
915
|
+
return "$code"
|
|
916
|
+
}
|
|
917
|
+
refresh_container_gh_auth || {
|
|
918
|
+
code=$?
|
|
919
|
+
progress_end
|
|
920
|
+
return "$code"
|
|
921
|
+
}
|
|
922
|
+
progress_end
|
|
358
923
|
}
|
|
359
924
|
|
|
360
925
|
run_refresh_gh_token_running() {
|
|
926
|
+
progress_section "Boxdown GitHub auth refresh"
|
|
927
|
+
progress_detail "Workspace: $WORKSPACE_FOLDER"
|
|
928
|
+
progress_set_steps \
|
|
929
|
+
"devcontainer-running:Using running devcontainer" \
|
|
930
|
+
"gh-token-read:Reading host GitHub CLI token" \
|
|
931
|
+
"gh-auth-refresh:Refreshing GitHub CLI auth inside the devcontainer" \
|
|
932
|
+
"gh-git-auth:Configuring workspace GitHub Git auth" \
|
|
933
|
+
"gh-auth-verify:Verifying GitHub CLI auth inside the devcontainer"
|
|
361
934
|
CONTAINER_ID="$(find_running_container_id)"
|
|
362
935
|
if [ -z "$CONTAINER_ID" ]; then
|
|
936
|
+
progress_fail_step "devcontainer-running"
|
|
937
|
+
progress_end
|
|
363
938
|
die "No running devcontainer found for: $WORKSPACE_FOLDER"
|
|
364
939
|
fi
|
|
365
940
|
|
|
366
|
-
|
|
941
|
+
progress_start_step "devcontainer-running"
|
|
942
|
+
progress_complete_step "devcontainer-running"
|
|
943
|
+
refresh_container_gh_auth || {
|
|
944
|
+
code=$?
|
|
945
|
+
progress_end
|
|
946
|
+
return "$code"
|
|
947
|
+
}
|
|
948
|
+
progress_end
|
|
367
949
|
}
|
|
368
950
|
|
|
369
951
|
print_port_hint() {
|
|
@@ -387,24 +969,98 @@ print_port_hint() {
|
|
|
387
969
|
|
|
388
970
|
open_shell() {
|
|
389
971
|
echo "Dropping into container shell..."
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
972
|
+
TERM="${TERM:-xterm-256color}" devcontainer_cli exec --workspace-folder "$WORKSPACE_FOLDER" -- env TERM="${TERM:-xterm-256color}" COLORTERM=truecolor bash -c '
|
|
973
|
+
if ! infocmp "${TERM:-xterm-256color}" >/dev/null 2>&1; then
|
|
974
|
+
export TERM=xterm-256color
|
|
975
|
+
fi
|
|
976
|
+
export COLORTERM="${COLORTERM:-truecolor}"
|
|
977
|
+
exec bash -i
|
|
978
|
+
'
|
|
397
979
|
}
|
|
398
980
|
|
|
399
981
|
ensure_container_sshd_runtime() {
|
|
400
|
-
|
|
982
|
+
local output
|
|
983
|
+
local code
|
|
984
|
+
local -a env_args
|
|
985
|
+
|
|
986
|
+
if [ "$VERBOSE" = true ]; then
|
|
987
|
+
env_args=(BOXDOWN_VERBOSE=1 BOXDOWN_PROGRESS=0)
|
|
988
|
+
else
|
|
989
|
+
env_args=(BOXDOWN_VERBOSE=0 BOXDOWN_PROGRESS=1)
|
|
990
|
+
fi
|
|
991
|
+
|
|
992
|
+
if [ "$VERBOSE" = true ]; then
|
|
993
|
+
devcontainer_cli exec --workspace-folder "$WORKSPACE_FOLDER" -- env "${env_args[@]}" bash .devcontainer/utils/ssh-bootstrap.sh runtime </dev/null >&2
|
|
994
|
+
return $?
|
|
995
|
+
fi
|
|
996
|
+
|
|
997
|
+
if progress_has_step "ssh-runtime"; then
|
|
998
|
+
progress_start_step "ssh-runtime"
|
|
999
|
+
else
|
|
1000
|
+
start_spinner "Preparing container SSH runtime"
|
|
1001
|
+
fi
|
|
1002
|
+
|
|
1003
|
+
if output="$(devcontainer_cli exec --workspace-folder "$WORKSPACE_FOLDER" -- env "${env_args[@]}" bash .devcontainer/utils/ssh-bootstrap.sh runtime </dev/null 2>&1)"; then
|
|
1004
|
+
if progress_has_step "ssh-runtime"; then
|
|
1005
|
+
progress_complete_step "ssh-runtime"
|
|
1006
|
+
else
|
|
1007
|
+
stop_spinner clear
|
|
1008
|
+
fi
|
|
1009
|
+
print_progress_markers "$output"
|
|
1010
|
+
if ! progress_has_step "ssh-runtime"; then
|
|
1011
|
+
progress_item "Preparing container SSH runtime"
|
|
1012
|
+
fi
|
|
1013
|
+
return 0
|
|
1014
|
+
fi
|
|
1015
|
+
|
|
1016
|
+
code=$?
|
|
1017
|
+
if progress_has_step "ssh-runtime"; then
|
|
1018
|
+
progress_fail_step "ssh-runtime"
|
|
1019
|
+
else
|
|
1020
|
+
stop_spinner clear
|
|
1021
|
+
fi
|
|
1022
|
+
print_progress_markers "$output"
|
|
1023
|
+
print_command_failure "prepare SSH runtime" "$code" "$output"
|
|
1024
|
+
return "$code"
|
|
401
1025
|
}
|
|
402
1026
|
|
|
403
1027
|
run_ssh_proxy() {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
1028
|
+
progress_section "Boxdown SSH proxy"
|
|
1029
|
+
progress_detail "Workspace: $WORKSPACE_FOLDER"
|
|
1030
|
+
progress_set_steps \
|
|
1031
|
+
"ssh-alias:Updating SSH alias" \
|
|
1032
|
+
"ssh-identity:Preparing SSH identity" \
|
|
1033
|
+
"devcontainer-start:Starting devcontainer" \
|
|
1034
|
+
"ssh-runtime:Preparing container SSH runtime"
|
|
1035
|
+
progress_start_step "ssh-alias"
|
|
1036
|
+
if install_ssh_config_alias --quiet >&2; then
|
|
1037
|
+
progress_complete_step "ssh-alias"
|
|
1038
|
+
else
|
|
1039
|
+
progress_fail_step "ssh-alias"
|
|
1040
|
+
progress_end
|
|
1041
|
+
return 1
|
|
1042
|
+
fi
|
|
1043
|
+
|
|
1044
|
+
progress_start_step "ssh-identity"
|
|
1045
|
+
if ensure_host_ssh_key; then
|
|
1046
|
+
progress_complete_step "ssh-identity"
|
|
1047
|
+
else
|
|
1048
|
+
progress_fail_step "ssh-identity"
|
|
1049
|
+
progress_end
|
|
1050
|
+
return 1
|
|
1051
|
+
fi
|
|
1052
|
+
|
|
1053
|
+
start_devcontainer || {
|
|
1054
|
+
code=$?
|
|
1055
|
+
progress_end
|
|
1056
|
+
return "$code"
|
|
1057
|
+
}
|
|
1058
|
+
ensure_container_sshd_runtime || {
|
|
1059
|
+
code=$?
|
|
1060
|
+
progress_end
|
|
1061
|
+
return "$code"
|
|
1062
|
+
}
|
|
1063
|
+
progress_end
|
|
408
1064
|
|
|
409
1065
|
exec docker exec -i "$CONTAINER_ID" /usr/sbin/sshd -i \
|
|
410
1066
|
-o LogLevel=QUIET \
|
|
@@ -417,7 +1073,16 @@ run_ssh_proxy() {
|
|
|
417
1073
|
}
|
|
418
1074
|
|
|
419
1075
|
run_shell() {
|
|
420
|
-
|
|
1076
|
+
progress_section "Boxdown start"
|
|
1077
|
+
progress_detail "Workspace: $WORKSPACE_FOLDER"
|
|
1078
|
+
progress_set_steps \
|
|
1079
|
+
"devcontainer-start:Starting devcontainer"
|
|
1080
|
+
start_devcontainer || {
|
|
1081
|
+
code=$?
|
|
1082
|
+
progress_end
|
|
1083
|
+
return "$code"
|
|
1084
|
+
}
|
|
1085
|
+
progress_end
|
|
421
1086
|
print_port_hint
|
|
422
1087
|
open_shell
|
|
423
1088
|
}
|
|
@@ -436,14 +1101,14 @@ while [ $# -gt 0 ]; do
|
|
|
436
1101
|
MODE="ssh-proxy"
|
|
437
1102
|
shift
|
|
438
1103
|
;;
|
|
439
|
-
ssh
|
|
1104
|
+
ssh)
|
|
440
1105
|
MODE="ssh-config-install"
|
|
441
1106
|
if [ "${2:-}" = "install" ]; then
|
|
442
1107
|
shift 2
|
|
443
1108
|
elif [ "$#" -eq 1 ] || [ "${2#-}" != "$2" ]; then
|
|
444
1109
|
shift
|
|
445
1110
|
else
|
|
446
|
-
die "Unknown command: ssh
|
|
1111
|
+
die "Unknown command: ssh ${2}"
|
|
447
1112
|
fi
|
|
448
1113
|
;;
|
|
449
1114
|
--refresh-gh-token)
|
|
@@ -458,6 +1123,10 @@ while [ $# -gt 0 ]; do
|
|
|
458
1123
|
RECREATE=true
|
|
459
1124
|
shift
|
|
460
1125
|
;;
|
|
1126
|
+
--verbose)
|
|
1127
|
+
VERBOSE=true
|
|
1128
|
+
shift
|
|
1129
|
+
;;
|
|
461
1130
|
*)
|
|
462
1131
|
echo "Unknown option: $1" >&2
|
|
463
1132
|
echo "Run with --help for usage." >&2
|
|
@@ -466,6 +1135,14 @@ while [ $# -gt 0 ]; do
|
|
|
466
1135
|
esac
|
|
467
1136
|
done
|
|
468
1137
|
|
|
1138
|
+
if [ "$VERBOSE" = false ]; then
|
|
1139
|
+
if [ -n "${CI:-}" ] && [ "${CI:-}" != "0" ] && [ "${CI:-}" != "false" ]; then
|
|
1140
|
+
VERBOSE=true
|
|
1141
|
+
elif ! supports_progress_tty; then
|
|
1142
|
+
VERBOSE=true
|
|
1143
|
+
fi
|
|
1144
|
+
fi
|
|
1145
|
+
|
|
469
1146
|
case "$MODE" in
|
|
470
1147
|
shell)
|
|
471
1148
|
run_shell
|