Skip to content

IbrahimF1/Datadog-Hackathon-26

Repository files navigation

🀝 PeerCode

Distributed LLM Context Consensus for Parallel Development

A coordination server that enables multiple Claude Code sessions to build software in parallel β€” with live context sync, structured debates, file locking, and AI-powered planning.

Node.js TypeScript Express Vitest License: Private ClickHouse Datadog


πŸ“– Table of Contents


🎯 The Problem

When teams parallelize work via Claude Code, each developer's local context drifts as they discover constraints, change approaches, or uncover dependencies. Today's solutions require humans to manually sync through Slack, PRs, or meetings. The LLMs themselves β€” the entities actually doing the work β€” have no mechanism to:

  • πŸ” Detect when local context contradicts the shared plan
  • πŸ“‘ Propagate significant context changes to peers automatically
  • πŸ”€ Integrate peer context updates without human intervention
  • βš”οΈ Resolve contradictions through structured "debate" before humans get involved

PeerCode fixes this by treating LLMs as first-class participants in context synchronization.


✨ Key Features

Feature Description
🧠 AI-Powered Planning Claude API decomposes projects into phases, tasks, and interface contracts
πŸ“‘ Context Delta Propagation Bidirectional live sync of discoveries, contract changes, and scope shifts
πŸ”’ File-Level Locking Granular locks at file, section, or line level with auto-expiry
βš”οΈ Structured Debates Agents negotiate conflicts over up to 5 rounds before human escalation
πŸ”„ GitHub Sync Coordination Serialized push coordination to the peer-progress branch
πŸ‘οΈ Real-Time Presence Track which sessions are online and what they're working on
πŸ“Š Datadog LLM Observability Full tracing of every MCP tool call and agent action
πŸ’Ύ ClickHouse Event Streaming Append-only audit trail for deltas, debates, and sync events

πŸ—οΈ Architecture

graph TB
    subgraph "Client Layer"
        UI["🌐 Web UI<br/>(Roadmap + Kanban)"]
        CA["πŸ€– Claude Session A<br/>(MCP Client)"]
        CB["πŸ€– Claude Session B<br/>(MCP Client)"]
        CC["πŸ€– Claude Session C<br/>(MCP Client)"]
    end

    subgraph "PeerCode Server"
        REST["πŸ”Œ REST API<br/>/api"]
        MCP["πŸ“‘ MCP Server<br/>/mcp"]
        WS["⚑ WebSocket<br/>/ws"]
        BUS["πŸ”„ Event Bus"]

        subgraph "Core Services"
            PS["πŸ“‹ Project Service"]
            TS["πŸ“ Task Service"]
            LS["πŸ”’ Lock Service"]
            DS["πŸ“‘ Delta Service"]
            DBS["βš”οΈ Debate Service"]
            PLN["🧠 Planning Service"]
            SYN["πŸ”„ Sync Service"]
            PRS["πŸ‘οΈ Presence Service"]
        end
    end

    subgraph "Storage Layer"
        CH["πŸ’Ύ ClickHouse<br/>(Event Streams)"]
        MEM["🧠 In-Memory<br/>(Live State Fallback)"]
    end

    subgraph "External Integrations"
        ANTH["🧠 Anthropic API<br/>(Claude)"]
        NIM["πŸ” Nimble<br/>(Web Search)"]
        DD["πŸ“Š Datadog<br/>(LLM Observability)"]
    end

    UI -->|HTTP| REST
    CA -->|Streamable HTTP| MCP
    CB -->|Streamable HTTP| MCP
    CC -->|Streamable HTTP| MCP
    UI -->|WS| WS
    CA -.->|WS subscribe| WS
    CB -.->|WS subscribe| WS
    CC -.->|WS subscribe| WS

    REST --> BUS
    MCP --> BUS
    BUS --> WS

    PS --> MEM
    TS --> MEM
    LS --> MEM
    DS --> MEM
    DBS --> MEM
    SYN --> MEM
    PLN --> ANTH
    DBS --> NIM

    BUS --> CH
    DS --> CH
    DBS --> CH

    MCP --> DD
