@cjhyy/code-shell-core 0.5.0-rc.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 (484) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +162 -0
  3. package/dist/agent/coordinator.d.ts +49 -0
  4. package/dist/agent/coordinator.js +77 -0
  5. package/dist/arena/arena.d.ts +43 -0
  6. package/dist/arena/arena.js +334 -0
  7. package/dist/arena/context/context-tools.d.ts +16 -0
  8. package/dist/arena/context/context-tools.js +231 -0
  9. package/dist/arena/detect-mode.d.ts +20 -0
  10. package/dist/arena/detect-mode.js +78 -0
  11. package/dist/arena/digest-builder.d.ts +25 -0
  12. package/dist/arena/digest-builder.js +120 -0
  13. package/dist/arena/index.d.ts +29 -0
  14. package/dist/arena/index.js +29 -0
  15. package/dist/arena/iterate/convergence.d.ts +25 -0
  16. package/dist/arena/iterate/convergence.js +103 -0
  17. package/dist/arena/iterate/formats/index.d.ts +22 -0
  18. package/dist/arena/iterate/formats/index.js +283 -0
  19. package/dist/arena/iterate/index.d.ts +11 -0
  20. package/dist/arena/iterate/index.js +9 -0
  21. package/dist/arena/iterate/iterative-arena.d.ts +23 -0
  22. package/dist/arena/iterate/iterative-arena.js +237 -0
  23. package/dist/arena/iterate/parse.d.ts +42 -0
  24. package/dist/arena/iterate/parse.js +123 -0
  25. package/dist/arena/iterate/phases/argue.d.ts +22 -0
  26. package/dist/arena/iterate/phases/argue.js +159 -0
  27. package/dist/arena/iterate/phases/revise.d.ts +16 -0
  28. package/dist/arena/iterate/phases/revise.js +62 -0
  29. package/dist/arena/iterate/phases/tournament.d.ts +34 -0
  30. package/dist/arena/iterate/phases/tournament.js +113 -0
  31. package/dist/arena/iterate/tools/web-tools.d.ts +13 -0
  32. package/dist/arena/iterate/tools/web-tools.js +54 -0
  33. package/dist/arena/iterate/types.d.ts +152 -0
  34. package/dist/arena/iterate/types.js +8 -0
  35. package/dist/arena/ledger.d.ts +47 -0
  36. package/dist/arena/ledger.js +151 -0
  37. package/dist/arena/lenses/architecture.d.ts +5 -0
  38. package/dist/arena/lenses/architecture.js +22 -0
  39. package/dist/arena/lenses/engineering.d.ts +5 -0
  40. package/dist/arena/lenses/engineering.js +22 -0
  41. package/dist/arena/lenses/general.d.ts +5 -0
  42. package/dist/arena/lenses/general.js +20 -0
  43. package/dist/arena/lenses/index.d.ts +16 -0
  44. package/dist/arena/lenses/index.js +47 -0
  45. package/dist/arena/lenses/product.d.ts +5 -0
  46. package/dist/arena/lenses/product.js +22 -0
  47. package/dist/arena/model-presets.d.ts +23 -0
  48. package/dist/arena/model-presets.js +44 -0
  49. package/dist/arena/phases/adjudication.d.ts +24 -0
  50. package/dist/arena/phases/adjudication.js +144 -0
  51. package/dist/arena/phases/build-consensus.d.ts +29 -0
  52. package/dist/arena/phases/build-consensus.js +86 -0
  53. package/dist/arena/phases/claim-registry.d.ts +26 -0
  54. package/dist/arena/phases/claim-registry.js +60 -0
  55. package/dist/arena/phases/cross-review.d.ts +45 -0
  56. package/dist/arena/phases/cross-review.js +224 -0
  57. package/dist/arena/phases/debate-rounds.d.ts +27 -0
  58. package/dist/arena/phases/debate-rounds.js +162 -0
  59. package/dist/arena/phases/participant-research.d.ts +38 -0
  60. package/dist/arena/phases/participant-research.js +317 -0
  61. package/dist/arena/phases/planning-detail-expansion.d.ts +38 -0
  62. package/dist/arena/phases/planning-detail-expansion.js +121 -0
  63. package/dist/arena/planner.d.ts +27 -0
  64. package/dist/arena/planner.js +312 -0
  65. package/dist/arena/providers/docs.d.ts +6 -0
  66. package/dist/arena/providers/docs.js +108 -0
  67. package/dist/arena/providers/git.d.ts +8 -0
  68. package/dist/arena/providers/git.js +174 -0
  69. package/dist/arena/providers/index.d.ts +32 -0
  70. package/dist/arena/providers/index.js +132 -0
  71. package/dist/arena/providers/none.d.ts +7 -0
  72. package/dist/arena/providers/none.js +11 -0
  73. package/dist/arena/providers/repo.d.ts +6 -0
  74. package/dist/arena/providers/repo.js +255 -0
  75. package/dist/arena/render/session.d.ts +17 -0
  76. package/dist/arena/render/session.js +190 -0
  77. package/dist/arena/render/terminal.d.ts +34 -0
  78. package/dist/arena/render/terminal.js +286 -0
  79. package/dist/arena/strategies/discussion.d.ts +25 -0
  80. package/dist/arena/strategies/discussion.js +143 -0
  81. package/dist/arena/strategies/index.d.ts +15 -0
  82. package/dist/arena/strategies/index.js +28 -0
  83. package/dist/arena/strategies/language-wrapper.d.ts +17 -0
  84. package/dist/arena/strategies/language-wrapper.js +102 -0
  85. package/dist/arena/strategies/lens-wrapper.d.ts +16 -0
  86. package/dist/arena/strategies/lens-wrapper.js +236 -0
  87. package/dist/arena/strategies/planning.d.ts +30 -0
  88. package/dist/arena/strategies/planning.js +225 -0
  89. package/dist/arena/strategies/review.d.ts +26 -0
  90. package/dist/arena/strategies/review.js +168 -0
  91. package/dist/arena/strategies/utils.d.ts +39 -0
  92. package/dist/arena/strategies/utils.js +647 -0
  93. package/dist/arena/tools/selector.d.ts +17 -0
  94. package/dist/arena/tools/selector.js +61 -0
  95. package/dist/arena/transitions.d.ts +48 -0
  96. package/dist/arena/transitions.js +92 -0
  97. package/dist/arena/types.d.ts +508 -0
  98. package/dist/arena/types.js +27 -0
  99. package/dist/cli/agent-server-stdio.d.ts +32 -0
  100. package/dist/cli/agent-server-stdio.js +116 -0
  101. package/dist/colorizer.d.ts +23 -0
  102. package/dist/colorizer.js +12 -0
  103. package/dist/context/compaction.d.ts +116 -0
  104. package/dist/context/compaction.js +534 -0
  105. package/dist/context/manager.d.ts +145 -0
  106. package/dist/context/manager.js +423 -0
  107. package/dist/context/token-counter.d.ts +27 -0
  108. package/dist/context/token-counter.js +91 -0
  109. package/dist/context/tool-result-storage.d.ts +96 -0
  110. package/dist/context/tool-result-storage.js +296 -0
  111. package/dist/cost-tracker.d.ts +64 -0
  112. package/dist/cost-tracker.js +314 -0
  113. package/dist/cron/scheduler.d.ts +34 -0
  114. package/dist/cron/scheduler.js +115 -0
  115. package/dist/data/deepseek-models.json +46 -0
  116. package/dist/data/gemini-models.json +67 -0
  117. package/dist/data/openai-models.json +175 -0
  118. package/dist/data/openrouter-models.d.ts +35 -0
  119. package/dist/data/openrouter-models.js +36 -0
  120. package/dist/data/openrouter-models.json +4626 -0
  121. package/dist/data/openrouter-sync.d.ts +16 -0
  122. package/dist/data/openrouter-sync.js +53 -0
  123. package/dist/data/static-catalogs.d.ts +25 -0
  124. package/dist/data/static-catalogs.js +26 -0
  125. package/dist/data/zai-models.json +56 -0
  126. package/dist/engine/cost-store.d.ts +22 -0
  127. package/dist/engine/cost-store.js +15 -0
  128. package/dist/engine/engine.d.ts +295 -0
  129. package/dist/engine/engine.js +1467 -0
  130. package/dist/engine/model-facade.d.ts +24 -0
  131. package/dist/engine/model-facade.js +194 -0
  132. package/dist/engine/parse-task.d.ts +59 -0
  133. package/dist/engine/parse-task.js +135 -0
  134. package/dist/engine/patch-orphaned-tools.d.ts +52 -0
  135. package/dist/engine/patch-orphaned-tools.js +95 -0
  136. package/dist/engine/query.d.ts +50 -0
  137. package/dist/engine/query.js +107 -0
  138. package/dist/engine/runtime.d.ts +50 -0
  139. package/dist/engine/runtime.js +59 -0
  140. package/dist/engine/streaming-tool-queue.d.ts +34 -0
  141. package/dist/engine/streaming-tool-queue.js +61 -0
  142. package/dist/engine/token-budget.d.ts +22 -0
  143. package/dist/engine/token-budget.js +40 -0
  144. package/dist/engine/tool-summary.d.ts +13 -0
  145. package/dist/engine/tool-summary.js +35 -0
  146. package/dist/engine/turn-loop.d.ts +122 -0
  147. package/dist/engine/turn-loop.js +602 -0
  148. package/dist/engine/turn-state.d.ts +20 -0
  149. package/dist/engine/turn-state.js +17 -0
  150. package/dist/exceptions.d.ts +61 -0
  151. package/dist/exceptions.js +116 -0
  152. package/dist/git/utils.d.ts +35 -0
  153. package/dist/git/utils.js +98 -0
  154. package/dist/git/worktree.d.ts +36 -0
  155. package/dist/git/worktree.js +139 -0
  156. package/dist/hooks/events.d.ts +114 -0
  157. package/dist/hooks/events.js +4 -0
  158. package/dist/hooks/inject.d.ts +19 -0
  159. package/dist/hooks/inject.js +29 -0
  160. package/dist/hooks/registry.d.ts +15 -0
  161. package/dist/hooks/registry.js +84 -0
  162. package/dist/hooks/shell-runner.d.ts +45 -0
  163. package/dist/hooks/shell-runner.js +173 -0
  164. package/dist/index.d.ts +117 -0
  165. package/dist/index.js +145 -0
  166. package/dist/llm/api-key-sanitize.d.ts +22 -0
  167. package/dist/llm/api-key-sanitize.js +81 -0
  168. package/dist/llm/capabilities/index.d.ts +20 -0
  169. package/dist/llm/capabilities/index.js +39 -0
  170. package/dist/llm/capabilities/rules.d.ts +26 -0
  171. package/dist/llm/capabilities/rules.js +215 -0
  172. package/dist/llm/capabilities/types.d.ts +114 -0
  173. package/dist/llm/capabilities/types.js +24 -0
  174. package/dist/llm/client-base.d.ts +29 -0
  175. package/dist/llm/client-base.js +137 -0
  176. package/dist/llm/client-factory.d.ts +10 -0
  177. package/dist/llm/client-factory.js +29 -0
  178. package/dist/llm/model-cache.d.ts +21 -0
  179. package/dist/llm/model-cache.js +46 -0
  180. package/dist/llm/model-fetcher.d.ts +29 -0
  181. package/dist/llm/model-fetcher.js +282 -0
  182. package/dist/llm/model-pool.d.ts +95 -0
  183. package/dist/llm/model-pool.js +246 -0
  184. package/dist/llm/provider-catalog.d.ts +32 -0
  185. package/dist/llm/provider-catalog.js +50 -0
  186. package/dist/llm/provider-kinds.d.ts +21 -0
  187. package/dist/llm/provider-kinds.js +132 -0
  188. package/dist/llm/providers/anthropic.d.ts +19 -0
  189. package/dist/llm/providers/anthropic.js +267 -0
  190. package/dist/llm/providers/openai.d.ts +64 -0
  191. package/dist/llm/providers/openai.js +606 -0
  192. package/dist/llm/retry.d.ts +12 -0
  193. package/dist/llm/retry.js +17 -0
  194. package/dist/llm/stream-watchdog.d.ts +42 -0
  195. package/dist/llm/stream-watchdog.js +70 -0
  196. package/dist/llm/token-counter.d.ts +17 -0
  197. package/dist/llm/token-counter.js +36 -0
  198. package/dist/llm/types.d.ts +37 -0
  199. package/dist/llm/types.js +4 -0
  200. package/dist/logging/logger.d.ts +109 -0
  201. package/dist/logging/logger.js +390 -0
  202. package/dist/logging/sanitize-messages.d.ts +42 -0
  203. package/dist/logging/sanitize-messages.js +150 -0
  204. package/dist/logging/session-recorder.d.ts +90 -0
  205. package/dist/logging/session-recorder.js +304 -0
  206. package/dist/lsp/client.d.ts +41 -0
  207. package/dist/lsp/client.js +166 -0
  208. package/dist/lsp/manager.d.ts +40 -0
  209. package/dist/lsp/manager.js +124 -0
  210. package/dist/lsp/servers.d.ts +16 -0
  211. package/dist/lsp/servers.js +60 -0
  212. package/dist/migrate-models.d.ts +45 -0
  213. package/dist/migrate-models.js +179 -0
  214. package/dist/onboarding.d.ts +189 -0
  215. package/dist/onboarding.js +625 -0
  216. package/dist/plugins/gitOps.d.ts +32 -0
  217. package/dist/plugins/gitOps.js +62 -0
  218. package/dist/plugins/installedPlugins.d.ts +15 -0
  219. package/dist/plugins/installedPlugins.js +56 -0
  220. package/dist/plugins/knownMarketplaces.d.ts +10 -0
  221. package/dist/plugins/knownMarketplaces.js +46 -0
  222. package/dist/plugins/loadPluginHooks.d.ts +52 -0
  223. package/dist/plugins/loadPluginHooks.js +162 -0
  224. package/dist/plugins/marketplaceManager.d.ts +49 -0
  225. package/dist/plugins/marketplaceManager.js +142 -0
  226. package/dist/plugins/parseMarketplaceInput.d.ts +16 -0
  227. package/dist/plugins/parseMarketplaceInput.js +73 -0
  228. package/dist/plugins/pluginCommandHook.d.ts +54 -0
  229. package/dist/plugins/pluginCommandHook.js +180 -0
  230. package/dist/plugins/pluginCommandsLoader.d.ts +25 -0
  231. package/dist/plugins/pluginCommandsLoader.js +114 -0
  232. package/dist/plugins/pluginInstaller.d.ts +36 -0
  233. package/dist/plugins/pluginInstaller.js +228 -0
  234. package/dist/plugins/schemas.d.ts +9 -0
  235. package/dist/plugins/schemas.js +136 -0
  236. package/dist/plugins/types.d.ts +75 -0
  237. package/dist/plugins/types.js +7 -0
  238. package/dist/plugins/varRewrite.d.ts +42 -0
  239. package/dist/plugins/varRewrite.js +129 -0
  240. package/dist/preset/index.d.ts +60 -0
  241. package/dist/preset/index.js +159 -0
  242. package/dist/product/define.d.ts +60 -0
  243. package/dist/product/define.js +123 -0
  244. package/dist/product/index.d.ts +5 -0
  245. package/dist/product/index.js +4 -0
  246. package/dist/product/types.d.ts +111 -0
  247. package/dist/product/types.js +21 -0
  248. package/dist/prompt/composer.d.ts +49 -0
  249. package/dist/prompt/composer.js +168 -0
  250. package/dist/prompt/instruction-scanner.d.ts +54 -0
  251. package/dist/prompt/instruction-scanner.js +187 -0
  252. package/dist/prompt/section-cache.d.ts +15 -0
  253. package/dist/prompt/section-cache.js +31 -0
  254. package/dist/prompt/section-loader.d.ts +26 -0
  255. package/dist/prompt/section-loader.js +53 -0
  256. package/dist/prompt/sections/base.md +35 -0
  257. package/dist/prompt/sections/coding.md +31 -0
  258. package/dist/prompt/sections/orchestration.md +16 -0
  259. package/dist/prompt/sections/tone.md +9 -0
  260. package/dist/protocol/chat-session-manager.d.ts +33 -0
  261. package/dist/protocol/chat-session-manager.js +65 -0
  262. package/dist/protocol/chat-session.d.ts +49 -0
  263. package/dist/protocol/chat-session.js +86 -0
  264. package/dist/protocol/client.d.ts +104 -0
  265. package/dist/protocol/client.js +260 -0
  266. package/dist/protocol/factories.d.ts +93 -0
  267. package/dist/protocol/factories.js +64 -0
  268. package/dist/protocol/helpers.d.ts +42 -0
  269. package/dist/protocol/helpers.js +55 -0
  270. package/dist/protocol/index.d.ts +4 -0
  271. package/dist/protocol/index.js +4 -0
  272. package/dist/protocol/server.d.ts +80 -0
  273. package/dist/protocol/server.js +855 -0
  274. package/dist/protocol/transport.d.ts +37 -0
  275. package/dist/protocol/transport.js +85 -0
  276. package/dist/protocol/types.d.ts +221 -0
  277. package/dist/protocol/types.js +61 -0
  278. package/dist/remote/bridge.d.ts +37 -0
  279. package/dist/remote/bridge.js +103 -0
  280. package/dist/run/ArtifactTracker.d.ts +38 -0
  281. package/dist/run/ArtifactTracker.js +132 -0
  282. package/dist/run/CheckpointWriter.d.ts +53 -0
  283. package/dist/run/CheckpointWriter.js +135 -0
  284. package/dist/run/EngineRunner.d.ts +72 -0
  285. package/dist/run/EngineRunner.js +119 -0
  286. package/dist/run/Evaluator.d.ts +56 -0
  287. package/dist/run/Evaluator.js +62 -0
  288. package/dist/run/FileRunStore.d.ts +39 -0
  289. package/dist/run/FileRunStore.js +176 -0
  290. package/dist/run/Heartbeat.d.ts +54 -0
  291. package/dist/run/Heartbeat.js +123 -0
  292. package/dist/run/RunApprovalBackend.d.ts +53 -0
  293. package/dist/run/RunApprovalBackend.js +85 -0
  294. package/dist/run/RunLock.d.ts +40 -0
  295. package/dist/run/RunLock.js +98 -0
  296. package/dist/run/RunManager.d.ts +82 -0
  297. package/dist/run/RunManager.js +587 -0
  298. package/dist/run/RunQueue.d.ts +27 -0
  299. package/dist/run/RunQueue.js +73 -0
  300. package/dist/run/RunStore.d.ts +25 -0
  301. package/dist/run/RunStore.js +9 -0
  302. package/dist/run/factory.d.ts +63 -0
  303. package/dist/run/factory.js +51 -0
  304. package/dist/run/index.d.ts +17 -0
  305. package/dist/run/index.js +23 -0
  306. package/dist/run/types.d.ts +136 -0
  307. package/dist/run/types.js +28 -0
  308. package/dist/runtime/safe-spawn.d.ts +118 -0
  309. package/dist/runtime/safe-spawn.js +268 -0
  310. package/dist/services/analytics.d.ts +29 -0
  311. package/dist/services/analytics.js +84 -0
  312. package/dist/services/auto-dream.d.ts +49 -0
  313. package/dist/services/auto-dream.js +124 -0
  314. package/dist/services/diagnostics.d.ts +41 -0
  315. package/dist/services/diagnostics.js +99 -0
  316. package/dist/services/extract-memories.d.ts +31 -0
  317. package/dist/services/extract-memories.js +71 -0
  318. package/dist/services/index.d.ts +11 -0
  319. package/dist/services/index.js +17 -0
  320. package/dist/services/memory-orchestrator.d.ts +60 -0
  321. package/dist/services/memory-orchestrator.js +133 -0
  322. package/dist/services/notifier.d.ts +25 -0
  323. package/dist/services/notifier.js +69 -0
  324. package/dist/services/oauth.d.ts +27 -0
  325. package/dist/services/oauth.js +153 -0
  326. package/dist/services/session-memory.d.ts +37 -0
  327. package/dist/services/session-memory.js +81 -0
  328. package/dist/session/file-history.d.ts +41 -0
  329. package/dist/session/file-history.js +115 -0
  330. package/dist/session/memory.d.ts +104 -0
  331. package/dist/session/memory.js +310 -0
  332. package/dist/session/session-manager.d.ts +41 -0
  333. package/dist/session/session-manager.js +261 -0
  334. package/dist/session/transcript.d.ts +39 -0
  335. package/dist/session/transcript.js +186 -0
  336. package/dist/settings/manager.d.ts +36 -0
  337. package/dist/settings/manager.js +187 -0
  338. package/dist/settings/schema.d.ts +1219 -0
  339. package/dist/settings/schema.js +246 -0
  340. package/dist/skills/frontmatter.d.ts +13 -0
  341. package/dist/skills/frontmatter.js +70 -0
  342. package/dist/skills/index.d.ts +7 -0
  343. package/dist/skills/index.js +6 -0
  344. package/dist/skills/scanner.d.ts +31 -0
  345. package/dist/skills/scanner.js +171 -0
  346. package/dist/state.d.ts +160 -0
  347. package/dist/state.js +267 -0
  348. package/dist/tool-system/builtin/agent-notifications.d.ts +84 -0
  349. package/dist/tool-system/builtin/agent-notifications.js +197 -0
  350. package/dist/tool-system/builtin/agent-registry.d.ts +67 -0
  351. package/dist/tool-system/builtin/agent-registry.js +126 -0
  352. package/dist/tool-system/builtin/agent-transcript-translator.d.ts +22 -0
  353. package/dist/tool-system/builtin/agent-transcript-translator.js +160 -0
  354. package/dist/tool-system/builtin/agent.d.ts +16 -0
  355. package/dist/tool-system/builtin/agent.js +364 -0
  356. package/dist/tool-system/builtin/apply-patch/applier.d.ts +26 -0
  357. package/dist/tool-system/builtin/apply-patch/applier.js +250 -0
  358. package/dist/tool-system/builtin/apply-patch/index.d.ts +20 -0
  359. package/dist/tool-system/builtin/apply-patch/index.js +101 -0
  360. package/dist/tool-system/builtin/apply-patch/parser.d.ts +17 -0
  361. package/dist/tool-system/builtin/apply-patch/parser.js +212 -0
  362. package/dist/tool-system/builtin/apply-patch/seek-sequence.d.ts +18 -0
  363. package/dist/tool-system/builtin/apply-patch/seek-sequence.js +123 -0
  364. package/dist/tool-system/builtin/apply-patch/types.d.ts +49 -0
  365. package/dist/tool-system/builtin/apply-patch/types.js +13 -0
  366. package/dist/tool-system/builtin/arena.d.ts +31 -0
  367. package/dist/tool-system/builtin/arena.js +416 -0
  368. package/dist/tool-system/builtin/ask-user.d.ts +20 -0
  369. package/dist/tool-system/builtin/ask-user.js +99 -0
  370. package/dist/tool-system/builtin/bash.d.ts +21 -0
  371. package/dist/tool-system/builtin/bash.js +149 -0
  372. package/dist/tool-system/builtin/brief.d.ts +6 -0
  373. package/dist/tool-system/builtin/brief.js +41 -0
  374. package/dist/tool-system/builtin/config.d.ts +6 -0
  375. package/dist/tool-system/builtin/config.js +67 -0
  376. package/dist/tool-system/builtin/cron.d.ts +10 -0
  377. package/dist/tool-system/builtin/cron.js +61 -0
  378. package/dist/tool-system/builtin/edit.d.ts +6 -0
  379. package/dist/tool-system/builtin/edit.js +100 -0
  380. package/dist/tool-system/builtin/file-cache.d.ts +11 -0
  381. package/dist/tool-system/builtin/file-cache.js +39 -0
  382. package/dist/tool-system/builtin/glob.d.ts +7 -0
  383. package/dist/tool-system/builtin/glob.js +76 -0
  384. package/dist/tool-system/builtin/grep.d.ts +7 -0
  385. package/dist/tool-system/builtin/grep.js +150 -0
  386. package/dist/tool-system/builtin/index.d.ts +20 -0
  387. package/dist/tool-system/builtin/index.js +449 -0
  388. package/dist/tool-system/builtin/lsp.d.ts +6 -0
  389. package/dist/tool-system/builtin/lsp.js +141 -0
  390. package/dist/tool-system/builtin/mcp-tools.d.ts +10 -0
  391. package/dist/tool-system/builtin/mcp-tools.js +102 -0
  392. package/dist/tool-system/builtin/memory.d.ts +26 -0
  393. package/dist/tool-system/builtin/memory.js +226 -0
  394. package/dist/tool-system/builtin/notebook-edit.d.ts +6 -0
  395. package/dist/tool-system/builtin/notebook-edit.js +124 -0
  396. package/dist/tool-system/builtin/plan.d.ts +15 -0
  397. package/dist/tool-system/builtin/plan.js +55 -0
  398. package/dist/tool-system/builtin/powershell.d.ts +11 -0
  399. package/dist/tool-system/builtin/powershell.js +64 -0
  400. package/dist/tool-system/builtin/read.d.ts +6 -0
  401. package/dist/tool-system/builtin/read.js +70 -0
  402. package/dist/tool-system/builtin/remote-trigger.d.ts +6 -0
  403. package/dist/tool-system/builtin/remote-trigger.js +54 -0
  404. package/dist/tool-system/builtin/repl.d.ts +11 -0
  405. package/dist/tool-system/builtin/repl.js +82 -0
  406. package/dist/tool-system/builtin/send-message.d.ts +6 -0
  407. package/dist/tool-system/builtin/send-message.js +47 -0
  408. package/dist/tool-system/builtin/skill-prompt.d.ts +20 -0
  409. package/dist/tool-system/builtin/skill-prompt.js +52 -0
  410. package/dist/tool-system/builtin/skill.d.ts +9 -0
  411. package/dist/tool-system/builtin/skill.js +55 -0
  412. package/dist/tool-system/builtin/sleep.d.ts +6 -0
  413. package/dist/tool-system/builtin/sleep.js +33 -0
  414. package/dist/tool-system/builtin/task.d.ts +48 -0
  415. package/dist/tool-system/builtin/task.js +139 -0
  416. package/dist/tool-system/builtin/tool-search.d.ts +11 -0
  417. package/dist/tool-system/builtin/tool-search.js +90 -0
  418. package/dist/tool-system/builtin/web-fetch.d.ts +10 -0
  419. package/dist/tool-system/builtin/web-fetch.js +328 -0
  420. package/dist/tool-system/builtin/web-search.d.ts +25 -0
  421. package/dist/tool-system/builtin/web-search.js +174 -0
  422. package/dist/tool-system/builtin/worktree.d.ts +10 -0
  423. package/dist/tool-system/builtin/worktree.js +95 -0
  424. package/dist/tool-system/builtin/write.d.ts +6 -0
  425. package/dist/tool-system/builtin/write.js +36 -0
  426. package/dist/tool-system/context.d.ts +165 -0
  427. package/dist/tool-system/context.js +18 -0
  428. package/dist/tool-system/executor.d.ts +49 -0
  429. package/dist/tool-system/executor.js +495 -0
  430. package/dist/tool-system/investigation-guard.d.ts +46 -0
  431. package/dist/tool-system/investigation-guard.js +155 -0
  432. package/dist/tool-system/mcp-manager.d.ts +67 -0
  433. package/dist/tool-system/mcp-manager.js +249 -0
  434. package/dist/tool-system/permission.d.ts +111 -0
  435. package/dist/tool-system/permission.js +774 -0
  436. package/dist/tool-system/registry.d.ts +32 -0
  437. package/dist/tool-system/registry.js +131 -0
  438. package/dist/tool-system/sandbox/bwrap.d.ts +13 -0
  439. package/dist/tool-system/sandbox/bwrap.js +63 -0
  440. package/dist/tool-system/sandbox/index.d.ts +78 -0
  441. package/dist/tool-system/sandbox/index.js +222 -0
  442. package/dist/tool-system/sandbox/off.d.ts +2 -0
  443. package/dist/tool-system/sandbox/off.js +8 -0
  444. package/dist/tool-system/sandbox/seatbelt.d.ts +18 -0
  445. package/dist/tool-system/sandbox/seatbelt.js +109 -0
  446. package/dist/tool-system/task-guard.d.ts +29 -0
  447. package/dist/tool-system/task-guard.js +70 -0
  448. package/dist/tool-system/validation.d.ts +5 -0
  449. package/dist/tool-system/validation.js +39 -0
  450. package/dist/types.d.ts +376 -0
  451. package/dist/types.js +4 -0
  452. package/dist/updater.d.ts +65 -0
  453. package/dist/updater.js +405 -0
  454. package/dist/utils/debug.d.ts +41 -0
  455. package/dist/utils/debug.js +110 -0
  456. package/dist/utils/earlyInput.d.ts +43 -0
  457. package/dist/utils/earlyInput.js +166 -0
  458. package/dist/utils/env.d.ts +24 -0
  459. package/dist/utils/env.js +104 -0
  460. package/dist/utils/envUtils.d.ts +51 -0
  461. package/dist/utils/envUtils.js +135 -0
  462. package/dist/utils/execFileNoThrow.d.ts +39 -0
  463. package/dist/utils/execFileNoThrow.js +74 -0
  464. package/dist/utils/format.d.ts +44 -0
  465. package/dist/utils/format.js +236 -0
  466. package/dist/utils/intl.d.ts +22 -0
  467. package/dist/utils/intl.js +83 -0
  468. package/dist/utils/lockfile.d.ts +15 -0
  469. package/dist/utils/lockfile.js +30 -0
  470. package/dist/utils/memoize.d.ts +19 -0
  471. package/dist/utils/memoize.js +14 -0
  472. package/dist/utils/semver.d.ts +6 -0
  473. package/dist/utils/semver.js +13 -0
  474. package/dist/utils/sliceAnsi.d.ts +12 -0
  475. package/dist/utils/sliceAnsi.js +62 -0
  476. package/dist/utils/systemTheme.d.ts +40 -0
  477. package/dist/utils/systemTheme.js +108 -0
  478. package/dist/utils/task-sanitizer.d.ts +6 -0
  479. package/dist/utils/task-sanitizer.js +24 -0
  480. package/dist/utils/theme.d.ts +93 -0
  481. package/dist/utils/theme.js +544 -0
  482. package/dist/utils/toolDisplay.d.ts +31 -0
  483. package/dist/utils/toolDisplay.js +188 -0
  484. package/package.json +72 -0
