gitnexus 1.6.4-rc.99 → 1.6.4

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 (143) hide show
  1. package/dist/_shared/index.d.ts +8 -0
  2. package/dist/_shared/index.d.ts.map +1 -1
  3. package/dist/_shared/index.js +9 -0
  4. package/dist/_shared/index.js.map +1 -1
  5. package/dist/_shared/integrations/circuit-breaker.d.ts +183 -0
  6. package/dist/_shared/integrations/circuit-breaker.d.ts.map +1 -0
  7. package/dist/_shared/integrations/circuit-breaker.js +236 -0
  8. package/dist/_shared/integrations/circuit-breaker.js.map +1 -0
  9. package/dist/_shared/integrations/resilient-fetch.d.ts +99 -0
  10. package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -0
  11. package/dist/_shared/integrations/resilient-fetch.js +204 -0
  12. package/dist/_shared/integrations/resilient-fetch.js.map +1 -0
  13. package/dist/_shared/integrations/retry.d.ts +60 -0
  14. package/dist/_shared/integrations/retry.d.ts.map +1 -0
  15. package/dist/_shared/integrations/retry.js +67 -0
  16. package/dist/_shared/integrations/retry.js.map +1 -0
  17. package/dist/_shared/integrations/understand-quickly.d.ts +79 -0
  18. package/dist/_shared/integrations/understand-quickly.d.ts.map +1 -0
  19. package/dist/_shared/integrations/understand-quickly.js +139 -0
  20. package/dist/_shared/integrations/understand-quickly.js.map +1 -0
  21. package/dist/_shared/test-helpers.d.ts +13 -0
  22. package/dist/_shared/test-helpers.d.ts.map +1 -0
  23. package/dist/_shared/test-helpers.js +13 -0
  24. package/dist/_shared/test-helpers.js.map +1 -0
  25. package/dist/cli/index.js +9 -0
  26. package/dist/cli/publish.d.ts +29 -0
  27. package/dist/cli/publish.js +174 -0
  28. package/dist/config/ignore-service.js +2 -0
  29. package/dist/core/embeddings/hf-env.d.ts +9 -37
  30. package/dist/core/embeddings/hf-env.js +65 -83
  31. package/dist/core/embeddings/http-client.d.ts +6 -0
  32. package/dist/core/embeddings/http-client.js +22 -18
  33. package/dist/core/group/bridge-db.js +7 -6
  34. package/dist/core/group/config-parser.js +19 -1
  35. package/dist/core/group/extractors/include-extractor.d.ts +39 -0
  36. package/dist/core/group/extractors/include-extractor.js +565 -0
  37. package/dist/core/group/extractors/manifest-extractor.js +8 -0
  38. package/dist/core/group/extractors/thrift-extractor.js +8 -0
  39. package/dist/core/group/matching.js +2 -0
  40. package/dist/core/group/storage.js +8 -1
  41. package/dist/core/group/sync.js +33 -0
  42. package/dist/core/group/types.d.ts +2 -1
  43. package/dist/core/ingestion/call-processor.js +6 -4
  44. package/dist/core/ingestion/cpp-ue-preprocessor.d.ts +12 -0
  45. package/dist/core/ingestion/cpp-ue-preprocessor.js +260 -0
  46. package/dist/core/ingestion/heritage-processor.js +9 -4
  47. package/dist/core/ingestion/import-processor.js +3 -2
  48. package/dist/core/ingestion/language-provider.d.ts +32 -0
  49. package/dist/core/ingestion/languages/c-cpp.js +2 -0
  50. package/dist/core/ingestion/parsing-processor.js +4 -0
  51. package/dist/core/ingestion/workers/parse-worker.js +4 -0
  52. package/dist/core/wiki/llm-client.d.ts +16 -0
  53. package/dist/core/wiki/llm-client.js +101 -63
  54. package/dist/server/api.js +7 -2
  55. package/package.json +2 -2
  56. package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +16 -14
  57. package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +16 -14
  58. package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +16 -14
  59. package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +16 -14
  60. package/web/assets/{agent-Dl2d-mDi.js → agent-BpHQleHE.js} +17 -17
  61. package/web/assets/architecture-YZFGNWBL-S5CXDPWN-BUzkWgDl.js +1 -0
  62. package/web/assets/{architectureDiagram-EMZXCZ2Q-uiiIna83.js → architectureDiagram-EMZXCZ2Q-CXbzok1G.js} +3 -3
  63. package/web/assets/{blockDiagram-IGV67L2C-uBKdDzXA.js → blockDiagram-IGV67L2C-DA1QJ4ZB.js} +4 -4
  64. package/web/assets/{c4Diagram-DFAF54RM-DTxaX43T.js → c4Diagram-DFAF54RM-DeJV1rCn.js} +2 -2
  65. package/web/assets/{chunk-3GS5O3IE-BxKKu7d7.js → chunk-3GS5O3IE-B8hpnia8.js} +2 -2
  66. package/web/assets/{chunk-3YCYZ6SJ-BJZnGFjg.js → chunk-3YCYZ6SJ-B-BVu21C.js} +1 -1
  67. package/web/assets/{chunk-6NTNNK5N-CIL_eO2d.js → chunk-6NTNNK5N-DW-jYSDr.js} +1 -1
  68. package/web/assets/{chunk-A34GCYZU-Dv4Vkem9.js → chunk-A34GCYZU-BbZl-IKy.js} +1 -1
  69. package/web/assets/{chunk-DJ7UZH7F-Cskl-nb3.js → chunk-DJ7UZH7F-B5tMfF87.js} +1 -1
  70. package/web/assets/{chunk-DKKBVRCY-D3S2BD56.js → chunk-DKKBVRCY-Djm-6K_e.js} +2 -2
  71. package/web/assets/{chunk-DU5LTGQ6-B8Zh51LG.js → chunk-DU5LTGQ6-QPoynYcp.js} +1 -1
  72. package/web/assets/{chunk-FXACKDTF-Cb4xHVUz.js → chunk-FXACKDTF-jieSmbe2.js} +3 -3
  73. package/web/assets/chunk-H3VCZNTA-8EMHZ3SV.js +1 -0
  74. package/web/assets/chunk-HN6EAY2L-CgE_agsD.js +1 -0
  75. package/web/assets/{chunk-O5ABG6QK-V3sk7Bps.js → chunk-O5ABG6QK-DEZV1O19.js} +1 -1
  76. package/web/assets/{chunk-PK6DOVAG-FvG7aKfZ.js → chunk-PK6DOVAG-BXv0JnsJ.js} +3 -3
  77. package/web/assets/{chunk-RNJOYNJ4-BPANsy8V.js → chunk-RNJOYNJ4-BiBkF9dN.js} +1 -1
  78. package/web/assets/chunk-RWUO3TPN-DTWzAhQ1.js +1 -0
  79. package/web/assets/chunk-TBF5ZNIQ-BSl6s9lT.js +1 -0
  80. package/web/assets/{chunk-TYMNRAUI-BnMe6HfP.js → chunk-TYMNRAUI-D1NDLIMG.js} +1 -1
  81. package/web/assets/{chunk-W7ZLLLMY-BqZFKM5j.js → chunk-W7ZLLLMY-Bu-cdLzs.js} +1 -1
  82. package/web/assets/{chunk-WSB5WSVC-EKS7-Nnc.js → chunk-WSB5WSVC-Dor71SOz.js} +1 -1
  83. package/web/assets/{chunk-XGPFEOL4-BBab-enK.js → chunk-XGPFEOL4-CUonLRle.js} +1 -1
  84. package/web/assets/classDiagram-PPOCWD7C-Cdd6UdVv.js +1 -0
  85. package/web/assets/classDiagram-v2-23LJLIIU-DNhxY2Ib.js +1 -0
  86. package/web/assets/{cose-bilkent-PNC4W37J-DjEQkTZ4.js → cose-bilkent-PNC4W37J-DdZq7Qz_.js} +1 -1
  87. package/web/assets/dagre-E77IOHMT-Cfj_6e17.js +4 -0
  88. package/web/assets/{diagram-H7BISOXX-CMuISoJL.js → diagram-H7BISOXX-BNvpsrBv.js} +2 -2
  89. package/web/assets/{diagram-JC5VWROH-DHq_eoeM.js → diagram-JC5VWROH-Cn0rtDbJ.js} +1 -1
  90. package/web/assets/{diagram-LXUTUG65-C0NczIgW.js → diagram-LXUTUG65-CHfoVKNm.js} +2 -2
  91. package/web/assets/{diagram-WEHSV5V5-WsBnpSuc.js → diagram-WEHSV5V5-BLxHksnu.js} +1 -1
  92. package/web/assets/{erDiagram-GCSMX5X6-DxHFHFR6.js → erDiagram-GCSMX5X6-DfdN6iqF.js} +2 -2
  93. package/web/assets/flowDiagram-OTCZ4VVT-aAZw4c_M.js +162 -0
  94. package/web/assets/ganttDiagram-MUNLMDZQ-BEfC_7Or.js +292 -0
  95. package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-B6ZeRLP0.js +1 -0
  96. package/web/assets/gitGraphDiagram-3HKGZ4G3-CG0kC8Q5.js +106 -0
  97. package/web/assets/{index-DDcYO1IJ.js → index-3NUCUW2s.js} +119 -119
  98. package/web/assets/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +1 -0
  99. package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +2 -0
  100. package/web/assets/{ishikawaDiagram-YMYX4NHK-C-JI2Ih7.js → ishikawaDiagram-YMYX4NHK-BF8AtDaj.js} +2 -2
  101. package/web/assets/{journeyDiagram-SO5T7YLQ-IPX4h3iD.js → journeyDiagram-SO5T7YLQ-BW8oKa3N.js} +3 -3
  102. package/web/assets/{kanban-definition-LJHFXRCJ-B23LtshQ.js → kanban-definition-LJHFXRCJ-DzbOsR-2.js} +6 -6
  103. package/web/assets/{mindmap-definition-2EUWGEK5-DJKUsrCo.js → mindmap-definition-2EUWGEK5-BIXGQALq.js} +25 -25
  104. package/web/assets/packet-4T2RLAQJ-EV4IVRXR-Bs7ysNMU.js +1 -0
  105. package/web/assets/pie-ZZUOXDRM-N23DN5KN-Csi8nnbH.js +1 -0
  106. package/web/assets/{pieDiagram-3IATQBI2-Bj26KTKk.js → pieDiagram-3IATQBI2-QY-u7P6a.js} +3 -3
  107. package/web/assets/{quadrantDiagram-E256RVCF-VAk5oIRr.js → quadrantDiagram-E256RVCF-Di4aNiU8.js} +3 -3
  108. package/web/assets/radar-PYXPWWZC-P6TP7ZYP-DJlyXh2-.js +1 -0
  109. package/web/assets/{requirementDiagram-M5DCFWZL-CmlTJ_vQ.js → requirementDiagram-M5DCFWZL-CzUUrhQD.js} +4 -4
  110. package/web/assets/{sankeyDiagram-L3NBLAOT-C-f_DdcX.js → sankeyDiagram-L3NBLAOT-D2fbMiIU.js} +3 -3
  111. package/web/assets/{sequenceDiagram-ZOUHS735-DmtNf1NF.js → sequenceDiagram-ZOUHS735-BNdkqguh.js} +6 -6
  112. package/web/assets/stateDiagram-MLPALWAM-51_Q2w2L.js +1 -0
  113. package/web/assets/stateDiagram-v2-B5LQ5ZB2-8nHs2aNE.js +1 -0
  114. package/web/assets/{timeline-definition-5SPVSISX-BkpqZxt2.js → timeline-definition-5SPVSISX-DkMiGj4Z.js} +9 -9
  115. package/web/assets/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +1 -0
  116. package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +1 -0
  117. package/web/assets/{vennDiagram-IE5QUKF5-iAJ08JBe.js → vennDiagram-IE5QUKF5-BCxMmf9q.js} +3 -3
  118. package/web/assets/wardley-RL74JXVD-BCRCBASE-CMStJhpn.js +1 -0
  119. package/web/assets/{wardleyDiagram-XU3VSMPF-BDiKTkL4.js → wardleyDiagram-XU3VSMPF-ijlLF77s.js} +4 -4
  120. package/web/assets/{xychartDiagram-ZHJ5623Y-CknyZyQK.js → xychartDiagram-ZHJ5623Y-DZ7fP1_3.js} +3 -3
  121. package/web/index.html +1 -1
  122. package/web/assets/architecture-YZFGNWBL-S5CXDPWN-BYXnTu07.js +0 -1
  123. package/web/assets/chunk-H3VCZNTA-BOGhqvxW.js +0 -1
  124. package/web/assets/chunk-HN6EAY2L-CitKFy1e.js +0 -1
  125. package/web/assets/chunk-RWUO3TPN-BHusg2jI.js +0 -1
  126. package/web/assets/chunk-TBF5ZNIQ-CXamrpH3.js +0 -1
  127. package/web/assets/classDiagram-PPOCWD7C-B-LkKU0P.js +0 -1
  128. package/web/assets/classDiagram-v2-23LJLIIU-_NGI4VEh.js +0 -1
  129. package/web/assets/dagre-E77IOHMT-D6Xacg1x.js +0 -4
  130. package/web/assets/flowDiagram-OTCZ4VVT-_G1VxyQS.js +0 -162
  131. package/web/assets/ganttDiagram-MUNLMDZQ-BIHObj0t.js +0 -292
  132. package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-BXJXsixL.js +0 -1
  133. package/web/assets/gitGraphDiagram-3HKGZ4G3-COZUkHTD.js +0 -106
  134. package/web/assets/info-OMHHGYJF-BF2H5H6G-C820LK0J.js +0 -1
  135. package/web/assets/infoDiagram-MN7RKWGX-BeOjfPc_.js +0 -2
  136. package/web/assets/packet-4T2RLAQJ-EV4IVRXR-BvWtM5jq.js +0 -1
  137. package/web/assets/pie-ZZUOXDRM-N23DN5KN-BnDgj0TQ.js +0 -1
  138. package/web/assets/radar-PYXPWWZC-P6TP7ZYP-2IuDlZ6r.js +0 -1
  139. package/web/assets/stateDiagram-MLPALWAM-Lq7UVrkj.js +0 -1
  140. package/web/assets/stateDiagram-v2-B5LQ5ZB2-DCiXBPeS.js +0 -1
  141. package/web/assets/treeView-SZITEDCU-5DXDK3XO-Ipq1EIaF.js +0 -1
  142. package/web/assets/treemap-W4RFUUIX-WYLRDWKO-DESFxovu.js +0 -1
  143. package/web/assets/wardley-RL74JXVD-BCRCBASE-BVkhckBY.js +0 -1
