totopo 0.1.6 → 0.1.7

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "totopo",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Secure AI Box — isolated dev environments for AI coding assistants",
5
5
  "type": "module",
6
6
  "bin": {
@@ -48,6 +48,7 @@
48
48
  "lint": "biome check .",
49
49
  "format": "biome format --write .",
50
50
  "fix:all": "biome check --write .",
51
+ "check": "pnpm typecheck && pnpm lint && tsx src/releases/check.ts",
51
52
  "generate-changelog": "tsx src/releases/generate-changelog.ts",
52
53
  "rc": "tsx src/releases/rc.ts",
53
54
  "rc:promote": "tsx src/releases/release.ts",
@@ -1,46 +1,95 @@
1
1
  # =============================================================================
2
- # Secure AI Dev Container — Next.js / Node.js
2
+ # Secure AI Dev Container — General-purpose multi-stack
3
3
  # =============================================================================
4
4
  # Non-root user, no git remote access, AI tools: claude, kilo, opencode
5
+ # Runtimes: Node.js, Python, Go, Rust, Java (Temurin 21), Bun
5
6
  # =============================================================================
6
7
 
7
- FROM node:22-bookworm-slim
8
+ FROM debian:bookworm-slim
8
9
  LABEL totopo.managed=true
9
10
 
10
11
  # ---------------------------------------------------------------------------
11
- # System packages
12
+ # Layer 1 — System packages
12
13
  # ---------------------------------------------------------------------------
13
14
  RUN apt-get update && apt-get install -y --no-install-recommends \
14
- git \
15
- curl \
16
- wget \
17
- bash \
18
- jq \
19
- unzip \
20
- ca-certificates \
21
- procps \
15
+ # Core utilities
16
+ git curl wget bash zsh make \
17
+ # Build essentials (needed for Rust compilation, C extensions, etc.)
18
+ build-essential pkg-config libssl-dev \
19
+ # Utilities
20
+ jq unzip zip tree htop procps lsb-release gnupg ca-certificates \
21
+ # Modern search/navigation tools
22
+ ripgrep fzf \
23
+ # Database clients
24
+ sqlite3 postgresql-client default-mysql-client redis-tools \
25
+ # Python (system runtime)
26
+ python3 python3-pip python3-venv pipx \
27
+ # Java build tools
28
+ maven \
22
29
  && rm -rf /var/lib/apt/lists/*
23
30
 
24
31
  # ---------------------------------------------------------------------------
25
- # Create non-root user
32
+ # Layer 2 — fd (not available as fd-find in bookworm; install from GitHub)
26
33
  # ---------------------------------------------------------------------------
27
- RUN groupadd --gid 1001 devuser \
28
- && useradd --uid 1001 --gid devuser --shell /bin/bash --create-home devuser
34
+ RUN ARCH=$(dpkg --print-architecture) && \
35
+ FD_VERSION=$(curl -fsSL https://api.github.com/repos/sharkdp/fd/releases/latest \
36
+ | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'][1:])") && \
37
+ curl -fsSL "https://github.com/sharkdp/fd/releases/download/v${FD_VERSION}/fd_${FD_VERSION}_${ARCH}.deb" \
38
+ -o /tmp/fd.deb && dpkg -i /tmp/fd.deb && rm /tmp/fd.deb
29
39
 
30
40
  # ---------------------------------------------------------------------------
31
- # Git remote block enforced via git's own system-level config.
32
- # protocol.allow never -> blocks https, ssh, git:// and ALL other transports
33
- # protocol.file.allow -> keeps local operations (commit, branch, log) working
34
- #
35
- # This is set in /etc/gitconfig (system scope) so it applies to every user
36
- # and every process — including direct calls to /usr/bin/git. It cannot be
37
- # bypassed without overwriting /etc/gitconfig, which requires root.
41
+ # Layer 3yq (not in apt)
42
+ # ---------------------------------------------------------------------------
43
+ RUN ARCH=$(dpkg --print-architecture) && \
44
+ curl -fsSL "https://github.com/mikefarah/yq/releases/latest/download/yq_linux_${ARCH}" \
45
+ -o /usr/local/bin/yq && chmod +x /usr/local/bin/yq
46
+
47
+ # ---------------------------------------------------------------------------
48
+ # Layer 4 — GitHub CLI
49
+ # ---------------------------------------------------------------------------
50
+ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
51
+ | dd of=/usr/share/keyrings/githubcli-archive-keyring.gpg && \
52
+ echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/githubcli-archive-keyring.gpg] \
53
+ https://cli.github.com/packages stable main" \
54
+ > /etc/apt/sources.list.d/github-cli.list && \
55
+ apt-get update && apt-get install -y gh && rm -rf /var/lib/apt/lists/*
56
+
57
+ # ---------------------------------------------------------------------------
58
+ # Layer 5 — Node.js LTS (via NodeSource)
59
+ # ---------------------------------------------------------------------------
60
+ RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
61
+ apt-get install -y nodejs && rm -rf /var/lib/apt/lists/*
62
+
63
+ # ---------------------------------------------------------------------------
64
+ # Layer 6 — Eclipse Temurin 21 JDK (Adoptium apt repo)
65
+ # ---------------------------------------------------------------------------
66
+ RUN curl -fsSL https://packages.adoptium.net/artifactory/api/gpg/key/public \
67
+ | gpg --dearmor -o /usr/share/keyrings/adoptium.gpg && \
68
+ echo "deb [signed-by=/usr/share/keyrings/adoptium.gpg] \
69
+ https://packages.adoptium.net/artifactory/deb $(lsb_release -cs) main" \
70
+ > /etc/apt/sources.list.d/adoptium.list && \
71
+ apt-get update && apt-get install -y temurin-21-jdk && rm -rf /var/lib/apt/lists/*
72
+ RUN echo 'export JAVA_HOME=$(dirname $(dirname $(readlink -f $(which java))))' \
73
+ > /etc/profile.d/java.sh
74
+
75
+ # ---------------------------------------------------------------------------
76
+ # Layer 7 — Go (official tarball, latest stable, multi-arch)
77
+ # ---------------------------------------------------------------------------
78
+ RUN ARCH=$(dpkg --print-architecture) && \
79
+ GO_VERSION=$(curl -fsSL 'https://go.dev/dl/?mode=json' \
80
+ | python3 -c "import sys,json; d=json.load(sys.stdin); print(d[0]['version'].lstrip('go'))") && \
81
+ curl -fsSL "https://go.dev/dl/go${GO_VERSION}.linux-${ARCH}.tar.gz" \
82
+ | tar -xz -C /usr/local && \
83
+ echo 'export PATH=/usr/local/go/bin:$PATH' > /etc/profile.d/go.sh
84
+
85
+ # ---------------------------------------------------------------------------
86
+ # Layer 8 — Git remote block
38
87
  # ---------------------------------------------------------------------------
39
88
  RUN git config --system protocol.allow never && \
40
89
  git config --system protocol.file.allow always
41
90
 
42
91
  # ---------------------------------------------------------------------------
43
- # Global npm tools installed as root so they land in /usr/local/bin
92
+ # Layer 9Global npm tools
44
93
  # ---------------------------------------------------------------------------
45
94
  RUN npm install -g \
46
95
  pnpm \
@@ -50,18 +99,39 @@ RUN npm install -g \
50
99
  && npm cache clean --force
51
100
 
52
101
  # ---------------------------------------------------------------------------
53
- # Switch to non-root user for remainder
102
+ # Layer 10 — Non-root user
54
103
  # ---------------------------------------------------------------------------
104
+ RUN groupadd --gid 1001 devuser && \
105
+ useradd --uid 1001 --gid devuser --shell /bin/bash --create-home devuser
106
+
55
107
  USER devuser
56
108
  WORKDIR /workspace
57
109
 
58
110
  # ---------------------------------------------------------------------------
59
- # Shell experience
111
+ # Layer 11 — Rust (installed as devuser via rustup)
112
+ # ---------------------------------------------------------------------------
113
+ RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \
114
+ | sh -s -- -y --no-modify-path --default-toolchain stable && \
115
+ /home/devuser/.cargo/bin/rustup component add rustfmt clippy
116
+
117
+ # ---------------------------------------------------------------------------
118
+ # Layer 12 — Bun (installed as devuser via official installer)
119
+ # ---------------------------------------------------------------------------
120
+ RUN curl -fsSL https://bun.sh/install | bash
121
+
122
+ # ---------------------------------------------------------------------------
123
+ # Layer 13 — Python user tools (uv + poetry via pipx)
124
+ # ---------------------------------------------------------------------------
125
+ RUN pipx install uv && pipx install poetry
126
+
127
+ # ---------------------------------------------------------------------------
128
+ # Layer 14 — PATH + shell experience
60
129
  # ---------------------------------------------------------------------------
130
+ ENV PATH="/home/devuser/.cargo/bin:/home/devuser/.bun/bin:/home/devuser/.local/bin:/usr/local/go/bin:${PATH}"
61
131
  RUN echo 'export PS1="\[\033[01;32m\][devcontainer]\[\033[00m\] \[\033[01;34m\]\w\[\033[00m\] \$ "' \
62
- >> /home/devuser/.bashrc && \
132
+ >> /home/devuser/.bashrc && \
63
133
  echo 'echo ""' >> /home/devuser/.bashrc && \
64
134
  echo "echo \" Type 'status' to re-run the readiness check.\"" >> /home/devuser/.bashrc && \
65
135
  echo 'alias status="node /workspace/.totopo/post-start.mjs"' >> /home/devuser/.bashrc
66
136
 
67
- CMD ["/bin/bash"]
137
+ CMD ["/bin/bash"]
@@ -81,9 +81,30 @@ checkTool("opencode");
81
81
  // ─── Runtimes ────────────────────────────────────────────────────────────────
82
82
  section("Runtimes");
83
83
 
84
+ // JavaScript
84
85
  ok("node", run("node --version") ?? "not found");
85
86
  ok("npm", `v${run("npm --version") ?? "not found"}`);
86
87
  ok("pnpm", run("pnpm --version") ? `v${run("pnpm --version")}` : "not found");
88
+ ok("bun", run("bun --version") ? `v${run("bun --version")}` : "not found");
89
+ // Python
90
+ ok("python3", run("python3 --version") ?? "not found");
91
+ ok("uv", run("uv --version") ?? "not found");
92
+ // Go
93
+ ok("go", run("go version") ?? "not found");
94
+ // Rust
95
+ ok("cargo", run("cargo --version") ?? "not found");
96
+ // Java
97
+ ok("java", run("java --version")?.split("\n")[0] ?? "not found");
98
+
99
+ // ─── Dev tools ───────────────────────────────────────────────────────────────
100
+ section("Dev tools");
101
+
102
+ ok("gh", run("gh --version")?.split("\n")[0] ?? "not found");
103
+ ok("rg", run("rg --version")?.split("\n")[0] ?? "not found");
104
+ ok("fd", run("fd --version") ?? "not found");
105
+ ok("fzf", run("fzf --version") ?? "not found");
106
+ ok("jq", run("jq --version") ?? "not found");
107
+ ok("yq", run("yq --version") ?? "not found");
87
108
 
88
109
  // ─── API keys ────────────────────────────────────────────────────────────────
89
110
  section("API keys");