Skip to content
Back to skills

Ainb Spawn

BSecurity

Spawn a coding-agent session correctly with `ainb run`: always into a git worktree, never bare into a plain checkout. Use whenever you are about to start a Claude/Codex/Gemini/Copilot session in a terminal. Guards the invocations that silently produce a `(broken)` workspace row, two agents sharing one working tree, a `--parent` flag that never fires, or a teardown that cancels itself and leaks the session.

  • 23 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added September 3, 2026
ai-agentsgobashgit

Works with

  • terminal
  • cli

Security analysis

B85/100
  • highPerforms destructive filesystem operations

Pro shows the line behind each finding and how to fix it

Scanned September 3, 2026

npx -y skills add stevengonsalvez/claudecode-bootstrap --skill ainb-spawn --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Ainb Spawn?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Ainb Spawn
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/stevengonsalvez-ainb-spawn/badge)](https://www.skillsdirectory.com/skills/stevengonsalvez-ainb-spawn)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: ainb-fleet:ainb-spawn
description: |
  Spawn a coding-agent session correctly with `ainb run`: always into a git
  worktree, never bare into a plain checkout. Use whenever you are about to
  start a Claude/Codex/Gemini/Copilot session in a terminal. Guards the
  invocations that silently produce a `(broken)` workspace row, two agents
  sharing one working tree, a `--parent` flag that never fires, or a teardown
  that cancels itself and leaks the session.
version: "0.1.0"
user-invocable: true
triggers:
  - ainb-fleet:ainb-spawn
  - ainb spawn
  - spawn a coding agent
  - run claude in a worktree
  - start an agent session
allowed-tools:
  - Bash
---

# ainb spawn, start a session correctly

One command, two legal shapes for `--repo`. Getting that choice wrong is what
shares a working tree between two agents or nests a worktree inside a worktree.

## The two legal shapes

Fresh session off a repo root (the common case):

```bash
ainb run \
  --repo /absolute/path/to/repo-root \
  --worktree --create-branch fix/issue-101 \
  --tool claude \
  --dangerously-skip-permissions \
  -p "$(cat /tmp/task-101.md)"
```

Existing task worktree (isolation already done, do not nest another):

```bash
ainb run --repo /absolute/path/to/existing/worktree --tool claude -p "$(cat task.md)"
```

Which shape? One command decides it (`.git` is a *file* in a real worktree, a
*directory* in a normal clone):

```bash
test -f "$P/.git" && echo "worktree: pass bare" || echo "repo root: add --worktree --create-branch"
```

## Flags, and why

| Flag | Why |
|---|---|
| `--repo <abs-path>` | Repo root, or an existing task worktree. Absolute, always. |
| `--create-branch <branch>` | Implies `--worktree` and names the branch. Prefer over bare `--worktree`, which invents `ainb/session-<shortid>`. |
| `--worktree` | Isolation. Lands at `~/.agents-in-a-box/worktrees/by-name/<repo>--<branch>--<shortid>`. |
| `--tool claude\|codex\|gemini\|copilot` | Which CLI to launch (default `claude`). |
| `--model <id>` | Passed through to the provider unchanged. Optional. |
| `--dangerously-skip-permissions` | Unattended runs only. |
| `-p "<task>"` | Initial prompt, sent once the input box is ready. |
| `--name <handle>` | Optional stable tmux handle. Legal: it changes the session/tmux name only, never `workspace_name`, and fleet routes on the tmux name. Prefer the minted name unless you want something to type at. |
| `--parent <session-id>` | Routes the child's completions to your inbox. Needs *your own* session id, which you must resolve (see below), not an env var. |

## Parent linkage, resolve your own id

There is **no `$AINB_SESSION_ID`**. ainb exports only `AINB_PARENT_SESSION` into
a session, and that holds the *parent's* id, not the session's own. Resolve
yours from the tmux session name:

```bash
MY_TMUX=$(tmux display-message -p '#{session_name}' 2>/dev/null)
MY_ID=$(ainb list --format json \
        | jq -r --arg t "$MY_TMUX" '.[] | select(.tmux_session_name == $t) | .session_id')

ainb run --repo "$REPO" --worktree --create-branch "$BRANCH" --tool claude \
  ${MY_ID:+--parent "$MY_ID"} -p "$(cat "$TASK_FILE")"
```

Empty `MY_ID` (not inside an ainb session) omits the flag and spawns unparented,
which is fine. The `${...:+...}` guard is not cosmetic: an unresolved id fails
two different ways, and only one of them is loud.

## Traps

| Trap | What happens | Do instead |
|---|---|---|
| `--repo <repo-root>` with no `--worktree` / `--create-branch` | Agent runs in the repo's own working tree; two agents stomp each other. The TUI used to render that row as `(broken)`; it now names it after the owning repo, so nothing in `ainb list` flags the mistake. | Add `--worktree --create-branch <branch>` |
| `--parent ""` (quoted, empty or whitespace-only) | Accepted by the parser, then trimmed and dropped by `ainb run`. The child spawns UNPARENTED, no warning, and its completions never reach your inbox. | `${MY_ID:+--parent "$MY_ID"}` so an empty id emits no flag |
| `--parent $MY_ID` unquoted with `MY_ID` unset (e.g. `"$AINB_SESSION_ID"`, which ainb never exports) | The token vanishes before clap sees it, so clap consumes the NEXT token as the parent id. Next token starts with `-`, or `--parent` was last: clap aborts with `error: a value is required for '--parent <PARENT>'`, exit 2, nothing spawns. Next token is a bare word (path, branch): clap swallows it as the parent id and the flag it belonged to is lost, corrupting the spawn. | Resolve `MY_ID` from the tmux name (above), then `${MY_ID:+--parent "$MY_ID"}` |
| `ainb kill <id>` / `ainb git cleanup` without `--force` | Both prompt `[y/N]` on stdin with no tty check. From a tool call the read returns empty, they print `Cancelled.` and exit 0, so the session leaks while you believe it is gone. | Always `--force` |
| `rm -rf <dir>` right after a bare `ainb kill` | Deletes the checkout out from under a still-live agent. | `--force`, then confirm via `ainb list` before deleting |
| `tmux new-session ... claude -p` for repo coding | No worktree, no session record, invisible to every fleet verb. | Use `ainb run` |

## Verify

```bash
ainb list --format json | jq -r '.[] | "\(.session_id)\t\(.workspace_name)\t\(.worktree_path)"'
ainb status <id>              # one-shot state
ainb logs <id> --lines 80     # recent output, -f to follow
ainb kill <id> --force        # teardown, exact id only; --force is mandatory here
ainb git cleanup --dry-run    # preview the worktree prune
ainb git cleanup --force      # perform it
```

`workspace_name == "(broken)"` means ainb could not resolve the session root to
a git repository at all: no ancestor directory holds a usable `.git`, and the
directory name carries no `<repo>--<branch>--<shortid>` hint to fall back on.
Kill it and respawn with `--worktree --create-branch`.

A plain checkout, or a subdirectory of one, is **not** broken. It resolves to the
repository that owns it and is labelled with that repository's name. It is only
unisolated, and `ainb list` will not tell you that, so a real-looking
`workspace_name` is not proof you passed the isolation flags.

## Note: subdirectory sessions carry the owning repo's name

Point `--repo` at a subdirectory of a checkout and the TUI workspace row shows
the **owning repository's** name, not the subdirectory's. That is intended (the
workspace row is the grouping key and the repo owns the group), but it reads as a
rename to anyone who remembers the old labels. Not a bug, and not a sign the
wrong path was passed.

## See also

- [`/ainb-fleet:standup`](../standup/SKILL.md) to confirm the session joined the fleet.
- `/coding-agent` (toolkit skill) for choosing between `ainb run`, a Task subagent, and raw tmux.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.