@@ -1,4 +1,5 @@
1
1
  import { logger } from '../logger.js';
2
+ import { CircuitOpenError, ResilientFetchExhaustedError, resilientFetch } from '../../_shared/index.js';
2
3
  /**
3
4
  * Resolve LLM configuration from env vars, saved config, and optional overrides.
4
5
  * Priority: overrides (CLI flags) > env vars > ~/.gitnexus/config.json > error
@@ -37,6 +38,45 @@ export async function resolveLLMConfig(overrides) {
37
38
  export function estimateTokens(text) {
38
39
  return Math.ceil(text.length / 4);
39
40
  }
41
+ /**
42
+ * Validate that a base URL supplied for LLM API calls is a safe HTTP/HTTPS
43
+ * endpoint (CWE-918 / CodeQL js/http-to-file-access).
44
+ *
45
+ * Allowed:
46
+ * - https:// with any hostname (public LLM APIs, Azure, OpenRouter, …)
47
+ * - http:// restricted to localhost / 127.0.0.1 (local servers: Ollama, LiteLLM, …)
48
+ *
49
+ * Rejected:
50
+ * - file://, data:, javascript:, and any other non-HTTP scheme
51
+ * - http:// aimed at non-loopback hosts (avoids SSRF against internal networks)
52
+ *
53
+ * Throws with a descriptive message on validation failure so callers surface a
54
+ * clear error rather than an opaque network error.
55
+ */
56
+ export function validateLLMBaseUrl(baseUrl) {
57
+ let parsed;
58
+ try {
59
+ parsed = new URL(baseUrl);
60
+ }
61
+ catch {
62
+ // Do not include the raw input in the message — it may contain credentials.
63
+ throw new Error('Invalid LLM base URL: must be a well-formed http:// or https:// URL');
64
+ }
65
+ if (!['https:', 'http:'].includes(parsed.protocol)) {
66
+ // Use parsed.protocol only (scheme), not the full URL, to avoid leaking credentials.
67
+ throw new Error(`LLM base URL must use http:// or https:// (got ${parsed.protocol})`);
68
+ }
69
+ if (parsed.protocol === 'http:') {
70
+ // Node's URL parser preserves IPv6 brackets in hostname (e.g. "[::1]"),
71
+ // so strip them before comparing to bare address literals.
72
+ const host = parsed.hostname.toLowerCase().replace(/^\[|\]$/g, '');
73
+ if (host !== 'localhost' && host !== '127.0.0.1' && host !== '::1') {
74
+ // Use parsed.origin (scheme+host+port, no credentials) instead of the full URL.
75
+ throw new Error(`Insecure http:// LLM base URLs are only allowed for localhost/127.0.0.1. ` +
76
+ `Use https:// for remote endpoints (got ${parsed.origin})`);
77
+ }
78
+ }
79
+ }
40
80
  /**
41
81
  * Returns true if the given base URL is an Azure OpenAI endpoint.
42
82
  * Uses proper hostname matching to avoid spoofed URLs like
@@ -78,6 +118,8 @@ export function buildRequestUrl(baseUrl, apiVersion) {
78
118
  * Retries up to 3 times on transient failures (429, 5xx, network errors).
79
119
  */
