@mcp-graph-workflow/mcp-graph 5.22.0 → 5.25.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 (225) hide show
  1. package/dist/api/routes/benchmark.d.ts.map +1 -1
  2. package/dist/api/routes/benchmark.js +22 -6
  3. package/dist/api/routes/benchmark.js.map +1 -1
  4. package/dist/api/routes/code-graph.d.ts.map +1 -1
  5. package/dist/api/routes/code-graph.js +2 -1
  6. package/dist/api/routes/code-graph.js.map +1 -1
  7. package/dist/api/routes/folder.d.ts +6 -0
  8. package/dist/api/routes/folder.d.ts.map +1 -1
  9. package/dist/api/routes/folder.js +53 -8
  10. package/dist/api/routes/folder.js.map +1 -1
  11. package/dist/api/routes/import.js +2 -1
  12. package/dist/api/routes/import.js.map +1 -1
  13. package/dist/api/routes/siebel.d.ts.map +1 -1
  14. package/dist/api/routes/siebel.js +4 -2
  15. package/dist/api/routes/siebel.js.map +1 -1
  16. package/dist/api/routes/skills.d.ts.map +1 -1
  17. package/dist/api/routes/skills.js +5 -2
  18. package/dist/api/routes/skills.js.map +1 -1
  19. package/dist/api/routes/translation.d.ts.map +1 -1
  20. package/dist/api/routes/translation.js +33 -9
  21. package/dist/api/routes/translation.js.map +1 -1
  22. package/dist/core/context/context-assembler.d.ts.map +1 -1
  23. package/dist/core/context/context-assembler.js +7 -0
  24. package/dist/core/context/context-assembler.js.map +1 -1
  25. package/dist/core/docs/docs-cache-store.js +1 -1
  26. package/dist/core/docs/docs-cache-store.js.map +1 -1
  27. package/dist/core/docs/stack-detector.js +6 -3
  28. package/dist/core/docs/stack-detector.js.map +1 -1
  29. package/dist/core/events/event-bus.d.ts +1 -1
  30. package/dist/core/events/event-bus.d.ts.map +1 -1
  31. package/dist/core/events/event-bus.js +13 -3
  32. package/dist/core/events/event-bus.js.map +1 -1
  33. package/dist/core/importer/prd-to-graph.d.ts.map +1 -1
  34. package/dist/core/importer/prd-to-graph.js +20 -5
  35. package/dist/core/importer/prd-to-graph.js.map +1 -1
  36. package/dist/core/integrations/integration-orchestrator.d.ts +1 -0
  37. package/dist/core/integrations/integration-orchestrator.d.ts.map +1 -1
  38. package/dist/core/integrations/integration-orchestrator.js +40 -19
  39. package/dist/core/integrations/integration-orchestrator.js.map +1 -1
  40. package/dist/core/knowledge/knowledge-packager.d.ts +44 -0
  41. package/dist/core/knowledge/knowledge-packager.d.ts.map +1 -0
  42. package/dist/core/knowledge/knowledge-packager.js +311 -0
  43. package/dist/core/knowledge/knowledge-packager.js.map +1 -0
  44. package/dist/core/parser/classify.js +2 -2
  45. package/dist/core/parser/classify.js.map +1 -1
  46. package/dist/core/parser/file-reader.d.ts.map +1 -1
  47. package/dist/core/parser/file-reader.js +9 -2
  48. package/dist/core/parser/file-reader.js.map +1 -1
  49. package/dist/core/parser/read-pdf.d.ts.map +1 -1
  50. package/dist/core/parser/read-pdf.js +5 -1
  51. package/dist/core/parser/read-pdf.js.map +1 -1
  52. package/dist/core/rag/knowledge-synthesizer.js +2 -2
  53. package/dist/core/rag/knowledge-synthesizer.js.map +1 -1
  54. package/dist/core/rag/node-indexer.d.ts.map +1 -1
  55. package/dist/core/rag/node-indexer.js +3 -2
  56. package/dist/core/rag/node-indexer.js.map +1 -1
  57. package/dist/core/store/migrations.d.ts.map +1 -1
  58. package/dist/core/store/migrations.js +10 -0
  59. package/dist/core/store/migrations.js.map +1 -1
  60. package/dist/core/store/sqlite-store.d.ts.map +1 -1
  61. package/dist/core/store/sqlite-store.js +39 -19
  62. package/dist/core/store/sqlite-store.js.map +1 -1
  63. package/dist/core/translation/chunked-analyzer.d.ts +36 -0
  64. package/dist/core/translation/chunked-analyzer.d.ts.map +1 -0
  65. package/dist/core/translation/chunked-analyzer.js +146 -0
  66. package/dist/core/translation/chunked-analyzer.js.map +1 -0
  67. package/dist/core/translation/confidence/ambiguity-detector.d.ts.map +1 -1
  68. package/dist/core/translation/confidence/ambiguity-detector.js +3 -1
  69. package/dist/core/translation/confidence/ambiguity-detector.js.map +1 -1
  70. package/dist/core/translation/language-detect.d.ts.map +1 -1
  71. package/dist/core/translation/language-detect.js +131 -0
  72. package/dist/core/translation/language-detect.js.map +1 -1
  73. package/dist/core/translation/memory/translation-memory.d.ts +14 -0
  74. package/dist/core/translation/memory/translation-memory.d.ts.map +1 -1
  75. package/dist/core/translation/memory/translation-memory.js +93 -0
  76. package/dist/core/translation/memory/translation-memory.js.map +1 -1
  77. package/dist/core/translation/parsers/cpp-parser-adapter.d.ts +9 -0
  78. package/dist/core/translation/parsers/cpp-parser-adapter.d.ts.map +1 -0
  79. package/dist/core/translation/parsers/cpp-parser-adapter.js +45 -0
  80. package/dist/core/translation/parsers/cpp-parser-adapter.js.map +1 -0
  81. package/dist/core/translation/parsers/csharp-parser-adapter.d.ts.map +1 -1
  82. package/dist/core/translation/parsers/csharp-parser-adapter.js +19 -22
  83. package/dist/core/translation/parsers/csharp-parser-adapter.js.map +1 -1
  84. package/dist/core/translation/parsers/dart-parser-adapter.d.ts +9 -0
  85. package/dist/core/translation/parsers/dart-parser-adapter.d.ts.map +1 -0
  86. package/dist/core/translation/parsers/dart-parser-adapter.js +44 -0
  87. package/dist/core/translation/parsers/dart-parser-adapter.js.map +1 -0
  88. package/dist/core/translation/parsers/elixir-parser-adapter.d.ts +9 -0
  89. package/dist/core/translation/parsers/elixir-parser-adapter.d.ts.map +1 -0
  90. package/dist/core/translation/parsers/elixir-parser-adapter.js +45 -0
  91. package/dist/core/translation/parsers/elixir-parser-adapter.js.map +1 -0
  92. package/dist/core/translation/parsers/go-parser-adapter.d.ts.map +1 -1
  93. package/dist/core/translation/parsers/go-parser-adapter.js +5 -2
  94. package/dist/core/translation/parsers/go-parser-adapter.js.map +1 -1
  95. package/dist/core/translation/parsers/haskell-parser-adapter.d.ts +9 -0
  96. package/dist/core/translation/parsers/haskell-parser-adapter.d.ts.map +1 -0
  97. package/dist/core/translation/parsers/haskell-parser-adapter.js +38 -0
  98. package/dist/core/translation/parsers/haskell-parser-adapter.js.map +1 -0
  99. package/dist/core/translation/parsers/java-parser-adapter.d.ts.map +1 -1
  100. package/dist/core/translation/parsers/java-parser-adapter.js +6 -1
  101. package/dist/core/translation/parsers/java-parser-adapter.js.map +1 -1
  102. package/dist/core/translation/parsers/kotlin-parser-adapter.d.ts +9 -0
  103. package/dist/core/translation/parsers/kotlin-parser-adapter.d.ts.map +1 -0
  104. package/dist/core/translation/parsers/kotlin-parser-adapter.js +43 -0
  105. package/dist/core/translation/parsers/kotlin-parser-adapter.js.map +1 -0
  106. package/dist/core/translation/parsers/lua-parser-adapter.d.ts +9 -0
  107. package/dist/core/translation/parsers/lua-parser-adapter.d.ts.map +1 -0
  108. package/dist/core/translation/parsers/lua-parser-adapter.js +42 -0
  109. package/dist/core/translation/parsers/lua-parser-adapter.js.map +1 -0
  110. package/dist/core/translation/parsers/php-parser-adapter.d.ts +9 -0
  111. package/dist/core/translation/parsers/php-parser-adapter.d.ts.map +1 -0
  112. package/dist/core/translation/parsers/php-parser-adapter.js +44 -0
  113. package/dist/core/translation/parsers/php-parser-adapter.js.map +1 -0
  114. package/dist/core/translation/parsers/rust-parser-adapter.js +1 -1
  115. package/dist/core/translation/parsers/scala-parser-adapter.d.ts +9 -0
  116. package/dist/core/translation/parsers/scala-parser-adapter.d.ts.map +1 -0
  117. package/dist/core/translation/parsers/scala-parser-adapter.js +43 -0
  118. package/dist/core/translation/parsers/scala-parser-adapter.js.map +1 -0
  119. package/dist/core/translation/parsers/swift-parser-adapter.d.ts +9 -0
  120. package/dist/core/translation/parsers/swift-parser-adapter.d.ts.map +1 -0
  121. package/dist/core/translation/parsers/swift-parser-adapter.js +44 -0
  122. package/dist/core/translation/parsers/swift-parser-adapter.js.map +1 -0
  123. package/dist/core/translation/pre-indexed-analyzer.d.ts +19 -0
  124. package/dist/core/translation/pre-indexed-analyzer.d.ts.map +1 -0
  125. package/dist/core/translation/pre-indexed-analyzer.js +100 -0
  126. package/dist/core/translation/pre-indexed-analyzer.js.map +1 -0
  127. package/dist/core/translation/prompt-builder.d.ts +2 -0
  128. package/dist/core/translation/prompt-builder.d.ts.map +1 -1
  129. package/dist/core/translation/prompt-builder.js +56 -8
  130. package/dist/core/translation/prompt-builder.js.map +1 -1
  131. package/dist/core/translation/prompt-paginator.d.ts +20 -0
  132. package/dist/core/translation/prompt-paginator.d.ts.map +1 -0
  133. package/dist/core/translation/prompt-paginator.js +108 -0
  134. package/dist/core/translation/prompt-paginator.js.map +1 -0
  135. package/dist/core/translation/translation-orchestrator.d.ts +9 -2
  136. package/dist/core/translation/translation-orchestrator.d.ts.map +1 -1
  137. package/dist/core/translation/translation-orchestrator.js +116 -16
  138. package/dist/core/translation/translation-orchestrator.js.map +1 -1
  139. package/dist/core/translation/translation-store.d.ts +6 -0
  140. package/dist/core/translation/translation-store.d.ts.map +1 -1
  141. package/dist/core/translation/translation-store.js +28 -0
  142. package/dist/core/translation/translation-store.js.map +1 -1
  143. package/dist/core/utils/circularity.d.ts +13 -0
  144. package/dist/core/utils/circularity.d.ts.map +1 -0
  145. package/dist/core/utils/circularity.js +30 -0
  146. package/dist/core/utils/circularity.js.map +1 -0
  147. package/dist/mcp/code-intelligence-wrapper.d.ts.map +1 -1
  148. package/dist/mcp/code-intelligence-wrapper.js +4 -2
  149. package/dist/mcp/code-intelligence-wrapper.js.map +1 -1
  150. package/dist/mcp/init-project.d.ts.map +1 -1
  151. package/dist/mcp/init-project.js +4 -2
  152. package/dist/mcp/init-project.js.map +1 -1
  153. package/dist/mcp/server.js +21 -4
  154. package/dist/mcp/server.js.map +1 -1
  155. package/dist/mcp/tool-classification.d.ts.map +1 -1
  156. package/dist/mcp/tool-classification.js +0 -1
  157. package/dist/mcp/tool-classification.js.map +1 -1
  158. package/dist/mcp/tools/analyze-translation.d.ts.map +1 -1
  159. package/dist/mcp/tools/analyze-translation.js +48 -8
  160. package/dist/mcp/tools/analyze-translation.js.map +1 -1
  161. package/dist/mcp/tools/clone-node.d.ts.map +1 -1
  162. package/dist/mcp/tools/clone-node.js +8 -3
  163. package/dist/mcp/tools/clone-node.js.map +1 -1
  164. package/dist/mcp/tools/edge.js +1 -1
  165. package/dist/mcp/tools/edge.js.map +1 -1
  166. package/dist/mcp/tools/import-graph.d.ts.map +1 -1
  167. package/dist/mcp/tools/import-graph.js +4 -2
  168. package/dist/mcp/tools/import-graph.js.map +1 -1
  169. package/dist/mcp/tools/index.d.ts.map +1 -1
  170. package/dist/mcp/tools/index.js +4 -0
  171. package/dist/mcp/tools/index.js.map +1 -1
  172. package/dist/mcp/tools/knowledge-export.d.ts +8 -0
  173. package/dist/mcp/tools/knowledge-export.d.ts.map +1 -0
  174. package/dist/mcp/tools/knowledge-export.js +100 -0
  175. package/dist/mcp/tools/knowledge-export.js.map +1 -0
  176. package/dist/mcp/tools/memory.d.ts.map +1 -1
  177. package/dist/mcp/tools/memory.js +1 -0
  178. package/dist/mcp/tools/memory.js.map +1 -1
  179. package/dist/mcp/tools/move-node.d.ts.map +1 -1
  180. package/dist/mcp/tools/move-node.js +4 -14
  181. package/dist/mcp/tools/move-node.js.map +1 -1
  182. package/dist/mcp/tools/node.d.ts.map +1 -1
  183. package/dist/mcp/tools/node.js +5 -16
  184. package/dist/mcp/tools/node.js.map +1 -1
  185. package/dist/mcp/tools/siebel-generate-sif.js +4 -2
  186. package/dist/mcp/tools/siebel-generate-sif.js.map +1 -1
  187. package/dist/mcp/tools/translate-code.d.ts.map +1 -1
  188. package/dist/mcp/tools/translate-code.js +54 -7
  189. package/dist/mcp/tools/translate-code.js.map +1 -1
  190. package/dist/mcp/tools/translation-jobs.d.ts +8 -0
  191. package/dist/mcp/tools/translation-jobs.d.ts.map +1 -0
  192. package/dist/mcp/tools/translation-jobs.js +100 -0
  193. package/dist/mcp/tools/translation-jobs.js.map +1 -0
  194. package/dist/schemas/knowledge-package.schema.d.ts +87 -0
  195. package/dist/schemas/knowledge-package.schema.d.ts.map +1 -0
  196. package/dist/schemas/knowledge-package.schema.js +48 -0
  197. package/dist/schemas/knowledge-package.schema.js.map +1 -0
  198. package/dist/web/dashboard/dist/assets/benchmark-tab-sjsZBd-4.js +1 -0
  199. package/dist/web/dashboard/dist/assets/{circle-alert-vaRHjxbG.js → circle-alert-DcTbCUEa.js} +1 -1
  200. package/dist/web/dashboard/dist/assets/{context-tab-DRUGmBRL.js → context-tab-DNMJ2Pv-.js} +1 -1
  201. package/dist/web/dashboard/dist/assets/{gitnexus-tab-h8BwIua3.js → gitnexus-tab-CZ9LJbwz.js} +1 -1
  202. package/dist/web/dashboard/dist/assets/{graph-section-C4ymXtzh.js → graph-section-BdcXKKoS.js} +1 -1
  203. package/dist/web/dashboard/dist/assets/{graph-tab-C6nWMQkR.js → graph-tab-CFzux3kf.js} +1 -1
  204. package/dist/web/dashboard/dist/assets/{graph-utils-DkRXfigF.js → graph-utils-_8jpWA5z.js} +1 -1
  205. package/dist/web/dashboard/dist/assets/{index-DmT4Jne7.js → index-Bny20bel.js} +1 -1
  206. package/dist/web/dashboard/dist/assets/index-CITYTuX5.js +218 -0
  207. package/dist/web/dashboard/dist/assets/{index-BW0cq1-5.js → index-DSI2SYWO.js} +1 -1
  208. package/dist/web/dashboard/dist/assets/{insights-tab-CL9LCuow.js → insights-tab-DUA76KUY.js} +2 -2
  209. package/dist/web/dashboard/dist/assets/{journey-tab-CbJSfdpz.js → journey-tab-FTd6jBta.js} +1 -1
  210. package/dist/web/dashboard/dist/assets/{languages-tab-Vjkz6r99.js → languages-tab-B_nhFL2q.js} +1 -1
  211. package/dist/web/dashboard/dist/assets/{loader-circle-CrUmRfZB.js → loader-circle-D1DpGd2u.js} +1 -1
  212. package/dist/web/dashboard/dist/assets/{logs-tab-CeH_wY9u.js → logs-tab-CzL36_Qy.js} +1 -1
  213. package/dist/web/dashboard/dist/assets/{lsp-tab-BLIpJrAk.js → lsp-tab-DdHhJq_H.js} +1 -1
  214. package/dist/web/dashboard/dist/assets/memories-tab-CzgCahnV.js +1 -0
  215. package/dist/web/dashboard/dist/assets/{prd-backlog-tab-BBUG4V7M.js → prd-backlog-tab-C8Cl7swI.js} +1 -1
  216. package/dist/web/dashboard/dist/assets/{refresh-cw-DRsAUgYq.js → refresh-cw-DSYiHmbh.js} +1 -1
  217. package/dist/web/dashboard/dist/assets/{siebel-tab-DZXhcoUu.js → siebel-tab-B4XOaUGz.js} +3 -3
  218. package/dist/web/dashboard/dist/assets/{skills-tab-_A8OYt_b.js → skills-tab-CkpnwPJY.js} +1 -1
  219. package/dist/web/dashboard/dist/assets/{style-DpBYmOVU.js → style-BOQDk6qp.js} +1 -1
  220. package/dist/web/dashboard/dist/assets/{triangle-alert-N0TixBQV.js → triangle-alert-Bf6Ly19h.js} +1 -1
  221. package/dist/web/dashboard/dist/index.html +1 -1
  222. package/package.json +2 -2
  223. package/dist/web/dashboard/dist/assets/benchmark-tab-D7nae4k4.js +0 -1
  224. package/dist/web/dashboard/dist/assets/index-DSPPavjF.js +0 -218
  225. package/dist/web/dashboard/dist/assets/memories-tab-BHOvEW0o.js +0 -1
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Pre-indexed Analysis — leverages Code Intelligence symbol table
3
+ * to provide instant translation analysis for already-indexed files.
4
+ *
5
+ * Maps code intelligence symbol kinds to UCR constructs:
6
+ * function → uc_fn_def, class → uc_class_def, interface → uc_interface, etc.
7
+ */
8
+ import { logger } from "../utils/logger.js";
9
+ /** Map Code Intelligence symbol kind → UCR construct ID */
10
+ const KIND_TO_CONSTRUCT = {
11
+ function: "uc_fn_def",
12
+ method: "uc_fn_def",
13
+ class: "uc_class_def",
14
+ interface: "uc_interface",
15
+ enum: "uc_type_enum",
16
+ variable: "uc_var_const",
17
+ type: "uc_type_alias",
18
+ property: "uc_fn_def",
19
+ };
20
+ /** File extension → detected language */
21
+ const EXT_TO_LANGUAGE = {
22
+ ".ts": "typescript",
23
+ ".tsx": "typescript",
24
+ ".js": "javascript",
25
+ ".jsx": "javascript",
26
+ ".py": "python",
27
+ ".java": "java",
28
+ ".go": "go",
29
+ ".rs": "rust",
30
+ ".cs": "csharp",
31
+ ".rb": "ruby",
32
+ ".php": "php",
33
+ ".swift": "swift",
34
+ ".kt": "kotlin",
35
+ ".scala": "scala",
36
+ ".lua": "lua",
37
+ ".cpp": "cpp",
38
+ ".cc": "cpp",
39
+ ".c": "c",
40
+ ".dart": "dart",
41
+ };
42
+ /**
43
+ * Try to build a TranslationAnalysis from the Code Intelligence index.
44
+ * Returns null if the file is not indexed or the index is stale.
45
+ */
46
+ export function analyzeFromIndex(codeStore, projectId, filePath) {
47
+ try {
48
+ const meta = codeStore.getIndexMeta(projectId);
49
+ if (!meta)
50
+ return null;
51
+ // Get symbols for this specific file
52
+ const allSymbols = codeStore.getAllSymbols(projectId, 10000);
53
+ const fileSymbols = allSymbols.filter((s) => s.file === filePath);
54
+ if (fileSymbols.length === 0)
55
+ return null;
56
+ // Detect language from file extension
57
+ const parts = filePath.split(".");
58
+ const ext = parts.length > 1 ? "." + parts[parts.length - 1].toLowerCase() : "";
59
+ const detectedLanguage = EXT_TO_LANGUAGE[ext] ?? "unknown";
60
+ // Map symbols to constructs
61
+ const constructCounts = new Map();
62
+ for (const sym of fileSymbols) {
63
+ const constructId = KIND_TO_CONSTRUCT[sym.kind];
64
+ if (constructId) {
65
+ constructCounts.set(constructId, (constructCounts.get(constructId) ?? 0) + 1);
66
+ }
67
+ }
68
+ const constructs = Array.from(constructCounts.entries()).map(([canonicalName, count]) => ({
69
+ canonicalName,
70
+ count,
71
+ confidence: 0.9, // slightly lower than direct parsing since we're mapping kinds
72
+ }));
73
+ const totalConstructs = constructs.reduce((sum, c) => sum + c.count, 0);
74
+ const uniqueConstructs = constructs.length;
75
+ const complexityScore = Math.min(uniqueConstructs / 15, 1);
76
+ const analysis = {
77
+ detectedLanguage,
78
+ detectedConfidence: 1.0, // file extension is definitive
79
+ constructs,
80
+ complexityScore,
81
+ estimatedTranslatability: totalConstructs > 0 ? 0.95 : 0,
82
+ ambiguousConstructs: [],
83
+ totalConstructs,
84
+ };
85
+ logger.debug("pre-indexed-analysis", {
86
+ file: filePath,
87
+ language: detectedLanguage,
88
+ symbols: fileSymbols.length,
89
+ constructs: totalConstructs,
90
+ });
91
+ return { analysis, fromIndex: true };
92
+ }
93
+ catch (err) {
94
+ logger.debug("pre-indexed-analysis:failed", {
95
+ error: err instanceof Error ? err.message : String(err),
96
+ });
97
+ return null;
98
+ }
99
+ }
100
+ //# sourceMappingURL=pre-indexed-analyzer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pre-indexed-analyzer.js","sourceRoot":"","sources":["../../../src/core/translation/pre-indexed-analyzer.ts"],"names":[],"mappings":"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"}
@@ -14,6 +14,8 @@ export interface PromptContext {
14
14
  sourceCode: string;
15
15
  scores: TranslationScore[];
16
16
  ambiguities: AmbiguityReport[];
17
+ /** Max prompt token budget (default: 8000). */
18
+ maxPromptTokens?: number;
17
19
  }
