Metadata-Version: 2.4
Name: agent-code-squad
Version: 0.1.9
Summary: MCP server for orchestrating multi-subagent code runs with minimized context and patch-only outputs.
License: MIT
Author: dzrlab
Requires-Python: >=3.10,<4.0
Classifier: License :: OSI Approved :: MIT License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: mcp (==1.25.0)
Project-URL: Homepage, https://example.invalid/agent-code-squad
Description-Content-Type: text/markdown

# agent-code-squad

Python MCP server that queues code-writing subagents with minimal context packs, isolated git worktrees, and patch-first collection. Heavy work (git worktree add + codex exec start) runs in a background worker to avoid tool-call timeouts.

## Quickstart

```sh
cd mcp-tools/agent-code-squad
poetry env use python3
poetry install
poetry run agent-code-squad
```

## MCP client config (example)

```toml
[mcp_servers.agent-code-squad]
command = "poetry"
args = ["run", "agent-code-squad"]
cwd = "/Volumes/workspace/dzrlab/k3s-test/mcp-tools/agent-code-squad"
```

## Project config (recommended)

Create `<repo_root>/.codex/code-squad/config.json` to set defaults per project.

Priority: `.codex/code-squad/config.json` → CLI flags → built-in defaults.

Example:

```json
{
  "dispatch_dir": "~/.codex/code-squad",
  "defaults": {
    "model": "gpt-5.2-codex",
    "sandbox": "workspace-write",
    "approval_policy": "never",
    "auto_context_pack": {
      "enabled": true,
      "glob": "**/*",
      "max_files": 14,
      "max_snippets": 28,
      "max_total_chars": 24000,
      "hints": []
    },
    "worker_concurrency": 2
  },
  "guardrails": {
    "enforce_sparse_checkout": true,
    "early_scope_enforcement": true,
    "strict_context_pack_scope": true,
    "require_patch": true
  },
  "energy_saver": {
    "default_reasoning_effort": "medium",
    "max_reasoning_effort": "medium"
  }
}
```

## Recommended flow

1) `code_squad_execute`: start tasks immediately and return quickly (default non-blocking).
2) Optional manual flow:
   - `code_squad_run`: queue tasks and enqueue workers right away.
   - `code_squad_tick`: optional bounded status refresh (enqueues already-queued tasks if needed).
   - `code_squad_status` / `code_squad_events`: poll light status or stream JSONL events.
   - `code_squad_collect`: extract patches from job stdout and persist under run artifacts (works even after worktree cleanup).
   - `code_squad_verify`: optional; runs `compileall`/`pytest` or custom `options.commands` arrays; results saved under artifacts.
   - `code_squad_report`: emit run/task summary as `report.json` and `report.md`.
   - `code_squad_prune`: clean up old runs/worktrees by retention policy.
   - `code_squad_cancel` (optional): cancel a job or all tasks in a run.
   - `code_squad_cleanup`: drop worktrees and optionally delete run artifacts.

## Modify Multiple Modules

When the user request is “modify several modules”, prefer one task per module and enforce boundaries so parallel work stays precise.

- Put each module under a distinct directory (example: `modules/<name>/`).
- Use `allow_globs` per task to restrict which files a task is allowed to touch.
- Use `deny_globs` to protect shared areas (configs, app entrypoints, shared libs) from module tasks.
- `allow_globs` / `deny_globs` are also injected into the subagent prompt as hard rules to reduce scope drift.
- If `allow_globs` is set, the worktree attempts a best-effort `git sparse-checkout` to physically hide non-allowed paths (further reducing context + accidental edits). The mapping prefers the tightest directory prefix (e.g. `modules/user/**` → `modules/user`).
- If scope is violated, collection marks `scope.ok=false` and writes a scope artifact under `runs/<run_id>/artifacts/scope/<slug>.json`.

Example `code_squad_execute` input:

```json
{
  "cwd": "/path/to/repo",
  "tasks": [
    {
      "name": "user module",
      "scope_name": "modules/user",
      "allow_globs": ["modules/user/**"],
      "deny_globs": ["shared/**", "config/**", "app/**"],
      "prompt": "Fix bug in user module: ... (patch only)"
    },
    {
      "name": "billing module",
      "scope_name": "modules/billing",
      "allow_globs": ["modules/billing/**"],
      "deny_globs": ["shared/**", "config/**", "app/**"],
      "prompt": "Fix bug in billing module: ... (patch only)"
    }
  ],
  "options": {
    "poll_interval": 1.0,
    "wait_seconds": 0,
    "cleanup": true,
    "keep_failed": true
  }
}
```

## Auto Context Packs (Default)

If a task does not provide `context_pack`, automatic context packing runs by default (cached under `<dispatch_base>/context_packs/`).

- To disable: `options.auto_context_pack=false` (or config `"defaults.auto_context_pack.enabled": false`).
- `options.auto_context_pack`: dict with keys `glob`, `max_files`, `max_snippets`, `max_total_chars`, and optional `hints`.
- Query selection per task: `task.context_query` → `task.scope_name` → `task.name`.
- If a task specifies `allow_globs` / `deny_globs`, the context pack generation applies the same filters to reduce cross-scope leakage.
- The pack seeds common entrypoints (`AGENTS.md`, `README*`, common dependency/build files) before doing `rg` snippet extraction.

