sid-isnt-done 0.5.0

sid is a UNIX-inspired coding agent for Anthropic-compatible APIs
Documentation

SID(1)

NAME

sid - run a small, rc-configured coding agent in the current workspace

SYNOPSIS

sid [OPTIONS]
sid --prompt PROMPT [OPTIONS]
sid --resume SESSION [OPTIONS]
sid --raw [--resume SESSION] [OPTIONS]
sid --listen SPEC [--resume SESSION] [OPTIONS]
sid --connect SPEC [OPTIONS]
SID_HOME=DIR sid [OPTIONS]
sid --bash-debug COMMAND
sid-seatbelt [--writable-roots DIR[:DIR...]] -- COMMAND [ARG...]

Generated help spells long options with one leading dash. The parser also accepts the double-dash forms used below.

DESCRIPTION

sid starts an interactive coding-agent session rooted at the current working directory. The workspace is mounted for the model's virtual filesystem as /; that virtual mount is not an operating-system chroot. Agent definitions, tool definitions, and optional skills are read from rc-style configuration files rather than from hardcoded tool lists.

sid requires SID_HOME to be set and non-empty. When no sid configuration exists in SID_HOME, sid starts the built-in sid agent with no configured external tools. When agents.conf or tools.conf exists, configuration is loaded from SID_HOME.

The interactive prompt accepts ordinary user messages and slash commands. Use /help inside a running session for chat commands such as changing the model, switching agents, compacting the conversation into a new child session, saving or loading transcripts, clearing context, and printing session stats. Use --resume <session-id-or-dir> to reopen an earlier session directory, reload transcript.json, continue appending to the same journals, and restore the persisted bash shell state for future bash tool calls.

Use --prompt <text> to run one non-interactive user turn, print the assistant response, and exit. In prompt mode sid resumes the most recently started session for the current working directory by default; use --resume to target a specific session instead.

Use --raw to run sid as a JSONL protocol server on stdin/stdout. In raw mode the process owns session state and emits accepted request markers, typed events, prompts, and terminal results instead of the human-oriented terminal UI. Requests are semantic operations such as user turns, agent switches, compaction, and config updates. Raw mode is intended for alternative frontends and local automation. Use --listen SPEC to run the same protocol on a reconnectable socket instead of stdin/stdout. SPEC is tcp://HOST:PORT, vsock://CID:PORT on Linux, or unix:///path/to/socket on Unix platforms. New connections replace older connections and receive the server message history before live messages. Answered prompts are replayed as prompt_ack messages instead of fresh prompts, while unanswered prompts are replayed as prompts. Use --connect SPEC to attach the normal terminal UI to a listening raw server. The client speaks JSONL over the socket internally, but renders assistant output, tool output, prompts, results, and slash commands like an ordinary interactive sid session.

QUICKSTART

Install and initialize:

cargo install sid-isnt-done
SID_HOME=~/.sid sid-init

sid-init copies the bundled starter configuration (agents, tools, and prompts) into SID_HOME. It requires SID_HOME to be set. Files that already exist are skipped, so it is safe to re-run after upgrading.

Start a session:

export CLAUDIUS_API_KEY="..."
SID_HOME=~/.sid sid

Run one prompt and continue the latest session for the current directory:

SID_HOME=~/.sid sid --prompt "Summarize the pending changes"

Run one bash command through the configured bash tool and exit:

SID_HOME=~/.sid sid --bash-debug 'pwd && ls'

From a source checkout, you can skip sid-init and point SID_HOME directly at the bundled init/ directory:

cargo build
SID_HOME=init cargo run --bin sid
SID_HOME=init cargo run --bin sid -- --bash-debug 'pwd && ls'

BUILDING

sid is a Rust project using the 2024 edition. Use Rust 1.94 or newer and the normal Cargo workflow:

cargo build
cargo test
cargo install --path .

Interactive sessions use the Anthropic client from claudius. Set CLAUDIUS_API_KEY or ANTHROPIC_API_KEY before starting sid. Values that begin with file:// are treated by claudius as paths to files containing the API key.

macOS is the only platform where sid can use /usr/bin/sandbox-exec. On other systems, or on macOS systems where that program is unavailable, sid runs bash and external tools without the Seatbelt wrapper and prints a startup warning.

OPTIONS

--param-model MODEL : Use MODEL for the session. The default is supplied by claudius and is currently printed by sid --help.

--param-system PROMPT : Set the initial system prompt. Agent prompt files and agent configuration can override this value when a configured workspace is loaded.

--param-max-tokens TOKENS : Set the maximum response tokens per model request.

--param-temperature TEMP : Set sampling temperature. TEMP must be between 0.0 and 1.0.

--param-top-p TOP_P : Set nucleus sampling. TOP_P must be between 0.0 and 1.0.

--param-top-k TOP_K : Set top-k sampling.

--param-thinking TOKENS : Enable extended thinking with the given token budget.

