Skip to main content
Glama
volkangunay

agentclaim

by volkangunay

agentclaim

Несколько агентов. Одно рабочее дерево. Git вас не спасёт.

Владение файлами для параллельных ИИ-агентов кодирования — чтобы они перестали молча перезаписывать друг друга.

npm node dependencies license github

npm i -g agentclaim && agentclaim init

Проблема

Вы запускаете два, три, пять агентов кодирования одновременно. Они используют одно рабочее дерево.

Git был создан для людей, работающих в отдельных клонах и сливающих изменения позже. Он понятия не имеет, что делать с двумя писателями, редактирующими один и тот же checkout в одну и ту же секунду. Нет ни маркера конфликта, ни предупреждения, ни слияния — вторая запись просто побеждает, а первая исчезает.

Вот три реальных инцидента из одного дня в одном репозитории. Все три попали в продакшн. Ни один из них не породил ни единого сообщения об ошибке.

1. Гонка при индексации

git add делает снимок файла таким, каким он есть в этот момент.

 session A            session B
 ─────────            ─────────
                      git add i18n.js Money.jsx   ← snapshots i18n.js v1
 write i18n.js v2
                      git commit                  ← commit contains i18n.js v1

Коммит отправил новый Money.jsx вместе со старым i18n.js. Экран отображал сырые ключи перевода в продакшне. Git сообщил об успехе. Последующий исправляющий коммит попал в ту же самую гонку.

2. Разрушительный откат

git checkout HEAD -- i18n.js api.demo.js   # session A tidies its tree
git commit -a                              # session B, two seconds later

Работа сессии B была откачена с диска, а затем закоммичена. Молча.

3. Врата, которые солгали

В скрипте развёртывания была проверка на грязное дерево. Она проверяла дерево во время развёртывания, а не гонку во время коммита. Врата стали зелёными, коммит был неправильным, и развёртывание добросовестно опубликовало неправильный коммит.


Related MCP server: asynkor

Решение

Записи становятся умнее. Коммиты остаются строгими.

Блокировать каждого второго писателя было бы знаком «стоп», а не решением — и инструмент, который блокирует работу, которую людям нужно делать, будет отключён. Два агента в одном файле находятся в реальном конфликте только тогда, когда они затрагивают одну и ту же область.

Поэтому agentclaim не спрашивает «кто владеет этим файлом?». Он спрашивает «что изменилось с тех пор, как я смотрел на него в последний раз?» — единственный вопрос, который отделяет правки другого агента от ваших собственных. Разные области — оба агента работают. Одни и те же строки — один из них останавливается.

agentclaim: src/checkout.ts is also being edited by another agent — your edits do not overlap theirs.
  their lines: 12-19
  your lines:  84-91
Both edits are kept. You may not commit this file until they are done.

Запись всего файла Write — это тоже не конфликт: она трёхсторонне сливается с работой другого агента с помощью git merge-file, так что обе правки попадают в результат:

agentclaim: src/checkout.ts was merged, not overwritten.
Another agent had edited this file; your write has been combined with
their changes. Re-read the file before continuing — it now contains both.

Пересекающиеся строки — это тоже не знак «стоп»

Точечная правка хирургична: она применяется только в том случае, если её якорный текст всё ещё существует в файле в его текущем состоянии. Это одно свойство делает всю работу.

  • якорь всё ещё на месте → его замена сохраняет правки другого агента, потому что их изменения, по определению, находятся где-то ещё в тексте

  • якорь исчез → инструмент отказывается сам, и агент перечитывает

В любом случае результат уже корректен, поэтому блокировка стоила бы лишнего цикла и ничего не дала бы. agentclaim добавляет контекст вместо этого:

agentclaim: heads up — another agent just changed the same lines of src/checkout.ts.
  their lines: 12-19
  your lines:  14-16

Your edit still applies cleanly on top of their version. This is what
they changed, in case it affects what you were about to do:
  @@ line 12-19 @@
  -  const total = items.length
  +  const total = items.reduce((n, i) => n + i.qty, 0)

Nothing is blocked. You may not commit this file until they are done.

Что на самом деле останавливает агента

Четыре вещи, и только они:

Остановлено

Почему

Запись всего файла, которую нельзя трёхсторонне слить

Нет правильного автоматического ответа, и одна из двух версий будет потеряна.

Запись всего файла в файл, который эта сессия никогда не читала

