maesttro 0.4.3 → 0.5.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/docker/Dockerfile CHANGED
@@ -1,5 +1,5 @@
1
1
  # git is built from source: Debian ships 2.47 and the runner wants a recent
2
- # git. Builder matches node:22-slim's Debian so the runtime libs line up.
2
+ # git. Builder matches node:24-slim's Debian so the runtime libs line up.
3
3
  FROM debian:bookworm-slim AS git-build
4
4
  ARG GIT_VERSION=2.55.0
5
5
  ARG GIT_SHA256=457fdb04dc8728e007d4688695e6912e6f680727920f2a40bf11eacc17505357
@@ -14,9 +14,18 @@ RUN apt-get update \
14
14
  && make -j"$(nproc)" prefix=/usr/local sysconfdir=/etc NO_TCLTK=1 NO_PERL=1 NO_PYTHON=1 NO_GETTEXT=1 NO_RUST=1 \
15
15
  DESTDIR=/out all install
16
16
 
17
- FROM node:22-slim
17
+ FROM oven/bun:1.4.2-slim AS bun
18
+ FROM ghcr.io/astral-sh/uv:0.12.19 AS uv
19
+
20
+ FROM node:24-slim
21
+
22
+ # Lets `maesttro update` find and remove older runner images once they lose their tag
23
+ LABEL org.maesttro.runner="1"
18
24
 
19
25
  COPY --from=git-build /out/usr/local /usr/local
26
+ COPY --from=bun /usr/local/bin/bun /usr/local/bin/bun
27
+ COPY --from=uv /uv /uvx /usr/local/bin/
28
+ RUN ln -s /usr/local/bin/bun /usr/local/bin/bunx
20
29
 
21
30
  # gh comes from GitHub's apt repo: Debian's lags by years and predates the
22
31
  # hosts.yml / config.yml behaviour the CLI's read-only session mount relies on
@@ -30,8 +39,32 @@ RUN apt-get update \
30
39
  > /etc/apt/sources.list.d/github-cli.list \
31
40
  && apt-get update \
32
41
  && apt-get install -y --no-install-recommends gh \