--param-no-color : Disable ANSI color and style output.

--bash-debug COMMAND : Run COMMAND through the configured built-in bash tool and exit. This is useful for checking tool configuration without starting an interactive chat.

--prompt PROMPT : Run one non-interactive user turn, print the assistant response, and exit. Unless --resume is supplied, prompt mode resumes the most recently started session recorded for the current working directory. If no matching session exists, sid creates a new one.

--raw : Run a JSONL protocol server on stdin/stdout instead of the interactive readline UI. Stdout is reserved for protocol messages in this mode. Raw server messages include a monotonic sequence field so clients can de-duplicate replayed messages.

--listen SPEC : Run a reconnectable JSONL protocol server and imply --raw. SPEC is tcp://HOST:PORT, vsock://CID:PORT on Linux, with CID optional or any for VMADDR_CID_ANY, or unix:///path/to/socket on Unix platforms. When a new client connects, sid disconnects the previous socket, replays all prior server messages to the new socket, and then continues streaming live output. Accepted user_turn requests are replayed as request messages before their related events/results so frontends can rebuild the transcript from the raw stream alone. Prompts that were already answered are replayed as prompt_ack messages with the accepted response; unanswered prompts are replayed as normal prompt messages. A replay_complete message marks the end of the replayed history.

--connect SPEC : Connect the normal terminal UI to a reconnectable JSONL protocol server. SPEC accepts the same URL forms as --listen; for vsock://PORT, vsock://any:PORT, and vsock://-1:PORT, connect mode targets the host CID. --connect is mutually exclusive with --raw, --listen, --prompt, --resume, and --bash-debug.

--resume SESSION : Resume an existing session by timestamp id or by session directory path. Session ids are resolved under ${SID_SESSIONS:-${SID_HOME}/sessions}. Resuming reloads the saved transcript, continues the existing event and API journals, preserves ordered tool numbering, appends a synthetic bash {"restart": true} tool/result pair to the transcript, and leaves the next real bash command to start a fresh shell.

--help : Print the command-line help.

MODEL SELECTION

The model can be selected at startup with --param-model MODEL, configured per agent with <agent>_MODEL, or changed during a session with /model MODEL. Run sid --help to see the compiled default model. Use /help inside a session to see the current chat commands.

sid passes model names through to claudius; it does not maintain a separate registry of available model names. Prefer provider documentation or the Anthropic models API for the current model list.

CONFIGURATION

Configuration uses two required files when configuration is present:

agents.conf
tools.conf

Agent prompts live in agents/. External tool executables and manifests live in tools/. Skills live in skills/<skill>/SKILL.md unless SID_SKILLS_PATH is set.

The bundled starter configuration is in init/:

SID_HOME=init sid

AGENTS

An agent is an rc-conf service in agents.conf. Service names are discovered by rc_conf; each service may define fields under the service prefix:

DEFAULT_AGENT="build"

build_ENABLED="YES"
build_NAME="Let's Go"
build_DESC="buildit"
build_TOOLS="bash edit format"
build_SKILLS="*"
build_MODEL="claude-sonnet-4-5"
build_MAX_TOKENS="8192"
build_THINKING="on"

<agent>_ENABLED : Controls whether the agent can start. YES starts immediately, MANUAL asks the operator before starting, and NO disables the agent.

<agent>_NAME : Optional display name.

<agent>_DESC : Optional description.

<agent>_TOOLS : Space-split list of configured tool names exposed to the agent.

<agent>_SKILLS : Space-split list of skills to mount. Use * to mount every loaded skill.

<agent>_MODEL, <agent>_SYSTEM, <agent>_MAX_TOKENS : Optional model, inline system-prompt override, and response-token overrides.

<agent>_PROMPT : Optional colon-separated list of markdown files. Relative paths are resolved under the config root, ~/ expands from HOME, all listed files must exist, and their contents are concatenated in order with blank lines. This becomes the agent's base system prompt before <agent>_SYSTEM overrides are applied.

<agent>_PROMPT_COMPACTION, <agent>_PROMPT_MEMORY_EXPERT : Optional named prompt bundles resolved the same way as <agent>_PROMPT. sid uses COMPACTION for the /compact request sent to that agent and MEMORY_EXPERT for the follow-up addendum used by ask_an_expert on compacted sessions. Other PROMPT_* keys are ignored by sid.

<agent>_TEMPERATURE, <agent>_TOP_P, <agent>_TOP_K : Optional sampling controls.

<agent>_STOP_SEQUENCES : Space-split stop sequence list. Shell-style quoting is supported by shvar.

<agent>_THINKING : on, yes, or true enables the default thinking budget. A number sets an explicit budget. off, no, or false disables thinking.

<agent>_USE_COLOR, <agent>_NO_COLOR : Optional terminal color controls.

<agent>_SESSION_BUDGET : Optional token budget for the session.