## Change Size Limits (Optional)

To prevent large/low-signal edits:

- Per-task: `task.max_touched_files`, `task.max_patch_bytes`
- Or defaults: `options.max_touched_files`, `options.max_patch_bytes`

If limits are exceeded, scope is marked `ok=false` and `code_squad_execute` fails the task.

## Scope Guardrails (Hardening)

- `enforce_sparse_checkout` (default `true`): if `allow_globs` is set, sparse-checkout runs before the subagent starts; failures hard-fail the task.
- `early_scope_enforcement` (default `true`): once a patch appears in stdout, scope is checked immediately; violations cancel the job early.
- `strict_context_pack_scope` (default `true`): provided `task.context_pack` is rejected if it contains out-of-scope paths (based on `allow_globs`/`deny_globs`).
- `require_patch` (default `true`): tasks that finish without a patch are treated as failed (scope `limits.require_patch`).

## Cleanup and Retention

Worktree cleanup is controlled by `options.cleanup` / `options.keep_failed` (used by the background finalizer).

- `options.cleanup` (default `true`): remove worktrees after execution
- `options.keep_failed` (default `true`): keep `failed` and `timeout` task worktrees for debugging
- `options.cleanup_delete_run_artifacts` (default `false`): also delete run artifacts (use with care)

For periodic cleanup of old runs/worktrees, use `code_squad_prune`:

- Defaults: keep last `5` runs, keep successful runs for `3` days, keep failed/timeout runs for `1` day
- `dry_run=true` by default; set `dry_run=false` to actually delete

## Logs and Artifacts

Each run writes an index file to make review/debug easier:

- `runs/<run_id>/artifacts/index.json`: run/task summary plus expected artifact paths
- `code_squad_execute` returns quickly with `index_path` and `next_poll_ms`; heavy work is done asynchronously.
- `runs/<run_id>/artifacts/timeline.jsonl`: structured timeline events (used by `recent_events` in status/execute/collect).
- `code_squad_status` returns `progress`, `next_action`, `next_poll_ms`, and a per-task `message` (last human line, trimmed) plus `has_patch`.
- `code_squad_events` defaults to `max_items=30` and filters out thread/turn/heartbeat noise; it only returns human/diff-bearing events unless `include_noise=true` (or `options.debug=true`).
- `code_squad_collect` persists patches to disk and returns paths by default; set `options.include_patch=true` to inline patch text in the response.

## Reasoning effort cap (eco)

This server enforces `model_reasoning_effort<=max_reasoning_effort` for all tasks (default max is `medium`).

- If you want lower effort, set `options.model_reasoning_effort="low"` (or `options.reasoning_effort="low"`).
- Requests above the configured max are clamped down to the max.

## Tools

- `code_squad_capabilities_get`: defaults and dispatch paths.
- `code_squad_context_pack`: ripgrep-based context pack with snippet/char caps.
- `code_squad_run`: queue tasks with per-task model/sandbox/approval/extra_config (auto-enqueues workers).
- `code_squad_execute`: start run and return quickly (optional short wait via `options.wait_seconds`).
- `code_squad_tick`: optional bounded worker pump (refresh a few running).
- `code_squad_status`: summarize task states with compact last messages.
- `code_squad_events`: stream compacted JSONL events per job using cursors (supports noise filtering).
- `code_squad_collect`: extract patch + touched files from job stdout and persist under artifacts.
- `code_squad_verify`: run `compileall`/`pytest` or custom commands using `sys.executable`, persisting results.
- `code_squad_report`: write `report.json`/`report.md` under run artifacts.
- `code_squad_prune`: clean up old runs/worktrees by retention policy.
- `code_squad_cancel`: cancel a job or whole run (sets state to `cancelled`).
- `code_squad_cleanup`: remove worktrees and (optional) run artifacts under `.codex/code-squad/`.

## Debug output

All tools accept `options.debug=true` to return a `debug` block (paths, timings, raw stdout/stderr/events). Default responses stay minimal and omit worktree/run/dispatch paths, trace IDs, PIDs, and full prompts.

For robustness, `options` is treated as best-effort: non-dict inputs are coerced to `{}` rather than hard-failing validation.

## Paths and defaults

- Run metadata: `<dispatch_base>/runs/<run_id>/run.json`.
- Job artifacts: `<dispatch_base>/runs/<run_id>/jobs/<job_id>/{meta.json,stdout.jsonl,stderr.log,last_message.txt}`.
- Worktrees: `<repo>/.codex/code-squad/worktrees/<run_id>/<task_slug>`.
- Dispatch base (default): `<repo>/.codex/code-squad`.
- Defaults: model `gpt-5.1-codex-max`, sandbox `workspace-write`, approval policy `never`, worker concurrency `2`.
- Override via `.codex/code-squad/config.json` or CLI flags (config takes priority over CLI).

