ragcode-context-engine 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +366 -0
  3. package/README.zh-CN.md +363 -0
  4. package/dist/src/cli/configure/app.d.ts +6 -0
  5. package/dist/src/cli/configure/app.js +81 -0
  6. package/dist/src/cli/configure/run.d.ts +5 -0
  7. package/dist/src/cli/configure/run.js +85 -0
  8. package/dist/src/cli/configure/state.d.ts +42 -0
  9. package/dist/src/cli/configure/state.js +174 -0
  10. package/dist/src/cli/configure.d.ts +31 -0
  11. package/dist/src/cli/configure.js +101 -0
  12. package/dist/src/cli/index.d.ts +2 -0
  13. package/dist/src/cli/index.js +503 -0
  14. package/dist/src/cli/tui/index-progress.d.ts +12 -0
  15. package/dist/src/cli/tui/index-progress.js +49 -0
  16. package/dist/src/cli/tui/watch-status.d.ts +10 -0
  17. package/dist/src/cli/tui/watch-status.js +27 -0
  18. package/dist/src/cli/update.d.ts +18 -0
  19. package/dist/src/cli/update.js +111 -0
  20. package/dist/src/config/dotenv.d.ts +1 -0
  21. package/dist/src/config/dotenv.js +14 -0
  22. package/dist/src/config/graph-runtime.d.ts +13 -0
  23. package/dist/src/config/graph-runtime.js +29 -0
  24. package/dist/src/config/runtime-config.d.ts +87 -0
  25. package/dist/src/config/runtime-config.js +215 -0
  26. package/dist/src/config/semantic-runtime.d.ts +24 -0
  27. package/dist/src/config/semantic-runtime.js +89 -0
  28. package/dist/src/context/context-builder.d.ts +20 -0
  29. package/dist/src/context/context-builder.js +277 -0
  30. package/dist/src/context/expansion-policy.d.ts +6 -0
  31. package/dist/src/context/expansion-policy.js +49 -0
  32. package/dist/src/context/skeletonizer.d.ts +2 -0
  33. package/dist/src/context/skeletonizer.js +79 -0
  34. package/dist/src/context/snippet-renderer.d.ts +2 -0
  35. package/dist/src/context/snippet-renderer.js +67 -0
  36. package/dist/src/core/contracts.d.ts +74 -0
  37. package/dist/src/core/contracts.js +1 -0
  38. package/dist/src/core/engine.d.ts +64 -0
  39. package/dist/src/core/engine.js +442 -0
  40. package/dist/src/core/types.d.ts +490 -0
  41. package/dist/src/core/types.js +1 -0
  42. package/dist/src/diagnostics/doctor.d.ts +66 -0
  43. package/dist/src/diagnostics/doctor.js +193 -0
  44. package/dist/src/diagnostics/embedding-test.d.ts +24 -0
  45. package/dist/src/diagnostics/embedding-test.js +83 -0
  46. package/dist/src/graph/diff-files.d.ts +1 -0
  47. package/dist/src/graph/diff-files.js +14 -0
  48. package/dist/src/graph/impact-report.d.ts +10 -0
  49. package/dist/src/graph/impact-report.js +173 -0
  50. package/dist/src/graph/in-memory-graph-store.d.ts +36 -0
  51. package/dist/src/graph/in-memory-graph-store.js +395 -0
  52. package/dist/src/graph/owner-ranking.d.ts +2 -0
  53. package/dist/src/graph/owner-ranking.js +41 -0
  54. package/dist/src/graph/sqlite-graph-store.d.ts +51 -0
  55. package/dist/src/graph/sqlite-graph-store.js +724 -0
  56. package/dist/src/graph/sqlite-statements.d.ts +36 -0
  57. package/dist/src/graph/sqlite-statements.js +105 -0
  58. package/dist/src/graph/target-matcher.d.ts +13 -0
  59. package/dist/src/graph/target-matcher.js +64 -0
  60. package/dist/src/index.d.ts +32 -0
  61. package/dist/src/index.js +32 -0
  62. package/dist/src/indexing/analyzers/fallback-analyzer.d.ts +6 -0
  63. package/dist/src/indexing/analyzers/fallback-analyzer.js +45 -0
  64. package/dist/src/indexing/analyzers/go-treesitter-analyzer.d.ts +2 -0
  65. package/dist/src/indexing/analyzers/go-treesitter-analyzer.js +87 -0
  66. package/dist/src/indexing/analyzers/java-treesitter-analyzer.d.ts +2 -0
  67. package/dist/src/indexing/analyzers/java-treesitter-analyzer.js +88 -0
  68. package/dist/src/indexing/analyzers/python-treesitter-analyzer.d.ts +2 -0
  69. package/dist/src/indexing/analyzers/python-treesitter-analyzer.js +96 -0
  70. package/dist/src/indexing/analyzers/registry.d.ts +5 -0
  71. package/dist/src/indexing/analyzers/registry.js +23 -0
  72. package/dist/src/indexing/analyzers/rust-treesitter-analyzer.d.ts +2 -0
  73. package/dist/src/indexing/analyzers/rust-treesitter-analyzer.js +96 -0
  74. package/dist/src/indexing/analyzers/tree-sitter-base.d.ts +30 -0
  75. package/dist/src/indexing/analyzers/tree-sitter-base.js +163 -0
  76. package/dist/src/indexing/analyzers/types.d.ts +17 -0
  77. package/dist/src/indexing/analyzers/types.js +1 -0
  78. package/dist/src/indexing/analyzers/typescript-analyzer.d.ts +5 -0
  79. package/dist/src/indexing/analyzers/typescript-analyzer.js +199 -0
  80. package/dist/src/indexing/ast-analyzer.d.ts +11 -0
  81. package/dist/src/indexing/ast-analyzer.js +11 -0
  82. package/dist/src/indexing/chunker.d.ts +11 -0
  83. package/dist/src/indexing/chunker.js +157 -0
  84. package/dist/src/indexing/ignore-policy.d.ts +6 -0
  85. package/dist/src/indexing/ignore-policy.js +40 -0
  86. package/dist/src/indexing/indexer.d.ts +13 -0
  87. package/dist/src/indexing/indexer.js +189 -0
  88. package/dist/src/indexing/language.d.ts +3 -0
  89. package/dist/src/indexing/language.js +24 -0
  90. package/dist/src/indexing/scanner.d.ts +13 -0
  91. package/dist/src/indexing/scanner.js +87 -0
  92. package/dist/src/lsp/definition-resolver.d.ts +6 -0
  93. package/dist/src/lsp/definition-resolver.js +60 -0
  94. package/dist/src/lsp/typescript-language-service.d.ts +21 -0
  95. package/dist/src/lsp/typescript-language-service.js +82 -0
  96. package/dist/src/mcp/server.d.ts +11 -0
  97. package/dist/src/mcp/server.js +64 -0
  98. package/dist/src/mcp/tools.d.ts +266 -0
  99. package/dist/src/mcp/tools.js +309 -0
  100. package/dist/src/project/project-identity.d.ts +2 -0
  101. package/dist/src/project/project-identity.js +24 -0
  102. package/dist/src/project/project-registry.d.ts +12 -0
  103. package/dist/src/project/project-registry.js +49 -0
  104. package/dist/src/project/workspace-resolver.d.ts +20 -0
  105. package/dist/src/project/workspace-resolver.js +62 -0
  106. package/dist/src/retrieval/graph-reranker.d.ts +11 -0
  107. package/dist/src/retrieval/graph-reranker.js +0 -0
  108. package/dist/src/retrieval/hybrid-retriever.d.ts +31 -0
  109. package/dist/src/retrieval/hybrid-retriever.js +111 -0
  110. package/dist/src/retrieval/path-classification.d.ts +6 -0
  111. package/dist/src/retrieval/path-classification.js +22 -0
  112. package/dist/src/retrieval/query-matching.d.ts +22 -0
  113. package/dist/src/retrieval/query-matching.js +166 -0
  114. package/dist/src/retrieval/query-planner.d.ts +5 -0
  115. package/dist/src/retrieval/query-planner.js +77 -0
  116. package/dist/src/retrieval/ranking-signals.d.ts +19 -0
  117. package/dist/src/retrieval/ranking-signals.js +97 -0
  118. package/dist/src/retrieval/topology-distance.d.ts +21 -0
  119. package/dist/src/retrieval/topology-distance.js +116 -0
  120. package/dist/src/reuse/reuse-detector.d.ts +12 -0
  121. package/dist/src/reuse/reuse-detector.js +564 -0
  122. package/dist/src/semantic/deterministic-embedding.d.ts +7 -0
  123. package/dist/src/semantic/deterministic-embedding.js +31 -0
  124. package/dist/src/semantic/in-memory-semantic-store.d.ts +11 -0
  125. package/dist/src/semantic/in-memory-semantic-store.js +65 -0
  126. package/dist/src/semantic/lance-semantic-store.d.ts +131 -0
  127. package/dist/src/semantic/lance-semantic-store.js +623 -0
  128. package/dist/src/semantic/openai-compatible-embedding.d.ts +19 -0
  129. package/dist/src/semantic/openai-compatible-embedding.js +75 -0
  130. package/dist/src/service/service-identity.d.ts +13 -0
  131. package/dist/src/service/service-identity.js +48 -0
  132. package/dist/src/service/service-manager.d.ts +29 -0
  133. package/dist/src/service/service-manager.js +231 -0
  134. package/dist/src/service/service-templates.d.ts +22 -0
  135. package/dist/src/service/service-templates.js +101 -0
  136. package/dist/src/subgraph/impact-explainer.d.ts +2 -0
  137. package/dist/src/subgraph/impact-explainer.js +54 -0
  138. package/dist/src/subgraph/node-expander.d.ts +13 -0
  139. package/dist/src/subgraph/node-expander.js +139 -0
  140. package/dist/src/subgraph/output-preset.d.ts +3 -0
  141. package/dist/src/subgraph/output-preset.js +102 -0
  142. package/dist/src/subgraph/subgraph-builder.d.ts +17 -0
  143. package/dist/src/subgraph/subgraph-builder.js +688 -0
  144. package/dist/src/topology/export-index.d.ts +7 -0
  145. package/dist/src/topology/export-index.js +14 -0
  146. package/dist/src/topology/framework-topology.d.ts +3 -0
  147. package/dist/src/topology/framework-topology.js +460 -0
  148. package/dist/src/topology/import-resolver.d.ts +2 -0
  149. package/dist/src/topology/import-resolver.js +29 -0
  150. package/dist/src/topology/orm-topology.d.ts +3 -0
  151. package/dist/src/topology/orm-topology.js +200 -0
  152. package/dist/src/topology/runtime-topology.d.ts +3 -0
  153. package/dist/src/topology/runtime-topology.js +204 -0
  154. package/dist/src/topology/symbol-resolver.d.ts +6 -0
  155. package/dist/src/topology/symbol-resolver.js +74 -0
  156. package/dist/src/topology/test-topology.d.ts +2 -0
  157. package/dist/src/topology/test-topology.js +82 -0
  158. package/dist/src/utils/hash.d.ts +2 -0
  159. package/dist/src/utils/hash.js +7 -0
  160. package/dist/src/utils/path.d.ts +2 -0
  161. package/dist/src/utils/path.js +7 -0
  162. package/dist/src/watch/event-journal.d.ts +17 -0
  163. package/dist/src/watch/event-journal.js +81 -0
  164. package/dist/src/watch/file-event-coalescer.d.ts +9 -0
  165. package/dist/src/watch/file-event-coalescer.js +39 -0
  166. package/dist/src/watch/index-scheduler.d.ts +52 -0
  167. package/dist/src/watch/index-scheduler.js +190 -0
  168. package/dist/src/watch/watch-daemon.d.ts +73 -0
  169. package/dist/src/watch/watch-daemon.js +368 -0
  170. package/dist/src/watch/watcher-liveness.d.ts +47 -0
  171. package/dist/src/watch/watcher-liveness.js +168 -0
  172. package/dist/src/web/server.d.ts +1 -0
  173. package/dist/src/web/server.js +375 -0
  174. package/package.json +94 -0