<agent>_CACHING_ENABLED : Optional prompt-cache toggle.

<agent>_USER_INSTRUCTIONS : Optional boolean. Defaults to YES. Set to NO to disable automatic hook-based user-instruction injection for this agent.

<agent>_AGENTS_MD : Optional boolean. Defaults to YES. Set to NO to disable AGENTS.md file injection.

<agent>_AGENTS_MD_PATH : Optional colon-separated list of AGENTS.md files to read. Relative paths are resolved under the workspace root, ~/ expands from HOME, missing files are skipped, and existing files are concatenated in path order. Put global files before local files so local instructions appear later in the injected document with proper context. If unset, sid uses AGENTS_MD_PATH from the environment, then falls back to ./AGENTS.md.

<agent>_USER_INSTRUCTIONS_HOOK : Optional rc-conf service name. sid invokes agents/<service> run for each user turn and appends the hook's standard output to the injected user instructions. The executable must answer rcvar and run.

If <agent>_PROMPT is unset, the prompt file for an agent is agents/<agent>.md. If the agent is an alias, sid follows the rc-conf alias lookup order and uses the first matching prompt file. Prompt-file content becomes the agent's system prompt unless overridden by <agent>_SYSTEM.

If DEFAULT_AGENT is unset, sid starts the first enabled agent. If no agent is enabled, it starts the first manual agent after confirmation.

Within an interactive session, sid can hand work from one configured agent to another without restarting:

/compact
/agent
/agent list
/agent switch <name>

The active transcript, session journals, and persisted bash state remain tied to the same sid session directory. Explicit runtime overrides such as /model, /temperature, /stop, /thinking, /budget, and /cache remain in effect after an agent switch until they are changed again.

/compact runs the reserved compact agent when it is configured in agents.conf; otherwise sid uses a built-in compaction prompt. The command creates a new child session whose initial transcript is a summary of the prior session. Set compact_PROMPT_COMPACTION to override the request sent to the compactor and compact_PROMPT_MEMORY_EXPERT to override the follow-up memory mode prompt captured into compacted-session provenance. Compacted sessions expose an ask_an_expert tool that can consult the earlier summary writer by contextual memory.

USER INSTRUCTIONS

User instructions are dynamically appended as a final text block on each user turn before sid sends the turn to the model. The saved conversation history is remains after the turn, so that caching works and the agent always has proper context on the things to which they pay attention.

Hook output is wrapped under # User instructions from hook <name>. Direct system and operator instructions take precedence over these injected user instructions.

A hook is an rc-style executable in agents/. It uses agents.conf plus a per-invocation overlay and receives RC_CONF_PATH, RC_D_PATH, RCVAR_ARGV0, and any rcvars it advertises. Common advertised variables are:

<hook>_WORKSPACE_ROOT
<hook>_CONFIG_ROOT
<hook>_AGENT_ID
<hook>_HOOK_NAME
<hook>_AGENTS_MD_PATH
<hook>_USER_MESSAGE_FILE
<hook>_SKILLS_MANIFEST_FILE
<hook>_SKILLS_DIR
<hook>_SCRATCH_DIR
<hook>_TEMP_DIR
<hook>_TMPDIR
<hook>_RC_CONF_PATH
<hook>_RC_D_PATH

Example hook:

#!/bin/sh
set -eu

PREFIX=${RCVAR_ARGV0:?missing RCVAR_ARGV0}

case "${1:-}" in
rcvar)
    printf '%s\n' \
        "${PREFIX}_WORKSPACE_ROOT" \
        "${PREFIX}_AGENT_ID"
    ;;
run)
    WORKSPACE_ROOT=$(printenv "${PREFIX}_WORKSPACE_ROOT")
    AGENT_ID=$(printenv "${PREFIX}_AGENT_ID")
    printf 'Agent %s is working in %s\n' "$AGENT_ID" "$WORKSPACE_ROOT"
    ;;
*)
    echo "usage: $0 [rcvar|run]" >&2
    exit 129
    ;;
esac

SKILLS

Skills are markdown documents mounted read-only into the model-visible virtual filesystem. By default, sid scans:

skills/<skill>/SKILL.md

Set SID_SKILLS_PATH to a colon-separated list of directories to load skills from somewhere else. Each directory in the path is scanned for immediate children containing SKILL.md. If two directories provide the same skill id, the earlier directory wins.

Expose skills to an agent with <agent>_SKILLS:

build_SKILLS="rust-style release-checklist"

Use * to expose every loaded skill:

build_SKILLS="*"

A skill should be self-contained markdown that tells the model when to use it and what procedure to follow. Keep skill ids stable and filesystem-friendly; the document is mounted for the model at /skills/<skill>/SKILL.md. Bash and external tools do not see this virtual /skills mount.

The bundled skill-inject user-instructions hook delegates to sid-skill-inject. Enable it with <agent>_USER_INSTRUCTIONS_HOOK and mention an exposed skill as $skill-id in a user prompt to append a Codex-style block to that turn:

