contextgit 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.claude/settings.local.json +41 -0
- package/.contextgit/config.json +10 -0
- package/.contextgit/system-prompt.md +4 -0
- package/.github/workflows/contextgit-ci.yml +40 -0
- package/CLAUDE.md +123 -0
- package/CLAUDE.md.next +65 -0
- package/docs/ContextGit_ARCHITECTURE_v3.md +1141 -0
- package/docs/ContextGit_DELTA.md +84 -0
- package/docs/ContextGit_PHASE1_PLAN.md +177 -0
- package/docs/ContextGit_PHASE2_PLAN.md +535 -0
- package/docs/ContextGit_PRD_v4.md +488 -0
- package/docs/decisions.md +370 -0
- package/package.json +23 -8
- package/packages/api/package.json +25 -0
- package/packages/api/src/bootstrap.ts +64 -0
- package/packages/api/src/config.ts +45 -0
- package/packages/api/src/index.ts +17 -0
- package/packages/api/src/middleware/auth.test.ts +83 -0
- package/packages/api/src/middleware/auth.ts +41 -0
- package/packages/api/src/remote-store.test.ts +301 -0
- package/packages/api/src/router.ts +121 -0
- package/packages/api/src/server-config.ts +34 -0
- package/packages/api/src/server.ts +38 -0
- package/packages/api/src/store-router.ts +241 -0
- package/packages/api/tsconfig.json +8 -0
- package/packages/cli/bin/run.js +4 -0
- package/packages/cli/package.json +29 -0
- package/packages/cli/src/bootstrap.ts +68 -0
- package/packages/cli/src/commands/branch.ts +58 -0
- package/packages/cli/src/commands/claim.ts +58 -0
- package/packages/cli/src/commands/commit.ts +79 -0
- package/packages/cli/src/commands/context.ts +46 -0
- package/packages/cli/src/commands/doctor.ts +99 -0
- package/packages/cli/src/commands/init.ts +141 -0
- package/packages/cli/src/commands/keygen.ts +65 -0
- package/packages/cli/src/commands/log.ts +103 -0
- package/packages/cli/src/commands/merge.ts +36 -0
- package/packages/cli/src/commands/pull.ts +145 -0
- package/packages/cli/src/commands/push.ts +158 -0
- package/packages/cli/src/commands/remote-show.ts +87 -0
- package/packages/cli/src/commands/search.ts +54 -0
- package/packages/cli/src/commands/serve.ts +61 -0
- package/packages/cli/src/commands/set-remote.ts +30 -0
- package/packages/cli/src/commands/status.ts +62 -0
- package/packages/cli/src/commands/unclaim.ts +28 -0
- package/packages/cli/src/config.ts +64 -0
- package/packages/cli/src/git-hooks.ts +61 -0
- package/packages/cli/tsconfig.json +9 -0
- package/packages/core/package.json +28 -0
- package/packages/core/src/embeddings.test.ts +58 -0
- package/packages/core/src/embeddings.ts +75 -0
- package/packages/core/src/engine.ts +274 -0
- package/packages/core/src/index.ts +6 -0
- package/packages/core/src/snapshot.ts +82 -0
- package/packages/core/src/summarizer.test.ts +120 -0
- package/packages/core/src/summarizer.ts +113 -0
- package/packages/core/src/threads.ts +29 -0
- package/packages/core/src/types.ts +240 -0
- package/packages/core/tsconfig.json +9 -0
- package/packages/mcp/package.json +31 -0
- package/packages/mcp/src/auto-snapshot.ts +83 -0
- package/packages/mcp/src/config.ts +53 -0
- package/packages/mcp/src/git-sync.ts +94 -0
- package/packages/mcp/src/index.ts +19 -0
- package/packages/mcp/src/server.ts +377 -0
- package/packages/mcp/tsconfig.json +9 -0
- package/packages/store/package.json +30 -0
- package/packages/store/src/branch-merge.test.ts +127 -0
- package/packages/store/src/engine-integration.test.ts +93 -0
- package/packages/store/src/index.ts +3 -0
- package/packages/store/src/interface.ts +62 -0
- package/packages/store/src/local/claims.test.ts +190 -0
- package/packages/store/src/local/index.ts +380 -0
- package/packages/store/src/local/local-store.test.ts +164 -0
- package/packages/store/src/local/migrations.ts +99 -0
- package/packages/store/src/local/queries.ts +760 -0
- package/packages/store/src/local/schema.ts +157 -0
- package/packages/store/src/remote/index.ts +300 -0
- package/packages/store/tsconfig.json +9 -0
- package/pnpm-workspace.yaml +2 -0
- package/scripts/build.sh +28 -0
- package/tsconfig.base.json +14 -0
- package/vitest.config.ts +15 -0
|
@@ -0,0 +1,1141 @@
|
|
|
1
|
+
# ContextGit — Architecture Document
|
|
2
|
+
|
|
3
|
+
**Version 3.0 | March 2026**
|
|
4
|
+
**Status: Internal — Co-founder Review**
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## Table of Contents
|
|
9
|
+
|
|
10
|
+
1. [System Overview](#1-system-overview)
|
|
11
|
+
2. [High-Level Architecture](#2-high-level-architecture)
|
|
12
|
+
3. [Context Engine](#3-context-engine)
|
|
13
|
+
4. [Session Start Contract](#4-session-start-contract)
|
|
14
|
+
5. [Workflow Integrations](#5-workflow-integrations)
|
|
15
|
+
6. [Multi-Agent Model](#6-multi-agent-model)
|
|
16
|
+
7. [Git Branch Synchronisation](#7-git-branch-synchronisation)
|
|
17
|
+
8. [Persistence Layer](#8-persistence-layer)
|
|
18
|
+
9. [Integration Interfaces](#9-integration-interfaces)
|
|
19
|
+
10. [API Layer](#10-api-layer)
|
|
20
|
+
11. [Web Platform](#11-web-platform)
|
|
21
|
+
12. [Data Model](#12-data-model)
|
|
22
|
+
13. [Authentication and Multi-tenancy](#13-authentication-and-multi-tenancy)
|
|
23
|
+
14. [Deployment Architecture](#14-deployment-architecture)
|
|
24
|
+
15. [Phase Build Plan](#15-phase-build-plan)
|
|
25
|
+
16. [Open Questions](#16-open-questions)
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 1. System Overview
|
|
30
|
+
|
|
31
|
+
ContextGit is the memory layer for AI agent workflows. It provides persistent, structured, shared context to any agent — regardless of how that agent is invoked.
|
|
32
|
+
|
|
33
|
+
There are four user-facing surfaces:
|
|
34
|
+
|
|
35
|
+
**MCP Server** — For interactive tools (Claude Code, Cursor, Codex). Runs locally. Auto-detects git branches, installs hooks, handles background snapshotting.
|
|
36
|
+
|
|
37
|
+
**REST API** — For automated pipelines, CI agents, custom frameworks (LangChain, CrewAI). Full feature parity with the MCP server. No MCP required.
|
|
38
|
+
|
|
39
|
+
**CLI** — For Ralph-style loops, shell scripts, and automation. `contextgit snapshot` generates AGENTS.md. `contextgit commit` checkpoints from the command line. Composable with any bash workflow.
|
|
40
|
+
|
|
41
|
+
**Web Platform** — A GitHub-like frontend where developers browse, search, publish, and clone agent context repositories.
|
|
42
|
+
|
|
43
|
+
All four surfaces share a single Context Engine and dual-mode Persistence Layer.
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 2. High-Level Architecture
|
|
48
|
+
|
|
49
|
+
```
|
|
50
|
+
┌──────────────────────────────────────────────────────────────────────────┐
|
|
51
|
+
│ HOW AGENTS CONNECT │
|
|
52
|
+
│ │
|
|
53
|
+
│ ┌─────────────────┐ ┌──────────────────┐ ┌────────────────────────┐ │
|
|
54
|
+
│ │ MCP Server │ │ REST API │ │ CLI │ │
|
|
55
|
+
│ │ (interactive │ │ (pipelines, │ │ (Ralph loops, │ │
|
|
56
|
+
│ │ tools) │ │ CI, custom) │ │ shell scripts, CI) │ │
|
|
57
|
+
│ └────────┬────────┘ └────────┬─────────┘ └───────────┬────────────┘ │
|
|
58
|
+
└───────────┼────────────────────┼───────────────────────┼───────────────┘
|
|
59
|
+
│ │ │
|
|
60
|
+
└───────────────────┴────────────┬───────────┘
|
|
61
|
+
│
|
|
62
|
+
┌────────────────────────────────────────────┴───────────────────────────┐
|
|
63
|
+
│ CONTEXTHUB CORE │
|
|
64
|
+
│ │
|
|
65
|
+
│ ┌──────────────────────────────────────────────────────────────────┐ │
|
|
66
|
+
│ │ Context Engine (based on GCC / Aline) │ │
|
|
67
|
+
│ │ COMMIT | BRANCH | MERGE | CONTEXT │ │
|
|
68
|
+
│ │ Rolling summaries | Open threads | Session contract │ │
|
|
69
|
+
│ │ AGENTS.md generator | Snapshot export │ │
|
|
70
|
+
│ └──────────────────────────────┬───────────────────────────────────┘ │
|
|
71
|
+
│ │ │
|
|
72
|
+
│ ┌──────────────────┴────────────────────┐ │
|
|
73
|
+
│ │ Storage Interface │ │
|
|
74
|
+
│ └──────────────┬───────────────┬─────────┘ │
|
|
75
|
+
│ │ │ │
|
|
76
|
+
│ ┌──────────────┴──────┐ ┌─────┴──────────────┐ │
|
|
77
|
+
│ │ LocalStore │ │ RemoteStore │ │
|
|
78
|
+
│ │ SQLite + sqlite-vec│ │ Postgres + pgvector│ │
|
|
79
|
+
│ │ Solo dev, offline │ │ Team, hosted, CI │ │
|
|
80
|
+
│ └─────────────────────┘ └────────────────────┘ │
|
|
81
|
+
└─────────────────────────────────────────────────────────────────────────┘
|
|
82
|
+
│
|
|
83
|
+
┌───────────┴────────────────────────────────────────────────────────────┐
|
|
84
|
+
│ ContextGit Web Platform │
|
|
85
|
+
│ Explore repos | Branch viewer | Diff view | Threads | Search │
|
|
86
|
+
│ Clone | Fork | Star | Team dashboards | Live agent activity │
|
|
87
|
+
└────────────────────────────────────────────────────────────────────────┘
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
---
|
|
91
|
+
|
|
92
|
+
## 3. Context Engine
|
|
93
|
+
|
|
94
|
+
The context engine is a port of GCC/Aline's core logic, decoupled from any storage backend or integration interface. It is the only layer that understands the semantics of agent context.
|
|
95
|
+
|
|
96
|
+
### 3.1 Commands
|
|
97
|
+
|
|
98
|
+
**COMMIT(message, content, tags, threads)**
|
|
99
|
+
|
|
100
|
+
Creates a context checkpoint:
|
|
101
|
+
1. Generates a new rolling summary by compressing new content with the previous summary
|
|
102
|
+
2. Processes thread updates — marks open threads closed, creates new open threads
|
|
103
|
+
3. Stores the commit: id, parent_id, branch_id, agent_id, role, tool, workflow_type, message, content, summary, threads, embedding, commit_type
|
|
104
|
+
4. Updates branch HEAD
|
|
105
|
+
5. Returns commit id
|
|
106
|
+
|
|
107
|
+
**BRANCH(name, from_commit_id?)**
|
|
108
|
+
|
|
109
|
+
Creates an isolated context workspace branching from HEAD. The new branch inherits the parent's rolling summary — the agent arrives already oriented.
|
|
110
|
+
|
|
111
|
+
**MERGE(branch_id, summary)**
|
|
112
|
+
|
|
113
|
+
Integrates a branch into its parent:
|
|
114
|
+
1. Creates a merge commit with pointers to both parent commits
|
|
115
|
+
2. Generates synthesis summary combining both trajectories
|
|
116
|
+
3. Carries forward unresolved open threads from the merged branch
|
|
117
|
+
4. Updates parent branch HEAD, marks source branch merged
|
|
118
|
+
|
|
119
|
+
**CONTEXT(scope, options)**
|
|
120
|
+
|
|
121
|
+
Retrieves history at the requested granularity:
|
|
122
|
+
|
|
123
|
+
| Scope | Returns | Max tokens |
|
|
124
|
+
|-------|---------|-----------|
|
|
125
|
+
| `global` | Full session start snapshot | ~600 |
|
|
126
|
+
| `branch` | Current branch summary | ~500 |
|
|
127
|
+
| `search` | Semantic search across all branches | ~800 |
|
|
128
|
+
| `commit` | Specific commit full content | variable |
|
|
129
|
+
| `raw` | Paginated raw execution trace | paginated |
|
|
130
|
+
|
|
131
|
+
**SNAPSHOT(format)**
|
|
132
|
+
|
|
133
|
+
New command. Generates a formatted export of the session start contract for use outside MCP contexts:
|
|
134
|
+
|
|
135
|
+
| Format | Output | Use case |
|
|
136
|
+
|--------|--------|---------|
|
|
137
|
+
| `agents-md` | Markdown AGENTS.md file | Ralph loops, `contextgit snapshot > AGENTS.md` |
|
|
138
|
+
| `json` | Structured JSON | CI pipelines, custom integrations |
|
|
139
|
+
| `text` | Plain text | Shell scripts, logging |
|
|
140
|
+
|
|
141
|
+
### 3.2 Rolling Summary Algorithm
|
|
142
|
+
|
|
143
|
+
Every COMMIT generates a new bounded summary:
|
|
144
|
+
|
|
145
|
+
```
|
|
146
|
+
new_summary = compress(previous_summary + new_content)
|
|
147
|
+
max_tokens = 2000 (configurable)
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
**Phase 1 (rule-based):** Structured extraction — most recent decisions weighted highest, older details compressed to single-line entries, contradicted decisions removed.
|
|
151
|
+
|
|
152
|
+
**Phase 2+ (LLM-based):** Lightweight LLM call with specialised summarisation prompt. Better quality, small latency cost. Configurable.
|
|
153
|
+
|
|
154
|
+
**Versioned summaries:** Every COMMIT stores both raw content and the generated summary. The summary history is append-only. If quality degrades, summaries can be regenerated from raw commits.
|
|
155
|
+
|
|
156
|
+
### 3.3 Open Threads
|
|
157
|
+
|
|
158
|
+
Open threads are a first-class data structure, explicitly tagged on commits:
|
|
159
|
+
|
|
160
|
+
```typescript
|
|
161
|
+
interface Thread {
|
|
162
|
+
id: string
|
|
163
|
+
projectId: string
|
|
164
|
+
branchId: string
|
|
165
|
+
description: string // max 200 chars, must be scannable
|
|
166
|
+
status: 'open' | 'closed'
|
|
167
|
+
openedInCommit: string
|
|
168
|
+
closedInCommit?: string
|
|
169
|
+
closedNote?: string
|
|
170
|
+
workflowType?: string // which workflow opened this thread
|
|
171
|
+
}
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
On COMMIT:
|
|
175
|
+
```typescript
|
|
176
|
+
threads: {
|
|
177
|
+
open: ["sliding window vs fixed window not yet decided"],
|
|
178
|
+
close: [{ id: "thread_abc", note: "chose Upstash Redis, see commit" }]
|
|
179
|
+
}
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Open threads are immune to summary compression and always surfaced at session start.
|
|
183
|
+
|
|
184
|
+
### 3.4 Workflow Attribution
|
|
185
|
+
|
|
186
|
+
Every commit carries workflow metadata for traceability across the team dashboard:
|
|
187
|
+
|
|
188
|
+
```typescript
|
|
189
|
+
interface CommitWorkflowMeta {
|
|
190
|
+
workflowType: 'interactive' | 'ralph-loop' | 'ci' | 'background' | 'custom'
|
|
191
|
+
tool: string // 'claude-code' | 'cursor' | 'codex' | 'github-actions' | etc.
|
|
192
|
+
agentRole: AgentRole
|
|
193
|
+
loopIteration?: number // for Ralph loops
|
|
194
|
+
ciRunId?: string // for CI pipelines
|
|
195
|
+
pipelineName?: string // for custom frameworks
|
|
196
|
+
}
|
|
197
|
+
```
|
|
198
|
+
|
|
199
|
+
This data powers the team dashboard — you can see not just who committed context but what kind of workflow it came from.
|
|
200
|
+
|
|
201
|
+
---
|
|
202
|
+
|
|
203
|
+
## 4. Session Start Contract
|
|
204
|
+
|
|
205
|
+
Every agent, in every workflow, calls `context_get scope=global` at startup and receives the same compact structured snapshot. Always under 600 tokens. Regardless of project age.
|
|
206
|
+
|
|
207
|
+
### 4.1 Snapshot Structure
|
|
208
|
+
|
|
209
|
+
```
|
|
210
|
+
=== PROJECT STATE ===
|
|
211
|
+
<rolling summary — max 2000 tokens>
|
|
212
|
+
Distilled reality of the project: stack, conventions, key decisions,
|
|
213
|
+
completed modules. Built from actual development, not the PRD.
|
|
214
|
+
|
|
215
|
+
=== CURRENT BRANCH: <branch-name> ===
|
|
216
|
+
<branch summary — max 500 tokens>
|
|
217
|
+
What this line of work has done and where it stands.
|
|
218
|
+
|
|
219
|
+
=== LAST 3 COMMITS ===
|
|
220
|
+
[<timestamp>] "<message>" by <agent-role> via <tool> (<workflow-type>)
|
|
221
|
+
[<timestamp>] "<message>" by <agent-role> via <tool> (<workflow-type>)
|
|
222
|
+
[<timestamp>] "<message>" by <agent-role> via <tool> (<workflow-type>)
|
|
223
|
+
|
|
224
|
+
=== OPEN THREADS ===
|
|
225
|
+
[ ] <description> (opened <date>, <branch>, <workflow-type>)
|
|
226
|
+
[ ] <description> (opened <date>, <branch>, <workflow-type>)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
**Total budget: ~400–600 tokens. Flat cost regardless of project age.**
|
|
230
|
+
|
|
231
|
+
### 4.2 AGENTS.md Export
|
|
232
|
+
|
|
233
|
+
For Ralph loops and shell-script workflows, the snapshot can be exported as AGENTS.md:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
236
|
+
contextgit snapshot --format=agents-md > AGENTS.md
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
Generates a Ralph-compatible AGENTS.md with the same information structured for the Ralph prompt pattern:
|
|
240
|
+
|
|
241
|
+
```markdown
|
|
242
|
+
## Project State
|
|
243
|
+
Next.js 14, Tailwind, JWT RS256 auth, Stripe webhooks.
|
|
244
|
+
Middleware pattern for all auth. API routes under /api/v1.
|
|
245
|
+
|
|
246
|
+
## Current Branch: feature/rate-limiting
|
|
247
|
+
Implementing rate limiting. Redis chosen over in-memory.
|
|
248
|
+
Upstash client installed. Middleware skeleton in place.
|
|
249
|
+
|
|
250
|
+
## Recent Activity
|
|
251
|
+
- [2h ago] Upstash client configured (dev, Claude Code)
|
|
252
|
+
- [5h ago] Decided against in-memory store (dev, Ralph loop)
|
|
253
|
+
- [yesterday] Rate limit middleware skeleton created (dev, Ralph loop)
|
|
254
|
+
|
|
255
|
+
## Open Threads
|
|
256
|
+
- [ ] Sliding window vs fixed window — not yet decided
|
|
257
|
+
- [ ] Test coverage for rate limiter — pending
|
|
258
|
+
|
|
259
|
+
## Build & Run
|
|
260
|
+
<operational notes from AGENTS.md commits>
|
|
261
|
+
```
|
|
262
|
+
|
|
263
|
+
This is the bridge between ContextGit and Ralph. Ralph loops auto-generate AGENTS.md from accumulated context rather than maintaining it manually. It is never stale.
|
|
264
|
+
|
|
265
|
+
### 4.3 Why the Snapshot Stays Flat at Scale
|
|
266
|
+
|
|
267
|
+
A project with 300 commits across 20 branches still produces a ~500 token snapshot because:
|
|
268
|
+
|
|
269
|
+
- Project summary is a compressed distillation, not a log (max 2000 tokens)
|
|
270
|
+
- Branch summary covers only the current branch (max 500 tokens)
|
|
271
|
+
- Only the last 3 commits are included in full
|
|
272
|
+
- Open threads are short single-line descriptions
|
|
273
|
+
|
|
274
|
+
The other 297 commits exist in the database, searchable on demand:
|
|
275
|
+
|
|
276
|
+
```
|
|
277
|
+
context_get scope=search query="how we handled token refresh"
|
|
278
|
+
→ 2–3 most relevant commits, ~800 tokens, loaded only when needed
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## 5. Workflow Integrations
|
|
284
|
+
|
|
285
|
+
ContextGit is workflow-agnostic. The same context engine and storage layer serves every major AI agent pattern through the appropriate integration interface.
|
|
286
|
+
|
|
287
|
+
### 5.1 Interactive Sessions (MCP)
|
|
288
|
+
|
|
289
|
+
Claude Code, Cursor, Codex, and any MCP-compatible tool. The MCP server runs locally alongside the developer's tool. Zero workflow change required.
|
|
290
|
+
|
|
291
|
+
```
|
|
292
|
+
Developer opens Claude Code
|
|
293
|
+
→ MCP server starts, detects git branch
|
|
294
|
+
→ Agent calls context_get scope=global (via system prompt injection)
|
|
295
|
+
→ Receives compact snapshot, oriented in ~500 tokens
|
|
296
|
+
→ Works normally
|
|
297
|
+
→ context_commit called at milestones (agent-initiated or background snapshot)
|
|
298
|
+
→ Session closes
|
|
299
|
+
|
|
300
|
+
Next session
|
|
301
|
+
→ Same lean snapshot, updated with last session's commits
|
|
302
|
+
→ Agent picks up exactly where the last session left off
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
**Agent cooperation:** Background snapshotting every N tool calls (default 10) as a fallback for agents that don't call `context_commit` reliably. System prompt fragment instructs the agent when to commit. Both are belt-and-suspenders.
|
|
306
|
+
|
|
307
|
+
### 5.2 Ralph / Autonomous Loop (CLI)
|
|
308
|
+
|
|
309
|
+
Ralph's `while true` loop already solves the execution problem. ContextGit adds the memory layer without changing the loop mechanics.
|
|
310
|
+
|
|
311
|
+
```bash
|
|
312
|
+
#!/bin/bash
|
|
313
|
+
while true; do
|
|
314
|
+
# 1. Generate AGENTS.md from ContextGit snapshot (replaces manual maintenance)
|
|
315
|
+
contextgit snapshot --format=agents-md > AGENTS.md
|
|
316
|
+
|
|
317
|
+
# 2. Run Ralph iteration (reads AGENTS.md + IMPLEMENTATION_PLAN.md as always)
|
|
318
|
+
cat PROMPT.md | claude -p --dangerously-skip-permissions \
|
|
319
|
+
--output-format=stream-json \
|
|
320
|
+
--model opus \
|
|
321
|
+
--verbose
|
|
322
|
+
|
|
323
|
+
# 3. Checkpoint context after iteration completes
|
|
324
|
+
contextgit commit \
|
|
325
|
+
--message "Loop iteration: $(git log -1 --pretty=%s)" \
|
|
326
|
+
--workflow-type ralph-loop \
|
|
327
|
+
--loop-iteration $ITERATION
|
|
328
|
+
|
|
329
|
+
# 4. Push code as normal
|
|
330
|
+
git push origin "$(git branch --show-current)"
|
|
331
|
+
|
|
332
|
+
ITERATION=$((ITERATION + 1))
|
|
333
|
+
done
|
|
334
|
+
```
|
|
335
|
+
|
|
336
|
+
**What ContextGit adds to Ralph without changing it:**
|
|
337
|
+
|
|
338
|
+
- `AGENTS.md` is generated from accumulated context — never manually maintained, never stale
|
|
339
|
+
- Architectural decisions, failed approaches, and conventions discovered in one loop iteration persist across restarts
|
|
340
|
+
- When a second developer runs the same loop on the same project, their `AGENTS.md` reflects everything the first developer's loops discovered
|
|
341
|
+
- Web UI provides visibility into what the loop has been doing — branch tree, commit history, open threads — without reading raw git logs
|
|
342
|
+
|
|
343
|
+
**What stays unchanged:** `IMPLEMENTATION_PLAN.md` is entirely Ralph's domain. ContextGit does not touch it. Clean separation: Ralph owns task tracking, ContextGit owns institutional memory.
|
|
344
|
+
|
|
345
|
+
### 5.3 CI / GitHub Actions (REST API)
|
|
346
|
+
|
|
347
|
+
```yaml
|
|
348
|
+
# .github/workflows/ai-agent.yml
|
|
349
|
+
name: AI Context Agent
|
|
350
|
+
|
|
351
|
+
on: [pull_request]
|
|
352
|
+
|
|
353
|
+
jobs:
|
|
354
|
+
agent-review:
|
|
355
|
+
runs-on: ubuntu-latest
|
|
356
|
+
steps:
|
|
357
|
+
- uses: actions/checkout@v4
|
|
358
|
+
|
|
359
|
+
- name: Install ContextGit CLI
|
|
360
|
+
run: npm install -g contextgit
|
|
361
|
+
|
|
362
|
+
- name: Pull context snapshot
|
|
363
|
+
run: |
|
|
364
|
+
contextgit snapshot \
|
|
365
|
+
--project ${{ vars.CONTEXTHUB_PROJECT_ID }} \
|
|
366
|
+
--store ${{ secrets.CONTEXTHUB_REMOTE_URL }} \
|
|
367
|
+
--format agents-md > AGENTS.md
|
|
368
|
+
env:
|
|
369
|
+
CONTEXTHUB_API_KEY: ${{ secrets.CONTEXTHUB_API_KEY }}
|
|
370
|
+
|
|
371
|
+
- name: Run review agent
|
|
372
|
+
run: |
|
|
373
|
+
cat prompts/pr-review.md | claude -p \
|
|
374
|
+
--dangerously-skip-permissions \
|
|
375
|
+
--model sonnet
|
|
376
|
+
|
|
377
|
+
- name: Commit agent findings to context
|
|
378
|
+
run: |
|
|
379
|
+
contextgit commit \
|
|
380
|
+
--message "CI review: PR #${{ github.event.number }} findings" \
|
|
381
|
+
--workflow-type ci \
|
|
382
|
+
--ci-run-id ${{ github.run_id }} \
|
|
383
|
+
--store ${{ secrets.CONTEXTHUB_REMOTE_URL }}
|
|
384
|
+
env:
|
|
385
|
+
CONTEXTHUB_API_KEY: ${{ secrets.CONTEXTHUB_API_KEY }}
|
|
386
|
+
```
|
|
387
|
+
|
|
388
|
+
Every CI run builds on what previous runs discovered. A flaky test pattern found in one run is committed to context and surfaced to the next agent that touches the same code area.
|
|
389
|
+
|
|
390
|
+
### 5.4 Multi-Agent Orchestration (MCP or REST)
|
|
391
|
+
|
|
392
|
+
Sub-agents call `context_get scope=global` on startup. No manual briefing. Each agent writes its findings directly to the shared store, attributed by role and workflow type.
|
|
393
|
+
|
|
394
|
+
See Section 6 for full detail.
|
|
395
|
+
|
|
396
|
+
### 5.5 Custom Agent Frameworks (REST API)
|
|
397
|
+
|
|
398
|
+
LangChain, CrewAI, custom pipelines — any Python or Node.js orchestration framework calls the REST API directly:
|
|
399
|
+
|
|
400
|
+
```python
|
|
401
|
+
import requests
|
|
402
|
+
|
|
403
|
+
CONTEXTHUB_URL = "https://app.contextgit.dev"
|
|
404
|
+
PROJECT_ID = "uuid"
|
|
405
|
+
API_KEY = os.environ["CONTEXTHUB_API_KEY"]
|
|
406
|
+
headers = {"Authorization": f"Bearer {API_KEY}"}
|
|
407
|
+
|
|
408
|
+
# Session start — get compact snapshot
|
|
409
|
+
snapshot = requests.get(
|
|
410
|
+
f"{CONTEXTHUB_URL}/v1/projects/{PROJECT_ID}/snapshot",
|
|
411
|
+
headers=headers
|
|
412
|
+
).json()
|
|
413
|
+
|
|
414
|
+
# Inject into agent system prompt
|
|
415
|
+
system_context = snapshot["formatted"]["agents_md"]
|
|
416
|
+
|
|
417
|
+
# ... run pipeline with context ...
|
|
418
|
+
|
|
419
|
+
# Commit findings
|
|
420
|
+
requests.post(
|
|
421
|
+
f"{CONTEXTHUB_URL}/v1/projects/{PROJECT_ID}/commits",
|
|
422
|
+
json={
|
|
423
|
+
"message": "Pipeline run complete",
|
|
424
|
+
"content": pipeline_findings,
|
|
425
|
+
"workflowType": "custom",
|
|
426
|
+
"pipelineName": "langchain-review",
|
|
427
|
+
"threads": {"open": new_open_threads, "close": resolved_threads}
|
|
428
|
+
},
|
|
429
|
+
headers=headers
|
|
430
|
+
)
|
|
431
|
+
```
|
|
432
|
+
|
|
433
|
+
### 5.6 Background Agents
|
|
434
|
+
|
|
435
|
+
Background agents (Cursor background, autonomous overnight runs) connect via MCP. Their commits are attributed `workflow_type: background`. When the developer opens an interactive session the next morning, the snapshot includes everything the background agent discovered overnight — the same compact format, updated.
|
|
436
|
+
|
|
437
|
+
---
|
|
438
|
+
|
|
439
|
+
## 6. Multi-Agent Model
|
|
440
|
+
|
|
441
|
+
### 6.1 Agent Roles
|
|
442
|
+
|
|
443
|
+
Every agent is registered with a role:
|
|
444
|
+
|
|
445
|
+
| Role | Description | Typical workflow |
|
|
446
|
+
|------|-------------|-----------------|
|
|
447
|
+
| `orchestrator` | Coordinates agents, writes synthesis commits | Any |
|
|
448
|
+
| `dev` | Implements features | Interactive, Ralph, custom |
|
|
449
|
+
| `test` | Writes and runs tests, commits findings | Interactive, CI, Ralph |
|
|
450
|
+
| `review` | Reviews PRs and architecture | CI, interactive |
|
|
451
|
+
| `background` | Autonomous overnight or async work | Background agents |
|
|
452
|
+
| `ci` | CI pipeline agents | GitHub Actions, CI |
|
|
453
|
+
| `solo` | Default for single-developer setups | Interactive |
|
|
454
|
+
|
|
455
|
+
Role is set in MCP config or passed as a CLI flag. Stored on every commit for attribution and filtering.
|
|
456
|
+
|
|
457
|
+
### 6.2 Write Model
|
|
458
|
+
|
|
459
|
+
Every agent writes directly to the shared store. Every commit is attributed to its author agent, role, tool, and workflow type. The orchestrator additionally writes synthesis commits.
|
|
460
|
+
|
|
461
|
+
Append-only commits mean concurrent writes from multiple agents across multiple workflows do not conflict.
|
|
462
|
+
|
|
463
|
+
### 6.3 Multi-Agent + Multi-Workflow Example
|
|
464
|
+
|
|
465
|
+
```
|
|
466
|
+
feature/payments — 3 agents, 2 workflow types
|
|
467
|
+
|
|
468
|
+
Ralph loop (overnight):
|
|
469
|
+
contextgit snapshot > AGENTS.md
|
|
470
|
+
→ loop runs, dev agent implements Stripe integration
|
|
471
|
+
→ contextgit commit role=dev workflow=ralph-loop
|
|
472
|
+
"Stripe webhook endpoint created at /api/webhooks/stripe"
|
|
473
|
+
|
|
474
|
+
CI pipeline (triggered by push):
|
|
475
|
+
→ test agent: context snapshot pulled, aware of dev agent's commit
|
|
476
|
+
→ runs tests, finds edge case
|
|
477
|
+
→ contextgit commit role=ci workflow=ci ci-run-id=abc123
|
|
478
|
+
"24 tests passing. Duplicate webhook on network retry."
|
|
479
|
+
threads.open: ["network retry duplicate webhook — needs idempotency fix"]
|
|
480
|
+
|
|
481
|
+
Developer opens interactive session (morning):
|
|
482
|
+
→ context_get scope=global
|
|
483
|
+
→ snapshot shows: Stripe implemented (Ralph loop), test edge case found (CI)
|
|
484
|
+
→ open thread: duplicate webhook issue
|
|
485
|
+
→ developer's Claude Code agent picks up the thread immediately
|
|
486
|
+
→ context_commit role=dev workflow=interactive
|
|
487
|
+
"Idempotency key includes retry count. Duplicate issue resolved."
|
|
488
|
+
threads.close: ["network retry duplicate webhook — needs idempotency fix"]
|
|
489
|
+
```
|
|
490
|
+
|
|
491
|
+
No agent is manually briefed. No context is lost between workflow switches. The institutional memory accumulates across all of them.
|
|
492
|
+
|
|
493
|
+
---
|
|
494
|
+
|
|
495
|
+
## 7. Git Branch Synchronisation
|
|
496
|
+
|
|
497
|
+
Context branches mirror git branches automatically. No manual management required.
|
|
498
|
+
|
|
499
|
+
### 7.1 Branch Detection
|
|
500
|
+
|
|
501
|
+
The MCP server and CLI both read the current git branch:
|
|
502
|
+
|
|
503
|
+
```typescript
|
|
504
|
+
import simpleGit from 'simple-git'
|
|
505
|
+
|
|
506
|
+
const git = simpleGit(process.cwd())
|
|
507
|
+
const branch = await git.revparse(['--abbrev-ref', 'HEAD'])
|
|
508
|
+
// → "feature/payments"
|
|
509
|
+
// Auto-scope all commits to the matching context branch
|
|
510
|
+
// Create the context branch if it doesn't exist yet
|
|
511
|
+
```
|
|
512
|
+
|
|
513
|
+
### 7.2 Git Hooks
|
|
514
|
+
|
|
515
|
+
`contextgit init` offers to install three git hooks:
|
|
516
|
+
|
|
517
|
+
**post-checkout** — fires when developer switches branches, updates active context branch.
|
|
518
|
+
|
|
519
|
+
**post-merge** — fires when git merge completes, triggers context MERGE to match.
|
|
520
|
+
|
|
521
|
+
**post-commit** (optional) — fires on every git commit, creates lightweight auto context commit tagged to the git SHA.
|
|
522
|
+
|
|
523
|
+
### 7.3 Branch Lifecycle
|
|
524
|
+
|
|
525
|
+
```
|
|
526
|
+
git checkout -b feature/payments
|
|
527
|
+
→ context branch created: feature/payments
|
|
528
|
+
→ inherits main branch summary as starting point
|
|
529
|
+
|
|
530
|
+
[development across multiple sessions, workflows, agents]
|
|
531
|
+
|
|
532
|
+
git merge feature/payments (or PR merged)
|
|
533
|
+
→ post-merge hook fires
|
|
534
|
+
→ context branch merges into main
|
|
535
|
+
→ synthesis summary generated
|
|
536
|
+
→ unresolved open threads carried forward
|
|
537
|
+
→ context branch status → merged
|
|
538
|
+
|
|
539
|
+
git branch -d feature/payments
|
|
540
|
+
→ context branch remains (history is permanent)
|
|
541
|
+
→ accessible via web UI and search forever
|
|
542
|
+
```
|
|
543
|
+
|
|
544
|
+
---
|
|
545
|
+
|
|
546
|
+
## 8. Persistence Layer
|
|
547
|
+
|
|
548
|
+
### 8.1 Storage Interface
|
|
549
|
+
|
|
550
|
+
```typescript
|
|
551
|
+
interface ContextStore {
|
|
552
|
+
// Commits
|
|
553
|
+
createCommit(commit: CommitInput): Promise<Commit>
|
|
554
|
+
getCommit(id: string): Promise<Commit | null>
|
|
555
|
+
listCommits(branchId: string, pagination: Pagination): Promise<Commit[]>
|
|
556
|
+
getSessionSnapshot(projectId: string, branchId: string): Promise<SessionSnapshot>
|
|
557
|
+
getFormattedSnapshot(projectId: string, branchId: string, format: SnapshotFormat): Promise<string>
|
|
558
|
+
|
|
559
|
+
// Branches
|
|
560
|
+
createBranch(branch: BranchInput): Promise<Branch>
|
|
561
|
+
getBranch(id: string): Promise<Branch | null>
|
|
562
|
+
getBranchByGitName(projectId: string, gitBranch: string): Promise<Branch | null>
|
|
563
|
+
listBranches(projectId: string): Promise<Branch[]>
|
|
564
|
+
updateBranchHead(branchId: string, commitId: string): Promise<void>
|
|
565
|
+
mergeBranch(sourceBranchId: string, targetBranchId: string, summary: string): Promise<Commit>
|
|
566
|
+
|
|
567
|
+
// Open threads
|
|
568
|
+
listOpenThreads(projectId: string): Promise<Thread[]>
|
|
569
|
+
listOpenThreadsByBranch(branchId: string): Promise<Thread[]>
|
|
570
|
+
|
|
571
|
+
// Search
|
|
572
|
+
semanticSearch(query: string, projectId: string, limit: number): Promise<SearchResult[]>
|
|
573
|
+
fullTextSearch(query: string, projectId: string): Promise<SearchResult[]>
|
|
574
|
+
|
|
575
|
+
// Agents and projects
|
|
576
|
+
upsertAgent(agent: AgentInput): Promise<Agent>
|
|
577
|
+
listAgents(projectId: string): Promise<Agent[]>
|
|
578
|
+
getProject(id: string): Promise<Project | null>
|
|
579
|
+
createProject(project: ProjectInput): Promise<Project>
|
|
580
|
+
}
|
|
581
|
+
```
|
|
582
|
+
|
|
583
|
+
### 8.2 LocalStore (SQLite + sqlite-vec)
|
|
584
|
+
|
|
585
|
+
Used when `store: local`. Ships inside the npx binary. Zero external dependencies.
|
|
586
|
+
|
|
587
|
+
```sql
|
|
588
|
+
CREATE TABLE projects (
|
|
589
|
+
id TEXT PRIMARY KEY,
|
|
590
|
+
name TEXT NOT NULL,
|
|
591
|
+
description TEXT,
|
|
592
|
+
github_url TEXT,
|
|
593
|
+
created_at INTEGER NOT NULL
|
|
594
|
+
);
|
|
595
|
+
|
|
596
|
+
CREATE TABLE branches (
|
|
597
|
+
id TEXT PRIMARY KEY,
|
|
598
|
+
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
599
|
+
name TEXT NOT NULL,
|
|
600
|
+
git_branch TEXT NOT NULL,
|
|
601
|
+
github_pr_url TEXT,
|
|
602
|
+
parent_branch_id TEXT REFERENCES branches(id),
|
|
603
|
+
head_commit_id TEXT,
|
|
604
|
+
status TEXT NOT NULL DEFAULT 'active',
|
|
605
|
+
created_at INTEGER NOT NULL,
|
|
606
|
+
merged_at INTEGER
|
|
607
|
+
);
|
|
608
|
+
|
|
609
|
+
CREATE TABLE commits (
|
|
610
|
+
id TEXT PRIMARY KEY,
|
|
611
|
+
branch_id TEXT NOT NULL REFERENCES branches(id),
|
|
612
|
+
parent_id TEXT REFERENCES commits(id),
|
|
613
|
+
merge_source_branch_id TEXT REFERENCES branches(id),
|
|
614
|
+
agent_id TEXT NOT NULL,
|
|
615
|
+
agent_role TEXT NOT NULL DEFAULT 'solo',
|
|
616
|
+
tool TEXT NOT NULL,
|
|
617
|
+
workflow_type TEXT NOT NULL DEFAULT 'interactive',
|
|
618
|
+
loop_iteration INTEGER,
|
|
619
|
+
ci_run_id TEXT,
|
|
620
|
+
pipeline_name TEXT,
|
|
621
|
+
message TEXT NOT NULL,
|
|
622
|
+
content TEXT NOT NULL,
|
|
623
|
+
summary TEXT NOT NULL,
|
|
624
|
+
commit_type TEXT NOT NULL DEFAULT 'manual',
|
|
625
|
+
git_commit_sha TEXT,
|
|
626
|
+
created_at INTEGER NOT NULL
|
|
627
|
+
);
|
|
628
|
+
|
|
629
|
+
CREATE TABLE threads (
|
|
630
|
+
id TEXT PRIMARY KEY,
|
|
631
|
+
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
632
|
+
branch_id TEXT NOT NULL REFERENCES branches(id),
|
|
633
|
+
description TEXT NOT NULL,
|
|
634
|
+
status TEXT NOT NULL DEFAULT 'open',
|
|
635
|
+
workflow_type TEXT,
|
|
636
|
+
opened_in_commit TEXT NOT NULL REFERENCES commits(id),
|
|
637
|
+
closed_in_commit TEXT REFERENCES commits(id),
|
|
638
|
+
closed_note TEXT,
|
|
639
|
+
created_at INTEGER NOT NULL
|
|
640
|
+
);
|
|
641
|
+
|
|
642
|
+
CREATE TABLE agents (
|
|
643
|
+
id TEXT PRIMARY KEY,
|
|
644
|
+
project_id TEXT NOT NULL REFERENCES projects(id),
|
|
645
|
+
role TEXT NOT NULL DEFAULT 'solo',
|
|
646
|
+
tool TEXT NOT NULL,
|
|
647
|
+
workflow_type TEXT NOT NULL DEFAULT 'interactive',
|
|
648
|
+
display_name TEXT,
|
|
649
|
+
total_commits INTEGER DEFAULT 0,
|
|
650
|
+
last_seen INTEGER NOT NULL,
|
|
651
|
+
created_at INTEGER NOT NULL
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
CREATE VIRTUAL TABLE commit_embeddings USING vec0(
|
|
655
|
+
commit_id TEXT PRIMARY KEY,
|
|
656
|
+
embedding FLOAT[384]
|
|
657
|
+
);
|
|
658
|
+
|
|
659
|
+
CREATE INDEX idx_commits_branch ON commits(branch_id, created_at DESC);
|
|
660
|
+
CREATE INDEX idx_commits_workflow ON commits(project_id, workflow_type, created_at DESC);
|
|
661
|
+
CREATE INDEX idx_threads_project_status ON threads(project_id, status);
|
|
662
|
+
CREATE INDEX idx_branches_git ON branches(project_id, git_branch);
|
|
663
|
+
```
|
|
664
|
+
|
|
665
|
+
### 8.3 RemoteStore (Postgres + pgvector)
|
|
666
|
+
|
|
667
|
+
Mirrors LocalStore schema with additions for multi-tenancy and platform features:
|
|
668
|
+
|
|
669
|
+
```sql
|
|
670
|
+
CREATE TABLE organizations (
|
|
671
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
672
|
+
name TEXT NOT NULL,
|
|
673
|
+
slug TEXT UNIQUE NOT NULL,
|
|
674
|
+
plan TEXT NOT NULL DEFAULT 'free',
|
|
675
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
676
|
+
);
|
|
677
|
+
|
|
678
|
+
CREATE TABLE users (
|
|
679
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
680
|
+
org_id UUID REFERENCES organizations(id),
|
|
681
|
+
email TEXT UNIQUE NOT NULL,
|
|
682
|
+
display_name TEXT,
|
|
683
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
684
|
+
);
|
|
685
|
+
|
|
686
|
+
CREATE TABLE projects (
|
|
687
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
688
|
+
org_id UUID REFERENCES organizations(id),
|
|
689
|
+
name TEXT NOT NULL,
|
|
690
|
+
slug TEXT NOT NULL,
|
|
691
|
+
description TEXT,
|
|
692
|
+
visibility TEXT NOT NULL DEFAULT 'private',
|
|
693
|
+
github_url TEXT,
|
|
694
|
+
stars INTEGER DEFAULT 0,
|
|
695
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
696
|
+
UNIQUE(org_id, slug)
|
|
697
|
+
);
|
|
698
|
+
|
|
699
|
+
-- Core tables mirror LocalStore (UUID keys, TIMESTAMPTZ dates, same columns)
|
|
700
|
+
|
|
701
|
+
CREATE EXTENSION IF NOT EXISTS vector;
|
|
702
|
+
ALTER TABLE commits ADD COLUMN embedding vector(384);
|
|
703
|
+
CREATE INDEX ON commits USING ivfflat (embedding vector_cosine_ops) WITH (lists = 100);
|
|
704
|
+
|
|
705
|
+
CREATE TABLE stars (
|
|
706
|
+
user_id UUID REFERENCES users(id),
|
|
707
|
+
project_id UUID REFERENCES projects(id),
|
|
708
|
+
created_at TIMESTAMPTZ DEFAULT NOW(),
|
|
709
|
+
PRIMARY KEY (user_id, project_id)
|
|
710
|
+
);
|
|
711
|
+
|
|
712
|
+
CREATE TABLE forks (
|
|
713
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
714
|
+
source_project_id UUID REFERENCES projects(id),
|
|
715
|
+
forked_project_id UUID REFERENCES projects(id),
|
|
716
|
+
created_at TIMESTAMPTZ DEFAULT NOW()
|
|
717
|
+
);
|
|
718
|
+
|
|
719
|
+
-- Row-level security
|
|
720
|
+
ALTER TABLE projects ENABLE ROW LEVEL SECURITY;
|
|
721
|
+
CREATE POLICY "org members see own projects or public"
|
|
722
|
+
ON projects FOR ALL
|
|
723
|
+
USING (org_id = auth.jwt() ->> 'org_id' OR visibility = 'public');
|
|
724
|
+
```
|
|
725
|
+
|
|
726
|
+
### 8.4 getSessionSnapshot Implementation
|
|
727
|
+
|
|
728
|
+
```typescript
|
|
729
|
+
async getSessionSnapshot(projectId: string, branchId: string): Promise<SessionSnapshot> {
|
|
730
|
+
const headCommit = await this.getHeadCommit(branchId)
|
|
731
|
+
const branch = await this.getBranch(branchId)
|
|
732
|
+
|
|
733
|
+
const projectSummary = branch.parentBranchId
|
|
734
|
+
? await this.getHeadCommitSummary(branch.parentBranchId)
|
|
735
|
+
: headCommit.summary
|
|
736
|
+
|
|
737
|
+
const recentCommits = await this.listCommits(branchId, { limit: 3 })
|
|
738
|
+
const openThreads = await this.listOpenThreads(projectId)
|
|
739
|
+
|
|
740
|
+
return {
|
|
741
|
+
projectSummary, // max 2000 tokens
|
|
742
|
+
branchName: branch.name,
|
|
743
|
+
branchSummary: headCommit.summary, // max 500 tokens
|
|
744
|
+
recentCommits, // last 3, full content with workflow attribution
|
|
745
|
+
openThreads, // all open, short descriptions with workflow type
|
|
746
|
+
}
|
|
747
|
+
}
|
|
748
|
+
|
|
749
|
+
async getFormattedSnapshot(
|
|
750
|
+
projectId: string,
|
|
751
|
+
branchId: string,
|
|
752
|
+
format: 'agents-md' | 'json' | 'text'
|
|
753
|
+
): Promise<string> {
|
|
754
|
+
const snapshot = await this.getSessionSnapshot(projectId, branchId)
|
|
755
|
+
|
|
756
|
+
if (format === 'agents-md') {
|
|
757
|
+
return formatAsAgentsMd(snapshot) // Ralph-compatible markdown
|
|
758
|
+
} else if (format === 'json') {
|
|
759
|
+
return JSON.stringify(snapshot)
|
|
760
|
+
} else {
|
|
761
|
+
return formatAsText(snapshot)
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
---
|
|
767
|
+
|
|
768
|
+
## 9. Integration Interfaces
|
|
769
|
+
|
|
770
|
+
### 9.1 MCP Server
|
|
771
|
+
|
|
772
|
+
**Installation:**
|
|
773
|
+
|
|
774
|
+
```bash
|
|
775
|
+
npx contextgit init
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
Generates `.contextgit/config.json`:
|
|
779
|
+
|
|
780
|
+
```json
|
|
781
|
+
{
|
|
782
|
+
"project": "my-project",
|
|
783
|
+
"store": "local",
|
|
784
|
+
"agentRole": "solo",
|
|
785
|
+
"workflowType": "interactive",
|
|
786
|
+
"autoSnapshot": true,
|
|
787
|
+
"snapshotInterval": 10,
|
|
788
|
+
"installGitHooks": true,
|
|
789
|
+
"embeddingModel": "local"
|
|
790
|
+
}
|
|
791
|
+
```
|
|
792
|
+
|
|
793
|
+
**MCP Tools exposed to agent:** `context_get`, `context_commit`, `context_branch`, `context_merge` — same as before. See prior version for full tool schemas.
|
|
794
|
+
|
|
795
|
+
**Background snapshotting:** MCP server counts tool calls and auto-commits every N calls (default 10). Tagged `commit_type: auto`, displayed differently in the web UI, can be promoted to manual.
|
|
796
|
+
|
|
797
|
+
**System prompt fragment** injected by `contextgit init`:
|
|
798
|
+
|
|
799
|
+
```
|
|
800
|
+
You have access to a persistent context system. Use it consistently.
|
|
801
|
+
|
|
802
|
+
ALWAYS at session start: call context_get scope="global". This returns a compact
|
|
803
|
+
snapshot (~500 tokens) of project state, branch, recent commits, and open threads.
|
|
804
|
+
Read it before doing anything else.
|
|
805
|
+
|
|
806
|
+
DURING work, call context_commit when you: complete a feature or fix, make an
|
|
807
|
+
architectural decision, discover a failed approach, open or close a thread.
|
|
808
|
+
|
|
809
|
+
WHEN exploring uncertain approaches: context_branch first. Abandon or merge.
|
|
810
|
+
|
|
811
|
+
FOR specific past decisions: context_get scope=search. Do not load raw history.
|
|
812
|
+
|
|
813
|
+
The snapshot is NOT the PRD. It is distilled reality. Treat it as ground truth.
|
|
814
|
+
```
|
|
815
|
+
|
|
816
|
+
### 9.2 CLI
|
|
817
|
+
|
|
818
|
+
```bash
|
|
819
|
+
# Installation (alongside MCP server, same package)
|
|
820
|
+
npm install -g contextgit
|
|
821
|
+
# or without global install
|
|
822
|
+
npx contextgit <command>
|
|
823
|
+
|
|
824
|
+
# Core commands
|
|
825
|
+
contextgit init # init project, generate config, install hooks
|
|
826
|
+
contextgit snapshot # print snapshot to stdout (text format)
|
|
827
|
+
contextgit snapshot --format agents-md # print AGENTS.md formatted snapshot
|
|
828
|
+
contextgit snapshot --format json # print JSON snapshot
|
|
829
|
+
contextgit commit --message "..." # create a context commit
|
|
830
|
+
contextgit commit --message "..." \
|
|
831
|
+
--workflow-type ralph-loop \
|
|
832
|
+
--loop-iteration 42 # commit with workflow metadata
|
|
833
|
+
contextgit search "query" # semantic search, prints results
|
|
834
|
+
contextgit branch create <name> # create context branch
|
|
835
|
+
contextgit branch merge <name> # merge context branch
|
|
836
|
+
contextgit clone <url> # clone public context repository
|
|
837
|
+
contextgit push # push local context to remote store
|
|
838
|
+
contextgit pull # pull remote context to local store
|
|
839
|
+
contextgit status # show current branch, head commit, open threads
|
|
840
|
+
|
|
841
|
+
# Remote store flags (override config)
|
|
842
|
+
contextgit snapshot --store <url> --api-key <key>
|
|
843
|
+
contextgit commit --store <url> --api-key <key>
|
|
844
|
+
```
|
|
845
|
+
|
|
846
|
+
**Ralph loop integration (canonical pattern):**
|
|
847
|
+
|
|
848
|
+
```bash
|
|
849
|
+
#!/bin/bash
|
|
850
|
+
ITERATION=0
|
|
851
|
+
|
|
852
|
+
while true; do
|
|
853
|
+
# Auto-generate AGENTS.md — never manually maintained
|
|
854
|
+
contextgit snapshot --format agents-md > AGENTS.md
|
|
855
|
+
|
|
856
|
+
# Ralph iteration
|
|
857
|
+
cat PROMPT.md | claude -p \
|
|
858
|
+
--dangerously-skip-permissions \
|
|
859
|
+
--output-format=stream-json \
|
|
860
|
+
--model opus \
|
|
861
|
+
--verbose
|
|
862
|
+
|
|
863
|
+
# Checkpoint context
|
|
864
|
+
contextgit commit \
|
|
865
|
+
--message "$(git log -1 --pretty=%s)" \
|
|
866
|
+
--workflow-type ralph-loop \
|
|
867
|
+
--loop-iteration $ITERATION
|
|
868
|
+
|
|
869
|
+
git push origin "$(git branch --show-current)"
|
|
870
|
+
ITERATION=$((ITERATION + 1))
|
|
871
|
+
done
|
|
872
|
+
```
|
|
873
|
+
|
|
874
|
+
### 9.3 REST API
|
|
875
|
+
|
|
876
|
+
Full feature parity with the MCP server. Used by CI pipelines, custom frameworks, and any non-MCP agent.
|
|
877
|
+
|
|
878
|
+
See Section 10 for endpoint reference.
|
|
879
|
+
|
|
880
|
+
---
|
|
881
|
+
|
|
882
|
+
## 10. API Layer
|
|
883
|
+
|
|
884
|
+
### 10.1 REST Endpoints
|
|
885
|
+
|
|
886
|
+
**Context operations (MCP server, CLI, pipelines)**
|
|
887
|
+
```
|
|
888
|
+
POST /v1/projects/:id/commits
|
|
889
|
+
GET /v1/projects/:id/commits/:commitId
|
|
890
|
+
GET /v1/projects/:id/snapshot ← session start contract (JSON)
|
|
891
|
+
GET /v1/projects/:id/snapshot?format=agents-md ← AGENTS.md format
|
|
892
|
+
POST /v1/projects/:id/branches
|
|
893
|
+
PATCH /v1/projects/:id/branches/:branchId
|
|
894
|
+
POST /v1/projects/:id/branches/:branchId/merge
|
|
895
|
+
POST /v1/projects/:id/search
|
|
896
|
+
GET /v1/projects/:id/threads?status=open
|
|
897
|
+
GET /v1/projects/:id/agents
|
|
898
|
+
```
|
|
899
|
+
|
|
900
|
+
**Platform operations (web frontend)**
|
|
901
|
+
```
|
|
902
|
+
GET /v1/projects ← explore public repos
|
|
903
|
+
GET /v1/projects/:org/:slug ← project home
|
|
904
|
+
POST /v1/projects/:org/:slug/star
|
|
905
|
+
POST /v1/projects/:org/:slug/fork
|
|
906
|
+
GET /v1/projects/:org/:slug/clone-bundle ← download context bundle
|
|
907
|
+
GET /v1/projects/:org/:slug/commits ← paginated history
|
|
908
|
+
GET /v1/projects/:org/:slug/branches ← branch tree
|
|
909
|
+
```
|
|
910
|
+
|
|
911
|
+
### 10.2 WebSocket Events
|
|
912
|
+
|
|
913
|
+
```typescript
|
|
914
|
+
WS /v1/projects/:id/live
|
|
915
|
+
|
|
916
|
+
// Server emits — now includes workflow_type for dashboard filtering
|
|
917
|
+
{ type: "agent_commit", agentId, role, workflowType, commitId, message, branchName, timestamp }
|
|
918
|
+
{ type: "agent_branch", agentId, role, workflowType, branchId, name, timestamp }
|
|
919
|
+
{ type: "agent_merge", agentId, role, workflowType, branchId, timestamp }
|
|
920
|
+
{ type: "thread_opened", threadId, description, workflowType, branchName, agentId, timestamp }
|
|
921
|
+
{ type: "thread_closed", threadId, note, workflowType, agentId, timestamp }
|
|
922
|
+
{ type: "agent_active", agentId, role, tool, workflowType, branchName, timestamp }
|
|
923
|
+
{ type: "loop_iteration", loopIteration, agentId, branchName, timestamp } // Ralph loops
|
|
924
|
+
{ type: "ci_run", ciRunId, pipelineName, status, branchName, timestamp } // CI
|
|
925
|
+
```
|
|
926
|
+
|
|
927
|
+
### 10.3 Clone Bundle
|
|
928
|
+
|
|
929
|
+
```
|
|
930
|
+
GET /v1/projects/:org/:slug/clone-bundle
|
|
931
|
+
|
|
932
|
+
Response: application/zip
|
|
933
|
+
context-bundle.zip
|
|
934
|
+
├── manifest.json ← schema version, project metadata, branch list
|
|
935
|
+
├── branches.json ← full branch tree with metadata
|
|
936
|
+
├── commits.ndjson ← all commits with workflow attribution
|
|
937
|
+
├── threads.json ← all threads (open and closed)
|
|
938
|
+
└── embeddings.bin ← pre-computed embeddings (optional)
|
|
939
|
+
```
|
|
940
|
+
|
|
941
|
+
---
|
|
942
|
+
|
|
943
|
+
## 11. Web Platform
|
|
944
|
+
|
|
945
|
+
### 11.1 Routes
|
|
946
|
+
|
|
947
|
+
```
|
|
948
|
+
/ ← Explore: public repos, trending, search
|
|
949
|
+
/explore ← Browse all public repos
|
|
950
|
+
/:org/:project ← Project home
|
|
951
|
+
/:org/:project/commits ← Commit history with diff view
|
|
952
|
+
/:org/:project/branches ← Branch tree (D3.js)
|
|
953
|
+
/:org/:project/threads ← Open and closed threads
|
|
954
|
+
/:org/:project/search ← Semantic + full-text search
|
|
955
|
+
/:org/:project/agents ← Agent registry and attribution
|
|
956
|
+
/:org/:project/workflows ← Workflow activity breakdown
|
|
957
|
+
/dashboard ← Team live dashboard
|
|
958
|
+
/dashboard/:project ← Project-level live view with workflow filter
|
|
959
|
+
```
|
|
960
|
+
|
|
961
|
+
### 11.2 Key Components
|
|
962
|
+
|
|
963
|
+
**Explore page** — Public context repos, stars, recent activity, tag search. The network-effect surface.
|
|
964
|
+
|
|
965
|
+
**Project home** — Description, linked GitHub repo, star count, clone command. Workflow activity summary showing which workflow types are most active on this project.
|
|
966
|
+
|
|
967
|
+
**Branch tree** — D3.js visualisation. Nodes coloured by agent role. Shape indicates workflow type (circle=interactive, diamond=ralph-loop, square=ci). Hovering shows commit message, author, and workflow. Clicking opens diff view.
|
|
968
|
+
|
|
969
|
+
**Commit diff view** — Previous vs new summary, full content, thread operations, full attribution: agent, role, tool, workflow type, loop iteration or CI run ID if applicable.
|
|
970
|
+
|
|
971
|
+
**Threads panel** — Open and closed threads across all workflows. Filterable by branch, workflow type, agent, date. Closed threads show resolution note and linked commit.
|
|
972
|
+
|
|
973
|
+
**Workflow breakdown page (`/workflows`)** — New in v3. Shows contribution breakdown by workflow type: how many commits came from interactive sessions vs Ralph loops vs CI vs background agents. Timeline of activity. Helps teams understand how their agents are actually being used.
|
|
974
|
+
|
|
975
|
+
**Team dashboard (live)** — Real-time activity across all workflows via WebSocket. Filter by workflow type: see only Ralph loop commits, or only CI commits, or everything. The "war room" view for teams running parallel workflows.
|
|
976
|
+
|
|
977
|
+
**Semantic search** — Full-text and vector similarity. Filterable by branch, agent role, workflow type, date, tags, thread status.
|
|
978
|
+
|
|
979
|
+
### 11.3 Frontend Stack
|
|
980
|
+
|
|
981
|
+
```
|
|
982
|
+
React 18 + TypeScript
|
|
983
|
+
React Router v6
|
|
984
|
+
Tailwind CSS
|
|
985
|
+
D3.js ← branch tree, knowledge map, workflow timeline
|
|
986
|
+
TanStack Query ← data fetching and caching
|
|
987
|
+
Zustand ← client state
|
|
988
|
+
WebSocket (native) ← live dashboard
|
|
989
|
+
```
|
|
990
|
+
|
|
991
|
+
---
|
|
992
|
+
|
|
993
|
+
## 12. Data Model
|
|
994
|
+
|
|
995
|
+
### 12.1 Core Entities and Relationships
|
|
996
|
+
|
|
997
|
+
```
|
|
998
|
+
Organization 1──* User
|
|
999
|
+
Organization 1──* Project
|
|
1000
|
+
Project 1──* Branch
|
|
1001
|
+
Project 1──* Thread
|
|
1002
|
+
Project 1──* Agent
|
|
1003
|
+
Branch 1──* Commit
|
|
1004
|
+
Branch 0──1 Branch (parent)
|
|
1005
|
+
Branch 0──1 GitPR (linked PR URL)
|
|
1006
|
+
Commit 0──1 Commit (parent)
|
|
1007
|
+
Commit 0──1 Branch (merge source)
|
|
1008
|
+
Commit 1──* Thread (opened or closed in this commit)
|
|
1009
|
+
Commit *──1 WorkflowMeta (type, loop iteration, CI run ID)
|
|
1010
|
+
Agent *──1 User
|
|
1011
|
+
Agent *──1 Role
|
|
1012
|
+
Agent *──1 WorkflowType
|
|
1013
|
+
Agent 1──* Commit
|
|
1014
|
+
```
|
|
1015
|
+
|
|
1016
|
+
### 12.2 Key Field Constraints
|
|
1017
|
+
|
|
1018
|
+
- Rolling summaries: max 2000 tokens (enforced before write)
|
|
1019
|
+
- Branch summaries: max 500 tokens
|
|
1020
|
+
- Thread descriptions: max 200 characters
|
|
1021
|
+
- Commit content: unbounded
|
|
1022
|
+
- Embeddings: 384 dimensions (all-MiniLM-L6-v2, configurable)
|
|
1023
|
+
- Workflow type: enum `interactive | ralph-loop | ci | background | custom`
|
|
1024
|
+
|
|
1025
|
+
---
|
|
1026
|
+
|
|
1027
|
+
## 13. Authentication and Multi-tenancy
|
|
1028
|
+
|
|
1029
|
+
**Phase 1 (local):** No auth. LocalStore at `~/.contextgit/`.
|
|
1030
|
+
|
|
1031
|
+
**Phase 2 (remote):** Email + password via Supabase Auth. GitHub OAuth. API keys for programmatic access (MCP server, CLI, REST). API keys scoped by role — read-only keys for CI agents, read-write for dev agents.
|
|
1032
|
+
|
|
1033
|
+
**Phase 3 (team tier):** SSO via SAML/OIDC. Per-workflow API keys — CI pipelines get a CI-scoped key, Ralph loops get a dev-scoped key. Audit log captures every commit with full workflow attribution.
|
|
1034
|
+
|
|
1035
|
+
**Multi-tenancy:** Row-level security in Postgres. Every query scoped to authenticated org. Public project reads bypass RLS. Writes always require authentication.
|
|
1036
|
+
|
|
1037
|
+
---
|
|
1038
|
+
|
|
1039
|
+
## 14. Deployment Architecture
|
|
1040
|
+
|
|
1041
|
+
### 14.1 Phase 1 — Local Only
|
|
1042
|
+
|
|
1043
|
+
```
|
|
1044
|
+
Developer machine:
|
|
1045
|
+
npx contextgit (MCP server + CLI, ~50MB with SQLite bundled)
|
|
1046
|
+
└── ~/.contextgit/projects/<project-id>.db
|
|
1047
|
+
```
|
|
1048
|
+
|
|
1049
|
+
No cloud. No accounts. Single npm package.
|
|
1050
|
+
|
|
1051
|
+
### 14.2 Phase 2 and 3 — Hosted
|
|
1052
|
+
|
|
1053
|
+
```
|
|
1054
|
+
Supabase (managed Postgres):
|
|
1055
|
+
- Core database with workflow attribution columns
|
|
1056
|
+
- pgvector (semantic search)
|
|
1057
|
+
- Auth (email, GitHub OAuth, SSO)
|
|
1058
|
+
- Realtime (WebSocket for live dashboard)
|
|
1059
|
+
- Row-level security (multi-tenancy)
|
|
1060
|
+
|
|
1061
|
+
Vercel (web platform):
|
|
1062
|
+
- Next.js frontend
|
|
1063
|
+
- API routes
|
|
1064
|
+
- CDN for static assets
|
|
1065
|
+
- Edge functions for clone bundle generation
|
|
1066
|
+
|
|
1067
|
+
Enterprise (self-hosted):
|
|
1068
|
+
Docker Compose:
|
|
1069
|
+
- Node.js API server
|
|
1070
|
+
- Postgres + pgvector
|
|
1071
|
+
- React frontend (nginx)
|
|
1072
|
+
- Optional: local embedding model server
|
|
1073
|
+
```
|
|
1074
|
+
|
|
1075
|
+
### 14.3 Cost Profile (Bootstrapped)
|
|
1076
|
+
|
|
1077
|
+
Supabase free tier covers all development and early beta. Upgrade to Supabase Pro ($25/month) when team tier customers onboard. Vercel free tier covers the web platform until significant traffic.
|
|
1078
|
+
|
|
1079
|
+
**Total infrastructure cost until first paying customer: $0.**
|
|
1080
|
+
|
|
1081
|
+
---
|
|
1082
|
+
|
|
1083
|
+
## 15. Phase Build Plan
|
|
1084
|
+
|
|
1085
|
+
### Phase 1 — Weeks 1–4: Core Engine + All Three Interfaces
|
|
1086
|
+
|
|
1087
|
+
| Week | Deliverable |
|
|
1088
|
+
|------|-------------|
|
|
1089
|
+
| 1 | Fork GCC/Aline. Storage interface + LocalStore. COMMIT and CONTEXT working. Workflow attribution columns in schema from day one. |
|
|
1090
|
+
| 2 | BRANCH and MERGE. Rolling summary (rule-based). Open threads. SNAPSHOT command with agents-md format. |
|
|
1091
|
+
| 3 | MCP server. CLI. Git branch detection + hook installer. Background snapshotting. |
|
|
1092
|
+
| 4 | REST API (core endpoints). Vector embeddings. Package as npx binary. Validate on real project across two workflows: interactive + Ralph loop. |
|
|
1093
|
+
|
|
1094
|
+
**Phase 1 gate (all three must pass):**
|
|
1095
|
+
- Does `context_get scope=global` return a snapshot that orients an agent without reading any other documentation?
|
|
1096
|
+
- Does `contextgit snapshot --format agents-md` generate a useful AGENTS.md in a real Ralph loop?
|
|
1097
|
+
- Does the REST API snapshot endpoint work correctly for a simulated CI pipeline call?
|
|
1098
|
+
|
|
1099
|
+
### Phase 2 — Weeks 5–8: Team, Multi-Agent, CI
|
|
1100
|
+
|
|
1101
|
+
| Week | Deliverable |
|
|
1102
|
+
|------|-------------|
|
|
1103
|
+
| 5 | RemoteStore (Postgres + pgvector). Supabase setup. API key auth with role scoping. |
|
|
1104
|
+
| 6 | Agent registry with roles and workflow types. Orchestrator synthesis commits. |
|
|
1105
|
+
| 7 | CI integration — GitHub Actions example workflow, tested end to end. Context sync push/pull. |
|
|
1106
|
+
| 8 | Multi-workflow test: Ralph loop + interactive session + CI pipeline, all writing to same project. Validate cross-workflow context retrieval. |
|
|
1107
|
+
|
|
1108
|
+
**Phase 2 gate:** Three different workflow types contributing to the same project context store. Each workflow's snapshot reflects commits from the others.
|
|
1109
|
+
|
|
1110
|
+
### Phase 3 — Weeks 9–14: Web Platform
|
|
1111
|
+
|
|
1112
|
+
| Week | Deliverable |
|
|
1113
|
+
|------|-------------|
|
|
1114
|
+
| 9 | REST API for platform. Auth. Project home. |
|
|
1115
|
+
| 10 | Branch tree (D3.js, workflow-type node shapes). Commit diff view with full attribution. |
|
|
1116
|
+
| 11 | Threads panel. Workflow breakdown page. Search UI. |
|
|
1117
|
+
| 12 | Public repos. Clone bundle. Star and fork. |
|
|
1118
|
+
| 13 | Live team dashboard with workflow filter (WebSocket). Knowledge map. |
|
|
1119
|
+
| 14 | Polish, performance, docs. Public beta. |
|
|
1120
|
+
|
|
1121
|
+
---
|
|
1122
|
+
|
|
1123
|
+
## 16. Open Questions
|
|
1124
|
+
|
|
1125
|
+
**Rolling summary quality in Phase 1** — Rule-based compression may produce poor summaries on complex projects. Is it good enough to validate the concept in week 4, or do we need an LLM call from the start? If the Phase 1 gate fails because of summary quality, this is the first fix.
|
|
1126
|
+
|
|
1127
|
+
**Embedding model** — Local all-MiniLM-L6-v2 (384 dim, no API key, ~23MB) vs OpenAI text-embedding-3-small (better quality, requires key). Start local, make it configurable.
|
|
1128
|
+
|
|
1129
|
+
**Ralph loop commit noise** — Each loop iteration creates one context commit. A 200-iteration run creates 200 commits. Should Ralph-loop commits have a different retention/display policy than interactive commits? Recommendation: show by default but allow filtering by workflow type in the UI.
|
|
1130
|
+
|
|
1131
|
+
**CI commit granularity** — A CI pipeline that runs 50 times a day would create 50 context commits per day. Most of these may be low signal. Should CI commits be filtered unless they open a new thread or match a significance threshold? Recommendation: CI commits visible but deprioritised in the snapshot's "last 3 commits" display — only surfaced if they opened an open thread.
|
|
1132
|
+
|
|
1133
|
+
**Auto-commit noise (interactive sessions)** — At 10 tool calls per auto-snapshot, an active session generates 20-30 auto commits per hour. Should auto commits be hidden by default in the UI?
|
|
1134
|
+
|
|
1135
|
+
**Thread granularity** — Per-project threads are simpler and always visible. Per-branch threads are more organised but risk siloing unresolved questions. Recommendation: per-project with branch attribution.
|
|
1136
|
+
|
|
1137
|
+
**Public platform timing** — Invite-only for first 30 days to ensure quality of early public repos. Open after.
|
|
1138
|
+
|
|
1139
|
+
---
|
|
1140
|
+
|
|
1141
|
+
*Update this document as architectural decisions are made and validated. Every open question above should be resolved before the relevant phase begins.*
|