80
120
  export async function callLLM(prompt, config, systemPrompt, options) {
121
+ // Validate base URL before any fetch (CodeQL js/http-to-file-access)
122
+ validateLLMBaseUrl(config.baseUrl);
81
123
  const messages = [];
82
124
  if (systemPrompt) {
83
125
  messages.push({ role: 'system', content: systemPrompt });
@@ -110,69 +152,68 @@ export async function callLLM(prompt, config, systemPrompt, options) {
110
152
  const authHeaders = azure
111
153
  ? { 'api-key': config.apiKey }
112
154
  : { Authorization: `Bearer ${config.apiKey}` };
113
- const MAX_RETRIES = 3;
114
- let lastError = null;
115
- for (let attempt = 0; attempt < MAX_RETRIES; attempt++) {
116
- try {
117
- const response = await fetch(url, {
118
- method: 'POST',
119
- headers: {
120
- 'Content-Type': 'application/json',
121
- ...authHeaders,
122
- },
123
- body: JSON.stringify(body),
124
- });
125
- if (!response.ok) {
126
- const errorText = await response.text().catch(() => 'unknown error');
127
- // Azure content filter — surface a clear message instead of a generic API error
128
- if (azure &&
129
- response.status === 400 &&
130
- (errorText.includes('content_filter') ||
131
- errorText.includes('ResponsibleAIPolicyViolation'))) {
132
- throw new Error(`Azure content filter blocked this request. The prompt triggered content policy. Details: ${errorText.slice(0, 300)}`);
133
- }
134
- // Rate limit — wait with exponential backoff and retry
135
- if (response.status === 429 && attempt < MAX_RETRIES - 1) {
136
- const retryAfter = parseInt(response.headers.get('retry-after') || '0', 10);
137
- const delay = retryAfter > 0 ? retryAfter * 1000 : 2 ** attempt * 3000;
138
- await sleep(delay);
139
- continue;
140
- }
141
- // Server error — retry with backoff
142
- if (response.status >= 500 && attempt < MAX_RETRIES - 1) {
143
- await sleep((attempt + 1) * 2000);
144
- continue;
145
- }
146
- throw new Error(`LLM API error (${response.status}): ${errorText.slice(0, 500)}`);
147
- }
148
- // Streaming path
149
- if (useStream && response.body) {
150
- return await readSSEStream(response.body, options.onChunk);
151
- }
152
- // Non-streaming path
153
- const json = (await response.json());
154
- const choice = json.choices?.[0];
155
- if (!choice?.message?.content) {
156
- throw new Error('LLM returned empty response');
157
- }
158
- return {
159
- content: choice.message.content,
160
- promptTokens: json.usage?.prompt_tokens,
161
- completionTokens: json.usage?.completion_tokens,
162
- };
155
+ // Network resilience (bounded retries with exponential-backoff jitter,
156
+ // 5xx + 429 + Retry-After handling, in-process circuit breaker on the
157
+ // LLM endpoint) is delegated to resilientFetch. Provider-specific
158
+ // error parsing (Azure content filter, empty-content checks) stays
159
+ // here since it requires response-body inspection.
160
+ let response;
161
+ try {
162
+ response = await resilientFetch(url, {
163
+ method: 'POST',
164
+ headers: {
165
+ 'Content-Type': 'application/json',
166
+ ...authHeaders,
167
+ },
168
+ body: JSON.stringify(body),
169
+ // Per-attempt timeout. Without this each retry can hang
170
+ // indefinitely on a frozen TCP connection — the per-call
171
+ // signal is the only timeout `resilientFetch` honors;
172
+ // `capDelayMs` only bounds the *backoff* between attempts.
173
+ // 60s matches typical LLM completion budgets.
174
+ signal: AbortSignal.timeout(60_000),
175
+ }, {
176
+ breakerKey: `wiki-llm-${new URL(url).host}`,
177
+ retry: { maxAttempts: 3, baseDelayMs: 2_000, capDelayMs: 30_000 },
178
+ });
179
+ }
180
+ catch (err) {
181
+ if (err instanceof CircuitOpenError) {
182
+ throw new Error(`LLM endpoint circuit open: retry in ${Math.ceil(err.retryAfterMs / 1000)}s. ${err.message}`);
163
183
  }
164
- catch (err) {
165
- lastError = err;
166
- // Network error — retry with backoff
167
- if (attempt < MAX_RETRIES - 1 &&
168
- (err.code === 'ECONNREFUSED' || err.code === 'ETIMEDOUT' || err.message?.includes('fetch'))) {
169
- await sleep((attempt + 1) * 3000);
170
- continue;
171
- }
172
- throw err;
184
+ if (err instanceof ResilientFetchExhaustedError) {
185
+ const errorText = await err.response.text().catch(() => 'unknown error');
186
+ throw new Error(`LLM API error (${err.response.status} after retries): ${errorText.slice(0, 500)}`);
187
+ }
188
+ throw err;
189
+ }
190
+ if (!response.ok) {
191
+ const errorText = await response.text().catch(() => 'unknown error');
192
+ // Azure content filter — surface a clear message instead of a generic API error.
193
+ if (azure &&
194
+ response.status === 400 &&
195
+ (errorText.includes('content_filter') || errorText.includes('ResponsibleAIPolicyViolation'))) {
196
+ throw new Error(`Azure content filter blocked this request. The prompt triggered content policy. Details: ${errorText.slice(0, 300)}`);
173
197
  }
198
+ // Any other non-OK response here is a terminal 4xx — resilientFetch
199
+ // already retried 5xx/429 to exhaustion and would have thrown above.
200
+ throw new Error(`LLM API error (${response.status}): ${errorText.slice(0, 500)}`);
201
+ }
202
+ // Streaming path
203
+ if (useStream && response.body) {
204
+ return await readSSEStream(response.body, options.onChunk);
174
205
  }
175
- throw lastError || new Error('LLM call failed after retries');
206
+ // Non-streaming path
207
+ const json = (await response.json());
208
+ const choice = json.choices?.[0];
209
+ if (!choice?.message?.content) {
210
+ throw new Error('LLM returned empty response');
211
+ }
212
+ return {
213
+ content: choice.message.content,
214
+ promptTokens: json.usage?.prompt_tokens,
215
+ completionTokens: json.usage?.completion_tokens,
216
+ };
176
217
  }
177
218
  /**
178
219
  * Read an SSE stream from an OpenAI-compatible streaming response.
@@ -224,6 +265,3 @@ async function readSSEStream(body, onChunk) {
224
265
  }
225
266
  return { content };
226
267
  }
227
- function sleep(ms) {
228
- return new Promise((resolve) => setTimeout(resolve, ms));
229
- }
@@ -638,7 +638,11 @@ export const createServer = async (port, host = '127.0.0.1') => {
638
638
  (job.repoPath && path.basename(job.repoPath).toLowerCase() === lower);
639
639
  if (isMatch && ['queued', 'cloning', 'analyzing'].includes(job.status)) {
640
640
  if (process.env.DEBUG) {
641
- console.log(`[debug] resolveRepo waiting for active job ${job.id} (${normalizedName})...`);
641
+ // Sanitize user-controlled values to prevent log injection (CodeQL js/log-injection).
642
+ logger.debug({
643
+ jobId: String(job.id).replace(/[\r\n]/g, ' '),
644
+ repoName: String(normalizedName).replace(/[\r\n]/g, ' '),
645
+ }, '[debug] resolveRepo waiting for active job');
642
646
  }
643
647
  for (let wait = 0; wait < HOLD_QUEUE_TIMEOUT_SECS; wait++) {
644
648
  if (clientGone)
@@ -662,7 +666,8 @@ export const createServer = async (port, host = '127.0.0.1') => {
662
666
  // (e.g. registry file not yet flushed after clone completes).
663
667
  if (!found && normalizedName && !isRetry) {
664
668
  if (process.env.DEBUG) {
665
- console.log(`[debug] resolveRepo 404 for "${normalizedName}". Triggering deep init...`);
669
+ // Sanitize user-controlled values to prevent log injection (CodeQL js/log-injection).
670
+ logger.debug({ repoName: String(normalizedName).replace(/[\r\n]/g, ' ') }, '[debug] resolveRepo 404, triggering deep init');
666
671
  }
667
672
  await backend.init();
668
673
  return await resolveRepo(normalizedName, true, req);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gitnexus",
3
- "version": "1.6.4-rc.99",
3
+ "version": "1.6.4",
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",
@@ -116,6 +116,6 @@
116
116
  }
117
117
  },
118
118
  "engines": {
119
- "node": ">=20.0.0"
119
+ "node": ">=22.0.0"
120
120
  }
121
121
  }
@@ -34,16 +34,17 @@ CFLAGS_C_Debug :=
34
34
  CFLAGS_CC_Debug := \
35
35
  -fno-rtti \
36
36
  -fno-exceptions \
37
+ -fno-strict-aliasing \
37
38
  -std=gnu++17
38
39
 
39
40
  INCS_Debug := \
40
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
41
- -I/home/runner/.cache/node-gyp/20.20.2/src \
42
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
43
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
44
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
45
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
46
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
41
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
42
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
43
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
44
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
45
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
46
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
47
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
47
48
 
48
49
  DEFS_Release := \
49
50
  '-DNODE_GYP_MODULE_NAME=node_addon_api' \
@@ -75,16 +76,17 @@ CFLAGS_C_Release :=
75
76
  CFLAGS_CC_Release := \
76
77
  -fno-rtti \
77
78
  -fno-exceptions \
79
+ -fno-strict-aliasing \
78
80
  -std=gnu++17
79
81
 
80
82
  INCS_Release := \
81
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
82
- -I/home/runner/.cache/node-gyp/20.20.2/src \
83
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
84
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
85
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
86
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
87
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
83
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
84
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
85
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
86
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
87
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
88
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
89
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
88
90
 
89
91
  OBJS :=
90
92
 
@@ -34,16 +34,17 @@ CFLAGS_C_Debug :=
34
34
  CFLAGS_CC_Debug := \
35
35
  -fno-rtti \
36
36
  -fno-exceptions \
37
+ -fno-strict-aliasing \
37
38
  -std=gnu++17
38
39
 
39
40
  INCS_Debug := \
40
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
41
- -I/home/runner/.cache/node-gyp/20.20.2/src \
42
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
43
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
44
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
45
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
46
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
41
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
42
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
43
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
44
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
45
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
46
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
47
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
47
48
 
48
49
  DEFS_Release := \
49
50
  '-DNODE_GYP_MODULE_NAME=node_addon_api_except' \
@@ -75,16 +76,17 @@ CFLAGS_C_Release :=
75
76
  CFLAGS_CC_Release := \
76
77
  -fno-rtti \
77
78
  -fno-exceptions \
79
+ -fno-strict-aliasing \
78
80
  -std=gnu++17
79
81
 
80
82
  INCS_Release := \
81
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
82
- -I/home/runner/.cache/node-gyp/20.20.2/src \
83
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
84
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
85
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
86
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
87
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
83
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
84
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
85
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
86
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
87
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
88
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
89
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
88
90
 
89
91
  OBJS :=
90
92
 
@@ -34,16 +34,17 @@ CFLAGS_C_Debug :=
34
34
  CFLAGS_CC_Debug := \
35
35
  -fno-rtti \
36
36
  -fno-exceptions \
37
+ -fno-strict-aliasing \
37
38
  -std=gnu++17
38
39
 
39
40
  INCS_Debug := \
40
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
41
- -I/home/runner/.cache/node-gyp/20.20.2/src \
42
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
43
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
44
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
45
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
46
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
41
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
42
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
43
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
44
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
45
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
46
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
47
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
47
48
 
48
49
  DEFS_Release := \
49
50
  '-DNODE_GYP_MODULE_NAME=node_addon_api_except_all' \
@@ -75,16 +76,17 @@ CFLAGS_C_Release :=
75
76
  CFLAGS_CC_Release := \
76
77
  -fno-rtti \
77
78
  -fno-exceptions \
79
+ -fno-strict-aliasing \
78
80
  -std=gnu++17
79
81
 
80
82
  INCS_Release := \
81
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
82
- -I/home/runner/.cache/node-gyp/20.20.2/src \
83
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
84
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
85
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
86
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
87
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
83
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
84
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
85
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
86
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
87
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
88
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
89
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
88
90
 
89
91
  OBJS :=
90
92
 
@@ -34,16 +34,17 @@ CFLAGS_C_Debug :=
34
34
  CFLAGS_CC_Debug := \
35
35
  -fno-rtti \
36
36
  -fno-exceptions \
37
+ -fno-strict-aliasing \
37
38
  -std=gnu++17
38
39
 
39
40
  INCS_Debug := \
40
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
41
- -I/home/runner/.cache/node-gyp/20.20.2/src \
42
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
43
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
44
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
45
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
46
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
41
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
42
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
43
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
44
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
45
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
46
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
47
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
47
48
 
48
49
  DEFS_Release := \
49
50
  '-DNODE_GYP_MODULE_NAME=node_addon_api_maybe' \
@@ -75,16 +76,17 @@ CFLAGS_C_Release :=
75
76
  CFLAGS_CC_Release := \
76
77
  -fno-rtti \
77
78
  -fno-exceptions \
79
+ -fno-strict-aliasing \
78
80
  -std=gnu++17
79
81
 
80
82
  INCS_Release := \
81
- -I/home/runner/.cache/node-gyp/20.20.2/include/node \
82
- -I/home/runner/.cache/node-gyp/20.20.2/src \
83
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/config \
84
- -I/home/runner/.cache/node-gyp/20.20.2/deps/openssl/openssl/include \
85
- -I/home/runner/.cache/node-gyp/20.20.2/deps/uv/include \
86
- -I/home/runner/.cache/node-gyp/20.20.2/deps/zlib \
87
- -I/home/runner/.cache/node-gyp/20.20.2/deps/v8/include
83
+ -I/home/runner/.cache/node-gyp/22.22.2/include/node \
84
+ -I/home/runner/.cache/node-gyp/22.22.2/src \
85
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/config \
86
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/openssl/openssl/include \
87
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/uv/include \
88
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/zlib \
89
+ -I/home/runner/.cache/node-gyp/22.22.2/deps/v8/include
88
90
 
89
91
  OBJS :=
90
92