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
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
#
|
|
3
|
+
# Container-side Python runtime setup for the repo-local devcontainer workflow.
|
|
4
|
+
|
|
5
|
+
set -euo pipefail
|
|
6
|
+
|
|
7
|
+
PYTHON_PACKAGES=(python3 python3-venv python3-pip pipx)
|
|
8
|
+
|
|
9
|
+
progress() {
|
|
10
|
+
if [ "${BOXDOWN_PROGRESS:-0}" = "1" ]; then
|
|
11
|
+
printf 'BOXDOWN_PROGRESS: %s\n' "$*"
|
|
12
|
+
fi
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
as_root() {
|
|
16
|
+
if [ "$(id -u)" -eq 0 ]; then
|
|
17
|
+
"$@"
|
|
18
|
+
else
|
|
19
|
+
sudo "$@"
|
|
20
|
+
fi
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
python_runtime_ready() {
|
|
24
|
+
command -v python3 >/dev/null 2>&1 || return 1
|
|
25
|
+
python3 -m venv --help >/dev/null 2>&1 || return 1
|
|
26
|
+
python3 -m pip --version >/dev/null 2>&1 || return 1
|
|
27
|
+
command -v pipx >/dev/null 2>&1 || return 1
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
apt_lists_present() {
|
|
31
|
+
find /var/lib/apt/lists -mindepth 1 -type f -name '*_Packages*' -print -quit 2>/dev/null | grep -q .
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
install_python_packages() {
|
|
35
|
+
as_root env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends "${PYTHON_PACKAGES[@]}"
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
install_python_runtime() {
|
|
39
|
+
if python_runtime_ready; then
|
|
40
|
+
return 0
|
|
41
|
+
fi
|
|
42
|
+
|
|
43
|
+
progress "Installing Python runtime packages"
|
|
44
|
+
if ! apt_lists_present; then
|
|
45
|
+
as_root apt-get update
|
|
46
|
+
fi
|
|
47
|
+
|
|
48
|
+
if ! install_python_packages; then
|
|
49
|
+
as_root apt-get update
|
|
50
|
+
install_python_packages
|
|
51
|
+
fi
|
|
52
|
+
|
|
53
|
+
as_root rm -rf /var/lib/apt/lists/*
|
|
54
|
+
python_runtime_ready
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
main() {
|
|
58
|
+
case "${1:-install}" in
|
|
59
|
+
install)
|
|
60
|
+
install_python_runtime
|
|
61
|
+
;;
|
|
62
|
+
*)
|
|
63
|
+
echo "Usage: $(basename "$0") [install]" >&2
|
|
64
|
+
return 1
|
|
65
|
+
;;
|
|
66
|
+
esac
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
main "$@"
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Shell bootstrap for Boxdown runtime-mounted secret environment files.
|
|
3
|
+
|
|
4
|
+
SECRET_ENV_DIR="${BOXDOWN_SECRET_ENV_DIR:-/run/boxdown/secrets}"
|
|
5
|
+
|
|
6
|
+
export_if_present() {
|
|
7
|
+
local name="$1"
|
|
8
|
+
local path="${SECRET_ENV_DIR}/${name}"
|
|
9
|
+
local value
|
|
10
|
+
|
|
11
|
+
[[ -r "${path}" ]] || return 0
|
|
12
|
+
IFS= read -r value < "${path}" || true
|
|
13
|
+
|
|
14
|
+
if [[ -n "${value}" ]]; then
|
|
15
|
+
export "${name}=${value}"
|
|
16
|
+
fi
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
export_if_present ANTHROPIC_API_KEY
|
|
20
|
+
export_if_present SNYK_TOKEN
|
|
21
|
+
export_if_present OP_SERVICE_ACCOUNT_TOKEN
|
|
22
|
+
unset value
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
# Expose a root-only forwarded SSH-agent socket to the non-root container user.
|
|
3
|
+
|
|
4
|
+
set -euo pipefail
|
|
5
|
+
|
|
6
|
+
SOURCE_SOCKET="${BOXDOWN_GIT_SIGNING_SOURCE_SOCKET:-/run/boxdown/ssh-agent.sock}"
|
|
7
|
+
TARGET_SOCKET="${SSH_AUTH_SOCK:-/run/boxdown/ssh-agent-node.sock}"
|
|
8
|
+
PROXY_SCRIPT="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/ssh-agent-proxy.mjs"
|
|
9
|
+
|
|
10
|
+
if ssh-add -L >/dev/null 2>&1; then
|
|
11
|
+
exit 0
|
|
12
|
+
fi
|
|
13
|
+
|
|
14
|
+
if ! command -v sudo >/dev/null 2>&1 || ! command -v node >/dev/null 2>&1; then
|
|
15
|
+
exit 1
|
|
16
|
+
fi
|
|
17
|
+
|
|
18
|
+
sudo -n node "${PROXY_SCRIPT}" --source "${SOURCE_SOCKET}" --target "${TARGET_SOCKET}" --uid "$(id -u)" --gid "$(id -g)" >/dev/null 2>&1 &
|
|
19
|
+
|
|
20
|
+
for _ in $(seq 1 20); do
|
|
21
|
+
if [[ -S "${TARGET_SOCKET}" ]] && ssh-add -L >/dev/null 2>&1; then
|
|
22
|
+
exit 0
|
|
23
|
+
fi
|
|
24
|
+
sleep 0.1
|
|
25
|
+
done
|
|
26
|
+
|
|
27
|
+
exit 1
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
import { chmodSync, chownSync, existsSync, unlinkSync } from 'node:fs'
|
|
4
|
+
import { createConnection, createServer } from 'node:net'
|
|
5
|
+
|
|
6
|
+
function option (name) {
|
|
7
|
+
const index = process.argv.indexOf(name)
|
|
8
|
+
return index === -1 ? undefined : process.argv[index + 1]
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const source = option('--source')
|
|
12
|
+
const target = option('--target')
|
|
13
|
+
const uid = Number(option('--uid'))
|
|
14
|
+
const gid = Number(option('--gid'))
|
|
15
|
+
|
|
16
|
+
if (source === undefined || target === undefined || !Number.isInteger(uid) || !Number.isInteger(gid)) {
|
|
17
|
+
process.stderr.write('ssh-agent-proxy: expected --source, --target, --uid, and --gid.\n')
|
|
18
|
+
process.exit(2)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
if (existsSync(target)) unlinkSync(target)
|
|
22
|
+
|
|
23
|
+
const server = createServer((client) => {
|
|
24
|
+
const upstream = createConnection(source)
|
|
25
|
+
client.pipe(upstream)
|
|
26
|
+
upstream.pipe(client)
|
|
27
|
+
client.on('error', () => upstream.destroy())
|
|
28
|
+
upstream.on('error', () => client.destroy())
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
server.on('error', (error) => {
|
|
32
|
+
process.stderr.write(`ssh-agent-proxy: ${error.message}\n`)
|
|
33
|
+
process.exit(1)
|
|
34
|
+
})
|
|
35
|
+
|
|
36
|
+
server.listen(target, () => {
|
|
37
|
+
chmodSync(target, 0o600)
|
|
38
|
+
chownSync(target, uid, gid)
|
|
39
|
+
})
|
|
@@ -11,6 +11,12 @@ SSH_USER="${DEVCONTAINER_SSH_USER:-node}"
|
|
|
11
11
|
PUBLIC_KEY_FILE="${DEVCONTAINER_SSH_PUBLIC_KEY_FILE:-${WORKSPACE_FOLDER}/.devcontainer/.ssh/id_ed25519.pub}"
|
|
12
12
|
OPENSSH_CONFIGURE_TIMEOUT_SECONDS="${DEVCONTAINER_OPENSSH_CONFIGURE_TIMEOUT_SECONDS:-180}"
|
|
13
13
|
|
|
14
|
+
progress() {
|
|
15
|
+
if [ "${BOXDOWN_PROGRESS:-0}" = "1" ]; then
|
|
16
|
+
printf 'BOXDOWN_PROGRESS: %s\n' "$*"
|
|
17
|
+
fi
|
|
18
|
+
}
|
|
19
|
+
|
|
14
20
|
as_root() {
|
|
15
21
|
if [ "$(id -u)" -eq 0 ]; then
|
|
16
22
|
"$@"
|
|
@@ -98,10 +104,12 @@ ensure_openssh_server_configured() {
|
|
|
98
104
|
|
|
99
105
|
install_openssh_server() {
|
|
100
106
|
if [ ! -x /usr/sbin/sshd ]; then
|
|
107
|
+
progress "Installing openssh-server packages"
|
|
101
108
|
as_root apt-get update
|
|
102
109
|
as_root env DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends openssh-server
|
|
103
110
|
fi
|
|
104
111
|
|
|
112
|
+
progress "Configuring openssh-server"
|
|
105
113
|
ensure_openssh_server_configured
|
|
106
114
|
}
|
|
107
115
|
|
|
@@ -164,6 +172,7 @@ ensure_runtime_ready() {
|
|
|
164
172
|
return 1
|
|
165
173
|
fi
|
|
166
174
|
|
|
175
|
+
progress "Preparing SSH daemon runtime"
|
|
167
176
|
ensure_openssh_server_configured
|
|
168
177
|
as_root ssh-keygen -A
|
|
169
178
|
as_root install -d -m 0755 /run/sshd
|
package/dist/bin/cli.cjs
CHANGED
package/dist/bin/cli.mjs
CHANGED