42
+ build-essential pkg-config \
43
+ unzip zip xz-utils bzip2 wget jq ripgrep fd-find tree file procps rsync patch sqlite3 \
44
+ libicu72 libssl3 zlib1g libgssapi-krb5-2 \
45
+ && ln -s /usr/bin/fdfind /usr/local/bin/fd \
33
46
  && rm -rf /var/lib/apt/lists/*
34
47
 
48
+ ARG DOTNET_SDK_CHANNEL=10.0
49
+ ENV DOTNET_ROOT=/usr/share/dotnet \
50
+ DOTNET_CLI_TELEMETRY_OPTOUT=1 \
51
+ DOTNET_NOLOGO=1 \
52
+ DOTNET_GENERATE_ASPNET_CERTIFICATE=false \
53
+ DOTNET_SKIP_WORKLOAD_INTEGRITY_CHECK=true \
54
+ NUGET_XMLDOC_MODE=skip
55
+ RUN curl -fsSL https://dot.net/v1/dotnet-install.sh -o /tmp/dotnet-install.sh \
56
+ && bash /tmp/dotnet-install.sh --channel "${DOTNET_SDK_CHANNEL}" --install-dir "${DOTNET_ROOT}" \
57
+ && ln -s "${DOTNET_ROOT}/dotnet" /usr/local/bin/dotnet \
58
+ && rm /tmp/dotnet-install.sh
59
+
60
+ # Python comes from uv (python-build-standalone), not Debian: one toolchain for
61
+ # interpreters, venvs and tools; python/python3/pip stay on PATH for node-gyp and habit
62
+ ARG PYTHON_VERSION=3.14
63
+ RUN UV_PYTHON_INSTALL_DIR=/usr/local/share/uv/python UV_PYTHON_BIN_DIR=/usr/local/bin \
64
+ uv python install "${PYTHON_VERSION}" --default \
65
+ && ln -s "$(dirname "$(readlink -f /usr/local/bin/python3)")/pip3" /usr/local/bin/pip3 \
66
+ && ln -s pip3 /usr/local/bin/pip
67
+
35
68
  # System-level, not ~/.gitconfig: /home/agent is the persistent volume and
36
69
  # shadows anything baked into home for existing installs
37
70
  COPY gitconfig /etc/gitconfig
@@ -40,7 +73,12 @@ COPY runner-marker /etc/maesttro/runner
40
73
  # Curated client CLIs — keep in sync with src/clients.ts
41
74
  RUN npm install -g \
42
75
  @anthropic-ai/claude-code \
43
- opencode-ai
76
+ opencode-ai \
77
+ typescript \
78
+ && corepack enable
79
+ # The image pins the client version; an in-container update would only land on
80
+ # the ephemeral layer and be re-downloaded every session
81
+ ENV DISABLE_AUTOUPDATER=1
44
82
 
45
83
  RUN useradd -m -s /bin/bash agent
46
84
  USER agent
@@ -49,6 +87,27 @@ USER agent
49
87
  RUN mkdir -p /home/agent/.config/opencode /home/agent/.claude
50
88
  WORKDIR /workspace
51
89
 
90
+ # Everything the agent installs lands on the container's writable layer, never
91
+ # the shared /home/agent volume, so it is gone when the session's container exits
92
+ ENV AGENT_TOOLS=/opt/agent-tools
93
+ ENV NPM_CONFIG_PREFIX=${AGENT_TOOLS} \
94
+ NPM_CONFIG_CACHE=${AGENT_TOOLS}/cache/npm \
95
+ COREPACK_HOME=${AGENT_TOOLS}/corepack \
96
+ COREPACK_ENABLE_DOWNLOAD_PROMPT=0 \
97
+ BUN_INSTALL=${AGENT_TOOLS}/bun \
98
+ PYTHONUSERBASE=${AGENT_TOOLS} \
99
+ PIP_BREAK_SYSTEM_PACKAGES=1 \
100
+ PIP_CACHE_DIR=${AGENT_TOOLS}/cache/pip \
101
+ UV_CACHE_DIR=${AGENT_TOOLS}/cache/uv \
102
+ UV_TOOL_DIR=${AGENT_TOOLS}/uv/tools \
103
+ UV_TOOL_BIN_DIR=${AGENT_TOOLS}/bin \
104
+ UV_PYTHON_INSTALL_DIR=${AGENT_TOOLS}/uv/python \
105
+ UV_PYTHON_BIN_DIR=${AGENT_TOOLS}/bin \
106
+ DOTNET_CLI_HOME=${AGENT_TOOLS}/dotnet \
107
+ NUGET_PACKAGES=${AGENT_TOOLS}/cache/nuget \
108
+ NUGET_HTTP_CACHE_PATH=${AGENT_TOOLS}/cache/nuget-http
109
+ ENV PATH=${AGENT_TOOLS}/bin:${AGENT_TOOLS}/bun/bin:${AGENT_TOOLS}/dotnet/.dotnet/tools:${PATH}
110
+
52
111
  # Client configs are applied at container start by `maesttro configure`
53
112
  # (mounted from the host's install): /home/agent is a persistent volume, so
54
113
  # anything baked here would only ever reach brand-new volumes.
@@ -14,5 +14,8 @@ if [ -n "$uid" ] && [ "$(stat -c %u:%g /home/agent)" != "$owner" ]; then
14
14
  find /home/agent -xdev -exec chown -h "$owner" {} + 2>/dev/null || true
15
15
  fi
16
16
 
17
+ mkdir -p "$AGENT_TOOLS"
18
+ chown "$owner" "$AGENT_TOOLS"
19
+
17
20
  export HOME=/home/agent USER=agent LOGNAME=agent
18
21
  exec setpriv --reuid=agent --regid=agent --init-groups /bin/bash -c "$*"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "maesttro",
3
- "version": "0.4.3",
3
+ "version": "0.5.0",
4
4
  "description": "Isolated Docker runner for local coding agents (opencode, claude, ...) under a dedicated bot GitHub identity, with curated configs baked in per client.",
5
5
  "type": "module",
6
6
  "bin": {
@@ -26,5 +26,8 @@
26
26
  "node": ">=18"
27
27
  },
28
28
  "license": "UNLICENSED",
29
- "private": false
29
+ "private": false,
30
+ "devDependencies": {
31
+ "@clack/prompts": "1.8.1"
32
+ }
30
33
  }