<skill>
<name>skill-id</name>
<path>/skills/skill-id/SKILL.md</path>
...skill markdown...
</skill>

Custom hooks can symlink to sid-skill-inject or exec sid-skill-inject "$@" to reuse the same $skill-id parsing and block rendering. The sid-skill-inject binary must be on the hook process's PATH.

TOOLS

Tools are rc-conf services in tools.conf. There are no implicit external tools: a tool named by an agent must also be defined in tools.conf. Canonical tool ids and model-visible external tool names must be 1-64 ASCII letters, digits, underscores, or hyphens.

bash_ENABLED="MANUAL"
edit_ENABLED="MANUAL"
edit_CONFIRM="YES"
fmt_ENABLED="MANUAL"
fmt_CONFIRM="YES"

format_INHERIT="YES"
format_ALIASES="fmt"

<tool>_ENABLED : Controls whether the tool can be used. YES allows calls, MANUAL prompts the operator for every call, and NO disables the tool.

<tool>_ALIASES : Defines aliases resolved before filesystem lookup. In the example above, format resolves to canonical tool fmt.

<tool>_CONFIRM : Optional boolean. When YES and the tool is MANUAL, sid invokes tools/<id> confirm before the host-owned yes/no prompt. The confirm subcommand renders a preview to standard output; it does not authorize the call and must not perform the tool operation. The starter edit tool keeps view previews compact, but mutating editor commands render a file summary plus a diff preview. Set DIFF to a shell command to filter that unified diff, or set DIFF empty to show the raw unified diff text.

<tool>_PROMPT : Optional colon-separated markdown bundle resolved under the config root and concatenated in order. sid loads it into tool config metadata. Other prompt-shaped tool variables remain available to your rc-style tool scripts, but sid does not ingest them unless they become host-owned keys.

bash : Built-in bash capability. It is exposed to the model as Anthropic's bash tool. It runs in the host filesystem namespace, not a chroot. The initial working directory is the workspace root; host / remains visible subject to normal OS permissions and the optional macOS Seatbelt policy. It does not need a tools/bash executable or tools/bash.json manifest.

edit : Built-in text-editor capability. It is exposed to the model as Anthropic's text editor tool, but calls are routed through tools/edit; the starter script execs sid-editor-tool. The helper process is not chrooted, but the editor protocol resolves file paths under WORKSPACE_ROOT; /etc/passwd in an editor request means $WORKSPACE_ROOT/etc/passwd, not host /etc/passwd. tools/edit must exist and be executable when edit is configured. A tools/edit.json manifest is optional because the model-visible schema comes from the built-in Anthropic text-editor tool definition.

read : Read a file or a line range from the workspace. This is a narrower, read-only alternative to the editor's view command. The starter tools/read script delegates to sid-editor-tool --readonly. It accepts path, and optional start_line/end_line parameters (1-indexed, inclusive; -1 means end of file). Output includes line numbers. Directories are listed instead of read. Enabled YES by default because it is read-only.

search : Search the workspace for a pattern using ripgrep. Returns matching lines with file paths and line numbers. Accepts pattern (regex by default), optional path to restrict scope, fixed_strings for literal matching, include for glob-based file filtering, and max_results (default 200). Enabled YES by default because it is read-only.

glob : List workspace files matching a glob pattern. Accepts pattern (e.g. *.rs, Cargo.*) and optional path to restrict to a subdirectory. Ignores .git, node_modules, and target directories. Enabled YES by default because it is read-only.

git_status : Show the working tree status of the git repository. Accepts an optional short boolean for --short format. Enabled YES by default because it is read-only.

git_diff : Show changes in the git working tree or between commits. Accepts optional staged boolean for --cached, path to restrict scope, and ref to diff against a specific commit or branch. Enabled YES by default because it is read-only.

External tools must provide both files below for the canonical tool id:

tools/<id>
tools/<id>.json

The executable must be marked executable. The manifest supplies the model description and input schema:

{
  "protocol_version": 1,
  "description": "Format source files in the workspace.",
  "input_schema": {
    "type": "object",
    "properties": {
      "paths": {
        "type": "array",
        "items": { "type": "string" }
      }
    },
    "required": ["paths"]
  }
}

Manifest rules:

  • protocol_version is required and must be 1.
  • description is required and must not be empty.
  • input_schema is required and must be a JSON object.
  • The manifest does not contain the tool name.

The model-visible name is the name listed in <agent>_TOOLS, not necessarily the canonical id. Thus format can resolve to canonical executable tools/fmt while still appearing to the model as format.

TOOL PROTOCOL

Tool executables are rc-style programs. They must respond to rcvar and run; they may also respond to confirm for manual-call previews.

#!/bin/sh
set -eu

PREFIX=${RCVAR_ARGV0:?missing RCVAR_ARGV0}

