totopo 3.7.0-rc-2 → 3.8.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 CHANGED
@@ -70,11 +70,11 @@ A few key concepts:
70
70
 
71
71
  ### `totopo.yaml`
72
72
 
73
- The config is minimal — four fields:
73
+ The config is minimal — only `workspace_id` is required; the rest are optional:
74
74
 
75
- - **`workspace_id`** — unique slug for container naming and cache directory
76
- - **`profiles`** — Dockerfile image variants (see [Profiles](#profiles))
77
- - **`shadow_paths`** — gitignore-style patterns hidden from agents (see [Shadow Paths](#shadow-paths))
75
+ - **`workspace_id`** *(required)* — unique slug for container naming and cache directory
76
+ - **`profiles`** *(optional)* — Dockerfile image variants (see [Profiles](#profiles))
77
+ - **`shadow_paths`** *(optional)* — gitignore-style patterns hidden from agents (see [Shadow Paths](#shadow-paths))
78
78
  - **`env_file`** *(optional)* — path to env file injected at runtime (see [Environment Variables](#environment-variables))
79
79
 
80
80
  On every run, totopo shows the workspace menu:
@@ -127,27 +127,26 @@ profiles:
127
127
  description: "Base image: Node.js, git, and AI CLIs"
128
128
  dockerfile_hook: |
129
129
  # No extras — uses the totopo base image as-is (Node.js + git + AI CLIs).
130
- extended:
131
- description: Base image + Go, Java, Rust, and Bun
132
- dockerfile_hook: |
133
- # Go
134
- RUN apt-get update && apt-get install -y --no-install-recommends golang-go && rm -rf /var/lib/apt/lists/*
135
- # Java (headless JDK — includes javac; needed for Kotlin, Scala, Android tooling)
136
- RUN apt-get update && apt-get install -y --no-install-recommends default-jdk-headless && rm -rf /var/lib/apt/lists/*
137
- # Rust (system-wide install — devuser can use cargo and rustc)
138
- ENV RUSTUP_HOME=/usr/local/rustup
139
- ENV CARGO_HOME=/usr/local/cargo
140
- ENV PATH=/usr/local/cargo/bin:$PATH
141
- RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path && chmod -R a+rx /usr/local/cargo /usr/local/rustup
142
- # Bun (fast JS runtime, bundler, and package manager)
143
- ENV BUN_INSTALL=/usr/local/bun
144
- ENV PATH=/usr/local/bun/bin:$PATH
145
- RUN curl -fsSL https://bun.sh/install | bash
130
+
131
+ # Uncomment to enable additional runtimes (Go, Java, Rust, Bun):
132
+ # extended:
133
+ # description: Base image + Go, Java, Rust, and Bun
134
+ # dockerfile_hook: |
135
+ # # Go
136
+ # RUN apt-get update && apt-get install -y --no-install-recommends golang-go && rm -rf /var/lib/apt/lists/*
137
+ # # Java (headless JDK)
138
+ # RUN apt-get update && apt-get install -y --no-install-recommends default-jdk-headless && rm -rf /var/lib/apt/lists/*
139
+ # # Rust (system-wide)
140
+ # ENV RUSTUP_HOME=/usr/local/rustup CARGO_HOME=/usr/local/cargo PATH=/usr/local/cargo/bin:$PATH
141
+ # RUN curl -sSf https://sh.rustup.rs | sh -s -- -y --no-modify-path && chmod -R a+rx /usr/local/cargo /usr/local/rustup
142
+ # # Bun
143
+ # ENV BUN_INSTALL=/usr/local/bun PATH=/usr/local/bun/bin:$PATH
144
+ # RUN curl -fsSL https://bun.sh/install | bash
146
145
  # Add more profiles here — or ask the agent inside the container to set one up for you.
147
146
 
148
147
  ```
149
148
 
150
- Two profiles are set by default. When multiple profiles are defined, totopo prompts you to pick one at session start (the choice is remembered). A profile change triggers a container rebuild on the next session.
149
+ New workspaces ship with the `default` profile active and an `extended` profile (Go, Java, Rust, Bun) included as a commented-out template — uncomment to enable. When multiple profiles are defined, totopo prompts you to pick one at session start (the choice is remembered). A profile change triggers a container rebuild on the next session.
151
150
 
152
151
  The base image is defined in [`templates/Dockerfile`](templates/Dockerfile) — inspect it to see what's already included before adding your own layers. To force a fully fresh build (no Docker layer cache), use **Manage Workspace > Clean rebuild**.
153
152
 
@@ -50,6 +50,7 @@ export const BAKED_TEMPLATE_FILES = [
50
50
  "claude-statusline.sh",
51
51
  "git-readonly-wrapper.mjs",
52
52
  "npmrc",
53
+ "pnpm-config.yaml",
53
54
  "runtime-constants.mjs",
54
55
  "startup-git-mode.mjs",
55
56
  "startup.mjs",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "totopo",
3
- "version": "3.7.0-rc-2",
3
+ "version": "3.8.0",
4
4
  "description": "Run AI coding agents safely in your local codebase",
5
5
  "type": "module",
6
6
  "bin": {
@@ -8,7 +8,7 @@
8
8
  # dockerfile_hook in totopo.yaml profiles.
9
9
  # =============================================================================
10
10
 
11
- FROM debian:bookworm-slim
11
+ FROM debian:trixie-slim
12
12
  LABEL totopo.managed=true
13
13
 
14
14
  # Enable 24-bit color support for AI CLIs (suppresses color upgrade prompts)
@@ -24,8 +24,8 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
24
24
  build-essential pkg-config libssl-dev \
25
25
  # Utilities
26
26
  jq unzip zip tree htop procps lsb-release gnupg ca-certificates sox file bubblewrap \
27
- # Modern search/navigation tools
28
- ripgrep fzf \
27
+ # Modern search/navigation tools (fd-find installs the binary as 'fdfind'; symlinked to 'fd' below)
28
+ ripgrep fzf fd-find \
29
29
  # Database clients
30
30
  sqlite3 postgresql-client default-mysql-client redis-tools \
31
31
  # Python (needed for build scripts and as a light default)
@@ -33,13 +33,10 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
33
33
  && rm -rf /var/lib/apt/lists/*
34
34
 
35
35
  # ---------------------------------------------------------------------------
36
- # Layer 2 — fd (GitHub release)
36
+ # Layer 2 — fd (from apt fd-find; Debian names the binary 'fdfind')
37
+ # Symlink to 'fd' so the tool is callable by its upstream name.
37
38
  # ---------------------------------------------------------------------------
38
- RUN ARCH=$(dpkg --print-architecture) && \
39
- FD_VERSION=$(curl -fsSL https://api.github.com/repos/sharkdp/fd/releases/latest \
40
- | python3 -c "import sys,json; print(json.load(sys.stdin)['tag_name'][1:])") && \
41
- curl -fsSL "https://github.com/sharkdp/fd/releases/download/v${FD_VERSION}/fd_${FD_VERSION}_${ARCH}.deb" \
42
- -o /tmp/fd.deb && dpkg -i /tmp/fd.deb && rm /tmp/fd.deb
39
+ RUN ln -sf "$(command -v fdfind)" /usr/local/bin/fd
43
40
 
44
41
  # ---------------------------------------------------------------------------
45
42
  # Layer 3 — yq (GitHub release)
@@ -59,9 +56,10 @@ RUN curl -fsSL https://cli.github.com/packages/githubcli-archive-keyring.gpg \
59
56
  apt-get update && apt-get install -y gh && rm -rf /var/lib/apt/lists/*
60
57
 
61
58
  # ---------------------------------------------------------------------------
62
- # Layer 5 — Node.js LTS (via NodeSource)
59
+ # Layer 5 — Node.js 24 LTS (via NodeSource)
60
+ # Trixie's apt nodejs is 20.x; NodeSource is pinned to the current Active LTS (24.x).
63
61
  # ---------------------------------------------------------------------------
64
- RUN curl -fsSL https://deb.nodesource.com/setup_lts.x | bash - && \
62
+ RUN curl -fsSL https://deb.nodesource.com/setup_24.x | bash - && \
65
63
  apt-get install -y nodejs && rm -rf /var/lib/apt/lists/*
66
64
 
67
65
  # ---------------------------------------------------------------------------
@@ -85,18 +83,20 @@ RUN npm install -g \
85
83
  # ---------------------------------------------------------------------------
86
84
  RUN groupadd --gid 1001 devuser && \
87
85
  useradd --uid 1001 --gid devuser --shell /bin/bash --create-home devuser && \
88
- mkdir -p /home/devuser/.local/state /home/devuser/.local/share /home/devuser/.local/share/pnpm /home/devuser/.local/bin && \
86
+ mkdir -p /home/devuser/.local/state /home/devuser/.local/share /home/devuser/.local/share/pnpm /home/devuser/.local/bin /home/devuser/.config/pnpm && \
89
87
  date -u +"%Y-%m-%dT%H:%M:%S.000Z" > /home/devuser/.ai-cli-updated && \
90
88
  chown -R devuser:devuser /home/devuser
91
89
 
92
90
  # ---------------------------------------------------------------------------
93
- # Layer 9 — Bake startup script + git mode helper + shared constants into image
91
+ # Layer 9 — Bake startup script + git mode helper + shared constants + pnpm config into image
92
+ # pnpm 11+ reads settings from ~/.config/pnpm/config.yaml; ~/.npmrc covers anyone pinning pnpm <= 10.
94
93
  # ---------------------------------------------------------------------------
95
94
  COPY npmrc /home/devuser/.npmrc
95
+ COPY pnpm-config.yaml /home/devuser/.config/pnpm/config.yaml
96
96
  COPY startup.mjs /home/devuser/startup.mjs
97
97
  COPY startup-git-mode.mjs /home/devuser/startup-git-mode.mjs
98
98
  COPY runtime-constants.mjs /home/devuser/runtime-constants.mjs
99
- RUN chown devuser:devuser /home/devuser/.npmrc /home/devuser/startup.mjs /home/devuser/startup-git-mode.mjs /home/devuser/runtime-constants.mjs
99
+ RUN chown devuser:devuser /home/devuser/.npmrc /home/devuser/.config/pnpm/config.yaml /home/devuser/startup.mjs /home/devuser/startup-git-mode.mjs /home/devuser/runtime-constants.mjs
100
100
 
101
101
  # ---------------------------------------------------------------------------
102
102
  # Layer 10 — Bake git read-only wrapper into image
@@ -0,0 +1,9 @@
1
+ # pnpm global config. pnpm 11+ reads its settings from here (~/.config/pnpm/config.yaml),
2
+ # no longer from ~/.npmrc. Keys are camelCase, unlike the kebab-case equivalents in .npmrc.
3
+ #
4
+ # storeDir pins the global store onto a bind-mounted, same-device cache so pnpm never falls back
5
+ # to creating a .pnpm-store inside the mounted /workspace. packageImportMethod=copy avoids
6
+ # cross-filesystem hardlink failures. The matching ~/.npmrc keeps this working for anyone who
7
+ # pins an older pnpm via packageManager (pnpm <= 10 still reads .npmrc).
8
+ storeDir: /home/devuser/.local/share/pnpm/store
9
+ packageImportMethod: copy