Skip to main content
Glama
README.md
# sangam

**Your coding agent and your teammate's coding agent, on the same page.**

You use Claude Code. Your friend uses Codex. You're building the same thing.
Today that means one of you drives and the rest watch — or you leave notes for
each other's agents and hope.

sangam gives both agents a shared memory of what actually happened, and stops
them editing the same file at the same time.

```bash
npx sangam init --server=https://sangam.you.workers.dev
# → send your teammate one line:
npx sangam join https://sangam.you.workers.dev#prj_a1b2c3#K3y…
```

---

## Why not just have the agents write notes to each other?

Because what crosses is a sentence the *agent* chose to write. Two problems, and
the second is the fatal one:

1. **It's lossy.** 200k tokens of work becomes "refactored auth, see src/auth".
2. **It's voluntary.** It only happens if the model remembers to do it.

Any tool with a `save_context()` in it has the same defect in nicer packaging.
Structure doesn't fix this — *voluntariness is the lossiness*.

**sangam inverts it.** Claude Code and Codex already write a complete, verbatim
record of every session to disk, without being asked:

```
~/.claude/projects/<project>/<session>.jsonl
~/.codex/sessions/YYYY/MM/DD/rollout-<ts>-<uuid>.jsonl
```

sangam tails those files. Nothing is summarised, because nothing needs to be.
**The model is never in the loop on the write side.** Then MCP is used only for
*reading*: your teammate's agent queries the raw stream and gets their exact
words back, with attribution.

Capture is mechanical. Recall is on demand.

---

## What your agent gets

| tool | what it does |
|---|---|
| `ctx_brief` | who's active, what landed since you last worked, what's claimed. ~500 tokens |
| `ctx_search` | your teammates' **verbatim** words and actions, ranked so *human instructions* beat agent chatter |
| `ctx_thread` | expand one moment: what they asked, then what their agent actually did |
| `ctx_claim` / `ctx_release` / `ctx_who_has` | file leases, with a human-readable reason attached |
| `ctx_note` | the one voluntary write, for a decision the transcript can't show |

Plus, without the model having to cooperate at all:

- **SessionStart hook** puts the team's state *into* the context window
- **PreToolUse hook** refuses an edit to a file a teammate holds
- **git pre-push** refuses a push touching someone else's claimed files

---

## Install

```bash
npx sangam init            # local only: your own Claude Code + Codex share context
npx sangam install-hooks   # enforcement: deny colliding edits, brief every session
npx sangam doctor          # check what it can see
```

Zero runtime dependencies. Node ships SQLite with FTS5, so there is nothing to
compile and nothing to install.

To work with other people, deploy the server to **your own** Cloudflare account —
so your transcripts go to infrastructure you control, not to us:

```bash
cd server && npx wrangler deploy
npx sangam init --server=https://sangam.<you>.workers.dev
npx sangam connection      # the one line your teammate pastes
```

---

## How it works

```
MACHINE A (you)                         MACHINE B (teammate)
  Claude Code                             Codex
    │ writes          ▲ MCP (stdio)         │ writes        ▲ MCP (stdio)
    ▼                 │                     ▼               │
  ~/.claude/…jsonl    │                   ~/.codex/…jsonl   │
    │                 │                     │               │
    └──► sangamd ─────┘                     └──► sangamd ───┘
          tail → normalise → scrub              (full local replica,
          → local SQLite + FTS                   FTS index, works offline)
                    │                                  │
                    └──── push / pull ────────┬─────────┘
                                              ▼
                              Cloudflare Worker → Durable Object per project
                                  · total order (gseq)
                                  · lease arbitration
                                  · live presence
```

The server is deliberately **not** a search engine — every client keeps a full
local replica, so recall is instant and works on a plane. The server does only
what can't be done locally: ordering, lease arbitration, fanout.

Leases are a single-writer problem, which is exactly what a Durable Object is:
one request at a time, strongly-consistent storage, so "is this claimed?" is an
ordinary branch with no lock protocol. Tested rather than assumed — **50
simultaneous claims on the same pattern yield exactly one winner.**

---

## Honest limitations

These are measured, not guessed. If any of them matters to you, it should matter
before you install rather than after.

- **Enforcement is asymmetric today, and the git gate is the only universal
  layer.** Claude Code exposes `PreToolUse`, so an edit can be blocked *before*
  it happens. Recent Codex builds *do* ship hooks too — verified in
  0.140.0-alpha.19: `PreToolUse`, `PermissionRequest` and `permissionDecision`
  are all present — but sangam does not rely on them yet, for three reasons
  worth knowing:
  - Codex hooks are **trust-gated and fail silently**. An untrusted hook is
    skipped with no prompt and no error, and there is no CLI command to trust
    one (only a TUI slash command, or `--dangerously-bypass-hook-trust`). A
    security control that silently does nothing is worse than none.
  - The registration format is **version-skewed** and changing between builds.
  - An admin can disable all non-managed hooks outright with
    `allow_managed_hooks_only` in `/etc/codex/requirements.toml`.

  So on Codex, Cursor, or a human in vim, collisions are caught by **git
  pre-push**. Wiring Codex's `PreToolUse` is the next enforcement upgrade, gated
  on a post-install check that asserts the hook actually fired.
- **Codex reasoning does not transfer.** Measured across 40 real sessions: 3592
  `reasoning` items, all `encrypted_content`, 10 (0.3%) with a readable summary.
  Claude Code's `thinking` transfers in full. Human turns, assistant messages,
  tool calls and tool output transfer from both.
- **Tool output is not synced by default.** It is 51–88% of transcript bytes and
  it is where secrets live. The reasoning trace of an 81 MB session is ~5 MB, so
  you lose very little by leaving the bulk at home.
- **These log formats are internal and undocumented.** Anthropic and OpenAI can
  change them in any release. Parsing is deliberately fault-tolerant, every event
  records the emitting CLI version, and `sangam doctor` reports record shapes it
  does not recognise instead of silently dropping them.
- **Hooks fail open, by design and by the host's own rules.** If the server is
  unreachable your edit is allowed; a hook that times out is also cancelled and
  the tool call proceeds. Wedging someone's work because their wifi dropped is
  worse than a missed lease, and the git gate still catches it before anything is
  shared. Treat leases as coordination, not as a security boundary.
- **`notify` is a dead end** and sangam does not use it: it is fire-and-forget
  with stdin/stdout closed, carries a single event, and is marked for removal in
  Codex's own source.

## Privacy

Everything is scoped to one repo and, by default, the last 14 days. Nothing
leaves your machine until you attach a server, and the recommended server is one
you deploy to your own Cloudflare account. Project keys are trust-on-first-use,
stored hashed, compared in constant time; knowing a project id is never enough.

## License

MIT.