case "${1:-}" in
rcvar)
    printf '%s\n' \
        "${PREFIX}_REQUEST_FILE" \
        "${PREFIX}_RESULT_FILE" \
        "${PREFIX}_SCRATCH_DIR" \
        "${PREFIX}_TEMP_DIR" \
        "${PREFIX}_TMPDIR" \
        "${PREFIX}_WORKSPACE_ROOT" \
        "${PREFIX}_AGENT_ID" \
        "${PREFIX}_TOOL_ID" \
        "${PREFIX}_TOOL_NAME" \
        "${PREFIX}_TOOL_PROTOCOL" \
        "${PREFIX}_RC_CONF_PATH" \
        "${PREFIX}_RC_D_PATH"
    ;;
confirm)
    export REQUEST_FILE=$(printenv "${PREFIX}_REQUEST_FILE")
    export WORKSPACE_ROOT=$(printenv "${PREFIX}_WORKSPACE_ROOT")
    printf 'Format paths from %s under %s\n' "$REQUEST_FILE" "$WORKSPACE_ROOT"
    ;;
run)
    export REQUEST_FILE=$(printenv "${PREFIX}_REQUEST_FILE")
    export RESULT_FILE=$(printenv "${PREFIX}_RESULT_FILE")
    export TMPDIR=$(printenv "${PREFIX}_TMPDIR")
    export WORKSPACE_ROOT=$(printenv "${PREFIX}_WORKSPACE_ROOT")
    exec ./tools/fmt.impl
    ;;
*)
    echo "usage: $0 [rcvar|confirm|run]" >&2
    exit 129
    ;;
esac

Each sid process creates a timestamp-named session directory under ${SID_SESSIONS:-${SID_HOME}/sessions}, for example 2026-04-20T18-42-13.123456-0700. Durable session state is written to a small set of append-only journals:

session.json
transcript.json
events.jsonl
api.jsonl
tool-streams.jsonl

Starting sid --resume <session> reuses that directory instead of creating a new one. sid reloads transcript.json, appends a session_resume record to events.jsonl, continues api.jsonl and ordered tool sequences, appends a synthetic bash {"restart": true} tool/result pair to transcript.json, and starts the next real PTY-backed bash command from a fresh shell.

Starting sid --prompt <text> without --resume scans the sessions root for the most recently started session whose recorded workspace_root matches the current directory, resumes that transcript, appends the new turn, and exits after printing the response.

Running /compact creates a fresh session directory instead of mutating the current one. The new session.json records which prior session it came from plus the prompt/model snapshot for the summary writer so future ask_an_expert calls can recurse through older compacted sessions.

For each tool call, sid creates a fresh ordered runtime directory under <session>/tmp/tool-000001/, writes request.json, writes an rc-conf overlay, invokes tools/<id> run, reads result.json, appends lifecycle and stream records to the session journals, then deletes the runtime directory by default. The tool process runs with the workspace root as its current directory, receives a per-invocation TMPDIR, and inherits standard input, standard output, and standard error. Tool processes are not chrooted; host / is still the process root unless the operating system or sandbox policy denies a particular operation.

For MANUAL tools with <tool>_CONFIRM=YES, sid prepares the same request and overlay, invokes tools/<id> confirm, captures its stdout as preview text, appends confirmation output to tool-streams.jsonl, then asks the operator for yes/no itself. If preview rendering fails, sid falls back to showing the raw request JSON. The real run subcommand is not invoked unless the operator approves.

The request file has this shape:

{
  "protocol_version": 1,
  "request_id": "sidreq_123",
  "tool": {
    "id": "fmt"
  },
  "invocation": {
    "tool_use_id": "toolu_abc",
    "input": {
      "paths": ["src/lib.rs"]
    }
  },
  "agent": {
    "id": "build"
  },
  "workspace": {
    "root": "/abs/workspace",
    "cwd": "/abs/workspace"
  },
  "files": {
    "scratch_dir": "/sid/sessions/2026-04-20T18-42-13.123456-0700/tmp/tool-000001",
    "temp_dir": "/sid/sessions/2026-04-20T18-42-13.123456-0700/tmp/tool-000001/tmp",
    "result_file": "/sid/sessions/2026-04-20T18-42-13.123456-0700/tmp/tool-000001/result.json"
  }
}

A successful result is:

{
  "protocol_version": 1,
  "request_id": "sidreq_123",
  "ok": true,
  "output": {
    "kind": "text",
    "text": "Formatted 3 files."
  }
}

A handled failure is:

{
  "protocol_version": 1,
  "request_id": "sidreq_123",
  "ok": false,
  "error": {
    "code": "invalid_input",
    "message": "paths must not be empty"
  }
}

