contextgit 0.0.4 → 0.0.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.
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAgD5C,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,MAAM,CAAC,WAAW,SAA0C;IAE5D,MAAM,CAAC,KAAK;;;MAWX;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CA0G3B"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,OAAO,EAAS,MAAM,aAAa,CAAA;AAyD5C,MAAM,CAAC,OAAO,OAAO,IAAK,SAAQ,OAAO;IACvC,MAAM,CAAC,WAAW,SAA0C;IAE5D,MAAM,CAAC,KAAK;;;MAWX;IAEK,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;CAwJ3B"}
@@ -7,6 +7,14 @@ import { nanoid } from 'nanoid';
7
7
  import { simpleGit } from 'simple-git';
8
8
  import { LocalStore } from '@contextgit/store';
9
9
  import { installGitHooks } from '../git-hooks.js';
10
+ import { detectClients, injectMcpServer } from '../lib/client-config.js';
11
+ const MCP_SYSTEM_PROMPT = `You have access to ContextGit memory tools.
12
+
13
+ At the start of every session, call context_get with scope=global immediately — before reading any files, before asking any questions, before doing any work. Do not skip this step.
14
+
15
+ After completing significant work (a feature, a decision, a resolved problem), call context_commit with a message describing what was done, what was decided, and any open questions. Include the current git branch and commit hash at the top of the message.
16
+
17
+ If you are about to explore a risky or experimental approach, call context_branch first to create an isolated context workspace.`;
10
18
  const SYSTEM_PROMPT_FRAGMENT = `\
11
19
  You have access to ContextGit memory tools.
12
20
 
@@ -148,9 +156,59 @@ export default class Init extends Command {
148
156
  }
149
157
  this.log(``);
150
158
  this.log(`System prompt written to .contextgit/system-prompt.md`);
151
- this.log(`Add its contents to your Claude Code MCP config to enable ContextGit.`);
152
159
  this.log(``);
153
- this.log(SYSTEM_PROMPT_FRAGMENT);
160
+ // ── Auto-configure MCP clients ─────────────────────────────────────────────
161
+ try {
162
+ const clients = detectClients();
163
+ if (clients.length === 0) {
164
+ this.log(`⚠️ No MCP clients detected.`);
165
+ this.log(``);
166
+ this.log(`Add the following to your MCP client config manually:`);
167
+ this.log(``);
168
+ this.log(` "contextgit": {`);
169
+ this.log(` "command": "npx",`);
170
+ this.log(` "args": ["contextgit", "mcp"],`);
171
+ this.log(` "systemPrompt": "${MCP_SYSTEM_PROMPT.replace(/\n/g, '\\n')}"`);
172
+ this.log(` }`);
173
+ this.log(``);
174
+ this.log(`Searched:`);
175
+ this.log(` ~/.claude.json`);
176
+ this.log(` ~/.cursor/mcp.json`);
177
+ this.log(` ~/Library/Application Support/Claude/claude_desktop_config.json`);
178
+ }
179
+ else {
180
+ let anyInjected = false;
181
+ for (const client of clients) {
182
+ const result = injectMcpServer(client.path, client.type, MCP_SYSTEM_PROMPT);
183
+ const label = clientLabel(client.type).padEnd(14);
184
+ const shortPath = client.path.replace(process.env['HOME'] ?? '', '~');
185
+ if (result.status === 'injected') {
186
+ this.log(`✅ Configured ${label} (${shortPath})`);
187
+ anyInjected = true;
188
+ }
189
+ else if (result.status === 'already-present') {
190
+ this.log(`⏭ ${label} already configured (skipped)`);
191
+ }
192
+ else if (result.status === 'error') {
193
+ this.log(`❌ ${label} config error: ${result.reason}`);
194
+ this.log(` Path: ${shortPath}`);
195
+ this.log(` Fix manually or re-run after repairing the file.`);
196
+ }
197
+ else {
198
+ this.log(`⏭ ${label} not found (skipped)`);
199
+ }
200
+ }
201
+ if (anyInjected) {
202
+ this.log(``);
203
+ this.log(`ContextGit is ready. Open Claude Code in this project and start a session.`);
204
+ this.log(`The agent will call context_get automatically on every session start.`);
205
+ }
206
+ }
207
+ }
208
+ catch (err) {
209
+ this.log(`⚠️ Could not auto-configure MCP clients: ${String(err)}`);
210
+ this.log(`Add the MCP server entry manually — see .contextgit/system-prompt.md`);
211
+ }
154
212
  }
155
213
  }
156
214
  // ─── Helpers ──────────────────────────────────────────────────────────────────
@@ -166,6 +224,15 @@ async function detectGitBranch(cwd) {
166
224
  function writeSystemPrompt(promptPath) {
167
225
  writeFileSync(promptPath, SYSTEM_PROMPT_FRAGMENT);
168
226
  }
227
+ function clientLabel(type) {
228
+ if (type === 'claude-code')
229
+ return 'Claude Code';
230
+ if (type === 'cursor')
231
+ return 'Cursor';
232
+ if (type === 'claude-desktop')
233
+ return 'Claude Desktop';
234
+ return type;
235
+ }
169
236
  /** Prompt the user with a yes/no question. Defaults to yes on empty input. */
170
237
  function promptYesNo(question) {
171
238
  return new Promise(resolve => {
@@ -1 +1 @@
1
- {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"init.js","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ export type ClientType = 'claude-code' | 'cursor' | 'claude-desktop';
2
+ export interface DetectedClient {
3
+ type: ClientType;
4
+ path: string;
5
+ }
6
+ export interface InjectionResult {
7
+ status: 'injected' | 'already-present' | 'skipped' | 'error';
8
+ reason?: string;
9
+ }
10
+ /** Return all MCP clients whose config file exists on disk. */
11
+ export declare function detectClients(home?: string): DetectedClient[];
12
+ /** Check whether a contextgit entry already exists under mcpServers. */
13
+ export declare function isAlreadyInjected(config: Record<string, unknown>): boolean;
14
+ /**
15
+ * Inject the contextgit MCP server entry into the given client config file.
16
+ * Uses an atomic write (temp file + rename) so the original is never corrupted.
17
+ */
18
+ export declare function injectMcpServer(configPath: string, _clientType: ClientType, systemPrompt: string): InjectionResult;
19
+ //# sourceMappingURL=client-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-config.d.ts","sourceRoot":"","sources":["../../src/lib/client-config.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,UAAU,GAAG,aAAa,GAAG,QAAQ,GAAG,gBAAgB,CAAA;AAEpE,MAAM,WAAW,cAAc;IAC7B,IAAI,EAAE,UAAU,CAAA;IAChB,IAAI,EAAE,MAAM,CAAA;CACb;AAED,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,GAAG,iBAAiB,GAAG,SAAS,GAAG,OAAO,CAAA;IAC5D,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAoBD,+DAA+D;AAC/D,wBAAgB,aAAa,CAAC,IAAI,GAAE,MAAkB,GAAG,cAAc,EAAE,CAKxE;AAED,wEAAwE;AACxE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAI1E;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAC7B,UAAU,EAAE,MAAM,EAClB,WAAW,EAAE,UAAU,EACvB,YAAY,EAAE,MAAM,GACnB,eAAe,CAyCjB"}
@@ -0,0 +1,74 @@
1
+ import { existsSync, readFileSync, writeFileSync, renameSync } from 'fs';
2
+ import { homedir } from 'os';
3
+ import { join } from 'path';
4
+ const MCP_ENTRY = {
5
+ command: 'npx',
6
+ args: ['contextgit', 'mcp'],
7
+ };
8
+ /** Resolve known config paths for each client type. */
9
+ function clientPaths(home) {
10
+ const appData = process.env['APPDATA'] ?? '';
11
+ return {
12
+ 'claude-code': join(home, '.claude.json'),
13
+ 'cursor': join(home, '.cursor', 'mcp.json'),
14
+ 'claude-desktop': process.platform === 'win32'
15
+ ? join(appData, 'Claude', 'claude_desktop_config.json')
16
+ : join(home, 'Library', 'Application Support', 'Claude', 'claude_desktop_config.json'),
17
+ };
18
+ }
19
+ /** Return all MCP clients whose config file exists on disk. */
20
+ export function detectClients(home = homedir()) {
21
+ const paths = clientPaths(home);
22
+ return Object.keys(paths)
23
+ .filter(type => existsSync(paths[type]))
24
+ .map(type => ({ type, path: paths[type] }));
25
+ }
26
+ /** Check whether a contextgit entry already exists under mcpServers. */
27
+ export function isAlreadyInjected(config) {
28
+ const servers = config['mcpServers'] ?? config['globalShortcuts']?.['mcpServers'];
29
+ if (!servers || typeof servers !== 'object')
30
+ return false;
31
+ return 'contextgit' in servers;
32
+ }
33
+ /**
34
+ * Inject the contextgit MCP server entry into the given client config file.
35
+ * Uses an atomic write (temp file + rename) so the original is never corrupted.
36
+ */
37
+ export function injectMcpServer(configPath, _clientType, systemPrompt) {
38
+ // Read existing content — create empty object if file doesn't exist
39
+ let raw = '{}';
40
+ if (existsSync(configPath)) {
41
+ raw = readFileSync(configPath, 'utf8');
42
+ }
43
+ let config;
44
+ try {
45
+ config = JSON.parse(raw);
46
+ }
47
+ catch {
48
+ return {
49
+ status: 'error',
50
+ reason: 'existing config is not valid JSON — skipped to avoid data loss',
51
+ };
52
+ }
53
+ if (isAlreadyInjected(config)) {
54
+ return { status: 'already-present' };
55
+ }
56
+ // Resolve the mcpServers object — handle Claude Desktop's globalShortcuts wrapper
57
+ let target;
58
+ if (config['globalShortcuts'] &&
59
+ typeof config['globalShortcuts'] === 'object' &&
60
+ 'mcpServers' in config['globalShortcuts']) {
61
+ target = config['globalShortcuts']['mcpServers'];
62
+ }
63
+ else {
64
+ if (!config['mcpServers'])
65
+ config['mcpServers'] = {};
66
+ target = config['mcpServers'];
67
+ }
68
+ target['contextgit'] = { ...MCP_ENTRY, systemPrompt };
69
+ const tmpPath = configPath + '.contextgit-tmp';
70
+ writeFileSync(tmpPath, JSON.stringify(config, null, 2) + '\n', 'utf8');
71
+ renameSync(tmpPath, configPath);
72
+ return { status: 'injected' };
73
+ }
74
+ //# sourceMappingURL=client-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-config.js","sourceRoot":"","sources":["../../src/lib/client-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=client-config.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-config.test.d.ts","sourceRoot":"","sources":["../../src/lib/client-config.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,97 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
2
+ import { mkdtempSync, rmSync, writeFileSync, readFileSync, existsSync } from 'fs';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ import { detectClients, injectMcpServer, isAlreadyInjected } from './client-config.js';
6
+ const SYSTEM_PROMPT = 'test system prompt';
7
+ let tmpDir;
8
+ beforeEach(() => {
9
+ tmpDir = mkdtempSync(join(tmpdir(), 'contextgit-test-'));
10
+ });
11
+ afterEach(() => {
12
+ rmSync(tmpDir, { recursive: true, force: true });
13
+ });
14
+ // 1. detectClients returns empty array when no config files exist
15
+ it('detectClients returns empty array when no config files exist', () => {
16
+ const result = detectClients(tmpDir);
17
+ expect(result).toEqual([]);
18
+ });
19
+ // 2. detectClients returns Claude Code entry when ~/.claude.json exists
20
+ it('detectClients returns claude-code when .claude.json exists', () => {
21
+ writeFileSync(join(tmpDir, '.claude.json'), '{}');
22
+ const result = detectClients(tmpDir);
23
+ expect(result).toHaveLength(1);
24
+ expect(result[0].type).toBe('claude-code');
25
+ expect(result[0].path).toBe(join(tmpDir, '.claude.json'));
26
+ });
27
+ // 3. injectMcpServer writes correct JSON structure to a new empty config file
28
+ it('injectMcpServer writes correct JSON to a new empty config file', () => {
29
+ const configPath = join(tmpDir, '.claude.json');
30
+ // file does not exist yet
31
+ const result = injectMcpServer(configPath, 'claude-code', SYSTEM_PROMPT);
32
+ expect(result.status).toBe('injected');
33
+ const written = JSON.parse(readFileSync(configPath, 'utf8'));
34
+ const servers = written['mcpServers'];
35
+ expect(servers).toBeDefined();
36
+ const entry = servers['contextgit'];
37
+ expect(entry['command']).toBe('npx');
38
+ expect(entry['args']).toEqual(['contextgit', 'mcp']);
39
+ expect(entry['systemPrompt']).toBe(SYSTEM_PROMPT);
40
+ });
41
+ // 4. injectMcpServer merges into existing config without touching other keys
42
+ it('injectMcpServer merges without touching other keys', () => {
43
+ const configPath = join(tmpDir, '.claude.json');
44
+ writeFileSync(configPath, JSON.stringify({
45
+ someOtherKey: 'keep-me',
46
+ mcpServers: { 'other-server': { command: 'npx', args: ['other'] } },
47
+ }));
48
+ const result = injectMcpServer(configPath, 'claude-code', SYSTEM_PROMPT);
49
+ expect(result.status).toBe('injected');
50
+ const written = JSON.parse(readFileSync(configPath, 'utf8'));
51
+ expect(written['someOtherKey']).toBe('keep-me');
52
+ const servers = written['mcpServers'];
53
+ expect(servers['other-server']).toBeDefined();
54
+ expect(servers['contextgit']).toBeDefined();
55
+ });
56
+ // 5. injectMcpServer returns already-present if contextgit key exists
57
+ it('injectMcpServer returns already-present if contextgit exists', () => {
58
+ const configPath = join(tmpDir, '.claude.json');
59
+ writeFileSync(configPath, JSON.stringify({
60
+ mcpServers: { contextgit: { command: 'npx', args: ['contextgit', 'mcp'] } },
61
+ }));
62
+ const result = injectMcpServer(configPath, 'claude-code', SYSTEM_PROMPT);
63
+ expect(result.status).toBe('already-present');
64
+ });
65
+ // 6. injectMcpServer returns error and does not write if existing file is invalid JSON
66
+ it('injectMcpServer returns error and does not write if file is invalid JSON', () => {
67
+ const configPath = join(tmpDir, '.claude.json');
68
+ writeFileSync(configPath, 'NOT JSON {{{');
69
+ const originalContent = readFileSync(configPath, 'utf8');
70
+ const result = injectMcpServer(configPath, 'claude-code', SYSTEM_PROMPT);
71
+ expect(result.status).toBe('error');
72
+ expect(result.reason).toContain('not valid JSON');
73
+ // File must not have been overwritten
74
+ expect(readFileSync(configPath, 'utf8')).toBe(originalContent);
75
+ });
76
+ // 7. injectMcpServer uses atomic write (temp file + rename)
77
+ it('injectMcpServer cleans up temp file after write', () => {
78
+ const configPath = join(tmpDir, '.claude.json');
79
+ injectMcpServer(configPath, 'claude-code', SYSTEM_PROMPT);
80
+ // Temp file should not exist after successful rename
81
+ expect(existsSync(configPath + '.contextgit-tmp')).toBe(false);
82
+ // Final file should exist
83
+ expect(existsSync(configPath)).toBe(true);
84
+ });
85
+ // 8. isAlreadyInjected returns true when contextgit is present under mcpServers
86
+ describe('isAlreadyInjected', () => {
87
+ it('returns true when contextgit is under mcpServers', () => {
88
+ expect(isAlreadyInjected({ mcpServers: { contextgit: {} } })).toBe(true);
89
+ });
90
+ it('returns false when contextgit is absent', () => {
91
+ expect(isAlreadyInjected({ mcpServers: { other: {} } })).toBe(false);
92
+ });
93
+ it('returns false when mcpServers is missing', () => {
94
+ expect(isAlreadyInjected({})).toBe(false);
95
+ });
96
+ });
97
+ //# sourceMappingURL=client-config.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"client-config.test.js","sourceRoot":"","sources":["../../src/lib/client-config.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "contextgit",
3
- "version": "0.0.4",
3
+ "version": "0.0.6",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "contextgit": "./bin/run.js"
@@ -19,9 +19,9 @@
19
19
  "typecheck": "tsc --noEmit"
20
20
  },
21
21
  "dependencies": {
22
- "@contextgit/core": "0.0.3",
23
- "@contextgit/store": "0.0.3",
24
- "@contextgit/api": "0.0.3",
22
+ "@contextgit/core": "0.0.5",
23
+ "@contextgit/store": "0.0.5",
24
+ "@contextgit/api": "0.0.5",
25
25
  "@oclif/core": "^3.27.0",
26
26
  "nanoid": "^5.0.0",
27
27
  "simple-git": "^3.27.0"