Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ just test # pytest
just lint # ruff check
just fmt # ruff format
just typecheck # mypy --strict
just scenario -- tests/scenarios/basic_coordination.toml
just run -- ... # run the dispatch CLI in-tree
uv run dispatch --help
uv run dispatchd --help
Expand All @@ -34,6 +35,7 @@ dispatch owns one `codex app-server` subprocess (stdio JSONL, shared `~/.codex`)
- `.agents/plans/v0/` — phased plan (`PLAN.md`) + references (`REFS.md`); tracked.
- `spikes/` — App Server probe scripts; seed of the integration suite.
- `tests/fixtures/` — small named App Server, JSONL, CLI-smoke, and registry fixtures.
- `tests/scenarios/` — live agent workflow fixtures run intentionally with `just scenario`.
- `.agents/notes/` — working notes, session recaps, learnings; **gitignored, local only**.
- `skills/` — first-party Codex skills for operating dispatch (`dispatch`) and dispatch-backed direct messages (`dm`).
- `plugins/dispatch/` — workspace-local Codex plugin bundle exposing the skills and MCP server.
Expand Down Expand Up @@ -66,6 +68,7 @@ Use the project language consistently:
- **Async core, sync CLI.** The daemon is asyncio end-to-end; the CLI is a thin sync client over the control socket. No blocking calls in the loop (use `aiosqlite`, asyncio subprocess, `run_in_executor`). See [python-conventions](.claude/rules/python-conventions.md).
- **Never touch the user's live state in tests.** Integration tests use a real ephemeral app-server with an isolated `CODEX_HOME` and `ephemeral:true` lanes.
- **Fixtures should be exercised.** Add checked-in cases under `tests/fixtures/` only when a test loads them; prefer Python builders over binary SQLite fixtures.
- **Live scenarios are opt-in.** Scenario fixtures start real isolated Dispatch/Codex daemons and make model calls; keep them small, synthetic, low-effort, and outside `just check`.

## Source control

Expand Down
2 changes: 2 additions & 0 deletions docs/development/design.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,7 @@ The client supports the full responder loop. v1 surfaces `waiting_on_approval` a
- MCP: the official Python **`mcp`** SDK (stdio transport first). Scheduling: small custom asyncio scheduler + `croniter` for cron (interval needs no lib). No `dateutil`/RRULE in v1.
- Tests: **pytest** + **pytest-asyncio**. Hooks: **lefthook** (polyglot; runs ruff/mypy/pytest). Task runner: **just** (justfile) for `test`/`lint`/`typecheck`/`run`. Daemon keep-alive: **launchd** LaunchAgent plist. CI: GitHub Actions + `astral-sh/setup-uv`.
- Fixture corpus: `tests/fixtures/` stores small named App Server payloads, Codex JSONL sync sources, CLI-smoke notes, and registry builders. Every checked-in fixture should be loaded by a test. Prefer builders over binary SQLite files.
- Live scenarios: `tests/scenarios/` plus `scripts/run_scenario.py` exercise agent-level workflows through the public CLI with isolated `DISPATCH_HOME`/`CODEX_HOME`. They use real model calls and are run intentionally via `just scenario -- <scenario>`, not as part of the default gate.

## Data model (registry, SQLite)

Expand All @@ -187,6 +188,7 @@ The client supports the full responder loop. v1 surfaces `waiting_on_approval` a
- `test_examples(registry)` runs op examples as assertions.
- Unit: message router (canned JSONL), trigger/guard evaluation, registry, error projections.
- Release smoke: `just pypi-smoke -- --package-spec outfitter-dispatch==<version>` installs the published package with `uvx`, uses a temporary `DISPATCH_HOME`, verifies daemon/model/list paths, and shuts down cleanly.
- Agent workflow smoke: `just scenario -- tests/scenarios/basic_coordination.toml` starts a real isolated daemon, creates live Codex lanes, waits for completion, and verifies list/get/tail state.

## Rough build slices (detailed by the implementation plan)

Expand Down
11 changes: 11 additions & 0 deletions docs/usage/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,17 @@ derived `models` schema, starts the daemon, reads the live App Server model
catalog, verifies the cached registry read, checks the empty first-run lane list,
and shuts the daemon down.

For an agent-level live scenario against the in-tree CLI, run:

```bash
just scenario -- tests/scenarios/basic_coordination.toml
```

This starts Dispatch with temporary `DISPATCH_HOME` and `CODEX_HOME`, creates
synthetic Codex lanes, waits for their turns to complete, verifies `list`/`get`
/`tail` state, then shuts the daemon down. It uses real Codex auth/model calls,
so it is intentionally separate from `just check`.

If `dispatch doctor` fails before the app-server smoke because the Codex CLI is
not installed or authenticated, fix that first and rerun the doctor. Use
`dispatch doctor --no-app-server` when you only need to inspect package, PATH,
Expand Down
4 changes: 4 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ test-int *args:
pypi-smoke *args:
uv run python scripts/check_pypi_smoke.py {{args}}

# Run a live agent scenario against an isolated DISPATCH_HOME/CODEX_HOME.
scenario *args:
uv run python scripts/run_scenario.py {{args}}

# Lint with ruff.
lint:
uv run ruff check .
Expand Down
Loading