Loading

πŸ”„ How It Works

Agent Coordination Loop

sequenceDiagram
    participant A as πŸ€– Claude A
    participant S as πŸ–₯️ PeerCode Server
    participant B as πŸ€– Claude B

    Note over A,B: 1. Sync Phase β€” Pull context before work
    A->>S: peercode_get_deltas(projectId)
    S-->>A: { deltas, requiresAction: false }
    A->>S: peercode_lock_file("src/auth.ts", 10-45)
    S-->>A: { lockId, success: true }

    Note over A,B: 2. Work Phase β€” Push discoveries
    Note over A: Discovers API contract change needed
    A->>S: peercode_push_delta(type: "contract_change", ...)
    S->>B: WS: delta_received πŸ””

    Note over A,B: 3. Conflict Phase β€” Structured debate
    B->>S: peercode_get_deltas()
    S-->>B: { requiresAction: true ⚠️ }
    B->>S: peercode_start_debate(position, constraints)
    S->>A: WS: debate_update πŸ””

    loop Debate Rounds (max 5)
        A->>S: peercode_respond_debate(message)
        S->>B: WS: debate_update πŸ””
        B->>S: peercode_respond_debate(message)
        S->>A: WS: debate_update πŸ””
    end

    Note over A,B: 4. Resolution
    B->>S: peercode_respond_debate(proposeResolution: true)
    S-->>A,B: Debate resolved βœ…

    Note over A,B: 5. Sync Phase β€” Push to git
    A->>S: peercode_sync_github(action: "start")
    S-->>A: { status: "go", pullShas: [...] }
    Note over A: git pull β†’ resolve β†’ git push
    A->>S: peercode_sync_github(action: "complete", commitSha)
    S->>B: WS: sync_complete πŸ””

    Note over A,B: 6. Cleanup
    A->>S: peercode_release_lock(lockId)
Loading

Merge Point Flow

stateDiagram-v2
    [*] --> TODO
    TODO --> IN_PROGRESS: Assign & start
    IN_PROGRESS --> REVIEW: Work complete
    REVIEW --> MERGE_POINT: Approved
    MERGE_POINT --> DONE: Phase sync barrier reached
    MERGE_POINT --> IN_PROGRESS: Rejected

    note right of MERGE_POINT
        πŸ”’ Contracts locked
        All sessions must sync
        to same peer-progress HEAD
    end note
Loading

Context Delta Lifecycle

flowchart LR
    A["πŸ” Discovery<br/>by Agent"] --> B["πŸ“€ push_delta<br/>to server"]
    B --> C["πŸ’Ύ Stored in<br/>ClickHouse"]
    C --> D["πŸ”” WS broadcast<br/>to peers"]
    D --> E{"Peer evaluates<br/>conflict?"}
    E -->|No conflict| F["βœ… ack_delta<br/>Auto-adapt"]
    E -->|Conflict!| G["βš”οΈ start_debate<br/>Negotiate"]
    G --> H{"Consensus<br/>reached?"}
    H -->|Yes| I["βœ… Resolved<br/>Contract updated"]
    H -->|No, 5 rounds| J["🚨 Escalate<br/>to humans"]
Loading

πŸ› οΈ Tech Stack

Layer Technology Purpose
🟒 Runtime Node.js β‰₯ 20 Server runtime
πŸ”΅ Language TypeScript 6.0 (strict) Type safety
🌐 HTTP Express 5 REST API framework
⚑ Realtime ws (WebSocket) Server-push events
πŸ“‘ MCP @modelcontextprotocol/sdk Agent tool protocol
🧠 AI @anthropic-ai/sdk Project planning & decomposition
πŸ” Search Nimble API Web search for debates & planning
πŸ’Ύ Storage ClickHouse Cloud Append-only event streams
🧠 Live State In-Memory (with CH fallback) Mutable coordination state
πŸ“Š Observability dd-trace + Datadog LLM Obs End-to-end tracing
βœ… Validation Zod 4 Schema validation
πŸ§ͺ Testing Vitest Unit & integration tests

