gitnexus-mcp 0.1.0

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 (53) hide show
  1. package/dist/bridge/daemon-client.d.ts +77 -0
  2. package/dist/bridge/daemon-client.d.ts.map +1 -0
  3. package/dist/bridge/daemon-client.js +135 -0
  4. package/dist/bridge/daemon-client.js.map +1 -0
  5. package/dist/bridge/protocol.d.ts +28 -0
  6. package/dist/bridge/protocol.d.ts.map +1 -0
  7. package/dist/bridge/protocol.js +18 -0
  8. package/dist/bridge/protocol.js.map +1 -0
  9. package/dist/bridge/websocket-server.d.ts +85 -0
  10. package/dist/bridge/websocket-server.d.ts.map +1 -0
  11. package/dist/bridge/websocket-server.js +180 -0
  12. package/dist/bridge/websocket-server.js.map +1 -0
  13. package/dist/cli.d.ts +9 -0
  14. package/dist/cli.d.ts.map +1 -0
  15. package/dist/cli.js +56 -0
  16. package/dist/cli.js.map +1 -0
  17. package/dist/commands/daemon.d.ts +37 -0
  18. package/dist/commands/daemon.d.ts.map +1 -0
  19. package/dist/commands/daemon.js +173 -0
  20. package/dist/commands/daemon.js.map +1 -0
  21. package/dist/commands/generate-guidance.d.ts +13 -0
  22. package/dist/commands/generate-guidance.d.ts.map +1 -0
  23. package/dist/commands/generate-guidance.js +140 -0
  24. package/dist/commands/generate-guidance.js.map +1 -0
  25. package/dist/commands/serve.d.ts +13 -0
  26. package/dist/commands/serve.d.ts.map +1 -0
  27. package/dist/commands/serve.js +23 -0
  28. package/dist/commands/serve.js.map +1 -0
  29. package/dist/commands/setup.d.ts +8 -0
  30. package/dist/commands/setup.d.ts.map +1 -0
  31. package/dist/commands/setup.js +48 -0
  32. package/dist/commands/setup.js.map +1 -0
  33. package/dist/config/detect-ides.d.ts +12 -0
  34. package/dist/config/detect-ides.d.ts.map +1 -0
  35. package/dist/config/detect-ides.js +81 -0
  36. package/dist/config/detect-ides.js.map +1 -0
  37. package/dist/config/inject-config.d.ts +9 -0
  38. package/dist/config/inject-config.d.ts.map +1 -0
  39. package/dist/config/inject-config.js +65 -0
  40. package/dist/config/inject-config.js.map +1 -0
  41. package/dist/config/paths.d.ts +16 -0
  42. package/dist/config/paths.d.ts.map +1 -0
  43. package/dist/config/paths.js +32 -0
  44. package/dist/config/paths.js.map +1 -0
  45. package/dist/mcp/server.d.ts +21 -0
  46. package/dist/mcp/server.d.ts.map +1 -0
  47. package/dist/mcp/server.js +183 -0
  48. package/dist/mcp/server.js.map +1 -0
  49. package/dist/mcp/tools.d.ts +24 -0
  50. package/dist/mcp/tools.d.ts.map +1 -0
  51. package/dist/mcp/tools.js +166 -0
  52. package/dist/mcp/tools.js.map +1 -0
  53. package/package.json +45 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.d.ts","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAeH;;GAEG;AACH,UAAU,eAAe;IACvB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE;QACL,SAAS,EAAE,MAAM,CAAC;QAClB,aAAa,EAAE,MAAM,CAAC;QACtB,UAAU,EAAE,MAAM,CAAC;QACnB,cAAc,EAAE,MAAM,CAAC;QACvB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC;IACF,QAAQ,EAAE,KAAK,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;QACb,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,MAAM,CAAC;QACjB,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;IACH,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;CACd;AAKD,wBAAgB,kBAAkB,IAAI,eAAe,GAAG,IAAI,CAE3D;AAED,wBAAsB,aAAa,CAAC,OAAO,EAAE,aAAa,iBAsLzD"}