18
20
  /**
19
21
  * Build a mapping prompt — asks the LLM to analyze constructs and choose mappings.
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../../src/core/translation/prompt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAElF,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,WAAW,EAAE,eAAe,EAAE,CAAC;CAChC;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAmC7D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAkDjE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAkBR;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAuBR"}
1
+ {"version":3,"file":"prompt-builder.d.ts","sourceRoot":"","sources":["../../../src/core/translation/prompt-builder.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AASlF,MAAM,WAAW,aAAa;IAC5B,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,EAAE,gBAAgB,EAAE,CAAC;IAC3B,WAAW,EAAE,eAAe,EAAE,CAAC;IAC/B,+CAA+C;IAC/C,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAmC7D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,aAAa,GAAG,MAAM,CAiGjE;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAkBR;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,aAAa,EAClB,UAAU,EAAE,MAAM,EAClB,MAAM,EAAE,MAAM,EAAE,GACf,MAAM,CAuBR"}
@@ -7,6 +7,11 @@
7
7
  * - syntactic repair: fix syntax errors in generated code
8
8
  * - semantic repair: fix semantic issues preserving meaning
9
9
  */
10
+ import { estimateTokens } from "../context/token-estimator.js";
11
+ /** Default max prompt token budget (~32KB). */
12
+ const DEFAULT_MAX_PROMPT_TOKENS = 8000;
13
+ /** Max constructs to show in the table when truncating. */
14
+ const MAX_CONSTRUCTS_ON_TRUNCATE = 20;
10
15
  /**
11
16
  * Build a mapping prompt — asks the LLM to analyze constructs and choose mappings.
12
17
  */
