Repository navigation
Slice 1: Add workspace parameter to amicode_session tool #1060
Description
Important
Problem — The amicode_session tool always inherits the parent session's directory — there is no way for an agent to programmatically spawn a child session into an isolated git worktree. The backend APIs exist (POST /experimental/worktree, worktree.ready/worktree.failed events, Session.CreateInput.workspaceID) but the tool does not call them.
Approach — Add an optional workspace string parameter to amicode_session. When "create", call the existing worktree API, wait for readiness with a 30-second timeout, then bind the child session to the new worktree directory. When a path string, validate it as a git worktree of the current project. On any failure, fail hard — never silently fall back to the parent directory. Clean up orphan worktrees on partial failure.
Scope — in: tool schema, parseSpawnArgs extension, handler worktree logic, EngineClientShape extension, timeout + compensating cleanup, feature-gate error translation, soft warning at 5+ worktrees, tests · out: skill prompt updates (Slice 2), lifecycle management tool (Slice 3), engine API changes
Acceptance Criteria
-
amicode_sessionschema includesworkspacewith type["string", "null"]and description documenting"create", path, and null semantics -
parseSpawnArgsinsession_spawn.tsvalidates the newworkspacefield: acceptsnull,"create", or a non-empty string path; rejects other values - When
workspace: "create", the handler calls the worktree creation API (viaengineClient), waits for theworktree.readyevent, and creates the child session scoped to the returned worktree directory - The synchronous wait has a 30-second timeout — on expiry, the handler attempts
DELETEon the partial worktree and returns a timeout error - When session creation fails after successful worktree creation, the handler attempts a compensating
DELETEof the worktree (best-effort) before returning the session error - When
workspace: "<path>", the handler validates the path is a git worktree of the current project (the worktree's.gitfile points back to the main repo's.gitdirectory) and rejects unknown paths with a clear error - When the experimental worktrees feature gate is off, the API's rejection is translated into an actionable error message ("Workspace isolation requires the experimental worktrees feature to be enabled")
- A soft warning is included in the tool's response text when the project already has 5+ active worktrees (does not block creation)
- The tool fails hard on any worktree error — never silently falls back to the parent directory
-
EngineClientShapeis extended withworktreemethods (at minimumcreate,list,remove) so the handler and tests can type-check worktree calls - Existing
amicode_sessionbehavior is unchanged whenworkspaceisnullor omitted
Testing Decisions
Extend the existing test infrastructure in packages/extension/test/:
session_spawn.test.ts— add cases forparseSpawnArgswith theworkspacefield: null, "create", valid path, empty string, non-string → validates the pure arg parsingsession_spawn_double_create.test.ts— extendmakeMockEngine()withworktree: { create, list, remove }methods; add a test that concurrentworkspace: "create"spawns both get their own worktrees (the double-create gate deduplicates sessions, not worktrees)- New:
session_workspace.test.ts— focused integration tests for the worktree path:workspace: "create"→ mock engine returns worktree info → session created with worktree directoryworkspace: "create"+ worktree creation timeout → compensating delete called, tool returns errorworkspace: "create"+ session creation failure after worktree → compensating delete calledworkspace: "create"+ feature gate off (API rejects) → actionable error messageworkspace: "<path>"with valid worktree → session created with that directoryworkspace: "<path>"with invalid path → rejection errorworkspace: null→ unchanged behavior (inherits parent directory)
Reuse the makeMockEngine() pattern from existing tests, extended with worktree methods.
Key Decisions
-
String parameter, not object.
workspaceis"create" | "<path>" | null— a simple string for LLM reliability. Branch naming is left to the worktree API's default (theopencode/<slug>convention). If explicit branch control is needed later, migrate to an object in Slice 3. -
worktree.readymeansgit worktree addreturned 0. It does NOT include project bootstrap (dependency install, etc.). Bootstrap is the child session's skill's responsibility. -
Git-worktree-of-this-repo validation. Existing worktree paths are validated by checking the
.gitfile points back to the main repo's.gitdirectory — not limited to the known-sandboxes registry. This accepts manually-created worktrees. -
API is the feature-gate authority. The tool does not duplicate the experimental-feature check; it translates the API's rejection into an actionable error.
-
Error response structure. Tool errors include a
reasonfield distinguishing:timeout,api_rejected(feature gate),validation_failed(bad path),session_failed(post-worktree session error).
Constraints & Invariants
- The opencode engine's worktree APIs are consumed as-is — no engine changes in this slice
- The
EngineClientShapeinterface must remain backward-compatible — newworktreemethods are optional so existing tests that construct mock engines without them still compile - The
session_spawn.tsmodule must remain zero-import (pure policy) — worktree API calls stay in the handler, not the policy module - The existing double-create gate (
spawnGate.coalesce) continues to work — workspace parameter is included in the gate key so two concurrentworkspace: "create"spawns are NOT coalesced (each needs its own worktree)
Prior Art
packages/extension/src/amicode_tools_core.tslines 1941-2149 — the tool definition and handler to modifypackages/extension/opencode-plugin/session_spawn.ts— the pure policy module for arg parsingpackages/extension/test/session_spawn_double_create.test.tslines 43-64 — themakeMockEngine()pattern to extendpackages/app/src/components/prompt-input/submit.tslines 357-398 — the UI's worktree creation flow (reference implementation)packages/opencode/src/worktree/index.ts— theWorktree.Serviceinterface andInfotypepackages/opencode/src/session/session.tslines 261-272 —Session.CreateInputwith the existingworkspaceIDfield
Source
Part of #1059
Activity
amicode_workspacelifecycle management tool #1062feat(session): add workspace parameter to amicode_session (#1060)
feat: agent-initiated workspace isolation — wire amicode_session to t…
jeonghun-jj-lee commentedon Sep 14, 2026
Landed in #1063 (
5b25681a) — Slice 1:workspaceparameter onamicode_session. Shipped as part of the single-PR #1059 implementation. Closing now.