contextgit 0.1.4 → 0.1.6

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.
Files changed (30) hide show
  1. package/README.md +130 -0
  2. package/bin/contextgit-mcp.js +7 -0
  3. package/package.json +24 -14
  4. package/node_modules/@contextgit/mcp/dist/auto-snapshot.d.ts +0 -30
  5. package/node_modules/@contextgit/mcp/dist/auto-snapshot.d.ts.map +0 -1
  6. package/node_modules/@contextgit/mcp/dist/auto-snapshot.js +0 -68
  7. package/node_modules/@contextgit/mcp/dist/auto-snapshot.js.map +0 -1
  8. package/node_modules/@contextgit/mcp/dist/config.d.ts +0 -17
  9. package/node_modules/@contextgit/mcp/dist/config.d.ts.map +0 -1
  10. package/node_modules/@contextgit/mcp/dist/config.js +0 -48
  11. package/node_modules/@contextgit/mcp/dist/config.js.map +0 -1
  12. package/node_modules/@contextgit/mcp/dist/git-sync.d.ts +0 -15
  13. package/node_modules/@contextgit/mcp/dist/git-sync.d.ts.map +0 -1
  14. package/node_modules/@contextgit/mcp/dist/git-sync.js +0 -87
  15. package/node_modules/@contextgit/mcp/dist/git-sync.js.map +0 -1
  16. package/node_modules/@contextgit/mcp/dist/index.d.ts +0 -3
  17. package/node_modules/@contextgit/mcp/dist/index.d.ts.map +0 -1
  18. package/node_modules/@contextgit/mcp/dist/index.js +0 -17
  19. package/node_modules/@contextgit/mcp/dist/index.js.map +0 -1
  20. package/node_modules/@contextgit/mcp/dist/server.d.ts +0 -3
  21. package/node_modules/@contextgit/mcp/dist/server.d.ts.map +0 -1
  22. package/node_modules/@contextgit/mcp/dist/server.js +0 -377
  23. package/node_modules/@contextgit/mcp/dist/server.js.map +0 -1
  24. package/node_modules/@contextgit/mcp/package.json +0 -31
  25. package/node_modules/@contextgit/mcp/src/auto-snapshot.ts +0 -83
  26. package/node_modules/@contextgit/mcp/src/config.ts +0 -53
  27. package/node_modules/@contextgit/mcp/src/git-sync.ts +0 -94
  28. package/node_modules/@contextgit/mcp/src/index.ts +0 -19
  29. package/node_modules/@contextgit/mcp/src/server.ts +0 -568
  30. package/node_modules/@contextgit/mcp/tsconfig.json +0 -9
