✋ call-dibs
Call dibs on shared stuff.
A tiny lock ledger so humans and AI agents stop fighting over the same phone, GPU, or test bench.
$ dibs claim phone-a --note "regression run"
claimed phone-a as alice
$ dibs claim phone-a # …from another session
BUSY phone-a: held by alice since 2026-09-02T21:14:03Z (3m ago) — "regression run"
$ dibs release phone-a
released phone-a (was alice)
Why
You have one test phone, one GPU, one hardware bench — and several
terminals (or several coding agents) that can all reach it. dibs is the
smallest thing that makes them take turns.
- One file, no dependencies. A single Python script, stdlib only. No daemon, no server, no database.
- Cross-platform. macOS, Linux, Windows.
- Legible. The ledger is one human-readable JSON file per resource, and every "busy" says who, since when, and why.
- Agent-friendly. Stable exit codes,
--json, a blocking--wait, and arunwrapper that always releases — even when the command fails.
Install
pipx install call-dibs # or: pip install call-dibs · uv tool install call-dibs
Works the same on macOS, Linux, and Windows. Prefer no package manager? It's
one file — dibs.py — drop it on your PATH.
Set up
Tell dibs what you share. Write ~/.dibs/resources.json once, by hand:
{
"phone-a": "Android test phone on the bench",
"gpu-0": "the shared training GPU",
"printer": "label printer, room 2"
}
Only these names can be claimed, so a typo can't silently create a new lock.
dibs never edits this file.
Use
| command | what it does |
|---|---|
dibs claim <r...> [--note ...] [--wait [--timeout N]] |
claim one or more resources. Exit 2 + holder info if busy |
dibs release <r...> [--force] |
release |
dibs status [r] [--json] |
who has what |
dibs wait <r...> [--timeout N] |
block until free, without claiming |
dibs run <r> -- <cmd...> |
claim → run → always release |
dibs watch |
live terminal view |
Exit codes: 0 ok · 2 busy · 3 not yours · 4 wait timeout · 1 error.
Who's asking
Every claim records an owner, and only that owner can release it. Name
yourself once per session with DIBS_OWNER:
export DIBS_OWNER=alice # people
DIBS_OWNER=agent:task-123 dibs claim … # agents: inline, so every call agrees
If it's unset, dibs falls back to user@host:pid — fine for one-off use,
wrong for agents whose shell changes every command. --force releases
someone else's lock when they're gone.
Groups
Claim several resources in one call and they form a group. The claim is all-or-nothing — if any resource is busy, nothing is taken — and the group gets a tag so you can drop the whole set at once:
$ dibs claim phone-a gpu-0 --note "regression run"
claimed gpu-0 as alice
claimed phone-a as alice
group g-3fa2c1: gpu-0, phone-a (discard with: dibs release g-3fa2c1)
$ dibs release g-3fa2c1
Name the group yourself with --as NAME.
For AI agents
skills/dibs/ is a drop-in skill for Claude Code (and reads fine as an
AGENTS.md snippet for anything else). It teaches the protocol: claim before
touching hardware, one call per set, release when done, never force-break
someone else's lock.
cp -r skills/dibs ~/.claude/skills/
Menu bar (macOS)
See the ledger at a glance: dibs ✋2 in the top bar when two things are
claimed, dibs ✓ when everything is free, and who-has-what in the dropdown.
Install SwiftBar, then add the plugin:
open "swiftbar://addplugin?src=https://raw.githubusercontent.com/NeoMarcoPolo/call-dibs/main/contrib/dibs.5s.sh"
How it works
One JSON file per resource under ~/.dibs/ (override with DIBS_DIR). A
claim is an atomic O_CREAT|O_EXCL create, so racing claimers get exactly
one winner. Locks are advisory and are held until released — there is no
expiry. The ledger is per-machine by default; point DIBS_DIR at a shared
directory to span machines.
Contributing
python3 -m unittest discover tests. Keep it small.
Releases: bump version in pyproject.toml and dibs.py, then push a
v* tag — CI publishes to PyPI via trusted publishing (maintainer approval
required).
License
Release files for call-dibs 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| call_dibs-0.3.0.tar.gz | 10.0 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| call_dibs-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 19.5 kB
Release files / call_dibs-0.3.0.tar.gz
| Download URL | call_dibs-0.3.0.tar.gz |
|---|---|
| Size | 10.0 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ad551afd2747c55777610043e68cef58cba60b07fdc466c59649c24668112ff6
|
|
BLAKE2b-256 checksum How to use checksums |
2d21143c60553b31184c1afcdaa084131ef14a9bfc560ec429f04f7b85f97a0a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency logRelease files / call_dibs-0.3.0-py3-none-any.whl
| Download URL | call_dibs-0.3.0-py3-none-any.whl |
|---|---|
| Size | 9.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
9f4d0c457a9b6ba3b7d681465ecb5568ca4c5f3bc354f03b9a2a5f9296bd4bd1
|
|
BLAKE2b-256 checksum How to use checksums |
da34fe4c3038c5f30a6007acd3be4b7d08fe6a6959d0519283dce4c8bdbe68b8
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Sep 3, 2026.
Transparency log