@@ -24,7 +29,7 @@ export function buildMappingPrompt(ctx) {
24
29
  if (ctx.ambiguities.length > 0) {
25
30
  sections.push(``, `### Ambiguities Requiring Decision`, ``);
26
31
  for (const amb of ctx.ambiguities) {
27
- sections.push(`- **${amb.canonicalName}** (${amb.ambiguityType}): ${amb.candidates.length} candidates`);
32
+ sections.push(`- **${amb.canonicalName ?? amb.constructId}** (${amb.ambiguityType}): ${amb.candidates.length} candidates`);
28
33
  for (const c of amb.candidates) {
29
34
  sections.push(` - ${c.tradeoff} (confidence: ${c.confidence})`);
30
35
  }
@@ -40,25 +45,39 @@ export function buildMappingPrompt(ctx) {
40
45
  * Build a full translation prompt — asks the LLM to translate the code.
41
46
  */
42
47
  export function buildTranslationPrompt(ctx) {
43
- const deterministicCount = ctx.scores.filter((s) => !s.needsAiAssist).length;
44
- const aiAssistCount = ctx.scores.filter((s) => s.needsAiAssist).length;
48
+ const maxTokens = ctx.maxPromptTokens ?? DEFAULT_MAX_PROMPT_TOKENS;
49
+ let truncated = false;
50
+ // Possibly truncate scores to top N by count (we don't have count here, so limit by total)
51
+ let effectiveScores = ctx.scores;
52
+ if (effectiveScores.length > MAX_CONSTRUCTS_ON_TRUNCATE) {
53
+ // Sort by finalConfidence desc, keep top N
54
+ effectiveScores = [...effectiveScores]
55
+ .sort((a, b) => b.finalConfidence - a.finalConfidence)
56
+ .slice(0, MAX_CONSTRUCTS_ON_TRUNCATE);
57
+ truncated = true;
58
+ }
59
+ const deterministicCount = effectiveScores.filter((s) => !s.needsAiAssist).length;
60
+ const aiAssistCount = effectiveScores.filter((s) => s.needsAiAssist).length;
61
+ // Possibly truncate source code to fit budget
62
+ let sourceBlock = ctx.sourceCode;
63
+ const sourceLines = ctx.sourceCode.split("\n");
45
64
  const sections = [
46
65
  `## Code Translation: ${ctx.sourceLanguage} → ${ctx.targetLanguage}`,
47
66
  ``,
48
67
  `### Source Code`,
49
68
  "```" + ctx.sourceLanguage,
50
- ctx.sourceCode,
69
+ sourceBlock,
51
70
  "```",
52
71
  ``,
53
72
  `### Construct Analysis`,
54
73
  `- **Deterministic mappings**: ${deterministicCount} (high confidence, direct translation)`,
55
74
  `- **AI-assisted mappings**: ${aiAssistCount} (require judgment)`,
56
75
  ``,
57
- formatScoresTable(ctx.scores),
76
+ formatScoresTable(effectiveScores),
58
77
  ];
59
78
  if (aiAssistCount > 0) {
60
79
  sections.push(``, `### Constructs Requiring AI Judgment`);
61
- for (const score of ctx.scores.filter((s) => s.needsAiAssist)) {
80
+ for (const score of effectiveScores.filter((s) => s.needsAiAssist)) {
62
81
  sections.push(`- **${score.constructId}** (confidence: ${score.finalConfidence.toFixed(2)})`);
63
82
  if (score.alternatives.length > 0) {
64
83
  for (const alt of score.alternatives) {
@@ -70,11 +89,40 @@ export function buildTranslationPrompt(ctx) {
70
89
  if (ctx.ambiguities.length > 0) {
71
90
  sections.push(``, `### Ambiguity Warnings`);
72
91
  for (const amb of ctx.ambiguities) {
73
- sections.push(`- **${amb.canonicalName}**: ${amb.ambiguityType} — ${amb.recommendation ?? "review needed"}`);
92
+ const name = amb.canonicalName ?? amb.constructId;
93
+ sections.push(`- **${name}**: ${amb.ambiguityType} — ${amb.recommendation ?? "review needed"}`);
74
94
  }
75
95
  }
76
96
  sections.push(``, `### Instructions`, `Translate the source code to ${ctx.targetLanguage}.`, `Use the construct mappings above. For AI-assisted constructs, choose the best mapping.`, `Preserve semantics, follow ${ctx.targetLanguage} conventions (naming, idioms).`, `Return ONLY the translated code.`);
77
- return sections.join("\n");
97
+ // Check token budget — if over, truncate source code block
98
+ let result = sections.join("\n");
99
+ if (estimateTokens(result) > maxTokens) {
100
+ // Binary search for max lines that fit within budget
101
+ let lo = 1;
102
+ let hi = sourceLines.length;
103
+ while (lo < hi) {
104
+ const mid = Math.ceil((lo + hi) / 2);
105
+ const candidate = sourceLines.slice(0, mid).join("\n")
106
+ + `\n... [truncated — showing first ${mid} lines of ${sourceLines.length} total]`;
107
+ sections[4] = candidate; // replace source code block content
108
+ const candidateResult = sections.join("\n");
109
+ if (estimateTokens(candidateResult) <= maxTokens) {
110
+ lo = mid;
111
+ }
112
+ else {
113
+ hi = mid - 1;
114
+ }
115
+ }
116
+ sourceBlock = sourceLines.slice(0, lo).join("\n")
117
+ + `\n... [truncated — showing first ${lo} lines of ${sourceLines.length} total]`;
118
+ sections[4] = sourceBlock;
119
+ truncated = true;
120
+ result = sections.join("\n");
121
+ }
122
+ if (truncated) {
123
+ result += `\n<!-- truncated: true -->`;
124
+ }
125
+ return result;
78
126
  }
79
127
  /**
80
128
  * Build a syntactic repair prompt — fix syntax errors in generated code.
@@ -1 +1 @@
1
- {"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../../src/core/translation/prompt-builder.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"prompt-builder.js","sourceRoot":"","sources":["../../../src/core/translation/prompt-builder.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Prompt Paginator — splits large translation prompts into numbered pages.
3
+ *
4
+ * When a prompt exceeds the token budget (default 8K tokens), it splits
5
+ * at natural boundaries (code sections) and returns paginated results.
6
+ * Each page is self-contained with construct context header.
7
+ */
8
+ export interface PromptPage {
9
+ content: string;
10
+ currentPage: number;
11
+ totalPages: number;
12
+ tokenEstimate: number;
13
+ truncated: boolean;
14
+ }
15
+ /**
16
+ * Paginate a prompt if it exceeds the token budget.
17
+ * Returns a single page if within budget (no pagination needed).
18
+ */
19
+ export declare function paginatePrompt(prompt: string, pageTokenBudget?: number, requestedPage?: number): PromptPage;
20
+ //# sourceMappingURL=prompt-paginator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-paginator.d.ts","sourceRoot":"","sources":["../../../src/core/translation/prompt-paginator.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAOH,MAAM,WAAW,UAAU;IACzB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,OAAO,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAC5B,MAAM,EAAE,MAAM,EACd,eAAe,GAAE,MAAkC,EACnD,aAAa,GAAE,MAAU,GACxB,UAAU,CAoCZ"}
@@ -0,0 +1,108 @@
1
+ /**
2
+ * Prompt Paginator — splits large translation prompts into numbered pages.
3
+ *
4
+ * When a prompt exceeds the token budget (default 8K tokens), it splits
5
+ * at natural boundaries (code sections) and returns paginated results.
6
+ * Each page is self-contained with construct context header.
7
+ */
8
+ import { estimateTokens } from "../context/token-estimator.js";
9
+ import { logger } from "../utils/logger.js";
10
+ const DEFAULT_PAGE_TOKEN_BUDGET = 8000;
11
+ /**
12
+ * Paginate a prompt if it exceeds the token budget.
13
+ * Returns a single page if within budget (no pagination needed).
14
+ */
15
+ export function paginatePrompt(prompt, pageTokenBudget = DEFAULT_PAGE_TOKEN_BUDGET, requestedPage = 1) {
16
+ const totalTokens = estimateTokens(prompt);
17
+ // If within budget, return as single page
18
+ if (totalTokens <= pageTokenBudget) {
19
+ return {
20
+ content: prompt,
21
+ currentPage: 1,
22
+ totalPages: 1,
23
+ tokenEstimate: totalTokens,
24
+ truncated: false,
25
+ };
26
+ }
27
+ // Split prompt into sections at markdown headers or code block boundaries
28
+ const sections = splitPromptSections(prompt);
29
+ const pages = buildPages(sections, pageTokenBudget);
30
+ const totalPages = pages.length;
31
+ const pageIndex = Math.max(0, Math.min(requestedPage - 1, totalPages - 1));
32
+ const page = pages[pageIndex];
33
+ logger.debug("prompt:paginated", {
34
+ totalTokens,
35
+ totalPages,
36
+ requestedPage,
37
+ pageTokens: estimateTokens(page),
38
+ });
39
+ return {
40
+ content: page,
41
+ currentPage: pageIndex + 1,
42
+ totalPages,
43
+ tokenEstimate: estimateTokens(page),
44
+ truncated: true,
45
+ };
46
+ }
47
+ /**
48
+ * Split a prompt into logical sections (headers, code blocks, tables).
49
+ */
50
+ function splitPromptSections(prompt) {
51
+ const sections = [];
52
+ const lines = prompt.split("\n");
53
+ let current = [];
54
+ for (const line of lines) {
55
+ // Split at markdown headers (##, ###)
56
+ if (/^#{2,3}\s/.test(line) && current.length > 0) {
57
+ sections.push(current.join("\n"));
58
+ current = [];
59
+ }
60
+ current.push(line);
61
+ }
62
+ if (current.length > 0) {
63
+ sections.push(current.join("\n"));
64
+ }
65
+ return sections;
66
+ }
67
+ /**
68
+ * Build pages from sections, respecting token budget per page.
69
+ * First section (header/metadata) is included in every page.
70
+ */
71
+ function buildPages(sections, pageTokenBudget) {
72
+ if (sections.length === 0)
73
+ return [""];
74
+ if (sections.length === 1)
75
+ return [sections[0]];
76
+ const header = sections[0]; // Always include first section as context
77
+ const headerTokens = estimateTokens(header);
78
+ const availablePerPage = pageTokenBudget - headerTokens - 100; // 100 tokens for pagination metadata
79
+ const pages = [];
80
+ let currentPageSections = [];
81
+ let currentTokens = 0;
82
+ for (let i = 1; i < sections.length; i++) {
83
+ const sectionTokens = estimateTokens(sections[i]);
84
+ if (currentTokens + sectionTokens > availablePerPage && currentPageSections.length > 0) {
85
+ // Flush current page
86
+ const pageNum = pages.length + 1;
87
+ const pageHeader = `${header}\n\n_Page ${pageNum} of translation prompt_\n`;
88
+ pages.push(pageHeader + currentPageSections.join("\n\n"));
89
+ currentPageSections = [];
90
+ currentTokens = 0;
91
+ }
92
+ currentPageSections.push(sections[i]);
93
+ currentTokens += sectionTokens;
94
+ }
95
+ // Flush remaining
96
+ if (currentPageSections.length > 0) {
97
+ const pageNum = pages.length + 1;
98
+ const pageHeader = `${header}\n\n_Page ${pageNum} of translation prompt_\n`;
99
+ pages.push(pageHeader + currentPageSections.join("\n\n"));
100
+ }
101
+ // If everything fit in one page, return as-is
102
+ if (pages.length === 0) {
103
+ return [sections.join("\n\n")];
104
+ }
105
+ // Update total pages count in each page
106
+ return pages.map((p) => p.replace(/Page (\d+) of translation prompt/, `Page $1 of ${pages.length} — translation prompt`));
107
+ }
108
+ //# sourceMappingURL=prompt-paginator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"prompt-paginator.js","sourceRoot":"","sources":["../../../src/core/translation/prompt-paginator.ts"],"names":[],"mappings":"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"}
@@ -5,6 +5,7 @@
5
5
  */
6
6
  import { ConstructRegistry } from "./ucr/construct-registry.js";
7
7
  import { TranslationStore } from "./translation-store.js";
8
+ import type { CodeStore } from "../code/code-store.js";
8
9
  import type { TranslationAnalysis, TranslationScope } from "./translation-types.js";
9
10
  interface AnalyzeHints {
10
11
  languageHint?: string;
@@ -49,11 +50,17 @@ interface FinalizeResult {
49
50
  export declare class TranslationOrchestrator {
50
51
  private readonly registry;
51
52
  private readonly store;
52
- constructor(registry: ConstructRegistry, store: TranslationStore);
53
+ private readonly codeStore?;
54
+ constructor(registry: ConstructRegistry, store: TranslationStore, codeStore?: CodeStore | undefined);
53
55
  /**
54
56
  * Analyze source code — detect language, identify constructs, compute complexity.
57
+ * Results are cached with SHA-256 content hash (TTL 60min, max 100 entries).
58
+ * When filePath + projectId are provided and Code Intelligence has indexed the file,
59
+ * uses pre-indexed analysis (instant, zero parsing cost).
55
60
  */
56
- analyzeSource(code: string, hints?: AnalyzeHints): TranslationAnalysis;
61
+ analyzeSource(code: string, hints?: AnalyzeHints, filePath?: string, projectId?: string): TranslationAnalysis & {
62
+ cacheHit: boolean;
63
+ };
57
64
  /**
58
65
  * Prepare a translation job — creates the job, analyzes source, builds prompt.
59
66
  */
@@ -1 +1 @@
1
- {"version":3,"file":"translation-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/core/translation/translation-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,mBAAmB,EAAkB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAYpG,UAAU,YAAY;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,KAAK,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,UAAU,cAAc;IACtB,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,QAAQ,EAAE,YAAY,CAAC;CACxB;AAOD,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;gBADL,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,gBAAgB;IAG1C;;OAEG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,GAAG,mBAAmB;IA8DtE;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa;IAyCtD;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc;CAkD1E"}
1
+ {"version":3,"file":"translation-orchestrator.d.ts","sourceRoot":"","sources":["../../../src/core/translation/translation-orchestrator.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAGH,OAAO,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChE,OAAO,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEvD,OAAO,KAAK,EAAE,mBAAmB,EAAkB,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAqEpG,UAAU,YAAY;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,UAAU,YAAY;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,cAAc,EAAE,MAAM,CAAC;IACvB,KAAK,EAAE,gBAAgB,CAAC;CACzB;AAED,UAAU,aAAa;IACrB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,mBAAmB,CAAC;CAC/B;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,oBAAoB,EAAE,KAAK,CAAC;QAAE,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAChF,KAAK,EAAE,KAAK,CAAC;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACvE,eAAe,EAAE,MAAM,CAAC;IACxB,iBAAiB,EAAE,MAAM,EAAE,CAAC;CAC7B;AAED,UAAU,cAAc;IACtB,GAAG,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,UAAU,CAAC,EAAE,MAAM,CAAC;QAAC,eAAe,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IACnF,QAAQ,EAAE,YAAY,CAAC;CACxB;AAqBD,qBAAa,uBAAuB;IAEhC,OAAO,CAAC,QAAQ,CAAC,QAAQ;IACzB,OAAO,CAAC,QAAQ,CAAC,KAAK;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;gBAFV,QAAQ,EAAE,iBAAiB,EAC3B,KAAK,EAAE,gBAAgB,EACvB,SAAS,CAAC,EAAE,SAAS,YAAA;IAGxC;;;;;OAKG;IACH,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,YAAY,EAAE,QAAQ,CAAC,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,mBAAmB,GAAG;QAAE,QAAQ,EAAE,OAAO,CAAA;KAAE;IAqFrI;;OAEG;IACH,kBAAkB,CAAC,KAAK,EAAE,YAAY,GAAG,aAAa;IA+CtD;;OAEG;IACH,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,cAAc;CAkD1E"}
@@ -3,28 +3,111 @@
3
3
  *
4
4
  * Flow: analyzeSource → prepareTranslation → (AI generates code) → finalizeTranslation
5
5
  */
6
+ import { createHash } from "node:crypto";
7
+ import { analyzeFromIndex } from "./pre-indexed-analyzer.js";
6
8
  import { detectLanguageFromCode } from "./language-detect.js";
7
9
  import { TsParserAdapter } from "./parsers/ts-parser-adapter.js";
8
10
  import { PythonParserAdapter } from "./parsers/python-parser-adapter.js";
11
+ import { JavaParserAdapter } from "./parsers/java-parser-adapter.js";
12
+ import { GoParserAdapter } from "./parsers/go-parser-adapter.js";
13
+ import { CSharpParserAdapter } from "./parsers/csharp-parser-adapter.js";
14
+ import { RustParserAdapter } from "./parsers/rust-parser-adapter.js";
15
+ import { RubyParserAdapter } from "./parsers/ruby-parser-adapter.js";
16
+ import { PhpParserAdapter } from "./parsers/php-parser-adapter.js";
17
+ import { SwiftParserAdapter } from "./parsers/swift-parser-adapter.js";
18
+ import { KotlinParserAdapter } from "./parsers/kotlin-parser-adapter.js";
19
+ import { ScalaParserAdapter } from "./parsers/scala-parser-adapter.js";
20
+ import { ElixirParserAdapter } from "./parsers/elixir-parser-adapter.js";
21
+ import { DartParserAdapter } from "./parsers/dart-parser-adapter.js";
22
+ import { HaskellParserAdapter } from "./parsers/haskell-parser-adapter.js";
23
+ import { CppParserAdapter } from "./parsers/cpp-parser-adapter.js";
24
+ import { LuaParserAdapter } from "./parsers/lua-parser-adapter.js";
9
25
  import { scoreConstructs } from "./confidence/equivalence-scorer.js";
10
26
  import { detectAmbiguities } from "./confidence/ambiguity-detector.js";
11
27
  import { buildTranslationPrompt } from "./prompt-builder.js";
12
28
  import { TranslationError } from "../utils/errors.js";
29
+ /**
30
+ * Mapping of equivalent constructs across languages.
31
+ * When source construct X translates to target construct Y,
32
+ * both are valid equivalents and should not be flagged as risk.
33
+ */
34
+ const EQUIVALENT_CONSTRUCTS = new Map([
35
+ ["uc_for_each", "uc_for_loop"],
36
+ ["uc_for_loop", "uc_for_each"],
37
+ ["uc_fn_def", "uc_arrow_fn"],
38
+ ["uc_arrow_fn", "uc_fn_def"],
39
+ ]);
40
+ // ── Analysis Cache (LRU, SHA-256 keyed) ────────────
41
+ const ANALYSIS_CACHE_TTL_MS = 3_600_000; // 60 minutes
42
+ const ANALYSIS_CACHE_MAX_ENTRIES = 100;
43
+ const analysisCache = new Map();
44
+ function computeCacheKey(code, targetLanguage) {
45
+ return createHash("sha256")
46
+ .update(code + "|" + (targetLanguage ?? ""))
47
+ .digest("hex");
48
+ }
49
+ function evictOldestIfNeeded() {
50
+ if (analysisCache.size <= ANALYSIS_CACHE_MAX_ENTRIES)
51
+ return;
52
+ let oldestKey;
53
+ let oldestTs = Infinity;
54
+ for (const [key, entry] of analysisCache) {
55
+ if (entry.timestamp < oldestTs) {
56
+ oldestTs = entry.timestamp;
57
+ oldestKey = key;
58
+ }
59
+ }
60
+ if (oldestKey)
61
+ analysisCache.delete(oldestKey);
62
+ }
13
63
  const PARSERS = new Map([
14
64
  ["typescript", new TsParserAdapter()],
15
65
  ["python", new PythonParserAdapter()],
66
+ ["java", new JavaParserAdapter()],
67
+ ["go", new GoParserAdapter()],
68
+ ["csharp", new CSharpParserAdapter()],
69
+ ["rust", new RustParserAdapter()],
70
+ ["ruby", new RubyParserAdapter()],
71
+ ["php", new PhpParserAdapter()],
72
+ ["swift", new SwiftParserAdapter()],
73
+ ["kotlin", new KotlinParserAdapter()],
74
+ ["scala", new ScalaParserAdapter()],
75
+ ["elixir", new ElixirParserAdapter()],
76
+ ["dart", new DartParserAdapter()],
77
+ ["haskell", new HaskellParserAdapter()],
78
+ ["cpp", new CppParserAdapter()],
79
+ ["lua", new LuaParserAdapter()],
16
80
  ]);
17
81
  export class TranslationOrchestrator {
18
82
  registry;
19
83
  store;
20
- constructor(registry, store) {
84
+ codeStore;
85
+ constructor(registry, store, codeStore) {
21
86
  this.registry = registry;
22
87
  this.store = store;
88
+ this.codeStore = codeStore;
23
89
  }
24
90
  /**
25
91
  * Analyze source code — detect language, identify constructs, compute complexity.
92
+ * Results are cached with SHA-256 content hash (TTL 60min, max 100 entries).
93
+ * When filePath + projectId are provided and Code Intelligence has indexed the file,
94
+ * uses pre-indexed analysis (instant, zero parsing cost).
26
95
  */
27
- analyzeSource(code, hints) {
96
+ analyzeSource(code, hints, filePath, projectId) {
97
+ // Try pre-indexed analysis (Layer 5) when file context is available
98
+ if (filePath && projectId && this.codeStore) {
99
+ const preIndexed = analyzeFromIndex(this.codeStore, projectId, filePath);
100
+ if (preIndexed) {
101
+ const result = { ...preIndexed.analysis, cacheHit: false };
102
+ return result;
103
+ }
104
+ }
105
+ // Check cache
106
+ const cacheKey = computeCacheKey(code, hints?.targetLanguage);
107
+ const cached = analysisCache.get(cacheKey);
108
+ if (cached && Date.now() - cached.timestamp < ANALYSIS_CACHE_TTL_MS) {
109
+ return { ...cached.result, cacheHit: true };
110
+ }
28
111
  // Detect language
29
112
  const detection = detectLanguageFromCode(code);
30
113
  const lang = hints?.languageHint ?? detection.languageId;
@@ -68,7 +151,7 @@ export class TranslationOrchestrator {
68
151
  const estimatedTranslatability = scores.length > 0
69
152
  ? scores.reduce((sum, s) => sum + s.finalConfidence, 0) / scores.length
70
153
  : 0;
71
- return {
154
+ const result = {
72
155
  detectedLanguage: lang,
73
156
  detectedConfidence: confidence,
74
157
  constructs,
@@ -76,13 +159,19 @@ export class TranslationOrchestrator {
76
159
  estimatedTranslatability,
77
160
  ambiguousConstructs: ambiguities.map((a) => a.constructId),
78
161
  totalConstructs: parsed.length,
162
+ cacheHit: false,
79
163
  };
164
+ // Store in cache
165
+ analysisCache.set(cacheKey, { result, timestamp: Date.now() });
166
+ evictOldestIfNeeded();
167
+ return result;
80
168
  }
81
169
  /**
82
170
  * Prepare a translation job — creates the job, analyzes source, builds prompt.
83
171
  */
84
172
  prepareTranslation(input) {
85
- const analysis = this.analyzeSource(input.sourceCode, {
173
+ const sourceCode = input.sourceCode ?? "";
174
+ const analysis = this.analyzeSource(sourceCode, {
86
175
  languageHint: input.sourceLanguage,
87
176
  targetLanguage: input.targetLanguage,
88
177
  });
@@ -91,7 +180,7 @@ export class TranslationOrchestrator {
91
180
  projectId: input.projectId,
92
181
  sourceLanguage: analysis.detectedLanguage,
93
182
  targetLanguage: input.targetLanguage,
94
- sourceCode: input.sourceCode,
183
+ sourceCode,
95
184
  scope: input.scope,
96
185
  });
97
186
  // Update to analyzing status
@@ -100,17 +189,21 @@ export class TranslationOrchestrator {
100
189
  analysis: analysis,
101
190
  });
102
191
  // Build scores + ambiguities for prompt
192
+ // Guard: if registry has no seed data, scoreConstructs returns [] safely
103
193
  const parser = PARSERS.get(analysis.detectedLanguage);
104
- const parsed = parser ? parser.parseSnippet(input.sourceCode) : [];
105
- const constructIds = [...new Set(parsed.map((p) => p.constructId))];
194
+ const parsed = parser ? parser.parseSnippet(sourceCode) : [];
195
+ const constructIds = [...new Set(parsed.map((p) => p.constructId))].filter(Boolean);
106
196
  const scores = scoreConstructs(this.registry, constructIds, analysis.detectedLanguage, input.targetLanguage);
107
197
  const ambiguities = detectAmbiguities(scores, this.registry, analysis.detectedLanguage, input.targetLanguage);
198
+ // Filter out scores/ambiguities with undefined construct data
199
+ const safeScores = scores.filter((s) => s.constructId != null);
200
+ const safeAmbiguities = ambiguities.filter((a) => a.constructId != null && a.canonicalName != null);
108
201
  const promptCtx = {
109
202
  sourceLanguage: analysis.detectedLanguage,
110
203
  targetLanguage: input.targetLanguage,
111
- sourceCode: input.sourceCode,
112
- scores,
113
- ambiguities,
204
+ sourceCode,
205
+ scores: safeScores,
206
+ ambiguities: safeAmbiguities,
114
207
  };
115
208
  const prompt = buildTranslationPrompt(promptCtx);
116
209
  return { jobId: job.id, prompt, analysis };
@@ -175,12 +268,19 @@ function buildEvidence(source, target, sourceLang, targetLang) {
175
268
  translated.push({ source: id, target: id, method: "direct" });
176
269
  }
177
270
  else {
178
- risks.push({
179
- construct: id,
180
- severity: "medium",
181
- message: `${id} from ${sourceLang} has no direct equivalent detected in ${targetLang} output`,
182
- });
183
- reviewPoints.push(`Review mapping of ${id}`);
271
+ // Check if an equivalent construct exists in target (e.g. uc_for_each ↔ uc_for_loop)
272
+ const equivalent = EQUIVALENT_CONSTRUCTS.get(id);
273
+ if (equivalent && targetIds.has(equivalent)) {
274
+ translated.push({ source: id, target: equivalent, method: "equivalent" });
275
+ }
276
+ else {
277
+ risks.push({
278
+ construct: id,
279
+ severity: "medium",
280
+ message: `${id} from ${sourceLang} has no direct equivalent detected in ${targetLang} output`,
281
+ });
282
+ reviewPoints.push(`Review mapping of ${id}`);
283
+ }
184
284
  }
185
285
  }
186
286
  // Coverage-based confidence