package/README.md ADDED
@@ -0,0 +1,130 @@
1
+ # ContextGit
2
+
3
+ Every time you start a new session with an AI coding agent, it starts from zero. It doesn't know what was built yesterday, what decisions were made, or what's left to do. You spend the first 10 minutes of every session re-explaining your project. ContextGit fixes this — it gives your agents a persistent memory layer that survives across sessions, branches, and machines.
4
+
5
+ ## Install
6
+
7
+ ```bash
8
+ npm install -g contextgit
9
+ cd your-project
10
+ contextgit init
11
+ ```
12
+
13
+ > **Restart Claude Code** (or any MCP client) after running `init` for the MCP server to take effect.
14
+
15
+ That's it. `init` registers the MCP server, updates CLAUDE.md with session instructions, and installs Claude Code hooks. Start a new session — the agent calls `project_memory_load` automatically and picks up exactly where the last session left off.
16
+
17
+ ## How it works
18
+
19
+ ContextGit stores structured context commits alongside your git history. Each commit captures what was done, what was decided, and what questions remain open.
20
+
21
+ ```
22
+ Session 1: Agent builds auth module → saves context commit
23
+ Session 2: Agent loads snapshot → knows auth is done → starts on the next task
24
+ ```
25
+
26
+ ## What the agent sees
27
+
28
+ When an agent calls `project_memory_load`, it gets a snapshot like this:
29
+
30
+ ```
31
+ ## Project State
32
+ Auth module complete. API routes tested. Database schema finalized.
33
+
34
+ ## Current Branch: Context: main
35
+ Implementing payment integration. Stripe SDK configured.
36
+
37
+ ## Recent Activity
38
+ - [2026-03-20T08:33:44Z] "Payment webhook handler done" by solo via claude-code
39
+ - [2026-03-20T07:15:22Z] "Stripe SDK integration" by solo via claude-code
40
+ - [2026-03-19T16:42:11Z] "Auth module complete" by solo via claude-code
41
+
42
+ ## Open Threads
43
+ - [FREE] Need to add rate limiting to payment endpoints
44
+ - [CLAIMED by studio-mcp-agent] Build invoice PDF generation
45
+ - [FREE] Decide on webhook retry strategy
46
+
47
+ ## Active Claims
48
+ - "Build invoice PDF generation" claimed by studio-mcp-agent (2h TTL)
49
+ ```
50
+
51
+ The agent reads this and knows exactly where the project stands without you saying a word.
52
+
53
+ ## MCP tools
54
+
55
+ These tools are exposed to the agent via MCP. The agent calls them as part of its normal workflow.
56
+
57
+ | Tool | What it does |
58
+ |------|-------------|
59
+ | `project_memory_load` | Load the full project snapshot — what was built, what's decided, open threads, active claims. Call at session start. |
60
+ | `project_memory_save` | Save a context commit — what you did, decisions made, open questions. Call before ending a session. |
61
+ | `context_search` | Semantic + full-text search over past context commits. |
62
+ | `project_task_claim` | Claim a task so other agents skip it. Claims auto-expire after 2 hours. |
63
+ | `project_task_unclaim` | Release a claimed task. |
64
+ | `project_memory_branch` | Create a context branch for experimental work. |
65
+ | `project_memory_merge` | Merge a context branch back into the parent. |
66
+
67
+ ## CLI commands
68
+
69
+ ```bash
70
+ contextgit init # Initialize contextgit in current project
71
+ contextgit init --hooks # Initialize with git hooks
72
+ contextgit commit "message" # Write a context commit
73
+ contextgit status # Show current project state
74
+ contextgit search "query" # Search past commits
75
+ contextgit claim "task" # Claim a task
76
+ contextgit unclaim <id> # Release a claim
77
+ contextgit branch <name> # Create a context branch
78
+ contextgit merge <id> # Merge a context branch
79
+ contextgit serve # Start the REST API server
80
+ ```
81
+
82
+ ## Architecture
83
+
84
+ Monorepo with strict dependency ordering:
85
+
86
+ ```
87
+ packages/
88
+ core/ → Types, snapshot formatter, embedding service, context engine
89
+ store/ → Storage interface, LocalStore (SQLite), RemoteStore, SupabaseStore
90
+ mcp/ → MCP server (stdio transport, launched by Claude Code)
91
+ cli/ → CLI commands (oclif)
92
+ api/ → REST API (Express)
93
+ ```
94
+
95
+ **Local storage:** SQLite via better-sqlite3. One DB per project at `~/.contextgit/projects/<id>.db`.
96
+
97
+ **Remote storage:** Optional Supabase (Postgres + pgvector) for cross-machine sync and team use.
98
+
99
+ **Embeddings:** Local all-MiniLM-L6-v2 (384 dimensions, no API key needed) for semantic search.
100
+
101
+ ## Configuration
102
+
103
+ Project config lives at `.contextgit/config.json`:
104
+
105
+ ```json
106
+ {
107
+ "project": "my-project",
108
+ "projectId": "unique-id",
109
+ "store": "local",
110
+ "agentRole": "solo",
111
+ "workflowType": "interactive",
112
+ "autoSnapshot": false,
113
+ "snapshotInterval": 10,
114
+ "embeddingModel": "local"
115
+ }
116
+ ```
117
+
118
+ ## Current status
119
+
120
+ This is an early-stage tool. It works for solo developers using Claude Code across one or more machines. The core memory layer is solid — context commits, branches, threads, search, and snapshots all work.
121
+
122
+ ## Known limitations
123
+
124
+ - No automatic context merge when git branches are merged (manual `project_memory_merge` required)
125
+ - No integration with external boards (Linear, Jira, GitHub Issues)
126
+ - Semantic search requires the embedding model to download on first use (~23MB)
127
+
128
+ ## License
129
+
130
+ MIT
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env node
2
+ // Starts the ContextGit MCP server (stdio transport).
3
+ // Uses Node module resolution — works whether @contextgit/mcp is nested or hoisted.
4
+ import('@contextgit/mcp').catch(err => {
5
+ console.error('[contextgit-mcp] Failed to start:', err.message)
6
+ process.exit(1)
7
+ })
package/package.json CHANGED
@@ -1,10 +1,10 @@
1
1
  {
2
2
  "name": "contextgit",
3
- "version": "0.1.4",
3
+ "version": "0.1.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "contextgit": "./bin/run.js",
7
- "contextgit-mcp": "./node_modules/@contextgit/mcp/dist/index.js"
7
+ "contextgit-mcp": "./bin/contextgit-mcp.js"
8
8
  },
