Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Oneshot I/O

A non-interactive I/O plugin for scripting, batch jobs, and CI. It runs the agent for a single turn, auto-approves every approval request, and writes a JSON transcript of the run to stdout (and optionally a file).

The name reflects its semantics: one prompt in, one transcript out, then the process exits. (A future nexus.io.headless plugin will keep a long-running process alive so external systems can drive it — this is not that.)

Details

IDnexus.io.oneshot
DependenciesNone

Use this plugin instead of nexus.io.tui or nexus.io.browser — exactly one I/O plugin should be active at a time.

Prompt resolution

The plugin resolves the prompt to feed into the agent from the first of these sources that is non-empty:

  1. NEXUS_ONESHOT_PROMPT environment variable
  2. input field in the plugin config
  3. input_file field in the plugin config (path to a text file)
  4. Piped stdin (only when stdin is not a terminal)

If none of these yield a prompt, the run fails fast and still emits a JSON document containing the error so callers get something actionable.

Configuration

plugins:
  active:
    - nexus.io.oneshot
    - nexus.llm.anthropic
    - nexus.agent.react
    - nexus.memory.capped

  nexus.io.oneshot:
    input: ""             # inline prompt, or leave empty to use another source
    input_file: ""        # path to a file containing the prompt
    output_file: ""       # optional: also write the JSON transcript to this path
    pretty: true          # pretty-print the JSON (default true)
    read_stdin: true      # allow reading a piped stdin as a fallback (default true)

All fields are optional.

Usage

# Pipe a prompt through stdin
echo "What is 2+2?" | bin/nexus -config configs/oneshot.yaml

# Supply the prompt via environment variable
NEXUS_ONESHOT_PROMPT="Summarize octopus intelligence" \
  bin/nexus -config configs/oneshot.yaml

# Read the prompt from a file (via config)
bin/nexus -config configs/oneshot.yaml   # with input_file: ./prompt.txt set

# Feed the JSON transcript into jq for post-processing
echo "List three interesting facts about octopuses" \
  | bin/nexus -config configs/oneshot-planned.yaml \
  | jq '.final_output'

Auto-approval

The oneshot plugin auto-approves every approval request so agents with planners and protected tools can run unattended:

  • io.approval.request (tool call approval) → responds Approved: true
  • plan.approval.request (planner approval) → responds Approved: true
  • io.ask (free-form question to the user) → responds with an empty string

Every auto-approval is recorded in the approvals array of the transcript so callers can audit what happened.

⚠️ Because every approval is granted, be deliberate about which tools you make available under this profile. Avoid enabling destructive shell commands or filesystem writes outside a sandbox unless you trust the prompt source.

JSON transcript schema

The root document is tagged with schema: "nexus.oneshot.transcript/v1".

FieldTypeDescription
schemastringAlways nexus.oneshot.transcript/v1
session_idstringNexus session ID (matches ~/.nexus/sessions/<id>/)
started_at / ended_atRFC3339 timestampLifetime of the run
duration_msnumberWall-clock duration
final_outputstringFinal assistant message text
plansarrayplan.created events (full plan snapshots)
plan_updatesarrayagent.plan events (step status transitions)
thinkingarraythinking.step events (reasoning trace)
approvalsarrayAuto-approved tool / plan / ask requests
errorsarraycore.error events and error-role io.output messages

Every array field is omitted from the JSON when empty.

Events

Subscribes To

EventPriorityPurpose
io.output50Capture final assistant text and error messages
io.approval.request10Auto-approve tool call approvals
plan.approval.request10Auto-approve plan approvals
io.ask10Auto-respond with an empty answer
plan.created50Record generated plans in the transcript
agent.plan50Record plan status updates
thinking.step50Record reasoning trace
agent.turn.start / agent.turn.end50Detect when the single turn has completed
core.error50Record errors in the transcript

The approval / ask handlers subscribe at priority 10 so they run before any other plugin’s handlers and respond immediately.

Emits

EventWhen
io.inputOnce during Ready, with the resolved prompt
io.approval.responseAuto-approval for a tool call
plan.approval.responseAuto-approval for a plan
io.ask.responseAuto-response for an ask prompt
io.session.startOn Ready
io.session.endAfter the final JSON transcript has been flushed

Lifecycle

  1. Init wires subscriptions and reads config.
  2. Ready emits io.session.start, resolves the prompt, then emits io.input on a new goroutine so the engine’s main loop can install its signal + session-end handlers.
  3. The agent runs its turn. Any approval or ask prompts are auto-handled.
  4. When agent.turn.end brings the turn depth back to zero, the plugin builds the JSON transcript, writes it to stdout (and output_file if set), then emits io.session.end to trigger engine shutdown.
  5. Shutdown is idempotent — if the run was terminated by a signal before the turn completed, it still flushes whatever was captured.

Sample profiles

Two profiles ship with Nexus: