Skip to main content

Multi-project sandbox coordinator: SQLite-backed task locks + git worktree isolation for concurrent AI agent sessions

Project description

pac-collab

Multi-project sandbox coordinator for concurrent AI agent sessions.

Multiple independent agents can work on different tasks across entirely different repositories at the same time. pac-collab gives each task a lock (so two agents never grab the same task in the same project) and an isolated git worktree (so their files never touch), all tracked in one shared SQLite registry.

How it works

  • Shared state — a single coordinator.db lives in the OS user data directory (located via platformdirs), so every invocation of the package, from any process or repository, sees the same master registry. WAL journal mode + 10s busy timeout make it safe under concurrency.
  • The lock — a partial unique index on (project_id, task_id) WHERE status = 'ACTIVE'. Acquiring inserts the ACTIVE row inside a BEGIN IMMEDIATE transaction; two concurrent acquires of the same task cannot both succeed. Finished rows stay as history.
  • File isolation — every task gets its own worktree at ~/.pac-collab/sandboxes/{project_id}/task_{task_id}, on its own branch agent/{feature_name}-{task_id} cut from origin/main (configurable via base_ref / --base-ref for repos whose default branch differs).

Install

pip install pac-collab

MCP server (primary interface for agents)

The package ships an MCP server (stdio) exposing every coordinator operation as a tool, so agent harnesses call the coordinator natively instead of shelling out:

pac-collab-mcp                     # console script
python -m pac_collab.mcp_server    # PATH-independent equivalent

Register it in any MCP client (.mcp.json / Claude Code / plugin):

{
  "mcpServers": {
    "pac-collab": {
      "command": "python",
      "args": ["-m", "pac_collab.mcp_server"]
    }
  }
}

Tools: acquire_sandbox(base_repo_path, project_id, task_id, feature_name, base_ref="origin/main"), heartbeat(project_id, task_id), release_sandbox(project_id, task_id, outcome), list_sandboxes(project_id=None), prune_stale_sandboxes(timeout_minutes=60) — identical semantics to the Python API below. Every tool call opens its own SQLite connection, so concurrent sessions can each run their own server instance against the same shared registry.

Python API

from pac_collab import SandboxCoordinator

with SandboxCoordinator() as coord:
    grant = coord.acquire_sandbox(
        base_repo_path="C:/repos/backend-api",
        project_id="backend-api",
        task_id="T-101",
        feature_name="rate-limiter",
    )
    # {"status": "ALLOCATED", "sandbox_path": "...", "branch_name": "agent/rate-limiter-T-101"}
    # or {"status": "REJECTED", "reason": "Task already active in this project"}

    coord.heartbeat("backend-api", "T-101")          # call periodically while working
    coord.release_sandbox("backend-api", "T-101", "SUCCESS")  # commit + push + destroy worktree

    coord.list_sandboxes()                # everything, all projects
    coord.list_sandboxes("backend-api")   # one project
    coord.prune_stale_sandboxes(60)       # reap ACTIVE rows with heartbeats older than 60 min

CLI

Every command prints JSON; failed operations exit non-zero.

pac-collab acquire --base-repo-path C:/repos/backend-api --project-id backend-api --task-id T-101 --feature-name rate-limiter
pac-collab heartbeat --project-id backend-api --task-id T-101
pac-collab release  --project-id backend-api --task-id T-101 --outcome SUCCESS
pac-collab list     [--project-id backend-api]
pac-collab prune    [--timeout-minutes 60]

Semantics worth knowing

  • release --outcome SUCCESS commits (agent: completed {task_id}) and pushes before destroying the worktree. If the commit or push fails, the sandbox is kept ACTIVE and intact — no work is lost, and the error is returned so the agent can retry.
  • release --outcome FAILED discards everything: worktree removed, local branch deleted, row marked FAILED.
  • prune marks stale sessions STALE_FAILED and removes their worktrees even if the base repo has vanished — the lock is always released.
  • Identifiers are slugified ([^A-Za-z0-9._-]-) for branch and directory names; the lock itself always uses the raw ids.
  • Statuses: ACTIVESUCCESS | FAILED | STALE_FAILED.

Development / publishing

python -m build
twine upload dist/*

Publish with the eatopia PyPI token (in ~/.pypirc, username __token__) — same account as pac-pincers.

Project details


Download files

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

Source Distribution

pac_collab-0.2.0.tar.gz (9.2 kB view details)

Uploaded Source

Built Distribution

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

pac_collab-0.2.0-py3-none-any.whl (12.7 kB view details)

Uploaded Python 3

File details

Details for the file pac_collab-0.2.0.tar.gz.

File metadata

  • Download URL: pac_collab-0.2.0.tar.gz
  • Upload date:
  • Size: 9.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for pac_collab-0.2.0.tar.gz
Algorithm Hash digest
SHA256 91d16580eeecb26990ffa0bff96396c7c1e419249e096e7a57905dfd4296cfa4
MD5 552f6ec165b424792de3bf1cb0f638d8
BLAKE2b-256 48637fd757c31f8d1feb46f092c3e040de8a89d4d2c5398137f2473cba032dcc

See more details on using hashes here.

File details

Details for the file pac_collab-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pac_collab-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 12.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.0

File hashes

Hashes for pac_collab-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 c6d2a99095765ef773d9433b0734e52d1117946962c2b3865e97f415909dc9c1
MD5 1b2209b257773f4e6b06beaa00ea15e6
BLAKE2b-256 08abf95f361f7b2890df719f5c0d33018b592bc97be456ada7b5937ca80634af

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page