Protocol rules:

  • During confirm, standard output is the human-readable preview.
  • During run, standard output and standard error are for the human terminal.
  • When a session is active, confirm, stdout, and stderr bytes are copied into tool-streams.jsonl. Non-UTF-8 chunks are stored as base64.
  • During run, sid only parses result.json.
  • Exit status 0 means process transport succeeded, so result.json must exist and be valid.
  • Nonzero exit status is treated as process failure; any partial result file is ignored.
  • request_id in the result must match the request.
  • Protocol v1 output is text-only.
  • Runtime tool scratch is deleted after the invocation unless a debug keep environment variable is set.

ENVIRONMENT

SID_HOME : Configuration root. Must be set and non-empty.

SID_SESSIONS : Session directory root. If unset or empty, sid stores sessions under ${SID_HOME}/sessions.

SID_SESSION_ID : Timestamp session id for the current sid process. Set by sid for child processes.

SID_SESSION_DIR : Absolute or configured path to the current session directory. Set by sid for child processes.

SID_KEEP_TOOL_SCRATCH : Set to 1, true, yes, or on to preserve per-tool runtime directories under <session>/tmp/ after invocations.

SID_KEEP_FAILED_TOOL_SCRATCH : Set to 1, true, yes, or on to preserve per-tool runtime directories only for failed invocations.

SID_SKILLS_PATH : Colon-separated list of directories to scan for */SKILL.md. If unset, sid scans skills/ under the configuration root.

<hook>_USER_MESSAGE_FILE : Per-turn user-instructions hook rcvar containing a scratch file with the current user message text.

<hook>_SKILLS_MANIFEST_FILE : Per-turn user-instructions hook rcvar containing a tab-separated manifest of exposed, $mention-invocable skills. Each row is skill-id<TAB>/skills/<skill-id>/SKILL.md<TAB>scratch-content-file.

<hook>_SKILLS_DIR : Per-turn user-instructions hook rcvar containing the scratch directory that holds skill content files referenced by <hook>_SKILLS_MANIFEST_FILE.

AGENTS_MD_PATH : Colon-separated list of AGENTS.md files to inject when <agent>_AGENTS_MD_PATH is unset. Relative paths are resolved under the workspace root. Files are concatenated in order, so list global files before local files if you desire that. If both are unset, sid checks ./AGENTS.md.

SID_WORKSPACE_ROOT : Set by sid for child processes to the absolute workspace root.

RCVAR_ARGV0 : Set during tool invocation to the invoked tool name rendered as an rc variable prefix.

RC_CONF_PATH : Set during tool invocation to <config-root>/tools.conf:<session>/tmp/tool-000001/tool-invoke.conf.

RC_D_PATH : Set during tool invocation to <config-root>/tools.

For each configured tool service, the overlay binds these variables under that service's prefix:

<tool>_REQUEST_FILE
<tool>_RESULT_FILE
<tool>_SCRATCH_DIR
<tool>_TEMP_DIR
<tool>_TMPDIR
<tool>_WORKSPACE_ROOT
<tool>_SESSION_ID
<tool>_SESSION_DIR
<tool>_AGENT_ID
<tool>_TOOL_ID
<tool>_TOOL_NAME
<tool>_TOOL_PROTOCOL
<tool>_RC_CONF_PATH
<tool>_RC_D_PATH

Aliases get their own prefix. If the model invokes format, the tool reads format_REQUEST_FILE; if it invokes fmt, it reads fmt_REQUEST_FILE.

SANDBOXING

On macOS, sid wraps bash and external tool processes with /usr/bin/sandbox-exec when it is available. This is a sandbox wrapper, not a chroot: processes still see host /. The generated policy allows reads from the workspace, session scratch, temporary directories, ~/src, ~/.cargo, ~/.rustup, common Git config locations under $HOME, and /Library/Developer/CommandLineTools; and, writes to the workspace, session directory, and system temporary directory, and loopback networking. On systems without sandbox-exec, commands run without this wrapper.

sid-seatbelt is a helper for running an arbitrary command under the same macOS Seatbelt policy:

sid-seatbelt --writable-roots "$PWD:/tmp" -- make test

FILES

agents.conf : Agent services and default-agent selection.

agents/<agent>.md : Agent prompt markdown.

tools.conf : Tool services, enable states, and aliases.

tools/<id> : Rc-style executable for an external tool or the edit bridge.

tools/<id>.json : Tool manifest for model-visible external tools.

skills/<skill>/SKILL.md : Optional skill document mounted read-only under /skills/<skill>/.

${SID_SESSIONS:-${SID_HOME}/sessions}/${SID_SESSION_ID}/session.json : Session metadata with the timestamp id, ISO-like creation time, microsecond Unix timestamp, process id, and recorded workspace_root.

${SID_SESSIONS:-${SID_HOME}/sessions}/${SID_SESSION_ID}/transcript.json : Auto-saved chat transcript.

${SID_SESSIONS:-${SID_HOME}/sessions}/${SID_SESSION_ID}/events.jsonl : Session and tool lifecycle journal.