Не с чем сливать; это слепая перезапись.

Индексация или коммит файла, который активно редактирует другой агент

Инцидент №1: так один агент отправляет незаконченную работу другого.

Команда git, которую мы не можем разобрать, которая косвенно затрагивает git (eval, sh -c), пока активна другая сессия

Мы не будем гадать о git reset --hard.

Ничто в пути редактирования не останавливается. В этом суть: инструмент, который прерывает агентов, выполняющих обычную работу, будет отключён, и тогда он не защищает ничего.

Коммиты — это строгая часть

Как только две живые сессии коснулись файла, ни одна из них не может его индексировать или коммитить — потому что именно так один агент отправляет незаконченную работу другого. Инцидент №1 выше.

Эта защита была бы тупиком, если бы у неё не было выхода, поэтому у неё их три:

Выход

Что он делает

agentclaim release <path>

«Я закончил здесь». Снимает только вашу долю, не требует --force и не может быть использован для кражи файла. Другой агент может коммитить немедленно.

ничего не делать

Сессия перестаёт блокировать файл, который она не редактировала в течение touchTtlMinutes (по умолчанию 10). Агенты работают часами; никто не редактирует один файл часами.

agentclaim release <path> --force

Полный захват. Грубый инструмент, который всё ещё доступен, когда он нужен.

Завершение сессии или её сбой освобождают всё, что она удерживала, поэтому дерево никогда не остаётся заблокированным.

Нет сервера. Нет демона. Нет зависимостей. Хранилище — это каталог внутри .git/.


Быстрый старт

npm i -g agentclaim
cd your-repo
agentclaim init

Не хотите устанавливать глобально? npx agentclaim init тоже работает — он сначала копирует себя в ~/.agentclaim/lib, потому что хуки должны указывать на путь, который будет существовать завтра.

Вот и всё. init настраивает хуки Claude Code и устанавливает git-хук pre-commit (сцепляясь с любым существующим). Проверьте это в любое время:

$ agentclaim status
SESSION          FILES  AGE   LAST SEEN
● money screen       3  6m    2s
  ai visibility      2  22m   14s

FILE                    HELD BY        AGE
web/src/Money.jsx       (you)          6m
web/src/i18n.jsx        (you)          6m
web/src/api.demo.js     ai visibility  22m

Дайте вашей сессии читаемое имя, чтобы сообщение об ошибке другого агента имело смысл:

agentclaim label "money screen"

Что init меняет на вашей машине

Три вещи. Ничего больше.

Что

Где

Отмена

Записи хуков

.claude/settings.json (сначала создаётся резервная копия)

agentclaim uninstall

Хук pre-commit

.git/hooks/ (существующий хук сцепляется, никогда не заменяется)

agentclaim uninstall

Хранилище заявок

.git/agentclaim/ — внутри .git, никогда не коммитится

удалите каталог

Никаких сетевых вызовов. Никакой телеметрии. Никаких фоновых процессов. Ни одна строка вашего кода не затрагивается, и в git status не появляется ничего нового.


Он ничего не делает, когда вы одни

Если ваша сессия — единственная живая в дереве, все врата сокращаются до разрешения. Никакие заявки не применяются, никакие команды не проверяются, нечего обходить.

Это сделано намеренно. Врата, через которые нельзя пройти, хуже, чем отсутствие врат, потому что люди учатся их отключать, и тогда они не защищают ничего. agentclaim имеет зубы только в той ситуации, для которой он создан.

$ agentclaim doctor
...
1 live session(s) · 3 claim(s) · TTL 30m · mode block
single session -> gates inactive (no-op)

Четыре врат

#

Врата

Когда

Что они останавливают

1

Запись

перед Write / Edit

ничего в пути редактирования — записи всего файла сливаются, и останавливается только несливаемая запись

2

Git

перед командой Bash

git add -A, git commit -a, git checkout -- x, git reset --hard, git stash, git clean, затрагивающие файлы, которыми вы не владеете

3

Правда коммита

после git commit

гонка снимков — содержимое коммита, не соответствующее диску

4

pre-commit

при любом git commit

индексированные файлы, принадлежащие другому, из любого инструмента

Врата 3 — это то, что не ловит больше ничто. Они перечитывают каждый путь в коммите с помощью git show <sha>:<path> и сравнивают его побайтово с файлом на диске:

