Skip to content

Commit 7d78bf9

Browse files
Merge branch 'johannesburg'
2 parents 48bb893 + fd4293c commit 7d78bf9

5 files changed

Lines changed: 84 additions & 2 deletions

File tree

‎README.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ Run AI coding assistants in containers/vms.
1111
╚══════╝╚═╝╚══════╝ ╚═════╝
1212
```
1313

14-
Silo lets you run AI tools like Claude Code, Cline, Codex, OpenCode, Paperclip AI, GitHub Copilot CLI, Mistral Vibe, and Kilo Code in isolated Docker containers, Apple containers (lightweight VMs), Fly.io machines (remote VMs), or [Namespace devboxes](https://namespace.so/devbox) (remote VMs). The coding tools are configured to run in auto-approve mode.
14+
Silo lets you run AI tools like Claude Code, Cline, Codex, OpenCode, Paperclip AI, GitHub Copilot CLI, Mistral Vibe, Kilo Code, and Pi Coding Agent in isolated Docker containers, Apple containers (lightweight VMs), Fly.io machines (remote VMs), or [Namespace devboxes](https://namespace.so/devbox) (remote VMs). The coding tools are configured to run in auto-approve mode.
1515

1616
> [!WARNING]
1717
> Built using AI. No isolation is perfect. Use at your own risk.
@@ -57,6 +57,7 @@ Silo resolves this by running AI tools in isolated containers/vms with:
5757
| GitHub Copilot CLI | `silo copilot` | GitHub's Copilot CLI |
5858
| Mistral Vibe | `silo vibe` | Mistral's CLI coding assistant |
5959
| Kilo Code CLI | `silo kilo` | Kilo's terminal coding agent |
60+
| Pi Coding Agent | `silo pi` | Pi's coding assistant |
6061

6162
## Installation
6263

@@ -104,6 +105,7 @@ silo paperclipai
104105
silo copilot
105106
silo vibe
106107
silo kilo
108+
silo pi
107109

108110
# Pass arguments to the tool (silo flags before tool name, tool args after)
109111
silo claude --help

‎dockerfile_test.go‎

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ func TestAvailableTools(t *testing.T) {
5454
"copilot": true,
5555
"vibe": true,
5656
"kilo": true,
57+
"pi": true,
5758
}
5859

5960
for _, tool := range tools {
@@ -81,6 +82,7 @@ func TestToolDescription(t *testing.T) {
8182
{"copilot", "Copilot"},
8283
{"vibe", "Vibe"},
8384
{"kilo", "Kilo"},
85+
{"pi", "Pi"},
8486
{"unknown", "Unknown"},
8587
}
8688

‎main.go‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import (
3535
"github.com/leighmcculloch/silo/tools/mistralvibe"
3636
"github.com/leighmcculloch/silo/tools/opencode"
3737
"github.com/leighmcculloch/silo/tools/paperclipai"
38+
"github.com/leighmcculloch/silo/tools/pi"
3839
"github.com/spf13/cobra"
3940
)
4041

@@ -53,6 +54,7 @@ var (
5354
copilotcli.Tool,
5455
mistralvibe.Tool,
5556
kilocode.Tool,
57+
pi.Tool,
5658
}
5759
)
5860

@@ -149,7 +151,7 @@ func newRootCmd(stdout, stderr io.Writer) *cobra.Command {
149151
███████║██║███████╗╚██████╔╝
150152
╚══════╝╚═╝╚══════╝ ╚═════╝
151153
`) + `
152-
Run AI tools (Claude Code, Cline, Codex, OpenCode, Paperclip AI, Copilot, Mistral Vibe, Kilo Code) in isolated
154+
Run AI tools (Claude Code, Cline, Codex, OpenCode, Paperclip AI, Copilot, Mistral Vibe, Kilo Code, Pi Coding Agent) in isolated
153155
Docker containers with proper security sandboxing.
154156
155157
The container is configured with:
@@ -174,6 +176,7 @@ Configuration is loaded from (in order, merged):
174176
silo copilot
175177
silo vibe
176178
silo kilo
179+
silo pi
177180
178181
# Silo flags go before the tool name; tool args go after
179182
silo --backend docker claude --continue

‎tools/pi/Dockerfile‎

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
# ============================================
2+
# Pi Coding Agent stage
3+
# ============================================
4+
FROM base AS pi
5+
6+
ARG HOME
7+
ARG TOOL_VERSION
8+
9+
RUN set -e && \
10+
npm install -g @mariozechner/pi-coding-agent${TOOL_VERSION:+"@$TOOL_VERSION"} && \
11+
pi --version
12+
13+
# SILO_POST_BUILD_HOOKS_PI

‎tools/pi/pi.go‎

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
package pi
2+
3+
import (
4+
"context"
5+
_ "embed"
6+
"encoding/json"
7+
"io"
8+
"net/http"
9+
10+
"github.com/leighmcculloch/silo/config"
11+
"github.com/leighmcculloch/silo/tools"
12+
)
13+
14+
//go:embed Dockerfile
15+
var dockerfileStage string
16+
17+
// Tool is the Pi Coding Agent tool definition.
18+
var Tool = tools.Tool{
19+
Name: "pi",
20+
Description: "Pi Coding Agent - AI coding assistant",
21+
DockerfileStage: dockerfileStage,
22+
Command: func(home string) []string {
23+
return []string{home + "/.local/node/bin/pi"}
24+
},
25+
DefaultConfig: func() config.ToolConfig {
26+
return config.ToolConfig{
27+
MountsRW: []string{"~/.pi"},
28+
}
29+
},
30+
LatestVersion: fetchLatestVersion,
31+
}
32+
33+
// fetchLatestVersion queries the npm registry for the latest pi version.
34+
func fetchLatestVersion(ctx context.Context) string {
35+
req, err := http.NewRequestWithContext(ctx, http.MethodGet, "https://registry.npmjs.org/@mariozechner/pi-coding-agent/latest", nil)
36+
if err != nil {
37+
return ""
38+
}
39+
40+
resp, err := http.DefaultClient.Do(req)
41+
if err != nil {
42+
return ""
43+
}
44+
defer resp.Body.Close()
45+
46+
if resp.StatusCode != http.StatusOK {
47+
return ""
48+
}
49+
50+
body, err := io.ReadAll(resp.Body)
51+
if err != nil {
52+
return ""
53+
}
54+
55+
var pkg struct {
56+
Version string `json:"version"`
57+
}
58+
if err := json.Unmarshal(body, &pkg); err != nil {
59+
return ""
60+
}
61+
return pkg.Version
62+
}

0 commit comments

Comments
 (0)