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.
- package/dist/bridge/daemon-client.d.ts +77 -0
- package/dist/bridge/daemon-client.d.ts.map +1 -0
- package/dist/bridge/daemon-client.js +135 -0
- package/dist/bridge/daemon-client.js.map +1 -0
- package/dist/bridge/protocol.d.ts +28 -0
- package/dist/bridge/protocol.d.ts.map +1 -0
- package/dist/bridge/protocol.js +18 -0
- package/dist/bridge/protocol.js.map +1 -0
- package/dist/bridge/websocket-server.d.ts +85 -0
- package/dist/bridge/websocket-server.d.ts.map +1 -0
- package/dist/bridge/websocket-server.js +180 -0
- package/dist/bridge/websocket-server.js.map +1 -0
- package/dist/cli.d.ts +9 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/daemon.d.ts +37 -0
- package/dist/commands/daemon.d.ts.map +1 -0
- package/dist/commands/daemon.js +173 -0
- package/dist/commands/daemon.js.map +1 -0
- package/dist/commands/generate-guidance.d.ts +13 -0
- package/dist/commands/generate-guidance.d.ts.map +1 -0
- package/dist/commands/generate-guidance.js +140 -0
- package/dist/commands/generate-guidance.js.map +1 -0
- package/dist/commands/serve.d.ts +13 -0
- package/dist/commands/serve.d.ts.map +1 -0
- package/dist/commands/serve.js +23 -0
- package/dist/commands/serve.js.map +1 -0
- package/dist/commands/setup.d.ts +8 -0
- package/dist/commands/setup.d.ts.map +1 -0
- package/dist/commands/setup.js +48 -0
- package/dist/commands/setup.js.map +1 -0
- package/dist/config/detect-ides.d.ts +12 -0
- package/dist/config/detect-ides.d.ts.map +1 -0
- package/dist/config/detect-ides.js +81 -0
- package/dist/config/detect-ides.js.map +1 -0
- package/dist/config/inject-config.d.ts +9 -0
- package/dist/config/inject-config.d.ts.map +1 -0
- package/dist/config/inject-config.js +65 -0
- package/dist/config/inject-config.js.map +1 -0
- package/dist/config/paths.d.ts +16 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +32 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/mcp/server.d.ts +21 -0
- package/dist/mcp/server.d.ts.map +1 -0
- package/dist/mcp/server.js +183 -0
- package/dist/mcp/server.js.map +1 -0
- package/dist/mcp/tools.d.ts +24 -0
- package/dist/mcp/tools.d.ts.map +1 -0
- package/dist/mcp/tools.js +166 -0
- package/dist/mcp/tools.js.map +1 -0
- 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":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AAsChD,gEAAgE;AAChE,IAAI,cAAc,GAA2B,IAAI,CAAC;AAElD,MAAM,UAAU,kBAAkB;IAChC,OAAO,cAAc,CAAC;AACxB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,OAAsB;IACxD,MAAM,IAAI,GAAG,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;IAExC,IAAI,aAAa,GAAqB,IAAI,CAAC;IAC3C,MAAM,UAAU,GAAmB,IAAI,GAAG,EAAE,CAAC;IAC7C,MAAM,eAAe,GAA2B,IAAI,GAAG,EAAE,CAAC,CAAC,wCAAwC;IAQnG,MAAM,aAAa,GAAiC,IAAI,GAAG,EAAE,CAAC;IAC9D,MAAM,qBAAqB,GAAwB,IAAI,GAAG,EAAE,CAAC,CAAC,mCAAmC;IAEjG,MAAM,GAAG,GAAG,IAAI,eAAe,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,OAAO,CAAC,GAAG,CAAC,0CAA0C,IAAI,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAE/C,GAAG,CAAC,EAAE,CAAC,YAAY,EAAE,CAAC,EAAE,EAAE,GAAG,EAAE,EAAE;QAC/B,sCAAsC;QACtC,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAC;QAChE,MAAM,UAAU,GAAG,GAAG,CAAC,QAAQ,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC;QAE/D,IAAI,UAAU,KAAK,SAAS,EAAE,CAAC;YAC7B,qBAAqB;YACrB,IAAI,aAAa,EAAE,CAAC;gBAClB,aAAa,CAAC,KAAK,EAAE,CAAC;YACxB,CAAC;YACD,aAAa,GAAG,EAAE,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,qBAAqB,CAAC,CAAC;YAEnC,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAEvD,qCAAqC;oBACrC,IAAI,GAAG,CAAC,IAAI,KAAK,SAAS,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC;wBACzC,cAAc,GAAG,GAAG,CAAC,MAAyB,CAAC;wBAC/C,OAAO,CAAC,GAAG,CAAC,wBAAwB,cAAc,CAAC,WAAW,KAAK,cAAc,CAAC,KAAK,CAAC,SAAS,SAAS,CAAC,CAAC;wBAE5G,8CAA8C;wBAC9C,MAAM,mBAAmB,GAAG,IAAI,CAAC,SAAS,CAAC;4BACzC,IAAI,EAAE,gBAAgB;4BACtB,OAAO,EAAE,cAAc;yBACxB,CAAC,CAAC;wBACH,UAAU,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE;4BAC1B,IAAI,MAAM,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;gCACzC,MAAM,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;4BACnC,CAAC;wBACH,CAAC,CAAC,CAAC;wBACH,OAAO;oBACT,CAAC;oBAED,6EAA6E;oBAC7E,IAAI,GAAG,CAAC,EAAE,IAAI,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC,EAAE,CAAC;wBAC1C,MAAM,SAAS,GAAG,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAE,CAAC;wBAC/C,eAAe,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBAC/B,IAAI,SAAS,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;4BAC5C,SAAS,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC;wBACtC,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,kCAAkC,EAAE,KAAK,CAAC,CAAC;gBAC3D,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBAClB,IAAI,aAAa,KAAK,EAAE,EAAE,CAAC;oBACzB,aAAa,GAAG,IAAI,CAAC;oBACrB,cAAc,GAAG,IAAI,CAAC,CAAC,yCAAyC;oBAChE,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,CAAC;gBACxC,CAAC;YACH,CAAC,CAAC,CAAC;QAEL,CAAC;aAAM,CAAC;YACN,wBAAwB;YACxB,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;YACnB,OAAO,CAAC,GAAG,CAAC,kCAAkC,UAAU,CAAC,IAAI,GAAG,CAAC,CAAC;YAElE,sDAAsD;YACtD,IAAI,cAAc,EAAE,CAAC;gBACnB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;oBACrB,IAAI,EAAE,gBAAgB;oBACtB,OAAO,EAAE,cAAc;iBACxB,CAAC,CAAC,CAAC;YACN,CAAC;YAED,EAAE,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,IAAI,EAAE,EAAE;gBACxB,IAAI,CAAC;oBACH,MAAM,GAAG,GAAkB,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC;oBAEvD,yBAAyB;oBACzB,IAAI,GAAG,CAAC,MAAM,KAAK,YAAY,EAAE,CAAC;wBAChC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;4BACrB,EAAE,EAAE,GAAG,CAAC,EAAE;4BACV,MAAM,EAAE,cAAc;yBACvB,CAAC,CAAC,CAAC;wBACJ,OAAO;oBACT,CAAC;oBAED,yDAAyD;oBACzD,IAAI,GAAG,CAAC,MAAM,IAAI,GAAG,CAAC,EAAE,EAAE,CAAC;wBACzB,0BAA0B;wBAC1B,IAAI,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;wBACpC,MAAM,YAAY,GAAG,GAAG,CAAC,SAAS,IAAI,SAAS,CAAC;wBAEhD,IAAI,CAAC,OAAO,EAAE,CAAC;4BACb,yDAAyD;4BACzD,MAAM,YAAY,GAAG,qBAAqB,CAAC,GAAG,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;4BAClE,MAAM,QAAQ,GAAG,YAAY,GAAG,CAAC,CAAC;4BAClC,qBAAqB,CAAC,GAAG,CAAC,YAAY,EAAE,QAAQ,CAAC,CAAC;4BAElD,OAAO,GAAG;gCACR,SAAS,EAAE,YAAY;gCACvB,UAAU,EAAE,QAAQ;gCACpB,SAAS,EAAE,QAAQ,IAAI,CAAC,GAAG,EAAE,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE;6BAC3E,CAAC;4BACF,aAAa,CAAC,GAAG,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC;4BAC/B,OAAO,CAAC,GAAG,CAAC,iBAAiB,YAAY,KAAK,QAAQ,EAAE,CAAC,CAAC;4BAE1D,mFAAmF;4BACnF,oEAAoE;wBACtE,CAAC;wBAED,6CAA6C;wBAC7C,qFAAqF;wBACrF,yGAAyG;wBACzG,6BAA6B;wBAC7B,MAAM,eAAe,GAAG,GAAG,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,UAAU,EAAE,CAAC;wBAEtE,IAAI,aAAa,IAAI,aAAa,CAAC,UAAU,KAAK,SAAS,CAAC,IAAI,EAAE,CAAC;4BACjE,eAAe,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;4BAChC,2BAA2B;4BAC3B,MAAM,UAAU,GAAG,EAAE,GAAG,GAAG,EAAE,SAAS,EAAE,eAAe,EAAE,CAAC;4BAC1D,aAAa,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;wBACjD,CAAC;6BAAM,CAAC;4BACN,uBAAuB;4BACvB,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC;gCACrB,EAAE,EAAE,GAAG,CAAC,EAAE;gCACV,KAAK,EAAE,EAAE,OAAO,EAAE,sEAAsE,EAAE;6BAC3F,CAAC,CAAC,CAAC;wBACN,CAAC;oBACH,CAAC;gBACH,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,OAAO,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAC;gBACvD,CAAC;YACH,CAAC,CAAC,CAAC;YAEH,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE;gBAClB,MAAM,OAAO,GAAG,aAAa,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;gBACtC,IAAI,OAAO,EAAE,CAAC;oBACZ,OAAO,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,SAAS,KAAK,OAAO,CAAC,UAAU,eAAe,CAAC,CAAC;oBAC1E,aAAa,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBAC3B,CAAC;gBACD,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;gBACtB,OAAO,CAAC,GAAG,CAAC,sBAAsB,UAAU,CAAC,IAAI,EAAE,CAAC,CAAC;YACvD,CAAC,CAAC,CAAC;QACL,CAAC;QAED,EAAE,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAAK,EAAE,EAAE;YACvB,OAAO,CAAC,KAAK,CAAC,kBAAkB,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC;QACnD,CAAC,CAAC,CAAC;IACL,CAAC,CAAC,CAAC;IAEH,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,CAAC,KAA4B,EAAE,EAAE;QAC/C,IAAI,KAAK,CAAC,IAAI,KAAK,YAAY,EAAE,CAAC;YAChC,OAAO,CAAC,KAAK,CAAC,UAAU,IAAI,qBAAqB,CAAC,CAAC;YACnD,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;YAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,OAAO,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,CAAC,CAAC;IACxC,CAAC,CAAC,CAAC;IAEH,0BAA0B;IAC1B,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE;QACxB,OAAO,CAAC,GAAG,CAAC,8BAA8B,CAAC,CAAC;QAC5C,GAAG,CAAC,KAAK,EAAE,CAAC;QACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACL,CAAC"}
|
|
@@ -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 @@
|
|
|
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
|