${SID_SESSIONS:-${SID_HOME}/sessions}/${SID_SESSION_ID}/api.jsonl : Ordered API request and response payload journal.

${SID_SESSIONS:-${SID_HOME}/sessions}/${SID_SESSION_ID}/tool-streams.jsonl : Tool confirmation, stdout, and stderr stream journal.

${SID_SESSIONS:-${SID_HOME}/sessions}/${SID_SESSION_ID}/tmp/ : Runtime scratch. Tool directories and bash temporary files live here while needed and are cleaned by default.

TROUBLESHOOTING

API key not provided and ANTHROPIC_API_KEY environment variable not set : Set CLAUDIUS_API_KEY or ANTHROPIC_API_KEY before starting sid.

agent references an undefined tool : The agent listed a name in <agent>_TOOLS that does not have a matching service in tools.conf. Add the tool service or remove it from the agent.

required tool executable does not exist : External tools need an executable at tools/<id>. The configured edit tool also needs an executable tools/edit bridge, normally copied from init/tools/edit.

required tool manifest does not exist : External tools need tools/<id>.json. The built-in bash and edit tools do not require manifests.

tool must be executable : Mark the tool script executable, for example chmod +x tools/fmt.

edit is disabled, bash is disabled, or edit call denied by operator : Check <tool>_ENABLED in tools.conf. YES allows the tool, MANUAL prompts before each use, and NO disables it.

Startup warning that sid will run bash and external tools UNSANDBOXED : /usr/bin/sandbox-exec is unavailable, so sid cannot apply the macOS Seatbelt wrapper. Bash and external tools still run, but without that sandbox policy.

sandbox-exec: sandbox_apply: Operation not permitted : sandbox-exec exists, but the current host or parent sandbox refused to apply the policy. Run sid outside the enclosing sandbox or on a macOS environment that permits Seatbelt policy application.

EXIT STATUS

0 : Successful interactive session, accepted manual abort, or successful --bash-debug command.

1 : Help display, startup failure, configuration failure, client initialization failure, I/O failure, or --bash-debug failure.

64 : Command-line parse failure reported by arrrg.

EXAMPLES

Start with the bundled manual-confirmation tools:

SID_HOME=init sid

Run a one-shot bash configuration check:

SID_HOME=init sid --bash-debug 'pwd && ls'

Define a formatter tool:

cat >tools.conf <<'EOF'
fmt_ENABLED="YES"
format_INHERIT="YES"
format_ALIASES="fmt"
EOF

mkdir -p tools agents

Expose it to an agent:

cat >agents.conf <<'EOF'
DEFAULT_AGENT="build"
build_ENABLED="YES"
build_TOOLS="format"
EOF

cat >agents/build.md <<'EOF'
# Build

You are an expert builder.
EOF

Implement tools/fmt, mark it executable, and place the schema in tools/fmt.json. Calls to format will execute the canonical fmt tool while preserving format as the model-visible tool name.

SEE ALSO

SID-EDITOR-TOOL(1), SID-SEATBELT(1), RCINVOKE(1), SANDBOX-EXEC(1)

SID-EDITOR-TOOL(1)

NAME

sid-editor-tool - execute the sid text-editor tool protocol

SYNOPSIS

sid-editor-tool
sid-editor-tool --readonly
tools/edit confirm
tools/edit run
tools/read confirm
tools/read run

DESCRIPTION

sid-editor-tool is the helper used by the configured edit and read tools. It is not an interactive editor. In its default mode, confirm simulates mutating editor operations in memory and prints a diff preview to standard output, while run reads a sid tool request from REQUEST_FILE, executes one filesystem edit operation relative to WORKSPACE_ROOT, and writes a sid tool result to RESULT_FILE. With --readonly, the helper serves the read tool: it previews read requests, formats file contents with line numbers, lists directories, and rejects mutating editor commands. The helper process is not chrooted, but editor paths are workspace-rooted by the protocol implementation.

The starter init/tools/edit and init/tools/read scripts are the normal entrypoints. They receive prefixed rc-conf variables from sid, export the unprefixed environment used by sid-editor-tool, then exec sid-editor-tool with the appropriate mode flags.

COMMANDS

view : Read a file. Input fields are path and optional view_range.

str_replace : Replace one exact string in a file. Input fields are path, old_str, and optional new_str.

insert : Insert text at a line. Input fields are path, insert_line, and either insert_text or new_str.

create : Create a new file. Input fields are path and file_text.

COMMAND INPUT EXAMPLES

These examples show the invocation.input object inside the sid tool request envelope. The helper normally receives that envelope through REQUEST_FILE when tools/edit run is invoked by sid.

View a file:

{
  "command": "view",
  "path": "src/lib.rs"
}

View a line range:

{
  "command": "view",
  "path": "src/lib.rs",
  "view_range": [10, 40]
}

Replace one exact string:

