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,77 @@
1
+ /**
2
+ * Daemon Client
3
+ *
4
+ * WebSocket client that connects to the GitNexus daemon.
5
+ * Used by `serve` command to route tool calls through the daemon to the browser.
6
+ * Also receives codebase context for MCP resource exposure.
7
+ */
8
+ export interface BridgeMessage {
9
+ id: string;
10
+ method?: string;
11
+ params?: any;
12
+ result?: any;
13
+ error?: {
14
+ message: string;
15
+ };
16
+ type?: string;
17
+ context?: CodebaseContext;
18
+ agentName?: string;
19
+ }
20
+ /**
21
+ * Codebase context from browser
22
+ */
23
+ export interface CodebaseContext {
24
+ projectName: string;
25
+ stats: {
26
+ fileCount: number;
27
+ functionCount: number;
28
+ classCount: number;
29
+ interfaceCount: number;
30
+ methodCount: number;
31
+ };
32
+ hotspots: Array<{
33
+ name: string;
34
+ type: string;
35
+ filePath: string;
36
+ connections: number;
37
+ }>;
38
+ folderTree: string;
39
+ }
40
+ export declare class DaemonClient {
41
+ private port;
42
+ private ws;
43
+ private pendingRequests;
44
+ private requestId;
45
+ private _context;
46
+ private contextListeners;
47
+ private agentName;
48
+ constructor(port?: number, agentName?: string);
49
+ private detectAgent;
50
+ /**
51
+ * Connect to the daemon
52
+ */
53
+ connect(): Promise<void>;
54
+ private handleMessage;
55
+ /**
56
+ * Get current codebase context
57
+ */
58
+ get context(): CodebaseContext | null;
59
+ /**
60
+ * Listen for context changes
61
+ */
62
+ onContextChange(listener: (context: CodebaseContext | null) => void): () => boolean;
63
+ private notifyContextListeners;
64
+ /**
65
+ * Check if connected to daemon
66
+ */
67
+ get isConnected(): boolean;
68
+ /**
69
+ * Call a tool (routed through daemon to browser)
70
+ */
71
+ callTool(method: string, params: any): Promise<any>;
72
+ /**
73
+ * Disconnect from daemon
74
+ */
75
+ disconnect(): void;
76
+ }
77
+ //# sourceMappingURL=daemon-client.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-client.d.ts","sourceRoot":"","sources":["../../src/bridge/daemon-client.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAIH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,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;AAOD,qBAAa,YAAY;IAQX,OAAO,CAAC,IAAI;IAPxB,OAAO,CAAC,EAAE,CAA0B;IACpC,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,gBAAgB,CAA6D;IACrF,OAAO,CAAC,SAAS,CAAS;gBAEN,IAAI,GAAE,MAAc,EAAE,SAAS,CAAC,EAAE,MAAM;IAK5D,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACG,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC9B,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,IAAI,OAAO,IAAI,eAAe,GAAG,IAAI,CAEpC;IAED;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI;IAKnE,OAAO,CAAC,sBAAsB;IAI9B;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAuBzD;;OAEG;IACH,UAAU;CAIX"}
@@ -0,0 +1,135 @@
1
+ /**
2
+ * Daemon Client
3
+ *
4
+ * WebSocket client that connects to the GitNexus daemon.
5
+ * Used by `serve` command to route tool calls through the daemon to the browser.
6
+ * Also receives codebase context for MCP resource exposure.
7
+ */
8
+ import WebSocket from 'ws';
9
+ export class DaemonClient {
10
+ port;
11
+ ws = null;
12
+ pendingRequests = new Map();
13
+ requestId = 0;
14
+ _context = null;
15
+ contextListeners = new Set();
16
+ agentName;
17
+ constructor(port = 54319, agentName) {
18
+ this.port = port;
19
+ // Detect agent from environment or use provided name
20
+ this.agentName = agentName || process.env.GITNEXUS_AGENT || this.detectAgent();
21
+ }
22
+ detectAgent() {
23
+ // Try to detect agent from environment clues
24
+ if (process.env.CURSOR_SESSION_ID)
25
+ return 'Cursor';
26
+ if (process.env.CLAUDE_CODE)
27
+ return 'Claude Code';
28
+ if (process.env.WINDSURF_SESSION)
29
+ return 'Windsurf';
30
+ return 'Unknown';
31
+ }
32
+ /**
33
+ * Connect to the daemon
34
+ */
35
+ async connect() {
36
+ return new Promise((resolve, reject) => {
37
+ // Connect to /mcp path so daemon knows this is an MCP client
38
+ this.ws = new WebSocket(`ws://localhost:${this.port}/mcp`);
39
+ this.ws.on('open', () => {
40
+ resolve();
41
+ });
42
+ this.ws.on('error', (error) => {
43
+ reject(error);
44
+ });
45
+ this.ws.on('message', (data) => {
46
+ try {
47
+ const msg = JSON.parse(data.toString());
48
+ this.handleMessage(msg);
49
+ }
50
+ catch (error) {
51
+ console.error('Failed to parse message:', error);
52
+ }
53
+ });
54
+ this.ws.on('close', () => {
55
+ this.ws = null;
56
+ this._context = null;
57
+ // Reject all pending requests
58
+ for (const { reject } of this.pendingRequests.values()) {
59
+ reject(new Error('Connection closed'));
60
+ }
61
+ this.pendingRequests.clear();
62
+ });
63
+ });
64
+ }
65
+ handleMessage(msg) {
66
+ // Handle context update from daemon
67
+ if (msg.type === 'context_update' && msg.context) {
68
+ this._context = msg.context;
69
+ this.notifyContextListeners();
70
+ return;
71
+ }
72
+ // Response from daemon (originally from browser)
73
+ if (msg.id && this.pendingRequests.has(msg.id)) {
74
+ const { resolve, reject } = this.pendingRequests.get(msg.id);
75
+ this.pendingRequests.delete(msg.id);
76
+ if (msg.error) {
77
+ reject(new Error(msg.error.message));
78
+ }
79
+ else {
80
+ resolve(msg.result);
81
+ }
82
+ }
83
+ }
84
+ /**
85
+ * Get current codebase context
86
+ */
87
+ get context() {
88
+ return this._context;
89
+ }
90
+ /**
91
+ * Listen for context changes
92
+ */
93
+ onContextChange(listener) {
94
+ this.contextListeners.add(listener);
95
+ return () => this.contextListeners.delete(listener);
96
+ }
97
+ notifyContextListeners() {
98
+ this.contextListeners.forEach(listener => listener(this._context));
99
+ }
100
+ /**
101
+ * Check if connected to daemon
102
+ */
103
+ get isConnected() {
104
+ return this.ws !== null && this.ws.readyState === WebSocket.OPEN;
105
+ }
106
+ /**
107
+ * Call a tool (routed through daemon to browser)
108
+ */
109
+ async callTool(method, params) {
110
+ if (!this.isConnected) {
111
+ throw new Error('Not connected to daemon');
112
+ }
113
+ const id = `req_${++this.requestId}`;
114
+ return new Promise((resolve, reject) => {
115
+ this.pendingRequests.set(id, { resolve, reject });
116
+ const msg = { id, method, params, agentName: this.agentName };
117
+ this.ws.send(JSON.stringify(msg));
118
+ // Timeout after 30 seconds
119
+ setTimeout(() => {
120
+ if (this.pendingRequests.has(id)) {
121
+ this.pendingRequests.delete(id);
122
+ reject(new Error('Request timeout'));
123
+ }
124
+ }, 30000);
125
+ });
126
+ }
127
+ /**
128
+ * Disconnect from daemon
129
+ */
130
+ disconnect() {
131
+ this.ws?.close();
132
+ this.ws = null;
133
+ }
134
+ }
135
+ //# sourceMappingURL=daemon-client.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"daemon-client.js","sourceRoot":"","sources":["../../src/bridge/daemon-client.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,28 @@
1
+ /**
2
+ * Bridge Protocol Types
3
+ *
4
+ * JSON-RPC-like protocol for communication between bridge and browser.
5
+ */
6
+ export interface ToolCallRequest {
7
+ id: string;
8
+ method: string;
9
+ params: Record<string, any>;
10
+ }
11
+ export interface ToolCallResponse {
12
+ id: string;
13
+ result?: any;
14
+ error?: {
15
+ code?: number;
16
+ message: string;
17
+ };
18
+ }
19
+ export type BridgeMessage = ToolCallRequest | ToolCallResponse;
20
+ /**
21
+ * Check if message is a request (has method)
22
+ */
23
+ export declare function isRequest(msg: BridgeMessage): msg is ToolCallRequest;
24
+ /**
25
+ * Check if message is a response (has result or error)
26
+ */
27
+ export declare function isResponse(msg: BridgeMessage): msg is ToolCallResponse;
28
+ //# sourceMappingURL=protocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.d.ts","sourceRoot":"","sources":["../../src/bridge/protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,EAAE,MAAM,CAAC;IACf,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;CAC7B;AAED,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE;QACN,IAAI,CAAC,EAAE,MAAM,CAAC;QACd,OAAO,EAAE,MAAM,CAAC;KACjB,CAAC;CACH;AAED,MAAM,MAAM,aAAa,GAAG,eAAe,GAAG,gBAAgB,CAAC;AAE/D;;GAEG;AACH,wBAAgB,SAAS,CAAC,GAAG,EAAE,aAAa,GAAG,GAAG,IAAI,eAAe,CAEpE;AAED;;GAEG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,aAAa,GAAG,GAAG,IAAI,gBAAgB,CAEtE"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Bridge Protocol Types
3
+ *
4
+ * JSON-RPC-like protocol for communication between bridge and browser.
5
+ */
6
+ /**
7
+ * Check if message is a request (has method)
8
+ */
9
+ export function isRequest(msg) {
10
+ return 'method' in msg;
11
+ }
12
+ /**
13
+ * Check if message is a response (has result or error)
14
+ */
15
+ export function isResponse(msg) {
16
+ return 'result' in msg || 'error' in msg;
17
+ }
18
+ //# sourceMappingURL=protocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"protocol.js","sourceRoot":"","sources":["../../src/bridge/protocol.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAmBH;;GAEG;AACH,MAAM,UAAU,SAAS,CAAC,GAAkB;IAC1C,OAAO,QAAQ,IAAI,GAAG,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,GAAkB;IAC3C,OAAO,QAAQ,IAAI,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC;AAC3C,CAAC"}
@@ -0,0 +1,85 @@
1
+ /**
2
+ * WebSocket Bridge
3
+ *
4
+ * WebSocket server that connects to the GitNexus browser tab.
5
+ * Relays tool calls from MCP server to browser and returns results.
6
+ */
7
+ export interface BridgeMessage {
8
+ id: string;
9
+ method?: string;
10
+ params?: any;
11
+ result?: any;
12
+ error?: {
13
+ message: string;
14
+ };
15
+ type?: 'context' | string;
16
+ agentName?: string;
17
+ }
18
+ /**
19
+ * Codebase context sent from the GitNexus browser app
20
+ */
21
+ export interface CodebaseContext {
22
+ projectName: string;
23
+ stats: {
24
+ fileCount: number;
25
+ functionCount: number;
26
+ classCount: number;
27
+ interfaceCount: number;
28
+ methodCount: number;
29
+ };
30
+ hotspots: Array<{
31
+ name: string;
32
+ type: string;
33
+ filePath: string;
34
+ connections: number;
35
+ }>;
36
+ folderTree: string;
37
+ }
38
+ export declare class WebSocketBridge {
39
+ private port;
40
+ private wss;
41
+ private client;
42
+ private pendingRequests;
43
+ private requestId;
44
+ private started;
45
+ private _context;
46
+ private contextListeners;
47
+ private agentName;
48
+ constructor(port?: number, agentName?: string);
49
+ private detectAgent;
50
+ /**
51
+ * Start the WebSocket server (handles port-in-use gracefully)
52
+ */
53
+ start(): Promise<boolean>;
54
+ private handleMessage;
55
+ /**
56
+ * Check if browser is connected
57
+ */
58
+ get isConnected(): boolean;
59
+ /**
60
+ * Latest context received from browser (if any)
61
+ */
62
+ get context(): CodebaseContext | null;
63
+ /**
64
+ * Listen for context changes
65
+ */
66
+ onContextChange(listener: (context: CodebaseContext | null) => void): () => boolean;
67
+ private notifyContextListeners;
68
+ /**
69
+ * Check if server started successfully
70
+ */
71
+ get isStarted(): boolean;
72
+ /**
73
+ * Call a tool in the browser
74
+ */
75
+ callTool(method: string, params: any): Promise<any>;
76
+ /**
77
+ * Close the WebSocket server
78
+ */
79
+ close(): void;
80
+ /**
81
+ * MCP server calls this on shutdown
82
+ */
83
+ disconnect(): void;
84
+ }
85
+ //# sourceMappingURL=websocket-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-server.d.ts","sourceRoot":"","sources":["../../src/bridge/websocket-server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAKH,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,MAAM,CAAC,EAAE,GAAG,CAAC;IACb,KAAK,CAAC,EAAE;QAAE,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAC5B,IAAI,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,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;AAsBD,qBAAa,eAAe;IAUd,OAAO,CAAC,IAAI;IATxB,OAAO,CAAC,GAAG,CAAgC;IAC3C,OAAO,CAAC,MAAM,CAA0B;IACxC,OAAO,CAAC,eAAe,CAA2C;IAClE,OAAO,CAAC,SAAS,CAAK;IACtB,OAAO,CAAC,OAAO,CAAS;IACxB,OAAO,CAAC,QAAQ,CAAgC;IAChD,OAAO,CAAC,gBAAgB,CAA6D;IACrF,OAAO,CAAC,SAAS,CAAS;gBAEN,IAAI,GAAE,MAAc,EAAE,SAAS,CAAC,EAAE,MAAM;IAI5D,OAAO,CAAC,WAAW;IAQnB;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,OAAO,CAAC;IAyD/B,OAAO,CAAC,aAAa;IAqBrB;;OAEG;IACH,IAAI,WAAW,IAAI,OAAO,CAEzB;IAED;;OAEG;IACH,IAAI,OAAO,IAAI,eAAe,GAAG,IAAI,CAEpC;IAED;;OAEG;IACH,eAAe,CAAC,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI;IAKnE,OAAO,CAAC,sBAAsB;IAI9B;;OAEG;IACH,IAAI,SAAS,IAAI,OAAO,CAEvB;IAED;;OAEG;IACG,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;IAuBzD;;OAEG;IACH,KAAK;IAIL;;OAEG;IACH,UAAU;CAGX"}
@@ -0,0 +1,180 @@
1
+ /**
2
+ * WebSocket Bridge
3
+ *
4
+ * WebSocket server that connects to the GitNexus browser tab.
5
+ * Relays tool calls from MCP server to browser and returns results.
6
+ */
7
+ import { WebSocketServer, WebSocket } from 'ws';
8
+ import { createServer as createNetServer } from 'net';
9
+ /**
10
+ * Check if a port is available
11
+ */
12
+ async function isPortAvailable(port) {
13
+ return new Promise((resolve) => {
14
+ const server = createNetServer();
15
+ server.once('error', () => resolve(false));
16
+ server.once('listening', () => {
17
+ server.close();
18
+ resolve(true);
19
+ });
20
+ server.listen(port);
21
+ });
22
+ }
23
+ export class WebSocketBridge {
24
+ port;
25
+ wss = null;
26
+ client = null;
27
+ pendingRequests = new Map();
28
+ requestId = 0;
29
+ started = false;
30
+ _context = null;
31
+ contextListeners = new Set();
32
+ agentName;
33
+ constructor(port = 54319, agentName) {
34
+ this.port = port;
35
+ this.agentName = agentName || process.env.GITNEXUS_AGENT || this.detectAgent();
36
+ }
37
+ detectAgent() {
38
+ // Try to detect agent from environment clues
39
+ if (process.env.CURSOR_SESSION_ID)
40
+ return 'Cursor';
41
+ if (process.env.CLAUDE_CODE)
42
+ return 'Claude Code';
43
+ if (process.env.WINDSURF_SESSION)
44
+ return 'Windsurf';
45
+ return 'Unknown';
46
+ }
47
+ /**
48
+ * Start the WebSocket server (handles port-in-use gracefully)
49
+ */
50
+ async start() {
51
+ const available = await isPortAvailable(this.port);
52
+ if (!available) {
53
+ // Port already in use - another instance is handling browser connections
54
+ // This is OK - we can still run MCP server for stdio communication
55
+ console.error(`Port ${this.port} in use. Browser bridge running elsewhere.`);
56
+ return false;
57
+ }
58
+ return new Promise((resolve) => {
59
+ this.wss = new WebSocketServer({ port: this.port });
60
+ this.wss.on('connection', (ws) => {
61
+ // Only allow one browser connection at a time
62
+ if (this.client) {
63
+ this.client.close();
64
+ }
65
+ this.client = ws;
66
+ // Clear context until browser sends an update
67
+ this._context = null;
68
+ this.notifyContextListeners();
69
+ ws.on('message', (data) => {
70
+ try {
71
+ const msg = JSON.parse(data.toString());
72
+ this.handleMessage(msg);
73
+ }
74
+ catch (error) {
75
+ console.error('Failed to parse message:', error);
76
+ }
77
+ });
78
+ ws.on('close', () => {
79
+ if (this.client === ws) {
80
+ this.client = null;
81
+ this._context = null;
82
+ this.notifyContextListeners();
83
+ }
84
+ });
85
+ ws.on('error', (error) => {
86
+ console.error('WebSocket error:', error);
87
+ });
88
+ });
89
+ this.wss.on('listening', () => {
90
+ this.started = true;
91
+ resolve(true);
92
+ });
93
+ this.wss.on('error', (error) => {
94
+ console.error('WebSocket server error:', error);
95
+ resolve(false);
96
+ });
97
+ });
98
+ }
99
+ handleMessage(msg) {
100
+ // Browser can proactively send codebase context
101
+ if (msg.type === 'context' && msg.params) {
102
+ this._context = msg.params;
103
+ this.notifyContextListeners();
104
+ return;
105
+ }
106
+ // This is a response to a pending request
107
+ if (msg.id && this.pendingRequests.has(msg.id)) {
108
+ const { resolve, reject } = this.pendingRequests.get(msg.id);
109
+ this.pendingRequests.delete(msg.id);
110
+ if (msg.error) {
111
+ reject(new Error(msg.error.message));
112
+ }
113
+ else {
114
+ resolve(msg.result);
115
+ }
116
+ }
117
+ }
118
+ /**
119
+ * Check if browser is connected
120
+ */
121
+ get isConnected() {
122
+ return this.client !== null && this.client.readyState === WebSocket.OPEN;
123
+ }
124
+ /**
125
+ * Latest context received from browser (if any)
126
+ */
127
+ get context() {
128
+ return this._context;
129
+ }
130
+ /**
131
+ * Listen for context changes
132
+ */
133
+ onContextChange(listener) {
134
+ this.contextListeners.add(listener);
135
+ return () => this.contextListeners.delete(listener);
136
+ }
137
+ notifyContextListeners() {
138
+ this.contextListeners.forEach((listener) => listener(this._context));
139
+ }
140
+ /**
141
+ * Check if server started successfully
142
+ */
143
+ get isStarted() {
144
+ return this.started;
145
+ }
146
+ /**
147
+ * Call a tool in the browser
148
+ */
149
+ async callTool(method, params) {
150
+ if (!this.isConnected) {
151
+ throw new Error('GitNexus browser not connected. Open GitNexus and enable MCP toggle.');
152
+ }
153
+ const id = `req_${++this.requestId}`;
154
+ return new Promise((resolve, reject) => {
155
+ this.pendingRequests.set(id, { resolve, reject });
156
+ const msg = { id, method, params, agentName: this.agentName };
157
+ this.client.send(JSON.stringify(msg));
158
+ // Timeout after 30 seconds
159
+ setTimeout(() => {
160
+ if (this.pendingRequests.has(id)) {
161
+ this.pendingRequests.delete(id);
162
+ reject(new Error('Request timeout'));
163
+ }
164
+ }, 30000);
165
+ });
166
+ }
167
+ /**
168
+ * Close the WebSocket server
169
+ */
170
+ close() {
171
+ this.wss?.close();
172
+ }
173
+ /**
174
+ * MCP server calls this on shutdown
175
+ */
176
+ disconnect() {
177
+ this.close();
178
+ }
179
+ }
180
+ //# sourceMappingURL=websocket-server.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"websocket-server.js","sourceRoot":"","sources":["../../src/bridge/websocket-server.ts"],"names":[],"mappings":"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"}
package/dist/cli.d.ts ADDED
@@ -0,0 +1,9 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * GitNexus MCP CLI
4
+ *
5
+ * Bridge between external AI agents (Cursor, Claude Code, Windsurf)
6
+ * and GitNexus code intelligence running in the browser.
7
+ */
8
+ export {};
9
+ //# sourceMappingURL=cli.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG"}
package/dist/cli.js ADDED
@@ -0,0 +1,56 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * GitNexus MCP CLI
4
+ *
5
+ * Bridge between external AI agents (Cursor, Claude Code, Windsurf)
6
+ * and GitNexus code intelligence running in the browser.
7
+ */
8
+ import { serveCommand } from './commands/serve.js';
9
+ /**
10
+ * Minimal CLI:
11
+ * - Default: start MCP stdio server + local browser WebSocket bridge
12
+ * - Optional: `serve` alias, and `--port <port>`
13
+ *
14
+ * This is designed for MCP clients (Cursor/Claude/Windsurf) which spawn this
15
+ * process automatically; users should not need to run commands manually.
16
+ */
17
+ function parsePort(argv) {
18
+ const portFlagIndex = argv.findIndex((a) => a === '--port' || a === '-p');
19
+ if (portFlagIndex !== -1) {
20
+ const value = argv[portFlagIndex + 1];
21
+ if (value)
22
+ return value;
23
+ }
24
+ // Support `--port=54319`
25
+ const portEq = argv.find((a) => a.startsWith('--port='));
26
+ if (portEq)
27
+ return portEq.split('=')[1] || '54319';
28
+ return '54319';
29
+ }
30
+ async function main() {
31
+ const argv = process.argv.slice(2);
32
+ const first = argv[0];
33
+ const port = parsePort(argv);
34
+ // Allow `gitnexus-mcp serve` for compatibility, but default to serve anyway
35
+ if (!first || first === 'serve') {
36
+ await serveCommand({ port });
37
+ return;
38
+ }
39
+ // Minimal help for unknown commands
40
+ if (first === '--help' || first === '-h') {
41
+ // eslint-disable-next-line no-console
42
+ console.log('gitnexus-mcp\n\nUsage:\n gitnexus-mcp [serve] [--port <port>]\n');
43
+ process.exit(0);
44
+ }
45
+ // eslint-disable-next-line no-console
46
+ console.error(`Unknown command: ${first}`);
47
+ // eslint-disable-next-line no-console
48
+ console.error('Usage: gitnexus-mcp [serve] [--port <port>]');
49
+ process.exit(1);
50
+ }
51
+ main().catch((err) => {
52
+ // eslint-disable-next-line no-console
53
+ console.error(err instanceof Error ? err.message : err);
54
+ process.exit(1);
55
+ });
56
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";AACA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AACnD;;;;;;;GAOG;AAEH,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,CAAC,CAAC;IAC1E,IAAI,aAAa,KAAK,CAAC,CAAC,EAAE,CAAC;QACzB,MAAM,KAAK,GAAG,IAAI,CAAC,aAAa,GAAG,CAAC,CAAC,CAAC;QACtC,IAAI,KAAK;YAAE,OAAO,KAAK,CAAC;IAC1B,CAAC;IACD,yBAAyB;IACzB,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IACzD,IAAI,MAAM;QAAE,OAAO,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,OAAO,CAAC;IACnD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;IACnC,MAAM,KAAK,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;IACtB,MAAM,IAAI,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC;IAE7B,4EAA4E;IAC5E,IAAI,CAAC,KAAK,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QAChC,MAAM,YAAY,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC;QAC7B,OAAO;IACT,CAAC;IAED,oCAAoC;IACpC,IAAI,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;QACzC,sCAAsC;QACtC,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,oBAAoB,KAAK,EAAE,CAAC,CAAC;IAC3C,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,6CAA6C,CAAC,CAAC;IAC7D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,IAAI,EAAE,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;IACnB,sCAAsC;IACtC,OAAO,CAAC,KAAK,CAAC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;IACxD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -0,0 +1,37 @@
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
+ /**
12
+ * Codebase context sent from browser
13
+ */
14
+ interface CodebaseContext {
15
+ projectName: string;
16
+ stats: {
17
+ fileCount: number;
18
+ functionCount: number;
19
+ classCount: number;
20
+ interfaceCount: number;
21
+ methodCount: number;
22
+ };
23
+ hotspots: Array<{
24
+ name: string;
25
+ type: string;
26
+ filePath: string;
27
+ connections: number;
28
+ }>;
29
+ folderTree: string;
30
+ }
31
+ interface DaemonOptions {
32
+ port: string;
33
+ }
34
+ export declare function getCodebaseContext(): CodebaseContext | null;
35
+ export declare function daemonCommand(options: DaemonOptions): Promise<void>;
36
+ export {};
37
+ //# sourceMappingURL=daemon.d.ts.map