Skip to main content

dispatch

Local control plane for orchestrating Codex agent lanes over the Codex App Server. One authored contract per operation, projected to CLI + MCP (+ remote later) with no drift.

Quick Start

Install the CLI from PyPI:

uv tool install outfitter-dispatch
dispatch --help
dispatchd --help
dispatch doctor
dispatch up --json
dispatch down --json

From a source checkout:

uv sync
uv run dispatch --help
uv run dispatch doctor --no-app-server
uv run dispatch models --no-refresh
uv run dispatch permissions --no-refresh
uv run dispatch usage --no-refresh
uv run dispatch up --json
uv run dispatch daemon status

Create an owned managed thread, send it work, and inspect the daemon:

uv run dispatch new \
  --name docs \
  --cwd /path/to/dispatch \
  --goal "Finish the docs review." \
  --text "Please summarize the current stack state." \
  --image ./stack.png
uv run dispatch list
uv run dispatch get <dispatch-ref>
uv run dispatch tail <dispatch-ref> --limit 20
uv run dispatch daemon log --limit 10
uv run dispatch down --json

For durable or parallel launches, point new at a launch packet directory and preview it without side effects: dispatch new --name lane-a --cwd /repo --packet ./packet --dry-run --json, then --stage all to write durable session files under .agents/sessions/<ref>/. See docs/usage/README.md for packet layout, file/stdin inputs, and staging.

new and send accept repeatable --image PATH and --image-url HTTPS_URL options, with an optional --image-detail auto|low|high|original. Local images may be PNG, JPEG, GIF, or WebP and must be at most 20 MiB; remote URLs must resolve publicly and are fetched into ephemeral inline inputs without storing bytes. send --input-file - reads message text from stdin. Images work with normal sends, steering, durable queues, and interjection; silent --context injection remains text-only.

Use owned managed threads for turn-writing work. Existing desktop Codex threads can be attached as managed threads, but ADR-0005 blocks turn-writing and history-mutating commands such as send, stop, goal set, and goal clear on attached lanes by default. A local operator can explicitly opt in with [policy] allow_attached_writes = true in ~/.dispatch/config.toml; list --json and get --json expose writable, capabilities, and write_locked_reason so scripts can tell which lanes can receive writes. Every managed thread has a dispatch-local ref; full Codex thread UUIDs remain accepted everywhere. Titles and @handles are mutable convenience labels, not stable identity. Metadata lifecycle actions (rename, archive, restore) can target managed refs or raw unmanaged Codex thread ids. search uses App Server search for broad discovery, while query uses Dispatch's local indexed managed-history substrate. Attach is metadata-only by default; use dispatch sync <selector> when you want dispatch to refresh its local indexed view of an attached thread. Sync establishes metadata-only live observation, indexes recent App Server history first within explicit turn/item/time and page-checked byte budgets, and persists continuation plus cycle-guard state so later calls continue older history without starting over or spinning on malformed provider cursors. If <selector> is a raw unmanaged Codex thread id, sync first registers it as an attached read/metadata-managed lane, then refreshes the index. dispatch list --unmanaged --archived shows archived Codex sessions before you decide whether to sync or restore them. Bare dispatch history reads Dispatch's local index only; selector-scoped transcript reads through tail, history, or transcript-inclusive get use App Server thread/read(includeTurns:true) as the canonical source and backfill Dispatch's normalized local history index for that one thread.

Interactive App Server requests use dispatch request list and one generic dispatch request respond <id> '<json>' path. Owned threads default to durable attention; attached/unmanaged requests default to deny. dispatch schema "request respond" exposes the same response contract projected into grouped MCP tools.

History capture is configurable in ~/.dispatch/config.toml. The default standard mode captures operational facts and bounded searchable history metadata while keeping raw provider payloads gated. Live App Server events are stored as compact summaries; transcript reads index bounded turns, item text, tool names, and file/thread refs without retaining raw item payloads unless the retention policy allows it. Minimal capture keeps turn-level state but skips item-level transcript rows. Bare history overview is a local indexed summary. Normal selector-scoped history item/tool/file views render from the normalized index after refreshing one thread from the App Server, while history --raw remains a live raw-payload inspection path. Use debug only for development with bounded temp state; debug retention can store bounded raw provider event and item payloads with truncation markers for reducer/search diagnosis:

