Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

callcall

An enforced file-lock for parallel coding agents. Cross-CLI. · 中文 · Getting Started guide

callcall — a second agent's edit blocked on a file the first is editing

Two agent windows on the same repo: the moment one is editing a file, the other's edit to it is blocked until it's released. (single-terminal walkthrough)

When several coding-agent windows (Claude Code, Cursor, Codex, Aider, …) edit the same repo at once, two of them touch the same file and clobber each other. callcall makes that mechanically impossible, with no discipline required:

  • auto-guard — the moment an agent edits a file, callcall holds it; a second agent's edit to that file is blocked until the first is done. Nobody has to remember to register anything.
  • claim / check — explicit sticky locks, and a scriptable check <path> primitive so any CLI (or a git hook) can gate its own edits.
  • msg / inbox — a cross-CLI back-channel to coordinate when blocked.

Zero dependencies, just python3. Plain files under .callcall/.

callcall is not a task board

If you already keep a shared AGENTS.md / board / PRD that agents update by convention — keep it. That's your task tracker and shared memory, and it's better at rich context than callcall. But a convention only works if every agent remembers to read and update it; the moment one forgets, two edits collide. callcall is the enforcement layer underneath that convention: it doesn't track tasks, it just guarantees two agents can't write the same file at the same time — and it does it across different CLIs, where a Claude-Code-only "board + native messages" setup stops working. Use both.

Quick start

git clone https://github.com/william19307/callcall.git
cd your-project
/path/to/callcall/callcall init --claude    # set up this project (+ Claude Code hooks)

Or install it globally so callcall works in any repo:

/path/to/callcall/install.sh    # symlinks `callcall` onto your PATH

With --claude, that's it — the guard is automatic. Open two Claude Code windows and try to edit the same file from both; the second is blocked.

Usage

On Claude Code with hooks installed you don't need any of these — editing is guarded automatically. They're for other CLIs, scripts, and explicit locks. Each window uses a short id (--id auth, or export CALLCALL_ID=auth).

callcall status                              # which files are held + who's active
callcall check src/auth/login.ts             # safe for me to edit? (exit 3 if taken)
callcall claim  --id auth "src/auth/**"      # explicit sticky lock over a glob
callcall msg    --id auth ui "grabbing auth for ~20 min"   # coordinate
callcall inbox  --id ui                       # read messages
callcall release --id auth                    # drop your locks

Wrap a non-Claude CLI's edits (or a pre-commit hook) around callcall check --id <you> --hold <path>: it exits non-zero when another agent owns the file, and holds it for you when it's free — the same guard the Claude Code hook applies.

Automatic coordination with Claude Code

callcall init --claude adds three hooks to .claude/settings.json:

Hook What it does
SessionStart auto-registers the window and injects which files are currently held, so it opens knowing what not to touch
PreToolUse (Edit/Write) editing a free file auto-holds it; editing a file another active agent holds is blocked with a reason (never blocks the holder itself)
SessionEnd removes the window and releases everything it held

Other CLIs don't get hooks, but they follow the same board via the instruction snippet init drops into your rules file — so a mixed Claude-Code-plus-Cursor setup still coordinates.

For agents: one-paragraph protocol

For CLIs without hooks, paste into the agent's rules file (.cursorrules, …) — init does this for you:

Other agent windows may be editing this repo in parallel. Before editing a file, run callcall check --id <you> --hold <path>; if it exits non-zero the file is taken — callcall msg --id <you> <owner> "..." to coordinate, or wait. Read replies with callcall inbox --id <you>. callcall status shows which files are held.

How it works

All state lives in <project>/.callcall/state.json — plain JSON any tool or human can read. Writes go through a file lock (fcntl.flock) with atomic replace, so concurrent windows never corrupt it. A file is "held" either by an explicit claim (sticky until released) or by a recent auto-edit (for CALLCALL_EDIT_TTL seconds, default 1800); a held file is only enforced while its owner is still active (CALLCALL_STALE seconds, default 600). File keys are realpath-normalized so every agent identifies the same file identically. .callcall/ is gitignored.

Works with git worktrees

Running each agent in its own git worktree is a great way to isolate the filesystem — no two agents overwrite the same working-tree file. But worktrees don't prevent merge conflicts (two branches editing the same file), don't communicate interface changes (agent A changes a function signature agent B depends on), and don't stop duplicated work or contention over shared resources (the same dev database, port, .env, migrations, API quota). callcall covers exactly those.

All worktrees of a repo automatically share one board: callcall anchors it at the repo's main worktree (via git rev-parse --git-common-dir), so agents in different worktrees still see each other, claim across branches, and message. Run callcall init --claude once per worktree to get hooks there; the board is shared regardless. To point unrelated checkouts at one board, set CALLCALL_HOME=/shared/dir.

Development

./tests/test_callcall.sh    # end-to-end tests, no dependencies

MIT licensed. Contributions welcome.


中文

给并行的 AI coding agent 加一把"强制文件锁",跨 CLI。

同一个仓库里开多个 agent 窗口(Claude Code、Cursor、Codex、Aider……)并行改代码时, 两个 agent 会同时改同一个文件、互相覆盖。callcall 让这件事机械上不可能发生,且不靠自觉

  • 自动上锁——一个 agent 一开始编辑某文件,callcall 就把它锁住;另一个 agent 想改同一 文件会被直接拦下,直到前者结束。谁都不用记得去登记。
  • claim / check——显式的粘性锁,以及一个可脚本化的 check <路径> 原语,让任意 CLI(或 git hook)也能在改文件前自查。
  • msg / inbox——被拦下时用来沟通的跨 CLI 通道。

零依赖,只要 python3,状态就是 .callcall/ 下的纯文本。

callcall 不是任务看板

如果你已经有一个大家按约定更新的 AGENTS.md / 看板 / PRD——留着它,那是你的任务 追踪和共享记忆,论上下文丰富度它比 callcall 强。但约定只有在每个 agent 都记得读和写时 才有效,一旦有人忘了,就撞车。callcall 是压在这套约定下面的强制层:它不管任务,只 保证两个 agent 不会同时写同一个文件——而且跨不同 CLI 都管用,这正是"看板 + 原生消息" 那套(只在全 Claude Code 时才成立)失效的地方。两者一起用。

快速开始

cd 你的项目
/路径/callcall/callcall init --claude    # 初始化(接入 Claude Code hooks,之后强制自动生效)
# 或全局安装: /路径/callcall/install.sh

装好 --claude 后就不用管了——开两个 Claude Code 窗口去改同一个文件,第二个会被拦下。

手动命令(给其他 CLI / 脚本 / 显式锁)

callcall status                              # 哪些文件被占、谁在线
callcall check src/auth/login.ts             # 我能改这个文件吗?(被占则退出码 3)
callcall claim  --id auth "src/auth/**"      # 对一批文件上粘性锁
callcall msg    --id auth ui "auth 我占 20 分钟" ; callcall inbox --id ui
callcall release --id auth

MIT 协议,欢迎贡献。

About

CLI-agnostic coordination layer for parallel coding agents in one repo

Topics

Resources

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages