bots-garden/mini-mepublic Fork
⑂ ab6a77c
Commits
⬇ Clone ▾
git clone https://git.rickub.com/bots-garden/mini-me.git
git clone ssh://git@rickub.com/bots-garden/mini-me.git

Host key fingerprint (ed25519): SHA256:iycHnxEyq0Q7uyVpB7JlznP0G7JrTPXLYRcAU5CSLhc — verify it before your first connect.

Download ZIP

📦 Mini Me

k33g committed 2026-09-28T08:00:03+02:00 Browse files
ab6a77c parent: 59269a2
modified .gitignore +2 -2
@@ -1,8 +1,8 @@
1-kits
1+/kits
22 notes.txt
33 tmp
44 mm
5-mm-*
5+/mm-*
66 .mm/
77 blog
88 ebook
@@ -1,8 +1,8 @@
1-kits1+/kits
2 notes.txt2 notes.txt
3 tmp3 tmp
4 mm4 mm
5-mm-*5+/mm-*
6 .mm/6 .mm/
7 blog7 blog
8 ebook8 ebook
modified INSTALL.MACOS.md +64 -2
@@ -6,6 +6,68 @@ VERSION=0.2.1
66 curl -fsSLO "https://rickub.com/bots-garden/mini-me/releases/download/v${VERSION}/mm-${VERSION}-darwin-arm64"
77 chmod +x ./mm-${VERSION}-darwin-arm64
88 xattr -cr ./mm-${VERSION}-darwin-arm64
9-sudo rm /usr/local/bin/mm
9+sudo rm -f /usr/local/bin/mm
1010 sudo cp ./mm-${VERSION}-darwin-arm64 /usr/local/bin/mm
11-```
\ No newline at end of file
11+```
12+
13+## Use `mm` in a Docker Sandbox (the two kits)
14+
15+Instead of installing the binary, `mm` can run inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/): every command the model runs and every file it edits then happens in a container, on your mounted project. Two kits are published on Docker Hub at mm's version; each one brings the `k33g/mm-sandbox` image with `mm` in it, so nothing is built on your Mac.
16+
17+| Kit | For |
18+|---|---|
19+| `k33g/mm-tui:0.2.1` | the window mode (`mm -tui`) in your terminal |
20+| `k33g/mm-acp:0.2.1` | an editor that speaks the Agent Client Protocol (Zed, …) |
21+
22+You need Docker Desktop with the `sbx` command, and your model server (Docker Model Runner or llama-server) running on the Mac. Inside the sandbox, `localhost` is the sandbox itself: `agent.dmr.yaml` already falls back to `host.docker.internal`, which reaches the Mac.
23+
24+### Window mode: `mm-tui`
25+
26+From the project you want `mm` to work on:
27+
28+```bash
29+cd /path/to/your/project
30+sbx kit inspect k33g/mm-tui:0.2.1 # optional: what the kit declares
31+sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml
32+```
33+
34+What follows `--` is `mm`'s own command line (here the configuration file, relative to the project). `sbx ls` lists the sandboxes; `sbx run --name <name>` re-attaches to one.
35+
36+### From an editor: `mm-acp`
37+
38+Create the sandbox once, from the project the editor will open, with the configuration file baked in:
39+
40+```bash
41+cd /path/to/your/project
42+sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
43+```
44+
45+Then register it in Zed's `settings.json`:
46+
47+```json
48+{
49+ "agent_servers": {
50+ "mini-me (sandbox)": {
51+ "type": "custom",
52+ "command": "sbx",
53+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
54+ }
55+ }
56+}
57+```
58+
59+If Zed cannot find `sbx`, put the absolute path given by `which sbx` in `"command"`. One sandbox per project: give each one its own `--name` and its own entry in Zed. `sbx rm mm-acp` removes a sandbox; your project directory is not touched.
60+
61+### The v3 kits
62+
63+The same two kits also exist for the kit specification v3, in `docker-sbx-v3/` (not published yet, and not yet tried with `sbx`). From a clone of this repository:
64+
65+```bash
66+cd /path/to/your/project
67+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
68+sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml
69+```
70+
71+With the v3 kits, give `config` a path relative to the project: the workspace is mounted at `/home/agent/workspace`, so a `/Users/…` path does not exist inside the sandbox.
72+
73+Full guides: [Run mini-me in a Docker Sandbox](docs/en/how-to/run-in-a-docker-sandbox.md) (v2 kits, MCP, variants) and [Run mini-me with the v3 sandbox kits](docs/en/how-to/run-with-sandbox-kits-v3.md).
@@ -6,6 +6,68 @@ VERSION=0.2.1
6 curl -fsSLO "https://rickub.com/bots-garden/mini-me/releases/download/v${VERSION}/mm-${VERSION}-darwin-arm64"6 curl -fsSLO "https://rickub.com/bots-garden/mini-me/releases/download/v${VERSION}/mm-${VERSION}-darwin-arm64"
7 chmod +x ./mm-${VERSION}-darwin-arm647 chmod +x ./mm-${VERSION}-darwin-arm64
8 xattr -cr ./mm-${VERSION}-darwin-arm648 xattr -cr ./mm-${VERSION}-darwin-arm64
9-sudo rm /usr/local/bin/mm9+sudo rm -f /usr/local/bin/mm
10 sudo cp ./mm-${VERSION}-darwin-arm64 /usr/local/bin/mm10 sudo cp ./mm-${VERSION}-darwin-arm64 /usr/local/bin/mm
11-```
\ No newline at end of file\ No newline at end of file
11+```
12+
13+## Use `mm` in a Docker Sandbox (the two kits)
14+
15+Instead of installing the binary, `mm` can run inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/): every command the model runs and every file it edits then happens in a container, on your mounted project. Two kits are published on Docker Hub at mm's version; each one brings the `k33g/mm-sandbox` image with `mm` in it, so nothing is built on your Mac.
16+
17+| Kit | For |
18+|---|---|
19+| `k33g/mm-tui:0.2.1` | the window mode (`mm -tui`) in your terminal |
20+| `k33g/mm-acp:0.2.1` | an editor that speaks the Agent Client Protocol (Zed, …) |
21+
22+You need Docker Desktop with the `sbx` command, and your model server (Docker Model Runner or llama-server) running on the Mac. Inside the sandbox, `localhost` is the sandbox itself: `agent.dmr.yaml` already falls back to `host.docker.internal`, which reaches the Mac.
23+
24+### Window mode: `mm-tui`
25+
26+From the project you want `mm` to work on:
27+
28+```bash
29+cd /path/to/your/project
30+sbx kit inspect k33g/mm-tui:0.2.1 # optional: what the kit declares
31+sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml
32+```
33+
34+What follows `--` is `mm`'s own command line (here the configuration file, relative to the project). `sbx ls` lists the sandboxes; `sbx run --name <name>` re-attaches to one.
35+
36+### From an editor: `mm-acp`
37+
38+Create the sandbox once, from the project the editor will open, with the configuration file baked in:
39+
40+```bash
41+cd /path/to/your/project
42+sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
43+```
44+
45+Then register it in Zed's `settings.json`:
46+
47+```json
48+{
49+ "agent_servers": {
50+ "mini-me (sandbox)": {
51+ "type": "custom",
52+ "command": "sbx",
53+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
54+ }
55+ }
56+}
57+```
58+
59+If Zed cannot find `sbx`, put the absolute path given by `which sbx` in `"command"`. One sandbox per project: give each one its own `--name` and its own entry in Zed. `sbx rm mm-acp` removes a sandbox; your project directory is not touched.
60+
61+### The v3 kits
62+
63+The same two kits also exist for the kit specification v3, in `docker-sbx-v3/` (not published yet, and not yet tried with `sbx`). From a clone of this repository:
64+
65+```bash
66+cd /path/to/your/project
67+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
68+sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml
69+```
70+
71+With the v3 kits, give `config` a path relative to the project: the workspace is mounted at `/home/agent/workspace`, so a `/Users/…` path does not exist inside the sandbox.
72+
73+Full guides: [Run mini-me in a Docker Sandbox](docs/en/how-to/run-in-a-docker-sandbox.md) (v2 kits, MCP, variants) and [Run mini-me with the v3 sandbox kits](docs/en/how-to/run-with-sandbox-kits-v3.md).
added config.samples/agent.dmr.gemma.yaml +182 -0
new file mode 100644
@@ -0,0 +1,182 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+
3+provider: dmr
4+
5+#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
6+model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M
7+#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M
8+
9+baseUrl: http://localhost:12434/engines/v1
10+fallback: http://host.docker.internal:12434/engines/v1
11+
12+# Only when llama-server was started with --api-key; unset otherwise.
13+# apiKeyEnv: LLAMA_API_KEY
14+
15+# The `bash` tool.
16+# `false` removes it: the model can still read and edit files (editTools) and load skills,
17+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
18+bashTool: true
19+
20+# The built-in file tools: read_file, write_file, edit_file.
21+editTools: true
22+
23+# The built-in plan tool for managing multi-step plans.
24+# Set to false to disable plan creation and tracking via the `plan` tool.
25+planTool: true
26+
27+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
28+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
29+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
30+# lsp:
31+# servers:
32+# - name: gopls
33+# command: gopls
34+# extensions: [".go"]
35+# - name: typescript
36+# command: typescript-language-server
37+# args: ["--stdio"]
38+# extensions: [".ts", ".tsx", ".js", ".jsx"]
39+# - name: python
40+# command: pyright-langserver
41+# args: ["--stdio"]
42+# extensions: [".py"]
43+# - name: rust
44+# command: rust-analyzer
45+# extensions: [".rs"]
46+
47+# How many tokens the server actually serves.
48+# 0 = ask the server (llama-server tells it on /props)
49+contextWindow: 0
50+
51+# Max number of characters a tool returns to the model.
52+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
53+maxOutput: 16000
54+
55+# Max number of model <-> tools round trips for a single question.
56+# Raise it for tasks that need long chains of commands.
57+maxTurns: 40
58+
59+# Where the `read_skill` tool looks for its markdown procedures.
60+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
61+skillsDir: skills
62+
63+# Persistent sessions, per project.
64+# When enabled, every conversation is saved as one JSON file under `dir`.
65+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
66+sessions:
67+ enabled: true
68+ dir: .mm/sessions
69+
70+# How many lines of a command's output are echoed to the terminal.
71+# 0 disables it.
72+previewLines: 20
73+
74+displayCommands: true
75+# Show what a thinking model reasons about before it answers (dim italic in the
76+# terminal, its own style in the window, a thought chunk in an editor).
77+# The reasoning is always READ — it is what keeps the watchdog alive while the
78+# model thinks — this only says whether to show it.
79+showThinking: true
80+
81+
82+# The system prompt: what the agent is, and what it is allowed to do.
83+# This is the knob to play with — it is the shortest path to changing behaviour.
84+system: |
85+ Your name is Bob.
86+ You are a coding agent working in a terminal.
87+ You have a "bash" tool to run shell commands.
88+ Use it to explore files, run tests, inspect the repository, etc.
89+ Chain several commands if needed, then answer clearly in English.
90+
91+ A request often mixes things you answer from yourself ("say hello") with
92+ things only a command can answer ("list the files"). Handle every part, in
93+ the order asked, and run a command for each part that needs one.
94+ Never state the contents of a file, the output of a command, or the state of
95+ the repository unless a command in THIS answer returned it. What you did not
96+ read, you do not know: run the command instead of recalling it.
97+
98+ SKILLS
99+ You have a second tool, `read_skill`. Its description lists the procedures
100+ available for this project — one per kind of task.
101+
102+ Any request to DO something to a Go project is a skill, not a shell command
103+ you invent. Match the request against that list, call `read_skill` FIRST,
104+ before any bash command, and then follow what it says step by step.
105+
106+ FILE EDITING
107+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
108+ They are how a file gets read and changed here: each change is exact,
109+ checked before it is written, and comes back as a diff with line numbers.
110+ bash is for running things — building, testing, listing, searching.
111+
112+ - Read before you write: call `read_file` on the file (numbered=true when
113+ you need line numbers). You cannot target text you have not seen; never
114+ rely on what you think you remember about a file.
115+ - To change an existing file, call `edit_file` with one or more {old, new}
116+ pairs. `old` is copied from the file character for character — same
117+ spaces, same indentation, same line breaks — and appears exactly once:
118+ add the surrounding lines until it is unique. Several pairs are applied
119+ together, against the original file. An empty `new` deletes the text.
120+ - Call `write_file` only to create a file, or to rewrite one entirely and
121+ on purpose. On an existing file it replaces everything, including what
122+ you did not intend to touch.
123+ - Read the diff the tool returns: it says exactly what changed and on which
124+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
125+ edits — read the file again and fix `old`. Do not fall back to
126+ `write_file` to force the change through.
127+ - After editing code, run the narrowest check with bash: the formatter, the
128+ compiler, or the test covering that file.
129+
130+ RULES
131+ - Keep everything the file already does, unless the user asked to remove it.
132+ - Touch only the files the request is about. Do not add tests, files or
133+ features that were not asked for.
134+ - Never run a git command unless the user says git, commit or push.
135+ - Never move, rename or delete a file unless the user asked for it.
136+ - Then answer in English, in a few lines.
137+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
138+ to understand the options, then run the command.
139+
140+ BACKGROUND JOBS
141+ Never let a command block the answer. Anything that serves, watches or runs
142+ long goes to the background, with BOTH streams redirected and its pid kept:
143+
144+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
145+
146+ Redirecting only stdout still blocks until the process exits. Read the
147+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
148+ rule you cannot guess. Stop every job you started before you finish, and say
149+ which ones you left running.
150+
151+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
152+# we want precise and reproducible answers, not creativity.
153+sampling:
154+ temperature: 0.0
155+ parallel_tool_calls: false
156+ top_p: 0.9
157+ max_tokens: 32768
158+
159+# llama-server processes the whole prompt before the first token;
160+# on a laptop a 32k context can take a while. Raise it if it fires.
161+watchdogTimeout: 300s
162+
163+# Context compression.
164+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
165+context:
166+ enabled: true
167+
168+ # Compress when the history reaches this share of the window.
169+ threshold: 75
170+
171+ # Fallback on the message count, for when the window is unknown.
172+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
173+ maxMessages: 80
174+
175+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
176+ # The model works on the last few turns, so summarising them would make it redo what it just did.
177+ keepLastTurns: 3
178+
179+ # max_tokens of the summary request.
180+ summaryMaxTokens: 1200
181+
182+ showStats: true
new file mode 100644
@@ -0,0 +1,182 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+
3+provider: dmr
4+
5+#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
6+model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M
7+#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M
8+
9+baseUrl: http://localhost:12434/engines/v1
10+fallback: http://host.docker.internal:12434/engines/v1
11+
12+# Only when llama-server was started with --api-key; unset otherwise.
13+# apiKeyEnv: LLAMA_API_KEY
14+
15+# The `bash` tool.
16+# `false` removes it: the model can still read and edit files (editTools) and load skills,
17+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
18+bashTool: true
19+
20+# The built-in file tools: read_file, write_file, edit_file.
21+editTools: true
22+
23+# The built-in plan tool for managing multi-step plans.
24+# Set to false to disable plan creation and tracking via the `plan` tool.
25+planTool: true
26+
27+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
28+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
29+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
30+# lsp:
31+# servers:
32+# - name: gopls
33+# command: gopls
34+# extensions: [".go"]
35+# - name: typescript
36+# command: typescript-language-server
37+# args: ["--stdio"]
38+# extensions: [".ts", ".tsx", ".js", ".jsx"]
39+# - name: python
40+# command: pyright-langserver
41+# args: ["--stdio"]
42+# extensions: [".py"]
43+# - name: rust
44+# command: rust-analyzer
45+# extensions: [".rs"]
46+
47+# How many tokens the server actually serves.
48+# 0 = ask the server (llama-server tells it on /props)
49+contextWindow: 0
50+
51+# Max number of characters a tool returns to the model.
52+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
53+maxOutput: 16000
54+
55+# Max number of model <-> tools round trips for a single question.
56+# Raise it for tasks that need long chains of commands.
57+maxTurns: 40
58+
59+# Where the `read_skill` tool looks for its markdown procedures.
60+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
61+skillsDir: skills
62+
63+# Persistent sessions, per project.
64+# When enabled, every conversation is saved as one JSON file under `dir`.
65+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
66+sessions:
67+ enabled: true
68+ dir: .mm/sessions
69+
70+# How many lines of a command's output are echoed to the terminal.
71+# 0 disables it.
72+previewLines: 20
73+
74+displayCommands: true
75+# Show what a thinking model reasons about before it answers (dim italic in the
76+# terminal, its own style in the window, a thought chunk in an editor).
77+# The reasoning is always READ — it is what keeps the watchdog alive while the
78+# model thinks — this only says whether to show it.
79+showThinking: true
80+
81+
82+# The system prompt: what the agent is, and what it is allowed to do.
83+# This is the knob to play with — it is the shortest path to changing behaviour.
84+system: |
85+ Your name is Bob.
86+ You are a coding agent working in a terminal.
87+ You have a "bash" tool to run shell commands.
88+ Use it to explore files, run tests, inspect the repository, etc.
89+ Chain several commands if needed, then answer clearly in English.
90+
91+ A request often mixes things you answer from yourself ("say hello") with
92+ things only a command can answer ("list the files"). Handle every part, in
93+ the order asked, and run a command for each part that needs one.
94+ Never state the contents of a file, the output of a command, or the state of
95+ the repository unless a command in THIS answer returned it. What you did not
96+ read, you do not know: run the command instead of recalling it.
97+
98+ SKILLS
99+ You have a second tool, `read_skill`. Its description lists the procedures
100+ available for this project — one per kind of task.
101+
102+ Any request to DO something to a Go project is a skill, not a shell command
103+ you invent. Match the request against that list, call `read_skill` FIRST,
104+ before any bash command, and then follow what it says step by step.
105+
106+ FILE EDITING
107+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
108+ They are how a file gets read and changed here: each change is exact,
109+ checked before it is written, and comes back as a diff with line numbers.
110+ bash is for running things — building, testing, listing, searching.
111+
112+ - Read before you write: call `read_file` on the file (numbered=true when
113+ you need line numbers). You cannot target text you have not seen; never
114+ rely on what you think you remember about a file.
115+ - To change an existing file, call `edit_file` with one or more {old, new}
116+ pairs. `old` is copied from the file character for character — same
117+ spaces, same indentation, same line breaks — and appears exactly once:
118+ add the surrounding lines until it is unique. Several pairs are applied
119+ together, against the original file. An empty `new` deletes the text.
120+ - Call `write_file` only to create a file, or to rewrite one entirely and
121+ on purpose. On an existing file it replaces everything, including what
122+ you did not intend to touch.
123+ - Read the diff the tool returns: it says exactly what changed and on which
124+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
125+ edits — read the file again and fix `old`. Do not fall back to
126+ `write_file` to force the change through.
127+ - After editing code, run the narrowest check with bash: the formatter, the
128+ compiler, or the test covering that file.
129+
130+ RULES
131+ - Keep everything the file already does, unless the user asked to remove it.
132+ - Touch only the files the request is about. Do not add tests, files or
133+ features that were not asked for.
134+ - Never run a git command unless the user says git, commit or push.
135+ - Never move, rename or delete a file unless the user asked for it.
136+ - Then answer in English, in a few lines.
137+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
138+ to understand the options, then run the command.
139+
140+ BACKGROUND JOBS
141+ Never let a command block the answer. Anything that serves, watches or runs
142+ long goes to the background, with BOTH streams redirected and its pid kept:
143+
144+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
145+
146+ Redirecting only stdout still blocks until the process exits. Read the
147+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
148+ rule you cannot guess. Stop every job you started before you finish, and say
149+ which ones you left running.
150+
151+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
152+# we want precise and reproducible answers, not creativity.
153+sampling:
154+ temperature: 0.0
155+ parallel_tool_calls: false
156+ top_p: 0.9
157+ max_tokens: 32768
158+
159+# llama-server processes the whole prompt before the first token;
160+# on a laptop a 32k context can take a while. Raise it if it fires.
161+watchdogTimeout: 300s
162+
163+# Context compression.
164+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
165+context:
166+ enabled: true
167+
168+ # Compress when the history reaches this share of the window.
169+ threshold: 75
170+
171+ # Fallback on the message count, for when the window is unknown.
172+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
173+ maxMessages: 80
174+
175+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
176+ # The model works on the last few turns, so summarising them would make it redo what it just did.
177+ keepLastTurns: 3
178+
179+ # max_tokens of the summary request.
180+ summaryMaxTokens: 1200
181+
182+ showStats: true
added config.samples/agent.dmr.gpt-oss.yaml +183 -0
new file mode 100644
@@ -0,0 +1,183 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+
3+provider: dmr
4+
5+#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
6+#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M
7+#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M
8+model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL
9+
10+baseUrl: http://localhost:12434/engines/v1
11+fallback: http://host.docker.internal:12434/engines/v1
12+
13+# Only when llama-server was started with --api-key; unset otherwise.
14+# apiKeyEnv: LLAMA_API_KEY
15+
16+# The `bash` tool.
17+# `false` removes it: the model can still read and edit files (editTools) and load skills,
18+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
19+bashTool: true
20+
21+# The built-in file tools: read_file, write_file, edit_file.
22+editTools: true
23+
24+# The built-in plan tool for managing multi-step plans.
25+# Set to false to disable plan creation and tracking via the `plan` tool.
26+planTool: true
27+
28+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
29+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
30+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
31+# lsp:
32+# servers:
33+# - name: gopls
34+# command: gopls
35+# extensions: [".go"]
36+# - name: typescript
37+# command: typescript-language-server
38+# args: ["--stdio"]
39+# extensions: [".ts", ".tsx", ".js", ".jsx"]
40+# - name: python
41+# command: pyright-langserver
42+# args: ["--stdio"]
43+# extensions: [".py"]
44+# - name: rust
45+# command: rust-analyzer
46+# extensions: [".rs"]
47+
48+# How many tokens the server actually serves.
49+# 0 = ask the server (llama-server tells it on /props)
50+contextWindow: 0
51+
52+# Max number of characters a tool returns to the model.
53+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
54+maxOutput: 16000
55+
56+# Max number of model <-> tools round trips for a single question.
57+# Raise it for tasks that need long chains of commands.
58+maxTurns: 40
59+
60+# Where the `read_skill` tool looks for its markdown procedures.
61+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
62+skillsDir: skills
63+
64+# Persistent sessions, per project.
65+# When enabled, every conversation is saved as one JSON file under `dir`.
66+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
67+sessions:
68+ enabled: true
69+ dir: .mm/sessions
70+
71+# How many lines of a command's output are echoed to the terminal.
72+# 0 disables it.
73+previewLines: 20
74+
75+displayCommands: true
76+# Show what a thinking model reasons about before it answers (dim italic in the
77+# terminal, its own style in the window, a thought chunk in an editor).
78+# The reasoning is always READ — it is what keeps the watchdog alive while the
79+# model thinks — this only says whether to show it.
80+showThinking: true
81+
82+
83+# The system prompt: what the agent is, and what it is allowed to do.
84+# This is the knob to play with — it is the shortest path to changing behaviour.
85+system: |
86+ Your name is Bob.
87+ You are a coding agent working in a terminal.
88+ You have a "bash" tool to run shell commands.
89+ Use it to explore files, run tests, inspect the repository, etc.
90+ Chain several commands if needed, then answer clearly in English.
91+
92+ A request often mixes things you answer from yourself ("say hello") with
93+ things only a command can answer ("list the files"). Handle every part, in
94+ the order asked, and run a command for each part that needs one.
95+ Never state the contents of a file, the output of a command, or the state of
96+ the repository unless a command in THIS answer returned it. What you did not
97+ read, you do not know: run the command instead of recalling it.
98+
99+ SKILLS
100+ You have a second tool, `read_skill`. Its description lists the procedures
101+ available for this project — one per kind of task.
102+
103+ Any request to DO something to a Go project is a skill, not a shell command
104+ you invent. Match the request against that list, call `read_skill` FIRST,
105+ before any bash command, and then follow what it says step by step.
106+
107+ FILE EDITING
108+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
109+ They are how a file gets read and changed here: each change is exact,
110+ checked before it is written, and comes back as a diff with line numbers.
111+ bash is for running things — building, testing, listing, searching.
112+
113+ - Read before you write: call `read_file` on the file (numbered=true when
114+ you need line numbers). You cannot target text you have not seen; never
115+ rely on what you think you remember about a file.
116+ - To change an existing file, call `edit_file` with one or more {old, new}
117+ pairs. `old` is copied from the file character for character — same
118+ spaces, same indentation, same line breaks — and appears exactly once:
119+ add the surrounding lines until it is unique. Several pairs are applied
120+ together, against the original file. An empty `new` deletes the text.
121+ - Call `write_file` only to create a file, or to rewrite one entirely and
122+ on purpose. On an existing file it replaces everything, including what
123+ you did not intend to touch.
124+ - Read the diff the tool returns: it says exactly what changed and on which
125+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
126+ edits — read the file again and fix `old`. Do not fall back to
127+ `write_file` to force the change through.
128+ - After editing code, run the narrowest check with bash: the formatter, the
129+ compiler, or the test covering that file.
130+
131+ RULES
132+ - Keep everything the file already does, unless the user asked to remove it.
133+ - Touch only the files the request is about. Do not add tests, files or
134+ features that were not asked for.
135+ - Never run a git command unless the user says git, commit or push.
136+ - Never move, rename or delete a file unless the user asked for it.
137+ - Then answer in English, in a few lines.
138+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
139+ to understand the options, then run the command.
140+
141+ BACKGROUND JOBS
142+ Never let a command block the answer. Anything that serves, watches or runs
143+ long goes to the background, with BOTH streams redirected and its pid kept:
144+
145+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
146+
147+ Redirecting only stdout still blocks until the process exits. Read the
148+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
149+ rule you cannot guess. Stop every job you started before you finish, and say
150+ which ones you left running.
151+
152+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
153+# we want precise and reproducible answers, not creativity.
154+sampling:
155+ temperature: 0.0
156+ parallel_tool_calls: false
157+ top_p: 0.9
158+ max_tokens: 32768
159+
160+# llama-server processes the whole prompt before the first token;
161+# on a laptop a 32k context can take a while. Raise it if it fires.
162+watchdogTimeout: 300s
163+
164+# Context compression.
165+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
166+context:
167+ enabled: true
168+
169+ # Compress when the history reaches this share of the window.
170+ threshold: 75
171+
172+ # Fallback on the message count, for when the window is unknown.
173+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
174+ maxMessages: 80
175+
176+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
177+ # The model works on the last few turns, so summarising them would make it redo what it just did.
178+ keepLastTurns: 3
179+
180+ # max_tokens of the summary request.
181+ summaryMaxTokens: 1200
182+
183+ showStats: true
new file mode 100644
@@ -0,0 +1,183 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+
3+provider: dmr
4+
5+#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
6+#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M
7+#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M
8+model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL
9+
10+baseUrl: http://localhost:12434/engines/v1
11+fallback: http://host.docker.internal:12434/engines/v1
12+
13+# Only when llama-server was started with --api-key; unset otherwise.
14+# apiKeyEnv: LLAMA_API_KEY
15+
16+# The `bash` tool.
17+# `false` removes it: the model can still read and edit files (editTools) and load skills,
18+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
19+bashTool: true
20+
21+# The built-in file tools: read_file, write_file, edit_file.
22+editTools: true
23+
24+# The built-in plan tool for managing multi-step plans.
25+# Set to false to disable plan creation and tracking via the `plan` tool.
26+planTool: true
27+
28+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
29+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
30+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
31+# lsp:
32+# servers:
33+# - name: gopls
34+# command: gopls
35+# extensions: [".go"]
36+# - name: typescript
37+# command: typescript-language-server
38+# args: ["--stdio"]
39+# extensions: [".ts", ".tsx", ".js", ".jsx"]
40+# - name: python
41+# command: pyright-langserver
42+# args: ["--stdio"]
43+# extensions: [".py"]
44+# - name: rust
45+# command: rust-analyzer
46+# extensions: [".rs"]
47+
48+# How many tokens the server actually serves.
49+# 0 = ask the server (llama-server tells it on /props)
50+contextWindow: 0
51+
52+# Max number of characters a tool returns to the model.
53+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
54+maxOutput: 16000
55+
56+# Max number of model <-> tools round trips for a single question.
57+# Raise it for tasks that need long chains of commands.
58+maxTurns: 40
59+
60+# Where the `read_skill` tool looks for its markdown procedures.
61+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
62+skillsDir: skills
63+
64+# Persistent sessions, per project.
65+# When enabled, every conversation is saved as one JSON file under `dir`.
66+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
67+sessions:
68+ enabled: true
69+ dir: .mm/sessions
70+
71+# How many lines of a command's output are echoed to the terminal.
72+# 0 disables it.
73+previewLines: 20
74+
75+displayCommands: true
76+# Show what a thinking model reasons about before it answers (dim italic in the
77+# terminal, its own style in the window, a thought chunk in an editor).
78+# The reasoning is always READ — it is what keeps the watchdog alive while the
79+# model thinks — this only says whether to show it.
80+showThinking: true
81+
82+
83+# The system prompt: what the agent is, and what it is allowed to do.
84+# This is the knob to play with — it is the shortest path to changing behaviour.
85+system: |
86+ Your name is Bob.
87+ You are a coding agent working in a terminal.
88+ You have a "bash" tool to run shell commands.
89+ Use it to explore files, run tests, inspect the repository, etc.
90+ Chain several commands if needed, then answer clearly in English.
91+
92+ A request often mixes things you answer from yourself ("say hello") with
93+ things only a command can answer ("list the files"). Handle every part, in
94+ the order asked, and run a command for each part that needs one.
95+ Never state the contents of a file, the output of a command, or the state of
96+ the repository unless a command in THIS answer returned it. What you did not
97+ read, you do not know: run the command instead of recalling it.
98+
99+ SKILLS
100+ You have a second tool, `read_skill`. Its description lists the procedures
101+ available for this project — one per kind of task.
102+
103+ Any request to DO something to a Go project is a skill, not a shell command
104+ you invent. Match the request against that list, call `read_skill` FIRST,
105+ before any bash command, and then follow what it says step by step.
106+
107+ FILE EDITING
108+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
109+ They are how a file gets read and changed here: each change is exact,
110+ checked before it is written, and comes back as a diff with line numbers.
111+ bash is for running things — building, testing, listing, searching.
112+
113+ - Read before you write: call `read_file` on the file (numbered=true when
114+ you need line numbers). You cannot target text you have not seen; never
115+ rely on what you think you remember about a file.
116+ - To change an existing file, call `edit_file` with one or more {old, new}
117+ pairs. `old` is copied from the file character for character — same
118+ spaces, same indentation, same line breaks — and appears exactly once:
119+ add the surrounding lines until it is unique. Several pairs are applied
120+ together, against the original file. An empty `new` deletes the text.
121+ - Call `write_file` only to create a file, or to rewrite one entirely and
122+ on purpose. On an existing file it replaces everything, including what
123+ you did not intend to touch.
124+ - Read the diff the tool returns: it says exactly what changed and on which
125+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
126+ edits — read the file again and fix `old`. Do not fall back to
127+ `write_file` to force the change through.
128+ - After editing code, run the narrowest check with bash: the formatter, the
129+ compiler, or the test covering that file.
130+
131+ RULES
132+ - Keep everything the file already does, unless the user asked to remove it.
133+ - Touch only the files the request is about. Do not add tests, files or
134+ features that were not asked for.
135+ - Never run a git command unless the user says git, commit or push.
136+ - Never move, rename or delete a file unless the user asked for it.
137+ - Then answer in English, in a few lines.
138+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
139+ to understand the options, then run the command.
140+
141+ BACKGROUND JOBS
142+ Never let a command block the answer. Anything that serves, watches or runs
143+ long goes to the background, with BOTH streams redirected and its pid kept:
144+
145+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
146+
147+ Redirecting only stdout still blocks until the process exits. Read the
148+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
149+ rule you cannot guess. Stop every job you started before you finish, and say
150+ which ones you left running.
151+
152+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
153+# we want precise and reproducible answers, not creativity.
154+sampling:
155+ temperature: 0.0
156+ parallel_tool_calls: false
157+ top_p: 0.9
158+ max_tokens: 32768
159+
160+# llama-server processes the whole prompt before the first token;
161+# on a laptop a 32k context can take a while. Raise it if it fires.
162+watchdogTimeout: 300s
163+
164+# Context compression.
165+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
166+context:
167+ enabled: true
168+
169+ # Compress when the history reaches this share of the window.
170+ threshold: 75
171+
172+ # Fallback on the message count, for when the window is unknown.
173+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
174+ maxMessages: 80
175+
176+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
177+ # The model works on the last few turns, so summarising them would make it redo what it just did.
178+ keepLastTurns: 3
179+
180+ # max_tokens of the summary request.
181+ summaryMaxTokens: 1200
182+
183+ showStats: true
added config.samples/agent.dmr.qwen3.6.yaml +185 -0
new file mode 100644
@@ -0,0 +1,185 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+
3+provider: dmr
4+
5+#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
6+#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M
7+#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M
8+#model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL
9+
10+model: huggingface.co/unsloth/qwen3.6-35b-a3b-gguf:UD-Q4_K_M
11+
12+baseUrl: http://localhost:12434/engines/v1
13+fallback: http://host.docker.internal:12434/engines/v1
14+
15+# Only when llama-server was started with --api-key; unset otherwise.
16+# apiKeyEnv: LLAMA_API_KEY
17+
18+# The `bash` tool.
19+# `false` removes it: the model can still read and edit files (editTools) and load skills,
20+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
21+bashTool: true
22+
23+# The built-in file tools: read_file, write_file, edit_file.
24+editTools: true
25+
26+# The built-in plan tool for managing multi-step plans.
27+# Set to false to disable plan creation and tracking via the `plan` tool.
28+planTool: true
29+
30+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
31+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
32+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
33+# lsp:
34+# servers:
35+# - name: gopls
36+# command: gopls
37+# extensions: [".go"]
38+# - name: typescript
39+# command: typescript-language-server
40+# args: ["--stdio"]
41+# extensions: [".ts", ".tsx", ".js", ".jsx"]
42+# - name: python
43+# command: pyright-langserver
44+# args: ["--stdio"]
45+# extensions: [".py"]
46+# - name: rust
47+# command: rust-analyzer
48+# extensions: [".rs"]
49+
50+# How many tokens the server actually serves.
51+# 0 = ask the server (llama-server tells it on /props)
52+contextWindow: 0
53+
54+# Max number of characters a tool returns to the model.
55+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
56+maxOutput: 16000
57+
58+# Max number of model <-> tools round trips for a single question.
59+# Raise it for tasks that need long chains of commands.
60+maxTurns: 40
61+
62+# Where the `read_skill` tool looks for its markdown procedures.
63+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
64+skillsDir: skills
65+
66+# Persistent sessions, per project.
67+# When enabled, every conversation is saved as one JSON file under `dir`.
68+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
69+sessions:
70+ enabled: true
71+ dir: .mm/sessions
72+
73+# How many lines of a command's output are echoed to the terminal.
74+# 0 disables it.
75+previewLines: 20
76+
77+displayCommands: true
78+# Show what a thinking model reasons about before it answers (dim italic in the
79+# terminal, its own style in the window, a thought chunk in an editor).
80+# The reasoning is always READ — it is what keeps the watchdog alive while the
81+# model thinks — this only says whether to show it.
82+showThinking: true
83+
84+
85+# The system prompt: what the agent is, and what it is allowed to do.
86+# This is the knob to play with — it is the shortest path to changing behaviour.
87+system: |
88+ Your name is Bob.
89+ You are a coding agent working in a terminal.
90+ You have a "bash" tool to run shell commands.
91+ Use it to explore files, run tests, inspect the repository, etc.
92+ Chain several commands if needed, then answer clearly in English.
93+
94+ A request often mixes things you answer from yourself ("say hello") with
95+ things only a command can answer ("list the files"). Handle every part, in
96+ the order asked, and run a command for each part that needs one.
97+ Never state the contents of a file, the output of a command, or the state of
98+ the repository unless a command in THIS answer returned it. What you did not
99+ read, you do not know: run the command instead of recalling it.
100+
101+ SKILLS
102+ You have a second tool, `read_skill`. Its description lists the procedures
103+ available for this project — one per kind of task.
104+
105+ Any request to DO something to a Go project is a skill, not a shell command
106+ you invent. Match the request against that list, call `read_skill` FIRST,
107+ before any bash command, and then follow what it says step by step.
108+
109+ FILE EDITING
110+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
111+ They are how a file gets read and changed here: each change is exact,
112+ checked before it is written, and comes back as a diff with line numbers.
113+ bash is for running things — building, testing, listing, searching.
114+
115+ - Read before you write: call `read_file` on the file (numbered=true when
116+ you need line numbers). You cannot target text you have not seen; never
117+ rely on what you think you remember about a file.
118+ - To change an existing file, call `edit_file` with one or more {old, new}
119+ pairs. `old` is copied from the file character for character — same
120+ spaces, same indentation, same line breaks — and appears exactly once:
121+ add the surrounding lines until it is unique. Several pairs are applied
122+ together, against the original file. An empty `new` deletes the text.
123+ - Call `write_file` only to create a file, or to rewrite one entirely and
124+ on purpose. On an existing file it replaces everything, including what
125+ you did not intend to touch.
126+ - Read the diff the tool returns: it says exactly what changed and on which
127+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
128+ edits — read the file again and fix `old`. Do not fall back to
129+ `write_file` to force the change through.
130+ - After editing code, run the narrowest check with bash: the formatter, the
131+ compiler, or the test covering that file.
132+
133+ RULES
134+ - Keep everything the file already does, unless the user asked to remove it.
135+ - Touch only the files the request is about. Do not add tests, files or
136+ features that were not asked for.
137+ - Never run a git command unless the user says git, commit or push.
138+ - Never move, rename or delete a file unless the user asked for it.
139+ - Then answer in English, in a few lines.
140+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
141+ to understand the options, then run the command.
142+
143+ BACKGROUND JOBS
144+ Never let a command block the answer. Anything that serves, watches or runs
145+ long goes to the background, with BOTH streams redirected and its pid kept:
146+
147+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
148+
149+ Redirecting only stdout still blocks until the process exits. Read the
150+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
151+ rule you cannot guess. Stop every job you started before you finish, and say
152+ which ones you left running.
153+
154+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
155+# we want precise and reproducible answers, not creativity.
156+sampling:
157+ temperature: 0.0
158+ parallel_tool_calls: false
159+ top_p: 0.9
160+ max_tokens: 32768
161+
162+# llama-server processes the whole prompt before the first token;
163+# on a laptop a 32k context can take a while. Raise it if it fires.
164+watchdogTimeout: 300s
165+
166+# Context compression.
167+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
168+context:
169+ enabled: true
170+
171+ # Compress when the history reaches this share of the window.
172+ threshold: 75
173+
174+ # Fallback on the message count, for when the window is unknown.
175+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
176+ maxMessages: 80
177+
178+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
179+ # The model works on the last few turns, so summarising them would make it redo what it just did.
180+ keepLastTurns: 3
181+
182+ # max_tokens of the summary request.
183+ summaryMaxTokens: 1200
184+
185+ showStats: true
new file mode 100644
@@ -0,0 +1,185 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+
3+provider: dmr
4+
5+#model: huggingface.co/jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
6+#model: huggingface.co/unsloth/gemma-4-26b-a4b-it-gguf:UD-Q4_K_M
7+#model: huggingface.co/ornith-ai/ornith-1.5-35b-a3b-gguf:Q4_K_M
8+#model: huggingface.co/unsloth/gpt-oss-20b-gguf:UD-Q4_K_XL
9+
10+model: huggingface.co/unsloth/qwen3.6-35b-a3b-gguf:UD-Q4_K_M
11+
12+baseUrl: http://localhost:12434/engines/v1
13+fallback: http://host.docker.internal:12434/engines/v1
14+
15+# Only when llama-server was started with --api-key; unset otherwise.
16+# apiKeyEnv: LLAMA_API_KEY
17+
18+# The `bash` tool.
19+# `false` removes it: the model can still read and edit files (editTools) and load skills,
20+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
21+bashTool: true
22+
23+# The built-in file tools: read_file, write_file, edit_file.
24+editTools: true
25+
26+# The built-in plan tool for managing multi-step plans.
27+# Set to false to disable plan creation and tracking via the `plan` tool.
28+planTool: true
29+
30+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
31+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
32+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
33+# lsp:
34+# servers:
35+# - name: gopls
36+# command: gopls
37+# extensions: [".go"]
38+# - name: typescript
39+# command: typescript-language-server
40+# args: ["--stdio"]
41+# extensions: [".ts", ".tsx", ".js", ".jsx"]
42+# - name: python
43+# command: pyright-langserver
44+# args: ["--stdio"]
45+# extensions: [".py"]
46+# - name: rust
47+# command: rust-analyzer
48+# extensions: [".rs"]
49+
50+# How many tokens the server actually serves.
51+# 0 = ask the server (llama-server tells it on /props)
52+contextWindow: 0
53+
54+# Max number of characters a tool returns to the model.
55+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
56+maxOutput: 16000
57+
58+# Max number of model <-> tools round trips for a single question.
59+# Raise it for tasks that need long chains of commands.
60+maxTurns: 40
61+
62+# Where the `read_skill` tool looks for its markdown procedures.
63+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
64+skillsDir: skills
65+
66+# Persistent sessions, per project.
67+# When enabled, every conversation is saved as one JSON file under `dir`.
68+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
69+sessions:
70+ enabled: true
71+ dir: .mm/sessions
72+
73+# How many lines of a command's output are echoed to the terminal.
74+# 0 disables it.
75+previewLines: 20
76+
77+displayCommands: true
78+# Show what a thinking model reasons about before it answers (dim italic in the
79+# terminal, its own style in the window, a thought chunk in an editor).
80+# The reasoning is always READ — it is what keeps the watchdog alive while the
81+# model thinks — this only says whether to show it.
82+showThinking: true
83+
84+
85+# The system prompt: what the agent is, and what it is allowed to do.
86+# This is the knob to play with — it is the shortest path to changing behaviour.
87+system: |
88+ Your name is Bob.
89+ You are a coding agent working in a terminal.
90+ You have a "bash" tool to run shell commands.
91+ Use it to explore files, run tests, inspect the repository, etc.
92+ Chain several commands if needed, then answer clearly in English.
93+
94+ A request often mixes things you answer from yourself ("say hello") with
95+ things only a command can answer ("list the files"). Handle every part, in
96+ the order asked, and run a command for each part that needs one.
97+ Never state the contents of a file, the output of a command, or the state of
98+ the repository unless a command in THIS answer returned it. What you did not
99+ read, you do not know: run the command instead of recalling it.
100+
101+ SKILLS
102+ You have a second tool, `read_skill`. Its description lists the procedures
103+ available for this project — one per kind of task.
104+
105+ Any request to DO something to a Go project is a skill, not a shell command
106+ you invent. Match the request against that list, call `read_skill` FIRST,
107+ before any bash command, and then follow what it says step by step.
108+
109+ FILE EDITING
110+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
111+ They are how a file gets read and changed here: each change is exact,
112+ checked before it is written, and comes back as a diff with line numbers.
113+ bash is for running things — building, testing, listing, searching.
114+
115+ - Read before you write: call `read_file` on the file (numbered=true when
116+ you need line numbers). You cannot target text you have not seen; never
117+ rely on what you think you remember about a file.
118+ - To change an existing file, call `edit_file` with one or more {old, new}
119+ pairs. `old` is copied from the file character for character — same
120+ spaces, same indentation, same line breaks — and appears exactly once:
121+ add the surrounding lines until it is unique. Several pairs are applied
122+ together, against the original file. An empty `new` deletes the text.
123+ - Call `write_file` only to create a file, or to rewrite one entirely and
124+ on purpose. On an existing file it replaces everything, including what
125+ you did not intend to touch.
126+ - Read the diff the tool returns: it says exactly what changed and on which
127+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
128+ edits — read the file again and fix `old`. Do not fall back to
129+ `write_file` to force the change through.
130+ - After editing code, run the narrowest check with bash: the formatter, the
131+ compiler, or the test covering that file.
132+
133+ RULES
134+ - Keep everything the file already does, unless the user asked to remove it.
135+ - Touch only the files the request is about. Do not add tests, files or
136+ features that were not asked for.
137+ - Never run a git command unless the user says git, commit or push.
138+ - Never move, rename or delete a file unless the user asked for it.
139+ - Then answer in English, in a few lines.
140+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
141+ to understand the options, then run the command.
142+
143+ BACKGROUND JOBS
144+ Never let a command block the answer. Anything that serves, watches or runs
145+ long goes to the background, with BOTH streams redirected and its pid kept:
146+
147+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
148+
149+ Redirecting only stdout still blocks until the process exits. Read the
150+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
151+ rule you cannot guess. Stop every job you started before you finish, and say
152+ which ones you left running.
153+
154+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
155+# we want precise and reproducible answers, not creativity.
156+sampling:
157+ temperature: 0.0
158+ parallel_tool_calls: false
159+ top_p: 0.9
160+ max_tokens: 32768
161+
162+# llama-server processes the whole prompt before the first token;
163+# on a laptop a 32k context can take a while. Raise it if it fires.
164+watchdogTimeout: 300s
165+
166+# Context compression.
167+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
168+context:
169+ enabled: true
170+
171+ # Compress when the history reaches this share of the window.
172+ threshold: 75
173+
174+ # Fallback on the message count, for when the window is unknown.
175+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
176+ maxMessages: 80
177+
178+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
179+ # The model works on the last few turns, so summarising them would make it redo what it just did.
180+ keepLastTurns: 3
181+
182+ # max_tokens of the summary request.
183+ summaryMaxTokens: 1200
184+
185+ showStats: true
added config.samples/agent.llamacpp.ornith.yaml +188 -0
new file mode 100644
@@ -0,0 +1,188 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+#
3+# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M
4+# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M
5+#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M
6+#
7+provider: llamacpp
8+
9+#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
10+model: ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M
11+
12+# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1.
13+baseUrl: http://127.0.0.1:8080/v1
14+
15+# No fallback: llama-server is wherever you started it.
16+fallback: ""
17+
18+# Only when llama-server was started with --api-key; unset otherwise.
19+# apiKeyEnv: LLAMA_API_KEY
20+
21+# The `bash` tool.
22+# `false` removes it: the model can still read and edit files (editTools) and load skills,
23+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
24+bashTool: true
25+
26+# The built-in file tools: read_file, write_file, edit_file.
27+editTools: true
28+
29+# The built-in plan tool for managing multi-step plans.
30+# Set to false to disable plan creation and tracking via the `plan` tool.
31+planTool: true
32+
33+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
34+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
35+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
36+# lsp:
37+# servers:
38+# - name: gopls
39+# command: gopls
40+# extensions: [".go"]
41+# - name: typescript
42+# command: typescript-language-server
43+# args: ["--stdio"]
44+# extensions: [".ts", ".tsx", ".js", ".jsx"]
45+# - name: python
46+# command: pyright-langserver
47+# args: ["--stdio"]
48+# extensions: [".py"]
49+# - name: rust
50+# command: rust-analyzer
51+# extensions: [".rs"]
52+
53+# How many tokens the server actually serves.
54+# 0 = ask the server (llama-server tells it on /props)
55+contextWindow: 0
56+
57+# Max number of characters a tool returns to the model.
58+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
59+maxOutput: 16000
60+
61+# Max number of model <-> tools round trips for a single question.
62+# Raise it for tasks that need long chains of commands.
63+maxTurns: 40
64+
65+# Where the `read_skill` tool looks for its markdown procedures.
66+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
67+skillsDir: skills
68+
69+# Persistent sessions, per project.
70+# When enabled, every conversation is saved as one JSON file under `dir`.
71+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
72+sessions:
73+ enabled: true
74+ dir: .mm/sessions
75+
76+# How many lines of a command's output are echoed to the terminal.
77+# 0 disables it.
78+previewLines: 20
79+
80+displayCommands: true
81+# Show what a thinking model reasons about before it answers (dim italic in the
82+# terminal, its own style in the window, a thought chunk in an editor).
83+# The reasoning is always READ — it is what keeps the watchdog alive while the
84+# model thinks — this only says whether to show it.
85+showThinking: true
86+
87+
88+# The system prompt: what the agent is, and what it is allowed to do.
89+# This is the knob to play with — it is the shortest path to changing behaviour.
90+system: |
91+ Your name is Bob.
92+ You are a coding agent working in a terminal.
93+ You have a "bash" tool to run shell commands.
94+ Use it to explore files, run tests, inspect the repository, etc.
95+ Chain several commands if needed, then answer clearly in English.
96+
97+ A request often mixes things you answer from yourself ("say hello") with
98+ things only a command can answer ("list the files"). Handle every part, in
99+ the order asked, and run a command for each part that needs one.
100+ Never state the contents of a file, the output of a command, or the state of
101+ the repository unless a command in THIS answer returned it. What you did not
102+ read, you do not know: run the command instead of recalling it.
103+
104+ SKILLS
105+ You have a second tool, `read_skill`. Its description lists the procedures
106+ available for this project — one per kind of task.
107+
108+ Any request to DO something to a Go project is a skill, not a shell command
109+ you invent. Match the request against that list, call `read_skill` FIRST,
110+ before any bash command, and then follow what it says step by step.
111+
112+ FILE EDITING
113+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
114+ They are how a file gets read and changed here: each change is exact,
115+ checked before it is written, and comes back as a diff with line numbers.
116+ bash is for running things — building, testing, listing, searching.
117+
118+ - Read before you write: call `read_file` on the file (numbered=true when
119+ you need line numbers). You cannot target text you have not seen; never
120+ rely on what you think you remember about a file.
121+ - To change an existing file, call `edit_file` with one or more {old, new}
122+ pairs. `old` is copied from the file character for character — same
123+ spaces, same indentation, same line breaks — and appears exactly once:
124+ add the surrounding lines until it is unique. Several pairs are applied
125+ together, against the original file. An empty `new` deletes the text.
126+ - Call `write_file` only to create a file, or to rewrite one entirely and
127+ on purpose. On an existing file it replaces everything, including what
128+ you did not intend to touch.
129+ - Read the diff the tool returns: it says exactly what changed and on which
130+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
131+ edits — read the file again and fix `old`. Do not fall back to
132+ `write_file` to force the change through.
133+ - After editing code, run the narrowest check with bash: the formatter, the
134+ compiler, or the test covering that file.
135+
136+ RULES
137+ - Keep everything the file already does, unless the user asked to remove it.
138+ - Touch only the files the request is about. Do not add tests, files or
139+ features that were not asked for.
140+ - Never run a git command unless the user says git, commit or push.
141+ - Never move, rename or delete a file unless the user asked for it.
142+ - Then answer in English, in a few lines.
143+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
144+ to understand the options, then run the command.
145+
146+ BACKGROUND JOBS
147+ Never let a command block the answer. Anything that serves, watches or runs
148+ long goes to the background, with BOTH streams redirected and its pid kept:
149+
150+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
151+
152+ Redirecting only stdout still blocks until the process exits. Read the
153+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
154+ rule you cannot guess. Stop every job you started before you finish, and say
155+ which ones you left running.
156+
157+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
158+# we want precise and reproducible answers, not creativity.
159+sampling:
160+ temperature: 0.0
161+ parallel_tool_calls: false
162+ top_p: 0.9
163+ max_tokens: 32768
164+
165+# llama-server processes the whole prompt before the first token;
166+# on a laptop a 32k context can take a while. Raise it if it fires.
167+watchdogTimeout: 300s
168+
169+# Context compression.
170+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
171+context:
172+ enabled: true
173+
174+ # Compress when the history reaches this share of the window.
175+ threshold: 75
176+
177+ # Fallback on the message count, for when the window is unknown.
178+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
179+ maxMessages: 80
180+
181+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
182+ # The model works on the last few turns, so summarising them would make it redo what it just did.
183+ keepLastTurns: 3
184+
185+ # max_tokens of the summary request.
186+ summaryMaxTokens: 1200
187+
188+ showStats: true
new file mode 100644
@@ -0,0 +1,188 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+#
3+# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M
4+# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M
5+#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M
6+#
7+provider: llamacpp
8+
9+#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
10+model: ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M
11+
12+# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1.
13+baseUrl: http://127.0.0.1:8080/v1
14+
15+# No fallback: llama-server is wherever you started it.
16+fallback: ""
17+
18+# Only when llama-server was started with --api-key; unset otherwise.
19+# apiKeyEnv: LLAMA_API_KEY
20+
21+# The `bash` tool.
22+# `false` removes it: the model can still read and edit files (editTools) and load skills,
23+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
24+bashTool: true
25+
26+# The built-in file tools: read_file, write_file, edit_file.
27+editTools: true
28+
29+# The built-in plan tool for managing multi-step plans.
30+# Set to false to disable plan creation and tracking via the `plan` tool.
31+planTool: true
32+
33+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
34+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
35+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
36+# lsp:
37+# servers:
38+# - name: gopls
39+# command: gopls
40+# extensions: [".go"]
41+# - name: typescript
42+# command: typescript-language-server
43+# args: ["--stdio"]
44+# extensions: [".ts", ".tsx", ".js", ".jsx"]
45+# - name: python
46+# command: pyright-langserver
47+# args: ["--stdio"]
48+# extensions: [".py"]
49+# - name: rust
50+# command: rust-analyzer
51+# extensions: [".rs"]
52+
53+# How many tokens the server actually serves.
54+# 0 = ask the server (llama-server tells it on /props)
55+contextWindow: 0
56+
57+# Max number of characters a tool returns to the model.
58+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
59+maxOutput: 16000
60+
61+# Max number of model <-> tools round trips for a single question.
62+# Raise it for tasks that need long chains of commands.
63+maxTurns: 40
64+
65+# Where the `read_skill` tool looks for its markdown procedures.
66+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
67+skillsDir: skills
68+
69+# Persistent sessions, per project.
70+# When enabled, every conversation is saved as one JSON file under `dir`.
71+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
72+sessions:
73+ enabled: true
74+ dir: .mm/sessions
75+
76+# How many lines of a command's output are echoed to the terminal.
77+# 0 disables it.
78+previewLines: 20
79+
80+displayCommands: true
81+# Show what a thinking model reasons about before it answers (dim italic in the
82+# terminal, its own style in the window, a thought chunk in an editor).
83+# The reasoning is always READ — it is what keeps the watchdog alive while the
84+# model thinks — this only says whether to show it.
85+showThinking: true
86+
87+
88+# The system prompt: what the agent is, and what it is allowed to do.
89+# This is the knob to play with — it is the shortest path to changing behaviour.
90+system: |
91+ Your name is Bob.
92+ You are a coding agent working in a terminal.
93+ You have a "bash" tool to run shell commands.
94+ Use it to explore files, run tests, inspect the repository, etc.
95+ Chain several commands if needed, then answer clearly in English.
96+
97+ A request often mixes things you answer from yourself ("say hello") with
98+ things only a command can answer ("list the files"). Handle every part, in
99+ the order asked, and run a command for each part that needs one.
100+ Never state the contents of a file, the output of a command, or the state of
101+ the repository unless a command in THIS answer returned it. What you did not
102+ read, you do not know: run the command instead of recalling it.
103+
104+ SKILLS
105+ You have a second tool, `read_skill`. Its description lists the procedures
106+ available for this project — one per kind of task.
107+
108+ Any request to DO something to a Go project is a skill, not a shell command
109+ you invent. Match the request against that list, call `read_skill` FIRST,
110+ before any bash command, and then follow what it says step by step.
111+
112+ FILE EDITING
113+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
114+ They are how a file gets read and changed here: each change is exact,
115+ checked before it is written, and comes back as a diff with line numbers.
116+ bash is for running things — building, testing, listing, searching.
117+
118+ - Read before you write: call `read_file` on the file (numbered=true when
119+ you need line numbers). You cannot target text you have not seen; never
120+ rely on what you think you remember about a file.
121+ - To change an existing file, call `edit_file` with one or more {old, new}
122+ pairs. `old` is copied from the file character for character — same
123+ spaces, same indentation, same line breaks — and appears exactly once:
124+ add the surrounding lines until it is unique. Several pairs are applied
125+ together, against the original file. An empty `new` deletes the text.
126+ - Call `write_file` only to create a file, or to rewrite one entirely and
127+ on purpose. On an existing file it replaces everything, including what
128+ you did not intend to touch.
129+ - Read the diff the tool returns: it says exactly what changed and on which
130+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
131+ edits — read the file again and fix `old`. Do not fall back to
132+ `write_file` to force the change through.
133+ - After editing code, run the narrowest check with bash: the formatter, the
134+ compiler, or the test covering that file.
135+
136+ RULES
137+ - Keep everything the file already does, unless the user asked to remove it.
138+ - Touch only the files the request is about. Do not add tests, files or
139+ features that were not asked for.
140+ - Never run a git command unless the user says git, commit or push.
141+ - Never move, rename or delete a file unless the user asked for it.
142+ - Then answer in English, in a few lines.
143+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
144+ to understand the options, then run the command.
145+
146+ BACKGROUND JOBS
147+ Never let a command block the answer. Anything that serves, watches or runs
148+ long goes to the background, with BOTH streams redirected and its pid kept:
149+
150+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
151+
152+ Redirecting only stdout still blocks until the process exits. Read the
153+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
154+ rule you cannot guess. Stop every job you started before you finish, and say
155+ which ones you left running.
156+
157+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
158+# we want precise and reproducible answers, not creativity.
159+sampling:
160+ temperature: 0.0
161+ parallel_tool_calls: false
162+ top_p: 0.9
163+ max_tokens: 32768
164+
165+# llama-server processes the whole prompt before the first token;
166+# on a laptop a 32k context can take a while. Raise it if it fires.
167+watchdogTimeout: 300s
168+
169+# Context compression.
170+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
171+context:
172+ enabled: true
173+
174+ # Compress when the history reaches this share of the window.
175+ threshold: 75
176+
177+ # Fallback on the message count, for when the window is unknown.
178+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
179+ maxMessages: 80
180+
181+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
182+ # The model works on the last few turns, so summarising them would make it redo what it just did.
183+ keepLastTurns: 3
184+
185+ # max_tokens of the summary request.
186+ summaryMaxTokens: 1200
187+
188+ showStats: true
added config.samples/agent.llamacpp.qwen3.8.yaml +188 -0
new file mode 100644
@@ -0,0 +1,188 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+#
3+# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M
4+# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M
5+#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M
6+#
7+provider: llamacpp
8+
9+#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
10+model: unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M
11+
12+# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1.
13+baseUrl: http://127.0.0.1:8080/v1
14+
15+# No fallback: llama-server is wherever you started it.
16+fallback: ""
17+
18+# Only when llama-server was started with --api-key; unset otherwise.
19+# apiKeyEnv: LLAMA_API_KEY
20+
21+# The `bash` tool.
22+# `false` removes it: the model can still read and edit files (editTools) and load skills,
23+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
24+bashTool: true
25+
26+# The built-in file tools: read_file, write_file, edit_file.
27+editTools: true
28+
29+# The built-in plan tool for managing multi-step plans.
30+# Set to false to disable plan creation and tracking via the `plan` tool.
31+planTool: true
32+
33+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
34+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
35+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
36+# lsp:
37+# servers:
38+# - name: gopls
39+# command: gopls
40+# extensions: [".go"]
41+# - name: typescript
42+# command: typescript-language-server
43+# args: ["--stdio"]
44+# extensions: [".ts", ".tsx", ".js", ".jsx"]
45+# - name: python
46+# command: pyright-langserver
47+# args: ["--stdio"]
48+# extensions: [".py"]
49+# - name: rust
50+# command: rust-analyzer
51+# extensions: [".rs"]
52+
53+# How many tokens the server actually serves.
54+# 0 = ask the server (llama-server tells it on /props)
55+contextWindow: 0
56+
57+# Max number of characters a tool returns to the model.
58+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
59+maxOutput: 16000
60+
61+# Max number of model <-> tools round trips for a single question.
62+# Raise it for tasks that need long chains of commands.
63+maxTurns: 40
64+
65+# Where the `read_skill` tool looks for its markdown procedures.
66+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
67+skillsDir: skills
68+
69+# Persistent sessions, per project.
70+# When enabled, every conversation is saved as one JSON file under `dir`.
71+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
72+sessions:
73+ enabled: true
74+ dir: .mm/sessions
75+
76+# How many lines of a command's output are echoed to the terminal.
77+# 0 disables it.
78+previewLines: 20
79+
80+displayCommands: true
81+# Show what a thinking model reasons about before it answers (dim italic in the
82+# terminal, its own style in the window, a thought chunk in an editor).
83+# The reasoning is always READ — it is what keeps the watchdog alive while the
84+# model thinks — this only says whether to show it.
85+showThinking: true
86+
87+
88+# The system prompt: what the agent is, and what it is allowed to do.
89+# This is the knob to play with — it is the shortest path to changing behaviour.
90+system: |
91+ Your name is Bob.
92+ You are a coding agent working in a terminal.
93+ You have a "bash" tool to run shell commands.
94+ Use it to explore files, run tests, inspect the repository, etc.
95+ Chain several commands if needed, then answer clearly in English.
96+
97+ A request often mixes things you answer from yourself ("say hello") with
98+ things only a command can answer ("list the files"). Handle every part, in
99+ the order asked, and run a command for each part that needs one.
100+ Never state the contents of a file, the output of a command, or the state of
101+ the repository unless a command in THIS answer returned it. What you did not
102+ read, you do not know: run the command instead of recalling it.
103+
104+ SKILLS
105+ You have a second tool, `read_skill`. Its description lists the procedures
106+ available for this project — one per kind of task.
107+
108+ Any request to DO something to a Go project is a skill, not a shell command
109+ you invent. Match the request against that list, call `read_skill` FIRST,
110+ before any bash command, and then follow what it says step by step.
111+
112+ FILE EDITING
113+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
114+ They are how a file gets read and changed here: each change is exact,
115+ checked before it is written, and comes back as a diff with line numbers.
116+ bash is for running things — building, testing, listing, searching.
117+
118+ - Read before you write: call `read_file` on the file (numbered=true when
119+ you need line numbers). You cannot target text you have not seen; never
120+ rely on what you think you remember about a file.
121+ - To change an existing file, call `edit_file` with one or more {old, new}
122+ pairs. `old` is copied from the file character for character — same
123+ spaces, same indentation, same line breaks — and appears exactly once:
124+ add the surrounding lines until it is unique. Several pairs are applied
125+ together, against the original file. An empty `new` deletes the text.
126+ - Call `write_file` only to create a file, or to rewrite one entirely and
127+ on purpose. On an existing file it replaces everything, including what
128+ you did not intend to touch.
129+ - Read the diff the tool returns: it says exactly what changed and on which
130+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
131+ edits — read the file again and fix `old`. Do not fall back to
132+ `write_file` to force the change through.
133+ - After editing code, run the narrowest check with bash: the formatter, the
134+ compiler, or the test covering that file.
135+
136+ RULES
137+ - Keep everything the file already does, unless the user asked to remove it.
138+ - Touch only the files the request is about. Do not add tests, files or
139+ features that were not asked for.
140+ - Never run a git command unless the user says git, commit or push.
141+ - Never move, rename or delete a file unless the user asked for it.
142+ - Then answer in English, in a few lines.
143+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
144+ to understand the options, then run the command.
145+
146+ BACKGROUND JOBS
147+ Never let a command block the answer. Anything that serves, watches or runs
148+ long goes to the background, with BOTH streams redirected and its pid kept:
149+
150+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
151+
152+ Redirecting only stdout still blocks until the process exits. Read the
153+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
154+ rule you cannot guess. Stop every job you started before you finish, and say
155+ which ones you left running.
156+
157+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
158+# we want precise and reproducible answers, not creativity.
159+sampling:
160+ temperature: 0.0
161+ parallel_tool_calls: false
162+ top_p: 0.9
163+ max_tokens: 32768
164+
165+# llama-server processes the whole prompt before the first token;
166+# on a laptop a 32k context can take a while. Raise it if it fires.
167+watchdogTimeout: 300s
168+
169+# Context compression.
170+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
171+context:
172+ enabled: true
173+
174+ # Compress when the history reaches this share of the window.
175+ threshold: 75
176+
177+ # Fallback on the message count, for when the window is unknown.
178+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
179+ maxMessages: 80
180+
181+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
182+ # The model works on the last few turns, so summarising them would make it redo what it just did.
183+ keepLastTurns: 3
184+
185+ # max_tokens of the summary request.
186+ summaryMaxTokens: 1200
187+
188+ showStats: true
new file mode 100644
@@ -0,0 +1,188 @@
1+# Agent settings — same agent, served by llama.cpp's `llama-server` instead of Docker Model Runner.
2+#
3+# llama serve -hf JetBrains/Mellum2-12B-A2.5B-Instruct-GGUF-Q4_K_M:Q4_K_M
4+# llama serve -hf unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M
5+#. llama serve -hf ornith-ai/Ornith-1.5-35B-A3B-GGUF:Q4_K_M
6+#
7+provider: llamacpp
8+
9+#model: jetbrains/mellum2-12b-a2.5b-instruct-gguf-q4_k_m:Q4_K_M
10+model: unsloth/Qwen3.8-27B-GGUF:UD-Q4_K_M
11+
12+# llama-server's default is 127.0.0.1:8080; the OpenAI routes sit under /v1.
13+baseUrl: http://127.0.0.1:8080/v1
14+
15+# No fallback: llama-server is wherever you started it.
16+fallback: ""
17+
18+# Only when llama-server was started with --api-key; unset otherwise.
19+# apiKeyEnv: LLAMA_API_KEY
20+
21+# The `bash` tool.
22+# `false` removes it: the model can still read and edit files (editTools) and load skills,
23+# but never runs a command. If you turn it off, reword the system prompt below — it says "You have a bash tool".
24+bashTool: true
25+
26+# The built-in file tools: read_file, write_file, edit_file.
27+editTools: true
28+
29+# The built-in plan tool for managing multi-step plans.
30+# Set to false to disable plan creation and tracking via the `plan` tool.
31+planTool: true
32+
33+# Language servers for the `lsp` tool (definition, references, hover, symbols, diagnostics, rename).
34+# The file extension picks the server. A server missing from the PATH is skipped with a warning.
35+# No server listed = no `lsp` tool. Examples (uncomment what you have installed):
36+# lsp:
37+# servers:
38+# - name: gopls
39+# command: gopls
40+# extensions: [".go"]
41+# - name: typescript
42+# command: typescript-language-server
43+# args: ["--stdio"]
44+# extensions: [".ts", ".tsx", ".js", ".jsx"]
45+# - name: python
46+# command: pyright-langserver
47+# args: ["--stdio"]
48+# extensions: [".py"]
49+# - name: rust
50+# command: rust-analyzer
51+# extensions: [".rs"]
52+
53+# How many tokens the server actually serves.
54+# 0 = ask the server (llama-server tells it on /props)
55+contextWindow: 0
56+
57+# Max number of characters a tool returns to the model.
58+# Context safeguard: beyond that, the output is truncated (beginning + end kept).
59+maxOutput: 16000
60+
61+# Max number of model <-> tools round trips for a single question.
62+# Raise it for tasks that need long chains of commands.
63+maxTurns: 40
64+
65+# Where the `read_skill` tool looks for its markdown procedures.
66+# The path is relative to the CURRENT DIRECTORY, so run the agent from the directory that holds skills.
67+skillsDir: skills
68+
69+# Persistent sessions, per project.
70+# When enabled, every conversation is saved as one JSON file under `dir`.
71+# `/sessions` lists them, `/resume` continues one; in an editor, "Reload Agent" replays the thread.
72+sessions:
73+ enabled: true
74+ dir: .mm/sessions
75+
76+# How many lines of a command's output are echoed to the terminal.
77+# 0 disables it.
78+previewLines: 20
79+
80+displayCommands: true
81+# Show what a thinking model reasons about before it answers (dim italic in the
82+# terminal, its own style in the window, a thought chunk in an editor).
83+# The reasoning is always READ — it is what keeps the watchdog alive while the
84+# model thinks — this only says whether to show it.
85+showThinking: true
86+
87+
88+# The system prompt: what the agent is, and what it is allowed to do.
89+# This is the knob to play with — it is the shortest path to changing behaviour.
90+system: |
91+ Your name is Bob.
92+ You are a coding agent working in a terminal.
93+ You have a "bash" tool to run shell commands.
94+ Use it to explore files, run tests, inspect the repository, etc.
95+ Chain several commands if needed, then answer clearly in English.
96+
97+ A request often mixes things you answer from yourself ("say hello") with
98+ things only a command can answer ("list the files"). Handle every part, in
99+ the order asked, and run a command for each part that needs one.
100+ Never state the contents of a file, the output of a command, or the state of
101+ the repository unless a command in THIS answer returned it. What you did not
102+ read, you do not know: run the command instead of recalling it.
103+
104+ SKILLS
105+ You have a second tool, `read_skill`. Its description lists the procedures
106+ available for this project — one per kind of task.
107+
108+ Any request to DO something to a Go project is a skill, not a shell command
109+ you invent. Match the request against that list, call `read_skill` FIRST,
110+ before any bash command, and then follow what it says step by step.
111+
112+ FILE EDITING
113+ You have three tools for files: `read_file`, `edit_file` and `write_file`.
114+ They are how a file gets read and changed here: each change is exact,
115+ checked before it is written, and comes back as a diff with line numbers.
116+ bash is for running things — building, testing, listing, searching.
117+
118+ - Read before you write: call `read_file` on the file (numbered=true when
119+ you need line numbers). You cannot target text you have not seen; never
120+ rely on what you think you remember about a file.
121+ - To change an existing file, call `edit_file` with one or more {old, new}
122+ pairs. `old` is copied from the file character for character — same
123+ spaces, same indentation, same line breaks — and appears exactly once:
124+ add the surrounding lines until it is unique. Several pairs are applied
125+ together, against the original file. An empty `new` deletes the text.
126+ - Call `write_file` only to create a file, or to rewrite one entirely and
127+ on purpose. On an existing file it replaces everything, including what
128+ you did not intend to touch.
129+ - Read the diff the tool returns: it says exactly what changed and on which
130+ line. If `edit_file` refuses — text not found, ambiguous, overlapping
131+ edits — read the file again and fix `old`. Do not fall back to
132+ `write_file` to force the change through.
133+ - After editing code, run the narrowest check with bash: the formatter, the
134+ compiler, or the test covering that file.
135+
136+ RULES
137+ - Keep everything the file already does, unless the user asked to remove it.
138+ - Touch only the files the request is about. Do not add tests, files or
139+ features that were not asked for.
140+ - Never run a git command unless the user says git, commit or push.
141+ - Never move, rename or delete a file unless the user asked for it.
142+ - Then answer in English, in a few lines.
143+ - If you don't know how to use a <cli>, run `<cli> --help` (or `<cli> help`)
144+ to understand the options, then run the command.
145+
146+ BACKGROUND JOBS
147+ Never let a command block the answer. Anything that serves, watches or runs
148+ long goes to the background, with BOTH streams redirected and its pid kept:
149+
150+ nohup <command> > /tmp/<job>.log 2>&1 & echo $! > /tmp/<job>.pid
151+
152+ Redirecting only stdout still blocks until the process exits. Read the
153+ `bg-jobs` skill before you wait on, inspect or stop such a job — each has a
154+ rule you cannot guess. Stop every job you started before you finish, and say
155+ which ones you left running.
156+
157+# Generation settings (OpenAI API keys). Low temperature for a coding agent:
158+# we want precise and reproducible answers, not creativity.
159+sampling:
160+ temperature: 0.0
161+ parallel_tool_calls: false
162+ top_p: 0.9
163+ max_tokens: 32768
164+
165+# llama-server processes the whole prompt before the first token;
166+# on a laptop a 32k context can take a while. Raise it if it fires.
167+watchdogTimeout: 300s
168+
169+# Context compression.
170+# ON here: the agent knows the window (read from /props), so `threshold` has a number to apply to.
171+context:
172+ enabled: true
173+
174+ # Compress when the history reaches this share of the window.
175+ threshold: 75
176+
177+ # Fallback on the message count, for when the window is unknown.
178+ # One command costs 2 messages (call + response), so 80 is roughly 30 commands of history.
179+ maxMessages: 80
180+
181+ # How many recent questions (with their commands and answers) are kept as-is instead of being summarised.
182+ # The model works on the last few turns, so summarising them would make it redo what it just did.
183+ keepLastTurns: 3
184+
185+ # max_tokens of the summary request.
186+ summaryMaxTokens: 1200
187+
188+ showStats: true
added docker-sbx-v3/README.md +154 -0
new file mode 100644
@@ -0,0 +1,154 @@
1+# mm in a Docker Sandbox — kits v3
2+
3+The same two kits as [`../docker-sbx`](../docker-sbx/README.md), rewritten for the [kit specification v3](https://github.com/docker/sandbox-kit-spec) (`schemaVersion: "3"`). `docker-sbx/` (v2) is left untouched and keeps working: sbx still loads `spec.yaml` kits.
4+
5+- **mm-tui** — `sbx run` opens mm's window mode (`mm -tui`) on the workspace.
6+- **mm-acp** — `sbx create` once, then an editor that speaks the Agent Client Protocol runs `sbx exec -i … mm -acp`.
7+
8+```
9+docker-sbx-v3/
10+├── publish.sh build + push the image, then build + push the kits — the one command to release
11+├── build.sh builds the template image, k33g/mm-sandbox:<version> (PUSH=1: multi-arch, pushed)
12+├── sync-kits.sh points the kits at one image: owner + version
13+├── check-kits.sh builds the kits locally (no push, no sbx) and checks them with kit-tck if present
14+├── push-kits.sh builds and pushes the kits with buildx: <owner>/sbx-kit-mm-tui, <owner>/sbx-kit-mm-acp
15+├── template/
16+│ ├── Dockerfile docker/sandbox-templates:shell + mm (built from this checkout) — same image as v2
17+│ ├── mm-tui entry point of the mm-tui kit: `mm -tui "$@"`
18+│ └── mm-acp-info entry point of the mm-acp kit: prints the editor wiring, opens a shell
19+└── kits/
20+ ├── mm-tui/
21+ │ ├── mm-tui.yaml the descriptor: kind: workload, args, capabilities
22+ │ └── mm-tui.dockerfile the content: FROM <image>:<tag>, ENV, ENTRYPOINT ["mm-tui"]
23+ └── mm-acp/
24+ ├── mm-acp.yaml
25+ └── mm-acp.dockerfile … ENTRYPOINT ["mm-acp-info"]
26+```
27+
28+## What changed from the v2 kits
29+
30+| | v2 (`docker-sbx/kits/*/spec.yaml`) | v3 (`docker-sbx-v3/kits/*/`) |
31+|---|---|---|
32+| Files | one `spec.yaml` | `<kit>.yaml` (descriptor) + `<kit>.dockerfile` (content) |
33+| Kind | `kind: sandbox` | `kind: workload` |
34+| Name | `name: mm-tui` | none: a kit's identity is the reference it is consumed by |
35+| Image, entry point, env | `sandbox.image`, `sandbox.entrypoint`, `environment.variables` | `FROM`, `ENTRYPOINT`, `ENV` in the Dockerfile — the descriptor restates nothing the image config carries |
36+| Network | `permissions.network.allow` | `capabilities: - type: com.docker.sandbox/network-policy@1` (`runtime.allow`) |
37+| Agent launch | implicit | `capabilities: - type: com.docker.sandbox/sbx@1`: the host runs the ENTRYPOINT under bash, as the image's user (`agent`) |
38+| `tag` arg | substituted into `sandbox.image` at create | **build-phase** (`buildArg: MM_TAG`): baked in when the kit is built; also the kit's `version` and its `provides: mm@<tag>` |
39+| `config` arg | substituted into `environment.variables` | **create-phase** (`env: AGENT_CONFIG`): exported to the container at `sbx run` / `sbx create` |
40+| Owner of the image | rewritten in `sandbox.image` | its own build-phase arg, `image` (`k33g/mm-sandbox`) |
41+| Published as | `sbx kit push` → `k33g/mm-tui`, `k33g/mm-acp` | `docker buildx build --push` → `k33g/sbx-kit-mm-tui`, `k33g/sbx-kit-mm-acp` (an ordinary multi-arch image, with SBOM and provenance) |
42+
43+The repositories differ on purpose: pushing a v3 kit to `k33g/mm-tui:<version>` would replace the v2 kit published under that tag. `sbx-kit-<name>` is the naming Docker's own kits use.
44+
45+## Two things behave differently
46+
47+**The workspace is `/home/agent/workspace`.** The template's base image declares that `WORKDIR`, and `sbx@1` requires the host to mount the workspace at the image's working directory when it is absolute. A relative configuration path (`config=agent.dmr.yaml`) works as before. An absolute **host** path in `AGENT_CONFIG` (`/Users/…/agent.dmr.yaml`) does not: use the path relative to the workspace, or `/home/agent/workspace/…`. (Stated by the specification; not yet observed with sbx.)
48+
49+**The template image must be on a registry to run the kits from source.** A v3 kit is built on top of the template (`FROM k33g/mm-sandbox:<tag>`), and `sbx run ./docker-sbx-v3/kits/…` builds it in sbx's builder sandbox, whose own Docker engine pulls that image from the registry. `--pull never` and `sbx template load` no longer help. Push the image (`PUSH=1 ./docker-sbx-v3/build.sh`) before running a kit from source, or check the kits without sbx with `check-kits.sh`.
50+
51+## 0. Use the published kits (no build)
52+
53+Once `publish.sh` has run for a version:
54+
55+```bash
56+sbx kit inspect k33g/sbx-kit-mm-tui:0.2.1 # look before you run
57+
58+cd /path/to/your/project
59+sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml
60+sbx run k33g/sbx-kit-mm-tui:0.2.1 . --kit-arg config=agent.dmr.yaml
61+```
62+
63+What follows `--` is mm's own command line. Without it, mm reads the `config` argument, then `./agent.yaml` in the workspace, then its built-in defaults.
64+
65+From an editor, create the sandbox once, from the project the editor will open:
66+
67+```bash
68+cd /path/to/your/project
69+sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
70+```
71+
72+then register it — in Zed's `settings.json`:
73+
74+```json
75+{
76+ "agent_servers": {
77+ "mini-me (sandbox)": {
78+ "type": "custom",
79+ "command": "sbx",
80+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
81+ }
82+ }
83+}
84+```
85+
86+**Kit arguments.** On a published kit only `config` can be set: `image` and `tag` are build-phase and were fixed when the kit was built, so a published kit always names the image it was built on. To use another mm version, take the kit of that version.
87+
88+| `--kit-arg` | Default | Phase | Effect |
89+|---|---|---|---|
90+| `config=<path>` | empty | create | The file mm reads (its `AGENT_CONFIG`): relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. |
91+| `tag=<version>` | mm's version (`0.2.1`) | build | Which `<image>:<tag>` the kit is built FROM; also the kit's version. No `v`. |
92+| `image=<repo>` | `k33g/mm-sandbox` | build | Which repository the kit is built FROM. |
93+
94+## 1. Build the template
95+
96+From the repository root:
97+
98+```bash
99+./docker-sbx-v3/build.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, local store
100+PUSH=1 ./docker-sbx-v3/build.sh # multi-arch, pushed — needed before running a kit from source
101+```
102+
103+Same image, same rules as v2's `build.sh`; it then rewrites the kits' `image` and `tag` defaults (`sync-kits.sh`), so the kits always name the image just built.
104+
105+## 2. Check the kits without sbx
106+
107+```bash
108+./docker-sbx-v3/check-kits.sh # both kits
109+./docker-sbx-v3/check-kits.sh mm-tui # one
110+```
111+
112+Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit frontend, which validates the descriptor (unknown keys and arg patterns included), builds the companion Dockerfile and writes the published form to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (or `KIT_TCK=/path/to/kit-tck`), the result is also checked against the specification:
113+
114+```bash
115+git clone https://github.com/docker/sandbox-kit-spec && cd sandbox-kit-spec
116+go build -o ~/.local/bin/kit-tck ./cmd/kit-tck
117+```
118+
119+## 3. Run the kits from source
120+
121+With the template pushed (section 1):
122+
123+```bash
124+cd /path/to/your/project
125+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
126+sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml
127+```
128+
129+sbx recognizes a v3 kit directory by its single `*.yaml` declaring `schemaVersion: "3"` (and no `spec.yaml`), builds it in its builder sandbox (`sbx kit builder status`), and caches the result by the directory's content. From source, the build-phase args can be set too: `--kit-arg tag=0.2.2`.
130+
131+## 4. Publishing a version
132+
133+```bash
134+export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner
135+export DOCKER_PAT=dckr_pat_… # an access token with read/write scope
136+./docker-sbx-v3/publish.sh # TAG from release.env: k33g/mm-sandbox:0.2.1, k33g/sbx-kit-mm-tui:0.2.1, k33g/sbx-kit-mm-acp:0.2.1
137+```
138+
139+It is two steps you can also run alone:
140+
141+```bash
142+PUSH=1 ./docker-sbx-v3/build.sh v0.2.1 # the image, multi-arch, pushed
143+./docker-sbx-v3/push-kits.sh v0.2.1 # the kits: buildx build --push, linux/amd64 + linux/arm64
144+```
145+
146+`push-kits.sh` refuses to start when the image is not on the registry yet, runs `sync-kits.sh`, then builds each kit with the `mm-sandbox-builder` buildx instance (created by `build.sh` if needed) with SBOM and provenance attestations, and validates the pushed kits with `kit-tck` when it is available. No `sbx` is needed to publish. `IMAGE_OWNER`, `REGISTRY`, `KIT_PREFIX` and `PLATFORMS` override the defaults. The descriptors end up naming the new version — commit them.
147+
148+## The model server stays on the host
149+
150+Unchanged from v2: inside a sandbox `localhost` is the sandbox itself, and Docker Model Runner or llama-server are reached through `host.docker.internal`. Both kits allow ports 12434 (Docker Model Runner) and 8080 (llama-server) on the host. Another port: `sbx policy allow network host.docker.internal:<port>`.
151+
152+## Status
153+
154+Checked here: both kits build with the `docker/sandbox-kit:3` frontend (3.0.0-m.6), single- and multi-arch with attestations, and pass `kit-tck validate` (18/18); the published config is `User: agent`, `Entrypoint: [mm-tui]` (or `[mm-acp-info]`), no `Cmd`, `WorkingDir: /home/agent/workspace`. Not yet checked: running them with `sbx` (`sbx run`, `sbx create`, `sbx exec -i … mm -acp`), and pushing to Docker Hub. The kit specification itself is still marked experimental.
new file mode 100644
@@ -0,0 +1,154 @@
1+# mm in a Docker Sandbox — kits v3
2+
3+The same two kits as [`../docker-sbx`](../docker-sbx/README.md), rewritten for the [kit specification v3](https://github.com/docker/sandbox-kit-spec) (`schemaVersion: "3"`). `docker-sbx/` (v2) is left untouched and keeps working: sbx still loads `spec.yaml` kits.
4+
5+- **mm-tui** — `sbx run` opens mm's window mode (`mm -tui`) on the workspace.
6+- **mm-acp** — `sbx create` once, then an editor that speaks the Agent Client Protocol runs `sbx exec -i … mm -acp`.
7+
8+```
9+docker-sbx-v3/
10+├── publish.sh build + push the image, then build + push the kits — the one command to release
11+├── build.sh builds the template image, k33g/mm-sandbox:<version> (PUSH=1: multi-arch, pushed)
12+├── sync-kits.sh points the kits at one image: owner + version
13+├── check-kits.sh builds the kits locally (no push, no sbx) and checks them with kit-tck if present
14+├── push-kits.sh builds and pushes the kits with buildx: <owner>/sbx-kit-mm-tui, <owner>/sbx-kit-mm-acp
15+├── template/
16+│ ├── Dockerfile docker/sandbox-templates:shell + mm (built from this checkout) — same image as v2
17+│ ├── mm-tui entry point of the mm-tui kit: `mm -tui "$@"`
18+│ └── mm-acp-info entry point of the mm-acp kit: prints the editor wiring, opens a shell
19+└── kits/
20+ ├── mm-tui/
21+ │ ├── mm-tui.yaml the descriptor: kind: workload, args, capabilities
22+ │ └── mm-tui.dockerfile the content: FROM <image>:<tag>, ENV, ENTRYPOINT ["mm-tui"]
23+ └── mm-acp/
24+ ├── mm-acp.yaml
25+ └── mm-acp.dockerfile … ENTRYPOINT ["mm-acp-info"]
26+```
27+
28+## What changed from the v2 kits
29+
30+| | v2 (`docker-sbx/kits/*/spec.yaml`) | v3 (`docker-sbx-v3/kits/*/`) |
31+|---|---|---|
32+| Files | one `spec.yaml` | `<kit>.yaml` (descriptor) + `<kit>.dockerfile` (content) |
33+| Kind | `kind: sandbox` | `kind: workload` |
34+| Name | `name: mm-tui` | none: a kit's identity is the reference it is consumed by |
35+| Image, entry point, env | `sandbox.image`, `sandbox.entrypoint`, `environment.variables` | `FROM`, `ENTRYPOINT`, `ENV` in the Dockerfile — the descriptor restates nothing the image config carries |
36+| Network | `permissions.network.allow` | `capabilities: - type: com.docker.sandbox/network-policy@1` (`runtime.allow`) |
37+| Agent launch | implicit | `capabilities: - type: com.docker.sandbox/sbx@1`: the host runs the ENTRYPOINT under bash, as the image's user (`agent`) |
38+| `tag` arg | substituted into `sandbox.image` at create | **build-phase** (`buildArg: MM_TAG`): baked in when the kit is built; also the kit's `version` and its `provides: mm@<tag>` |
39+| `config` arg | substituted into `environment.variables` | **create-phase** (`env: AGENT_CONFIG`): exported to the container at `sbx run` / `sbx create` |
40+| Owner of the image | rewritten in `sandbox.image` | its own build-phase arg, `image` (`k33g/mm-sandbox`) |
41+| Published as | `sbx kit push` → `k33g/mm-tui`, `k33g/mm-acp` | `docker buildx build --push` → `k33g/sbx-kit-mm-tui`, `k33g/sbx-kit-mm-acp` (an ordinary multi-arch image, with SBOM and provenance) |
42+
43+The repositories differ on purpose: pushing a v3 kit to `k33g/mm-tui:<version>` would replace the v2 kit published under that tag. `sbx-kit-<name>` is the naming Docker's own kits use.
44+
45+## Two things behave differently
46+
47+**The workspace is `/home/agent/workspace`.** The template's base image declares that `WORKDIR`, and `sbx@1` requires the host to mount the workspace at the image's working directory when it is absolute. A relative configuration path (`config=agent.dmr.yaml`) works as before. An absolute **host** path in `AGENT_CONFIG` (`/Users/…/agent.dmr.yaml`) does not: use the path relative to the workspace, or `/home/agent/workspace/…`. (Stated by the specification; not yet observed with sbx.)
48+
49+**The template image must be on a registry to run the kits from source.** A v3 kit is built on top of the template (`FROM k33g/mm-sandbox:<tag>`), and `sbx run ./docker-sbx-v3/kits/…` builds it in sbx's builder sandbox, whose own Docker engine pulls that image from the registry. `--pull never` and `sbx template load` no longer help. Push the image (`PUSH=1 ./docker-sbx-v3/build.sh`) before running a kit from source, or check the kits without sbx with `check-kits.sh`.
50+
51+## 0. Use the published kits (no build)
52+
53+Once `publish.sh` has run for a version:
54+
55+```bash
56+sbx kit inspect k33g/sbx-kit-mm-tui:0.2.1 # look before you run
57+
58+cd /path/to/your/project
59+sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml
60+sbx run k33g/sbx-kit-mm-tui:0.2.1 . --kit-arg config=agent.dmr.yaml
61+```
62+
63+What follows `--` is mm's own command line. Without it, mm reads the `config` argument, then `./agent.yaml` in the workspace, then its built-in defaults.
64+
65+From an editor, create the sandbox once, from the project the editor will open:
66+
67+```bash
68+cd /path/to/your/project
69+sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
70+```
71+
72+then register it — in Zed's `settings.json`:
73+
74+```json
75+{
76+ "agent_servers": {
77+ "mini-me (sandbox)": {
78+ "type": "custom",
79+ "command": "sbx",
80+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
81+ }
82+ }
83+}
84+```
85+
86+**Kit arguments.** On a published kit only `config` can be set: `image` and `tag` are build-phase and were fixed when the kit was built, so a published kit always names the image it was built on. To use another mm version, take the kit of that version.
87+
88+| `--kit-arg` | Default | Phase | Effect |
89+|---|---|---|---|
90+| `config=<path>` | empty | create | The file mm reads (its `AGENT_CONFIG`): relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. |
91+| `tag=<version>` | mm's version (`0.2.1`) | build | Which `<image>:<tag>` the kit is built FROM; also the kit's version. No `v`. |
92+| `image=<repo>` | `k33g/mm-sandbox` | build | Which repository the kit is built FROM. |
93+
94+## 1. Build the template
95+
96+From the repository root:
97+
98+```bash
99+./docker-sbx-v3/build.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, local store
100+PUSH=1 ./docker-sbx-v3/build.sh # multi-arch, pushed — needed before running a kit from source
101+```
102+
103+Same image, same rules as v2's `build.sh`; it then rewrites the kits' `image` and `tag` defaults (`sync-kits.sh`), so the kits always name the image just built.
104+
105+## 2. Check the kits without sbx
106+
107+```bash
108+./docker-sbx-v3/check-kits.sh # both kits
109+./docker-sbx-v3/check-kits.sh mm-tui # one
110+```
111+
112+Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit frontend, which validates the descriptor (unknown keys and arg patterns included), builds the companion Dockerfile and writes the published form to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (or `KIT_TCK=/path/to/kit-tck`), the result is also checked against the specification:
113+
114+```bash
115+git clone https://github.com/docker/sandbox-kit-spec && cd sandbox-kit-spec
116+go build -o ~/.local/bin/kit-tck ./cmd/kit-tck
117+```
118+
119+## 3. Run the kits from source
120+
121+With the template pushed (section 1):
122+
123+```bash
124+cd /path/to/your/project
125+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
126+sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . --kit-arg config=agent.dmr.yaml
127+```
128+
129+sbx recognizes a v3 kit directory by its single `*.yaml` declaring `schemaVersion: "3"` (and no `spec.yaml`), builds it in its builder sandbox (`sbx kit builder status`), and caches the result by the directory's content. From source, the build-phase args can be set too: `--kit-arg tag=0.2.2`.
130+
131+## 4. Publishing a version
132+
133+```bash
134+export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner
135+export DOCKER_PAT=dckr_pat_… # an access token with read/write scope
136+./docker-sbx-v3/publish.sh # TAG from release.env: k33g/mm-sandbox:0.2.1, k33g/sbx-kit-mm-tui:0.2.1, k33g/sbx-kit-mm-acp:0.2.1
137+```
138+
139+It is two steps you can also run alone:
140+
141+```bash
142+PUSH=1 ./docker-sbx-v3/build.sh v0.2.1 # the image, multi-arch, pushed
143+./docker-sbx-v3/push-kits.sh v0.2.1 # the kits: buildx build --push, linux/amd64 + linux/arm64
144+```
145+
146+`push-kits.sh` refuses to start when the image is not on the registry yet, runs `sync-kits.sh`, then builds each kit with the `mm-sandbox-builder` buildx instance (created by `build.sh` if needed) with SBOM and provenance attestations, and validates the pushed kits with `kit-tck` when it is available. No `sbx` is needed to publish. `IMAGE_OWNER`, `REGISTRY`, `KIT_PREFIX` and `PLATFORMS` override the defaults. The descriptors end up naming the new version — commit them.
147+
148+## The model server stays on the host
149+
150+Unchanged from v2: inside a sandbox `localhost` is the sandbox itself, and Docker Model Runner or llama-server are reached through `host.docker.internal`. Both kits allow ports 12434 (Docker Model Runner) and 8080 (llama-server) on the host. Another port: `sbx policy allow network host.docker.internal:<port>`.
151+
152+## Status
153+
154+Checked here: both kits build with the `docker/sandbox-kit:3` frontend (3.0.0-m.6), single- and multi-arch with attestations, and pass `kit-tck validate` (18/18); the published config is `User: agent`, `Entrypoint: [mm-tui]` (or `[mm-acp-info]`), no `Cmd`, `WorkingDir: /home/agent/workspace`. Not yet checked: running them with `sbx` (`sbx run`, `sbx create`, `sbx exec -i … mm -acp`), and pushing to Docker Hub. The kit specification itself is still marked experimental.
added docker-sbx-v3/build.sh +105 -0
new file mode 100755
@@ -0,0 +1,105 @@
1+#!/usr/bin/env bash
2+# Build the mm sandbox template image, <owner>/mm-sandbox:<version>, from this
3+# checkout — the image both v3 kits are built FROM. The image tag follows mm's
4+# own tag, minus the "v": release.env says TAG="v0.2.1", the image is
5+# k33g/mm-sandbox:0.2.1 and `mm --version` inside it reports v0.2.1 — the
6+# same rule as the release assets.
7+#
8+# Usage:
9+# ./docker-sbx-v3/build.sh # TAG from release.env, image for this machine
10+# ./docker-sbx-v3/build.sh v0.2.2 # override the tag for this run
11+# PUSH=1 ./docker-sbx-v3/build.sh # multi-arch (linux/amd64 + linux/arm64) built
12+# # with buildx and PUSHED to the registry —
13+# # needs `docker login`; publish.sh does this
14+# IMAGE_OWNER=someone ./docker-sbx-v3/build.sh # another image owner (default k33g)
15+# PLATFORMS=linux/amd64 PUSH=1 … # narrower multi-arch set
16+# SHELL_TEMPLATE=docker/sandbox-templates:shell-docker ./docker-sbx-v3/build.sh
17+# # base it on the Docker-in-Docker shell
18+#
19+# Whatever the mode, the two kits under docker-sbx-v3/kits/ are then pointed
20+# at the image just built (docker-sbx-v3/sync-kits.sh), so kits and image move
21+# together. Publishing the kits themselves is docker-sbx-v3/push-kits.sh, and
22+# docker-sbx-v3/publish.sh chains the two.
23+#
24+# Unlike v2, a v3 kit is BUILT on top of this image (FROM), and sbx builds a
25+# source-form kit in its builder sandbox, whose Docker engine pulls from a
26+# registry: an image that is only in the local store is not enough for
27+# `sbx run ./docker-sbx-v3/kits/…`. Push it (PUSH=1) first.
28+set -euo pipefail
29+
30+cd "$(dirname "$0")/.."
31+
32+# release.env carries TAG ("v0.2.1"). It is git-ignored, so a checkout without
33+# it names the tag on the command line. A tag given on the command line wins.
34+if [ -f release.env ]; then
35+ # shellcheck source=/dev/null
36+ source release.env
37+fi
38+TAG="${1:-${TAG:-}}"
39+if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
40+ echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/build.sh v1.2.3)"
41+ exit 1
42+fi
43+
44+# Not OWNER: release.env uses that name for the git owner (bots-garden), and
45+# the image owner is a different thing — the Docker Hub account, k33g.
46+IMAGE_OWNER="${IMAGE_OWNER:-k33g}"
47+VERSION="${TAG#v}"
48+IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}"
49+PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
50+
51+build_args=(--build-arg "MM_VERSION=${TAG}")
52+if [ -n "${SHELL_TEMPLATE:-}" ]; then
53+ build_args+=(--build-arg "SHELL_TEMPLATE=${SHELL_TEMPLATE}")
54+fi
55+
56+if [ -n "${PUSH:-}" ]; then
57+ # Multi-arch needs buildx's container driver: the classic builder can
58+ # neither assemble a manifest list nor build for a foreign platform. The
59+ # Go stage cross-compiles on the build platform; only the final stage's
60+ # `RUN mm --version` runs under emulation (Docker Desktop ships QEMU).
61+ echo "🐳 Building and pushing ${IMAGE} for ${PLATFORMS} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})"
62+ if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then
63+ docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null
64+ fi
65+ docker buildx build --builder mm-sandbox-builder \
66+ --platform "${PLATFORMS}" \
67+ -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" \
68+ -t "${IMAGE}" --push .
69+ # The proof that ships: the registry holds one manifest per platform.
70+ docker buildx imagetools inspect "${IMAGE}" | grep -E '^Name:|Platform:' | sed 's/^/ /'
71+else
72+ echo "🐳 Building ${IMAGE} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})"
73+ docker build -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" -t "${IMAGE}" .
74+
75+ # The one proof that what was built starts: --version needs no config and
76+ # no model server. It also confirms the stamp reached the binary.
77+ reported="$(docker run --rm "${IMAGE}" mm --version)"
78+ if ! grep -q -- "${TAG}" <<<"${reported}"; then
79+ echo "❌ the image does not report ${TAG}: ${reported}"
80+ exit 1
81+ fi
82+ echo "✅ ${reported}"
83+fi
84+
85+./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}"
86+
87+if [ -n "${PUSH:-}" ]; then
88+ cat <<NEXT
89+
90+Image on the registry. Next:
91+
92+ try the kits from source sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
93+ publish them ./docker-sbx-v3/push-kits.sh ${TAG}
94+NEXT
95+else
96+ cat <<NEXT
97+
98+${IMAGE} is in the local image store only. That is enough for
99+./docker-sbx-v3/check-kits.sh (which builds the kits with your docker), not
100+for sbx: its builder sandbox pulls the FROM image from the registry. To run
101+the kits from source with sbx, push the image first:
102+
103+ PUSH=1 ./docker-sbx-v3/build.sh ${TAG}
104+NEXT
105+fi
new file mode 100755
@@ -0,0 +1,105 @@
1+#!/usr/bin/env bash
2+# Build the mm sandbox template image, <owner>/mm-sandbox:<version>, from this
3+# checkout — the image both v3 kits are built FROM. The image tag follows mm's
4+# own tag, minus the "v": release.env says TAG="v0.2.1", the image is
5+# k33g/mm-sandbox:0.2.1 and `mm --version` inside it reports v0.2.1 — the
6+# same rule as the release assets.
7+#
8+# Usage:
9+# ./docker-sbx-v3/build.sh # TAG from release.env, image for this machine
10+# ./docker-sbx-v3/build.sh v0.2.2 # override the tag for this run
11+# PUSH=1 ./docker-sbx-v3/build.sh # multi-arch (linux/amd64 + linux/arm64) built
12+# # with buildx and PUSHED to the registry —
13+# # needs `docker login`; publish.sh does this
14+# IMAGE_OWNER=someone ./docker-sbx-v3/build.sh # another image owner (default k33g)
15+# PLATFORMS=linux/amd64 PUSH=1 … # narrower multi-arch set
16+# SHELL_TEMPLATE=docker/sandbox-templates:shell-docker ./docker-sbx-v3/build.sh
17+# # base it on the Docker-in-Docker shell
18+#
19+# Whatever the mode, the two kits under docker-sbx-v3/kits/ are then pointed
20+# at the image just built (docker-sbx-v3/sync-kits.sh), so kits and image move
21+# together. Publishing the kits themselves is docker-sbx-v3/push-kits.sh, and
22+# docker-sbx-v3/publish.sh chains the two.
23+#
24+# Unlike v2, a v3 kit is BUILT on top of this image (FROM), and sbx builds a
25+# source-form kit in its builder sandbox, whose Docker engine pulls from a
26+# registry: an image that is only in the local store is not enough for
27+# `sbx run ./docker-sbx-v3/kits/…`. Push it (PUSH=1) first.
28+set -euo pipefail
29+
30+cd "$(dirname "$0")/.."
31+
32+# release.env carries TAG ("v0.2.1"). It is git-ignored, so a checkout without
33+# it names the tag on the command line. A tag given on the command line wins.
34+if [ -f release.env ]; then
35+ # shellcheck source=/dev/null
36+ source release.env
37+fi
38+TAG="${1:-${TAG:-}}"
39+if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
40+ echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/build.sh v1.2.3)"
41+ exit 1
42+fi
43+
44+# Not OWNER: release.env uses that name for the git owner (bots-garden), and
45+# the image owner is a different thing — the Docker Hub account, k33g.
46+IMAGE_OWNER="${IMAGE_OWNER:-k33g}"
47+VERSION="${TAG#v}"
48+IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}"
49+PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
50+
51+build_args=(--build-arg "MM_VERSION=${TAG}")
52+if [ -n "${SHELL_TEMPLATE:-}" ]; then
53+ build_args+=(--build-arg "SHELL_TEMPLATE=${SHELL_TEMPLATE}")
54+fi
55+
56+if [ -n "${PUSH:-}" ]; then
57+ # Multi-arch needs buildx's container driver: the classic builder can
58+ # neither assemble a manifest list nor build for a foreign platform. The
59+ # Go stage cross-compiles on the build platform; only the final stage's
60+ # `RUN mm --version` runs under emulation (Docker Desktop ships QEMU).
61+ echo "🐳 Building and pushing ${IMAGE} for ${PLATFORMS} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})"
62+ if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then
63+ docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null
64+ fi
65+ docker buildx build --builder mm-sandbox-builder \
66+ --platform "${PLATFORMS}" \
67+ -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" \
68+ -t "${IMAGE}" --push .
69+ # The proof that ships: the registry holds one manifest per platform.
70+ docker buildx imagetools inspect "${IMAGE}" | grep -E '^Name:|Platform:' | sed 's/^/ /'
71+else
72+ echo "🐳 Building ${IMAGE} (mm ${TAG}, base ${SHELL_TEMPLATE:-docker/sandbox-templates:shell})"
73+ docker build -f docker-sbx-v3/template/Dockerfile "${build_args[@]}" -t "${IMAGE}" .
74+
75+ # The one proof that what was built starts: --version needs no config and
76+ # no model server. It also confirms the stamp reached the binary.
77+ reported="$(docker run --rm "${IMAGE}" mm --version)"
78+ if ! grep -q -- "${TAG}" <<<"${reported}"; then
79+ echo "❌ the image does not report ${TAG}: ${reported}"
80+ exit 1
81+ fi
82+ echo "✅ ${reported}"
83+fi
84+
85+./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}"
86+
87+if [ -n "${PUSH:-}" ]; then
88+ cat <<NEXT
89+
90+Image on the registry. Next:
91+
92+ try the kits from source sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
93+ publish them ./docker-sbx-v3/push-kits.sh ${TAG}
94+NEXT
95+else
96+ cat <<NEXT
97+
98+${IMAGE} is in the local image store only. That is enough for
99+./docker-sbx-v3/check-kits.sh (which builds the kits with your docker), not
100+for sbx: its builder sandbox pulls the FROM image from the registry. To run
101+the kits from source with sbx, push the image first:
102+
103+ PUSH=1 ./docker-sbx-v3/build.sh ${TAG}
104+NEXT
105+fi
added docker-sbx-v3/check-kits.sh +60 -0
new file mode 100755
@@ -0,0 +1,60 @@
1+#!/usr/bin/env bash
2+# Build the two v3 kits locally, without pushing and without sbx, and check
3+# them against the kit specification when kit-tck is available.
4+#
5+# Usage:
6+# ./docker-sbx-v3/check-kits.sh # every kit under docker-sbx-v3/kits/
7+# ./docker-sbx-v3/check-kits.sh mm-tui # one kit
8+# KIT_TCK=/path/to/kit-tck … # the conformance tool, if not on the PATH
9+#
10+# Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's
11+# first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit
12+# frontend, which validates the descriptor (arg patterns included), builds
13+# <kit>.dockerfile and writes the published form — an OCI image whose
14+# manifest annotation carries the descriptor. The result lands in
15+# tmp/kits-v3/<kit>/ as an OCI layout, for the host platform only.
16+#
17+# The args are the descriptors' defaults, so run build.sh (or sync-kits.sh)
18+# first to point them at the image you want. That image is resolved by your
19+# BuildKit: from the local store with Docker Desktop's default builder,
20+# otherwise from the registry.
21+#
22+# kit-tck is the specification's conformance tool
23+# (github.com/docker/sandbox-kit-spec, `go build ./cmd/kit-tck`). Without it
24+# the build itself is the check: the frontend refuses a descriptor that does
25+# not validate.
26+set -euo pipefail
27+
28+cd "$(dirname "$0")/.."
29+
30+KIT_TCK="${KIT_TCK:-kit-tck}"
31+if [ $# -gt 0 ]; then
32+ kits=("$@")
33+else
34+ kits=()
35+ for dir in docker-sbx-v3/kits/*/; do
36+ kits+=("$(basename "${dir}")")
37+ done
38+fi
39+
40+for kit in "${kits[@]}"; do
41+ dir="docker-sbx-v3/kits/${kit}"
42+ if [ ! -f "${dir}/${kit}.yaml" ]; then
43+ echo "❌ no kit named '${kit}': expected ${dir}/${kit}.yaml" >&2
44+ exit 1
45+ fi
46+ out="tmp/kits-v3/${kit}"
47+ rm -rf "${out}"
48+ mkdir -p "$(dirname "${out}")"
49+
50+ echo "🧰 ${kit}: building ${dir}/${kit}.yaml"
51+ docker buildx build "${dir}" -f "${dir}/${kit}.yaml" \
52+ --output "type=oci,dest=${out},tar=false,name=${kit}:check"
53+
54+ if command -v "${KIT_TCK}" >/dev/null 2>&1; then
55+ "${KIT_TCK}" validate --layout "${out}" check
56+ else
57+ echo " (kit-tck not found: built and validated by the frontend only)"
58+ fi
59+ echo "✅ ${kit} → ${out}"
60+done
new file mode 100755
@@ -0,0 +1,60 @@
1+#!/usr/bin/env bash
2+# Build the two v3 kits locally, without pushing and without sbx, and check
3+# them against the kit specification when kit-tck is available.
4+#
5+# Usage:
6+# ./docker-sbx-v3/check-kits.sh # every kit under docker-sbx-v3/kits/
7+# ./docker-sbx-v3/check-kits.sh mm-tui # one kit
8+# KIT_TCK=/path/to/kit-tck … # the conformance tool, if not on the PATH
9+#
10+# Each kit is built with `docker buildx build -f <kit>.yaml`: the descriptor's
11+# first line, `# syntax=docker/sandbox-kit:3`, makes BuildKit pull the kit
12+# frontend, which validates the descriptor (arg patterns included), builds
13+# <kit>.dockerfile and writes the published form — an OCI image whose
14+# manifest annotation carries the descriptor. The result lands in
15+# tmp/kits-v3/<kit>/ as an OCI layout, for the host platform only.
16+#
17+# The args are the descriptors' defaults, so run build.sh (or sync-kits.sh)
18+# first to point them at the image you want. That image is resolved by your
19+# BuildKit: from the local store with Docker Desktop's default builder,
20+# otherwise from the registry.
21+#
22+# kit-tck is the specification's conformance tool
23+# (github.com/docker/sandbox-kit-spec, `go build ./cmd/kit-tck`). Without it
24+# the build itself is the check: the frontend refuses a descriptor that does
25+# not validate.
26+set -euo pipefail
27+
28+cd "$(dirname "$0")/.."
29+
30+KIT_TCK="${KIT_TCK:-kit-tck}"
31+if [ $# -gt 0 ]; then
32+ kits=("$@")
33+else
34+ kits=()
35+ for dir in docker-sbx-v3/kits/*/; do
36+ kits+=("$(basename "${dir}")")
37+ done
38+fi
39+
40+for kit in "${kits[@]}"; do
41+ dir="docker-sbx-v3/kits/${kit}"
42+ if [ ! -f "${dir}/${kit}.yaml" ]; then
43+ echo "❌ no kit named '${kit}': expected ${dir}/${kit}.yaml" >&2
44+ exit 1
45+ fi
46+ out="tmp/kits-v3/${kit}"
47+ rm -rf "${out}"
48+ mkdir -p "$(dirname "${out}")"
49+
50+ echo "🧰 ${kit}: building ${dir}/${kit}.yaml"
51+ docker buildx build "${dir}" -f "${dir}/${kit}.yaml" \
52+ --output "type=oci,dest=${out},tar=false,name=${kit}:check"
53+
54+ if command -v "${KIT_TCK}" >/dev/null 2>&1; then
55+ "${KIT_TCK}" validate --layout "${out}" check
56+ else
57+ echo " (kit-tck not found: built and validated by the frontend only)"
58+ fi
59+ echo "✅ ${kit} → ${out}"
60+done
added docker-sbx-v3/kits/mm-acp/mm-acp.dockerfile +20 -0
new file mode 100644
@@ -0,0 +1,20 @@
1+# syntax=docker/dockerfile:1
2+# check=skip=InvalidDefaultArgInFrom
3+# Content of the mm-acp kit (descriptor: mm-acp.yaml). Same template image as
4+# mm-tui; only the launch contract differs. No default on purpose (hence the
5+# skipped check above): the frontend always passes the kit's `image` and `tag`
6+# args — see kits/mm-tui/mm-tui.dockerfile.
7+ARG MM_IMAGE
8+ARG MM_TAG
9+FROM ${MM_IMAGE}:${MM_TAG}
10+
11+# v2's environment.variables. `sbx exec` inherits the image environment, so
12+# the editor's settings need not repeat them. AGENT_CONFIG comes from the kit's
13+# `config` arg (env:).
14+ENV LANG=C.UTF-8
15+
16+# v2's sandbox.entrypoint. Not `mm -acp`: nothing useful comes of speaking
17+# JSON-RPC to a terminal. Attaching with `sbx run` prints the editor wiring
18+# with this sandbox's real name, then opens a shell; the editor itself runs
19+# `sbx exec -i <sandbox> mm -acp`.
20+ENTRYPOINT ["mm-acp-info"]
new file mode 100644
@@ -0,0 +1,20 @@
1+# syntax=docker/dockerfile:1
2+# check=skip=InvalidDefaultArgInFrom
3+# Content of the mm-acp kit (descriptor: mm-acp.yaml). Same template image as
4+# mm-tui; only the launch contract differs. No default on purpose (hence the
5+# skipped check above): the frontend always passes the kit's `image` and `tag`
6+# args — see kits/mm-tui/mm-tui.dockerfile.
7+ARG MM_IMAGE
8+ARG MM_TAG
9+FROM ${MM_IMAGE}:${MM_TAG}
10+
11+# v2's environment.variables. `sbx exec` inherits the image environment, so
12+# the editor's settings need not repeat them. AGENT_CONFIG comes from the kit's
13+# `config` arg (env:).
14+ENV LANG=C.UTF-8
15+
16+# v2's sandbox.entrypoint. Not `mm -acp`: nothing useful comes of speaking
17+# JSON-RPC to a terminal. Attaching with `sbx run` prints the editor wiring
18+# with this sandbox's real name, then opens a shell; the editor itself runs
19+# `sbx exec -i <sandbox> mm -acp`.
20+ENTRYPOINT ["mm-acp-info"]
added docker-sbx-v3/kits/mm-acp/mm-acp.yaml +82 -0
new file mode 100644
@@ -0,0 +1,82 @@
1+# syntax=docker/sandbox-kit:3
2+# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json
3+#
4+# Docker Sandboxes kit (spec v3): mm as an editor's agent (Agent Client
5+# Protocol), on the mm sandbox template. The v2 twin is
6+# docker-sbx/kits/mm-acp/spec.yaml.
7+#
8+# sbx create --name mm-acp ./docker-sbx-v3/kits/mm-acp . \
9+# --kit-arg config=agent.dmr.yaml
10+#
11+# then, in the editor (Zed settings.json):
12+#
13+# "agent_servers": { "mini-me (sandbox)": { "type": "custom",
14+# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } }
15+#
16+# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the
17+# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the
18+# sandbox is created without attaching, and the editor starts `mm -acp` inside
19+# it for every conversation (sbx starts a stopped sandbox first). Attaching
20+# with `sbx run` runs the entry point (mm-acp.dockerfile), which prints this
21+# wiring with the sandbox's real name and opens a shell.
22+#
23+# sbx builds this source form in its builder sandbox, whose own Docker engine
24+# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the
25+# local image store (see docker-sbx-v3/README.md).
26+schemaVersion: "3"
27+kind: workload
28+displayName: Mini Me (editor, ACP)
29+description: >
30+ Holds mm, a minimal coding agent for local LLMs, for an editor that speaks
31+ the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox>
32+ mm -acp`; every command and file edit the model asks for happens inside the
33+ sandbox, on the mounted workspace. The model server stays on the host,
34+ reached through host.docker.internal.
35+sourceUrl: https://git.rickub.com/bots-garden/mini-me
36+# The kit's version is mm's: the image tag it is built on. A published kit is
37+# versioned by its OCI tag anyway, which wins over this field.
38+version: "${{ kit.args.tag }}"
39+provides: ["mm@${{ kit.args.tag }}"]
40+
41+args:
42+ # Build-phase (buildArg): see kits/mm-tui/mm-tui.yaml.
43+ image:
44+ default: "k33g/mm-sandbox"
45+ description: >-
46+ Repository of the mm sandbox template image, without the tag. Kept equal
47+ to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh.
48+ pattern: '^[a-z0-9][a-z0-9._/:-]*$'
49+ buildArg: MM_IMAGE
50+ tag:
51+ default: "0.2.1"
52+ description: >-
53+ Tag of the template image: mm's version without the "v", as
54+ docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the
55+ kit's version, hence version-shaped.
56+ pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$'
57+ buildArg: MM_TAG
58+ # Create-phase (env): baked into the container at `sbx create`, so
59+ # `sbx exec` inherits it and the editor's settings need not repeat the path.
60+ # `sbx exec -e AGENT_CONFIG=…` overrides it for one session.
61+ config:
62+ default: ""
63+ description: >-
64+ Configuration file mm reads (its AGENT_CONFIG): a path relative to the
65+ workspace, which is where `sbx exec` starts mm, or an absolute path
66+ inside the sandbox. Empty: ./agent.yaml in the workspace, then the
67+ built-in defaults.
68+ env: AGENT_CONFIG
69+
70+capabilities:
71+ # A sandbox-agent workload — see kits/mm-tui/mm-tui.yaml.
72+ - type: com.docker.sandbox/sbx@1
73+
74+ # The model server on the host — see kits/mm-tui/mm-tui.yaml.
75+ - type: com.docker.sandbox/network-policy@1
76+ config:
77+ runtime:
78+ allow:
79+ - "host.docker.internal:12434"
80+ - "localhost:12434"
81+ - "host.docker.internal:8080"
82+ - "localhost:8080"
new file mode 100644
@@ -0,0 +1,82 @@
1+# syntax=docker/sandbox-kit:3
2+# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json
3+#
4+# Docker Sandboxes kit (spec v3): mm as an editor's agent (Agent Client
5+# Protocol), on the mm sandbox template. The v2 twin is
6+# docker-sbx/kits/mm-acp/spec.yaml.
7+#
8+# sbx create --name mm-acp ./docker-sbx-v3/kits/mm-acp . \
9+# --kit-arg config=agent.dmr.yaml
10+#
11+# then, in the editor (Zed settings.json):
12+#
13+# "agent_servers": { "mini-me (sandbox)": { "type": "custom",
14+# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } }
15+#
16+# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the
17+# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the
18+# sandbox is created without attaching, and the editor starts `mm -acp` inside
19+# it for every conversation (sbx starts a stopped sandbox first). Attaching
20+# with `sbx run` runs the entry point (mm-acp.dockerfile), which prints this
21+# wiring with the sandbox's real name and opens a shell.
22+#
23+# sbx builds this source form in its builder sandbox, whose own Docker engine
24+# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the
25+# local image store (see docker-sbx-v3/README.md).
26+schemaVersion: "3"
27+kind: workload
28+displayName: Mini Me (editor, ACP)
29+description: >
30+ Holds mm, a minimal coding agent for local LLMs, for an editor that speaks
31+ the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox>
32+ mm -acp`; every command and file edit the model asks for happens inside the
33+ sandbox, on the mounted workspace. The model server stays on the host,
34+ reached through host.docker.internal.
35+sourceUrl: https://git.rickub.com/bots-garden/mini-me
36+# The kit's version is mm's: the image tag it is built on. A published kit is
37+# versioned by its OCI tag anyway, which wins over this field.
38+version: "${{ kit.args.tag }}"
39+provides: ["mm@${{ kit.args.tag }}"]
40+
41+args:
42+ # Build-phase (buildArg): see kits/mm-tui/mm-tui.yaml.
43+ image:
44+ default: "k33g/mm-sandbox"
45+ description: >-
46+ Repository of the mm sandbox template image, without the tag. Kept equal
47+ to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh.
48+ pattern: '^[a-z0-9][a-z0-9._/:-]*$'
49+ buildArg: MM_IMAGE
50+ tag:
51+ default: "0.2.1"
52+ description: >-
53+ Tag of the template image: mm's version without the "v", as
54+ docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the
55+ kit's version, hence version-shaped.
56+ pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$'
57+ buildArg: MM_TAG
58+ # Create-phase (env): baked into the container at `sbx create`, so
59+ # `sbx exec` inherits it and the editor's settings need not repeat the path.
60+ # `sbx exec -e AGENT_CONFIG=…` overrides it for one session.
61+ config:
62+ default: ""
63+ description: >-
64+ Configuration file mm reads (its AGENT_CONFIG): a path relative to the
65+ workspace, which is where `sbx exec` starts mm, or an absolute path
66+ inside the sandbox. Empty: ./agent.yaml in the workspace, then the
67+ built-in defaults.
68+ env: AGENT_CONFIG
69+
70+capabilities:
71+ # A sandbox-agent workload — see kits/mm-tui/mm-tui.yaml.
72+ - type: com.docker.sandbox/sbx@1
73+
74+ # The model server on the host — see kits/mm-tui/mm-tui.yaml.
75+ - type: com.docker.sandbox/network-policy@1
76+ config:
77+ runtime:
78+ allow:
79+ - "host.docker.internal:12434"
80+ - "localhost:12434"
81+ - "host.docker.internal:8080"
82+ - "localhost:8080"
added docker-sbx-v3/kits/mm-tui/mm-tui.dockerfile +25 -0
new file mode 100644
@@ -0,0 +1,25 @@
1+# syntax=docker/dockerfile:1
2+# check=skip=InvalidDefaultArgInFrom
3+# Content of the mm-tui kit (descriptor: mm-tui.yaml). The kit's build context
4+# is this directory, so mm itself cannot be built here: the template image
5+# (docker-sbx-v3/template/Dockerfile, built from the repository root) carries
6+# mm, its wrappers and the toolchains, and this layer only sets the launch
7+# contract. No default on purpose (hence the skipped check above): the frontend
8+# always passes the kit's `image` and `tag` args, and a default here would be a
9+# second copy of the descriptor's to keep in sync.
10+ARG MM_IMAGE
11+ARG MM_TAG
12+FROM ${MM_IMAGE}:${MM_TAG}
13+
14+# v2's environment.variables. tcell needs a terminal type and a UTF-8 locale
15+# to draw the window. AGENT_CONFIG comes from the kit's `config` arg (env:).
16+ENV TERM=xterm-256color \
17+ COLORTERM=truecolor \
18+ LANG=C.UTF-8
19+
20+# v2's sandbox.entrypoint. A wrapper, not `mm -tui` directly: it always adds
21+# -tui, whatever the user passes after "--". Setting ENTRYPOINT also drops the
22+# base template's CMD, so the launch argv is exactly mm-tui + the user's args.
23+# USER (agent) and WORKDIR (/home/agent/workspace) are inherited from the
24+# template, which is what sbx@1 reads.
25+ENTRYPOINT ["mm-tui"]
new file mode 100644
@@ -0,0 +1,25 @@
1+# syntax=docker/dockerfile:1
2+# check=skip=InvalidDefaultArgInFrom
3+# Content of the mm-tui kit (descriptor: mm-tui.yaml). The kit's build context
4+# is this directory, so mm itself cannot be built here: the template image
5+# (docker-sbx-v3/template/Dockerfile, built from the repository root) carries
6+# mm, its wrappers and the toolchains, and this layer only sets the launch
7+# contract. No default on purpose (hence the skipped check above): the frontend
8+# always passes the kit's `image` and `tag` args, and a default here would be a
9+# second copy of the descriptor's to keep in sync.
10+ARG MM_IMAGE
11+ARG MM_TAG
12+FROM ${MM_IMAGE}:${MM_TAG}
13+
14+# v2's environment.variables. tcell needs a terminal type and a UTF-8 locale
15+# to draw the window. AGENT_CONFIG comes from the kit's `config` arg (env:).
16+ENV TERM=xterm-256color \
17+ COLORTERM=truecolor \
18+ LANG=C.UTF-8
19+
20+# v2's sandbox.entrypoint. A wrapper, not `mm -tui` directly: it always adds
21+# -tui, whatever the user passes after "--". Setting ENTRYPOINT also drops the
22+# base template's CMD, so the launch argv is exactly mm-tui + the user's args.
23+# USER (agent) and WORKDIR (/home/agent/workspace) are inherited from the
24+# template, which is what sbx@1 reads.
25+ENTRYPOINT ["mm-tui"]
added docker-sbx-v3/kits/mm-tui/mm-tui.yaml +86 -0
new file mode 100644
@@ -0,0 +1,86 @@
1+# syntax=docker/sandbox-kit:3
2+# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json
3+#
4+# Docker Sandboxes kit (spec v3): mm in its window mode, on the mm sandbox
5+# template. The v2 twin is docker-sbx/kits/mm-tui/spec.yaml.
6+#
7+# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
8+#
9+# What follows "--" reaches mm as its own arguments (here the configuration
10+# file, relative to the workspace). Without it, the `config` argument below is
11+# read, then ./agent.yaml, then the built-in defaults:
12+#
13+# sbx run ./docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml
14+#
15+# v3 layout: this file is the descriptor (declarations only), mm-tui.dockerfile
16+# beside it is the content. What v2 wrote in `sandbox.image`,
17+# `sandbox.entrypoint` and `environment.variables` is now in that Dockerfile's
18+# FROM, ENTRYPOINT and ENV — the descriptor restates nothing the image config
19+# already carries.
20+#
21+# sbx builds this source form in its builder sandbox, whose own Docker engine
22+# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the
23+# local image store (see docker-sbx-v3/README.md).
24+schemaVersion: "3"
25+kind: workload
26+displayName: Mini Me (window mode)
27+description: >
28+ Runs mm, a minimal coding agent for local LLMs, in its single-window terminal
29+ mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or
30+ llama-server) stays on the host: inside the sandbox `localhost` is the sandbox
31+ itself, so the configuration file must reach the host through
32+ host.docker.internal — agent.dmr.yaml already falls back to it.
33+sourceUrl: https://git.rickub.com/bots-garden/mini-me
34+# The kit's version is mm's: the image tag it is built on. A published kit is
35+# versioned by its OCI tag anyway, which wins over this field.
36+version: "${{ kit.args.tag }}"
37+provides: ["mm@${{ kit.args.tag }}"]
38+
39+args:
40+ # Build-phase (buildArg): resolved when the kit is built, handed to
41+ # mm-tui.dockerfile as --build-arg, and baked into the published descriptor.
42+ # A published kit therefore always names the image it was built on.
43+ image:
44+ default: "k33g/mm-sandbox"
45+ description: >-
46+ Repository of the mm sandbox template image, without the tag. Kept equal
47+ to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh.
48+ pattern: '^[a-z0-9][a-z0-9._/:-]*$'
49+ buildArg: MM_IMAGE
50+ tag:
51+ default: "0.2.1"
52+ description: >-
53+ Tag of the template image: mm's version without the "v", as
54+ docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the
55+ kit's version, hence version-shaped.
56+ pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$'
57+ buildArg: MM_TAG
58+ # Create-phase (env): resolved at `sbx run` / `sbx create`, exported to the
59+ # container. Private otherwise — an arg without env: never reaches it.
60+ config:
61+ default: ""
62+ description: >-
63+ Configuration file mm reads (its AGENT_CONFIG): a path relative to the
64+ workspace, or an absolute path inside the sandbox. Empty: ./agent.yaml in
65+ the workspace, then the built-in defaults.
66+ env: AGENT_CONFIG
67+
68+capabilities:
69+ # A sandbox-agent workload: the host launches the image ENTRYPOINT (mm-tui)
70+ # under bash as the image's user (agent), and mounts the workspace at the
71+ # image's WORKDIR, /home/agent/workspace.
72+ - type: com.docker.sandbox/sbx@1
73+
74+ # The model server on the host. Requests leave the sandbox through its proxy,
75+ # which maps host.docker.internal to the host's localhost; both spellings are
76+ # listed so the rule matches whichever one the policy is checked against.
77+ # 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own
78+ # port with `sbx policy allow network host.docker.internal:<port>`.
79+ - type: com.docker.sandbox/network-policy@1
80+ config:
81+ runtime:
82+ allow:
83+ - "host.docker.internal:12434"
84+ - "localhost:12434"
85+ - "host.docker.internal:8080"
86+ - "localhost:8080"
new file mode 100644
@@ -0,0 +1,86 @@
1+# syntax=docker/sandbox-kit:3
2+# yaml-language-server: $schema=https://raw.githubusercontent.com/docker/sandbox-kit-spec/main/schema/kit.schema.json
3+#
4+# Docker Sandboxes kit (spec v3): mm in its window mode, on the mm sandbox
5+# template. The v2 twin is docker-sbx/kits/mm-tui/spec.yaml.
6+#
7+# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
8+#
9+# What follows "--" reaches mm as its own arguments (here the configuration
10+# file, relative to the workspace). Without it, the `config` argument below is
11+# read, then ./agent.yaml, then the built-in defaults:
12+#
13+# sbx run ./docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml
14+#
15+# v3 layout: this file is the descriptor (declarations only), mm-tui.dockerfile
16+# beside it is the content. What v2 wrote in `sandbox.image`,
17+# `sandbox.entrypoint` and `environment.variables` is now in that Dockerfile's
18+# FROM, ENTRYPOINT and ENV — the descriptor restates nothing the image config
19+# already carries.
20+#
21+# sbx builds this source form in its builder sandbox, whose own Docker engine
22+# PULLS the FROM image: <image>:<tag> must be on a registry, not only in the
23+# local image store (see docker-sbx-v3/README.md).
24+schemaVersion: "3"
25+kind: workload
26+displayName: Mini Me (window mode)
27+description: >
28+ Runs mm, a minimal coding agent for local LLMs, in its single-window terminal
29+ mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or
30+ llama-server) stays on the host: inside the sandbox `localhost` is the sandbox
31+ itself, so the configuration file must reach the host through
32+ host.docker.internal — agent.dmr.yaml already falls back to it.
33+sourceUrl: https://git.rickub.com/bots-garden/mini-me
34+# The kit's version is mm's: the image tag it is built on. A published kit is
35+# versioned by its OCI tag anyway, which wins over this field.
36+version: "${{ kit.args.tag }}"
37+provides: ["mm@${{ kit.args.tag }}"]
38+
39+args:
40+ # Build-phase (buildArg): resolved when the kit is built, handed to
41+ # mm-tui.dockerfile as --build-arg, and baked into the published descriptor.
42+ # A published kit therefore always names the image it was built on.
43+ image:
44+ default: "k33g/mm-sandbox"
45+ description: >-
46+ Repository of the mm sandbox template image, without the tag. Kept equal
47+ to <owner>/mm-sandbox by docker-sbx-v3/sync-kits.sh.
48+ pattern: '^[a-z0-9][a-z0-9._/:-]*$'
49+ buildArg: MM_IMAGE
50+ tag:
51+ default: "0.2.1"
52+ description: >-
53+ Tag of the template image: mm's version without the "v", as
54+ docker-sbx-v3/build.sh tags it (and rewrites this default to). Also the
55+ kit's version, hence version-shaped.
56+ pattern: '^[0-9]+(\.[0-9A-Za-z-]+)*$'
57+ buildArg: MM_TAG
58+ # Create-phase (env): resolved at `sbx run` / `sbx create`, exported to the
59+ # container. Private otherwise — an arg without env: never reaches it.
60+ config:
61+ default: ""
62+ description: >-
63+ Configuration file mm reads (its AGENT_CONFIG): a path relative to the
64+ workspace, or an absolute path inside the sandbox. Empty: ./agent.yaml in
65+ the workspace, then the built-in defaults.
66+ env: AGENT_CONFIG
67+
68+capabilities:
69+ # A sandbox-agent workload: the host launches the image ENTRYPOINT (mm-tui)
70+ # under bash as the image's user (agent), and mounts the workspace at the
71+ # image's WORKDIR, /home/agent/workspace.
72+ - type: com.docker.sandbox/sbx@1
73+
74+ # The model server on the host. Requests leave the sandbox through its proxy,
75+ # which maps host.docker.internal to the host's localhost; both spellings are
76+ # listed so the rule matches whichever one the policy is checked against.
77+ # 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own
78+ # port with `sbx policy allow network host.docker.internal:<port>`.
79+ - type: com.docker.sandbox/network-policy@1
80+ config:
81+ runtime:
82+ allow:
83+ - "host.docker.internal:12434"
84+ - "localhost:12434"
85+ - "host.docker.internal:8080"
86+ - "localhost:8080"
added docker-sbx-v3/publish.sh +75 -0
new file mode 100755
@@ -0,0 +1,75 @@
1+#!/usr/bin/env bash
2+# Build and publish everything to Docker Hub, by hand, in one go:
3+# <owner>/mm-sandbox:<version> the template image, linux/amd64 + linux/arm64
4+# <owner>/sbx-kit-mm-tui:<version> the window-mode kit (v3)
5+# <owner>/sbx-kit-mm-acp:<version> the editor (ACP) kit (v3)
6+#
7+# Usage:
8+# ./docker-sbx-v3/publish.sh # TAG from release.env (v0.2.1 → 0.2.1)
9+# ./docker-sbx-v3/publish.sh v0.2.2 # another tag
10+#
11+# Credentials, two environment variables:
12+# DOCKER_HANDLE the Docker Hub account — also the image owner (default k33g)
13+# DOCKER_PAT an access token with read/write scope
14+# With both set, the script logs in with them (and out at the end). With
15+# neither, it uses the login you already have (`docker login` done earlier).
16+#
17+# Needs: docker with buildx (Docker Desktop has it). No sbx: v3 kits are
18+# published with buildx. Pieces, runnable alone:
19+# PUSH=1 ./docker-sbx-v3/build.sh TAG image only
20+# ./docker-sbx-v3/push-kits.sh TAG kits only
21+set -euo pipefail
22+
23+cd "$(dirname "$0")/.."
24+
25+if [ -f release.env ]; then
26+ # shellcheck source=/dev/null
27+ source release.env
28+fi
29+TAG="${1:-${TAG:-}}"
30+if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
31+ echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/publish.sh v1.2.3)"
32+ exit 1
33+fi
34+
35+# Secrets pasted with a trailing newline or stray spaces are a classic.
36+DOCKER_HANDLE="$(printf '%s' "${DOCKER_HANDLE:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
37+DOCKER_PAT="$(printf '%s' "${DOCKER_PAT:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
38+case "${DOCKER_HANDLE}" in
39+*@* | *:*)
40+ echo "❌ DOCKER_HANDLE must be the Docker ID (username), not an e-mail: access tokens only pair with the username"
41+ exit 1
42+ ;;
43+esac
44+export IMAGE_OWNER="${IMAGE_OWNER:-${DOCKER_HANDLE:-k33g}}"
45+VERSION="${TAG#v}"
46+
47+logged_in_here=""
48+if [ -n "${DOCKER_HANDLE}" ] && [ -n "${DOCKER_PAT}" ]; then
49+ echo "🔐 docker login as ${DOCKER_HANDLE}"
50+ printf '%s' "${DOCKER_PAT}" | docker login --username "${DOCKER_HANDLE}" --password-stdin
51+ logged_in_here=1
52+elif [ -n "${DOCKER_HANDLE}${DOCKER_PAT}" ]; then
53+ echo "❌ set both DOCKER_HANDLE and DOCKER_PAT, or neither (to reuse an existing docker login)"
54+ exit 1
55+else
56+ echo "🔐 no DOCKER_HANDLE/DOCKER_PAT: using the existing docker login, publishing under ${IMAGE_OWNER}"
57+fi
58+# Whatever happens below, a login made here does not outlive the script.
59+cleanup() {
60+ if [ -n "${logged_in_here}" ]; then
61+ docker logout >/dev/null 2>&1 || true
62+ fi
63+}
64+trap cleanup EXIT
65+
66+echo
67+echo "═══ 1/2 image ${IMAGE_OWNER}/mm-sandbox:${VERSION}"
68+PUSH=1 ./docker-sbx-v3/build.sh "${TAG}"
69+
70+echo
71+echo "═══ 2/2 kits ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-tui:${VERSION} and ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-acp:${VERSION}"
72+./docker-sbx-v3/push-kits.sh "${TAG}"
73+
74+echo
75+echo "✨ Published ${TAG}. The kits' descriptors now name version ${VERSION} — commit them."
new file mode 100755
@@ -0,0 +1,75 @@
1+#!/usr/bin/env bash
2+# Build and publish everything to Docker Hub, by hand, in one go:
3+# <owner>/mm-sandbox:<version> the template image, linux/amd64 + linux/arm64
4+# <owner>/sbx-kit-mm-tui:<version> the window-mode kit (v3)
5+# <owner>/sbx-kit-mm-acp:<version> the editor (ACP) kit (v3)
6+#
7+# Usage:
8+# ./docker-sbx-v3/publish.sh # TAG from release.env (v0.2.1 → 0.2.1)
9+# ./docker-sbx-v3/publish.sh v0.2.2 # another tag
10+#
11+# Credentials, two environment variables:
12+# DOCKER_HANDLE the Docker Hub account — also the image owner (default k33g)
13+# DOCKER_PAT an access token with read/write scope
14+# With both set, the script logs in with them (and out at the end). With
15+# neither, it uses the login you already have (`docker login` done earlier).
16+#
17+# Needs: docker with buildx (Docker Desktop has it). No sbx: v3 kits are
18+# published with buildx. Pieces, runnable alone:
19+# PUSH=1 ./docker-sbx-v3/build.sh TAG image only
20+# ./docker-sbx-v3/push-kits.sh TAG kits only
21+set -euo pipefail
22+
23+cd "$(dirname "$0")/.."
24+
25+if [ -f release.env ]; then
26+ # shellcheck source=/dev/null
27+ source release.env
28+fi
29+TAG="${1:-${TAG:-}}"
30+if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
31+ echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/publish.sh v1.2.3)"
32+ exit 1
33+fi
34+
35+# Secrets pasted with a trailing newline or stray spaces are a classic.
36+DOCKER_HANDLE="$(printf '%s' "${DOCKER_HANDLE:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
37+DOCKER_PAT="$(printf '%s' "${DOCKER_PAT:-}" | tr -d '\r\n' | sed 's/^ *//; s/ *$//')"
38+case "${DOCKER_HANDLE}" in
39+*@* | *:*)
40+ echo "❌ DOCKER_HANDLE must be the Docker ID (username), not an e-mail: access tokens only pair with the username"
41+ exit 1
42+ ;;
43+esac
44+export IMAGE_OWNER="${IMAGE_OWNER:-${DOCKER_HANDLE:-k33g}}"
45+VERSION="${TAG#v}"
46+
47+logged_in_here=""
48+if [ -n "${DOCKER_HANDLE}" ] && [ -n "${DOCKER_PAT}" ]; then
49+ echo "🔐 docker login as ${DOCKER_HANDLE}"
50+ printf '%s' "${DOCKER_PAT}" | docker login --username "${DOCKER_HANDLE}" --password-stdin
51+ logged_in_here=1
52+elif [ -n "${DOCKER_HANDLE}${DOCKER_PAT}" ]; then
53+ echo "❌ set both DOCKER_HANDLE and DOCKER_PAT, or neither (to reuse an existing docker login)"
54+ exit 1
55+else
56+ echo "🔐 no DOCKER_HANDLE/DOCKER_PAT: using the existing docker login, publishing under ${IMAGE_OWNER}"
57+fi
58+# Whatever happens below, a login made here does not outlive the script.
59+cleanup() {
60+ if [ -n "${logged_in_here}" ]; then
61+ docker logout >/dev/null 2>&1 || true
62+ fi
63+}
64+trap cleanup EXIT
65+
66+echo
67+echo "═══ 1/2 image ${IMAGE_OWNER}/mm-sandbox:${VERSION}"
68+PUSH=1 ./docker-sbx-v3/build.sh "${TAG}"
69+
70+echo
71+echo "═══ 2/2 kits ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-tui:${VERSION} and ${IMAGE_OWNER}/${KIT_PREFIX:-sbx-kit-}mm-acp:${VERSION}"
72+./docker-sbx-v3/push-kits.sh "${TAG}"
73+
74+echo
75+echo "✨ Published ${TAG}. The kits' descriptors now name version ${VERSION} — commit them."
added docker-sbx-v3/push-kits.sh +94 -0
new file mode 100755
@@ -0,0 +1,94 @@
1+#!/usr/bin/env bash
2+# Build and publish the two v3 kits to Docker Hub:
3+# <owner>/sbx-kit-mm-tui:<version> and <owner>/sbx-kit-mm-acp:<version>
4+#
5+# Usage:
6+# ./docker-sbx-v3/push-kits.sh # TAG from release.env
7+# ./docker-sbx-v3/push-kits.sh v0.2.2 # override the tag
8+# IMAGE_OWNER=someone … # another owner (default k33g); the kits
9+# # are re-pointed at someone/mm-sandbox too
10+# REGISTRY=localhost:5000 … # another registry (default docker.io)
11+# KIT_PREFIX=mm-v3- … # repository prefix (default sbx-kit-)
12+# PLATFORMS=linux/amd64 … # narrower multi-arch set
13+#
14+# A v3 kit is an ordinary OCI image, so publishing is a buildx build: the
15+# descriptor's `# syntax=docker/sandbox-kit:3` line makes BuildKit run the kit
16+# frontend, which validates the descriptor, builds the companion Dockerfile
17+# FROM <owner>/mm-sandbox:<version> and pushes one image per platform with the
18+# descriptor in its manifest annotations. No sbx needed (v2 used
19+# `sbx kit push`, which only knows spec.yaml).
20+#
21+# The repositories are sbx-kit-<kit>, the naming Docker's own kits use, and
22+# NOT the v2 ones (<owner>/mm-tui, <owner>/mm-acp): pushing a v3 kit there at
23+# the same version would replace the published v2 kit.
24+#
25+# Needs a login: `docker login -u <handle>` with a Docker Hub access token.
26+# publish.sh runs this after the image. Push the image first: the kits are
27+# built FROM <owner>/mm-sandbox:<version>, pulled from the registry.
28+set -euo pipefail
29+
30+cd "$(dirname "$0")/.."
31+
32+if [ -f release.env ]; then
33+ # shellcheck source=/dev/null
34+ source release.env
35+fi
36+TAG="${1:-${TAG:-}}"
37+if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
38+ echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/push-kits.sh v1.2.3)"
39+ exit 1
40+fi
41+
42+IMAGE_OWNER="${IMAGE_OWNER:-k33g}"
43+REGISTRY="${REGISTRY:-docker.io}"
44+KIT_PREFIX="${KIT_PREFIX:-sbx-kit-}"
45+PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
46+VERSION="${TAG#v}"
47+IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}"
48+
49+# Fail here rather than in the middle of a multi-arch build.
50+if ! docker buildx imagetools inspect "${IMAGE}" >/dev/null 2>&1; then
51+ echo "❌ ${IMAGE} is not on the registry: the kits are built FROM it. Push it first: PUSH=1 ./docker-sbx-v3/build.sh ${TAG}"
52+ exit 1
53+fi
54+
55+./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}"
56+
57+# Same builder as build.sh: multi-arch needs the container driver.
58+if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then
59+ docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null
60+fi
61+
62+refs=()
63+for dir in docker-sbx-v3/kits/*/; do
64+ kit="$(basename "${dir}")"
65+ ref="${REGISTRY}/${IMAGE_OWNER}/${KIT_PREFIX}${kit}:${VERSION}"
66+ echo "🧰 ${kit} → ${ref}"
67+ # The build args are the kit's own arg names; the frontend validates them
68+ # against the descriptor and hands the Dockerfile the declared buildArg.
69+ # They repeat what sync-kits.sh just wrote, so the file and the push agree.
70+ docker buildx build --builder mm-sandbox-builder "${dir}" -f "${dir}${kit}.yaml" \
71+ --build-arg "image=${IMAGE_OWNER}/mm-sandbox" \
72+ --build-arg "tag=${VERSION}" \
73+ --platform "${PLATFORMS}" \
74+ --provenance=true --sbom=true \
75+ -t "${ref}" --push
76+ docker buildx imagetools inspect "${ref}" | grep -E '^Name:|Platform:' | sed 's/^/ /'
77+ refs+=("${ref}")
78+done
79+
80+# The specification's own check of what was pushed, when available.
81+if command -v "${KIT_TCK:-kit-tck}" >/dev/null 2>&1; then
82+ for ref in "${refs[@]}"; do
83+ "${KIT_TCK:-kit-tck}" validate "${ref}"
84+ done
85+fi
86+
87+cat <<NEXT
88+
89+Published. From any machine with Docker Sandboxes (docker.io is an allowed kit source by default):
90+
91+ window mode sbx run ${IMAGE_OWNER}/${KIT_PREFIX}mm-tui:${VERSION} . -- agent.dmr.yaml
92+ editor (ACP) sbx create --name mm-acp ${IMAGE_OWNER}/${KIT_PREFIX}mm-acp:${VERSION} . --kit-arg config=agent.dmr.yaml
93+ then register sbx exec -i mm-acp mm -acp in the editor
94+NEXT
new file mode 100755
@@ -0,0 +1,94 @@
1+#!/usr/bin/env bash
2+# Build and publish the two v3 kits to Docker Hub:
3+# <owner>/sbx-kit-mm-tui:<version> and <owner>/sbx-kit-mm-acp:<version>
4+#
5+# Usage:
6+# ./docker-sbx-v3/push-kits.sh # TAG from release.env
7+# ./docker-sbx-v3/push-kits.sh v0.2.2 # override the tag
8+# IMAGE_OWNER=someone … # another owner (default k33g); the kits
9+# # are re-pointed at someone/mm-sandbox too
10+# REGISTRY=localhost:5000 … # another registry (default docker.io)
11+# KIT_PREFIX=mm-v3- … # repository prefix (default sbx-kit-)
12+# PLATFORMS=linux/amd64 … # narrower multi-arch set
13+#
14+# A v3 kit is an ordinary OCI image, so publishing is a buildx build: the
15+# descriptor's `# syntax=docker/sandbox-kit:3` line makes BuildKit run the kit
16+# frontend, which validates the descriptor, builds the companion Dockerfile
17+# FROM <owner>/mm-sandbox:<version> and pushes one image per platform with the
18+# descriptor in its manifest annotations. No sbx needed (v2 used
19+# `sbx kit push`, which only knows spec.yaml).
20+#
21+# The repositories are sbx-kit-<kit>, the naming Docker's own kits use, and
22+# NOT the v2 ones (<owner>/mm-tui, <owner>/mm-acp): pushing a v3 kit there at
23+# the same version would replace the published v2 kit.
24+#
25+# Needs a login: `docker login -u <handle>` with a Docker Hub access token.
26+# publish.sh runs this after the image. Push the image first: the kits are
27+# built FROM <owner>/mm-sandbox:<version>, pulled from the registry.
28+set -euo pipefail
29+
30+cd "$(dirname "$0")/.."
31+
32+if [ -f release.env ]; then
33+ # shellcheck source=/dev/null
34+ source release.env
35+fi
36+TAG="${1:-${TAG:-}}"
37+if ! [[ "${TAG}" =~ ^v[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z.-]+)?$ ]]; then
38+ echo "❌ TAG must look like v1.2.3 or v1.2.3-rc.1, got '${TAG}' (check release.env or pass it: ./docker-sbx-v3/push-kits.sh v1.2.3)"
39+ exit 1
40+fi
41+
42+IMAGE_OWNER="${IMAGE_OWNER:-k33g}"
43+REGISTRY="${REGISTRY:-docker.io}"
44+KIT_PREFIX="${KIT_PREFIX:-sbx-kit-}"
45+PLATFORMS="${PLATFORMS:-linux/amd64,linux/arm64}"
46+VERSION="${TAG#v}"
47+IMAGE="${IMAGE_OWNER}/mm-sandbox:${VERSION}"
48+
49+# Fail here rather than in the middle of a multi-arch build.
50+if ! docker buildx imagetools inspect "${IMAGE}" >/dev/null 2>&1; then
51+ echo "❌ ${IMAGE} is not on the registry: the kits are built FROM it. Push it first: PUSH=1 ./docker-sbx-v3/build.sh ${TAG}"
52+ exit 1
53+fi
54+
55+./docker-sbx-v3/sync-kits.sh "${IMAGE_OWNER}" "${VERSION}"
56+
57+# Same builder as build.sh: multi-arch needs the container driver.
58+if ! docker buildx inspect mm-sandbox-builder >/dev/null 2>&1; then
59+ docker buildx create --name mm-sandbox-builder --driver docker-container --bootstrap >/dev/null
60+fi
61+
62+refs=()
63+for dir in docker-sbx-v3/kits/*/; do
64+ kit="$(basename "${dir}")"
65+ ref="${REGISTRY}/${IMAGE_OWNER}/${KIT_PREFIX}${kit}:${VERSION}"
66+ echo "🧰 ${kit} → ${ref}"
67+ # The build args are the kit's own arg names; the frontend validates them
68+ # against the descriptor and hands the Dockerfile the declared buildArg.
69+ # They repeat what sync-kits.sh just wrote, so the file and the push agree.
70+ docker buildx build --builder mm-sandbox-builder "${dir}" -f "${dir}${kit}.yaml" \
71+ --build-arg "image=${IMAGE_OWNER}/mm-sandbox" \
72+ --build-arg "tag=${VERSION}" \
73+ --platform "${PLATFORMS}" \
74+ --provenance=true --sbom=true \
75+ -t "${ref}" --push
76+ docker buildx imagetools inspect "${ref}" | grep -E '^Name:|Platform:' | sed 's/^/ /'
77+ refs+=("${ref}")
78+done
79+
80+# The specification's own check of what was pushed, when available.
81+if command -v "${KIT_TCK:-kit-tck}" >/dev/null 2>&1; then
82+ for ref in "${refs[@]}"; do
83+ "${KIT_TCK:-kit-tck}" validate "${ref}"
84+ done
85+fi
86+
87+cat <<NEXT
88+
89+Published. From any machine with Docker Sandboxes (docker.io is an allowed kit source by default):
90+
91+ window mode sbx run ${IMAGE_OWNER}/${KIT_PREFIX}mm-tui:${VERSION} . -- agent.dmr.yaml
92+ editor (ACP) sbx create --name mm-acp ${IMAGE_OWNER}/${KIT_PREFIX}mm-acp:${VERSION} . --kit-arg config=agent.dmr.yaml
93+ then register sbx exec -i mm-acp mm -acp in the editor
94+NEXT
added docker-sbx-v3/sync-kits.sh +44 -0
new file mode 100755
@@ -0,0 +1,44 @@
1+#!/usr/bin/env bash
2+# Point the two v3 kits at one image: <owner>/mm-sandbox:<version>.
3+#
4+# Usage: ./docker-sbx-v3/sync-kits.sh OWNER VERSION (e.g. k33g 0.2.1)
5+#
6+# Rewrites, in docker-sbx-v3/kits/*/*.yaml (the descriptors), only two values:
7+# args.image.default: "<owner>/mm-sandbox" which repository the kit is built FROM
8+# args.tag.default: "<version>" which tag — and the kit's version,
9+# since `version:` and `provides:`
10+# reference ${{ kit.args.tag }}
11+# Everything else — comments included — is left byte-for-byte alone, so a
12+# kit that already matches is not changed at all. build.sh and push-kits.sh
13+# call this, so the kits always name the image just built or pushed.
14+set -euo pipefail
15+
16+if [ $# -ne 2 ]; then
17+ echo "usage: $0 OWNER VERSION" >&2
18+ exit 2
19+fi
20+OWNER="$1"
21+VERSION="$2"
22+
23+# The kits' `tag` arg is also their version, so it carries the spec's version
24+# grammar: dotted segments, no "v" (the frontend refuses anything else).
25+if ! [[ "${VERSION}" =~ ^[0-9]+(\.[0-9A-Za-z-]+)*$ ]]; then
26+ echo "❌ VERSION must be version-shaped without a \"v\" (0.2.1, 0.2.2-rc.1), got '${VERSION}'" >&2
27+ exit 2
28+fi
29+
30+cd "$(dirname "$0")/.."
31+
32+for kit in docker-sbx-v3/kits/*/*.yaml; do
33+ if ! grep -q '^ image:$' "${kit}" || ! grep -q '^ tag:$' "${kit}"; then
34+ echo "❌ ${kit}: expected an 'args.image' and an 'args.tag' — not updated" >&2
35+ exit 1
36+ fi
37+ # sed -i.bak works on both GNU and BSD sed; the backup is removed at once.
38+ sed -i.bak -E \
39+ -e "/^ image:\$/,/^ default:/ s|^( default: )\"[^\"/]*(/mm-sandbox)\"|\1\"${OWNER}\2\"|" \
40+ -e "/^ tag:\$/,/^ default:/ s|^( default: )\"[^\"]*\"|\1\"${VERSION}\"|" \
41+ "${kit}"
42+ rm -f "${kit}.bak"
43+ echo "✅ ${kit} → image ${OWNER}/mm-sandbox, tag (and version) \"${VERSION}\""
44+done
new file mode 100755
@@ -0,0 +1,44 @@
1+#!/usr/bin/env bash
2+# Point the two v3 kits at one image: <owner>/mm-sandbox:<version>.
3+#
4+# Usage: ./docker-sbx-v3/sync-kits.sh OWNER VERSION (e.g. k33g 0.2.1)
5+#
6+# Rewrites, in docker-sbx-v3/kits/*/*.yaml (the descriptors), only two values:
7+# args.image.default: "<owner>/mm-sandbox" which repository the kit is built FROM
8+# args.tag.default: "<version>" which tag — and the kit's version,
9+# since `version:` and `provides:`
10+# reference ${{ kit.args.tag }}
11+# Everything else — comments included — is left byte-for-byte alone, so a
12+# kit that already matches is not changed at all. build.sh and push-kits.sh
13+# call this, so the kits always name the image just built or pushed.
14+set -euo pipefail
15+
16+if [ $# -ne 2 ]; then
17+ echo "usage: $0 OWNER VERSION" >&2
18+ exit 2
19+fi
20+OWNER="$1"
21+VERSION="$2"
22+
23+# The kits' `tag` arg is also their version, so it carries the spec's version
24+# grammar: dotted segments, no "v" (the frontend refuses anything else).
25+if ! [[ "${VERSION}" =~ ^[0-9]+(\.[0-9A-Za-z-]+)*$ ]]; then
26+ echo "❌ VERSION must be version-shaped without a \"v\" (0.2.1, 0.2.2-rc.1), got '${VERSION}'" >&2
27+ exit 2
28+fi
29+
30+cd "$(dirname "$0")/.."
31+
32+for kit in docker-sbx-v3/kits/*/*.yaml; do
33+ if ! grep -q '^ image:$' "${kit}" || ! grep -q '^ tag:$' "${kit}"; then
34+ echo "❌ ${kit}: expected an 'args.image' and an 'args.tag' — not updated" >&2
35+ exit 1
36+ fi
37+ # sed -i.bak works on both GNU and BSD sed; the backup is removed at once.
38+ sed -i.bak -E \
39+ -e "/^ image:\$/,/^ default:/ s|^( default: )\"[^\"/]*(/mm-sandbox)\"|\1\"${OWNER}\2\"|" \
40+ -e "/^ tag:\$/,/^ default:/ s|^( default: )\"[^\"]*\"|\1\"${VERSION}\"|" \
41+ "${kit}"
42+ rm -f "${kit}.bak"
43+ echo "✅ ${kit} → image ${OWNER}/mm-sandbox, tag (and version) \"${VERSION}\""
44+done
added docker-sbx-v3/template/Dockerfile +143 -0
new file mode 100644
@@ -0,0 +1,143 @@
1+# syntax=docker/dockerfile:1
2+#
3+# The mm sandbox template: Docker Sandboxes' `shell` image with mm installed.
4+#
5+# Build it from the REPOSITORY ROOT (the context is the mm sources), or run
6+# docker-sbx-v3/build.sh, which does exactly that and stamps mm's tag — the
7+# image tag is that tag without the "v", k33g/mm-sandbox:0.0.2 for v0.0.2:
8+#
9+# docker build -f docker-sbx-v3/template/Dockerfile \
10+# --build-arg MM_VERSION=v0.0.2 -t k33g/mm-sandbox:0.0.2 .
11+#
12+# The two v3 kits under docker-sbx-v3/kits/ are thin workloads built FROM this
13+# image: each one sets its own ENTRYPOINT (mm-tui, mm-acp-info), which the
14+# sandbox runtime reads as the agent's launch command (sbx@1). ENTRYPOINT and
15+# CMD are therefore deliberately not set here: the template stays agnostic.
16+
17+ARG GO_VERSION=1.26
18+ARG SHELL_TEMPLATE=docker/sandbox-templates:shell
19+
20+# ---- build stage: cross-compile mm for the target platform -----------------
21+FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-bookworm AS build
22+ARG TARGETOS
23+ARG TARGETARCH
24+# What `mm --version` reports: the tag, as 02-build-releases.sh stamps it.
25+ARG MM_VERSION=dev
26+
27+WORKDIR /src
28+COPY go.mod go.sum ./
29+RUN --mount=type=cache,target=/go/pkg/mod go mod download
30+COPY . .
31+# Same flags as 02-build-releases.sh: no C, no local paths, no symbols, the
32+# version stamped into internal/version.
33+RUN --mount=type=cache,target=/go/pkg/mod \
34+ --mount=type=cache,target=/root/.cache/go-build \
35+ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
36+ go build -trimpath -ldflags "-s -w -X mm/internal/version.stamped=${MM_VERSION}" -o /out/mm .
37+
38+# ---- template: the shell sandbox plus mm -----------------------------------
39+FROM ${SHELL_TEMPLATE}
40+
41+COPY --from=build --chmod=0755 /out/mm /usr/local/bin/mm
42+# The two kit entry points. mm-tui runs `mm -tui "$@"`; mm-acp-info prints how
43+# an editor reaches this sandbox and opens a shell (see docker-sbx-v3/README.md).
44+COPY --chmod=0755 docker-sbx-v3/template/mm-tui docker-sbx-v3/template/mm-acp-info /usr/local/bin/
45+
46+# tcell (the window mode) needs a terminal type and a UTF-8 locale; the kits
47+# set them too, this is the fallback for a plain `docker run`.
48+ENV TERM=xterm-256color \
49+ COLORTERM=truecolor \
50+ LANG=C.UTF-8
51+
52+# The pinned toolchains (/usr/local/go/bin, /usr/local/node/bin) must come
53+# before /usr/bin so they win over any Go or Node the base image ships.
54+ENV PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH
55+
56+# Without this, a go.mod whose `go` directive is newer than GO_VERSION makes the
57+# toolchain download and run a different Go, silently defeating the pin.
58+ENV GOTOOLCHAIN=local
59+
60+# ------------------------------------
61+# Shared curl options for every download below.
62+#
63+# ARG, not ENV: this is build-time only and must not leak into the image.
64+# ------------------------------------
65+ARG CURL_RETRY="--retry 5 --retry-all-errors --retry-delay 3 --connect-timeout 15"
66+
67+USER root
68+
69+# ------------------------------------
70+# Install Go toolchain and Node.js
71+# ------------------------------------
72+ARG GO_VERSION=1.26.0
73+ARG NODE_VERSION=24.21.0
74+ARG TARGETARCH
75+
76+RUN <<EOF
77+set -eux
78+apt-get update
79+apt-get install -y curl build-essential xz-utils
80+rm -rf /var/lib/apt/lists/*
81+EOF
82+
83+RUN <<EOF
84+set -eux
85+apt-get remove -y golang-go golang-doc
86+apt-get autoremove -y
87+curl ${CURL_RETRY} -C - -fsSL -o /tmp/go.tgz "https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz"
88+rm -rf /usr/local/go
89+tar -C /usr/local -xzf /tmp/go.tgz
90+rm /tmp/go.tgz
91+/usr/local/go/bin/go version
92+EOF
93+
94+RUN <<EOF
95+set -eux
96+case "${TARGETARCH}" in
97+ amd64) node_arch=x64 ;;
98+ arm64) node_arch=arm64 ;;
99+ *) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;;
100+esac
101+curl ${CURL_RETRY} -C - -fsSL -o /tmp/node.tar.xz "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz"
102+rm -rf /usr/local/node
103+mkdir -p /usr/local/node
104+tar -C /usr/local/node --strip-components=1 -xJf /tmp/node.tar.xz
105+rm /tmp/node.tar.xz
106+/usr/local/node/bin/node --version
107+/usr/local/node/bin/npm --version
108+EOF
109+
110+# ------------------------------------
111+# Persist the Go and Node environment for sandbox shells.
112+# /etc/sandbox-persistent.sh is sourced before every bash command in the sbx.
113+# ------------------------------------
114+RUN <<EOF
115+{
116+ echo 'export PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH'
117+ echo 'export GOTOOLCHAIN=local'
118+} >> /etc/sandbox-persistent.sh
119+EOF
120+
121+# Switch to agent user for Go tools installation (they go to /home/agent/go/bin)
122+USER agent
123+
124+# ------------------------------------
125+# Install Go developer tools
126+# ------------------------------------
127+ARG GOPLS_VERSION=v0.23.0
128+ARG X_TOOLS_VERSION=v0.49.0
129+ARG STATICCHECK_VERSION=v0.7.0
130+
131+# Retried: parallel multi-arch builds occasionally hit DNS timeouts on
132+# Docker Desktop's resolver. The module cache survives within this RUN,
133+# so a retry only fetches what's still missing.
134+RUN for i in 1 2 3 4 5; do \
135+ go install golang.org/x/tools/gopls@${GOPLS_VERSION} \
136+ && go install golang.org/x/tools/cmd/goimports@${X_TOOLS_VERSION} \
137+ && go install honnef.co/go/tools/cmd/staticcheck@${STATICCHECK_VERSION} \
138+ && exit 0; \
139+ echo "go install failed (attempt $i), retrying..." >&2; sleep $((i * 5)); \
140+ done; exit 1
141+
142+# Prove the binary runs on this platform before the image is tagged.
143+RUN mm --version && mm-tui --version
new file mode 100644
@@ -0,0 +1,143 @@
1+# syntax=docker/dockerfile:1
2+#
3+# The mm sandbox template: Docker Sandboxes' `shell` image with mm installed.
4+#
5+# Build it from the REPOSITORY ROOT (the context is the mm sources), or run
6+# docker-sbx-v3/build.sh, which does exactly that and stamps mm's tag — the
7+# image tag is that tag without the "v", k33g/mm-sandbox:0.0.2 for v0.0.2:
8+#
9+# docker build -f docker-sbx-v3/template/Dockerfile \
10+# --build-arg MM_VERSION=v0.0.2 -t k33g/mm-sandbox:0.0.2 .
11+#
12+# The two v3 kits under docker-sbx-v3/kits/ are thin workloads built FROM this
13+# image: each one sets its own ENTRYPOINT (mm-tui, mm-acp-info), which the
14+# sandbox runtime reads as the agent's launch command (sbx@1). ENTRYPOINT and
15+# CMD are therefore deliberately not set here: the template stays agnostic.
16+
17+ARG GO_VERSION=1.26
18+ARG SHELL_TEMPLATE=docker/sandbox-templates:shell
19+
20+# ---- build stage: cross-compile mm for the target platform -----------------
21+FROM --platform=$BUILDPLATFORM golang:${GO_VERSION}-bookworm AS build
22+ARG TARGETOS
23+ARG TARGETARCH
24+# What `mm --version` reports: the tag, as 02-build-releases.sh stamps it.
25+ARG MM_VERSION=dev
26+
27+WORKDIR /src
28+COPY go.mod go.sum ./
29+RUN --mount=type=cache,target=/go/pkg/mod go mod download
30+COPY . .
31+# Same flags as 02-build-releases.sh: no C, no local paths, no symbols, the
32+# version stamped into internal/version.
33+RUN --mount=type=cache,target=/go/pkg/mod \
34+ --mount=type=cache,target=/root/.cache/go-build \
35+ CGO_ENABLED=0 GOOS=${TARGETOS} GOARCH=${TARGETARCH} \
36+ go build -trimpath -ldflags "-s -w -X mm/internal/version.stamped=${MM_VERSION}" -o /out/mm .
37+
38+# ---- template: the shell sandbox plus mm -----------------------------------
39+FROM ${SHELL_TEMPLATE}
40+
41+COPY --from=build --chmod=0755 /out/mm /usr/local/bin/mm
42+# The two kit entry points. mm-tui runs `mm -tui "$@"`; mm-acp-info prints how
43+# an editor reaches this sandbox and opens a shell (see docker-sbx-v3/README.md).
44+COPY --chmod=0755 docker-sbx-v3/template/mm-tui docker-sbx-v3/template/mm-acp-info /usr/local/bin/
45+
46+# tcell (the window mode) needs a terminal type and a UTF-8 locale; the kits
47+# set them too, this is the fallback for a plain `docker run`.
48+ENV TERM=xterm-256color \
49+ COLORTERM=truecolor \
50+ LANG=C.UTF-8
51+
52+# The pinned toolchains (/usr/local/go/bin, /usr/local/node/bin) must come
53+# before /usr/bin so they win over any Go or Node the base image ships.
54+ENV PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH
55+
56+# Without this, a go.mod whose `go` directive is newer than GO_VERSION makes the
57+# toolchain download and run a different Go, silently defeating the pin.
58+ENV GOTOOLCHAIN=local
59+
60+# ------------------------------------
61+# Shared curl options for every download below.
62+#
63+# ARG, not ENV: this is build-time only and must not leak into the image.
64+# ------------------------------------
65+ARG CURL_RETRY="--retry 5 --retry-all-errors --retry-delay 3 --connect-timeout 15"
66+
67+USER root
68+
69+# ------------------------------------
70+# Install Go toolchain and Node.js
71+# ------------------------------------
72+ARG GO_VERSION=1.26.0
73+ARG NODE_VERSION=24.21.0
74+ARG TARGETARCH
75+
76+RUN <<EOF
77+set -eux
78+apt-get update
79+apt-get install -y curl build-essential xz-utils
80+rm -rf /var/lib/apt/lists/*
81+EOF
82+
83+RUN <<EOF
84+set -eux
85+apt-get remove -y golang-go golang-doc
86+apt-get autoremove -y
87+curl ${CURL_RETRY} -C - -fsSL -o /tmp/go.tgz "https://go.dev/dl/go${GO_VERSION}.linux-${TARGETARCH}.tar.gz"
88+rm -rf /usr/local/go
89+tar -C /usr/local -xzf /tmp/go.tgz
90+rm /tmp/go.tgz
91+/usr/local/go/bin/go version
92+EOF
93+
94+RUN <<EOF
95+set -eux
96+case "${TARGETARCH}" in
97+ amd64) node_arch=x64 ;;
98+ arm64) node_arch=arm64 ;;
99+ *) echo "unsupported TARGETARCH: ${TARGETARCH}" >&2; exit 1 ;;
100+esac
101+curl ${CURL_RETRY} -C - -fsSL -o /tmp/node.tar.xz "https://nodejs.org/dist/v${NODE_VERSION}/node-v${NODE_VERSION}-linux-${node_arch}.tar.xz"
102+rm -rf /usr/local/node
103+mkdir -p /usr/local/node
104+tar -C /usr/local/node --strip-components=1 -xJf /tmp/node.tar.xz
105+rm /tmp/node.tar.xz
106+/usr/local/node/bin/node --version
107+/usr/local/node/bin/npm --version
108+EOF
109+
110+# ------------------------------------
111+# Persist the Go and Node environment for sandbox shells.
112+# /etc/sandbox-persistent.sh is sourced before every bash command in the sbx.
113+# ------------------------------------
114+RUN <<EOF
115+{
116+ echo 'export PATH=/usr/local/go/bin:/usr/local/node/bin:/home/agent/go/bin:$PATH'
117+ echo 'export GOTOOLCHAIN=local'
118+} >> /etc/sandbox-persistent.sh
119+EOF
120+
121+# Switch to agent user for Go tools installation (they go to /home/agent/go/bin)
122+USER agent
123+
124+# ------------------------------------
125+# Install Go developer tools
126+# ------------------------------------
127+ARG GOPLS_VERSION=v0.23.0
128+ARG X_TOOLS_VERSION=v0.49.0
129+ARG STATICCHECK_VERSION=v0.7.0
130+
131+# Retried: parallel multi-arch builds occasionally hit DNS timeouts on
132+# Docker Desktop's resolver. The module cache survives within this RUN,
133+# so a retry only fetches what's still missing.
134+RUN for i in 1 2 3 4 5; do \
135+ go install golang.org/x/tools/gopls@${GOPLS_VERSION} \
136+ && go install golang.org/x/tools/cmd/goimports@${X_TOOLS_VERSION} \
137+ && go install honnef.co/go/tools/cmd/staticcheck@${STATICCHECK_VERSION} \
138+ && exit 0; \
139+ echo "go install failed (attempt $i), retrying..." >&2; sleep $((i * 5)); \
140+ done; exit 1
141+
142+# Prove the binary runs on this platform before the image is tagged.
143+RUN mm --version && mm-tui --version
added docker-sbx-v3/template/mm-acp-info +52 -0
new file mode 100644
@@ -0,0 +1,52 @@
1+#!/bin/bash
2+# Entry point of the mm-acp sandbox kit (docker-sbx-v3/kits/mm-acp).
3+#
4+# An editor never runs this script. It reaches mm with
5+#
6+# sbx exec -i <sandbox> mm -acp
7+#
8+# because an ACP client needs raw stdin/stdout and `sbx run` always allocates
9+# a terminal. So attaching to this sandbox with `sbx run` prints the wiring
10+# for the editor, with this sandbox's real name and paths, then opens a shell.
11+set -u
12+
13+name="${SANDBOX_NAME:-$(hostname)}"
14+workspace="${WORKSPACE_DIR:-$PWD}"
15+config="${AGENT_CONFIG:-}"
16+if [ -z "$config" ]; then
17+ config_note="none set — mm reads ./agent.yaml in the workspace, then its built-in defaults"
18+elif [ "${config#/}" = "$config" ]; then
19+ config_note="$config (relative to the workspace: ${workspace%/}/$config)"
20+else
21+ config_note="$config"
22+fi
23+
24+cat <<INFO
25+
26+ mm $(mm --version 2>/dev/null | awk '{print $2}') in sandbox "$name"
27+ workspace : $workspace
28+ config : $config_note
29+
30+ This sandbox is meant for an editor (Agent Client Protocol). Register it in
31+ Zed's settings.json — the editor starts mm inside the sandbox on every
32+ conversation, and sbx starts the sandbox first when it is stopped:
33+
34+ {
35+ "agent_servers": {
36+ "mini-me (sandbox)": {
37+ "type": "custom",
38+ "command": "sbx",
39+ "args": ["exec", "-i", "$name", "mm", "-acp"]
40+ }
41+ }
42+ }
43+
44+ Use the absolute path of sbx as "command" if the editor cannot find it
45+ (\`which sbx\` on the host). To change the configuration file for one
46+ session, add "-e", "AGENT_CONFIG=/path/in/workspace/agent.yaml" before
47+ "$name" in "args". Full guide: docker-sbx-v3/README.md
48+
49+ You are now in a shell inside the sandbox. \`mm agent.yaml\` works here too.
50+
51+INFO
52+exec bash -l
new file mode 100644
@@ -0,0 +1,52 @@
1+#!/bin/bash
2+# Entry point of the mm-acp sandbox kit (docker-sbx-v3/kits/mm-acp).
3+#
4+# An editor never runs this script. It reaches mm with
5+#
6+# sbx exec -i <sandbox> mm -acp
7+#
8+# because an ACP client needs raw stdin/stdout and `sbx run` always allocates
9+# a terminal. So attaching to this sandbox with `sbx run` prints the wiring
10+# for the editor, with this sandbox's real name and paths, then opens a shell.
11+set -u
12+
13+name="${SANDBOX_NAME:-$(hostname)}"
14+workspace="${WORKSPACE_DIR:-$PWD}"
15+config="${AGENT_CONFIG:-}"
16+if [ -z "$config" ]; then
17+ config_note="none set — mm reads ./agent.yaml in the workspace, then its built-in defaults"
18+elif [ "${config#/}" = "$config" ]; then
19+ config_note="$config (relative to the workspace: ${workspace%/}/$config)"
20+else
21+ config_note="$config"
22+fi
23+
24+cat <<INFO
25+
26+ mm $(mm --version 2>/dev/null | awk '{print $2}') in sandbox "$name"
27+ workspace : $workspace
28+ config : $config_note
29+
30+ This sandbox is meant for an editor (Agent Client Protocol). Register it in
31+ Zed's settings.json — the editor starts mm inside the sandbox on every
32+ conversation, and sbx starts the sandbox first when it is stopped:
33+
34+ {
35+ "agent_servers": {
36+ "mini-me (sandbox)": {
37+ "type": "custom",
38+ "command": "sbx",
39+ "args": ["exec", "-i", "$name", "mm", "-acp"]
40+ }
41+ }
42+ }
43+
44+ Use the absolute path of sbx as "command" if the editor cannot find it
45+ (\`which sbx\` on the host). To change the configuration file for one
46+ session, add "-e", "AGENT_CONFIG=/path/in/workspace/agent.yaml" before
47+ "$name" in "args". Full guide: docker-sbx-v3/README.md
48+
49+ You are now in a shell inside the sandbox. \`mm agent.yaml\` works here too.
50+
51+INFO
52+exec bash -l
added docker-sbx-v3/template/mm-tui +11 -0
new file mode 100644
@@ -0,0 +1,11 @@
1+#!/bin/bash
2+# Entry point of the mm-tui sandbox kit (docker-sbx-v3/kits/mm-tui).
3+#
4+# `sbx run` forwards whatever follows "--" as this script's arguments, so
5+#
6+# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
7+#
8+# runs `mm -tui agent.dmr.yaml` in the workspace. Without an argument mm reads
9+# $AGENT_CONFIG (the kit's `config` argument), then ./agent.yaml, then its
10+# built-in defaults. Flags pass through too: `-- -config other.yaml`.
11+exec mm -tui "$@"
new file mode 100644
@@ -0,0 +1,11 @@
1+#!/bin/bash
2+# Entry point of the mm-tui sandbox kit (docker-sbx-v3/kits/mm-tui).
3+#
4+# `sbx run` forwards whatever follows "--" as this script's arguments, so
5+#
6+# sbx run ./docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
7+#
8+# runs `mm -tui agent.dmr.yaml` in the workspace. Without an argument mm reads
9+# $AGENT_CONFIG (the kit's `config` argument), then ./agent.yaml, then its
10+# built-in defaults. Flags pass through too: `-- -config other.yaml`.
11+exec mm -tui "$@"
added docker-sbx/kits/mm-acp/spec.yaml +69 -0
new file mode 100644
@@ -0,0 +1,69 @@
1+# Docker Sandboxes kit: mm as an editor's agent (Agent Client Protocol), inside
2+# the mm sandbox template.
3+#
4+# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version>
5+# sbx create --pull never --name mm-acp ./docker-sbx/kits/mm-acp . \
6+# --kit-arg config=agent.dmr.yaml
7+#
8+# then, in the editor (Zed settings.json):
9+#
10+# "agent_servers": { "mini-me (sandbox)": { "type": "custom",
11+# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } }
12+#
13+# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the
14+# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the
15+# sandbox is created without attaching, and the editor starts `mm -acp` inside
16+# it for every conversation (sbx starts a stopped sandbox first). Attaching
17+# with `sbx run` runs the entry point below, which prints this wiring with the
18+# sandbox's real name and opens a shell.
19+schemaVersion: "2"
20+kind: sandbox
21+name: mm-acp
22+displayName: Mini Me (editor, ACP)
23+description: >
24+ Holds mm, a minimal coding agent for local LLMs, for an editor that speaks
25+ the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox>
26+ mm -acp`; every command and file edit the model asks for happens inside the
27+ sandbox, on the mounted workspace. The model server stays on the host,
28+ reached through host.docker.internal.
29+# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the
30+# vnd.docker.sandbox.kit.version annotation of the published kit.
31+version: "0.2.1"
32+sourceURL: https://git.rickub.com/bots-garden/mini-me
33+
34+args:
35+ tag:
36+ default: "0.2.1"
37+ description: >-
38+ Tag of the k33g/mm-sandbox image: mm's version without the "v", as
39+ docker-sbx/build.sh tags it (and rewrites this default to).
40+ pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$'
41+ config:
42+ default: ""
43+ description: >-
44+ Configuration file mm reads (its AGENT_CONFIG): an absolute path inside
45+ the sandbox, or a path relative to the workspace, which is where
46+ `sbx exec` starts mm. Empty: ./agent.yaml in the workspace, then the
47+ built-in defaults.
48+
49+sandbox:
50+ image: "k33g/mm-sandbox:${{ kit.args.tag }}"
51+ # Not `mm -acp`: nothing useful comes of speaking JSON-RPC to a terminal.
52+ entrypoint: [mm-acp-info]
53+
54+environment:
55+ variables:
56+ # Baked into the container, so `sbx exec` inherits it and the editor's
57+ # settings need not repeat the path. `sbx exec -e AGENT_CONFIG=…` overrides
58+ # it for one session.
59+ AGENT_CONFIG: "${{ kit.args.config }}"
60+ LANG: C.UTF-8
61+
62+# The model server on the host — see docker-sbx/kits/mm-tui/spec.yaml.
63+permissions:
64+ network:
65+ allow:
66+ - "host.docker.internal:12434"
67+ - "localhost:12434"
68+ - "host.docker.internal:8080"
69+ - "localhost:8080"
new file mode 100644
@@ -0,0 +1,69 @@
1+# Docker Sandboxes kit: mm as an editor's agent (Agent Client Protocol), inside
2+# the mm sandbox template.
3+#
4+# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version>
5+# sbx create --pull never --name mm-acp ./docker-sbx/kits/mm-acp . \
6+# --kit-arg config=agent.dmr.yaml
7+#
8+# then, in the editor (Zed settings.json):
9+#
10+# "agent_servers": { "mini-me (sandbox)": { "type": "custom",
11+# "command": "sbx", "args": ["exec", "-i", "mm-acp", "mm", "-acp"] } }
12+#
13+# Why `sbx exec -i` and not `sbx run`: an ACP client speaks JSON-RPC on the
14+# agent's raw stdin/stdout, and `sbx run` always allocates a terminal. So the
15+# sandbox is created without attaching, and the editor starts `mm -acp` inside
16+# it for every conversation (sbx starts a stopped sandbox first). Attaching
17+# with `sbx run` runs the entry point below, which prints this wiring with the
18+# sandbox's real name and opens a shell.
19+schemaVersion: "2"
20+kind: sandbox
21+name: mm-acp
22+displayName: Mini Me (editor, ACP)
23+description: >
24+ Holds mm, a minimal coding agent for local LLMs, for an editor that speaks
25+ the Agent Client Protocol (Zed, …). The editor runs `sbx exec -i <sandbox>
26+ mm -acp`; every command and file edit the model asks for happens inside the
27+ sandbox, on the mounted workspace. The model server stays on the host,
28+ reached through host.docker.internal.
29+# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the
30+# vnd.docker.sandbox.kit.version annotation of the published kit.
31+version: "0.2.1"
32+sourceURL: https://git.rickub.com/bots-garden/mini-me
33+
34+args:
35+ tag:
36+ default: "0.2.1"
37+ description: >-
38+ Tag of the k33g/mm-sandbox image: mm's version without the "v", as
39+ docker-sbx/build.sh tags it (and rewrites this default to).
40+ pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$'
41+ config:
42+ default: ""
43+ description: >-
44+ Configuration file mm reads (its AGENT_CONFIG): an absolute path inside
45+ the sandbox, or a path relative to the workspace, which is where
46+ `sbx exec` starts mm. Empty: ./agent.yaml in the workspace, then the
47+ built-in defaults.
48+
49+sandbox:
50+ image: "k33g/mm-sandbox:${{ kit.args.tag }}"
51+ # Not `mm -acp`: nothing useful comes of speaking JSON-RPC to a terminal.
52+ entrypoint: [mm-acp-info]
53+
54+environment:
55+ variables:
56+ # Baked into the container, so `sbx exec` inherits it and the editor's
57+ # settings need not repeat the path. `sbx exec -e AGENT_CONFIG=…` overrides
58+ # it for one session.
59+ AGENT_CONFIG: "${{ kit.args.config }}"
60+ LANG: C.UTF-8
61+
62+# The model server on the host — see docker-sbx/kits/mm-tui/spec.yaml.
63+permissions:
64+ network:
65+ allow:
66+ - "host.docker.internal:12434"
67+ - "localhost:12434"
68+ - "host.docker.internal:8080"
69+ - "localhost:8080"
added docker-sbx/kits/mm-tui/spec.yaml +68 -0
new file mode 100644
@@ -0,0 +1,68 @@
1+# Docker Sandboxes kit: mm in its window mode, inside the mm sandbox template.
2+#
3+# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version>
4+# sbx run --pull never ./docker-sbx/kits/mm-tui . -- agent.dmr.yaml
5+#
6+# What follows "--" reaches mm as its own arguments (here the configuration
7+# file, relative to the workspace). Without it, the `config` argument below is
8+# read, then ./agent.yaml, then the built-in defaults:
9+#
10+# sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml
11+#
12+# --pull never: the image is built locally; drop it once it is pushed.
13+schemaVersion: "2"
14+kind: sandbox
15+name: mm-tui
16+displayName: Mini Me (window mode)
17+description: >
18+ Runs mm, a minimal coding agent for local LLMs, in its single-window terminal
19+ mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or
20+ llama-server) stays on the host: inside the sandbox `localhost` is the sandbox
21+ itself, so the configuration file must reach the host through
22+ host.docker.internal — agent.dmr.yaml already falls back to it.
23+# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the
24+# vnd.docker.sandbox.kit.version annotation of the published kit.
25+version: "0.2.1"
26+sourceURL: https://git.rickub.com/bots-garden/mini-me
27+
28+args:
29+ tag:
30+ default: "0.2.1"
31+ description: >-
32+ Tag of the k33g/mm-sandbox image: mm's version without the "v", as
33+ docker-sbx/build.sh tags it (and rewrites this default to).
34+ pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$'
35+ config:
36+ default: ""
37+ description: >-
38+ Configuration file mm reads (its AGENT_CONFIG): an absolute path inside
39+ the sandbox, or a path relative to the workspace. Empty: ./agent.yaml in
40+ the workspace, then the built-in defaults.
41+
42+sandbox:
43+ image: "k33g/mm-sandbox:${{ kit.args.tag }}"
44+ # A wrapper, not `mm -tui` directly: the start script drops the fixed
45+ # options when the first user argument is not a flag, so `-- agent.yaml`
46+ # would otherwise lose -tui. The wrapper always adds it.
47+ entrypoint: [mm-tui]
48+
49+environment:
50+ variables:
51+ AGENT_CONFIG: "${{ kit.args.config }}"
52+ # tcell needs a terminal type and a UTF-8 locale to draw the window.
53+ TERM: xterm-256color
54+ COLORTERM: truecolor
55+ LANG: C.UTF-8
56+
57+# The model server on the host. Requests leave the sandbox through its proxy,
58+# which maps host.docker.internal to the host's localhost; both spellings are
59+# listed so the rule matches whichever one the policy is checked against.
60+# 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own
61+# port with `sbx policy allow network host.docker.internal:<port>`.
62+permissions:
63+ network:
64+ allow:
65+ - "host.docker.internal:12434"
66+ - "localhost:12434"
67+ - "host.docker.internal:8080"
68+ - "localhost:8080"
new file mode 100644
@@ -0,0 +1,68 @@
1+# Docker Sandboxes kit: mm in its window mode, inside the mm sandbox template.
2+#
3+# ./docker-sbx/build.sh # once: k33g/mm-sandbox:<version>
4+# sbx run --pull never ./docker-sbx/kits/mm-tui . -- agent.dmr.yaml
5+#
6+# What follows "--" reaches mm as its own arguments (here the configuration
7+# file, relative to the workspace). Without it, the `config` argument below is
8+# read, then ./agent.yaml, then the built-in defaults:
9+#
10+# sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml
11+#
12+# --pull never: the image is built locally; drop it once it is pushed.
13+schemaVersion: "2"
14+kind: sandbox
15+name: mm-tui
16+displayName: Mini Me (window mode)
17+description: >
18+ Runs mm, a minimal coding agent for local LLMs, in its single-window terminal
19+ mode (`mm -tui`) on the workspace. The model server (Docker Model Runner or
20+ llama-server) stays on the host: inside the sandbox `localhost` is the sandbox
21+ itself, so the configuration file must reach the host through
22+ host.docker.internal — agent.dmr.yaml already falls back to it.
23+# Kept equal to the image tag by docker-sbx/sync-kits.sh; becomes the
24+# vnd.docker.sandbox.kit.version annotation of the published kit.
25+version: "0.2.1"
26+sourceURL: https://git.rickub.com/bots-garden/mini-me
27+
28+args:
29+ tag:
30+ default: "0.2.1"
31+ description: >-
32+ Tag of the k33g/mm-sandbox image: mm's version without the "v", as
33+ docker-sbx/build.sh tags it (and rewrites this default to).
34+ pattern: '^[A-Za-z0-9_][A-Za-z0-9_.-]{0,127}$'
35+ config:
36+ default: ""
37+ description: >-
38+ Configuration file mm reads (its AGENT_CONFIG): an absolute path inside
39+ the sandbox, or a path relative to the workspace. Empty: ./agent.yaml in
40+ the workspace, then the built-in defaults.
41+
42+sandbox:
43+ image: "k33g/mm-sandbox:${{ kit.args.tag }}"
44+ # A wrapper, not `mm -tui` directly: the start script drops the fixed
45+ # options when the first user argument is not a flag, so `-- agent.yaml`
46+ # would otherwise lose -tui. The wrapper always adds it.
47+ entrypoint: [mm-tui]
48+
49+environment:
50+ variables:
51+ AGENT_CONFIG: "${{ kit.args.config }}"
52+ # tcell needs a terminal type and a UTF-8 locale to draw the window.
53+ TERM: xterm-256color
54+ COLORTERM: truecolor
55+ LANG: C.UTF-8
56+
57+# The model server on the host. Requests leave the sandbox through its proxy,
58+# which maps host.docker.internal to the host's localhost; both spellings are
59+# listed so the rule matches whichever one the policy is checked against.
60+# 12434 is Docker Model Runner, 8080 is llama-server's default. Add your own
61+# port with `sbx policy allow network host.docker.internal:<port>`.
62+permissions:
63+ network:
64+ allow:
65+ - "host.docker.internal:12434"
66+ - "localhost:12434"
67+ - "host.docker.internal:8080"
68+ - "localhost:8080"
modified docs/en/README.md +1 -0
@@ -13,6 +13,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
1313 - [Run mini-me on llama.cpp instead of Docker Model Runner](how-to/run-with-llama-cpp.md)
1414 - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md)
1515 - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the template and the two kits under `docker-sbx/`, window mode and editor
16+- [Run mini-me with the v3 sandbox kits](how-to/run-with-sandbox-kits-v3.md) — the same two kits for the kit specification v3, under `docker-sbx-v3/`
1617 - [Add a skill](how-to/add-a-skill.md)
1718 - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after
1819 - [Keep a long session inside the context window](how-to/manage-the-context-window.md)
@@ -13,6 +13,7 @@ This documentation is organised along the four [Diátaxis](https://diataxis.fr)
13 - [Run mini-me on llama.cpp instead of Docker Model Runner](how-to/run-with-llama-cpp.md)13 - [Run mini-me on llama.cpp instead of Docker Model Runner](how-to/run-with-llama-cpp.md)
14 - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md)14 - [Use mini-me from an editor (ACP)](how-to/use-from-an-editor.md)
15 - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the template and the two kits under `docker-sbx/`, window mode and editor15 - [Run mini-me in a Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — the template and the two kits under `docker-sbx/`, window mode and editor
16+- [Run mini-me with the v3 sandbox kits](how-to/run-with-sandbox-kits-v3.md) — the same two kits for the kit specification v3, under `docker-sbx-v3/`
16 - [Add a skill](how-to/add-a-skill.md)17 - [Add a skill](how-to/add-a-skill.md)
17 - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after18 - [Measure whether the model picks the right skill](how-to/measure-skill-routing.md) — the routing eval: run it, read its table, use it as a before-and-after
18 - [Keep a long session inside the context window](how-to/manage-the-context-window.md)19 - [Keep a long session inside the context window](how-to/manage-the-context-window.md)
modified docs/en/how-to/run-in-a-docker-sandbox.md +12 -9
@@ -2,6 +2,8 @@
22
33 This guide shows how to run `mm` inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), so that every command the model runs and every file it edits happens in a container, on a mounted copy of your project. It covers the two ways of using it: the window mode in your terminal, and from an editor through the Agent Client Protocol. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine.
44
5+> These are the **v2** kits (`spec.yaml`). The same two kits also exist for the kit specification v3, under `docker-sbx-v3/`: see [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md).
6+
57 Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the repository:
68
79 | Piece | What it is |
@@ -14,20 +16,20 @@ Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the rep
1416
1517 ## Use the published kits
1618
17-Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`:
19+Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`:
1820
1921 ```bash
2022 cd /path/to/your/project
21-sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml
23+sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml
2224 ```
2325
2426 for the window mode, and for an editor:
2527
2628 ```bash
27-sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml
29+sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
2830 ```
2931
30-then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.1.7` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.1.7` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm.
32+then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.2.1` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.2.1` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm.
3133
3234 ## Steps
3335
@@ -39,9 +41,9 @@ From the repository root:
3941 ./docker-sbx/build.sh
4042 ```
4143
42-This reads mm's tag from `release.env` (`v0.1.7`) and builds `k33g/mm-sandbox:0.1.7`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.1.7`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`.
44+This reads mm's tag from `release.env` (`v0.2.1`) and builds `k33g/mm-sandbox:0.2.1`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.2.1`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`.
4345
44-The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.1.7`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.1.7.tar`, to load there with `sbx template load`.
46+The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.2.1`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.2.1.tar`, to load there with `sbx template load`.
4547
4648 ### 2. Window mode in the terminal (kit `mm-tui`)
4749
@@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml
6264 | `--kit-arg` | Default | Effect |
6365 |---|---|---|
6466 | `config=<path>` | empty | The configuration file, as `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. |
65-| `tag=<version>` | the version last built (`0.1.7`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. |
67+| `tag=<version>` | the version last built (`0.2.1`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. |
6668
6769 The sandbox keeps its name (`mm-tui-<directory>` unless you pass `--name`); `sbx run --name <name>` re-attaches to it later. Inside, the window is the one described in [Use the window mode](use-the-window-mode.md). Sessions, when `sessions.enabled` is on, are written under the workspace's `.mm/sessions` — that is your host directory, so they survive the sandbox.
6870
@@ -118,10 +120,10 @@ Publishing is a manual step, from a machine with Docker Desktop (buildx and the
118120 ```bash
119121 export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner
120122 export DOCKER_PAT=dckr_pat_… # an access token with read/write scope
121-./docker-sbx/publish.sh # TAG from release.env: v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7
123+./docker-sbx/publish.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1
122124 ```
123125
124-With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.1.7` (image) and `./docker-sbx/push-kits.sh v0.1.7` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account.
126+With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.2.1` (image) and `./docker-sbx/push-kits.sh v0.2.1` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account.
125127
126128 ## MCP servers through the sbx gateway (GitHub as the example)
127129
@@ -175,5 +177,6 @@ Name the repository in your requests, for example "list the open issues of k33g/
175177 ## See also
176178
177179 - The kit format these two files follow: the Docker Sandboxes kit specification (`schemaVersion: "2"`), bundled with the `sbx` sources.
180+- The same kits for the kit specification v3: [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md).
178181 - What `mm -acp` exposes to the editor: [ACP reference](../reference/acp.md).
179182 - The flags and environment variables `mm` reads: [command line reference](../reference/cli.md).
@@ -2,6 +2,8 @@
2 2
3 This guide shows how to run `mm` inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), so that every command the model runs and every file it edits happens in a container, on a mounted copy of your project. It covers the two ways of using it: the window mode in your terminal, and from an editor through the Agent Client Protocol. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine.3 This guide shows how to run `mm` inside a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), so that every command the model runs and every file it edits happens in a container, on a mounted copy of your project. It covers the two ways of using it: the window mode in your terminal, and from an editor through the Agent Client Protocol. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine.
4 4
5+> These are the **v2** kits (`spec.yaml`). The same two kits also exist for the kit specification v3, under `docker-sbx-v3/`: see [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md).
6+
5 Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the repository:7 Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the repository:
6 8
7 | Piece | What it is |9 | Piece | What it is |
@@ -14,20 +16,20 @@ Everything lives under [`docker-sbx/`](../../../docker-sbx/README.md) in the rep
14 16
15 ## Use the published kits17 ## Use the published kits
16 18
17-Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`:19+Every release publishes the image and both kits to Docker Hub at mm's version — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — so the shortest path needs no build at all. Docker Hub is an allowed kit source by default (`sbx settings get kit.allowedSources` shows `docker.io/`), and a reference with a `/` but no registry host is read as `docker.io/…`:
18 20
19 ```bash21 ```bash
20 cd /path/to/your/project22 cd /path/to/your/project
21-sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml23+sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml
22 ```24 ```
23 25
24 for the window mode, and for an editor:26 for the window mode, and for an editor:
25 27
26 ```bash28 ```bash
27-sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml29+sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
28 ```30 ```
29 31
30-then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.1.7` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.1.7` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm.32+then the editor registration of step 3 below. No `--pull never`: the kit names `k33g/mm-sandbox:0.2.1` and sbx pulls it. `sbx kit inspect k33g/mm-tui:0.2.1` shows what a kit declares before you run it. The steps that follow build the same thing locally, for a work-in-progress mm.
31 33
32 ## Steps34 ## Steps
33 35
@@ -39,9 +41,9 @@ From the repository root:
39 ./docker-sbx/build.sh41 ./docker-sbx/build.sh
40 ```42 ```
41 43
42-This reads mm's tag from `release.env` (`v0.1.7`) and builds `k33g/mm-sandbox:0.1.7`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.1.7`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`.44+This reads mm's tag from `release.env` (`v0.2.1`) and builds `k33g/mm-sandbox:0.2.1`: the image tag is the version without the `v`, like the release assets, and `mm` inside is stamped with the tag — `mm --version` is run in the image as proof. The script then rewrites the kits' default `tag` argument to `0.2.1`, so the kits and the image move together. `./docker-sbx/build.sh v0.1.5` builds another version; an earlier image stays reachable with `--kit-arg tag=0.1.4`.
43 45
44-The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.1.7`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.1.7.tar`, to load there with `sbx template load`.46+The image is in your local Docker image store: every `sbx run` or `sbx create` on these kits takes `--pull never` until the image is pushed (`docker push k33g/mm-sandbox:0.2.1`), or `sbx` tries to pull it and fails. If `sbx` runs on another machine, `EXPORT=1 ./docker-sbx/build.sh` also writes `tmp/mm-sandbox-0.2.1.tar`, to load there with `sbx template load`.
45 47
46 ### 2. Window mode in the terminal (kit `mm-tui`)48 ### 2. Window mode in the terminal (kit `mm-tui`)
47 49
@@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml
62 | `--kit-arg` | Default | Effect |64 | `--kit-arg` | Default | Effect |
63 |---|---|---|65 |---|---|---|
64 | `config=<path>` | empty | The configuration file, as `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. |66 | `config=<path>` | empty | The configuration file, as `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. |
65-| `tag=<version>` | the version last built (`0.1.7`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. |67+| `tag=<version>` | the version last built (`0.2.1`) | Which `k33g/mm-sandbox:<version>` image the sandbox is made from. |
66 68
67 The sandbox keeps its name (`mm-tui-<directory>` unless you pass `--name`); `sbx run --name <name>` re-attaches to it later. Inside, the window is the one described in [Use the window mode](use-the-window-mode.md). Sessions, when `sessions.enabled` is on, are written under the workspace's `.mm/sessions` — that is your host directory, so they survive the sandbox.69 The sandbox keeps its name (`mm-tui-<directory>` unless you pass `--name`); `sbx run --name <name>` re-attaches to it later. Inside, the window is the one described in [Use the window mode](use-the-window-mode.md). Sessions, when `sessions.enabled` is on, are written under the workspace's `.mm/sessions` — that is your host directory, so they survive the sandbox.
68 70
@@ -118,10 +120,10 @@ Publishing is a manual step, from a machine with Docker Desktop (buildx and the
118 ```bash120 ```bash
119 export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner121 export DOCKER_HANDLE=k33g # the Docker Hub account, also the image owner
120 export DOCKER_PAT=dckr_pat_… # an access token with read/write scope122 export DOCKER_PAT=dckr_pat_… # an access token with read/write scope
121-./docker-sbx/publish.sh # TAG from release.env: v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7123+./docker-sbx/publish.sh # TAG from release.env: v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1
122 ```124 ```
123 125
124-With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.1.7` (image) and `./docker-sbx/push-kits.sh v0.1.7` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account.126+With both variables set, the script logs in with them and logs out when it is done; with neither, it reuses your existing `docker login`. Its two halves run alone as `PUSH=1 ./docker-sbx/build.sh v0.2.1` (image) and `./docker-sbx/push-kits.sh v0.2.1` (kits, `SBX=/path/to/sbx` if the CLI is not on the PATH). Both call `sync-kits.sh` first, which rewrites the kits' `version`, default `tag` and image owner, so a published kit always names the image pushed with it — commit the two `spec.yaml` afterwards. `sbx kit push` talks to the registry directly and authenticates from the Docker credential store, no sandbox daemon involved. `IMAGE_OWNER=<handle>` publishes under another account.
125 127
126 ## MCP servers through the sbx gateway (GitHub as the example)128 ## MCP servers through the sbx gateway (GitHub as the example)
127 129
@@ -175,5 +177,6 @@ Name the repository in your requests, for example "list the open issues of k33g/
175 ## See also177 ## See also
176 178
177 - The kit format these two files follow: the Docker Sandboxes kit specification (`schemaVersion: "2"`), bundled with the `sbx` sources.179 - The kit format these two files follow: the Docker Sandboxes kit specification (`schemaVersion: "2"`), bundled with the `sbx` sources.
180+- The same kits for the kit specification v3: [Run mini-me with the v3 sandbox kits](run-with-sandbox-kits-v3.md).
178 - What `mm -acp` exposes to the editor: [ACP reference](../reference/acp.md).181 - What `mm -acp` exposes to the editor: [ACP reference](../reference/acp.md).
179 - The flags and environment variables `mm` reads: [command line reference](../reference/cli.md).182 - The flags and environment variables `mm` reads: [command line reference](../reference/cli.md).
added docs/en/how-to/run-with-sandbox-kits-v3.md +111 -0
new file mode 100644
@@ -0,0 +1,111 @@
1+# How to run mini-me with the v3 sandbox kits
2+
3+This guide shows how to run `mm` in a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) with the kits written for the [kit specification v3](https://github.com/docker/sandbox-kit-spec), under [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). They do the same job as the v2 kits of [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md) — the window mode with `mm-tui`, an editor with `mm-acp` — and the v2 kits keep working beside them. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine.
4+
5+> **Status.** The v3 kits build with the `docker/sandbox-kit:3` frontend and pass the specification's conformance check (`kit-tck validate`), but they have not yet been run with `sbx`, and they are not published yet. The kit specification itself is still marked experimental.
6+
7+| Piece | What it is |
8+|---|---|
9+| `template/Dockerfile` | The **template** image, `k33g/mm-sandbox:<version>` — the same image as v2. |
10+| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | The window-mode kit: a descriptor (declarations) and a Dockerfile (content: `FROM` the template, `ENTRYPOINT ["mm-tui"]`). |
11+| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | The editor kit, same shape, `ENTRYPOINT ["mm-acp-info"]`. |
12+| `build.sh`, `sync-kits.sh` | Build the template, and point the kits at it. |
13+| `check-kits.sh` | Builds the kits locally and checks them, with no `sbx` and no push. |
14+| `push-kits.sh`, `publish.sh` | Publish the kits (and the template) to Docker Hub with `docker buildx`. |
15+
16+## Before you start: two differences with v2
17+
18+- **The template image must be on a registry.** A v3 kit is *built* on top of the template. When you run a kit from its directory, `sbx` builds it in its builder sandbox, and that sandbox's Docker engine pulls the template from the registry. An image that exists only in your local image store is not enough, and `--pull never` or `sbx template load` do not help. `k33g/mm-sandbox:0.2.1` is already on Docker Hub; for another version, push it first (step 1).
19+- **The workspace is `/home/agent/workspace`.** The template's base image declares that working directory, and a v3 agent workload (`sbx@1`) is mounted there. Give `config` a path relative to the workspace (`agent.dmr.yaml`, `demo/agent.dmr.yaml`); an absolute path of your Mac (`/Users/…`) does not exist inside the sandbox.
20+
21+## Steps
22+
23+### 1. Make the template available
24+
25+For the version in `release.env` (`v0.2.1`), nothing to do: `k33g/mm-sandbox:0.2.1` is on Docker Hub. For a work-in-progress `mm`, build and push the template from the repository root:
26+
27+```bash
28+PUSH=1 ./docker-sbx-v3/build.sh v0.2.2
29+```
30+
31+The script builds `k33g/mm-sandbox:0.2.2` for linux/amd64 and linux/arm64, pushes it, then rewrites the kits' `image` and `tag` defaults so they name that image. `IMAGE_OWNER=<handle>` pushes under your own account instead.
32+
33+### 2. Check the kits (optional)
34+
35+```bash
36+./docker-sbx-v3/check-kits.sh
37+```
38+
39+Each kit is built with `docker buildx build -f <kit>.yaml`, which runs the kit frontend: it refuses an unknown key or an argument that does not match its pattern. The result goes to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (`go build ./cmd/kit-tck` in a clone of the specification), the script also runs the conformance check and prints `✓ conforms`.
40+
41+### 3. Window mode in the terminal (kit `mm-tui`)
42+
43+From the project you want `mm` to work on:
44+
45+```bash
46+cd /path/to/your/project
47+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
48+```
49+
50+The first run builds the kit (a few seconds: one layer over the template), creates the sandbox, mounts the current directory and runs `mm -tui agent.dmr.yaml`. What follows `--` is `mm`'s own command line. Without it, `mm` reads the kit's `config` argument, then `./agent.yaml`, then its built-in defaults:
51+
52+```bash
53+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml
54+```
55+
56+### 4. From an editor (kit `mm-acp`)
57+
58+1. Create the sandbox once, from the project the editor will open:
59+
60+ ```bash
61+ cd /path/to/your/project
62+ sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . \
63+ --kit-arg config=agent.dmr.yaml
64+ ```
65+
66+2. Register it in the editor. In Zed's `settings.json`:
67+
68+ ```json
69+ {
70+ "agent_servers": {
71+ "mini-me (sandbox)": {
72+ "type": "custom",
73+ "command": "sbx",
74+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
75+ }
76+ }
77+ }
78+ ```
79+
80+3. Open the agent panel and pick **mini-me (sandbox)**. As with v2, the editor runs `sbx exec -i`, because an ACP client needs raw stdin and stdout and `sbx run` always allocates a terminal. `sbx run --name mm-acp` prints this wiring and opens a shell.
81+
82+### 5. Once the kits are published
83+
84+After `./docker-sbx-v3/publish.sh` (or `push-kits.sh`) has run for a version, the kits are ordinary images on Docker Hub, and no directory is needed:
85+
86+```bash
87+sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml
88+sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
89+```
90+
91+The repositories are `sbx-kit-<kit>`, not the v2 `k33g/mm-tui` / `k33g/mm-acp`, so that publishing a v3 kit never replaces a v2 one.
92+
93+## Kit arguments
94+
95+| `--kit-arg` | Default | When it applies | Effect |
96+|---|---|---|---|
97+| `config=<path>` | empty | at `sbx run` / `sbx create` | `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. |
98+| `tag=<version>` | mm's version (`0.2.1`) | when the kit is built | Which template tag the kit is built on; also the kit's version. No `v`. |
99+| `image=<repository>` | `k33g/mm-sandbox` | when the kit is built | Which template repository the kit is built on. |
100+
101+`tag` and `image` are build-phase arguments: they are fixed in a published kit, which always names the image it was built on. To use another `mm` version, take the kit of that version.
102+
103+## The model server stays on the host
104+
105+Unchanged from v2: Docker Model Runner and llama-server run on your machine and are reached through `host.docker.internal`. `agent.dmr.yaml` already falls back to it; for llama-server see [the v2 guide](run-in-a-docker-sandbox.md#the-model-server-stays-on-the-host). Both kits allow ports 12434 and 8080 on the host; for another port, `sbx policy allow network host.docker.internal:<port>`.
106+
107+## See also
108+
109+- What changed from the v2 kits, field by field: [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md).
110+- The v2 kits, the MCP gateway and the editor variants: [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md).
111+- The kit format: [specification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md).
new file mode 100644
@@ -0,0 +1,111 @@
1+# How to run mini-me with the v3 sandbox kits
2+
3+This guide shows how to run `mm` in a [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) with the kits written for the [kit specification v3](https://github.com/docker/sandbox-kit-spec), under [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). They do the same job as the v2 kits of [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md) — the window mode with `mm-tui`, an editor with `mm-acp` — and the v2 kits keep working beside them. It assumes Docker Desktop with the `sbx` command, and a model server (Docker Model Runner or llama-server) running on your machine.
4+
5+> **Status.** The v3 kits build with the `docker/sandbox-kit:3` frontend and pass the specification's conformance check (`kit-tck validate`), but they have not yet been run with `sbx`, and they are not published yet. The kit specification itself is still marked experimental.
6+
7+| Piece | What it is |
8+|---|---|
9+| `template/Dockerfile` | The **template** image, `k33g/mm-sandbox:<version>` — the same image as v2. |
10+| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | The window-mode kit: a descriptor (declarations) and a Dockerfile (content: `FROM` the template, `ENTRYPOINT ["mm-tui"]`). |
11+| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | The editor kit, same shape, `ENTRYPOINT ["mm-acp-info"]`. |
12+| `build.sh`, `sync-kits.sh` | Build the template, and point the kits at it. |
13+| `check-kits.sh` | Builds the kits locally and checks them, with no `sbx` and no push. |
14+| `push-kits.sh`, `publish.sh` | Publish the kits (and the template) to Docker Hub with `docker buildx`. |
15+
16+## Before you start: two differences with v2
17+
18+- **The template image must be on a registry.** A v3 kit is *built* on top of the template. When you run a kit from its directory, `sbx` builds it in its builder sandbox, and that sandbox's Docker engine pulls the template from the registry. An image that exists only in your local image store is not enough, and `--pull never` or `sbx template load` do not help. `k33g/mm-sandbox:0.2.1` is already on Docker Hub; for another version, push it first (step 1).
19+- **The workspace is `/home/agent/workspace`.** The template's base image declares that working directory, and a v3 agent workload (`sbx@1`) is mounted there. Give `config` a path relative to the workspace (`agent.dmr.yaml`, `demo/agent.dmr.yaml`); an absolute path of your Mac (`/Users/…`) does not exist inside the sandbox.
20+
21+## Steps
22+
23+### 1. Make the template available
24+
25+For the version in `release.env` (`v0.2.1`), nothing to do: `k33g/mm-sandbox:0.2.1` is on Docker Hub. For a work-in-progress `mm`, build and push the template from the repository root:
26+
27+```bash
28+PUSH=1 ./docker-sbx-v3/build.sh v0.2.2
29+```
30+
31+The script builds `k33g/mm-sandbox:0.2.2` for linux/amd64 and linux/arm64, pushes it, then rewrites the kits' `image` and `tag` defaults so they name that image. `IMAGE_OWNER=<handle>` pushes under your own account instead.
32+
33+### 2. Check the kits (optional)
34+
35+```bash
36+./docker-sbx-v3/check-kits.sh
37+```
38+
39+Each kit is built with `docker buildx build -f <kit>.yaml`, which runs the kit frontend: it refuses an unknown key or an argument that does not match its pattern. The result goes to `tmp/kits-v3/<kit>/`. With [`kit-tck`](https://github.com/docker/sandbox-kit-spec) on the `PATH` (`go build ./cmd/kit-tck` in a clone of the specification), the script also runs the conformance check and prints `✓ conforms`.
40+
41+### 3. Window mode in the terminal (kit `mm-tui`)
42+
43+From the project you want `mm` to work on:
44+
45+```bash
46+cd /path/to/your/project
47+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
48+```
49+
50+The first run builds the kit (a few seconds: one layer over the template), creates the sandbox, mounts the current directory and runs `mm -tui agent.dmr.yaml`. What follows `--` is `mm`'s own command line. Without it, `mm` reads the kit's `config` argument, then `./agent.yaml`, then its built-in defaults:
51+
52+```bash
53+sbx run /path/to/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml
54+```
55+
56+### 4. From an editor (kit `mm-acp`)
57+
58+1. Create the sandbox once, from the project the editor will open:
59+
60+ ```bash
61+ cd /path/to/your/project
62+ sbx create --name mm-acp /path/to/mini-me/docker-sbx-v3/kits/mm-acp . \
63+ --kit-arg config=agent.dmr.yaml
64+ ```
65+
66+2. Register it in the editor. In Zed's `settings.json`:
67+
68+ ```json
69+ {
70+ "agent_servers": {
71+ "mini-me (sandbox)": {
72+ "type": "custom",
73+ "command": "sbx",
74+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
75+ }
76+ }
77+ }
78+ ```
79+
80+3. Open the agent panel and pick **mini-me (sandbox)**. As with v2, the editor runs `sbx exec -i`, because an ACP client needs raw stdin and stdout and `sbx run` always allocates a terminal. `sbx run --name mm-acp` prints this wiring and opens a shell.
81+
82+### 5. Once the kits are published
83+
84+After `./docker-sbx-v3/publish.sh` (or `push-kits.sh`) has run for a version, the kits are ordinary images on Docker Hub, and no directory is needed:
85+
86+```bash
87+sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml
88+sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
89+```
90+
91+The repositories are `sbx-kit-<kit>`, not the v2 `k33g/mm-tui` / `k33g/mm-acp`, so that publishing a v3 kit never replaces a v2 one.
92+
93+## Kit arguments
94+
95+| `--kit-arg` | Default | When it applies | Effect |
96+|---|---|---|---|
97+| `config=<path>` | empty | at `sbx run` / `sbx create` | `mm`'s `AGENT_CONFIG`: relative to the workspace, or absolute inside the sandbox. Empty: `./agent.yaml`, then the built-in defaults. |
98+| `tag=<version>` | mm's version (`0.2.1`) | when the kit is built | Which template tag the kit is built on; also the kit's version. No `v`. |
99+| `image=<repository>` | `k33g/mm-sandbox` | when the kit is built | Which template repository the kit is built on. |
100+
101+`tag` and `image` are build-phase arguments: they are fixed in a published kit, which always names the image it was built on. To use another `mm` version, take the kit of that version.
102+
103+## The model server stays on the host
104+
105+Unchanged from v2: Docker Model Runner and llama-server run on your machine and are reached through `host.docker.internal`. `agent.dmr.yaml` already falls back to it; for llama-server see [the v2 guide](run-in-a-docker-sandbox.md#the-model-server-stays-on-the-host). Both kits allow ports 12434 and 8080 on the host; for another port, `sbx policy allow network host.docker.internal:<port>`.
106+
107+## See also
108+
109+- What changed from the v2 kits, field by field: [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md).
110+- The v2 kits, the MCP gateway and the editor variants: [Run mini-me in a Docker Sandbox](run-in-a-docker-sandbox.md).
111+- The kit format: [specification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md).
modified docs/fr/README.md +1 -0
@@ -13,6 +13,7 @@ Cette documentation est organisée selon les quatre quadrants [Diátaxis](https:
1313 - [Faire tourner mini-me sur llama.cpp plutôt que Docker Model Runner](how-to/run-with-llama-cpp.md)
1414 - [Utiliser mini-me depuis un éditeur (ACP)](how-to/use-from-an-editor.md)
1515 - [Faire tourner mini-me dans un Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — le template et les deux kits sous `docker-sbx/`, mode fenêtre et éditeur
16+- [Faire tourner mini-me avec les kits sandbox v3](how-to/run-with-sandbox-kits-v3.md) — les deux mêmes kits pour la spécification de kit v3, sous `docker-sbx-v3/`
1617 - [Ajouter un skill](how-to/add-a-skill.md)
1718 - [Mesurer si le modèle choisit le bon skill](how-to/measure-skill-routing.md) — l'eval de routage : le lancer, lire son tableau, s'en servir en avant/après
1819 - [Garder une longue session dans la fenêtre de contexte](how-to/manage-the-context-window.md)
@@ -13,6 +13,7 @@ Cette documentation est organisée selon les quatre quadrants [Diátaxis](https:
13 - [Faire tourner mini-me sur llama.cpp plutôt que Docker Model Runner](how-to/run-with-llama-cpp.md)13 - [Faire tourner mini-me sur llama.cpp plutôt que Docker Model Runner](how-to/run-with-llama-cpp.md)
14 - [Utiliser mini-me depuis un éditeur (ACP)](how-to/use-from-an-editor.md)14 - [Utiliser mini-me depuis un éditeur (ACP)](how-to/use-from-an-editor.md)
15 - [Faire tourner mini-me dans un Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — le template et les deux kits sous `docker-sbx/`, mode fenêtre et éditeur15 - [Faire tourner mini-me dans un Docker Sandbox](how-to/run-in-a-docker-sandbox.md) — le template et les deux kits sous `docker-sbx/`, mode fenêtre et éditeur
16+- [Faire tourner mini-me avec les kits sandbox v3](how-to/run-with-sandbox-kits-v3.md) — les deux mêmes kits pour la spécification de kit v3, sous `docker-sbx-v3/`
16 - [Ajouter un skill](how-to/add-a-skill.md)17 - [Ajouter un skill](how-to/add-a-skill.md)
17 - [Mesurer si le modèle choisit le bon skill](how-to/measure-skill-routing.md) — l'eval de routage : le lancer, lire son tableau, s'en servir en avant/après18 - [Mesurer si le modèle choisit le bon skill](how-to/measure-skill-routing.md) — l'eval de routage : le lancer, lire son tableau, s'en servir en avant/après
18 - [Garder une longue session dans la fenêtre de contexte](how-to/manage-the-context-window.md)19 - [Garder une longue session dans la fenêtre de contexte](how-to/manage-the-context-window.md)
modified docs/fr/how-to/run-in-a-docker-sandbox.md +12 -9
@@ -2,6 +2,8 @@
22
33 Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), pour que chaque commande lancée par le modèle et chaque fichier qu'il modifie le soient dans un conteneur, sur votre projet monté. Il couvre les deux usages : le mode fenêtre dans votre terminal, et depuis un éditeur via l'Agent Client Protocol. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine.
44
5+> Ce sont les kits **v2** (`spec.yaml`). Les deux mêmes kits existent aussi pour la spécification de kit v3, sous `docker-sbx-v3/` : voir [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md).
6+
57 Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt :
68
79 | Élément | Ce que c'est |
@@ -14,20 +16,20 @@ Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt :
1416
1517 ## Utiliser les kits publiés
1618
17-Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` :
19+Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` :
1820
1921 ```bash
2022 cd /chemin/de/votre/projet
21-sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml
23+sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml
2224 ```
2325
2426 pour le mode fenêtre, et pour un éditeur :
2527
2628 ```bash
27-sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml
29+sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
2830 ```
2931
30-puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.1.7` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.1.7` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail.
32+puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.2.1` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.2.1` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail.
3133
3234 ## Étapes
3335
@@ -39,9 +41,9 @@ Depuis la racine du dépôt :
3941 ./docker-sbx/build.sh
4042 ```
4143
42-Cela lit le tag de mm dans `release.env` (`v0.1.7`) et construit `k33g/mm-sandbox:0.1.7` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.1.7`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`.
44+Cela lit le tag de mm dans `release.env` (`v0.2.1`) et construit `k33g/mm-sandbox:0.2.1` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.2.1`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`.
4345
44-L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.1.7`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.1.7.tar`, à charger là-bas avec `sbx template load`.
46+L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.2.1`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.2.1.tar`, à charger là-bas avec `sbx template load`.
4547
4648 ### 2. Mode fenêtre dans le terminal (kit `mm-tui`)
4749
@@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml
6264 | `--kit-arg` | Défaut | Effet |
6365 |---|---|---|
6466 | `config=<chemin>` | vide | Le fichier de configuration, comme `AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. |
65-| `tag=<version>` | la dernière version construite (`0.1.7`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. |
67+| `tag=<version>` | la dernière version construite (`0.2.1`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. |
6668
6769 Le sandbox garde son nom (`mm-tui-<répertoire>` sauf `--name`) ; `sbx run --name <nom>` s'y rattache plus tard. À l'intérieur, la fenêtre est celle décrite dans [Utiliser le mode fenêtre](use-the-window-mode.md). Les sessions, quand `sessions.enabled` est actif, sont écrites sous `.mm/sessions` dans l'espace de travail — c'est votre répertoire hôte, elles survivent donc au sandbox.
6870
@@ -118,10 +120,10 @@ La publication est une étape manuelle, depuis une machine avec Docker Desktop (
118120 ```bash
119121 export DOCKER_HANDLE=k33g # le compte Docker Hub, aussi propriétaire de l'image
120122 export DOCKER_PAT=dckr_pat_… # un jeton d'accès en lecture/écriture
121-./docker-sbx/publish.sh # TAG depuis release.env : v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7
123+./docker-sbx/publish.sh # TAG depuis release.env : v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1
122124 ```
123125
124-Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.1.7` (l'image) et `./docker-sbx/push-kits.sh v0.1.7` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte.
126+Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.2.1` (l'image) et `./docker-sbx/push-kits.sh v0.2.1` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte.
125127
126128 ## Serveurs MCP via la passerelle sbx (exemple : GitHub)
127129
@@ -175,5 +177,6 @@ Nommez le dépôt dans vos demandes, par exemple « liste les issues ouvertes de
175177 ## Voir aussi
176178
177179 - Le format suivi par ces deux fichiers : la spécification des kits de Docker Sandboxes (`schemaVersion: "2"`), livrée avec les sources de `sbx`.
180+- Les mêmes kits pour la spécification de kit v3 : [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md).
178181 - Ce que `mm -acp` expose à l'éditeur : [référence ACP](../reference/acp.md).
179182 - Les drapeaux et variables d'environnement que `mm` lit : [référence de la ligne de commande](../reference/cli.md).
@@ -2,6 +2,8 @@
2 2
3 Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), pour que chaque commande lancée par le modèle et chaque fichier qu'il modifie le soient dans un conteneur, sur votre projet monté. Il couvre les deux usages : le mode fenêtre dans votre terminal, et depuis un éditeur via l'Agent Client Protocol. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine.3 Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/), pour que chaque commande lancée par le modèle et chaque fichier qu'il modifie le soient dans un conteneur, sur votre projet monté. Il couvre les deux usages : le mode fenêtre dans votre terminal, et depuis un éditeur via l'Agent Client Protocol. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine.
4 4
5+> Ce sont les kits **v2** (`spec.yaml`). Les deux mêmes kits existent aussi pour la spécification de kit v3, sous `docker-sbx-v3/` : voir [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md).
6+
5 Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt :7 Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt :
6 8
7 | Élément | Ce que c'est |9 | Élément | Ce que c'est |
@@ -14,20 +16,20 @@ Tout est sous [`docker-sbx/`](../../../docker-sbx/README.md) dans le dépôt :
14 16
15 ## Utiliser les kits publiés17 ## Utiliser les kits publiés
16 18
17-Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.1.7`, `k33g/mm-tui:0.1.7`, `k33g/mm-acp:0.1.7` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` :19+Chaque release publie l'image et les deux kits sur Docker Hub à la version de mm — `k33g/mm-sandbox:0.2.1`, `k33g/mm-tui:0.2.1`, `k33g/mm-acp:0.2.1` — le chemin le plus court ne demande donc aucune construction. Docker Hub est une source de kits autorisée par défaut (`sbx settings get kit.allowedSources` montre `docker.io/`), et une référence avec un `/` mais sans hôte de registre est lue comme `docker.io/…` :
18 20
19 ```bash21 ```bash
20 cd /chemin/de/votre/projet22 cd /chemin/de/votre/projet
21-sbx run k33g/mm-tui:0.1.7 . -- agent.dmr.yaml23+sbx run k33g/mm-tui:0.2.1 . -- agent.dmr.yaml
22 ```24 ```
23 25
24 pour le mode fenêtre, et pour un éditeur :26 pour le mode fenêtre, et pour un éditeur :
25 27
26 ```bash28 ```bash
27-sbx create --name mm-acp k33g/mm-acp:0.1.7 . --kit-arg config=agent.dmr.yaml29+sbx create --name mm-acp k33g/mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
28 ```30 ```
29 31
30-puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.1.7` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.1.7` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail.32+puis la déclaration dans l'éditeur de l'étape 3 ci-dessous. Pas de `--pull never` : le kit nomme `k33g/mm-sandbox:0.2.1` et sbx la télécharge. `sbx kit inspect k33g/mm-tui:0.2.1` montre ce qu'un kit déclare avant de le lancer. Les étapes qui suivent construisent la même chose en local, pour un mm en cours de travail.
31 33
32 ## Étapes34 ## Étapes
33 35
@@ -39,9 +41,9 @@ Depuis la racine du dépôt :
39 ./docker-sbx/build.sh41 ./docker-sbx/build.sh
40 ```42 ```
41 43
42-Cela lit le tag de mm dans `release.env` (`v0.1.7`) et construit `k33g/mm-sandbox:0.1.7` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.1.7`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`.44+Cela lit le tag de mm dans `release.env` (`v0.2.1`) et construit `k33g/mm-sandbox:0.2.1` : le tag de l'image est la version sans le `v`, comme les binaires de release, et le `mm` à l'intérieur est estampillé avec le tag — `mm --version` est exécuté dans l'image comme preuve. Le script réécrit ensuite la valeur par défaut de l'argument `tag` des kits à `0.2.1`, pour que kits et image avancent ensemble. `./docker-sbx/build.sh v0.1.5` construit une autre version ; une image antérieure reste joignable avec `--kit-arg tag=0.1.4`.
43 45
44-L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.1.7`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.1.7.tar`, à charger là-bas avec `sbx template load`.46+L'image est dans votre store d'images Docker local : chaque `sbx run` ou `sbx create` sur ces kits prend `--pull never` tant qu'elle n'est pas poussée (`docker push k33g/mm-sandbox:0.2.1`), sinon `sbx` tente de la télécharger et échoue. Si `sbx` tourne sur une autre machine, `EXPORT=1 ./docker-sbx/build.sh` écrit aussi `tmp/mm-sandbox-0.2.1.tar`, à charger là-bas avec `sbx template load`.
45 47
46 ### 2. Mode fenêtre dans le terminal (kit `mm-tui`)48 ### 2. Mode fenêtre dans le terminal (kit `mm-tui`)
47 49
@@ -62,7 +64,7 @@ sbx run --pull never ./docker-sbx/kits/mm-tui . --kit-arg config=agent.dmr.yaml
62 | `--kit-arg` | Défaut | Effet |64 | `--kit-arg` | Défaut | Effet |
63 |---|---|---|65 |---|---|---|
64 | `config=<chemin>` | vide | Le fichier de configuration, comme `AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. |66 | `config=<chemin>` | vide | Le fichier de configuration, comme `AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. |
65-| `tag=<version>` | la dernière version construite (`0.1.7`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. |67+| `tag=<version>` | la dernière version construite (`0.2.1`) | L'image `k33g/mm-sandbox:<version>` dont le sandbox est fait. |
66 68
67 Le sandbox garde son nom (`mm-tui-<répertoire>` sauf `--name`) ; `sbx run --name <nom>` s'y rattache plus tard. À l'intérieur, la fenêtre est celle décrite dans [Utiliser le mode fenêtre](use-the-window-mode.md). Les sessions, quand `sessions.enabled` est actif, sont écrites sous `.mm/sessions` dans l'espace de travail — c'est votre répertoire hôte, elles survivent donc au sandbox.69 Le sandbox garde son nom (`mm-tui-<répertoire>` sauf `--name`) ; `sbx run --name <nom>` s'y rattache plus tard. À l'intérieur, la fenêtre est celle décrite dans [Utiliser le mode fenêtre](use-the-window-mode.md). Les sessions, quand `sessions.enabled` est actif, sont écrites sous `.mm/sessions` dans l'espace de travail — c'est votre répertoire hôte, elles survivent donc au sandbox.
68 70
@@ -118,10 +120,10 @@ La publication est une étape manuelle, depuis une machine avec Docker Desktop (
118 ```bash120 ```bash
119 export DOCKER_HANDLE=k33g # le compte Docker Hub, aussi propriétaire de l'image121 export DOCKER_HANDLE=k33g # le compte Docker Hub, aussi propriétaire de l'image
120 export DOCKER_PAT=dckr_pat_… # un jeton d'accès en lecture/écriture122 export DOCKER_PAT=dckr_pat_… # un jeton d'accès en lecture/écriture
121-./docker-sbx/publish.sh # TAG depuis release.env : v0.1.7 → k33g/mm-sandbox:0.1.7, k33g/mm-tui:0.1.7, k33g/mm-acp:0.1.7123+./docker-sbx/publish.sh # TAG depuis release.env : v0.2.1 → k33g/mm-sandbox:0.2.1, k33g/mm-tui:0.2.1, k33g/mm-acp:0.2.1
122 ```124 ```
123 125
124-Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.1.7` (l'image) et `./docker-sbx/push-kits.sh v0.1.7` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte.126+Avec les deux variables, le script se connecte avec elles et se déconnecte à la fin ; sans elles, il réutilise votre `docker login` existant. Ses deux moitiés se lancent seules : `PUSH=1 ./docker-sbx/build.sh v0.2.1` (l'image) et `./docker-sbx/push-kits.sh v0.2.1` (les kits, `SBX=/chemin/vers/sbx` si la CLI n'est pas sur le PATH). Les deux appellent d'abord `sync-kits.sh`, qui réécrit `version`, le `tag` par défaut et le propriétaire de l'image des kits, de sorte qu'un kit publié nomme toujours l'image poussée avec lui — commitez ensuite les deux `spec.yaml`. `sbx kit push` parle directement au registre et s'authentifie depuis le magasin d'identifiants Docker, sans démon sandbox. `IMAGE_OWNER=<compte>` publie sous un autre compte.
125 127
126 ## Serveurs MCP via la passerelle sbx (exemple : GitHub)128 ## Serveurs MCP via la passerelle sbx (exemple : GitHub)
127 129
@@ -175,5 +177,6 @@ Nommez le dépôt dans vos demandes, par exemple « liste les issues ouvertes de
175 ## Voir aussi177 ## Voir aussi
176 178
177 - Le format suivi par ces deux fichiers : la spécification des kits de Docker Sandboxes (`schemaVersion: "2"`), livrée avec les sources de `sbx`.179 - Le format suivi par ces deux fichiers : la spécification des kits de Docker Sandboxes (`schemaVersion: "2"`), livrée avec les sources de `sbx`.
180+- Les mêmes kits pour la spécification de kit v3 : [Faire tourner mini-me avec les kits sandbox v3](run-with-sandbox-kits-v3.md).
178 - Ce que `mm -acp` expose à l'éditeur : [référence ACP](../reference/acp.md).181 - Ce que `mm -acp` expose à l'éditeur : [référence ACP](../reference/acp.md).
179 - Les drapeaux et variables d'environnement que `mm` lit : [référence de la ligne de commande](../reference/cli.md).182 - Les drapeaux et variables d'environnement que `mm` lit : [référence de la ligne de commande](../reference/cli.md).
added docs/fr/how-to/run-with-sandbox-kits-v3.md +111 -0
new file mode 100644
@@ -0,0 +1,111 @@
1+# Faire tourner mini-me avec les kits sandbox v3
2+
3+Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) avec les kits écrits pour la [spécification de kit v3](https://github.com/docker/sandbox-kit-spec), sous [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). Ils font le même travail que les kits v2 de [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md) — le mode fenêtre avec `mm-tui`, un éditeur avec `mm-acp` — et les kits v2 continuent de fonctionner à côté. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine.
4+
5+> **État.** Les kits v3 se construisent avec le frontend `docker/sandbox-kit:3` et passent le contrôle de conformité de la spécification (`kit-tck validate`), mais ils n'ont pas encore été lancés avec `sbx`, et ne sont pas encore publiés. La spécification de kit elle-même est encore marquée expérimentale.
6+
7+| Élément | Ce que c'est |
8+|---|---|
9+| `template/Dockerfile` | L'image **template**, `k33g/mm-sandbox:<version>` — la même image qu'en v2. |
10+| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | Le kit du mode fenêtre : un descripteur (les déclarations) et un Dockerfile (le contenu : `FROM` le template, `ENTRYPOINT ["mm-tui"]`). |
11+| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | Le kit pour un éditeur, même forme, `ENTRYPOINT ["mm-acp-info"]`. |
12+| `build.sh`, `sync-kits.sh` | Construisent le template, et alignent les kits dessus. |
13+| `check-kits.sh` | Construit les kits en local et les vérifie, sans `sbx` et sans push. |
14+| `push-kits.sh`, `publish.sh` | Publient les kits (et le template) sur Docker Hub avec `docker buildx`. |
15+
16+## Avant de commencer : deux différences avec la v2
17+
18+- **L'image template doit être sur un registre.** Un kit v3 est *construit* au-dessus du template. Quand vous lancez un kit depuis son dossier, `sbx` le construit dans son sandbox de build, dont le moteur Docker télécharge le template depuis le registre. Une image présente seulement dans votre stockage local ne suffit pas, et `--pull never` ou `sbx template load` n'y changent rien. `k33g/mm-sandbox:0.2.1` est déjà sur Docker Hub ; pour une autre version, poussez-la d'abord (étape 1).
19+- **L'espace de travail est `/home/agent/workspace`.** L'image de base du template déclare ce répertoire de travail, et un workload d'agent v3 (`sbx@1`) y est monté. Donnez à `config` un chemin relatif à l'espace de travail (`agent.dmr.yaml`, `demo/agent.dmr.yaml`) ; un chemin absolu de votre Mac (`/Users/…`) n'existe pas dans le sandbox.
20+
21+## Étapes
22+
23+### 1. Rendre le template disponible
24+
25+Pour la version de `release.env` (`v0.2.1`), rien à faire : `k33g/mm-sandbox:0.2.1` est sur Docker Hub. Pour un `mm` en cours de travail, construisez et poussez le template depuis la racine du dépôt :
26+
27+```bash
28+PUSH=1 ./docker-sbx-v3/build.sh v0.2.2
29+```
30+
31+Le script construit `k33g/mm-sandbox:0.2.2` pour linux/amd64 et linux/arm64, la pousse, puis réécrit les valeurs par défaut `image` et `tag` des kits pour qu'ils nomment cette image. `IMAGE_OWNER=<compte>` la pousse sous votre propre compte.
32+
33+### 2. Vérifier les kits (facultatif)
34+
35+```bash
36+./docker-sbx-v3/check-kits.sh
37+```
38+
39+Chaque kit est construit avec `docker buildx build -f <kit>.yaml`, qui passe par le frontend des kits : il refuse une clé inconnue ou un argument qui ne respecte pas son motif. Le résultat va dans `tmp/kits-v3/<kit>/`. Avec [`kit-tck`](https://github.com/docker/sandbox-kit-spec) dans le `PATH` (`go build ./cmd/kit-tck` dans un clone de la spécification), le script lance aussi le contrôle de conformité et affiche `✓ conforms`.
40+
41+### 3. Mode fenêtre dans le terminal (kit `mm-tui`)
42+
43+Depuis le projet sur lequel `mm` doit travailler :
44+
45+```bash
46+cd /chemin/de/votre/projet
47+sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
48+```
49+
50+Le premier lancement construit le kit (quelques secondes : une couche au-dessus du template), crée le sandbox, monte le répertoire courant et lance `mm -tui agent.dmr.yaml`. Ce qui suit `--` est la ligne de commande de `mm`. Sans rien après `--`, `mm` lit l'argument `config` du kit, puis `./agent.yaml`, puis ses valeurs par défaut :
51+
52+```bash
53+sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml
54+```
55+
56+### 4. Depuis un éditeur (kit `mm-acp`)
57+
58+1. Créez le sandbox une fois, depuis le projet que l'éditeur ouvrira :
59+
60+ ```bash
61+ cd /chemin/de/votre/projet
62+ sbx create --name mm-acp /chemin/de/mini-me/docker-sbx-v3/kits/mm-acp . \
63+ --kit-arg config=agent.dmr.yaml
64+ ```
65+
66+2. Déclarez-le dans l'éditeur. Dans le `settings.json` de Zed :
67+
68+ ```json
69+ {
70+ "agent_servers": {
71+ "mini-me (sandbox)": {
72+ "type": "custom",
73+ "command": "sbx",
74+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
75+ }
76+ }
77+ }
78+ ```
79+
80+3. Ouvrez le panneau d'agent et choisissez **mini-me (sandbox)**. Comme en v2, l'éditeur passe par `sbx exec -i`, parce qu'un client ACP a besoin de stdin et stdout bruts et que `sbx run` alloue toujours un terminal. `sbx run --name mm-acp` affiche ce branchement et ouvre un shell.
81+
82+### 5. Une fois les kits publiés
83+
84+Après `./docker-sbx-v3/publish.sh` (ou `push-kits.sh`) pour une version, les kits sont des images ordinaires sur Docker Hub, et aucun dossier n'est nécessaire :
85+
86+```bash
87+sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml
88+sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
89+```
90+
91+Les dépôts sont `sbx-kit-<kit>`, pas les `k33g/mm-tui` / `k33g/mm-acp` de la v2 : publier un kit v3 ne remplace jamais un kit v2.
92+
93+## Arguments des kits
94+
95+| `--kit-arg` | Défaut | Quand il s'applique | Effet |
96+|---|---|---|---|
97+| `config=<chemin>` | vide | à `sbx run` / `sbx create` | L'`AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. Vide : `./agent.yaml`, puis les valeurs par défaut. |
98+| `tag=<version>` | la version de mm (`0.2.1`) | à la construction du kit | Le tag du template sur lequel le kit est construit ; c'est aussi la version du kit. Sans `v`. |
99+| `image=<dépôt>` | `k33g/mm-sandbox` | à la construction du kit | Le dépôt du template sur lequel le kit est construit. |
100+
101+`tag` et `image` sont des arguments de construction : ils sont figés dans un kit publié, qui nomme toujours l'image sur laquelle il a été construit. Pour une autre version de `mm`, prenez le kit de cette version.
102+
103+## Le serveur de modèles reste sur l'hôte
104+
105+Rien ne change par rapport à la v2 : Docker Model Runner et llama-server tournent sur votre machine et sont joints par `host.docker.internal`. `agent.dmr.yaml` s'y replie déjà ; pour llama-server, voir [le guide v2](run-in-a-docker-sandbox.md#le-serveur-de-modèles-reste-sur-lhôte). Les deux kits autorisent les ports 12434 et 8080 de l'hôte ; pour un autre port, `sbx policy allow network host.docker.internal:<port>`.
106+
107+## Voir aussi
108+
109+- Ce qui change par rapport aux kits v2, champ par champ : [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md).
110+- Les kits v2, la passerelle MCP et les variantes pour éditeur : [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md).
111+- Le format des kits : [spécification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md).
new file mode 100644
@@ -0,0 +1,111 @@
1+# Faire tourner mini-me avec les kits sandbox v3
2+
3+Ce guide montre comment exécuter `mm` dans un [Docker Sandbox](https://docs.docker.com/ai/sandboxes/) avec les kits écrits pour la [spécification de kit v3](https://github.com/docker/sandbox-kit-spec), sous [`docker-sbx-v3/`](../../../docker-sbx-v3/README.md). Ils font le même travail que les kits v2 de [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md) — le mode fenêtre avec `mm-tui`, un éditeur avec `mm-acp` — et les kits v2 continuent de fonctionner à côté. Il suppose Docker Desktop avec la commande `sbx`, et un serveur de modèles (Docker Model Runner ou llama-server) qui tourne sur votre machine.
4+
5+> **État.** Les kits v3 se construisent avec le frontend `docker/sandbox-kit:3` et passent le contrôle de conformité de la spécification (`kit-tck validate`), mais ils n'ont pas encore été lancés avec `sbx`, et ne sont pas encore publiés. La spécification de kit elle-même est encore marquée expérimentale.
6+
7+| Élément | Ce que c'est |
8+|---|---|
9+| `template/Dockerfile` | L'image **template**, `k33g/mm-sandbox:<version>` — la même image qu'en v2. |
10+| `kits/mm-tui/mm-tui.yaml` + `mm-tui.dockerfile` | Le kit du mode fenêtre : un descripteur (les déclarations) et un Dockerfile (le contenu : `FROM` le template, `ENTRYPOINT ["mm-tui"]`). |
11+| `kits/mm-acp/mm-acp.yaml` + `mm-acp.dockerfile` | Le kit pour un éditeur, même forme, `ENTRYPOINT ["mm-acp-info"]`. |
12+| `build.sh`, `sync-kits.sh` | Construisent le template, et alignent les kits dessus. |
13+| `check-kits.sh` | Construit les kits en local et les vérifie, sans `sbx` et sans push. |
14+| `push-kits.sh`, `publish.sh` | Publient les kits (et le template) sur Docker Hub avec `docker buildx`. |
15+
16+## Avant de commencer : deux différences avec la v2
17+
18+- **L'image template doit être sur un registre.** Un kit v3 est *construit* au-dessus du template. Quand vous lancez un kit depuis son dossier, `sbx` le construit dans son sandbox de build, dont le moteur Docker télécharge le template depuis le registre. Une image présente seulement dans votre stockage local ne suffit pas, et `--pull never` ou `sbx template load` n'y changent rien. `k33g/mm-sandbox:0.2.1` est déjà sur Docker Hub ; pour une autre version, poussez-la d'abord (étape 1).
19+- **L'espace de travail est `/home/agent/workspace`.** L'image de base du template déclare ce répertoire de travail, et un workload d'agent v3 (`sbx@1`) y est monté. Donnez à `config` un chemin relatif à l'espace de travail (`agent.dmr.yaml`, `demo/agent.dmr.yaml`) ; un chemin absolu de votre Mac (`/Users/…`) n'existe pas dans le sandbox.
20+
21+## Étapes
22+
23+### 1. Rendre le template disponible
24+
25+Pour la version de `release.env` (`v0.2.1`), rien à faire : `k33g/mm-sandbox:0.2.1` est sur Docker Hub. Pour un `mm` en cours de travail, construisez et poussez le template depuis la racine du dépôt :
26+
27+```bash
28+PUSH=1 ./docker-sbx-v3/build.sh v0.2.2
29+```
30+
31+Le script construit `k33g/mm-sandbox:0.2.2` pour linux/amd64 et linux/arm64, la pousse, puis réécrit les valeurs par défaut `image` et `tag` des kits pour qu'ils nomment cette image. `IMAGE_OWNER=<compte>` la pousse sous votre propre compte.
32+
33+### 2. Vérifier les kits (facultatif)
34+
35+```bash
36+./docker-sbx-v3/check-kits.sh
37+```
38+
39+Chaque kit est construit avec `docker buildx build -f <kit>.yaml`, qui passe par le frontend des kits : il refuse une clé inconnue ou un argument qui ne respecte pas son motif. Le résultat va dans `tmp/kits-v3/<kit>/`. Avec [`kit-tck`](https://github.com/docker/sandbox-kit-spec) dans le `PATH` (`go build ./cmd/kit-tck` dans un clone de la spécification), le script lance aussi le contrôle de conformité et affiche `✓ conforms`.
40+
41+### 3. Mode fenêtre dans le terminal (kit `mm-tui`)
42+
43+Depuis le projet sur lequel `mm` doit travailler :
44+
45+```bash
46+cd /chemin/de/votre/projet
47+sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . -- agent.dmr.yaml
48+```
49+
50+Le premier lancement construit le kit (quelques secondes : une couche au-dessus du template), crée le sandbox, monte le répertoire courant et lance `mm -tui agent.dmr.yaml`. Ce qui suit `--` est la ligne de commande de `mm`. Sans rien après `--`, `mm` lit l'argument `config` du kit, puis `./agent.yaml`, puis ses valeurs par défaut :
51+
52+```bash
53+sbx run /chemin/de/mini-me/docker-sbx-v3/kits/mm-tui . --kit-arg config=agent.dmr.yaml
54+```
55+
56+### 4. Depuis un éditeur (kit `mm-acp`)
57+
58+1. Créez le sandbox une fois, depuis le projet que l'éditeur ouvrira :
59+
60+ ```bash
61+ cd /chemin/de/votre/projet
62+ sbx create --name mm-acp /chemin/de/mini-me/docker-sbx-v3/kits/mm-acp . \
63+ --kit-arg config=agent.dmr.yaml
64+ ```
65+
66+2. Déclarez-le dans l'éditeur. Dans le `settings.json` de Zed :
67+
68+ ```json
69+ {
70+ "agent_servers": {
71+ "mini-me (sandbox)": {
72+ "type": "custom",
73+ "command": "sbx",
74+ "args": ["exec", "-i", "mm-acp", "mm", "-acp"]
75+ }
76+ }
77+ }
78+ ```
79+
80+3. Ouvrez le panneau d'agent et choisissez **mini-me (sandbox)**. Comme en v2, l'éditeur passe par `sbx exec -i`, parce qu'un client ACP a besoin de stdin et stdout bruts et que `sbx run` alloue toujours un terminal. `sbx run --name mm-acp` affiche ce branchement et ouvre un shell.
81+
82+### 5. Une fois les kits publiés
83+
84+Après `./docker-sbx-v3/publish.sh` (ou `push-kits.sh`) pour une version, les kits sont des images ordinaires sur Docker Hub, et aucun dossier n'est nécessaire :
85+
86+```bash
87+sbx run k33g/sbx-kit-mm-tui:0.2.1 . -- agent.dmr.yaml
88+sbx create --name mm-acp k33g/sbx-kit-mm-acp:0.2.1 . --kit-arg config=agent.dmr.yaml
89+```
90+
91+Les dépôts sont `sbx-kit-<kit>`, pas les `k33g/mm-tui` / `k33g/mm-acp` de la v2 : publier un kit v3 ne remplace jamais un kit v2.
92+
93+## Arguments des kits
94+
95+| `--kit-arg` | Défaut | Quand il s'applique | Effet |
96+|---|---|---|---|
97+| `config=<chemin>` | vide | à `sbx run` / `sbx create` | L'`AGENT_CONFIG` de `mm` : relatif à l'espace de travail, ou absolu dans le sandbox. Vide : `./agent.yaml`, puis les valeurs par défaut. |
98+| `tag=<version>` | la version de mm (`0.2.1`) | à la construction du kit | Le tag du template sur lequel le kit est construit ; c'est aussi la version du kit. Sans `v`. |
99+| `image=<dépôt>` | `k33g/mm-sandbox` | à la construction du kit | Le dépôt du template sur lequel le kit est construit. |
100+
101+`tag` et `image` sont des arguments de construction : ils sont figés dans un kit publié, qui nomme toujours l'image sur laquelle il a été construit. Pour une autre version de `mm`, prenez le kit de cette version.
102+
103+## Le serveur de modèles reste sur l'hôte
104+
105+Rien ne change par rapport à la v2 : Docker Model Runner et llama-server tournent sur votre machine et sont joints par `host.docker.internal`. `agent.dmr.yaml` s'y replie déjà ; pour llama-server, voir [le guide v2](run-in-a-docker-sandbox.md#le-serveur-de-modèles-reste-sur-lhôte). Les deux kits autorisent les ports 12434 et 8080 de l'hôte ; pour un autre port, `sbx policy allow network host.docker.internal:<port>`.
106+
107+## Voir aussi
108+
109+- Ce qui change par rapport aux kits v2, champ par champ : [`docker-sbx-v3/README.md`](../../../docker-sbx-v3/README.md).
110+- Les kits v2, la passerelle MCP et les variantes pour éditeur : [Faire tourner mini-me dans un Docker Sandbox](run-in-a-docker-sandbox.md).
111+- Le format des kits : [spécification v3](https://github.com/docker/sandbox-kit-spec/blob/main/docs/spec/SPEC-v3.md).