agentclaim: ⚠ commit 045d1f7 does NOT match what is on disk:
  web/src/api.demo.js

This is the classic `git add` snapshot race: another session rewrote these
files after you staged them, so the commit captured stale content.
DO NOT DEPLOY. Fix it with:
  git add web/src/api.demo.js && git commit --amend --no-edit

Они сообщают только о файлах, удерживаемых другой сессией, поэтому обычная частичная индексация (git add x, продолжаете редактировать x, коммит) никогда не вызывает ложную тревогу.


Работает с любым агентом

Три уровня интеграции, от самого сильного к слабому. Используйте столько, сколько применимо.

Claude Code — хуки (самый сильный)

agentclaim init            # project-level  (.claude/settings.json)
agentclaim init --global   # every repo     (~/.claude/settings.json)

Врата запускаются до записи или команды. Агент получает отказ как обратную связь и сам выбирает другой файл.

Cursor · Windsurf · Codex · Zed · Cline · что угодно с MCP

agentclaim поставляет MCP-сервер, поэтому любой агент, говорящий на MCP, может присоединиться к тому же протоколу владения:

{
  "mcpServers": {
    "agentclaim": {
      "command": "agentclaim",
      "args": ["mcp"],
      "env": { "AGENTCLAIM_SESSION": "cursor-1", "AGENTCLAIM_AGENT": "cursor" }
    }
  }
}

Доступные инструменты: agentclaim_status, agentclaim_claim, agentclaim_release, agentclaim_check, agentclaim_verify_commit. Описания подсказывают модели, когда их вызывать.

Всё остальное — git-хук

agentclaim init устанавливает хук pre-commit, поэтому aider, обычный git commit, ваша IDE или shell-скрипт — все проходят ту же проверку. Ничего настраивать не нужно.

Для скриптов развёртывания и CI используйте врата с кодом выхода:

agentclaim check --staged --quiet || exit 1   # anyone else holding staged files?
agentclaim verify HEAD                        # did the commit capture disk?

Команды

agentclaim init [--global]    wire up the hooks (Claude Code + git pre-commit)
agentclaim status             who holds what
agentclaim who <path>         owner of a single file
agentclaim claim <path...>    claim files            [--note "..."]
agentclaim release <path...>  "I am done here"       [--all] [--force to take over]
agentclaim check <path...>    gate for scripts, exit 0/1  [--staged] [--quiet]
agentclaim verify [rev]       compare commit content against disk  [--all]
agentclaim label "<name>"     give this session a readable name
agentclaim gc                 collect stale claims
agentclaim doctor             diagnose the installation
agentclaim uninstall          remove the hooks
agentclaim mcp                run as an MCP server

Конфигурация

Необязательный .agentclaim.json в корне репозитория:

{
  "ttlMinutes": 30,
  "touchTtlMinutes": 10,
  "mode": "block",
  "ignore": ["node_modules/**", "dist/**", "*.lock", "package-lock.json"]
}
  • ttlMinutes — сессия без активности в течение этого времени считается завершённой, и её заявки можно перехватить. Каждый вызов хука обновляет сердцебиение, поэтому активная сессия никогда не истекает.

  • touchTtlMinutes — как долго сессия продолжает блокировать других от коммита файла после последней правки в нём. Намеренно короче, чем ttlMinutes: быть живым — не то же самое, что всё ещё работать в этом файле, и смешение этих понятий превращает защиту в тупик.

  • modeblock (по умолчанию), warn (сообщать, но разрешать), off.

  • ignore — никогда не заявляется. Держите сгенерированные файлы здесь; если lock-файлы и результаты сборки будут заявлены, врата будут срабатывать постоянно, и люди начнут их обходить.


Как это работает

