Skip to content

Commit cc5205f

Browse files
authored
Merge pull request #11 from sky-xo/fix/sandbox-flag-parsing
fix(spawn): correct --sandbox flag parsing for Gemini
2 parents ddf277f + c5ea73e commit cc5205f

4 files changed

Lines changed: 39 additions & 11 deletions

File tree

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,9 +54,9 @@ Names always include a unique 4-character suffix. The `--name` flag sets a prefi
5454
| Flag | Description |
5555
|------|-------------|
5656
| `--name` | Custom prefix for agent name |
57-
| `--sandbox` | Sandbox mode: `full` (default), `permissive`, or `none`/`read-only` |
57+
| `--sandbox` | Enable sandbox. Codex: `--sandbox` (defaults to `workspace-write`) or `--sandbox=VALUE` where VALUE is `read-only`, `workspace-write`, or `danger-full-access`. Gemini: `--sandbox` only (no value accepted) |
5858
| `--model` | Model to use (Codex: `o3`, `o4-mini`; Gemini: `gemini-2.5-pro`, etc.) |
59-
| `--yolo` | Auto-approve all tool calls (use with caution) |
59+
| `--yolo` | Auto-approve all tool calls (Gemini only) |
6060

6161
Agent state is stored in `~/.june/june.db`.
6262

TODO.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,3 +7,7 @@
77
- [ ] Create a consistent color palette for the UI (centralize colors used for borders, indicators, etc.)
88
- [ ] Character-level diff highlighting within changed lines (show specific changes, not just whole line)
99
- [ ] Full-width background - extend red/green background to right edge of panel
10+
11+
# Bugs
12+
13+
- [ ] Diffs don't currently show the entire diff

internal/cli/spawn.go

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -50,12 +50,15 @@ Examples:
5050
case "codex":
5151
// For Codex, if --sandbox was passed without value, default to workspace-write
5252
codexSandbox := sandbox
53-
if cmd.Flags().Changed("sandbox") && sandbox == "" {
53+
if sandbox == "true" {
5454
codexSandbox = "workspace-write"
5555
}
5656
return runSpawnCodex(name, task, model, reasoningEffort, codexSandbox, maxTokens)
5757
case "gemini":
58-
// For Gemini, sandbox is boolean - true if flag was passed at all
58+
// Gemini sandbox is boolean-only, reject explicit values
59+
if sandbox != "" && sandbox != "true" {
60+
return fmt.Errorf("Gemini --sandbox does not accept values, use --sandbox without a value")
61+
}
5962
geminiSandbox := cmd.Flags().Changed("sandbox")
6063
return runSpawnGemini(name, task, model, yolo, geminiSandbox)
6164
default:
@@ -68,7 +71,7 @@ Examples:
6871
cmd.Flags().StringVar(&name, "name", "", "Name prefix for the agent (auto-generated if omitted)")
6972
cmd.Flags().StringVar(&model, "model", "", "Model to use")
7073
cmd.Flags().StringVar(&sandbox, "sandbox", "", "Enable sandbox (Codex: optional value read-only|workspace-write|danger-full-access, defaults to workspace-write; Gemini: boolean)")
71-
cmd.Flags().Lookup("sandbox").NoOptDefVal = "" // Allow --sandbox without value
74+
cmd.Flags().Lookup("sandbox").NoOptDefVal = "true" // Allow --sandbox without value
7275

7376
// Codex-specific flags
7477
cmd.Flags().StringVar(&reasoningEffort, "reasoning-effort", "", "Reasoning effort (codex only)")

internal/cli/spawn_test.go

Lines changed: 27 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -183,13 +183,14 @@ func TestSpawnCmdFlagDefaults(t *testing.T) {
183183

184184
func TestSpawnCmdFlagParsing(t *testing.T) {
185185
tests := []struct {
186-
name string
187-
args []string
188-
wantErr bool
186+
name string
187+
args []string
188+
wantErr bool
189+
runValidation bool // if true, let RunE execute to test validation logic
189190
}{
190191
{
191192
name: "valid args with all flags",
192-
args: []string{"codex", "task", "--name", "test", "--model", "o3", "--reasoning-effort", "high", "--max-tokens", "4096", "--sandbox", "read-only"},
193+
args: []string{"codex", "task", "--name", "test", "--model", "o3", "--reasoning-effort", "high", "--max-tokens", "4096", "--sandbox=read-only"},
193194
wantErr: false,
194195
},
195196
{
@@ -212,14 +213,34 @@ func TestSpawnCmdFlagParsing(t *testing.T) {
212213
args: []string{"--name", "test"},
213214
wantErr: true,
214215
},
216+
{
217+
name: "sandbox without value followed by name flag",
218+
args: []string{"codex", "task", "--sandbox", "--name", "test"},
219+
wantErr: false,
220+
},
221+
{
222+
name: "gemini sandbox with name flag",
223+
args: []string{"gemini", "task", "--sandbox", "--name", "test"},
224+
wantErr: false,
225+
},
226+
{
227+
name: "gemini sandbox with explicit value errors",
228+
args: []string{"gemini", "task", "--sandbox=read-only"},
229+
wantErr: true,
230+
runValidation: true,
231+
},
215232
}
216233

217234
for _, tt := range tests {
218235
t.Run(tt.name, func(t *testing.T) {
219236
cmd := newSpawnCmd()
220237
cmd.SetArgs(tt.args)
221-
// Disable RunE to avoid actual execution
222-
cmd.RunE = func(c *cobra.Command, args []string) error { return nil }
238+
239+
// For tests that check validation errors, let RunE execute.
240+
// For others, disable to avoid actually spawning agents.
241+
if !tt.runValidation {
242+
cmd.RunE = func(c *cobra.Command, args []string) error { return nil }
243+
}
223244

224245
err := cmd.Execute()
225246
if (err != nil) != tt.wantErr {

0 commit comments

Comments
 (0)