πŸš€ Quick Start

Prerequisites

  • Node.js β‰₯ 20
  • ClickHouse Cloud instance (or use in-memory fallback)
  • Anthropic API key (for AI planning)
  • Datadog (optional, for LLM observability)

Setup

# 1. Clone the repository
git clone <repo-url>
cd Datadog26

# 2. Install dependencies
npm install

# 3. Configure environment
cp .env.example .env
# Edit .env with your keys and endpoints

# 4. Start development server
npm run dev

The server starts on http://localhost:3000 with these endpoints:

Endpoint Protocol Purpose
/api/* REST Project, task, lock, delta, debate, sync APIs
/mcp MCP (Streamable HTTP) Agent tool calls
/ws?projectId=<id> WebSocket Real-time event subscriptions
/ Static HTML Test UI dashboard
/health REST Health check (includes ClickHouse status)

Environment Variables

# Server
PORT=3000

# Anthropic (required for planning/decomposition)
ANTHROPIC_API_KEY=sk-ant-...
ANTHROPIC_MODEL=claude-opus-4-7

# ClickHouse Cloud (append-only streams)
CLICKHOUSE_URL=https://<id>.<region>.clickhouse.cloud:8443
CLICKHOUSE_USER=default
CLICKHOUSE_PASSWORD=...
CLICKHOUSE_DATABASE=peercode

# Datadog LLM Observability
DD_LLMOBS_ENABLED=1
DD_LLMOBS_ML_APP=peercode
DD_LLMOBS_AGENTLESS_ENABLED=0
DD_SITE=datadoghq.com

# Nimble (web search for debates/planning)
NIMBLE_API_KEY=...

πŸ“‘ API Reference

Projects

Method Endpoint Description
POST /api/projects Create a new project
GET /api/projects List all projects
GET /api/projects/:id Get full project state
PUT /api/projects/:id/decompose Trigger AI decomposition into phases/tasks

Team

Method Endpoint Description
POST /api/projects/:id/team Add a team member
GET /api/projects/:id/team/:memberId/questions Get planning questions
POST /api/projects/:id/team/:memberId/answers Submit planning answers

Tasks

Method Endpoint Description
GET /api/projects/:id/tasks List all tasks
PUT /api/projects/:id/tasks/:taskId/assign Assign task to member
PUT /api/projects/:id/tasks/:taskId/status Update task status
PUT /api/projects/:id/tasks/:taskId/lock Acquire file lock
DELETE /api/projects/:id/tasks/:taskId/lock Release file lock

Context Deltas

Method Endpoint Description
POST /api/mcp/context Push a context delta
GET /api/mcp/context/:projectId Get pending deltas
POST /api/mcp/context/:projectId/:deltaId/ack Acknowledge a delta

Debates

Method Endpoint Description
POST /api/mcp/debate Start or respond to a debate
GET /api/mcp/debate/:debateId?projectId= Get debate status

Sync & Presence

Method Endpoint Description
POST /api/projects/:id/sync Start or complete a sync
GET /api/projects/:id/conflicts List conflicting deltas & active debates
POST /api/projects/:id/conflicts/:conflictId/resolve Resolve a conflict
POST /api/projects/:id/presence Register session presence
GET /api/projects/:id/presence List active sessions
GET /api/projects/:id/events Recent event history

πŸ”Œ MCP Tools

The MCP server exposes these tools for Claude Code sessions via the Streamable HTTP transport at /mcp:

Tool Purpose
peercode_get_project Get full project state
peercode_lock_file Acquire a file/section lock
peercode_release_lock Release a held lock
peercode_heartbeat Extend a lock's expiry
peercode_push_delta Broadcast a context discovery
peercode_get_deltas Pull pending context updates
peercode_ack_delta Acknowledge a non-conflicting delta
peercode_start_debate Initiate a structured debate
peercode_respond_debate Respond in an active debate
peercode_get_debate Query debate status
peercode_sync_github Coordinate push to peer-progress
peercode_create_phase Dynamically create a new phase
peercode_create_task Dynamically create a new task
peercode_update_task Update task properties
peercode_move_task Move task to a different phase
peercode_replan Trigger AI replanning
peercode_web_search Nimble web search (debates/planning only)

πŸ’¬ WebSocket Events

Connect to /ws?projectId=<id> to receive real-time events:

// Context delta received
{ event: "delta_received", projectId, delta: ContextDelta }

// Lock acquired or released
{ event: "lock_changed", projectId, file, lockedBy?, released? }

// Debate started or updated
{ event: "debate_update", projectId, debate: Debate }

// GitHub sync completed
{ event: "sync_complete", projectId, commitSha, files }

// Task status changed
{ event: "task_update", projectId, taskId, status, assignee }

// Phase created / task created / task moved / replanned
{ event: "task_update", projectId, type, ... }

πŸ“ Project Structure

peercode-server/
β”œβ”€β”€ πŸ“„ src/
β”‚   β”œβ”€β”€ πŸ“„ index.ts                  # Entry point β€” wires all transports
β”‚   β”œβ”€β”€ πŸ“„ config.ts                 # Environment config (Zod-validated)
β”‚   β”œβ”€β”€ πŸ“‚ domain/
β”‚   β”‚   └── πŸ“„ types.ts              # All domain types (Project, Task, Debate, etc.)
β”‚   β”œβ”€β”€ πŸ“‚ services/
β”‚   β”‚   β”œβ”€β”€ πŸ“„ container.ts          # Composition root β€” DI for all services
β”‚   β”‚   β”œβ”€β”€ πŸ“„ eventBus.ts           # Pub/sub for domain events
β”‚   β”‚   β”œβ”€β”€ πŸ“„ projectService.ts     # Project CRUD + team management
β”‚   β”‚   β”œβ”€β”€ πŸ“„ taskService.ts        # Task status + assignment
β”‚   β”‚   β”œβ”€β”€ πŸ“„ lockService.ts        # File lock acquire/release/heartbeat
β”‚   β”‚   β”œβ”€β”€ πŸ“„ deltaService.ts       # Context delta push/get/ack
β”‚   β”‚   β”œβ”€β”€ πŸ“„ debateService.ts      # Structured debate rounds
β”‚   β”‚   β”œβ”€β”€ πŸ“„ planningService.ts    # AI decomposition via Anthropic
β”‚   β”‚   β”œβ”€β”€ πŸ“„ syncCoordinationService.ts  # Serialized push coordination
β”‚   β”‚   β”œβ”€β”€ πŸ“„ presenceService.ts    # Session tracking
β”‚   β”‚   β”œβ”€β”€ πŸ“„ sweeper.ts            # Auto-expire stale locks/debates
β”‚   β”‚   └── πŸ“„ errors.ts             # Domain error types
β”‚   β”œβ”€β”€ πŸ“‚ transports/
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ rest/
β”‚   β”‚   β”‚   └── πŸ“„ router.ts         # Express REST router
β”‚   β”‚   β”œβ”€β”€ πŸ“‚ mcp/
β”‚   β”‚   β”‚   └── πŸ“„ server.ts         # MCP server + Streamable HTTP transport
β”‚   β”‚   └── πŸ“‚ ws/
β”‚   β”‚       └── πŸ“„ server.ts         # WebSocket server (per-project subs)
β”‚   β”œβ”€β”€ πŸ“‚ storage/
β”‚   β”‚   β”œβ”€β”€ πŸ“„ liveStore.ts          # Mutable state interface
β”‚   β”‚   β”œβ”€β”€ πŸ“„ streamStore.ts        # Append-only event stream interface
β”‚   β”‚   β”œβ”€β”€ πŸ“„ inMemoryLiveStore.ts  # In-memory LiveStore
β”‚   β”‚   β”œβ”€β”€ πŸ“„ clickhouseLiveStore.ts # ClickHouse-backed LiveStore
β”‚   β”‚   └── πŸ“„ clickhouseStreamStore.ts # ClickHouse StreamStore
β”‚   β”œβ”€β”€ πŸ“‚ integrations/
β”‚   β”‚   β”œβ”€β”€ πŸ“„ anthropicClient.ts    # Anthropic API + Nimble search
β”‚   β”‚   └── πŸ“„ nimbleClient.ts      # Nimble web search client
β”‚   β”œβ”€β”€ πŸ“‚ observability/
β”‚   β”‚   └── πŸ“„ datadog.ts            # Datadog LLM Observability init + tracing
β”‚   └── πŸ“‚ util/
β”‚       └── πŸ“„ id.ts                 # ID generation utilities
β”œβ”€β”€ πŸ“‚ test/
β”‚   β”œβ”€β”€ πŸ“„ debate.test.ts            # Debate protocol tests
β”‚   β”œβ”€β”€ πŸ“„ delta.test.ts             # Context delta tests
β”‚   β”œβ”€β”€ πŸ“„ lock.test.ts              # File locking tests
β”‚   β”œβ”€β”€ πŸ“„ sync.test.ts              # Sync coordination tests
β”‚   β”œβ”€β”€ πŸ“„ integration.test.ts       # End-to-end integration tests
β”‚   └── πŸ“„ mock-server.mjs          # Mock server for testing
β”œβ”€β”€ πŸ“‚ public/
β”‚   β”œβ”€β”€ πŸ“„ index.html                # Test UI dashboard
β”‚   └── πŸ“„ app.js                    # Dashboard client logic
β”œβ”€β”€ πŸ“‚ skills/
β”‚   └── πŸ“„ peercode.md               # Claude Code skill definition
β”œβ”€β”€ πŸ“‚ docs/
β”‚   β”œβ”€β”€ πŸ“‚ logs/                     # Development logs
β”‚   β”œβ”€β”€ πŸ“‚ memory/                   # Context & decisions
β”‚   └── πŸ“‚ superpowers/specs/        # Feature specs
β”œβ”€β”€ πŸ“„ TECH_SPEC.md                  # Full technical specification
β”œβ”€β”€ πŸ“„ CLAUDE.md                     # Claude Code project context
β”œβ”€β”€ πŸ“„ vitest.config.ts              # Test configuration
β”œβ”€β”€ πŸ“„ tsconfig.json                 # TypeScript configuration
└── πŸ“„ package.json                  # Dependencies & scripts

πŸ§ͺ Testing

# Run all tests
npm test

# Run specific test file
npx vitest run test/debate.test.ts

# Run mock server
npm run mock

Test suites cover:

Suite File Coverage
βš”οΈ Debates test/debate.test.ts Debate rounds, resolution, escalation
πŸ“‘ Deltas test/delta.test.ts Push, get, ack, conflict detection
πŸ”’ Locks test/lock.test.ts Acquire, release, overlap, expiry
πŸ”„ Sync test/sync.test.ts Token coordination, start/complete
πŸ”— Integration test/integration.test.ts End-to-end flows

πŸ”’ Security

  • No secrets in code β€” all credentials via environment variables
  • GitHub tokens β€” each developer's Claude session uses its own local git auth; the server never handles GitHub credentials
  • MCP session isolation β€” per-session transports keyed by mcp-session-id
  • WebSocket auth β€” projectId-scoped subscriptions
  • Lock validation β€” session IDs verified on release
  • Input validation β€” Zod schemas on all MCP tool inputs

βš–οΈ License

Private β€” All rights reserved.


Built with ❀️ for the Datadog 2026 Hackathon

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors