gitnexus 1.6.4-rc.10 → 1.6.4-rc.12

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 (76) hide show
  1. package/dist/cli/setup.js +2 -2
  2. package/dist/server/api.d.ts +5 -0
  3. package/dist/server/api.js +113 -0
  4. package/package.json +3 -2
  5. package/scripts/build.js +22 -2
  6. package/web/assets/agent-DaprsFSX.js +597 -0
  7. package/web/assets/architecture-YZFGNWBL-S5CXDPWN-DEdGaPg2.js +1 -0
  8. package/web/assets/architectureDiagram-EMZXCZ2Q-Domyk_gO.js +36 -0
  9. package/web/assets/blockDiagram-IGV67L2C-B_2kD7tM.js +132 -0
  10. package/web/assets/c4Diagram-DFAF54RM-BhJJW8Gg.js +10 -0
  11. package/web/assets/chunk-3GS5O3IE-jlWIjPsl.js +231 -0
  12. package/web/assets/chunk-3YCYZ6SJ-Blq_IzZs.js +1 -0
  13. package/web/assets/chunk-6NTNNK5N-DyPc58pp.js +1 -0
  14. package/web/assets/chunk-7RZVMHOQ-BdIU-RGO.js +321 -0
  15. package/web/assets/chunk-A34GCYZU-BI2i_LdU.js +1 -0
  16. package/web/assets/chunk-AEOMTBSW-D7qjBMHW.js +1 -0
  17. package/web/assets/chunk-CilyBKbf.js +1 -0
  18. package/web/assets/chunk-DJ7UZH7F-i11ywiBl.js +1 -0
  19. package/web/assets/chunk-DKKBVRCY-1SffGI1N.js +4 -0
  20. package/web/assets/chunk-DU5LTGQ6-DaPeiwD5.js +1 -0
  21. package/web/assets/chunk-FXACKDTF-uhhi2PC2.js +159 -0
  22. package/web/assets/chunk-H3VCZNTA-IchcISDt.js +1 -0
  23. package/web/assets/chunk-HN6EAY2L-D7ZFMNrB.js +1 -0
  24. package/web/assets/chunk-KSICW3F5-C2tZmXwv.js +15 -0
  25. package/web/assets/chunk-O5ABG6QK-Bt-Km84H.js +1 -0
  26. package/web/assets/chunk-PK6DOVAG-ChlWY0BQ.js +206 -0
  27. package/web/assets/chunk-RNJOYNJ4-B724K7cW.js +1 -0
  28. package/web/assets/chunk-RWUO3TPN-DYn1XriD.js +1 -0
  29. package/web/assets/chunk-TBF5ZNIQ-DKtDz6ae.js +1 -0
  30. package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +1 -0
  31. package/web/assets/chunk-TYMNRAUI-g1h33cq-.js +1 -0
  32. package/web/assets/chunk-VELTKBKT-C9dVN39o.js +1 -0
  33. package/web/assets/chunk-W7ZLLLMY-Du-Hb9yb.js +1 -0
  34. package/web/assets/chunk-WSB5WSVC-B123clsZ.js +1 -0
  35. package/web/assets/chunk-XGPFEOL4-BR7Eue38.js +1 -0
  36. package/web/assets/classDiagram-PPOCWD7C-BglfKSs_.js +1 -0
  37. package/web/assets/classDiagram-v2-23LJLIIU-BSzTM28O.js +1 -0
  38. package/web/assets/context-builder-CqQNhRj1.js +15 -0
  39. package/web/assets/cose-bilkent-PNC4W37J-DCfErU-A.js +1 -0
  40. package/web/assets/dagre-E77IOHMT-tDRRhDoN.js +4 -0
  41. package/web/assets/diagram-H7BISOXX-CUVHlmAh.js +43 -0
  42. package/web/assets/diagram-JC5VWROH-BoyOxulB.js +24 -0
  43. package/web/assets/diagram-LXUTUG65-osr9hb7N.js +10 -0
  44. package/web/assets/diagram-WEHSV5V5-d8nUqS39.js +24 -0
  45. package/web/assets/erDiagram-GCSMX5X6-b-IwOhPS.js +85 -0
  46. package/web/assets/flowDiagram-OTCZ4VVT-Ott2Q0AP.js +162 -0
  47. package/web/assets/ganttDiagram-MUNLMDZQ-BYtgN_5s.js +292 -0
  48. package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-CFyBIGZq.js +1 -0
  49. package/web/assets/gitGraphDiagram-3HKGZ4G3-CsVD2gn4.js +106 -0
  50. package/web/assets/index-BleGLU8S.css +2 -0
  51. package/web/assets/index-C_xK08EW.js +885 -0
  52. package/web/assets/info-OMHHGYJF-BF2H5H6G-yjAxKEzh.js +1 -0
  53. package/web/assets/infoDiagram-MN7RKWGX-DXK0Unn5.js +2 -0
  54. package/web/assets/ishikawaDiagram-YMYX4NHK-CXsnC2FA.js +70 -0
  55. package/web/assets/journeyDiagram-SO5T7YLQ-BzZ07B-X.js +139 -0
  56. package/web/assets/kanban-definition-LJHFXRCJ-C6_EpAd9.js +89 -0
  57. package/web/assets/katex-GD7MH7QM-CJiOjBBJ.js +261 -0
  58. package/web/assets/mindmap-definition-2EUWGEK5-CCYGWZ1m.js +96 -0
  59. package/web/assets/packet-4T2RLAQJ-EV4IVRXR-B8k4E3IT.js +1 -0
  60. package/web/assets/pie-ZZUOXDRM-N23DN5KN-DdvfY118.js +1 -0
  61. package/web/assets/pieDiagram-3IATQBI2-RyvRlQb4.js +30 -0
  62. package/web/assets/quadrantDiagram-E256RVCF-Bfb6sxCx.js +7 -0
  63. package/web/assets/radar-PYXPWWZC-P6TP7ZYP-1EEDC_yU.js +1 -0
  64. package/web/assets/requirementDiagram-M5DCFWZL-DjvHDyvN.js +84 -0
  65. package/web/assets/sankeyDiagram-L3NBLAOT-CBCbbl8s.js +10 -0
  66. package/web/assets/sequenceDiagram-ZOUHS735-BscU8TUR.js +157 -0
  67. package/web/assets/stateDiagram-MLPALWAM-CJusEK2D.js +1 -0
  68. package/web/assets/stateDiagram-v2-B5LQ5ZB2-DImJ3PXD.js +1 -0
  69. package/web/assets/timeline-definition-5SPVSISX-DigPA1X8.js +120 -0
  70. package/web/assets/treeView-SZITEDCU-5DXDK3XO-CzPDt3aG.js +1 -0
  71. package/web/assets/treemap-W4RFUUIX-WYLRDWKO-B9Iqiorr.js +1 -0
  72. package/web/assets/vennDiagram-IE5QUKF5-C91UkZIf.js +34 -0
  73. package/web/assets/wardley-RL74JXVD-BCRCBASE-x42Qw7hp.js +1 -0
  74. package/web/assets/wardleyDiagram-XU3VSMPF-DloBhI0U.js +20 -0
  75. package/web/assets/xychartDiagram-ZHJ5623Y-BGWJvgwI.js +7 -0
  76. package/web/index.html +21 -0