.git/agentclaim/
  sessions/<id>.json   { sid, label, pid, started, seen, wt }
  claims/<hash>.json   { path, wt, sid, at, touchers }
  snap/<sid>/<hash>    what that session last saw on disk
  pending/<sid>/<hash> a merge computed before a write, applied right after it
  pass.json            short-lived identity token for the git hook
  • Место храненияgit rev-parse --git-common-dir, поэтому каждый worktree репозитория использует общий реестр.

  • Ключи заявок включают корень worktree, потому что один и тот же относительный путь в двух worktree — это два разных файла на диске. Отдельные worktree никогда не блокируют друг друга — worktree — это легитимное решение этой проблемы, а не то, что нужно наказывать.

  • Атомарность — это open(..., 'wx') — O_EXCL. Две одновременные заявки, один победитель, никакой гонки.

  • Живучесть основана на TTL. Хуки срабатывают при каждом вызове инструмента, поэтому seen остаётся свежим в течение секунд; заявки упавшего агента можно перехватить, и они никогда не блокируют репозиторий.

  • Логика регионов сравнивает снимок вашей сессии с файлом на диске с помощью git diff --no-index -U0 и объединяет с помощью git merge-file. Всё это собственная семантика git — та, которой вы уже доверяете, — без добавления зависимостей.

  • Слияния применяем мы, а не внедряем. Схема вывода хука содержит поле updatedInput, но ничто проверяемое не гарантирует, что оно применяется без автоматического одобрения вызова, а неверное предположение здесь молча потеряло бы работу другого агента. Поэтому слияние сохраняется и записывается сразу после выполнения инструмента, используя только те механизмы, которые мы контролируем.

  • Стоимость одного вызова инструмента — один короткоживущий процесс node: ~45 мс при работе в одиночку, ~83 мс, когда шлюзу действительно приходится рассуждать (измерено на репозитории из 200 файлов). Запуск node доминирует — создание снимка после чтения добавляет около 1 мс.

  • Нечего поддерживать. gc запускается при каждом старте сессии и удаляет заявки, снимки и ожидающие слияния завершившихся сессий, поэтому в .git/ ничего не накапливается.


Ограничения

Сформулировано прямо, потому что защита, которой вы доверяете ошибочно, хуже, чем её отсутствие.

  • git commit --no-verify пропускает слой хуков git. Слой Claude Code всё равно перехватывает это.

  • Агенты без хуков или MCP невидимы во время записи; они обнаруживаются при коммите.

  • Разбор команд намеренно не является полным парсером оболочки. Для eval / sh -c / обратных кавычек, затрагивающих git, agentclaim отказывает только пока активна другая сессия.

  • Сосуществование регионов требует знания того, что ваша сессия видела в последний раз, поэтому оно применяется только к файлам, которые агент прочитал или записал через свои инструменты. Файл, изменённый другим путём (shell sed, внешний редактор), невидим для этой логики.

  • agentclaim не понимает смысл. Две правки могут быть текстуально независимыми и при этом семантически несовместимыми; он сообщает вам, что другой агент был там, но суждение остаётся за вами.

  • Чистое трёхстороннее слияние всё равно может быть семантически неверным, точно так же, как и для людей. agentclaim сообщает вам, что файл был объединён, чтобы вы перечитали его перед использованием.

  • Заявки привязаны к машине. Ничего не синхронизируется между хостами.


Тестирование

npm test

32 сквозные проверки. Набор воспроизводит все три реальных инцидента, описанных выше, доказывает, что инструмент полностью бездействует для одиночной сессии, и проверяет каждый шлюз как на проходящем, так и на провальном примере — шлюз, который не ловит собственную ошибку, хуже, чем отсутствие шлюза, потому что он внушает доверие.


Ссылки

Лицензия

MIT © Volkan Günay

A
license - permissive license
Not graded
quality - not tested
C
maintenance

Resources

Unclaimed servers have limited discoverability.

Looking for Admin?

If you are the server author, to access and configure the admin panel.

Related MCP Servers

  • A
    license
    Not graded
    quality
    D
    maintenance
    Coordination layer for AI coding agents working on the same codebase. Adds file locks, shared project memory, and cross-machine file sync so Claude Code, Cursor, Windsurf, and other MCP agents stop overwriting each other.
    50
    Apache 2.0
  • A
    license
    A
    quality
    B
    maintenance
    Enables multiple AI agents to collaborate on the same git repository by coordinating work via a shared claims branch, detecting file conflicts before they happen.
    9
    PolyForm Noncommercial 1.0.0

View all related MCP servers

Related MCP Connectors

  • The team layer for AI coding agents: shared contracts, collision alerts, E2EE sessions.

  • Coding agents from Claude Code, Cursor and Codex claim jobs and lock files on one shared board.

  • Coordinate multiple AI agents over MCP: atomic claims, leases, shared ledger, handoffs, tasks.

View all MCP Connectors

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/volkangunay/agentclaim'

If you have feedback or need assistance with the MCP directory API, please join our Discord server