@@ -0,0 +1,363 @@
1
+ <p align="center">
2
+ <img src="docs/images/eeb4a920-7607-41a7-aa2c-1d897a96a1ee.png" alt="RagCode logo" width="180" />
3
+ </p>
4
+
5
+ <h1 align="center">RagCode ไธŠไธ‹ๆ–‡ๅผ•ๆ“Ž</h1>
6
+
7
+ <p align="center">
8
+ <a href="https://github.com/MarshallEriksen-Neura/ragcode/actions/workflows/ci.yml"><img src="https://github.com/MarshallEriksen-Neura/ragcode/actions/workflows/ci.yml/badge.svg" alt="CI" /></a>
9
+ <a href="https://www.npmjs.com/package/ragcode-context-engine"><img src="https://img.shields.io/npm/v/ragcode-context-engine.svg" alt="npm version" /></a>
10
+ <a href="./LICENSE"><img src="https://img.shields.io/badge/License-MIT-yellow.svg" alt="License: MIT" /></a>
11
+ <a href="https://nodejs.org/"><img src="https://img.shields.io/badge/node-%3E%3D24-green.svg" alt="Node >= 24" /></a>
12
+ </p>
13
+
14
+ <p align="center"><a href="./README.md">English</a> ยท <b>็ฎ€ไฝ“ไธญๆ–‡</b></p>
15
+
16
+ **RagCode ๆ˜ฏ้ขๅ‘็ผ–็ ๆ™บ่ƒฝไฝ“็š„ใ€Œๅฏ้ชŒ่ฏไธŠไธ‹ๆ–‡ๅฑ‚ใ€๏ผŒไธ”ๅ…จ็จ‹ๅœจๆœฌๅœฐ่ฟ่กŒใ€‚**
17
+
18
+ ็ปๅคงๅคšๆ•ฐไปฃ็ ๆ™บ่ƒฝๅทฅๅ…ทๆญขๆญฅไบŽ**ๆฃ€็ดข**โ€”โ€”ๆŠŠ็›ธๅ…ณไปฃ็ ็‰‡ๆฎตไธข็ป™ๆ™บ่ƒฝไฝ“ๅฐฑๅฎŒไบ‹ไบ†ใ€‚RagCode ๅคš่ตฐไธ€ๆญฅ๏ผšๅฎƒไผšๅ‘Š่ฏ‰ๆ™บ่ƒฝไฝ“**ๅฝ“ๅ‰ๆŽŒๆก็š„ๅทฒ้ชŒ่ฏไธŠไธ‹ๆ–‡ๆ˜ฏๅฆ่ถณไปฅๅฎ‰ๅ…จๅœฐๅŠจๆ‰‹**ใ€‚ๆฏไธ€ไธชๅ›ž็ญ”้ƒฝ้™„ๅธฆๆ˜Ž็กฎ็š„ๆฅๆบๅผ•็”จใ€ๆ–ฐ้ฒœๅบฆใ€ๅฝ’ๅฑž้“พใ€ๅฝฑๅ“ๅŠๅพ„๏ผˆblast-radius๏ผ‰ใ€่ฆ†็›–ไฟกๅท๏ผˆcoverage๏ผ‰๏ผŒไปฅๅŠไธ€ไธช `edit-readiness` ๅˆคๅฎš๏ผˆ`safe_to_edit_after_reading` / `investigate_only` / `not_enough_context`๏ผ‰โ€”โ€”ๅนถ่ฏšๅฎžๅœฐ่ฎฐๅฝ•่ฟ˜็ผบๅ“ชไบ›่ฏๆฎใ€‚
19
+
20
+ ๅฎƒ**ไธŽ็ผ–่พ‘ๅ™จๆ— ๅ…ณใ€MCP ๅŽŸ็”Ÿ**๏ผˆClaude Codeใ€Codex๏ผŒๆˆ–ไปปไฝ• MCP ๅฎขๆˆท็ซฏโ€”โ€”ไธ็ป‘ๅฎšๅ•ไธ€็ผ–่พ‘ๅ™จ๏ผ‰๏ผŒๅนถ**ๅฎŒๅ…จๅœจไฝ ็š„ๆœบๅ™จไธŠ่ฟ่กŒ**๏ผˆๆ— ้œ€่ดฆๅทใ€ๆ— ้œ€ API keyใ€ไปฃ็ ไธๅ‡บๆœฌๅœฐ๏ผ‰ใ€‚้ฆ–ๆฌก่ฟ่กŒ็”จ็กฎๅฎšๆ€งๅตŒๅ…ฅๅณๅฏ็ฆป็บฟๅทฅไฝœ๏ผ›ๅชๆœ‰ๅฝ“ไฝ ๆƒณ่ฆๆ›ดๅฅฝ็š„ๅฌๅ›žๆ—ถ๏ผŒๆ‰้œ€่ฆๆขไธŠ OpenAI ๅ…ผๅฎน็š„ๅตŒๅ…ฅproviderใ€‚
21
+
22
+ ๅฎƒๅ€Ÿ้‰ดไบ† CodeGraphใ€Understand-Anything ็ญ‰้กน็›ฎ็š„ๆ€่ทฏ๏ผŒๅนถๅœจๆญคๅŸบ็ก€ไธŠๅŠ ๅ…ฅไบ† LanceDB ่ฏญไน‰ๅฑ‚ไปฅๅŠๆ›ดๅผบ็š„ไธŠไธ‹ๆ–‡ๅผ•ๆ“Žๅฅ‘็บฆ๏ผš`get_context` ่ฟ”ๅ›ž็š„ๆ˜ฏๅฝ“ๅ‰ๅทฒ็ดขๅผ•็š„ใ€่ƒฝๅคŸๅธฎๅŠฉๆ™บ่ƒฝไฝ“ๅ›ž็ญ”ใ€่ฐƒ่ฏ•ใ€ไฟฎๆ”นๆˆ–่ฏ„ๅฎกไปฃ็ ็š„**ๆœ€ๅฐไปปๅŠกไธŠไธ‹ๆ–‡ๅŒ…**ใ€‚
23
+
24
+ ---
25
+
26
+ ## ไธบไป€ไนˆ้€‰ RagCode
27
+
28
+ | ๅฆ‚ๆžœไฝ ้œ€่ฆโ€ฆโ€ฆ | RagCode ้€‚ๅˆ๏ผŒๅ› ไธบโ€ฆโ€ฆ |
29
+ |---|---|
30
+ | ไธ่ขซๅ•ไธ€็ผ–่พ‘ๅ™จ้”ๅฎš็š„ไธŠไธ‹ๆ–‡่ƒฝๅŠ› | MCP ๅŽŸ็”Ÿ๏ผ›้€‚้…ไปปๆ„ๆ™บ่ƒฝไฝ“ๅฎฟไธป๏ผŒ่€Œ้žๆŸไธ€ไธช IDE |
31
+ | ไปฃ็ ๆฐธไธ็ฆปๅผ€ๆœฌๆœบ | ๅ…จๆœฌๅœฐ็ดขๅผ• + ็ฆป็บฟๅตŒๅ…ฅ๏ผŒๆ— ไบ‘็ซฏๅพ€่ฟ” |
32
+ | ่ฎฉๆ™บ่ƒฝไฝ“ใ€Œๆญฃ็กฎๅœฐๅŠจๆ‰‹ใ€่€Œ้žใ€Œ่‡ชไฟกๅœฐ็Šฏ้”™ใ€ | ๅธฆ่ฆ†็›–ไฟกๅทไธŽ edit-readiness ๅˆคๅฎš็š„้ชŒ่ฏๅผๅญๅ›พ๏ผŒ่€Œไธๆ˜ฏๅŽŸๅง‹็‰‡ๆฎตๅ †็ Œ |
33
+
34
+ ---
35
+
36
+ ## ๆŠ€ๆœฏๆ ˆ
37
+
38
+ | ้ข†ๅŸŸ | ๆŠ€ๆœฏ |
39
+ |------|-----------|
40
+ | ่ฏญ่จ€ / ่ฟ่กŒๆ—ถ | TypeScript 5.9ใ€Node.js **>= 24**๏ผˆไฝฟ็”จ `node:sqlite`๏ผ‰ใ€ESM ๆจกๅ— |
41
+ | ็ป“ๆž„ๅŒ–ๅ›พๅญ˜ๅ‚จ | `better-sqlite3`๏ผˆSQLite + FTS๏ผ‰๏ผŒๆต‹่ฏ•ๅœบๆ™ฏไธ‹ไฝฟ็”จๅ†…ๅญ˜ๅญ˜ๅ‚จ |
42
+ | ่ฏญไน‰ / ๅ‘้‡ๅญ˜ๅ‚จ | `@lancedb/lancedb` + `apache-arrow`๏ผŒๅนถๆไพ›ๅ†…ๅญ˜ๅญ˜ๅ‚จๅ…œๅบ• |
43
+ | AST / ่งฃๆž | TypeScript Compiler API๏ผˆTS/JS๏ผ‰ใ€`tree-sitter`๏ผˆPythonใ€Goใ€Rustใ€Java๏ผ‰ |
44
+ | MCP ้›†ๆˆ | `@modelcontextprotocol/sdk`๏ผˆstdio ๆœๅŠก๏ผ‰ |
45
+ | CLI | `commander`ใ€`ink` + `react`๏ผˆไบคไบ’ๅผๅ‘ๅฏผ๏ผ‰ |
46
+ | Web ไปช่กจ็›˜ | `express` + `ws` ๅŽ็ซฏ๏ผŒVue ๅ‰็ซฏ๏ผˆไฝไบŽ `web/`๏ผ‰ |
47
+ | ๆ–‡ไปถ็›‘ๅฌ | `chokidar` |
48
+ | ๆ ก้ชŒ | `zod` |
49
+ | ๅทฅๅ…ท้“พ | `tsx`๏ผˆๅผ€ๅ‘๏ผ‰ใ€`vitest`๏ผˆๆต‹่ฏ•๏ผ‰ใ€`tsc`๏ผˆๆž„ๅปบ + ็ฑปๅž‹ๆฃ€ๆŸฅ๏ผ‰ |
50
+
51
+ ---
52
+
53
+ ## ้กน็›ฎๆžถๆž„
54
+
55
+ RagCode ้‡‡็”จๅˆ†ๅฑ‚่ฎพ่ฎก๏ผŒไปปไฝ•ๅ…ทไฝ“็š„ๅญ˜ๅ‚จๅฎž็Žฐ้ƒฝไธไผš่ทจ่ถŠ่พน็•Œๆณ„ๆผใ€‚ๆ‰€ๆœ‰ๅฏนๅค–็š„ๆŽฅๅฃๅฑ‚๏ผˆCLIใ€MCPใ€Web๏ผ‰้ƒฝไพ่ต– `src/core` ไธญ็š„ๅฅ‘็บฆ๏ผŒ่€Œไธไพ่ต–ไปปไฝ•็‰นๅฎšๆ•ฐๆฎๅบ“ใ€‚
56
+
57
+ ```
58
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
59
+ ๆŽฅๅฃๅฑ‚ โ”‚ CLI โ”‚ โ”‚ MCP โ”‚ โ”‚ Web ไปช่กจ็›˜ โ”‚
60
+ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
61
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
62
+ โ”‚
63
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
64
+ โ”‚ ContextEngine (core) โ”‚ ่ง„่Œƒๅฅ‘็บฆ
65
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
66
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
67
+ โ–ผ โ–ผ โ–ผ โ–ผ โ–ผ
68
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ” โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
69
+ โ”‚indexingโ”‚ โ”‚ graph โ”‚ โ”‚ sem. โ”‚ โ”‚retrievalโ”‚ โ”‚ context โ”‚
70
+ โ”‚ ๆ‰ซๆ โ”‚ โ”‚ SQLite โ”‚ โ”‚Lance โ”‚ โ”‚ ่ง„ๅˆ’ๅ™จ โ”‚ โ”‚ ๆ‰“ๅŒ…ๅ™จ โ”‚
71
+ โ”‚ ๅˆ†ๅ— โ”‚ โ”‚ +FTS โ”‚ โ”‚ DB โ”‚ โ”‚ +่žๅˆ โ”‚ โ”‚ +้ข„็ฎ— โ”‚
72
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
73
+ โ”‚
74
+ โ”Œโ”€โ”€โ”€โ”€โ”€โ–ผโ”€โ”€โ”€โ”€โ”€โ”
75
+ โ”‚ watch โ”‚ ๅขž้‡ๆ–ฐ้ฒœๅบฆ
76
+ โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
77
+ ```
78
+
79
+ **ๅ„ๅฑ‚่Œ่ดฃ**๏ผˆ่ฏฆ่ง [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)๏ผ‰๏ผš
80
+
81
+ - **core** โ€” ่ง„่Œƒๅฅ‘็บฆ๏ผš`RepoIndex`ใ€`CodeFile`ใ€`CodeChunk`ใ€`GraphStore`ใ€`SemanticStore`ใ€`ContextEngine`ใ€‚่ฟ™ๆ˜ฏๅ…ถไป–ไธ€ๅˆ‡ๆ‰€ไพ่ต–็š„็จณๅฎš่พน็•Œใ€‚
82
+ - **indexing** โ€” ๆ–‡ไปถ็ณป็ปŸๆ‰ซๆใ€ๅฟฝ็•ฅ่ง„ๅˆ™ใ€ๅ“ˆๅธŒ่ฎก็ฎ—ใ€ๅˆ†ๅ—ไปฅๅŠ็ดขๅผ•ๆตๆฐด็บฟๆญฅ้ชคใ€‚ๅฎƒไธๆ„Ÿ็Ÿฅ MCPใ€‚
83
+ - **graph** โ€” ็ฒพ็กฎ็š„ไปฃ็ ็ป“ๆž„๏ผšๆ–‡ไปถใ€็ฌฆๅทใ€่พนใ€ๆŸฅๆ‰พใ€่ฐƒ็”จๆ–น/่ขซ่ฐƒ็”จๆ–น/ๅฝฑๅ“ๅˆ†ๆžใ€‚ๆต‹่ฏ•็”จๅ†…ๅญ˜ๅฎž็Žฐ๏ผŒ็”Ÿไบง็”จ SQLite + FTSใ€‚
84
+ - **semantic** โ€” ๅตŒๅ…ฅไธŽๅ‘้‡ๆฃ€็ดข๏ผŒ่—ๅœจๆŽฅๅฃไน‹ๅŽ๏ผŒๅ› ๆญคๅฏไปฅ่‡ช็”ฑๆ›ฟๆขๆไพ›ๅ•†๏ผˆ็กฎๅฎšๆ€งใ€OpenAI ๅ…ผๅฎนใ€ๆœฌๅœฐๆจกๅž‹๏ผ‰ๅ’Œๅญ˜ๅ‚จๅŽ็ซฏใ€‚
85
+ - **retrieval** โ€” ๆŸฅ่ฏข่ง„ๅˆ’๏ผšๆ„ๅ›พ่ฏ†ๅˆซใ€ๅ›พ + ่ฏญไน‰ๆฃ€็ดขใ€ๅˆ†ๆ•ฐ่žๅˆใ€็ป“ๆžœๅฝ’ไธ€ๅŒ–ใ€‚
86
+ - **context** โ€” ้ขๅ‘ๆ™บ่ƒฝไฝ“็š„่พ“ๅ‡บ๏ผšๅœจๅญ—็ฌฆ/Token ้ข„็ฎ—ๅ†…ๆŒ‘้€‰็‰‡ๆฎต๏ผŒ้™„ๅธฆ็†็”ฑใ€ๅˆ†ๆ•ฐใ€ๆฅๆบๅผ•็”จไปฅๅŠ `missingEvidence`ใ€‚
87
+ - **watch** โ€” ้•ฟๆ—ถ้—ด่ฟ่กŒ็š„็›‘ๅฌๅ™จใ€ๆŒไน…ๅŒ–ไบ‹ไปถๆ—ฅๅฟ—ใ€่„ๆ–‡ไปถๅˆๅนถ๏ผŒไปฅๅŠๅŽๅฐๆ‰น้‡้‡ๅปบ็ดขๅผ•่ฐƒๅบฆใ€‚
88
+ - **mcp** โ€” ่ฝป่–„็š„ๅ่ฎฎ้€‚้…ๅฑ‚๏ผšๅทฅๅ…ทๅ‘ฝๅใ€่พ“ๅ…ฅๆ ก้ชŒใ€ๅค„็†ๅ™จๅˆ†ๅ‘ใ€‚่ฟ™้‡ŒไธๅŒ…ๅซไปปไฝ•ๆฃ€็ดข้€ป่พ‘ใ€‚
89
+
90
+ **ไธŠไธ‹ๆ–‡ๅŒ…ๅฅ‘็บฆ**ๆ˜ฏๆ•ดไธชๅผ•ๆ“Ž็š„ๆ ธๅฟƒใ€‚`get_context` ่ฟ”ๅ›ž๏ผš
91
+
92
+ ```
93
+ brief โ†’ freshness โ†’ ownerChain โ†’ topology โ†’ ่ฏๆฎ็‰‡ๆฎต โ†’ missingEvidence โ†’ nextQueries
94
+ ```
95
+
96
+ ็‰‡ๆฎตๆ˜ฏ*่ฏๆฎ*๏ผŒ่€Œ้ž็ป“ๆžœ็š„ไธป่ฆ็ป„็ป‡ๆ–นๅผใ€‚ๅคงๆ–‡ไปถ้ป˜่ฎคไปฅ `skeleton`๏ผˆ้ชจๆžถ๏ผ‰ๅฑ•ๅผ€็บงๅˆซ่ฟ”ๅ›ž๏ผŒ่€Œ้žๅฎŒๆ•ดๆบ็ ๏ผŒๅนถไธ”ๆฏไธช็‰‡ๆฎต้ƒฝไผšๆŠฅๅ‘Š็œ็•ฅไบ†ๅคšๅฐ‘่กŒใ€‚
97
+
98
+ ---
99
+
100
+ ## ๅฟซ้€Ÿๅผ€ๅง‹
101
+
102
+ ### ๅ‰็ฝฎๆกไปถ
103
+
104
+ - **Node.js >= 24.0.0**๏ผˆๅฟ…้œ€โ€”โ€”SQLite ๅ›พๅญ˜ๅ‚จไฝฟ็”จ `node:sqlite`๏ผ‰
105
+ - Windowsใ€macOS ๆˆ– Linux
106
+ - ็บฆ 100 MB ็ฃ็›˜็ฉบ้—ด๏ผŒ็”จไบŽไพ่ต–ไธŽ็ดขๅผ•ๆ•ฐๆฎ
107
+
108
+ ### ๅฎ‰่ฃ…ๅนถ่ฟ่กŒ๏ผˆ็ปˆ็ซฏไผ˜ๅ…ˆใ€็ฆป็บฟไผ˜ๅ…ˆ๏ผ‰
109
+
110
+ ้ฆ–ๆฌก่ฟ่กŒๆ— ้œ€ไปปไฝ•ๅตŒๅ…ฅ API keyใ€ๆ— ้œ€่ดฆๅทใ€ๆ— ้œ€ๆ‰˜็ฎกๆœๅŠกใ€‚
111
+
112
+ ```bash
113
+ # ๅ…จๅฑ€ๅฎ‰่ฃ…
114
+ npm install -g ragcode-context-engine
115
+
116
+ cd my-project
117
+ ragcode init # ็ฆป็บฟไผ˜ๅ…ˆ้…็ฝฎ๏ผšsqlite + lancedb + ็กฎๅฎšๆ€งๅตŒๅ…ฅ
118
+ ragcode index . # ๆž„ๅปบ็ป“ๆž„ๅŒ– + ่ฏญไน‰็ดขๅผ•
119
+ ragcode setup-mcp # ไธบไฝ ็š„ๆ™บ่ƒฝไฝ“ๅฎขๆˆท็ซฏๆณจๅ†Œ MCP ๆœๅŠก
120
+ ```
121
+
122
+ ๆˆ–่€…ๅ…ๅฎ‰่ฃ…็›ดๆŽฅ่ฏ•็”จ๏ผš
123
+
124
+ ```bash
125
+ npx ragcode-context-engine index .
126
+ npx ragcode-context-engine search . "query"
127
+ ```
128
+
129
+ ไปŽๆบ็ ๅผ€ๅ‘๏ผˆๆœชๅ…จๅฑ€ๅฎ‰่ฃ…๏ผ‰๏ผŸ็”จ dev ่„šๆœฌ่ฟ่กŒไปปๆ„ๅ‘ฝไปคโ€”โ€”ๅฎƒ้€š่ฟ‡ `tsx` ็›ดๆŽฅๆ‰ง่กŒ TypeScript ๅ…ฅๅฃ๏ผš
130
+
131
+ ```bash
132
+ npm run dev -- index .
133
+ npm run dev -- setup-mcp --client codex --print
134
+ ```
135
+
136
+ ### ๅ‡็บง่ฏญไน‰ๅฌๅ›ž่ƒฝๅŠ›๏ผˆๅฏ้€‰๏ผŒๆฐธไธ้˜ปๅกž๏ผ‰
137
+
138
+ ```bash
139
+ ragcode configure # ็ผ–่พ‘ๅญ˜ๅ‚จ / ๆไพ›ๅ•† / ๆจกๅž‹ / base URL / ็ปดๅบฆ
140
+ ragcode configure --test # ้ชŒ่ฏๆไพ›ๅ•†๏ผˆๅคฑ่ดฅๅˆ†็ฑปๆธ…ๆ™ฐ๏ผ›็ปไธๆ‰“ๅฐๅฏ†้’ฅ๏ผ‰
141
+ ```
142
+
143
+ ่ฆไฝฟ็”จ OpenAI ๅ…ผๅฎน็š„ๆไพ›ๅ•†๏ผŒ่ฎพ็ฝฎๅตŒๅ…ฅๆไพ›ๅ•†ๅŠ key๏ผš
144
+
145
+ ```bash
146
+ export RAGCODE_EMBEDDING_PROVIDER=openai
147
+ export OPENAI_API_KEY=your-api-key
148
+ ```
149
+
150
+ ### CLI ๅ‘ฝไปค
151
+
152
+ ```bash
153
+ ragcode init [directory] # ๅˆๅง‹ๅŒ–้…็ฝฎ๏ผˆไบคไบ’ๅผๅ‘ๅฏผ๏ผ‰
154
+ ragcode index <repoRoot> # ็ดขๅผ•ไธ€ไธชไป“ๅบ“
155
+ ragcode search <repoRoot> <query> # ๆœ็ดขไปฃ็ 
156
+ ragcode status <repoRoot> # ๆฃ€ๆŸฅ็ดขๅผ•็Šถๆ€
157
+ ragcode context <repoRoot> <query> # ๆž„ๅปบไธŠไธ‹ๆ–‡ๅŒ…
158
+ ragcode mcp # ๅฏๅŠจ MCP ๆœๅŠก๏ผˆstdio๏ผ‰
159
+ ragcode setup-mcp # ไธบ Claude Desktop ๆณจๅ†Œ MCP
160
+ ragcode doctor [repoRoot] # ่ฟ่กŒๆ—ถ่ฏŠๆ–ญ
161
+ ragcode watch <repoRoot> # ๆ–‡ไปถ็›‘ๅฌๅฎˆๆŠค่ฟ›็จ‹
162
+ ragcode dashboard # Web ๅฏ่ง‚ๆต‹ๅŽ็ซฏ๏ผˆ็ซฏๅฃ 3000๏ผ‰
163
+ ```
164
+
165
+ ่ฟ่กŒ `ragcode --help` ๆˆ– `ragcode <command> --help` ๆŸฅ็œ‹ๆ›ดๅคš็ป†่Š‚ใ€‚
166
+
167
+ ### MCP ๆœๅŠก้›†ๆˆ
168
+
169
+ RagCode ๅฏไฝœไธบ MCP ๆœๅŠก่ฟ่กŒ๏ผŒ่ฎฉ Claude ็ญ‰ๆ™บ่ƒฝไฝ“็›ดๆŽฅ่ฐƒ็”จๅฎƒ็š„ๅทฅๅ…ทใ€‚ๆŒ‰ๅฎขๆˆท็ซฏ่‡ชๅŠจๆณจๅ†Œ๏ผš
170
+
171
+ ```bash
172
+ ragcode setup-mcp # Claude Desktop (~/.../claude_desktop_config.json)
173
+ ragcode setup-mcp --client claude-code # Claude Code (้กน็›ฎ ./.mcp.json)
174
+ ragcode setup-mcp --client codex # Codex CLI (~/.codex/config.toml)
175
+ ragcode setup-mcp --client codex --print # ไป…ๆ‰“ๅฐ้…็ฝฎ๏ผŒไธๅ†™ๆ–‡ไปถ
176
+ ```
177
+
178
+ ๆ—ขๆœ‰้…็ฝฎไผš่ขซๅŽŸๅœฐๅˆๅนถ๏ผˆไฟ็•™ๅ…ถๅฎƒๆœๅŠกๅ’Œๆ— ๅ…ณๅญ—ๆฎต๏ผŒๅนถๅœจ่ฆ†็›–ๅ‰ๅค‡ไปฝๅŽŸๆ–‡ไปถ๏ผ‰ใ€‚ๅŠ  `--force`
179
+ ๅฏ่ทณ่ฟ‡ๆ็คบ็›ดๆŽฅ่ฆ†็›–ๅทฒๆœ‰็š„ `ragcode` ๆก็›ฎ๏ผŒๅŠ  `--include-secrets` ๅฏๅ†™ๅ…ฅ็œŸๅฎž API ๅฏ†้’ฅ่€Œ้ž่„ฑๆ•ๅ ไฝ็ฌฆใ€‚
180
+
181
+ ๆˆ–ๆ‰‹ๅŠจๆทปๅŠ ๅˆฐไฝ ็š„ MCP ๅฎขๆˆท็ซฏ้…็ฝฎ๏ผš
182
+
183
+ ```json
184
+ {
185
+ "mcpServers": {
186
+ "ragcode": {
187
+ "command": "ragcode",
188
+ "args": ["mcp"],
189
+ "env": {
190
+ "RAGCODE_GRAPH_STORE": "sqlite",
191
+ "RAGCODE_SQLITE_PATH": ".ragcode/graph.sqlite",
192
+ "RAGCODE_SEMANTIC_STORE": "lancedb",
193
+ "RAGCODE_LANCEDB_URI": ".ragcode/lancedb",
194
+ "RAGCODE_EMBEDDING_PROVIDER": "deterministic"
195
+ }
196
+ }
197
+ }
198
+ }
199
+ ```
200
+
201
+ **ๅฏ็”จ็š„ MCP ๅทฅๅ…ท๏ผˆๅ…ฑ 19 ไธช๏ผ‰๏ผš**
202
+
203
+ - *็ดขๅผ•็”Ÿๅ‘ฝๅ‘จๆœŸ* โ€” `index_repo`ใ€`refresh_index`ใ€`index_status`ใ€`record_file_events`ใ€`watch_status`
204
+ - *ๆœ็ดขไธŽไธŠไธ‹ๆ–‡* โ€” `search_code`ใ€`get_context`ใ€`topology_map`ใ€`expand_node`
205
+ - *็ฌฆๅทไธŽๆ–‡ไปถ* โ€” `find_symbol`ใ€`explain_file`ใ€`find_owner`ใ€`find_reuse_candidates`
206
+ - *ๅฝฑๅ“ไธŽๆตๅ‘* โ€” `impact_analysis`ใ€`explain_impact`ใ€`related_tests`ใ€`trace_flow`ใ€`trace_request_flow`
207
+ - *่ฏ„ๅฎก* โ€” `review_diff`
208
+
209
+ `watch_status` ๆ˜ฏๅช่ฏป็š„๏ผšๅฎƒๆŠฅๅ‘Šๆ˜ฏๅฆๆœ‰ๆดป็€็š„ watcher ๅœจไฟๆŒ็ดขๅผ•ๆ–ฐ้ฒœ๏ผŒไฝ†็ปไธๅฏๅŠจ watcher๏ผˆๅฏๅŠจๅฑžไบŽ `ragcode watch` ๆˆ– OS ๆœๅŠก็š„่Œ่ดฃ๏ผ‰ใ€‚
210
+
211
+ ### Web ไปช่กจ็›˜๏ผˆ่ง‚ๆต‹ไธŽ่ฐƒ่ฏ•๏ผ‰
212
+
213
+ ไปช่กจ็›˜ๆ˜ฏ RagCode ็š„ๅฏ่ง‚ๆต‹้ขๆฟโ€”โ€”ๅ›พๅฏ่ง†ๅŒ–ใ€ๆœ็ดข่ฐƒ่ฏ•ใ€ไธŠไธ‹ๆ–‡ๅŒ…ๆฃ€่ง†ใ€็›‘ๅฌๅ™จ็›‘ๆŽง๏ผŒไปฅๅŠไธ€ไธชๅธฆ้€ๅญ—ๆฎตๆฅๆบๆ ‡ๆณจๅ’Œๅฏ†้’ฅ่„ฑๆ•็š„่ฟ่กŒๆ—ถ้…็ฝฎ่ง†ๅ›พใ€‚้…็ฝฎไธŽ่ฎพ็ฝฎไป็„ถ็•™ๅœจ็ปˆ็ซฏไธญๅฎŒๆˆใ€‚
214
+
215
+ ```bash
216
+ ragcode dashboard # ๅŽ็ซฏ API๏ผˆ็ซฏๅฃ 3000๏ผ‰
217
+ cd web && npm run dev # Vue ๅ‰็ซฏ๏ผˆ็ซฏๅฃ 5173๏ผŒๅผ€ๅ‘ๆจกๅผ๏ผ‰
218
+ ```
219
+
220
+ ่ฏฆ่ง [docs/DASHBOARD.md](docs/DASHBOARD.md) ไธŽ [web/README.md](web/README.md)ใ€‚
221
+
222
+ ---
223
+
224
+ ## ้กน็›ฎ็ป“ๆž„
225
+
226
+ ```
227
+ ragcode/
228
+ โ”œโ”€โ”€ src/
229
+ โ”‚ โ”œโ”€โ”€ core/ # ่ง„่Œƒๅฅ‘็บฆไธŽ็ผ–ๆŽ’้—จ้ข๏ผˆ็จณๅฎš่พน็•Œ๏ผ‰
230
+ โ”‚ โ”œโ”€โ”€ indexing/ # ๆ‰ซๆใ€ๅฟฝ็•ฅ่ง„ๅˆ™ใ€ๅ“ˆๅธŒใ€ๅˆ†ๅ—ใ€ๅˆ†ๆžๅ™จใ€ๆตๆฐด็บฟ
231
+ โ”‚ โ”œโ”€โ”€ graph/ # ็ป“ๆž„ๅŒ–ไปฃ็ ๅ›พ๏ผš็ฌฆๅทใ€ๆ–‡ไปถใ€่พนใ€ๆŸฅๆ‰พ
232
+ โ”‚ โ”œโ”€โ”€ semantic/ # ๅตŒๅ…ฅ + ๅ‘้‡ๅญ˜ๅ‚จ๏ผˆLanceDB / ๅ†…ๅญ˜๏ผ‰
233
+ โ”‚ โ”œโ”€โ”€ retrieval/ # ๆŸฅ่ฏข่ง„ๅˆ’ไธŽๆททๅˆ๏ผˆ็ฒพ็กฎ/ๅ›พ/ๅ…ณ้”ฎ่ฏ/่ฏญไน‰๏ผ‰่žๅˆ
234
+ โ”‚ โ”œโ”€โ”€ context/ # ๅœจ Token/ๅญ—็ฌฆ้ข„็ฎ—ๅ†…ๆž„ๅปบไธŠไธ‹ๆ–‡ๅŒ…
235
+ โ”‚ โ”œโ”€โ”€ subgraph/ # ็ป้ชŒ่ฏ็š„ไปฃ็ ๅญๅ›พ๏ผˆๅฝฑๅ“ / ๆต็จ‹ / ่ฏ„ๅฎก / ่ฐƒ่ฏ•๏ผ‰
236
+ โ”‚ โ”œโ”€โ”€ topology/ # ๆก†ๆžถ + ๆ•ฐๆฎๆตๆ‹“ๆ‰‘่พน
237
+ โ”‚ โ”œโ”€โ”€ reuse/ # ๅค็”จ / ้‡ๅคๆฃ€ๆต‹
238
+ โ”‚ โ”œโ”€โ”€ lsp/ # LSP ่พ…ๅŠฉ็š„็ฌฆๅท่งฃๆž
239
+ โ”‚ โ”œโ”€โ”€ watch/ # ็›‘ๅฌๅฎˆๆŠค่ฟ›็จ‹ใ€ไบ‹ไปถๆ—ฅๅฟ—ใ€่„ๆ–‡ไปถๅˆๅนถใ€่ฐƒๅบฆๅ™จ
240
+ โ”‚ โ”œโ”€โ”€ mcp/ # MCP ๅทฅๅ…ทๅฎšไน‰ไธŽๅค„็†ๅ™จ๏ผˆ่ฝป่–„้€‚้…ๅฑ‚๏ผ‰
241
+ โ”‚ โ”œโ”€โ”€ cli/ # ๅ‘ฝไปคๅ…ฅๅฃ๏ผˆcommander + ink ๅ‘ๅฏผ๏ผ‰
242
+ โ”‚ โ”œโ”€โ”€ web/ # ไปช่กจ็›˜ๅŽ็ซฏ๏ผˆexpress + ws๏ผ‰
243
+ โ”‚ โ”œโ”€โ”€ config/ # ่ฟ่กŒๆ—ถ้…็ฝฎ่งฃๆž
244
+ โ”‚ โ”œโ”€โ”€ project/ # ้กน็›ฎ่บซไปฝไธŽๅทฅไฝœๅŒบ่‡ชๅŠจไฝœ็”จๅŸŸ
245
+ โ”‚ โ”œโ”€โ”€ diagnostics/ # Doctor / ๅ†’็ƒŸๆฃ€ๆŸฅ
246
+ โ”‚ โ”œโ”€โ”€ types/ # ๅ…ฑไบซ็ฑปๅž‹ๅฃฐๆ˜Ž
247
+ โ”‚ โ””โ”€โ”€ utils/ # ๅฐๅž‹ๅ…ฑไบซๅทฅๅ…ท๏ผˆ้ž้ข†ๅŸŸๆ‰€ๆœ‰่€…๏ผ‰
248
+ โ”œโ”€โ”€ tests/ # Vitest ๅ›žๅฝ’ๆต‹่ฏ•ๅฅ—ไปถ๏ผˆๅŸบ็ก€ใ€ๅ›พใ€ๆฃ€็ดขใ€็›‘ๅฌโ€ฆโ€ฆ๏ผ‰
249
+ โ”œโ”€โ”€ docs/ # ๆžถๆž„็ฌ”่ฎฐใ€ๅฅ‘็บฆไธŽๅ†ณ็ญ–่ฎฐๅฝ•
250
+ โ”œโ”€โ”€ integrations/ # Codex/OMX ๆ™บ่ƒฝไฝ“ๆŠ€่ƒฝๆจกๆฟ๏ผˆragcode-context๏ผ‰
251
+ โ”œโ”€โ”€ scripts/ # init-configใ€setup-mcpใ€ๅŸบๅ‡†ๆต‹่ฏ•ใ€่ฏ„ไผฐใ€ๅฎก่ฎก
252
+ โ”œโ”€โ”€ web/ # Vue ไปช่กจ็›˜ๅ‰็ซฏ
253
+ โ””โ”€โ”€ benchmarks/ # ๅŸบๅ‡†ๆต‹่ฏ•ๅคนๅ…ทไธŽ็ป“ๆžœ
254
+ ```
255
+
256
+ ---
257
+
258
+ ## ๆ ธๅฟƒ็‰นๆ€ง
259
+
260
+ - **ๆททๅˆๆฃ€็ดข** โ€” ่žๅˆ็ฒพ็กฎใ€ๅ›พใ€ๅ…ณ้”ฎ่ฏไธŽ่ฏญไน‰ไฟกๅท๏ผŒๅ†ๅบ”็”จๆŒ‰ๆจกๅผ็š„ๅŠ ๆƒไธŽๅ›พ่ท็ฆป้‡ๆŽ’ใ€‚ๆœ€็ปˆๅˆ†ๆ•ฐ้žๆญฃ็š„ๅ€™้€‰ไผš่ขซ่ฟ‡ๆปคๆމใ€‚
261
+ - **ๆจกๅผๆ„Ÿ็Ÿฅ็š„ไธŠไธ‹ๆ–‡ๆ‰“ๅŒ…** โ€” ไปŽๆŸฅ่ฏขไธญ่งฃๆžๆฃ€็ดขๆจกๅผ๏ผš`debug`ใ€`feature`ใ€`refactor`ใ€`review` ๆˆ– `explain`๏ผŒๆฏ็งๆจกๅผไผ˜ๅ…ˆๅ…ณๆณจไธๅŒ็ฑปๅž‹็š„่ฏๆฎใ€‚
262
+ - **ไธŠไธ‹ๆ–‡ๅŒ…ๅฅ‘็บฆ** โ€” `brief`ใ€`freshness`ใ€`ownerChain`ใ€`topology`ใ€่ฏๆฎ็‰‡ๆฎตใ€`missingEvidence` ไปฅๅŠ `nextQueries`๏ผŒ้™„ๅธฆๆฅๆบๅผ•็”จไธŽ็œ็•ฅ็ปŸ่ฎกใ€‚่ฟ”ๅ›žไธ็กฎๅฎšๆ€ง๏ผŒ่ƒœ่ฟ‡ๅคธๅคงๅ…ถ่ฏใ€‚
263
+ - **็ป“ๆž„ๅŒ–ไปฃ็ ๅ›พ** โ€” ็ฌฆๅทใ€ๆ–‡ไปถ๏ผŒไปฅๅŠ `contains` / `imports` / `exports` / `calls` ่พน๏ผŒ็”ฑ SQLite + FTS ๆˆ–ๅ†…ๅญ˜ๅญ˜ๅ‚จๆ”ฏๆ’‘ใ€‚
264
+ - **ๆก†ๆžถ + ๆ•ฐๆฎๆตๆ‹“ๆ‰‘** โ€” ๆœ‰็•Œ็š„่ทฏ็”ฑ/ORM ่ฏๆฎ๏ผˆNext.jsใ€Expressใ€Fastifyใ€Prismaใ€Drizzle๏ผ‰๏ผŒไปฅ `calls_api`ใ€`routes_to`ใ€`reads_from`ใ€`writes_to` ไปฅๅŠ่ฏทๆฑ‚่ดŸ่ฝฝ `orm_dataflow` ่พน็š„ๅฝขๅผไบงๅ‡บใ€‚
265
+ - **ๅคš่ฏญ่จ€ๅˆ†ๆž** โ€” ้€š่ฟ‡ TS Compiler API ๅฏน TypeScript/JavaScript ๆไพ›ๅฎŒๆ•ด AST ๆ”ฏๆŒ๏ผ›้€š่ฟ‡ tree-sitter ๅฏน Pythonใ€Goใ€Rustใ€Java ่ฟ›่กŒๅˆ†ๆž๏ผŒๅ…ถไป–ๆ–‡ไปถ็ฑปๅž‹ๅˆ™ๅ›ž้€€ๅˆฐๆŒ‰่กŒๅˆ†ๅ—ใ€‚
266
+ - **ๅขž้‡ๆ–ฐ้ฒœๅบฆ** โ€” chokidar OS ็›‘ๅฌ โ†’ ๆŒไน…ๅŒ–ไบ‹ไปถๆ—ฅๅฟ— โ†’ ่„ๆ–‡ไปถๅˆๅนถ โ†’ ๅŽๅฐๆ‰น้‡้‡ๅปบ็ดขๅผ•ใ€‚้‡ๅฏๆ—ถๅ›žๆ”พๆ—ฅๅฟ—๏ผŒ็กฎไฟ่„ๆ–‡ไปถๅทฅไฝœไธไธขๅคฑใ€‚
267
+ - **็ฆป็บฟไผ˜ๅ…ˆ** โ€” ็กฎๅฎšๆ€งๅตŒๅ…ฅๆ— ้œ€ API key๏ผ›ไปปไฝ•ๆ—ถๅ€™้ƒฝ่ƒฝๆขๆˆ OpenAI ๅ…ผๅฎน็š„ๆไพ›ๅ•†๏ผŒๆ— ้œ€้‡ๆž„ๆžถๆž„ใ€‚
268
+ - **MCP ๅŽŸ็”Ÿ** โ€” 19 ไธชๆ™บ่ƒฝไฝ“ๅทฅๅ…ท่ฟ่กŒๅœจ่ฝป่–„็š„ stdio ๆœๅŠกไน‹ไธŠ๏ผˆ็ดขๅผ•็”Ÿๅ‘ฝๅ‘จๆœŸใ€ๆœ็ดข/ไธŠไธ‹ๆ–‡ใ€ๅฝฑๅ“/ๆตๅ‘ใ€่ฏ„ๅฎก๏ผ‰๏ผŒๅค–ๅŠ ไธ€ไธช Codex/OMX ๆŠ€่ƒฝๆจกๆฟ๏ผŒๅผ•ๅฏผๆ™บ่ƒฝไฝ“ไผ˜ๅ…ˆ่ตฐ MCPใ€CLI ๅ…œๅบ•ใ€‚
269
+ - **Web ๅฏ่ง‚ๆต‹ๆ€ง** โ€” ๅ›พๅฏ่ง†ๅŒ–ใ€ๆœ็ดข่ฐƒ่ฏ•ๅ™จใ€ไธŠไธ‹ๆ–‡ๅŒ…ๆฃ€่ง†ๅ™จใ€็›‘ๅฌๅ™จ็›‘ๆŽง๏ผŒไปฅๅŠ่„ฑๆ•็š„่ฟ่กŒๆ—ถ้…็ฝฎ่ง†ๅ›พใ€‚
270
+
271
+ ---
272
+
273
+ ## ๅผ€ๅ‘ๆต็จ‹
274
+
275
+ ๅ…‹้š†ๅนถๅˆๅง‹ๅŒ–๏ผš
276
+
277
+ ```bash
278
+ git clone https://github.com/MarshallEriksen-Neura/ragcode.git
279
+ cd ragcode
280
+ npm install
281
+ ```
282
+
283
+ ๅธธ็”จไปปๅŠก๏ผˆnpm ๆ˜ฏ CI ไฝฟ็”จ็š„ๆ ‡ๅ‡†ๅทฅๅ…ท้“พ๏ผ›ๆœฌๅœฐไนŸๅฏ็”จ `bun`๏ผ‰๏ผš
284
+
285
+ ```bash
286
+ npm run dev -- doctor # ้€š่ฟ‡ tsx ไปŽๆบ็ ่ฟ่กŒ CLI
287
+ npm run check # TypeScript ไธฅๆ ผ็ฑปๅž‹ๆฃ€ๆŸฅ๏ผˆไธไบงๅ‡บๆ–‡ไปถ๏ผ‰
288
+ npm test # ่ฟ่กŒ Vitest ๆต‹่ฏ•ๅฅ—ไปถ
289
+ npm run test:watcher # ไป…่ฟ่กŒ็›‘ๅฌ็›ธๅ…ณๆต‹่ฏ•
290
+ npm run build # ้€š่ฟ‡ tsconfig.build.json ็ผ–่ฏ‘ๅˆฐ dist/
291
+ ```
292
+
293
+ **ๅˆ†ๆ”ฏ็ญ–็•ฅ๏ผš** `main` ๆ˜ฏๅ—ไฟๆŠค็š„้ป˜่ฎคๅˆ†ๆ”ฏใ€‚ๅœจๅŠŸ่ƒฝๅˆ†ๆ”ฏไธŠๅทฅไฝœ๏ผŒๅนถๅ‘ `main` ๆไบค Pull Requestโ€”โ€”ๅˆ‡ๅ‹ฟ็›ดๆŽฅๆŽจ้€ๅˆฐ `main`ใ€‚
294
+
295
+ **CI**๏ผˆ[.github/workflows/ci.yml](.github/workflows/ci.yml)๏ผ‰ไผšๅœจๆฏๆฌกๆŽจ้€ๅ’Œๅ‘ `main` ๆไบค PR ๆ—ถ๏ผŒๅœจ Node 24 ไธŠๆŒ‰้กบๅบๆ‰ง่กŒ๏ผš`npm ci` โ†’ `npm run check` โ†’ `npm run build` โ†’ `npm test` โ†’ `npm pack --dry-run`ใ€‚ๆ‰€ๆœ‰ๆญฅ้ชคๅฟ…้กป้€š่ฟ‡ๆ‰่ƒฝๅˆๅนถใ€‚ๅ‘ๅธƒ็”ฑ [.github/workflows/publish.yml](.github/workflows/publish.yml) ่‡ชๅŠจๅŒ–ๅฎŒๆˆใ€‚
296
+
297
+ ไฝฟ็”จ็กฎๅฎšๆ€งๅตŒๅ…ฅ่ฟ›่กŒ็ฆป็บฟๅ†’็ƒŸ่ฟ่กŒ๏ผš
298
+
299
+ ```bash
300
+ export RAGCODE_GRAPH_STORE=sqlite
301
+ export RAGCODE_SQLITE_PATH=.ragcode/graph.sqlite
302
+ export RAGCODE_SEMANTIC_STORE=lancedb
303
+ export RAGCODE_LANCEDB_URI=.ragcode/lancedb
304
+ export RAGCODE_EMBEDDING_PROVIDER=deterministic
305
+
306
+ npm run dev -- doctor . --query "context engine"
307
+ npm run dev -- index .
308
+ npm run dev -- search . "context engine"
309
+ ```
310
+
311
+ ---
312
+
313
+ ## ็ผ–็ ่ง„่Œƒ
314
+
315
+ - **TypeScript ไธฅๆ ผๆจกๅผใ€‚** ไปปไฝ•ๆ”นๅŠจๅœจ่ขซ่ง†ไธบๅฎŒๆˆไน‹ๅ‰๏ผŒ`npm run check`๏ผˆ`tsc --noEmit`๏ผ‰ๅฟ…้กป้›ถ้”™่ฏฏ้€š่ฟ‡ใ€‚
316
+ - **ๅ…จ็จ‹ ESMใ€‚** ๅŒ…ๆ˜ฏ `"type": "module"`๏ผ›ไฝฟ็”จ ES import/export ไปฅๅŠ `node:` ๅ‰็ผ€็š„ๅ†…็ฝฎๆจกๅ—ใ€‚
317
+ - **ๅฐŠ้‡ๅˆ†ๅฑ‚่พน็•Œใ€‚** ไพ่ต– `src/core` ไธญ็š„ๅฅ‘็บฆ๏ผŒ่€Œ้žๅ…ทไฝ“ๅญ˜ๅ‚จใ€‚`indexing` ไธๅพ—ๆ„Ÿ็Ÿฅ MCP๏ผ›`mcp` ๅฟ…้กปไฟๆŒ่ฝป่–„ใ€ไธๅซๆฃ€็ดข้€ป่พ‘๏ผ›`watch` ๅชไพ่ต– `ContextEngine` ๅฅ‘็บฆใ€‚
318
+ - **ๅญ˜ๅ‚จๅฏๆ›ฟๆขใ€‚** ไปปไฝ•่งฆๅŠๅ›พๆˆ–่ฏญไน‰ๅญ˜ๅ‚จ็š„ไปฃ็ ้ƒฝ่ฆ่ตฐ `GraphStore` / `SemanticStore` ๆŽฅๅฃ๏ผŒไปฅไพฟๆต‹่ฏ•ๅ’Œๆœชๆฅ็š„ๅŽ็ซฏ่ƒฝๅคŸๆ›ฟๆขใ€‚
319
+ - **็จณๅฎš็š„ ID ไธŽๅ“ˆๅธŒใ€‚** ๅˆ†ๅ—ๆ‹ฅๆœ‰็กฎๅฎšๆ€งๅ†…ๅฎนๅ“ˆๅธŒไธŽ็จณๅฎš IDโ€”โ€”ไฟฎๆ”นๅˆ†ๅ—ๆˆ–ๅˆ†ๆžๅ™จๆ—ถ่ฆไฟๆŒ่ฟ™ไธ€็‚นใ€‚
320
+ - **ๅœจ่พน็•Œๅค„ๆ ก้ชŒ่พ“ๅ…ฅ**๏ผŒไฝฟ็”จ `zod`๏ผŒๅฐคๅ…ถๆ˜ฏ MCP ๅทฅๅ…ท่พ“ๅ…ฅใ€‚
321
+ - **็ปไธๆ‰“ๅฐๅฏ†้’ฅใ€‚** ้…็ฝฎ่ง†ๅ›พไธŽๆไพ›ๅ•†ๆต‹่ฏ•ไผšๅฏน API key ่„ฑๆ•๏ผ›ๆ•ๆ„Ÿๆ–‡ไปถ๏ผˆ`.env`ใ€ๅฏ†้’ฅใ€ๅ‡ญๆฎ๏ผ‰ไผšไปŽ็ดขๅผ•ไธญ่ฟ‡ๆปคๆމใ€‚
322
+
323
+ ---
324
+
325
+ ## ๆต‹่ฏ•
326
+
327
+ ๆต‹่ฏ•ไฝฟ็”จ **Vitest**๏ผŒไฝไบŽ [tests/](tests/)๏ผˆ38+ ๅฅ—ไปถ๏ผ‰ใ€‚ๅฎƒไปฌ่ฆ†็›–ๆ•ดไธชๅŸบ็ก€่ฎพๆ–ฝ๏ผšๆ‰ซๆไธŽๅขž้‡็ดขๅผ•ใ€SQLite ไธŽ LanceDB ๅญ˜ๅ‚จใ€ๆททๅˆๆฃ€็ดขไธŽๅ›พ้‡ๆŽ’ใ€ไธŠไธ‹ๆ–‡ๆ‰“ๅŒ…ไธŽ้ชจๆžถๅŒ–ใ€ๆ‹“ๆ‰‘่งฃๆžใ€็›‘ๅฌๅฎˆๆŠค่ฟ›็จ‹ไธŽๆ—ฅๅฟ—ๅ›žๆ”พใ€MCP ๆœๅŠกๅทฅๅ…ท๏ผŒไปฅๅŠ onboarding/configure CLI ๅ‘ๅฏผใ€‚
328
+
329
+ ```bash
330
+ npm test # ๅฎŒๆ•ดๅฅ—ไปถ
331
+ npm run test:watcher # ไป…็›‘ๅฌๅฎˆๆŠค่ฟ›็จ‹ + ็Šถๆ€ๆต‹่ฏ•
332
+ npx vitest run tests/foundation.test.ts # ๅ•ไธชๅฅ—ไปถ
333
+ ```
334
+
335
+ ๅฝ“ๆปก่ถณไปฅไธ‹ๆกไปถๆ—ถ๏ผŒๅŸบ็ก€่ฎพๆ–ฝ่ขซ่ฎคไธบๆ˜ฏ็จณๅ›บ็š„๏ผšไป“ๅบ“ๅฏ็กฎๅฎšๆ€งๆ‰ซๆใ€ๅˆ†ๅ—ๆ‹ฅๆœ‰็จณๅฎš ID/ๅ“ˆๅธŒใ€ๅ›พไธŽ่ฏญไน‰ๅญ˜ๅ‚จๅฏๆ›ฟๆขใ€CLI ไธŽ MCP ่ฐƒ็”จๅŒไธ€ไธชๅผ•ๆ“Žใ€ไธฅๆ ผ็ฑปๅž‹ๆฃ€ๆŸฅ้€š่ฟ‡๏ผŒๅนถไธ”ๆ‰ซๆ/็ดขๅผ•/ๆœ็ดข/ไธŠไธ‹ๆ–‡ๆ‰“ๅŒ…้ƒฝ่ขซๆต‹่ฏ•่ฆ†็›–ใ€‚ไปปไฝ•่กŒไธบๅ˜ๆ›ด้ƒฝ่ฆๅŒๆญฅๅขžๅŠ ๆˆ–ๆ›ดๆ–ฐๆต‹่ฏ•๏ผŒๅนถๅฐ†็ผ–ๅ†™ไธŽ่ฏ„ๅฎกไฟๆŒไธบไธคไธช็‹ฌ็ซ‹็š„็Žฏ่Š‚ใ€‚
336
+
337
+ ---
338
+
339
+ ## ่ดก็ŒฎๆŒ‡ๅ—
340
+
341
+ 1. Fork ไป“ๅบ“๏ผŒๅนถไปŽ `main` ๅˆ‡ๅ‡บไธ€ไธชๅŠŸ่ƒฝๅˆ†ๆ”ฏใ€‚
342
+ 2. ่ฟ›่กŒๆ”นๅŠจ๏ผŒไฟๆŒๅœจ็›ธๅ…ณๅฑ‚็š„่พน็•Œๅ†…๏ผˆๅ‚่ง [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md)๏ผ‰ใ€‚
343
+ 3. ไธบไปปไฝ•่กŒไธบๅ˜ๆ›ดๅœจ [tests/](tests/) ไธญๅขžๅŠ ๆˆ–ๆ›ดๆ–ฐๆต‹่ฏ•ใ€‚
344
+ 4. ๆŽจ้€ๅ‰ๅœจๆœฌๅœฐ่ฟ่กŒๅฎŒๆ•ด็š„ๆฃ€ๆŸฅๅ…ณๅก๏ผš
345
+ ```bash
346
+ npm run check && npm test && npm run build
347
+ ```
348
+ 5. ๆŽจ้€ไฝ ็š„ๅˆ†ๆ”ฏ๏ผŒๅนถๅ‘ `main` ๆไบค Pull Request๏ผŒ้™„ไธŠ็ฎ€ๆ˜Ž็š„ๅ˜ๆ›ด่ฏดๆ˜ŽไธŽๆต‹่ฏ•ๆƒ…ๅ†ตใ€‚
349
+
350
+ ๅฏนไบŽๆ™บ่ƒฝไฝ“่พ…ๅŠฉ่ดก็Œฎ๏ผŒ[integrations/codex/skills/ragcode-context/](integrations/codex/skills/ragcode-context/) ไธญ็š„ Codex/OMX ๆŠ€่ƒฝๆจกๆฟไผšๅผ•ๅฏผๆ™บ่ƒฝไฝ“ไผ˜ๅ…ˆไฝฟ็”จ RagCode ็š„ MCP ๅทฅๅ…ท๏ผŒๅนถๆไพ› CLI ๅ…œๅบ•ไธŽ็ผบๅคฑ็ดขๅผ•ๆขๅคโ€”โ€”่ฏฆ่ง [docs/CODEX_SKILL.md](docs/CODEX_SKILL.md)ใ€‚
351
+
352
+ ### ๆ›ดๅคšๆ–‡ๆกฃ
353
+
354
+ - [docs/ARCHITECTURE.md](docs/ARCHITECTURE.md) โ€” ๅˆ†ๅฑ‚ไธŽ่Œ่ดฃ
355
+ - [docs/INDEX_SCHEMA.md](docs/INDEX_SCHEMA.md) โ€” ็ดขๅผ• schema
356
+ - [docs/DASHBOARD.md](docs/DASHBOARD.md) โ€” Web ไปช่กจ็›˜
357
+ - [docs/CODEX_SKILL.md](docs/CODEX_SKILL.md) โ€” Codex/OMX ๆ™บ่ƒฝไฝ“ๆŠ€่ƒฝ
358
+
359
+ ---
360
+
361
+ ## ่ฎธๅฏ่ฏ
362
+
363
+ ๅŸบไบŽ [MIT ่ฎธๅฏ่ฏ](./LICENSE) ๅ‘ๅธƒใ€‚Copyright (c) 2026 RagCode Teamใ€‚
@@ -0,0 +1,6 @@
1
+ import type { WizardState } from "./state.js";
2
+ export interface ConfigureAppProps {
3
+ initialState: WizardState;
4
+ onFinish: (state: WizardState) => void;
5
+ }
6
+ export declare function ConfigureApp({ initialState, onFinish }: ConfigureAppProps): React.ReactElement;
@@ -0,0 +1,81 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { Box, Text, useApp, useInput } from "ink";
3
+ import { useState } from "react";
4
+ import { answerCurrentStep, cancelWizard, currentStep } from "./state.js";
5
+ // Pure rendering layer over the wizard state machine. All flow decisions live in state.ts;
6
+ // this component only translates keystrokes into answerCurrentStep/cancelWizard calls.
7
+ export function ConfigureApp({ initialState, onFinish }) {
8
+ const { exit } = useApp();
9
+ const [state, setState] = useState(initialState);
10
+ const step = currentStep(state);
11
+ const submit = (value) => {
12
+ const next = answerCurrentStep(state, value);
13
+ setState(next);
14
+ if (next.done) {
15
+ onFinish(next);
16
+ exit();
17
+ }
18
+ };
19
+ const cancel = () => {
20
+ const next = cancelWizard(state);
21
+ setState(next);
22
+ onFinish(next);
23
+ exit();
24
+ };
25
+ return (_jsxs(Box, { flexDirection: "column", paddingX: 1, children: [_jsx(Text, { bold: true, color: "cyan", children: state.mode === "first_run" ? "๐Ÿง™ RagCode First-Run Setup" : "๐Ÿ›  RagCode Configure" }), _jsxs(Text, { dimColor: true, children: ["repo: ", state.repoRoot, " (Esc cancels)"] }), _jsx(AnsweredSummary, { state: state }), step ? _jsx(StepView, { step: step, onSubmit: submit, onCancel: cancel }, step.key) : null] }));
26
+ }
27
+ function AnsweredSummary({ state }) {
28
+ const answered = state.steps.filter((step) => state.answers[step.key] !== undefined && !step.skip?.(state.answers));
29
+ return (_jsx(Box, { flexDirection: "column", marginTop: 1, children: answered.map((step) => (_jsxs(Text, { dimColor: true, children: ["\u2713 ", step.title, ": ", step.secret ? (state.answers[step.key] ? "<set>" : "<unchanged>") : state.answers[step.key]] }, step.key))) }));
30
+ }
31
+ function StepView({ step, onSubmit, onCancel }) {
32
+ if (step.kind === "select")
33
+ return _jsx(SelectStep, { step: step, onSubmit: onSubmit, onCancel: onCancel });
34
+ if (step.kind === "confirm")
35
+ return _jsx(ConfirmStep, { step: step, onSubmit: onSubmit, onCancel: onCancel });
36
+ return _jsx(TextStep, { step: step, onSubmit: onSubmit, onCancel: onCancel });
37
+ }
38
+ function SelectStep({ step, onSubmit, onCancel }) {
39
+ const options = step.options ?? [];
40
+ const defaultIndex = Math.max(0, options.findIndex((option) => option.value === step.defaultValue));
41
+ const [cursor, setCursor] = useState(defaultIndex);
42
+ useInput((_input, key) => {
43
+ if (key.escape)
44
+ return onCancel();
45
+ if (key.upArrow)
46
+ setCursor((index) => (index - 1 + options.length) % options.length);
47
+ if (key.downArrow)
48
+ setCursor((index) => (index + 1) % options.length);
49
+ if (key.return)
50
+ onSubmit(options[cursor]?.value ?? step.defaultValue);
51
+ });
52
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, children: step.title }), options.map((option, index) => (_jsxs(Text, { color: index === cursor ? "green" : undefined, children: [index === cursor ? "โฏ " : " ", option.label] }, option.value))), _jsx(Text, { dimColor: true, children: "\u2191/\u2193 to choose, Enter to confirm" })] }));
53
+ }
54
+ function ConfirmStep({ step, onSubmit, onCancel }) {
55
+ useInput((input, key) => {
56
+ if (key.escape)
57
+ return onCancel();
58
+ if (input.toLowerCase() === "y")
59
+ return onSubmit("yes");
60
+ if (input.toLowerCase() === "n")
61
+ return onSubmit("no");
62
+ if (key.return)
63
+ onSubmit(step.defaultValue);
64
+ });
65
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, children: step.title }), _jsxs(Text, { dimColor: true, children: ["y/n, Enter = ", step.defaultValue] })] }));
66
+ }
67
+ function TextStep({ step, onSubmit, onCancel }) {
68
+ const [value, setValue] = useState("");
69
+ useInput((input, key) => {
70
+ if (key.escape)
71
+ return onCancel();
72
+ if (key.return)
73
+ return onSubmit(value);
74
+ if (key.backspace || key.delete)
75
+ return setValue((current) => current.slice(0, -1));
76
+ if (input && !key.ctrl && !key.meta)
77
+ setValue((current) => current + input);
78
+ });
79
+ const display = step.secret ? "*".repeat(value.length) : value;
80
+ return (_jsxs(Box, { flexDirection: "column", marginTop: 1, children: [_jsx(Text, { bold: true, children: step.title }), _jsxs(Text, { children: ["> ", display, _jsx(Text, { inverse: true, children: " " })] }), step.defaultValue ? _jsxs(Text, { dimColor: true, children: ["Enter keeps: ", step.secret ? "<existing>" : step.defaultValue] }) : _jsx(Text, { dimColor: true, children: "Enter to skip" })] }));
81
+ }
@@ -0,0 +1,5 @@
1
+ import { type WizardMode } from "./state.js";
2
+ export declare function runInkConfigure(options: {
3
+ repoRoot: string;
4
+ mode: WizardMode;
5
+ }): Promise<void>;
@@ -0,0 +1,85 @@
1
+ import { jsx as _jsx } from "react/jsx-runtime";
2
+ import path from "node:path";
3
+ import { render } from "ink";
4
+ import { createRuntimeComponentsForRepo, loadRuntimeConfig, redactRuntimeConfig } from "../../config/runtime-config.js";
5
+ import { RagCodeEngine } from "../../core/engine.js";
6
+ import { runEmbeddingTest } from "../../diagnostics/embedding-test.js";
7
+ import { setupMCP } from "../../../scripts/setup-mcp.js";
8
+ import { applyConfigureUpdates } from "../configure.js";
9
+ import { ConfigureApp } from "./app.js";
10
+ import { createWizardState, wizardResult } from "./state.js";
11
+ // Orchestrates the Ink wizard: render the UI, then execute the collected actions in PRD
12
+ // order (test embedding -> save -> index -> setup MCP -> summary). All config IO stays in
13
+ // runtime-config/configure; the Ink app only collects answers.
14
+ export async function runInkConfigure(options) {
15
+ const repoRoot = path.resolve(options.repoRoot);
16
+ const current = redactRuntimeConfig(loadRuntimeConfig({ cwd: repoRoot, overrides: { repoRoot } }));
17
+ let finalState;
18
+ const { waitUntilExit } = render(_jsx(ConfigureApp, { initialState: createWizardState(options.mode, repoRoot, current), onFinish: (state) => {
19
+ finalState = state;
20
+ } }));
21
+ await waitUntilExit();
22
+ const result = finalState ? wizardResult(finalState) : undefined;
23
+ if (!result) {
24
+ console.log("Configuration unchanged.");
25
+ return;
26
+ }
27
+ if (result.actions.testEmbedding) {
28
+ // Test against the would-be config before persisting anything.
29
+ const test = await runEmbeddingTest({ cwd: repoRoot, overrides: { repoRoot, ...result.updates } });
30
+ if (test.ok) {
31
+ console.log(`๐Ÿงช Embedding test OK: provider=${test.provider}${test.model ? ` model=${test.model}` : ""} dimensions=${test.dimensions} latency=${test.latencyMs}ms`);
32
+ }
33
+ else {
34
+ console.log(`๐Ÿงช Embedding test FAILED (${test.failure?.kind}): ${test.failure?.message}`);
35
+ console.log(" Saving anyway keeps the config editable via `ragcode configure`; the offline deterministic provider always works.");
36
+ }
37
+ }
38
+ if (!result.actions.save) {
39
+ console.log("Configuration not saved.");
40
+ return;
41
+ }
42
+ const saved = await applyConfigureUpdates({ repoRoot, updates: result.updates });
43
+ console.log(`โœ… Configuration saved to: ${saved.configPath}`);
44
+ if (result.actions.indexNow) {
45
+ console.log("๐Ÿ“ฆ Indexing repository...");
46
+ const components = createRuntimeComponentsForRepo({ cwd: repoRoot, overrides: { repoRoot } });
47
+ const engine = new RagCodeEngine({
48
+ cwd: repoRoot,
49
+ graphStore: components.graphStore,
50
+ semanticStore: components.semanticStore,
51
+ embeddingProvider: components.embeddingProvider
52
+ });
53
+ try {
54
+ const index = await engine.indexRepo(repoRoot);
55
+ console.log(`โœ… Indexed ${index.files.length} files, ${index.chunks.length} chunks.`);
56
+ }
57
+ finally {
58
+ engine.close();
59
+ }
60
+ }
61
+ if (result.actions.setupMcp) {
62
+ setupMCP({ cwd: repoRoot, env: process.env });
63
+ }
64
+ if (result.actions.installWatcherService) {
65
+ // Loaded lazily so the wizard doesn't pull in the service layer unless the user opts in.
66
+ const { installWatcherService } = await import("../../service/service-manager.js");
67
+ try {
68
+ const service = await installWatcherService(repoRoot);
69
+ console.log(service.ok ? `๐Ÿ‘ ${service.message}` : `โš ๏ธ ${service.message}`);
70
+ }
71
+ catch (error) {
72
+ console.log(`โš ๏ธ Could not install the background watcher service: ${error instanceof Error ? error.message : String(error)}`);
73
+ console.log(" You can still keep the index fresh by running `ragcode watch .` manually.");
74
+ }
75
+ }
76
+ console.log("\n๐Ÿš€ Summary / next steps:");
77
+ if (!result.actions.indexNow)
78
+ console.log(" ragcode index . # build the index");
79
+ if (!result.actions.setupMcp)
80
+ console.log(" ragcode setup-mcp # register the MCP server");
81
+ if (!result.actions.installWatcherService)
82
+ console.log(" ragcode service install . # keep the index fresh automatically");
83
+ console.log(" ragcode configure # adjust storage/embedding later");
84
+ console.log(" ragcode dashboard # observe graph/search/context/watch");
85
+ }
@@ -0,0 +1,42 @@
1
+ import type { RedactedRuntimeConfig } from "../../config/runtime-config.js";
2
+ import type { ConfigureUpdates } from "../configure.js";
3
+ export type WizardMode = "configure" | "first_run";
4
+ export interface SelectOption {
5
+ value: string;
6
+ label: string;
7
+ }
8
+ export interface WizardStep {
9
+ key: string;
10
+ kind: "select" | "text" | "confirm";
11
+ title: string;
12
+ options?: SelectOption[];
13
+ defaultValue: string;
14
+ secret?: boolean;
15
+ skip?: (answers: WizardAnswers) => boolean;
16
+ }
17
+ export type WizardAnswers = Record<string, string>;
18
+ export interface WizardState {
19
+ mode: WizardMode;
20
+ repoRoot: string;
21
+ steps: WizardStep[];
22
+ stepIndex: number;
23
+ answers: WizardAnswers;
24
+ done: boolean;
25
+ cancelled: boolean;
26
+ }
27
+ export interface WizardActions {
28
+ testEmbedding: boolean;
29
+ save: boolean;
30
+ indexNow: boolean;
31
+ setupMcp: boolean;
32
+ installWatcherService: boolean;
33
+ }
34
+ export interface WizardResult {
35
+ updates: ConfigureUpdates;
36
+ actions: WizardActions;
37
+ }
38
+ export declare function createWizardState(mode: WizardMode, repoRoot: string, current: RedactedRuntimeConfig): WizardState;
39
+ export declare function currentStep(state: WizardState): WizardStep | undefined;
40
+ export declare function answerCurrentStep(state: WizardState, rawValue: string): WizardState;
41
+ export declare function cancelWizard(state: WizardState): WizardState;
42
+ export declare function wizardResult(state: WizardState): WizardResult | undefined;