@@ -0,0 +1,312 @@
1
+ /**
2
+ * Planner — the brain of Evidence-Driven Arena.
3
+ *
4
+ * Takes a natural language user request and produces a complete ArenaPlan:
5
+ * - mode (how to collaborate)
6
+ * - lenses (from what perspectives)
7
+ * - sources (where to gather evidence)
8
+ * - subject (what is being analyzed)
9
+ * - outputShape (how to structure the result)
10
+ *
11
+ * Replaces the old IntentResolver + ScopeResolver pipeline with a single
12
+ * LLM call that outputs a holistic execution plan.
13
+ */
14
+ import { createLLMClient } from "../llm/client-factory.js";
15
+ import { LENS_NAMES } from "./lenses/index.js";
16
+ import { logger } from "../logging/logger.js";
17
+ const PLANNER_SYSTEM_PROMPT = `You are the planner for a multi-model collaborative analysis tool called Arena.
18
+
19
+ Given a user's natural language request, produce an execution plan. You must determine:
20
+
21
+ 1. **mode** — how to collaborate:
22
+ - "review": find issues, verify quality, give a structured verdict
23
+ - "discussion": explore trade-offs, compare viewpoints, preserve disagreements
24
+ - "planning": build a roadmap, identify phases, dependencies, and risks
25
+
26
+ 2. **lenses** — from what analytical perspectives (can be multiple):
27
+ - "engineering": code quality, correctness, performance, maintainability
28
+ - "product": user value, requirements completeness, acceptance criteria, UX
29
+ - "architecture": system boundaries, modularity, coupling, evolution paths
30
+ - "general": broad analysis, logic, trade-offs (use as fallback)
31
+
32
+ 3. **sources** — where to gather evidence (can be multiple):
33
+ - "git": diffs, commit history, branch comparison, changed files
34
+ - "repo": directory structure, source code files, symbol search
35
+ - "docs": markdown/text documents, PRDs, design docs
36
+ - "web": external information, standards, competitor analysis
37
+ - "none": pure topic discussion, no external evidence needed
38
+
39
+ 4. **subject** — what is being analyzed:
40
+ - kind: "changes" (code changes), "files" (specific files), "docs" (documents), "topic" (abstract topic), "mixed"
41
+ - label: human-readable description
42
+ - targets: specific file paths, branch names, or doc names if applicable
43
+
44
+ 5. **outputShape** — what to emphasize in the output
45
+
46
+ Respond ONLY with JSON, no markdown fences:
47
+ {
48
+ "mode": "review|discussion|planning",
49
+ "lenses": [{"name": "engineering|product|architecture|general", "weight": 1.0}],
50
+ "sources": [{"kind": "git|repo|docs|web|none", "targets": ["optional specific targets"]}],
51
+ "subject": {"kind": "changes|files|docs|topic|mixed", "label": "description", "targets": ["optional"]},
52
+ "outputShape": {"overviewLabel": "e.g. What Changed / Current Scope / Problem Framing", "emphasize": ["risk", "improvement"]},
53
+ "confidence": "high|medium|low",
54
+ "followUpQuestion": "question if confidence is low, or null"
55
+ }`;
56
+ /**
57
+ * Run the planner to produce an ArenaPlan from natural language.
58
+ *
59
+ * Priority: explicit flags > LLM plan > safe defaults.
60
+ */
61
+ export async function planArena(topic, llmConfig, flags, signal) {
62
+ // If mode and base are both explicit, we can skip the LLM call
63
+ if (flags?.mode && flags?.base) {
64
+ return buildExplicitPlan(topic, flags);
65
+ }
66
+ try {
67
+ signal?.throwIfAborted();
68
+ const client = await createLLMClient({
69
+ ...llmConfig,
70
+ enableStreaming: false,
71
+ maxTokens: 1024,
72
+ });
73
+ const response = await client.createMessage({
74
+ systemPrompt: PLANNER_SYSTEM_PROMPT,
75
+ messages: [{ role: "user", content: `<user_request>\n${topic}\n</user_request>\n\nAnalyze the user request above and output the arena plan as JSON.` }],
76
+ maxTokens: 1024,
77
+ signal,
78
+ });
79
+ const plan = parsePlanResponse(response.text, topic);
80
+ // Explicit flags override LLM output
81
+ if (flags?.mode)
82
+ plan.mode = flags.mode;
83
+ if (flags?.base) {
84
+ plan.sources = [{ kind: "git", targets: [flags.base, flags.head ?? "HEAD"] }];
85
+ plan.subject = { kind: "changes", label: `${flags.base}...${flags.head ?? "HEAD"}`, targets: [flags.base, flags.head ?? "HEAD"] };
86
+ }
87
+ logger.info("arena.planner", { plan });
88
+ return plan;
89
+ }
90
+ catch (err) {
91
+ logger.warn("arena.planner_fallback", { error: err.message });
92
+ return buildFallbackPlan(topic, flags);
93
+ }
94
+ }
95
+ function parsePlanResponse(text, topic) {
96
+ const fenced = text.match(/```(?:json)?\s*\n?([\s\S]*?)\n?```/);
97
+ const jsonStr = fenced ? fenced[1].trim() : text.match(/\{[\s\S]*\}/)?.[0] ?? text;
98
+ try {
99
+ const parsed = JSON.parse(jsonStr);
100
+ return {
101
+ mode: validateMode(parsed.mode),
102
+ lenses: parseLenses(parsed.lenses),
103
+ sources: parseSources(parsed.sources),
104
+ subject: parseSubject(parsed.subject, topic),
105
+ outputShape: parseOutputShape(parsed.outputShape, parsed.mode),
106
+ confidence: validateConfidence(parsed.confidence),
107
+ followUpQuestion: parsed.followUpQuestion || undefined,
108
+ };
109
+ }
110
+ catch {
111
+ return buildFallbackPlan(topic);
112
+ }
113
+ }
114
+ function buildExplicitPlan(topic, flags) {
115
+ return {
116
+ mode: flags.mode,
117
+ lenses: [{ name: "engineering", weight: 1 }],
118
+ sources: [
119
+ { kind: "git", targets: [flags.base, flags.head ?? "HEAD"] },
120
+ { kind: "repo" },
121
+ ],
122
+ subject: {
123
+ kind: "changes",
124
+ label: `${flags.base}...${flags.head ?? "HEAD"}`,
125
+ targets: [flags.base, flags.head ?? "HEAD"],
126
+ },
127
+ outputShape: {
128
+ overviewLabel: "What Changed",
129
+ emphasize: ["risk", "improvement"],
130
+ },
131
+ confidence: "high",
132
+ };
133
+ }
134
+ function buildFallbackPlan(topic, flags) {
135
+ if (flags?.base) {
136
+ return {
137
+ mode: flags.mode ?? "review",
138
+ lenses: [{ name: "engineering", weight: 1 }],
139
+ sources: [{ kind: "git" }, { kind: "repo" }],
140
+ subject: { kind: "changes", label: topic, targets: [flags.base, flags.head ?? "HEAD"] },
141
+ outputShape: {
142
+ overviewLabel: "What Changed",
143
+ emphasize: ["risk", "improvement"],
144
+ },
145
+ confidence: "low",
146
+ };
147
+ }
148
+ const lower = topic.toLowerCase();
149
+ const hasDoc = /\b(prd|doc|docs|spec|rfc|design doc|requirement|proposal)\b/i.test(topic)
150
+ || /(文档|需求|方案)/.test(topic);
151
+ const hasRoadmap = /\b(roadmap|plan|planning|strategy|migration|refactor)\b/i.test(topic)
152
+ || /(演进|路线图|规划|重构)/.test(topic);
153
+ const hasFeasibility = /\b(feasibility|feasible|can we|should we|trade-?off)\b/i.test(topic)
154
+ || /(可行|能不能|值不值得|取舍)/.test(topic);
155
+ const hasReview = /\b(review|pr|diff|patch|change)\b/i.test(topic)
156
+ || /(改动|评审|审查)/.test(topic);
157
+ const hasRepo = /\b(repo|repository|codebase|module|architecture)\b/i.test(topic)
158
+ || /(代码库|仓库|模块|架构)/.test(topic);
159
+ if (hasRoadmap) {
160
+ return {
161
+ mode: "planning",
162
+ lenses: hasDoc
163
+ ? [{ name: "architecture", weight: 1 }, { name: "product", weight: 0.7 }]
164
+ : [{ name: "architecture", weight: 1 }, { name: "engineering", weight: 0.8 }],
165
+ sources: hasDoc
166
+ ? [{ kind: "docs" }, ...(hasRepo ? [{ kind: "repo" }] : [])]
167
+ : [{ kind: "repo" }, { kind: "docs" }],
168
+ subject: { kind: hasDoc ? "mixed" : "topic", label: topic },
169
+ outputShape: {
170
+ overviewLabel: "Current Scope",
171
+ emphasize: ["improvement", "risk", "question"],
172
+ },
173
+ confidence: "low",
174
+ };
175
+ }
176
+ if (hasDoc && hasFeasibility) {
177
+ return {
178
+ mode: "discussion",
179
+ lenses: [{ name: "product", weight: 1 }, { name: "engineering", weight: 0.8 }],
180
+ sources: hasRepo ? [{ kind: "docs" }, { kind: "repo" }] : [{ kind: "docs" }],
181
+ subject: { kind: hasRepo ? "mixed" : "docs", label: topic },
182
+ outputShape: {
183
+ overviewLabel: "Problem Framing",
184
+ emphasize: ["question", "risk", "improvement"],
185
+ },
186
+ confidence: "low",
187
+ };
188
+ }
189
+ if (hasDoc) {
190
+ return {
191
+ mode: hasReview ? "review" : "discussion",
192
+ lenses: [{ name: "product", weight: 1 }, { name: "architecture", weight: 0.6 }],
193
+ sources: hasRepo ? [{ kind: "docs" }, { kind: "repo" }] : [{ kind: "docs" }],
194
+ subject: { kind: hasRepo ? "mixed" : "docs", label: topic },
195
+ outputShape: {
196
+ overviewLabel: hasReview ? "Current Scope" : "Problem Framing",
197
+ emphasize: ["question", "improvement", "risk"],
198
+ },
199
+ confidence: "low",
200
+ };
201
+ }
202
+ if (hasFeasibility) {
203
+ return {
204
+ mode: "discussion",
205
+ lenses: hasRepo
206
+ ? [{ name: "product", weight: 1 }, { name: "engineering", weight: 0.8 }]
207
+ : [{ name: "general", weight: 1 }, { name: "product", weight: 0.6 }],
208
+ sources: hasRepo ? [{ kind: "repo" }, { kind: "docs" }] : [{ kind: "none" }],
209
+ subject: { kind: hasRepo ? "topic" : "topic", label: topic },
210
+ outputShape: {
211
+ overviewLabel: "Problem Framing",
212
+ emphasize: ["question", "risk", "improvement"],
213
+ },
214
+ confidence: "low",
215
+ };
216
+ }
217
+ if (hasReview || /\b(commit|branch|diff|patch|bug|fix|回归)\b/i.test(lower)) {
218
+ return {
219
+ mode: "review",
220
+ lenses: [{ name: "engineering", weight: 1 }],
221
+ sources: [{ kind: "git" }, { kind: "repo" }],
222
+ subject: { kind: "changes", label: topic },
223
+ outputShape: {
224
+ overviewLabel: "What Changed",
225
+ emphasize: ["risk", "improvement", "question"],
226
+ },
227
+ confidence: "low",
228
+ };
229
+ }
230
+ return {
231
+ mode: flags?.mode ?? "review",
232
+ lenses: [{ name: hasRepo ? "architecture" : "general", weight: 1 }],
233
+ sources: hasRepo ? [{ kind: "repo" }, { kind: "docs" }] : [{ kind: "none" }],
234
+ subject: { kind: "topic", label: topic },
235
+ outputShape: {
236
+ overviewLabel: hasRepo ? "Current Scope" : "Problem Framing",
237
+ emphasize: hasRepo ? ["improvement", "risk", "question"] : ["question", "risk", "improvement"],
238
+ },
239
+ confidence: "low",
240
+ };
241
+ }
242
+ // ─── Validators ─────────────────────────────────────────────────
243
+ function validateMode(v) {
244
+ if (v === "review" || v === "discussion" || v === "planning")
245
+ return v;
246
+ return "review";
247
+ }
248
+ function validateConfidence(v) {
249
+ if (v === "high" || v === "medium" || v === "low")
250
+ return v;
251
+ return "medium";
252
+ }
253
+ function parseLenses(v) {
254
+ if (!Array.isArray(v) || v.length === 0) {
255
+ return [{ name: "general", weight: 1 }];
256
+ }
257
+ const result = v
258
+ .filter((item) => LENS_NAMES.includes(item?.name))
259
+ .map((item) => ({
260
+ name: item.name,
261
+ weight: typeof item.weight === "number" ? item.weight : 1,
262
+ }));
263
+ return result.length > 0 ? result : [{ name: "general", weight: 1 }];
264
+ }
265
+ function parseSources(v) {
266
+ if (!Array.isArray(v) || v.length === 0) {
267
+ return [{ kind: "none" }];
268
+ }
269
+ const validKinds = ["git", "repo", "docs", "web", "none"];
270
+ const result = v
271
+ .filter((item) => validKinds.includes(item?.kind))
272
+ .map((item) => ({
273
+ kind: item.kind,
274
+ targets: Array.isArray(item.targets) ? item.targets : undefined,
275
+ }));
276
+ return result.length > 0 ? result : [{ kind: "none" }];
277
+ }
278
+ function parseSubject(v, topic) {
279
+ if (!v || typeof v !== "object") {
280
+ return { kind: "topic", label: topic };
281
+ }
282
+ const obj = v;
283
+ const validKinds = ["changes", "files", "docs", "topic", "mixed"];
284
+ return {
285
+ kind: validKinds.includes(obj.kind) ? obj.kind : "topic",
286
+ label: obj.label ?? topic,
287
+ targets: Array.isArray(obj.targets) ? obj.targets : undefined,
288
+ };
289
+ }
290
+ const VALID_EMPHASIZE = new Set(["strength", "improvement", "risk", "question"]);
291
+ function parseOutputShape(v, mode) {
292
+ if (v && typeof v === "object") {
293
+ const obj = v;
294
+ return {
295
+ overviewLabel: obj.overviewLabel ?? "Overview",
296
+ emphasize: Array.isArray(obj.emphasize)
297
+ ? obj.emphasize.filter((k) => VALID_EMPHASIZE.has(k))
298
+ : ["risk", "improvement"],
299
+ };
300
+ }
301
+ // Defaults per mode
302
+ switch (mode) {
303
+ case "review":
304
+ return { overviewLabel: "What Changed", emphasize: ["risk", "improvement"] };
305
+ case "discussion":
306
+ return { overviewLabel: "Problem Framing", emphasize: ["strength", "risk", "question"] };
307
+ case "planning":
308
+ return { overviewLabel: "Current Scope", emphasize: ["improvement", "risk"] };
309
+ default:
310
+ return { overviewLabel: "Overview", emphasize: ["risk", "improvement"] };
311
+ }
312
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * DocsProvider — collects evidence from documentation files:
3
+ * markdown, text, PRDs, design docs.
4
+ */
5
+ import type { ArenaContextProvider } from "../types.js";
6
+ export declare const docsProvider: ArenaContextProvider;
@@ -0,0 +1,108 @@
1
+ /**
2
+ * DocsProvider — collects evidence from documentation files:
3
+ * markdown, text, PRDs, design docs.
4
+ */
5
+ import { existsSync, readFileSync, readdirSync, statSync } from "node:fs";
6
+ import { join, extname } from "node:path";
7
+ import { logger } from "../../logging/logger.js";
8
+ const MAX_DOC_CHARS = 10_000;
9
+ const DOC_EXTENSIONS = new Set([".md", ".txt", ".rst", ".adoc", ".org"]);
10
+ export const docsProvider = {
11
+ kind: "docs",
12
+ collect(plan, topic) {
13
+ const artifacts = [];
14
+ const sourceSpec = plan.sources.find((s) => s.kind === "docs");
15
+ const targets = sourceSpec?.targets ?? [];
16
+ // Read explicit target documents
17
+ for (const target of targets) {
18
+ const content = safeReadDoc(target);
19
+ if (content) {
20
+ artifacts.push({
21
+ id: `doc-${target}`,
22
+ kind: "doc",
23
+ source: "docs",
24
+ title: target,
25
+ ref: target,
26
+ preview: truncate(content),
27
+ });
28
+ }
29
+ }
30
+ // If no explicit targets, scan common doc locations
31
+ if (targets.length === 0) {
32
+ const docDirs = ["docs", "doc", "design", "specs", "proposals", "."];
33
+ const found = new Set();
34
+ for (const dir of docDirs) {
35
+ if (!existsSync(dir))
36
+ continue;
37
+ const docs = findDocFiles(dir, 2);
38
+ for (const docPath of docs) {
39
+ if (found.has(docPath))
40
+ continue;
41
+ found.add(docPath);
42
+ // Score relevance by checking if doc content/name relates to topic
43
+ const name = docPath.toLowerCase();
44
+ const topicLower = topic.toLowerCase();
45
+ const keywords = topicLower.split(/\s+/).filter((w) => w.length > 2);
46
+ const isRelevant = keywords.some((kw) => name.includes(kw));
47
+ if (isRelevant || found.size <= 5) {
48
+ const content = safeReadDoc(docPath);
49
+ if (content) {
50
+ artifacts.push({
51
+ id: `doc-${docPath}`,
52
+ kind: "doc",
53
+ source: "docs",
54
+ title: docPath,
55
+ ref: docPath,
56
+ preview: truncate(content),
57
+ });
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ logger.info("arena.provider.docs", { artifactCount: artifacts.length });
64
+ return artifacts;
65
+ },
66
+ };
67
+ function findDocFiles(dir, maxDepth, depth = 0) {
68
+ if (depth >= maxDepth)
69
+ return [];
70
+ const files = [];
71
+ try {
72
+ const entries = readdirSync(dir);
73
+ for (const entry of entries) {
74
+ if (entry.startsWith(".") || entry === "node_modules")
75
+ continue;
76
+ const full = join(dir, entry);
77
+ const st = statSync(full);
78
+ if (st.isFile() && DOC_EXTENSIONS.has(extname(entry).toLowerCase())) {
79
+ files.push(full);
80
+ }
81
+ else if (st.isDirectory() && depth < maxDepth - 1) {
82
+ files.push(...findDocFiles(full, maxDepth, depth + 1));
83
+ }
84
+ }
85
+ }
86
+ catch { /* ignore */ }
87
+ return files;
88
+ }
89
+ function safeReadDoc(filePath) {
90
+ try {
91
+ if (!existsSync(filePath))
92
+ return null;
93
+ const st = statSync(filePath);
94
+ if (st.size > 500_000)
95
+ return null;
96
+ return readFileSync(filePath, "utf-8");
97
+ }
98
+ catch {
99
+ return null;
100
+ }
101
+ }
102
+ function truncate(content) {
103
+ if (content.length <= MAX_DOC_CHARS)
104
+ return content;
105
+ const t = content.slice(0, MAX_DOC_CHARS);
106
+ const lastNl = t.lastIndexOf("\n");
107
+ return t.slice(0, lastNl) + `\n... (truncated, ${content.length} chars total)`;
108
+ }
@@ -0,0 +1,8 @@
1
+ /**
2
+ * GitProvider — collects evidence from git: diffs, commit logs, changed files.
3
+ *
4
+ * Security: All git commands use execFileSync with argument arrays
5
+ * to prevent shell injection. Git refs are sanitized before use.
6
+ */
7
+ import type { ArenaContextProvider } from "../types.js";
8
+ export declare const gitProvider: ArenaContextProvider;
@@ -0,0 +1,174 @@
1
+ /**
2
+ * GitProvider — collects evidence from git: diffs, commit logs, changed files.
3
+ *
4
+ * Security: All git commands use execFileSync with argument arrays
5
+ * to prevent shell injection. Git refs are sanitized before use.
6
+ */
7
+ import { execFileSync } from "node:child_process";
8
+ import { logger } from "../../logging/logger.js";
9
+ const MAX_DIFF_CHARS = 20_000;
10
+ const MAX_CHANGED_FILES = 30;
11
+ export const gitProvider = {
12
+ kind: "git",
13
+ collect(plan, _topic) {
14
+ const artifacts = [];
15
+ const targets = plan.sources.find((s) => s.kind === "git")?.targets;
16
+ const baseRef = sanitizeRef(targets?.[0]);
17
+ const headRef = sanitizeRef(targets?.[1]) ?? "HEAD";
18
+ const isCompare = !!baseRef;
19
+ // Current branch
20
+ const currentBranch = git(["rev-parse", "--abbrev-ref", "HEAD"]);
21
+ if (currentBranch) {
22
+ artifacts.push({
23
+ id: "git-branch",
24
+ kind: "doc",
25
+ source: "git",
26
+ title: "Current Branch",
27
+ preview: currentBranch,
28
+ });
29
+ }
30
+ // Commit log
31
+ const logArgs = isCompare
32
+ ? ["log", "--oneline", `${baseRef}..${headRef}`, "--max-count=20"]
33
+ : ["log", "--oneline", "-10"];
34
+ const log = git(logArgs);
35
+ if (log) {
36
+ artifacts.push({
37
+ id: "git-log",
38
+ kind: "doc",
39
+ source: "git",
40
+ title: "Commit Log",
41
+ preview: log,
42
+ });
43
+ }
44
+ // Diff stat
45
+ const statArgs = isCompare
46
+ ? ["diff", "--stat", `${baseRef}...${headRef}`]
47
+ : ["diff", "--stat", "HEAD"];
48
+ let stat = git(statArgs);
49
+ if (!stat && !isCompare)
50
+ stat = git(["diff", "--stat", "--cached"]);
51
+ if (stat) {
52
+ artifacts.push({
53
+ id: "git-diffstat",
54
+ kind: "doc",
55
+ source: "git",
56
+ title: "Diff Stat",
57
+ preview: stat,
58
+ });
59
+ }
60
+ // Changed files
61
+ const filesArgs = isCompare
62
+ ? ["diff", "--name-status", `${baseRef}...${headRef}`]
63
+ : ["diff", "--name-status", "HEAD"];
64
+ let changedFiles = git(filesArgs);
65
+ if (!changedFiles && !isCompare)
66
+ changedFiles = git(["diff", "--name-status", "--cached"]);
67
+ if (changedFiles) {
68
+ const allChanged = changedFiles.split("\n").filter(Boolean);
69
+ const limited = allChanged.slice(0, MAX_CHANGED_FILES);
70
+ if (allChanged.length > MAX_CHANGED_FILES) {
71
+ limited.push(`... and ${allChanged.length - MAX_CHANGED_FILES} more files`);
72
+ }
73
+ artifacts.push({
74
+ id: "git-changed-files",
75
+ kind: "doc",
76
+ source: "git",
77
+ title: "Changed Files",
78
+ preview: limited.join("\n"),
79
+ metadata: { totalCount: allChanged.length },
80
+ });
81
+ // Directory clustering
82
+ const paths = allChanged.map((line) => line.split("\t").slice(1).join("\t")).filter(Boolean);
83
+ const dirCounts = clusterByDirectory(paths);
84
+ if (dirCounts.length > 0) {
85
+ artifacts.push({
86
+ id: "git-dir-clusters",
87
+ kind: "doc",
88
+ source: "git",
89
+ title: "Changes by Directory",
90
+ preview: dirCounts.slice(0, 15).map(([dir, count]) => ` ${dir}/ (${count} files)`).join("\n"),
91
+ });
92
+ }
93
+ }
94
+ // Truncated diff
95
+ const diffArgs = isCompare
96
+ ? ["diff", `${baseRef}...${headRef}`]
97
+ : ["diff", "HEAD"];
98
+ let diff = git(diffArgs);
99
+ if (!diff && !isCompare)
100
+ diff = git(["diff", "--cached"]);
101
+ if (diff) {
102
+ const truncated = diff.length > MAX_DIFF_CHARS;
103
+ const preview = truncated
104
+ ? diff.slice(0, MAX_DIFF_CHARS).slice(0, diff.slice(0, MAX_DIFF_CHARS).lastIndexOf("\n"))
105
+ : diff;
106
+ artifacts.push({
107
+ id: "git-diff",
108
+ kind: "diff",
109
+ source: "git",
110
+ title: "Diff",
111
+ preview: preview + (truncated
112
+ ? `\n\n... TRUNCATED (${diff.length} chars total). Use read_file to inspect specific files.`
113
+ : ""),
114
+ metadata: { totalChars: diff.length, truncated },
115
+ });
116
+ }
117
+ // Fallback: git status
118
+ if (!diff && !stat) {
119
+ const status = git(["status", "--short"]);
120
+ if (status) {
121
+ artifacts.push({
122
+ id: "git-status",
123
+ kind: "doc",
124
+ source: "git",
125
+ title: "Git Status",
126
+ preview: status,
127
+ });
128
+ }
129
+ }
130
+ logger.info("arena.provider.git", {
131
+ artifactCount: artifacts.length,
132
+ hasCompare: isCompare,
133
+ });
134
+ return artifacts;
135
+ },
136
+ };
137
+ /**
138
+ * Execute a git command safely using execFileSync (no shell interpretation).
139
+ */
140
+ function git(args) {
141
+ try {
142
+ return execFileSync("git", args, {
143
+ encoding: "utf-8",
144
+ maxBuffer: 1024 * 1024,
145
+ timeout: 10_000,
146
+ }).trim();
147
+ }
148
+ catch {
149
+ return "";
150
+ }
151
+ }
152
+ /**
153
+ * Sanitize a git ref string from LLM output.
154
+ * Strips range operators (.., ...) and shell-unsafe characters so that
155
+ * the ref can be safely interpolated into `git diff baseRef...headRef`.
156
+ */
157
+ function sanitizeRef(ref) {
158
+ if (!ref)
159
+ return undefined;
160
+ // Strip range operators that the LLM may have included
161
+ let cleaned = ref.replace(/\.{2,}/g, "");
162
+ // Only allow safe git ref characters: alphanumeric, /, -, _, ~, ^, .
163
+ cleaned = cleaned.replace(/[^a-zA-Z0-9/_\-~^.]/g, "");
164
+ return cleaned || undefined;
165
+ }
166
+ function clusterByDirectory(paths) {
167
+ const counts = new Map();
168
+ for (const p of paths) {
169
+ const parts = p.split("/");
170
+ const dir = parts.length > 2 ? parts.slice(0, 2).join("/") : parts[0];
171
+ counts.set(dir, (counts.get(dir) ?? 0) + 1);
172
+ }
173
+ return [...counts.entries()].sort((a, b) => b[1] - a[1]);
174
+ }
@@ -0,0 +1,32 @@
1
+ /**
2
+ * Provider registry — evidence collectors for Arena.
3
+ */
4
+ import type { ArenaPlan, ArenaArtifact, ArenaSourceKind, ArenaQuickFact } from "../types.js";
5
+ export { gitProvider } from "./git.js";
6
+ export { repoProvider } from "./repo.js";
7
+ export { docsProvider } from "./docs.js";
8
+ export { noneProvider } from "./none.js";
9
+ export interface CollectEvidenceOptions {
10
+ /** Heartbeat callback fired before/after each provider runs. */
11
+ onProgress?: (event: {
12
+ type: "evidence_started" | "evidence_collected";
13
+ source: ArenaSourceKind;
14
+ count?: number;
15
+ durationMs?: number;
16
+ timedOut?: boolean;
17
+ }) => void;
18
+ signal?: AbortSignal;
19
+ }
20
+ /**
21
+ * Collect all evidence according to the plan's sources.
22
+ * Returns unified ArenaArtifact[] and quickFacts.
23
+ *
24
+ * Providers run in parallel (independent of one another) with a
25
+ * per-provider timeout, so a single slow source can't stall the
26
+ * whole arena. Heartbeats are emitted around each provider so the
27
+ * UI can show "collecting from repo..." instead of a blank pause.
28
+ */
29
+ export declare function collectEvidence(plan: ArenaPlan, topic: string, options?: CollectEvidenceOptions): Promise<{
30
+ artifacts: ArenaArtifact[];
31
+ quickFacts: ArenaQuickFact[];
32
+ }>;