Skip to content

Commit 11a4404

Browse files
sre-helmcodebarckcodeclaude
authored
feat(run): --agent pi_gentle (Pi + Gentle Shell) (0.1.29) (#47)
The platform runs a third agent, pi_gentle: Pi launched with Gentle Shell, when the workspace has it installed. --agent accepts pi, pi_gentle and hermes; the platform refuses an agent the workspace lacks (agent_not_installed, exit 4 as before). Co-authored-by: barckcode <cristian@helmcode.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
1 parent 8526206 commit 11a4404

4 files changed

Lines changed: 43 additions & 6 deletions

File tree

‎README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ inside each tool later.
8888

8989
## Agent runs
9090

91-
`nan run` starts an agent (Pi or Hermes) in one of your
91+
`nan run` starts an agent (Pi, Pi + Gentle Shell or Hermes) in one of your
9292
[workspaces](https://cloud.nan.builders) and streams what it does. The run
9393
happens in the workspace, not on your machine: it keeps going if the command
9494
stops, and its log stays on nan.builders.
@@ -103,7 +103,7 @@ id=$(nan run --detach "upgrade the dependencies")
103103
| Flag | Default | |
104104
|---|---|---|
105105
| `--ws NAME` | your only workspace | Workspace to run in. Required when you have more than one. |
106-
| `--agent pi\|hermes` | `pi` | Agent to run. |
106+
| `--agent pi\|pi_gentle\|hermes` | `pi` | Agent to run: `pi_gentle` is Pi with Gentle Shell. The workspace must have it installed. |
107107
| `--model M` | the agent's own | Model for the agent. |
108108
| `--cwd PATH` | `/home/nan` | Folder in the workspace. |
109109
| `--worktree` / `--no-worktree` | auto | Work on a separate branch, or in the folder itself. See below. |

‎cmd/run.go‎

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"os"
99
"os/signal"
1010
"regexp"
11+
"slices"
1112
"strings"
1213
"time"
1314
"unicode/utf8"
@@ -140,7 +141,7 @@ func init() {
140141
rootCmd.AddCommand(runCmd)
141142
f := runCmd.Flags()
142143
f.StringVar(&runOpts.workspace, "ws", "", "Workspace to run in (default: your only workspace)")
143-
f.StringVar(&runOpts.agent, "agent", "pi", "Agent to run: pi or hermes")
144+
f.StringVar(&runOpts.agent, "agent", "pi", "Agent to run: pi, pi_gentle (Pi + Gentle Shell) or hermes, if the workspace has it installed")
144145
f.StringVar(&runOpts.model, "model", "", "Model for the agent (default: the agent's own)")
145146
f.StringVar(&runOpts.cwd, "cwd", "", "Folder in the workspace to run in (default: /home/nan)")
146147
f.BoolVar(&runOpts.worktree, "worktree", false, "Always work on a separate branch, nan-run/<id> (fails outside a git repository)")
@@ -397,9 +398,14 @@ func isTerminal(f *os.File) bool {
397398
return err == nil && info.Mode()&os.ModeCharDevice != 0
398399
}
399400

401+
// runAgents are the agents a run can use (the platform's runs.agent set):
402+
// pi_gentle is Pi with gentle-shell. The workspace must have the agent
403+
// installed; the platform answers agent_not_installed otherwise.
404+
var runAgents = []string{"pi", "pi_gentle", "hermes"}
405+
400406
func buildRunRequest(in promptInput, opts runOptions, args []string) (*api.CreateRunRequest, error) {
401-
if opts.agent != "pi" && opts.agent != "hermes" {
402-
return nil, usageErrorf("--agent must be pi or hermes, not %q", opts.agent)
407+
if !slices.Contains(runAgents, opts.agent) {
408+
return nil, usageErrorf("--agent must be pi, pi_gentle or hermes, not %q", opts.agent)
403409
}
404410
if opts.worktree && opts.noWorktree {
405411
return nil, usageErrorf("--worktree and --no-worktree contradict each other; pick one")

‎cmd/run_test.go‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -525,6 +525,37 @@ func TestRunFlagsShapeTheRequest(t *testing.T) {
525525
}
526526
}
527527

528+
// --agent takes every agent the platform runs: pi, pi_gentle (Pi with
529+
// gentle-shell) and hermes, sent as given. Anything else is a usage error.
530+
func TestRunAgentValues(t *testing.T) {
531+
for _, agent := range []string{"pi", "pi_gentle", "hermes"} {
532+
h := newHarness(t, &fakePlatform{})
533+
opts := defaultOpts()
534+
opts.agent = agent
535+
if err := doRun(context.Background(), h.env, opts, []string{"x"}); err != nil {
536+
t.Fatalf("%s: %v", agent, err)
537+
}
538+
if h.fake.created["agent"] != agent {
539+
t.Errorf("%s: created with %v", agent, h.fake.created["agent"])
540+
}
541+
}
542+
for _, bad := range []string{"gentle_shell", "pi-gentle", "Pi", ""} {
543+
h := newHarness(t, &fakePlatform{})
544+
opts := defaultOpts()
545+
opts.agent = bad
546+
err := doRun(context.Background(), h.env, opts, []string{"x"})
547+
if exitCode(err) != exitUsage || h.fake.created != nil {
548+
t.Errorf("%q: exit %d, sent %v", bad, exitCode(err), h.fake.created)
549+
}
550+
if err != nil && !strings.Contains(err.Error(), "pi, pi_gentle or hermes") {
551+
t.Errorf("%q: the error does not list the agents: %v", bad, err)
552+
}
553+
}
554+
if f := runCmd.Flags().Lookup("agent"); f == nil || !strings.Contains(f.Usage, "pi_gentle") {
555+
t.Errorf("--agent help does not mention pi_gentle")
556+
}
557+
}
558+
528559
func TestRunUsageErrorsExit64BeforeSendingAnything(t *testing.T) {
529560
long := strings.Repeat("a", maxPromptBytes+1)
530561
file := filepath.Join(t.TempDir(), "prompt.md")

‎internal/tui/tui.go‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3610,7 +3610,7 @@ func (m model) renderSetup(l layout) string {
36103610

36113611
// ── about renderer ───────────────────────────────────────────────────────────
36123612

3613-
const Version = "0.1.28"
3613+
const Version = "0.1.29"
36143614

36153615
func renderAbout(l layout) string {
36163616
var b strings.Builder

0 commit comments

Comments
 (0)