[history]
capture = "standard" # minimal | standard | debug
raw_payload_retention = "debug" # off | errors | debug | all
max_text_bytes = 8192
max_payload_bytes = 65536

dispatch doctor reports the active capture mode and warns when debug/raw retention is enabled.

new reports whether the first message was accepted by the App Server, not whether assistant work completed. Use get to inspect the latest turn state and persisted App Server errors, or watch for a bounded live event sample. Slash commands in --text are plain text; use --goal when creating a native App Server goal. Use dispatch models before pinning model or service-tier presets; Dispatch resolves aliases such as fast from the live App Server model catalog, accepts model-defined reasoning efforts, reports input/personality capabilities, and keeps omitted model/tier values on Codex defaults. Use dispatch permissions --cwd /repo before selecting a named Codex permission profile. Profiles are project-aware and may be disallowed by effective requirements. new --permission-profile <id> validates the live catalog before launch; it is mutually exclusive with sandbox, approval-policy, and approval-reviewer overrides so one authority source remains unambiguous.

For the operator guide, CLI/MCP examples, triggers, and plugin setup, start at docs/usage/README.md.

Start troubleshooting with dispatch doctor. It checks PATH visibility, the Codex CLI and auth footprint, daemon socket/pidfile state, registry schema/integrity, packaged skills/plugin assets, and a low-risk Codex App Server initialize smoke. If doctor reports an old registry schema, stop the daemon and run dispatch registry migrate before starting it again.

Dispatch owns a stdio App Server by default. An advanced local setup may instead attach to an existing WebSocket-over-Unix App Server with DISPATCH_APP_SERVER_SOCKET=/absolute/path.sock or [app_server].socket_path in ~/.dispatch/config.toml. The explicit socket path is fail-closed, and dispatch down never stops a shared server. See the shared App Server operator guide and ADR-0027.

Agent And Plugin Support

This repo ships first-party skills in skills/:

The workspace-local Codex plugin bundle lives at plugins/dispatch/, with a marketplace entry in .agents/plugins/marketplace.json. Restart Codex if the plugin does not appear immediately.

Project Docs

For contributors, AGENTS.md is the canonical fieldguide.

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

outfitter_dispatch-0.12.0.tar.gz (519.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

outfitter_dispatch-0.12.0-py3-none-any.whl (318.3 kB view details)

Uploaded Python 3

File details

Details for the file outfitter_dispatch-0.12.0.tar.gz.

File metadata

  • Download URL: outfitter_dispatch-0.12.0.tar.gz
  • Upload date:
  • Size: 519.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for outfitter_dispatch-0.12.0.tar.gz
Algorithm Hash digest
SHA256 8ce7cd5d50ea61d14fa61d4aeb02938838c126ae0345d6d16cd10e15dfef8a2b
MD5 b9d7c4a928fc3790a895d10383e4d871
BLAKE2b-256 8dca885642b59b2e46bfbd3a218ae17b1e448eb7fe1b8de5ff36c6bdd0ac52fe

See more details on using hashes here.

Provenance

The following attestation bundles were made for outfitter_dispatch-0.12.0.tar.gz:

Publisher: publish.yml on outfitter-dev/dispatch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file outfitter_dispatch-0.12.0-py3-none-any.whl.

File metadata

File hashes

Hashes for outfitter_dispatch-0.12.0-py3-none-any.whl
Algorithm Hash digest
SHA256 590b06ab45f43c1c0909a8f84e6555a1116b98d434a010f5f4db5a910beab520
MD5 431b6b8e0821893735126d31daacf69f
BLAKE2b-256 81fbda6f6c48a26e1f53d60793b9d1b53a2260afa5129934e38d7fc4722d3a27

See more details on using hashes here.

Provenance

The following attestation bundles were made for outfitter_dispatch-0.12.0-py3-none-any.whl:

Publisher: publish.yml on outfitter-dev/dispatch

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.13.0

2 files

This release

0.12.0 This release

2 files

0.11.0

2 files

0.10.0

2 files

0.9.0

2 files

0.8.2

2 files

0.8.1

2 files

0.8.0

2 files

0.7.0

2 files

0.5.0

2 files

0.2.1

2 files

0.2.0

2 files

0.1.0

2 files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page