Session tools: create_session, delete_session #156

Open
opened 2026-09-15 18:25:01 +02:00 by lz · 0 comments
Owner

"Open a session on the auth bug" — the capability most of the value rides on. Depends on #154. Scope: nexus:write.

create_session(workspace, name, initial_message?)

Wraps createSession, which takes no masterKey — verified — so no vault work.

initial_message is a launch argument, not a nudge. claude accepts the prompt as a positional argument, so it appends in buildLaunchCommand and becomes the session's first turn. No tmux send-keys, no window resolution, no race against startup.

Trap, hit during the original probe: several claude flags are variadic — --channels <servers...>, --dangerously-load-development-channels <servers...> — and silently swallow a trailing positional prompt. The session died with Input must be provided either through stdin or as a prompt argument. Audit argument order in composeLaunch and pin it with a test: the nexus plugin's --plugin-dir is unconditional and extraClaudeArgs are appended after it, so the positional has to land after all of them.

Second trap from the same probe: piping claude's stdout (e.g. | tee) flips it into --print mode.

Session names are validated against git check-ref-format --branch via nexus/src/lib/git-ref.ts — reuse it rather than re-deriving. Slashes are allowed (feature/login).

Serialize creates per workspace. createSession shells out to git -C /workspace worktree add with no serialization, and concurrent adds contend on index.lock. The retry-once path is scoped to each session's own name, so the failure mode is flakiness rather than data loss — but two simultaneous creates can both land in it, and a tool makes rapid succession easy in a way the UI did not.

The optimistic status: 'creating' row is inserted before the slow worktree and tmux work, so the tool returns promptly and the client polls rather than blocking.

delete_session

Wraps deleteSession, which hard-deletes so the UNIQUE(worker_id, name) slot frees for re-creation. No masterKey.

Watch for

createSession refuses a removing row — surface that as a clear tool error rather than a generic failure.

Both tools must reject a kind='workspace_shell' row, or offer it deliberately: the workspace shell is at most one per worker, reuses the entrypoint's boot tmux window, and has its own POST/DELETE /api/workers/:id/sessions/workspace endpoints. Deleting it through the generic path is not the same operation.

Done when

Claude can open a named session in a chosen workspace with a first instruction that actually runs as its opening turn, and close it again — plus a test that fails if a variadic flag is ever appended after the positional prompt.

"Open a session on the auth bug" — the capability most of the value rides on. Depends on #154. Scope: `nexus:write`. ## `create_session(workspace, name, initial_message?)` Wraps `createSession`, which takes no `masterKey` — verified — so no vault work. **`initial_message` is a launch argument, not a nudge.** `claude` accepts the prompt as a **positional argument**, so it appends in `buildLaunchCommand` and becomes the session's first turn. No `tmux send-keys`, no window resolution, no race against startup. **Trap, hit during the original probe:** several claude flags are variadic — `--channels <servers...>`, `--dangerously-load-development-channels <servers...>` — and silently swallow a trailing positional prompt. The session died with `Input must be provided either through stdin or as a prompt argument`. Audit argument order in `composeLaunch` and **pin it with a test**: the nexus plugin's `--plugin-dir` is unconditional and `extraClaudeArgs` are appended after it, so the positional has to land after all of them. Second trap from the same probe: piping claude's stdout (e.g. `| tee`) flips it into `--print` mode. Session names are validated against `git check-ref-format --branch` via `nexus/src/lib/git-ref.ts` — reuse it rather than re-deriving. Slashes are allowed (`feature/login`). **Serialize creates per workspace.** `createSession` shells out to `git -C /workspace worktree add` with no serialization, and concurrent adds contend on `index.lock`. The retry-once path is scoped to each session's own name, so the failure mode is flakiness rather than data loss — but two simultaneous creates can both land in it, and a tool makes rapid succession easy in a way the UI did not. The optimistic `status: 'creating'` row is inserted before the slow worktree and tmux work, so the tool returns promptly and the client polls rather than blocking. ## `delete_session` Wraps `deleteSession`, which hard-deletes so the `UNIQUE(worker_id, name)` slot frees for re-creation. No `masterKey`. ## Watch for `createSession` refuses a `removing` row — surface that as a clear tool error rather than a generic failure. Both tools must reject a `kind='workspace_shell'` row, or offer it deliberately: the workspace shell is at most one per worker, reuses the entrypoint's boot tmux window, and has its own `POST/DELETE /api/workers/:id/sessions/workspace` endpoints. Deleting it through the generic path is not the same operation. ## Done when Claude can open a named session in a chosen workspace with a first instruction that actually runs as its opening turn, and close it again — plus a test that fails if a variadic flag is ever appended after the positional prompt.
lz added this to the MCP support (#140) milestone 2026-09-15 18:25:01 +02:00
Sign in to join this conversation.
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
lz/agent-nexus#156
No description provided.