{
  "command": "str_replace",
  "path": "README.md",
  "old_str": "old text",
  "new_str": "new text"
}

Insert text at a line:

{
  "command": "insert",
  "path": "README.md",
  "insert_line": 12,
  "insert_text": "Inserted text\n"
}

Create a file:

{
  "command": "create",
  "path": "notes/todo.md",
  "file_text": "# Todo\n"
}

ENVIRONMENT

REQUEST_FILE : Path to the JSON request envelope.

RESULT_FILE : Path where the JSON result envelope must be written.

WORKSPACE_ROOT : Workspace root used for filesystem operations. Leading slashes in editor paths are stripped before joining with this directory, so editor path / names WORKSPACE_ROOT, not host /.

DIFF : Optional shell command used by confirm mode to render mutating edit previews from raw unified diff text. An empty value disables styling and prints the raw unified diff. When unset, the built-in sidiff renderer is used.

NO_COLOR : Disables ANSI color in the built-in sidiff renderer used by confirm mode.

EXIT STATUS

0 : The helper read the request and wrote a protocol result. The result may still contain "ok": false for handled editor failures.

nonzero : The helper failed before it could complete protocol transport, usually because a required environment variable was missing or a request/result file could not be read or written.

SEE ALSO

SID(1), SID TOOL PROTOCOL

SID-SEATBELT(1)

NAME

sid-seatbelt - run a command inside sid's macOS Seatbelt sandbox policy

SYNOPSIS

sid-seatbelt [--writable-roots DIR[:DIR...]] -- COMMAND [ARG...]

Generated help spells long options with one leading dash. The parser also accepts the double-dash form used above.

DESCRIPTION

sid-seatbelt execs COMMAND under /usr/bin/sandbox-exec using the same policy builder that sid uses for sandboxed bash and external tool processes. It is a macOS helper; it exits with an error when /usr/bin/sandbox-exec is not available. It does not chroot COMMAND; host / remains the process root.

The policy is deny-by-default, permits reads from writable roots outside $HOME, permits writes to configured writable roots and temporary directories, and limits network access to loopback. Reads from the user's home directory are limited to ~/src, ~/.cargo, ~/.rustup, ~/.config/git, and selected Git dotfiles such as ~/.gitconfig. It also allows /Library/Developer/CommandLineTools for system toolchain support.

OPTIONS

--writable-roots DIR[:DIR...] : Colon-separated list of directories that should be writable inside the sandbox.

EXAMPLES

Run tests with the current workspace and /tmp writable:

sid-seatbelt --writable-roots "$PWD:/tmp" -- cargo test

Start a local development server that may bind a loopback port:

sid-seatbelt --writable-roots "$PWD:/tmp" -- npm run dev

EXIT STATUS

1 : No command was supplied, sandbox-exec is unavailable, or exec failed.

Otherwise, sid-seatbelt replaces itself with sandbox-exec; the final status is the status reported by the sandboxed command.

SEE ALSO

SID(1), SANDBOX-EXEC(1)

RCINVOKE(1)

NAME

rcinvoke - invoke rc-style services by reading their advertised variables

DESCRIPTION

rcinvoke is not implemented by this repository, but sid tools are shaped to be compatible with it. A sid tool executable answers rcvar with the variables it needs, and answers run by performing the tool operation.

During a sid tool call, RC_CONF_PATH points at the workspace tools.conf plus sid's per-call overlay, and RC_D_PATH points at the configured tools/ directory. A tool can use those values to invoke another configured tool without reconstructing sid's environment by hand.

EXAMPLES

Invoke another configured tool from inside a sid tool:

rcinvoke --rc-conf-path "$RC_CONF_PATH" --rc-d-path "$RC_D_PATH" format

SEE ALSO

SID(1), SID TOOL PROTOCOL

SANDBOX-EXEC(1)

NAME

sandbox-exec - run a process under a macOS sandbox profile

DESCRIPTION

sandbox-exec is the macOS program sid uses when it is available. sid builds an SBPL policy at runtime and passes it to /usr/bin/sandbox-exec for bash, external tools, and sid-seatbelt. The policy restricts operations; it does not replace / with the workspace.

When sandbox-exec is unavailable, sid runs child processes without the Seatbelt wrapper. sid-seatbelt is stricter: it is specifically a sandbox-exec frontend and exits with an error if the program is missing.

POLICY

The generated sid policy:

  • denies by default;
  • allows child process execution and same-sandbox signaling;
  • allows reads from writable roots outside $HOME, plus ~/src, ~/.cargo, ~/.rustup, ~/.config/git, selected Git dotfiles such as ~/.gitconfig, and /Library/Developer/CommandLineTools;
  • allows writes to the workspace, configured writable roots, and temporary directories;
  • allows loopback networking for local servers and tools;
  • includes platform allowances needed for common shells, build tools, language runtimes, and system libraries.

SEE ALSO

SID(1), SID-SEATBELT(1)