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.1.tar.gz (9.6 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.1-py3-none-any.whl (13.1 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: pac_collab-0.2.1.tar.gz
  • Upload date:
  • Size: 9.6 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.1.tar.gz
Algorithm Hash digest
SHA256 f79de5dcc54fc28c35c8ce81b80ce0afd300597cf4eef10d3025d5bc384962aa
MD5 dba0ad65a7da137f790c5c5d258df054
BLAKE2b-256 7386c483db325b02377025720c9bdfe3b9aa3da7731e3827a0e72a4e829bfb69

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pac_collab-0.2.1-py3-none-any.whl
  • Upload date:
  • Size: 13.1 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 b81da609905beebd0f6505236ac7617f8b787c768ee1f809f62f3050a2900761
MD5 8e45fc5d0aa244e6ccd903ef11bc703c
BLAKE2b-256 e9f01f18378557dcb8904f13ba7152d654ad9780d7dabdef64b5fc8873953cd8

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