package/dist/cli/setup.js CHANGED
@@ -512,13 +512,13 @@ async function installCursorSkills(result) {
512
512
  }
513
513
  }
514
514
  /**
515
- * Install global OpenCode skills to ~/.config/opencode/skill/gitnexus/
515
+ * Install global OpenCode skills to ~/.config/opencode/skills/gitnexus/
516
516
  */
517
517
  async function installOpenCodeSkills(result) {
518
518
  const opencodeDir = path.join(os.homedir(), '.config', 'opencode');
519
519
  if (!(await dirExists(opencodeDir)))
520
520
  return;
521
- const skillsDir = path.join(opencodeDir, 'skill');
521
+ const skillsDir = path.join(opencodeDir, 'skills');
522
522
  try {
523
523
  const installed = await installSkillsTo(skillsDir);
524
524
  if (installed.length > 0) {
@@ -41,6 +41,11 @@ export declare class ClientDisconnectedError extends Error {
41
41
  constructor();
42
42
  }
43
43
  export declare const isIgnorableGraphQueryError: (err: unknown) => boolean;
44
+ export declare const SPA_FALLBACK_REGEX: RegExp;
45
+ export declare const resolveWebDistDir: (primaryDir: string, fallbackDir: string) => Promise<string | null>;
46
+ export declare const landingPageHtml: () => string;
47
+ export declare const staticCacheControlSetHeaders: (res: express.Response, filePath: string) => void;
48
+ export declare const registerWebUI: (app: express.Express, staticDir: string | null) => void;
44
49
  export declare const writeNdjsonRecord: (res: express.Response, record: GraphStreamRecord, signal?: AbortSignal) => Promise<void>;
45
50
  export declare const streamGraphNdjson: (res: express.Response, includeContent?: boolean, signal?: AbortSignal) => Promise<void>;
46
51
  export declare const createServer: (port: number, host?: string) => Promise<void>;
@@ -103,6 +103,98 @@ export const isIgnorableGraphQueryError = (err) => {
103
103
  message.includes('not found') ||
104
104
  message.includes('No table named'));
105
105
  };
106
+ export const SPA_FALLBACK_REGEX = /^(?!\/api(?:\/|$))(?!.*\.\w{1,10}$).*/;
107
+ export const resolveWebDistDir = async (primaryDir, fallbackDir) => {
108
+ const envDir = process.env.GITNEXUS_WEB_DIST;
109
+ const dirs = envDir ? [envDir, primaryDir, fallbackDir] : [primaryDir, fallbackDir];
110
+ for (const dir of dirs) {
111
+ try {
112
+ await fs.access(path.join(dir, 'index.html'));
113
+ return dir;
114
+ }
115
+ catch (err) {
116
+ if (err?.code !== 'ENOENT') {
117
+ console.warn(`[serve] could not access web UI dir ${dir}:`, err.message);
118
+ }
119
+ }
120
+ }
121
+ return null;
122
+ };
123
+ export const landingPageHtml = () => `<!DOCTYPE html>
124
+ <html lang="en">
125
+ <head>
126
+ <meta charset="utf-8">
127
+ <meta name="viewport" content="width=device-width,initial-scale=1">
128
+ <title>GitNexus</title>
129
+ <style>
130
+ *{margin:0;padding:0;box-sizing:border-box}
131
+ body{font-family:Outfit,system-ui,-apple-system,sans-serif;background:#06060a;color:#e4e4ed;min-height:100vh;display:flex;align-items:center;justify-content:center;padding:1.5rem}
132
+ .card{background:#101018;border:1px solid #2a2a3a;border-radius:0.75rem;padding:2rem;max-width:480px;width:100%}
133
+ .logo{font-size:1.5rem;font-weight:700;color:#e4e4ed;letter-spacing:-0.02em;margin-bottom:0.25rem}
134
+ .subtitle{font-size:0.875rem;color:#8888a0;margin-bottom:1.5rem}
135
+ .section-title{font-size:0.75rem;font-weight:600;text-transform:uppercase;letter-spacing:0.05em;color:#5a5a70;margin-bottom:0.75rem}
136
+ .endpoint{margin:0.25rem 0;font-size:0.875rem}
137
+ .endpoint a{color:#7c3aed;text-decoration:none}
138
+ .endpoint a:hover{text-decoration:underline}
139
+ .endpoint code{background:#16161f;padding:0.15em 0.4em;border-radius:0.25rem;font-size:0.8rem;color:#8888a0}
140
+ .divider{height:1px;background:#1e1e2a;margin:1.25rem 0}
141
+ .terminal{background:#0a0a10;border:1px solid #1e1e2a;border-radius:0.5rem;padding:0.75rem 1rem;font-family:'SF Mono',SFMono-Regular,Consolas,'Liberation Mono',Menlo,monospace;font-size:0.8rem;color:#8888a0;margin-bottom:1rem;overflow-x:auto}
142
+ .terminal .prompt{color:#7c3aed;user-select:none}
143
+ .terminal .cmd{color:#e4e4ed}
144
+ .link-row{display:flex;align-items:center;gap:0.5rem;font-size:0.875rem;margin-top:0.5rem}
145
+ .link-row svg{flex-shrink:0}
146
+ a.ext{color:#7c3aed;text-decoration:none;display:inline-flex;align-items:center;gap:0.25rem}
147
+ a.ext:hover{text-decoration:underline}
148
+ </style>
149
+ </head>
150
+ <body>
151
+ <div class="card">
152
+ <div class="logo">GitNexus</div>
153
+ <div class="subtitle">API server is running</div>
154
+ <div class="section-title">Endpoints</div>
155
+ <p class="endpoint"><a href="/api/info">/api/info</a> <span style="color:#5a5a70">— Server version &amp; context</span></p>
156
+ <p class="endpoint"><a href="/api/repos">/api/repos</a> <span style="color:#5a5a70">— Indexed repositories</span></p>
157
+ <p class="endpoint"><code>/api/heartbeat</code> <span style="color:#5a5a70">— SSE heartbeat</span></p>
158
+ <p class="endpoint"><code>/api/graph</code> <code>/api/query</code> <code>/api/search</code> <span style="color:#5a5a70">— Data</span></p>
159
+ <p class="endpoint"><code>/api/mcp</code> <span style="color:#5a5a70">— MCP over StreamableHTTP</span></p>
160
+ <div class="divider"></div>
161
+ <div class="section-title">Web UI not found</div>
162
+ <div class="terminal"><span class="prompt">$ </span><span class="cmd">cd gitnexus-web &amp;&amp; npm run build</span></div>
163
+ <div class="link-row">
164
+ <svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#7c3aed" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V8a2 2 0 0 1 2-2h6"/><polyline points="15 3 21 3 21 9"/><line x1="10" y1="14" x2="21" y2="3"/></svg>
165
+ <a class="ext" href="https://gitnexus.vercel.app" target="_blank" rel="noopener noreferrer">gitnexus.vercel.app</a>
166
+ <span style="color:#5a5a70">— connects to this server</span>
167
+ </div>
168
+ </div>
169
+ </body>
170
+ </html>`;
171
+ export const staticCacheControlSetHeaders = (res, filePath) => {
172
+ if (filePath.endsWith('.html')) {
173
+ res.setHeader('Cache-Control', 'no-cache');
174
+ }
175
+ else {
176
+ res.setHeader('Cache-Control', 'public, max-age=31536000, immutable');
177
+ }
178
+ };
179
+ export const registerWebUI = (app, staticDir) => {
180
+ if (staticDir) {
181
+ app.use(express.static(staticDir, {
182
+ setHeaders: staticCacheControlSetHeaders,
183
+ }));
184
+ // ⚠ This must remain the LAST route before the global error handler.
185
+ // The regex excludes /api paths AND paths with file extensions (.js, .css, etc.)
186
+ // so missing assets get real 404s instead of the SPA HTML.
187
+ // Adding routes below this will be unreachable for non-API, non-asset paths.
188
+ app.get(SPA_FALLBACK_REGEX, (_req, res) => {
189
+ res.sendFile(path.join(staticDir, 'index.html'));
190
+ });
191
+ }
192
+ else {
193
+ app.get('/', (_req, res) => {
194
+ res.type('html').send(landingPageHtml());
195
+ });
196
+ }
197
+ };
106
198
  const ensureStreamIsWritable = (res, signal) => {
107
199
  if (signal?.aborted || res.destroyed || res.writableEnded) {
108
200
  throw new ClientDisconnectedError();
@@ -1373,6 +1465,15 @@ export const createServer = async (port, host = '127.0.0.1') => {
1373
1465
  embedJobManager.cancelJob(req.params.jobId, 'Cancelled by user');
1374
1466
  res.json({ id: job.id, status: 'failed', error: 'Cancelled by user' });
1375
1467
  });
1468
+ // ── Web UI (served at root) ───────────────────────────────────────
1469
+ // Resolve the gitnexus-web dist directory relative to this file's location.
1470
+ // In the published package: <pkg>/dist/server/api.js → <pkg>/web/
1471
+ // In dev (tsx): gitnexus/src/server/api.ts → gitnexus-web/dist/
1472
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
1473
+ const webDistDir = path.resolve(__dirname, '..', '..', 'web');
1474
+ const devWebDistDir = path.resolve(__dirname, '..', '..', '..', 'gitnexus-web', 'dist');
1475
+ const staticDir = await resolveWebDistDir(webDistDir, devWebDistDir);
1476
+ registerWebUI(app, staticDir);
1376
1477
  // Global error handler — catch anything the route handlers miss
1377
1478
  app.use((err, _req, res, _next) => {
1378
1479
  console.error('Unhandled error:', err);
@@ -1400,5 +1501,17 @@ export const createServer = async (port, host = '127.0.0.1') => {
1400
1501
  };
1401
1502
  process.once('SIGINT', shutdown);
1402
1503
  process.once('SIGTERM', shutdown);
1504
+ // Catch-all crash guards (mirrors startMCPServer in mcp/server.ts)
1505
+ let shuttingDown = false;
1506
+ process.on('uncaughtException', (err) => {
1507
+ console.error('GitNexus uncaughtException:', err?.stack || err);
1508
+ if (!shuttingDown) {
1509
+ shuttingDown = true;
1510
+ shutdown().catch(() => { });
1511
+ }
1512
+ });
1513
+ process.on('unhandledRejection', (reason) => {
1514
+ console.error('GitNexus unhandledRejection:', reason?.stack || reason);
1515
+ });
1403
1516
  });
1404
1517
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.4-rc.10",
3
+ "version": "1.6.4-rc.12",
4
4
  "description": "Graph-powered code intelligence for AI agents. Index any codebase, query via MCP or CLI.",
5
5
  "author": "Abhigyan Patwari",
6
6
  "license": "PolyForm-Noncommercial-1.0.0",
@@ -35,7 +35,8 @@
35
35
  "hooks",
36
36
  "scripts",
37
37
  "skills",
38
- "vendor"
38
+ "vendor",
39
+ "web"
39
40
  ],
40
41
  "scripts": {
41
42
  "build": "node scripts/build.js",
package/scripts/build.js CHANGED
@@ -21,11 +21,11 @@ const SHARED_DEST = path.join(DIST, '_shared');
21
21
 
22
22
  // ── 1. Build gitnexus-shared ───────────────────────────────────────
23
23
  console.log('[build] compiling gitnexus-shared…');
24
- execSync('npx tsc', { cwd: SHARED_ROOT, stdio: 'inherit' });
24
+ execSync('npx tsc', { cwd: SHARED_ROOT, stdio: 'inherit', timeout: 120_000 });
25
25
 
26
26
  // ── 2. Build gitnexus ──────────────────────────────────────────────
27
27
  console.log('[build] compiling gitnexus…');
28
- execSync('npx tsc', { cwd: ROOT, stdio: 'inherit' });
28
+ execSync('npx tsc', { cwd: ROOT, stdio: 'inherit', timeout: 120_000 });
29
29
 
30
30
  // ── 3. Copy shared dist ────────────────────────────────────────────
31
31
  console.log('[build] copying shared module into dist/_shared…');
@@ -70,4 +70,24 @@ walk(DIST, ['.js', '.d.ts'], rewriteFile);
70
70
  const cliEntry = path.join(DIST, 'cli', 'index.js');
71
71
  if (fs.existsSync(cliEntry)) fs.chmodSync(cliEntry, 0o755);
72
72
 
73
+ // ── 6. Build & copy web UI ──────────────────────────────────────────
74
+ const WEB_ROOT = path.resolve(ROOT, '..', 'gitnexus-web');
75
+ const WEB_DEST = path.join(DIST, '..', 'web');
76
+
77
+ if (fs.existsSync(path.join(WEB_ROOT, 'package.json'))) {
78
+ console.log('[build] building gitnexus-web…');
79
+ if (!fs.existsSync(path.join(WEB_ROOT, 'node_modules'))) {
80
+ console.log('[build] installing gitnexus-web dependencies…');
81
+ execSync('npm ci', { cwd: WEB_ROOT, stdio: 'inherit', timeout: 120_000 });
82
+ }
83
+ execSync('npm run build', { cwd: WEB_ROOT, stdio: 'inherit', timeout: 120_000 });
84
+
85
+ // Copy dist → gitnexus/web/ (shipped in the npm package)
86
+ fs.rmSync(WEB_DEST, { recursive: true, force: true });
87
+ fs.cpSync(path.join(WEB_ROOT, 'dist'), WEB_DEST, { recursive: true });
88
+ console.log('[build] copied web UI → gitnexus/web/');
89
+ } else {
90
+ console.log('[build] skipping web UI (gitnexus-web not found)');
91
+ }
92
+
73
93
  console.log(`[build] done — rewrote ${rewritten} files.`);