@@ -0,0 +1,173 @@
1
+ /**
2
+ * Daemon Command
3
+ *
4
+ * Runs a persistent daemon that acts as the central hub for:
5
+ * - Browser connections (GitNexus web app)
6
+ * - MCP server connections (from AI tools like Cursor, Antigravity)
7
+ *
8
+ * This allows multiple AI tools to share the same browser bridge.
9
+ * Also stores codebase context sent by the browser for MCP resource exposure.
10
+ */
11
+ import { WebSocketServer, WebSocket } from 'ws';
12
+ // Module-level state for context (so MCP servers can access it)
13
+ let currentContext = null;
14
+ export function getCodebaseContext() {
15
+ return currentContext;
16
+ }
17
+ export async function daemonCommand(options) {
18
+ const port = parseInt(options.port, 10);
19
+ let browserClient = null;
20
+ const mcpClients = new Set();
21
+ const pendingRequests = new Map(); // request ID → which MCP client sent it
22
+ const agentSessions = new Map();
23
+ const agentInstanceCounters = new Map(); // agentType → next instance number
24
+ const wss = new WebSocketServer({ port });
25
+ console.log(`🔌 GitNexus MCP Daemon running on port ${port}`);
26
+ console.log(' Waiting for connections...\n');
27
+ wss.on('connection', (ws, req) => {
28
+ // Determine client type from URL path
29
+ const url = new URL(req.url || '/', `http://localhost:${port}`);
30
+ const clientType = url.pathname === '/mcp' ? 'mcp' : 'browser';
31
+ if (clientType === 'browser') {
32
+ // Browser connection
33
+ if (browserClient) {
34
+ browserClient.close();
35
+ }
36
+ browserClient = ws;
37
+ console.log('✅ Browser connected');
38
+ ws.on('message', (data) => {
39
+ try {
40
+ const msg = JSON.parse(data.toString());
41
+ // Handle context update from browser
42
+ if (msg.type === 'context' && msg.params) {
43
+ currentContext = msg.params;
44
+ console.log(`📊 Context received: ${currentContext.projectName} (${currentContext.stats.fileCount} files)`);
45
+ // Broadcast context update to all MCP clients
46
+ const contextNotification = JSON.stringify({
47
+ type: 'context_update',
48
+ context: currentContext,
49
+ });
50
+ mcpClients.forEach(client => {
51
+ if (client.readyState === WebSocket.OPEN) {
52
+ client.send(contextNotification);
53
+ }
54
+ });
55
+ return;
56
+ }
57
+ // Response from browser - route back to the MCP client that sent the request
58
+ if (msg.id && pendingRequests.has(msg.id)) {
59
+ const mcpClient = pendingRequests.get(msg.id);
60
+ pendingRequests.delete(msg.id);
61
+ if (mcpClient.readyState === WebSocket.OPEN) {
62
+ mcpClient.send(JSON.stringify(msg));
63
+ }
64
+ }
65
+ }
66
+ catch (error) {
67
+ console.error('Failed to parse browser message:', error);
68
+ }
69
+ });
70
+ ws.on('close', () => {
71
+ if (browserClient === ws) {
72
+ browserClient = null;
73
+ currentContext = null; // Clear context when browser disconnects
74
+ console.log('❌ Browser disconnected');
75
+ }
76
+ });
77
+ }
78
+ else {
79
+ // MCP server connection
80
+ mcpClients.add(ws);
81
+ console.log(`✅ MCP client connected (total: ${mcpClients.size})`);
82
+ // Send current context to new MCP client if available
83
+ if (currentContext) {
84
+ ws.send(JSON.stringify({
85
+ type: 'context_update',
86
+ context: currentContext,
87
+ }));
88
+ }
89
+ ws.on('message', (data) => {
90
+ try {
91
+ const msg = JSON.parse(data.toString());
92
+ // Handle context request
93
+ if (msg.method === 'getContext') {
94
+ ws.send(JSON.stringify({
95
+ id: msg.id,
96
+ result: currentContext,
97
+ }));
98
+ return;
99
+ }
100
+ // Tool call request from MCP server - forward to browser
101
+ if (msg.method && msg.id) {
102
+ // Handle session tracking
103
+ let session = agentSessions.get(ws);
104
+ const rawAgentName = msg.agentName || 'Unknown';
105
+ if (!session) {
106
+ // First time seeing this connection - assign instance ID
107
+ const currentCount = agentInstanceCounters.get(rawAgentName) || 0;
108
+ const newCount = currentCount + 1;
109
+ agentInstanceCounters.set(rawAgentName, newCount);
110
+ session = {
111
+ agentType: rawAgentName,
112
+ instanceId: newCount,
113
+ sessionId: `sess_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
114
+ };
115
+ agentSessions.set(ws, session);
116
+ console.log(`🆕 Registered ${rawAgentName} #${newCount}`);
117
+ // Notify browser about new agent (optional, mainly for UI updates if needed later)
118
+ // browserClient?.send(JSON.stringify({ type: 'agent_info', ... }));
119
+ }
120
+ // Construct display name (e.g., "Claude #1")
121
+ // If it's the first instance, maybe just keep "Claude" or do we always want numbers?
122
+ // User asked for tracking multiple, so "Claude #1" is clearer even for the first if we expect multiples.
123
+ // Let's use format "Name #N"
124
+ const uniqueAgentName = `${session.agentType} #${session.instanceId}`;
125
+ if (browserClient && browserClient.readyState === WebSocket.OPEN) {
126
+ pendingRequests.set(msg.id, ws);
127
+ // Forward with unique name
128
+ const forwardMsg = { ...msg, agentName: uniqueAgentName };
129
+ browserClient.send(JSON.stringify(forwardMsg));
130
+ }
131
+ else {
132
+ // No browser connected
133
+ ws.send(JSON.stringify({
134
+ id: msg.id,
135
+ error: { message: 'GitNexus browser not connected. Open GitNexus and enable MCP toggle.' }
136
+ }));
137
+ }
138
+ }
139
+ }
140
+ catch (error) {
141
+ console.error('Failed to parse MCP message:', error);
142
+ }
143
+ });
144
+ ws.on('close', () => {
145
+ const session = agentSessions.get(ws);
146
+ if (session) {
147
+ console.log(`❌ ${session.agentType} #${session.instanceId} disconnected`);
148
+ agentSessions.delete(ws);
149
+ }
150
+ mcpClients.delete(ws);
151
+ console.log(`Remaining clients: ${mcpClients.size}`);
152
+ });
153
+ }
154
+ ws.on('error', (error) => {
155
+ console.error('WebSocket error:', error.message);
156
+ });
157
+ });
158
+ wss.on('error', (error) => {
159
+ if (error.code === 'EADDRINUSE') {
160
+ console.error(`❌ Port ${port} is already in use.`);
161
+ console.error(' A daemon may already be running. Check with: lsof -i :54319');
162
+ process.exit(1);
163
+ }
164
+ console.error('Server error:', error);
165
+ });
166
+ // Keep the daemon running
167
+ process.on('SIGINT', () => {
168
+ console.log('\n👋 Shutting down daemon...');
169
+ wss.close();
170
+ process.exit(0);
171
+ });
172
+ }
173
+ //# sourceMappingURL=daemon.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon.js","sourceRoot":"","sources":["../../src/commands/daemon.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Generate Guidance Command
3
+ *
4
+ * Creates AI assistant guidance files for a project:
5
+ * - .cursor/rules/gitnexus.mdc - Cursor skills file
6
+ * - AGENTS.md - Generic tool usage patterns for Claude Code etc.
7
+ */
8
+ interface GenerateOptions {
9
+ output: string;
10
+ }
11
+ export declare function generateGuidanceCommand(options: GenerateOptions): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=generate-guidance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-guidance.d.ts","sourceRoot":"","sources":["../../src/commands/generate-guidance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,UAAU,eAAe;IACvB,MAAM,EAAE,MAAM,CAAC;CAChB;AA0GD,wBAAsB,uBAAuB,CAAC,OAAO,EAAE,eAAe,GAAG,OAAO,CAAC,IAAI,CAAC,CA8BrF"}
@@ -0,0 +1,140 @@
1
+ /**
2
+ * Generate Guidance Command
3
+ *
4
+ * Creates AI assistant guidance files for a project:
5
+ * - .cursor/rules/gitnexus.mdc - Cursor skills file
6
+ * - AGENTS.md - Generic tool usage patterns for Claude Code etc.
7
+ */
8
+ import { writeFile, mkdir } from 'fs/promises';
9
+ import { existsSync } from 'fs';
10
+ import { join } from 'path';
11
+ import chalk from 'chalk';
12
+ // Cursor uses MDC format (Markdown with frontmatter)
13
+ const CURSOR_RULES_CONTENT = `---
14
+ description: GitNexus MCP code intelligence tools
15
+ globs:
16
+ alwaysApply: true
17
+ ---
18
+
19
+ # GitNexus Code Intelligence
20
+
21
+ This project uses GitNexus MCP for code understanding. You have access to these tools:
22
+
23
+ ## Available MCP Tools
24
+
25
+ ### search
26
+ Semantic search across code. Returns functions, classes, files matching meaning.
27
+ - Use for: Finding code by description, not exact text
28
+ - Example: "authentication logic", "database connection handling"
29
+
30
+ ### cypher
31
+ Direct KuzuDB graph queries for relationship traversal.
32
+ - Pattern: \`MATCH (f:Function)-[:CodeRelation {type:'CALLS'}]->(g:Function) RETURN f.name, g.name\`
33
+ - Node types: File, Folder, Function, Class, Interface, Method, CodeElement
34
+ - Relation types: CONTAINS, DEFINES, IMPORTS, CALLS, EXTENDS, IMPLEMENTS
35
+
36
+ ### blastRadius
37
+ Find all code affected by changing a node. Returns N-hop connections.
38
+ - Use for: Before refactoring, understanding impact of changes
39
+
40
+ ### highlight
41
+ Highlight nodes in the graph visualization.
42
+
43
+ ### context
44
+ Get project overview: stats, hotspots, folder tree.
45
+ - Use for: Understanding project structure
46
+
47
+ ### grep
48
+ Regex pattern search across file contents.
49
+ - Use for: Finding exact patterns, TODOs
50
+
51
+ ### read
52
+ Read file content by path. Supports line ranges.
53
+
54
+ ## Best Practices
55
+
56
+ 1. **Start with context** - Understand project structure first
57
+ 2. **Use search for discovery** - Find by meaning, not keywords
58
+ 3. **Use cypher for relationships** - Call chains, imports, inheritance
59
+ 4. **Check blast radius before refactoring** - Understand impact
60
+
61
+ ## Cypher Examples
62
+
63
+ \`\`\`cypher
64
+ # Find functions that call a specific function
65
+ MATCH (caller:Function)-[:CodeRelation {type:'CALLS'}]->(target:Function {name: 'authenticate'})
66
+ RETURN caller.name, caller.filePath
67
+
68
+ # Find class inheritance
69
+ MATCH (child:Class)-[:CodeRelation {type:'EXTENDS'}]->(parent:Class)
70
+ RETURN child.name, parent.name
71
+ \`\`\`
72
+ `;
73
+ const AGENTS_MD_CONTENT = `# GitNexus Agent Guidelines
74
+
75
+ This document describes how to use GitNexus MCP tools for code understanding.
76
+
77
+ ## Quick Reference
78
+
79
+ | Tool | Use When | Example |
80
+ |------|----------|---------|
81
+ | \`search\` | Finding code by meaning | "user authentication flow" |
82
+ | \`cypher\` | Traversing relationships | Finding what calls a function |
83
+ | \`blastRadius\` | Before refactoring | What depends on this class? |
84
+ | \`context\` | Understanding project | Get overview, hotspots |
85
+ | \`grep\` | Exact pattern match | Find all TODO comments |
86
+ | \`read\` | Reading file content | View actual code |
87
+ | \`highlight\` | Visual feedback | Show user what you found |
88
+
89
+ ## Node Types
90
+ File, Folder, Function, Class, Interface, Method, CodeElement
91
+
92
+ ## Relation Types
93
+ CONTAINS, DEFINES, IMPORTS, CALLS, EXTENDS, IMPLEMENTS
94
+
95
+ ## Cypher Query Examples
96
+
97
+ \`\`\`cypher
98
+ -- Find functions called by a specific function
99
+ MATCH (f:Function {name: 'handleRequest'})-[:CodeRelation {type:'CALLS'}]->(called)
100
+ RETURN called.name, called.filePath
101
+
102
+ -- Find class hierarchy
103
+ MATCH (c:Class)-[:CodeRelation {type:'EXTENDS'}*1..3]->(parent)
104
+ RETURN c.name, collect(parent.name) as ancestors
105
+ \`\`\`
106
+
107
+ ## Workflow
108
+
109
+ 1. Run \`context\` to understand project structure
110
+ 2. Use \`search\` to find relevant code
111
+ 3. Use \`blastRadius\` before making changes
112
+ 4. Use \`read\` to examine actual code
113
+ `;
114
+ export async function generateGuidanceCommand(options) {
115
+ const outputDir = options.output || '.';
116
+ console.log(chalk.cyan('\n🔧 Generating AI agent guidance files...\n'));
117
+ try {
118
+ // Create .cursor/rules directory
119
+ const cursorRulesDir = join(outputDir, '.cursor', 'rules');
120
+ if (!existsSync(cursorRulesDir)) {
121
+ await mkdir(cursorRulesDir, { recursive: true });
122
+ }
123
+ // Write .cursor/rules/gitnexus.mdc
124
+ const cursorRulePath = join(cursorRulesDir, 'gitnexus.mdc');
125
+ await writeFile(cursorRulePath, CURSOR_RULES_CONTENT, 'utf-8');
126
+ console.log(chalk.green('✓'), 'Created', chalk.bold('.cursor/rules/gitnexus.mdc'));
127
+ // Write AGENTS.md
128
+ const agentsPath = join(outputDir, 'AGENTS.md');
129
+ await writeFile(agentsPath, AGENTS_MD_CONTENT, 'utf-8');
130
+ console.log(chalk.green('✓'), 'Created', chalk.bold('AGENTS.md'));
131
+ console.log(chalk.green('\n✅ Guidance files generated successfully!'));
132
+ console.log(chalk.dim('\nThese files help AI assistants understand how to use GitNexus MCP tools.'));
133
+ console.log(chalk.dim('Commit them to your repo so all team members benefit.\n'));
134
+ }
135
+ catch (error) {
136
+ console.error(chalk.red('\n❌ Error generating guidance files:'), error);
137
+ process.exit(1);
138
+ }
139
+ }
140
+ //# sourceMappingURL=generate-guidance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"generate-guidance.js","sourceRoot":"","sources":["../../src/commands/generate-guidance.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,KAAK,MAAM,OAAO,CAAC;AAM1B,qDAAqD;AACrD,MAAM,oBAAoB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2D5B,CAAC;AAEF,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAwCzB,CAAC;AAEF,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,OAAwB;IACpE,MAAM,SAAS,GAAG,OAAO,CAAC,MAAM,IAAI,GAAG,CAAC;IAExC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,8CAA8C,CAAC,CAAC,CAAC;IAExE,IAAI,CAAC;QACH,iCAAiC;QACjC,MAAM,cAAc,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,EAAE,OAAO,CAAC,CAAC;QAC3D,IAAI,CAAC,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAChC,MAAM,KAAK,CAAC,cAAc,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QACnD,CAAC;QAED,mCAAmC;QACnC,MAAM,cAAc,GAAG,IAAI,CAAC,cAAc,EAAE,cAAc,CAAC,CAAC;QAC5D,MAAM,SAAS,CAAC,cAAc,EAAE,oBAAoB,EAAE,OAAO,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,4BAA4B,CAAC,CAAC,CAAC;QAEnF,kBAAkB;QAClB,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,EAAE,WAAW,CAAC,CAAC;QAChD,MAAM,SAAS,CAAC,UAAU,EAAE,iBAAiB,EAAE,OAAO,CAAC,CAAC;QACxD,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC;QAElE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,4CAA4C,CAAC,CAAC,CAAC;QACvE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,4EAA4E,CAAC,CAAC,CAAC;QACrG,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,yDAAyD,CAAC,CAAC,CAAC;IAEpF,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,sCAAsC,CAAC,EAAE,KAAK,CAAC,CAAC;QACxE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Serve Command
3
+ *
4
+ * Starts the MCP server that bridges external AI agents to GitNexus.
5
+ * - Listens on stdio for MCP protocol (from AI tools)
6
+ * - Hosts a local WebSocket bridge for the GitNexus browser app
7
+ */
8
+ interface ServeOptions {
9
+ port: string;
10
+ }
11
+ export declare function serveCommand(options: ServeOptions): Promise<void>;
12
+ export {};
13
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAKH,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,wBAAsB,YAAY,CAAC,OAAO,EAAE,YAAY,iBAevD"}
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Serve Command
3
+ *
4
+ * Starts the MCP server that bridges external AI agents to GitNexus.
5
+ * - Listens on stdio for MCP protocol (from AI tools)
6
+ * - Hosts a local WebSocket bridge for the GitNexus browser app
7
+ */
8
+ import { startMCPServer } from '../mcp/server.js';
9
+ import { WebSocketBridge } from '../bridge/websocket-server.js';
10
+ export async function serveCommand(options) {
11
+ const port = parseInt(options.port, 10);
12
+ // Start local WebSocket bridge (browser connects to ws://localhost:<port>)
13
+ const client = new WebSocketBridge(port);
14
+ const started = await client.start();
15
+ if (!started) {
16
+ console.error(`Failed to start GitNexus browser bridge on port ${port}.`);
17
+ console.error('Another process is already using this port.');
18
+ process.exit(1);
19
+ }
20
+ // Start MCP server on stdio (AI tools connect here)
21
+ await startMCPServer(client);
22
+ }
23
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.js","sourceRoot":"","sources":["../../src/commands/serve.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,cAAc,EAAE,MAAM,kBAAkB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,+BAA+B,CAAC;AAMhE,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,OAAqB;IACtD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAExC,2EAA2E;IAC3E,MAAM,MAAM,GAAG,IAAI,eAAe,CAAC,IAAI,CAAC,CAAC;IACzC,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;IAErC,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,OAAO,CAAC,KAAK,CAAC,mDAAmD,IAAI,GAAG,CAAC,CAAC;QAC1E,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;QAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,oDAAoD;IACpD,MAAM,cAAc,CAAC,MAAM,CAAC,CAAC;AAC/B,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Setup Command
3
+ *
4
+ * Detects installed AI tools (Cursor, Claude Code, Windsurf) and
5
+ * configures their MCP settings to use GitNexus.
6
+ */
7
+ export declare function setupCommand(): Promise<void>;
8
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAQH,wBAAsB,YAAY,kBAyCjC"}
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Setup Command
3
+ *
4
+ * Detects installed AI tools (Cursor, Claude Code, Windsurf) and
5
+ * configures their MCP settings to use GitNexus.
6
+ */
7
+ import chalk from 'chalk';
8
+ import ora from 'ora';
9
+ import { detectIDEs } from '../config/detect-ides.js';
10
+ import { injectMCPConfig } from '../config/inject-config.js';
11
+ import { getBridgePath } from '../config/paths.js';
12
+ export async function setupCommand() {
13
+ console.log(chalk.blue('\n🔧 GitNexus MCP Setup\n'));
14
+ // Step 1: Get bridge path (this CLI itself is the bridge)
15
+ const spinner = ora('Locating bridge...').start();
16
+ const bridgePath = getBridgePath();
17
+ spinner.succeed(`Bridge located at ${chalk.dim(bridgePath)}`);
18
+ // Step 2: Detect AI tools
19
+ spinner.start('Detecting AI tools...');
20
+ const ides = await detectIDEs();
21
+ if (ides.length === 0) {
22
+ spinner.warn('No supported AI tools detected');
23
+ console.log(chalk.yellow('\nSupported tools: Cursor, Claude Code, Windsurf, VS Code'));
24
+ console.log('Install one of these tools to use GitNexus MCP.\n');
25
+ return;
26
+ }
27
+ spinner.succeed(`Found: ${ides.map(i => chalk.cyan(i.name)).join(', ')}`);
28
+ // Step 3: Inject MCP config into each IDE
29
+ for (const ide of ides) {
30
+ spinner.start(`Configuring ${ide.name}...`);
31
+ try {
32
+ await injectMCPConfig(ide, bridgePath);
33
+ spinner.succeed(`Configured ${chalk.cyan(ide.name)}`);
34
+ }
35
+ catch (error) {
36
+ spinner.fail(`Failed to configure ${ide.name}: ${error}`);
37
+ }
38
+ }
39
+ // Success message
40
+ console.log(chalk.green('\n✅ Setup complete!\n'));
41
+ console.log('Next steps:');
42
+ console.log(' 1. Open GitNexus in your browser');
43
+ console.log(' 2. Load a codebase');
44
+ console.log(' 3. Click the MCP toggle to connect');
45
+ console.log(' 4. Your AI tools can now use GitNexus!\n');
46
+ console.log(chalk.dim('Available tools: search, cypher, blastRadius, highlight\n'));
47
+ }
48
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.js","sourceRoot":"","sources":["../../src/commands/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,MAAM,OAAO,CAAC;AAC1B,OAAO,GAAG,MAAM,KAAK,CAAC;AACtB,OAAO,EAAE,UAAU,EAAY,MAAM,0BAA0B,CAAC;AAChE,OAAO,EAAE,eAAe,EAAE,MAAM,4BAA4B,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAEnD,MAAM,CAAC,KAAK,UAAU,YAAY;IAChC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,2BAA2B,CAAC,CAAC,CAAC;IAErD,0DAA0D;IAC1D,MAAM,OAAO,GAAG,GAAG,CAAC,oBAAoB,CAAC,CAAC,KAAK,EAAE,CAAC;IAClD,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IACnC,OAAO,CAAC,OAAO,CAAC,qBAAqB,KAAK,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IAE9D,0BAA0B;IAC1B,OAAO,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,MAAM,UAAU,EAAE,CAAC;IAEhC,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,IAAI,CAAC,gCAAgC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,MAAM,CAAC,2DAA2D,CAAC,CAAC,CAAC;QACvF,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACjE,OAAO;IACT,CAAC;IAED,OAAO,CAAC,OAAO,CAAC,UAAU,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAE1E,0CAA0C;IAC1C,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,OAAO,CAAC,KAAK,CAAC,eAAe,GAAG,CAAC,IAAI,KAAK,CAAC,CAAC;QAC5C,IAAI,CAAC;YACH,MAAM,eAAe,CAAC,GAAG,EAAE,UAAU,CAAC,CAAC;YACvC,OAAO,CAAC,OAAO,CAAC,cAAc,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QACxD,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,IAAI,CAAC,uBAAuB,GAAG,CAAC,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;IACH,CAAC;IAED,kBAAkB;IAClB,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,OAAO,CAAC,GAAG,CAAC,oCAAoC,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,CAAC;IACpC,OAAO,CAAC,GAAG,CAAC,sCAAsC,CAAC,CAAC;IACpD,OAAO,CAAC,GAAG,CAAC,4CAA4C,CAAC,CAAC;IAE1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,2DAA2D,CAAC,CAAC,CAAC;AACtF,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * IDE Detection
3
+ *
4
+ * Detects installed AI coding tools by checking for their config directories.
5
+ * Supports Windows, macOS, and Linux paths.
6
+ */
7
+ export interface IDE {
8
+ name: string;
9
+ configPath: string;
10
+ }
11
+ export declare function detectIDEs(): Promise<IDE[]>;
12
+ //# sourceMappingURL=detect-ides.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-ides.d.ts","sourceRoot":"","sources":["../../src/config/detect-ides.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAMH,MAAM,WAAW,GAAG;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AA+DD,wBAAsB,UAAU,IAAI,OAAO,CAAC,GAAG,EAAE,CAAC,CAyBjD"}
@@ -0,0 +1,81 @@
1
+ /**
2
+ * IDE Detection
3
+ *
4
+ * Detects installed AI coding tools by checking for their config directories.
5
+ * Supports Windows, macOS, and Linux paths.
6
+ */
7
+ import { existsSync } from 'fs';
8
+ import { homedir, platform } from 'os';
9
+ import { join } from 'path';
10
+ const IDE_CHECKS = [
11
+ {
12
+ name: 'Cursor',
13
+ paths: {
14
+ win32: ['AppData/Roaming/Cursor/User/globalStorage/mcp.json', '.cursor/mcp.json'],
15
+ darwin: ['.cursor/mcp.json', 'Library/Application Support/Cursor/User/globalStorage/mcp.json'],
16
+ linux: ['.cursor/mcp.json', '.config/Cursor/User/globalStorage/mcp.json'],
17
+ },
18
+ },
19
+ {
20
+ name: 'Claude Code',
21
+ paths: {
22
+ win32: ['.claude/mcp.json', 'AppData/Roaming/Claude/mcp.json'],
23
+ darwin: ['.claude/mcp.json', 'Library/Application Support/Claude/mcp.json'],
24
+ linux: ['.claude/mcp.json', '.config/Claude/mcp.json'],
25
+ },
26
+ },
27
+ {
28
+ name: 'Windsurf',
29
+ paths: {
30
+ win32: ['.windsurf/mcp.json', '.codeium/windsurf/mcp.json'],
31
+ darwin: ['.windsurf/mcp.json', '.codeium/windsurf/mcp.json'],
32
+ linux: ['.windsurf/mcp.json', '.codeium/windsurf/mcp.json'],
33
+ },
34
+ },
35
+ {
36
+ name: 'VS Code',
37
+ paths: {
38
+ win32: ['AppData/Roaming/Code/User/globalStorage/mcp.json'],
39
+ darwin: ['Library/Application Support/Code/User/globalStorage/mcp.json'],
40
+ linux: ['.config/Code/User/globalStorage/mcp.json'],
41
+ },
42
+ },
43
+ {
44
+ name: 'Antigravity',
45
+ paths: {
46
+ win32: ['.gemini/antigravity/mcp_config.json'],
47
+ darwin: ['.gemini/antigravity/mcp_config.json'],
48
+ linux: ['.gemini/antigravity/mcp_config.json'],
49
+ },
50
+ },
51
+ {
52
+ name: 'OpenCode',
53
+ paths: {
54
+ win32: ['.config/opencode/opencode.json', 'opencode.json'],
55
+ darwin: ['.config/opencode/opencode.json', 'opencode.json'],
56
+ linux: ['.config/opencode/opencode.json', 'opencode.json'],
57
+ },
58
+ },
59
+ ];
60
+ export async function detectIDEs() {
61
+ const home = homedir();
62
+ const os = platform();
63
+ const ides = [];
64
+ for (const check of IDE_CHECKS) {
65
+ const paths = check.paths[os] || check.paths.linux;
66
+ for (const relPath of paths) {
67
+ const configPath = join(home, relPath);
68
+ // Check if the parent directory exists (IDE is installed)
69
+ const dirPath = configPath.replace(/[/\\]mcp\.json$/, '');
70
+ const parentDir = dirPath.split(/[/\\]/).slice(0, -1).join('/');
71
+ // Look for IDE installation markers
72
+ const ideDirExists = existsSync(dirPath) || existsSync(parentDir);
73
+ if (ideDirExists) {
74
+ ides.push({ name: check.name, configPath });
75
+ break; // Found this IDE, move to next
76
+ }
77
+ }
78
+ }
79
+ return ides;
80
+ }
81
+ //# sourceMappingURL=detect-ides.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"detect-ides.js","sourceRoot":"","sources":["../../src/config/detect-ides.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * MCP Config Injection
3
+ *
4
+ * Adds GitNexus MCP server to an IDE's configuration.
5
+ * Handles different config formats for different tools.
6
+ */
7
+ import { type IDE } from './detect-ides.js';
8
+ export declare function injectMCPConfig(ide: IDE, bridgePath: string): Promise<void>;
9
+ //# sourceMappingURL=inject-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inject-config.d.ts","sourceRoot":"","sources":["../../src/config/inject-config.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,EAAE,KAAK,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAsB5C,wBAAsB,eAAe,CAAC,GAAG,EAAE,GAAG,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAqCjF"}
@@ -0,0 +1,65 @@
1
+ /**
2
+ * MCP Config Injection
3
+ *
4
+ * Adds GitNexus MCP server to an IDE's configuration.
5
+ * Handles different config formats for different tools.
6
+ */
7
+ import { readFileSync, writeFileSync, mkdirSync, existsSync } from 'fs';
8
+ import { dirname } from 'path';
9
+ export async function injectMCPConfig(ide, bridgePath) {
10
+ // Create directory structure if needed
11
+ if (!existsSync(ide.configPath)) {
12
+ const dir = dirname(ide.configPath);
13
+ mkdirSync(dir, { recursive: true });
14
+ }
15
+ // Handle OpenCode's different format
16
+ if (ide.name === 'OpenCode') {
17
+ await injectOpenCodeConfig(ide.configPath, bridgePath);
18
+ return;
19
+ }
20
+ // Standard MCP format (Cursor, Claude Code, Windsurf, VS Code, Antigravity)
21
+ let config = { mcpServers: {} };
22
+ // Read existing config if present
23
+ if (existsSync(ide.configPath)) {
24
+ try {
25
+ const content = readFileSync(ide.configPath, 'utf-8');
26
+ config = JSON.parse(content);
27
+ }
28
+ catch {
29
+ // Ignore parse errors, use empty config
30
+ }
31
+ }
32
+ // Ensure mcpServers object exists
33
+ config.mcpServers = config.mcpServers || {};
34
+ // Add GitNexus MCP server configuration
35
+ config.mcpServers.gitnexus = {
36
+ command: bridgePath,
37
+ args: ['serve'],
38
+ };
39
+ // Write updated config
40
+ writeFileSync(ide.configPath, JSON.stringify(config, null, 2));
41
+ }
42
+ async function injectOpenCodeConfig(configPath, bridgePath) {
43
+ let config = {};
44
+ // Read existing config if present
45
+ if (existsSync(configPath)) {
46
+ try {
47
+ const content = readFileSync(configPath, 'utf-8');
48
+ config = JSON.parse(content);
49
+ }
50
+ catch {
51
+ // Ignore parse errors
52
+ }
53
+ }
54
+ // Ensure mcp object exists
55
+ config.mcp = config.mcp || {};
56
+ // Add GitNexus MCP server (OpenCode format)
57
+ config.mcp.gitnexus = {
58
+ type: 'local',
59
+ command: bridgePath,
60
+ args: ['serve'],
61
+ };
62
+ // Write updated config
63
+ writeFileSync(configPath, JSON.stringify(config, null, 2));
64
+ }
65
+ //# sourceMappingURL=inject-config.js.map