9
9
  "oclif": {
10
10
  "bin": "contextgit",
@@ -15,24 +15,34 @@
15
15
  "dist",
16
16
  "bin"
17
17
  ],
18
+ "keywords": [
19
+ "ai",
20
+ "coding-agent",
21
+ "memory",
22
+ "context",
23
+ "git",
24
+ "mcp",
25
+ "claude-code",
26
+ "llm",
27
+ "persistent-memory"
28
+ ],
29
+ "description": "Persistent memory layer for AI agent workflows",
30
+ "license": "MIT",
31
+ "scripts": {
32
+ "build": "tsc",
33
+ "typecheck": "tsc --noEmit"
34
+ },
18
35
  "dependencies": {
19
- "@contextgit/core": "0.1.4",
20
- "@contextgit/store": "0.1.4",
21
- "@contextgit/api": "0.1.4",
22
- "@contextgit/mcp": "0.1.4",
36
+ "@contextgit/core": "0.1.6",
37
+ "@contextgit/store": "0.1.6",
38
+ "@contextgit/api": "0.1.6",
39
+ "@contextgit/mcp": "0.1.6",
23
40
  "@oclif/core": "^3.27.0",
24
41
  "nanoid": "^5.0.0",
25
42
  "simple-git": "^3.27.0"
26
43
  },
27
- "bundleDependencies": [
28
- "@contextgit/mcp"
29
- ],
30
44
  "devDependencies": {
31
45
  "@types/node": "^20.0.0",
32
46
  "typescript": "^5.4.0"
33
- },
34
- "scripts": {
35
- "build": "tsc",
36
- "typecheck": "tsc --noEmit"
37
47
  }
38
- }
48
+ }
@@ -1,30 +0,0 @@
1
- import type { ContextEngine } from '@contextgit/core';
2
- export interface AutoSnapshotOptions {
3
- /** Number of non-commit tool calls before an auto-commit fires. Default: 10. */
4
- interval?: number;
5
- }
6
- export declare class AutoSnapshotManager {
7
- private count;
8
- private readonly interval;
9
- private readonly engine;
10
- constructor(engine: ContextEngine, options?: AutoSnapshotOptions);
11
- /**
12
- * Record a tool call by name.
13
- *
14
- * - `context_commit` resets the counter (manual commit; no auto-commit fired).
15
- * - All other tool names increment the counter.
16
- * - When the counter reaches `interval`, an auto-commit is fired and the
17
- * counter resets to 0.
18
- *
19
- * Auto-commit failures are swallowed — the tool call is never blocked.
20
- *
21
- * @returns The new commit ID if an auto-commit was fired, otherwise undefined.
22
- */
23
- onToolCall(toolName: string): Promise<string | undefined>;
24
- /** Current tool-call count since the last commit (manual or auto). */
25
- get toolCallCount(): number;
26
- /** Manually reset the counter (e.g. after an out-of-band commit). */
27
- reset(): void;
28
- private fireAutoCommit;
29
- }
30
- //# sourceMappingURL=auto-snapshot.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-snapshot.d.ts","sourceRoot":"","sources":["../src/auto-snapshot.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,kBAAkB,CAAA;AAErD,MAAM,WAAW,mBAAmB;IAClC,gFAAgF;IAChF,QAAQ,CAAC,EAAE,MAAM,CAAA;CAClB;AAED,qBAAa,mBAAmB;IAC9B,OAAO,CAAC,KAAK,CAAI;IACjB,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAQ;IACjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAe;gBAE1B,MAAM,EAAE,aAAa,EAAE,OAAO,GAAE,mBAAwB;IAKpE;;;;;;;;;;;OAWG;IACG,UAAU,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;IAgB/D,sEAAsE;IACtE,IAAI,aAAa,IAAI,MAAM,CAE1B;IAED,qEAAqE;IACrE,KAAK,IAAI,IAAI;YAMC,cAAc;CAa7B"}
@@ -1,68 +0,0 @@
1
- // auto-snapshot.ts — AutoSnapshotManager
2
- //
3
- // Tracks tool calls made to the MCP server and fires an automatic context_commit
4
- // after every N=10 non-commit calls. This ensures context is preserved even when
5
- // the agent forgets to call context_commit manually.
6
- //
7
- // Context tool semantics:
8
- // context_commit → resets the counter (manual commit = checkpoint reached)
9
- // context_get → counted (each session-start snapshot counts toward the interval)
10
- // context_search → counted
11
- // any other tool → counted (future tools)
12
- export class AutoSnapshotManager {
13
- count = 0;
14
- interval;
15
- engine;
16
- constructor(engine, options = {}) {
17
- this.engine = engine;
18
- this.interval = options.interval ?? 10;
19
- }
20
- /**
21
- * Record a tool call by name.
22
- *
23
- * - `context_commit` resets the counter (manual commit; no auto-commit fired).
24
- * - All other tool names increment the counter.
25
- * - When the counter reaches `interval`, an auto-commit is fired and the
26
- * counter resets to 0.
27
- *
28
- * Auto-commit failures are swallowed — the tool call is never blocked.
29
- *
30
- * @returns The new commit ID if an auto-commit was fired, otherwise undefined.
31
- */
32
- async onToolCall(toolName) {
33
- if (toolName === 'context_commit') {
34
- this.count = 0;
35
- return undefined;
36
- }
37
- this.count++;
38
- if (this.count >= this.interval) {
39
- this.count = 0;
40
- return this.fireAutoCommit();
41
- }
42
- return undefined;
43
- }
44
- /** Current tool-call count since the last commit (manual or auto). */
45
- get toolCallCount() {
46
- return this.count;
47
- }
48
- /** Manually reset the counter (e.g. after an out-of-band commit). */
49
- reset() {
50
- this.count = 0;
51
- }
52
- // ─── Private ──────────────────────────────────────────────────────────────
53
- async fireAutoCommit() {
54
- try {
55
- const commit = await this.engine.commit({
56
- message: `Auto-snapshot after ${this.interval} tool calls`,
57
- content: `Automatic context checkpoint triggered after ${this.interval} tool calls without a manual context_commit.`,
58
- commitType: 'auto',
59
- });
60
- return commit.id;
61
- }
62
- catch {
63
- // Never block a tool call due to auto-snapshot failure.
64
- return undefined;
65
- }
66
- }
67
- }
68
- //# sourceMappingURL=auto-snapshot.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"auto-snapshot.js","sourceRoot":"","sources":["../src/auto-snapshot.ts"],"names":[],"mappings":"AAAA,yCAAyC;AACzC,EAAE;AACF,iFAAiF;AACjF,iFAAiF;AACjF,qDAAqD;AACrD,EAAE;AACF,0BAA0B;AAC1B,8EAA8E;AAC9E,uFAAuF;AACvF,8BAA8B;AAC9B,6CAA6C;AAS7C,MAAM,OAAO,mBAAmB;IACtB,KAAK,GAAG,CAAC,CAAA;IACA,QAAQ,CAAQ;IAChB,MAAM,CAAe;IAEtC,YAAY,MAAqB,EAAE,UAA+B,EAAE;QAClE,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAA;IACxC,CAAC;IAED;;;;;;;;;;;OAWG;IACH,KAAK,CAAC,UAAU,CAAC,QAAgB;QAC/B,IAAI,QAAQ,KAAK,gBAAgB,EAAE,CAAC;YAClC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;YACd,OAAO,SAAS,CAAA;QAClB,CAAC;QAED,IAAI,CAAC,KAAK,EAAE,CAAA;QAEZ,IAAI,IAAI,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE,CAAC;YAChC,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;YACd,OAAO,IAAI,CAAC,cAAc,EAAE,CAAA;QAC9B,CAAC;QAED,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,sEAAsE;IACtE,IAAI,aAAa;QACf,OAAO,IAAI,CAAC,KAAK,CAAA;IACnB,CAAC;IAED,qEAAqE;IACrE,KAAK;QACH,IAAI,CAAC,KAAK,GAAG,CAAC,CAAA;IAChB,CAAC;IAED,6EAA6E;IAErE,KAAK,CAAC,cAAc;QAC1B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;gBACtC,OAAO,EAAE,uBAAuB,IAAI,CAAC,QAAQ,aAAa;gBAC1D,OAAO,EAAE,gDAAgD,IAAI,CAAC,QAAQ,8CAA8C;gBACpH,UAAU,EAAE,MAAM;aACnB,CAAC,CAAA;YACF,OAAO,MAAM,CAAC,EAAE,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,wDAAwD;YACxD,OAAO,SAAS,CAAA;QAClB,CAAC;IACH,CAAC;CACF"}
@@ -1,17 +0,0 @@
1
- import type { ContextGitConfig } from '@contextgit/core';
2
- export declare class ConfigNotFoundError extends Error {
3
- constructor(startDir: string);
4
- }
5
- /**
6
- * Search upward from `startDir` for `.contextgit/config.json`.
7
- * Returns the first match found, or throws ConfigNotFoundError.
8
- */
9
- export declare function findConfigPath(startDir?: string): string;
10
- /**
11
- * Load and parse `.contextgit/config.json`.
12
- * Throws ConfigNotFoundError if not found, or Error if JSON is invalid.
13
- */
14
- export declare function loadConfig(startDir?: string): ContextGitConfig & {
15
- configDir: string;
16
- };
17
- //# sourceMappingURL=config.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,kBAAkB,CAAA;AAExD,qBAAa,mBAAoB,SAAQ,KAAK;gBAChC,QAAQ,EAAE,MAAM;CAI7B;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,QAAQ,GAAE,MAAsB,GAAG,MAAM,CAevE;AAED;;;GAGG;AACH,wBAAgB,UAAU,CAAC,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,GAAG;IAAE,SAAS,EAAE,MAAM,CAAA;CAAE,CAatF"}
@@ -1,48 +0,0 @@
1
- // config.ts — load and validate .contextgit/config.json
2
- // Searches from CWD upwards until it finds the config file.
3
- import { readFileSync } from 'fs';
4
- import { join, dirname } from 'path';
5
- export class ConfigNotFoundError extends Error {
6
- constructor(startDir) {
7
- super(`No .contextgit/config.json found searching upward from: ${startDir}`);
8
- this.name = 'ConfigNotFoundError';
9
- }
10
- }
11
- /**
12
- * Search upward from `startDir` for `.contextgit/config.json`.
13
- * Returns the first match found, or throws ConfigNotFoundError.
14
- */
15
- export function findConfigPath(startDir = process.cwd()) {
16
- let current = startDir;
17
- while (true) {
18
- const candidate = join(current, '.contextgit', 'config.json');
19
- try {
20
- readFileSync(candidate);
21
- return candidate;
22
- }
23
- catch {
24
- const parent = dirname(current);
25
- if (parent === current) {
26
- throw new ConfigNotFoundError(startDir);
27
- }
28
- current = parent;
29
- }
30
- }
31
- }
32
- /**
33
- * Load and parse `.contextgit/config.json`.
34
- * Throws ConfigNotFoundError if not found, or Error if JSON is invalid.
35
- */
36
- export function loadConfig(startDir) {
37
- const configPath = findConfigPath(startDir);
38
- const raw = readFileSync(configPath, 'utf-8');
39
- const config = JSON.parse(raw);
40
- if (!config.projectId) {
41
- throw new Error(`Invalid config at ${configPath}: missing required field 'projectId'`);
42
- }
43
- if (!config.project) {
44
- throw new Error(`Invalid config at ${configPath}: missing required field 'project'`);
45
- }
46
- return { ...config, configDir: dirname(configPath) };
47
- }
48
- //# sourceMappingURL=config.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"config.js","sourceRoot":"","sources":["../src/config.ts"],"names":[],"mappings":"AAAA,wDAAwD;AACxD,4DAA4D;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAA;AACjC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAGpC,MAAM,OAAO,mBAAoB,SAAQ,KAAK;IAC5C,YAAY,QAAgB;QAC1B,KAAK,CAAC,2DAA2D,QAAQ,EAAE,CAAC,CAAA;QAC5E,IAAI,CAAC,IAAI,GAAG,qBAAqB,CAAA;IACnC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,WAAmB,OAAO,CAAC,GAAG,EAAE;IAC7D,IAAI,OAAO,GAAG,QAAQ,CAAA;IACtB,OAAO,IAAI,EAAE,CAAC;QACZ,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,EAAE,aAAa,EAAE,aAAa,CAAC,CAAA;QAC7D,IAAI,CAAC;YACH,YAAY,CAAC,SAAS,CAAC,CAAA;YACvB,OAAO,SAAS,CAAA;QAClB,CAAC;QAAC,MAAM,CAAC;YACP,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;YAC/B,IAAI,MAAM,KAAK,OAAO,EAAE,CAAC;gBACvB,MAAM,IAAI,mBAAmB,CAAC,QAAQ,CAAC,CAAA;YACzC,CAAC;YACD,OAAO,GAAG,MAAM,CAAA;QAClB,CAAC;IACH,CAAC;AACH,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,UAAU,CAAC,QAAiB;IAC1C,MAAM,UAAU,GAAG,cAAc,CAAC,QAAQ,CAAC,CAAA;IAC3C,MAAM,GAAG,GAAG,YAAY,CAAC,UAAU,EAAE,OAAO,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAAqB,CAAA;IAElD,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,sCAAsC,CAAC,CAAA;IACxF,CAAC;IACD,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,IAAI,KAAK,CAAC,qBAAqB,UAAU,oCAAoC,CAAC,CAAA;IACtF,CAAC;IAED,OAAO,EAAE,GAAG,MAAM,EAAE,SAAS,EAAE,OAAO,CAAC,UAAU,CAAC,EAAE,CAAA;AACtD,CAAC"}
@@ -1,15 +0,0 @@
1
- /**
2
- * Capture the current git commit SHA and branch name.
3
- * Returns null on any error — must never block a context commit.
4
- */
5
- export declare function captureGitMetadata(cwd: string): Promise<{
6
- sha: string;
7
- branch: string;
8
- } | null>;
9
- /**
10
- * Install contextgit git hooks into <projectRoot>/.git/hooks/.
11
- * Idempotent: checks for the sentinel comment before appending.
12
- * Hook failures are logged to ~/.contextgit/hooks.log — never to stderr.
13
- */
14
- export declare function installGitHooks(projectRoot: string): Promise<void>;
15
- //# sourceMappingURL=git-sync.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"git-sync.d.ts","sourceRoot":"","sources":["../src/git-sync.ts"],"names":[],"mappings":"AAkBA;;;GAGG;AACH,wBAAsB,kBAAkB,CACtC,GAAG,EAAE,MAAM,GACV,OAAO,CAAC;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAWjD;AAmBD;;;;GAIG;AACH,wBAAsB,eAAe,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAwBxE"}
@@ -1,87 +0,0 @@
1
- // git-sync.ts — git metadata capture and hook installation.
2
- //
3
- // captureGitMetadata: used by context_commit (MCP) and commit CLI command to
4
- // auto-populate gitCommitSha on every context commit.
5
- //
6
- // installGitHooks: idempotent hook installer — writes post-commit,
7
- // post-checkout, post-merge scripts into .git/hooks/.
8
- import { writeFileSync, readFileSync, mkdirSync, existsSync, appendFileSync } from 'fs';
9
- import { join, resolve } from 'path';
10
- import { homedir } from 'os';
11
- import { simpleGit } from 'simple-git';
12
- const SENTINEL = '# contextgit';
13
- const HOOKS_LOG = join(homedir(), '.contextgit', 'hooks.log');
14
- // ─── captureGitMetadata ────────────────────────────────────────────────────────
15
- /**
16
- * Capture the current git commit SHA and branch name.
17
- * Returns null on any error — must never block a context commit.
18
- */
19
- export async function captureGitMetadata(cwd) {
20
- try {
21
- const git = simpleGit(cwd);
22
- const [sha, branch] = await Promise.all([
23
- git.revparse(['HEAD']),
24
- git.revparse(['--abbrev-ref', 'HEAD']),
25
- ]);
26
- return { sha: sha.trim(), branch: branch.trim() };
27
- }
28
- catch {
29
- return null;
30
- }
31
- }
32
- // ─── installGitHooks ──────────────────────────────────────────────────────────
33
- const HOOK_SCRIPTS = {
34
- 'post-commit': `#!/bin/sh
35
- ${SENTINEL}
36
- contextgit commit -m "git: $(git log -1 --pretty=%s)" 2>>"${HOOKS_LOG}" || true
37
- `,
38
- 'post-checkout': `#!/bin/sh
39
- ${SENTINEL}
40
- contextgit context --quiet 2>>"${HOOKS_LOG}" || true
41
- `,
42
- 'post-merge': `#!/bin/sh
43
- ${SENTINEL}
44
- contextgit commit -m "Merged into $(git rev-parse --abbrev-ref HEAD)" 2>>"${HOOKS_LOG}" || true
45
- `,
46
- };
47
- /**
48
- * Install contextgit git hooks into <projectRoot>/.git/hooks/.
49
- * Idempotent: checks for the sentinel comment before appending.
50
- * Hook failures are logged to ~/.contextgit/hooks.log — never to stderr.
51
- */
52
- export async function installGitHooks(projectRoot) {
53
- const hooksDir = join(resolve(projectRoot), '.git', 'hooks');
54
- mkdirSync(hooksDir, { recursive: true });
55
- for (const [hookName, script] of Object.entries(HOOK_SCRIPTS)) {
56
- const hookPath = join(hooksDir, hookName);
57
- if (existsSync(hookPath)) {
58
- const existing = readFileSync(hookPath, 'utf-8');
59
- if (existing.includes(SENTINEL))
60
- continue; // already installed
61
- // Append to existing hook
62
- writeFileSync(hookPath, existing.trimEnd() + '\n\n' + script);
63
- }
64
- else {
65
- writeFileSync(hookPath, script);
66
- }
67
- // Make executable (chmod +x)
68
- try {
69
- const { chmodSync } = await import('fs');
70
- chmodSync(hookPath, 0o755);
71
- }
72
- catch {
73
- logHookError(`chmod failed for ${hookPath}`);
74
- }
75
- }
76
- }
77
- function logHookError(msg) {
78
- try {
79
- const dir = join(homedir(), '.contextgit');
80
- mkdirSync(dir, { recursive: true });
81
- appendFileSync(HOOKS_LOG, `[${new Date().toISOString()}] ${msg}\n`);
82
- }
83
- catch {
84
- // truly silent
85
- }
86
- }
87
- //# sourceMappingURL=git-sync.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"git-sync.js","sourceRoot":"","sources":["../src/git-sync.ts"],"names":[],"mappings":"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"}
@@ -1,3 +0,0 @@
1
- #!/usr/bin/env node
2
- export {};
3
- //# sourceMappingURL=index.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
@@ -1,17 +0,0 @@
1
- #!/usr/bin/env node
2
- // index.ts — entry point for the ContextGit MCP server process.
3
- // Started by the MCP host (Claude Desktop / Claude Code) via stdio.
4
- import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
- import { createServer } from './server.js';
6
- async function main() {
7
- const server = await createServer();
8
- const transport = new StdioServerTransport();
9
- await server.connect(transport);
10
- // Server is now listening on stdin/stdout — process stays alive until the
11
- // host closes the connection.
12
- }
13
- main().catch(err => {
14
- console.error('[contextgit-mcp] Fatal error:', err);
15
- process.exit(1);
16
- });
17
- //# sourceMappingURL=index.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,gEAAgE;AAChE,oEAAoE;AAEpE,OAAO,EAAE,oBAAoB,EAAE,MAAM,2CAA2C,CAAA;AAChF,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE1C,KAAK,UAAU,IAAI;IACjB,MAAM,MAAM,GAAG,MAAM,YAAY,EAAE,CAAA;IACnC,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAA;IAC5C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAA;IAC/B,0EAA0E;IAC1E,8BAA8B;AAChC,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACjB,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAA;IACnD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;AACjB,CAAC,CAAC,CAAA"}
@@ -1,3 +0,0 @@
1
- import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
2
- export declare function createServer(): Promise<McpServer>;
3
- //# sourceMappingURL=server.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../src/server.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAA;AAsGnE,wBAAsB,YAAY,IAAI,OAAO,CAAC,SAAS,CAAC,CA4bvD"}