@armadra/agent 0.0.0-stage → 0.2.1

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 (407) hide show
  1. package/CHANGELOG.md +22 -0
  2. package/LICENSE +21 -0
  3. package/README.md +426 -2
  4. package/dist/agent/agent.d.ts +56 -0
  5. package/dist/agent/agent.js +129 -0
  6. package/dist/agent/loop.d.ts +51 -0
  7. package/dist/agent/loop.js +158 -0
  8. package/dist/agent/queue.d.ts +25 -0
  9. package/dist/agent/queue.js +55 -0
  10. package/dist/agent/retry.d.ts +22 -0
  11. package/dist/agent/retry.js +92 -0
  12. package/dist/agent/schema.d.ts +27 -0
  13. package/dist/agent/schema.js +186 -0
  14. package/dist/agent/session-cache.d.ts +100 -0
  15. package/dist/agent/session-cache.js +511 -0
  16. package/dist/agent/session-compaction.d.ts +49 -0
  17. package/dist/agent/session-compaction.js +251 -0
  18. package/dist/agent/session-core.d.ts +103 -0
  19. package/dist/agent/session-core.js +7 -0
  20. package/dist/agent/session-run.d.ts +55 -0
  21. package/dist/agent/session-run.js +246 -0
  22. package/dist/agent/session-state.d.ts +39 -0
  23. package/dist/agent/session-state.js +118 -0
  24. package/dist/agent/session-subagent.d.ts +54 -0
  25. package/dist/agent/session-subagent.js +157 -0
  26. package/dist/agent/session-sync.d.ts +20 -0
  27. package/dist/agent/session-sync.js +104 -0
  28. package/dist/agent/session-tools.d.ts +24 -0
  29. package/dist/agent/session-tools.js +277 -0
  30. package/dist/agent/session.d.ts +117 -0
  31. package/dist/agent/session.js +484 -0
  32. package/dist/agent/system-prompt.d.ts +49 -0
  33. package/dist/agent/system-prompt.js +121 -0
  34. package/dist/agent/tool-runner.d.ts +64 -0
  35. package/dist/agent/tool-runner.js +309 -0
  36. package/dist/agent/transform.d.ts +26 -0
  37. package/dist/agent/transform.js +171 -0
  38. package/dist/agent/types.d.ts +378 -0
  39. package/dist/agent/types.js +21 -0
  40. package/dist/ai/apis/anthropic-messages.d.ts +26 -0
  41. package/dist/ai/apis/anthropic-messages.js +214 -0
  42. package/dist/ai/apis/anthropic-request.d.ts +42 -0
  43. package/dist/ai/apis/anthropic-request.js +282 -0
  44. package/dist/ai/apis/api.d.ts +28 -0
  45. package/dist/ai/apis/api.js +102 -0
  46. package/dist/ai/apis/cache-params.d.ts +48 -0
  47. package/dist/ai/apis/cache-params.js +163 -0
  48. package/dist/ai/apis/google-generative-ai.d.ts +32 -0
  49. package/dist/ai/apis/google-generative-ai.js +249 -0
  50. package/dist/ai/apis/google-request.d.ts +40 -0
  51. package/dist/ai/apis/google-request.js +255 -0
  52. package/dist/ai/apis/openai-compat.d.ts +35 -0
  53. package/dist/ai/apis/openai-compat.js +142 -0
  54. package/dist/ai/apis/openai-completions.d.ts +28 -0
  55. package/dist/ai/apis/openai-completions.js +246 -0
  56. package/dist/ai/apis/openai-request.d.ts +35 -0
  57. package/dist/ai/apis/openai-request.js +303 -0
  58. package/dist/ai/apis/openai-responses-request.d.ts +52 -0
  59. package/dist/ai/apis/openai-responses-request.js +266 -0
  60. package/dist/ai/apis/openai-responses.d.ts +28 -0
  61. package/dist/ai/apis/openai-responses.js +303 -0
  62. package/dist/ai/apis/shared.d.ts +56 -0
  63. package/dist/ai/apis/shared.js +179 -0
  64. package/dist/ai/cache/economics.d.ts +24 -0
  65. package/dist/ai/cache/economics.js +69 -0
  66. package/dist/ai/cache/fingerprint.d.ts +17 -0
  67. package/dist/ai/cache/fingerprint.js +39 -0
  68. package/dist/ai/cache/miss.d.ts +49 -0
  69. package/dist/ai/cache/miss.js +96 -0
  70. package/dist/ai/cache/reporting.d.ts +39 -0
  71. package/dist/ai/cache/reporting.js +102 -0
  72. package/dist/ai/cache/types.d.ts +94 -0
  73. package/dist/ai/cache/types.js +19 -0
  74. package/dist/ai/cache/warmer.d.ts +94 -0
  75. package/dist/ai/cache/warmer.js +224 -0
  76. package/dist/ai/context.d.ts +35 -0
  77. package/dist/ai/context.js +114 -0
  78. package/dist/ai/cost.d.ts +21 -0
  79. package/dist/ai/cost.js +60 -0
  80. package/dist/ai/event-stream.d.ts +33 -0
  81. package/dist/ai/event-stream.js +101 -0
  82. package/dist/ai/fake/fake-provider.d.ts +68 -0
  83. package/dist/ai/fake/fake-provider.js +278 -0
  84. package/dist/ai/fake/fake-script.d.ts +69 -0
  85. package/dist/ai/fake/fake-script.js +142 -0
  86. package/dist/ai/http.d.ts +54 -0
  87. package/dist/ai/http.js +212 -0
  88. package/dist/ai/json-partial.d.ts +17 -0
  89. package/dist/ai/json-partial.js +243 -0
  90. package/dist/ai/overflow.d.ts +22 -0
  91. package/dist/ai/overflow.js +61 -0
  92. package/dist/ai/providers/auth.d.ts +71 -0
  93. package/dist/ai/providers/auth.js +202 -0
  94. package/dist/ai/providers/builtin.d.ts +23 -0
  95. package/dist/ai/providers/builtin.js +148 -0
  96. package/dist/ai/providers/catalog-data.d.ts +5 -0
  97. package/dist/ai/providers/catalog-data.js +19 -0
  98. package/dist/ai/providers/catalog.d.ts +28 -0
  99. package/dist/ai/providers/catalog.js +166 -0
  100. package/dist/ai/providers/registry.d.ts +83 -0
  101. package/dist/ai/providers/registry.js +305 -0
  102. package/dist/ai/sse.d.ts +32 -0
  103. package/dist/ai/sse.js +140 -0
  104. package/dist/ai/thinking.d.ts +42 -0
  105. package/dist/ai/thinking.js +101 -0
  106. package/dist/ai/types.d.ts +428 -0
  107. package/dist/ai/types.js +19 -0
  108. package/dist/bundle/ama-sandbox.cjs +324 -0
  109. package/dist/bundle/ama.cjs +25770 -0
  110. package/dist/bundle.d.ts +9 -0
  111. package/dist/bundle.js +15 -0
  112. package/dist/cli/args.d.ts +82 -0
  113. package/dist/cli/args.js +381 -0
  114. package/dist/cli/bootstrap.d.ts +18 -0
  115. package/dist/cli/bootstrap.js +398 -0
  116. package/dist/cli/compose-providers.d.ts +37 -0
  117. package/dist/cli/compose-providers.js +104 -0
  118. package/dist/cli/compose-session.d.ts +69 -0
  119. package/dist/cli/compose-session.js +370 -0
  120. package/dist/cli/compose-store.d.ts +24 -0
  121. package/dist/cli/compose-store.js +125 -0
  122. package/dist/cli/compose.d.ts +106 -0
  123. package/dist/cli/compose.js +206 -0
  124. package/dist/cli/default-model.d.ts +16 -0
  125. package/dist/cli/default-model.js +24 -0
  126. package/dist/cli/deps.d.ts +205 -0
  127. package/dist/cli/deps.js +12 -0
  128. package/dist/cli/exit-codes.d.ts +29 -0
  129. package/dist/cli/exit-codes.js +40 -0
  130. package/dist/cli/main.d.ts +26 -0
  131. package/dist/cli/main.js +165 -0
  132. package/dist/cli/runtime.d.ts +90 -0
  133. package/dist/cli/runtime.js +8 -0
  134. package/dist/cli/startup-screen.d.ts +15 -0
  135. package/dist/cli/startup-screen.js +56 -0
  136. package/dist/cli/startup-steps.d.ts +35 -0
  137. package/dist/cli/startup-steps.js +197 -0
  138. package/dist/cli/subcommands/auth.d.ts +12 -0
  139. package/dist/cli/subcommands/auth.js +91 -0
  140. package/dist/cli/subcommands/config.d.ts +44 -0
  141. package/dist/cli/subcommands/config.js +201 -0
  142. package/dist/cli/subcommands/context.d.ts +21 -0
  143. package/dist/cli/subcommands/context.js +41 -0
  144. package/dist/cli/subcommands/doctor.d.ts +11 -0
  145. package/dist/cli/subcommands/doctor.js +246 -0
  146. package/dist/cli/subcommands/models-cache-probe.d.ts +34 -0
  147. package/dist/cli/subcommands/models-cache-probe.js +190 -0
  148. package/dist/cli/subcommands/models-discover.d.ts +40 -0
  149. package/dist/cli/subcommands/models-discover.js +204 -0
  150. package/dist/cli/subcommands/models.d.ts +40 -0
  151. package/dist/cli/subcommands/models.js +144 -0
  152. package/dist/cli/subcommands/sessions.d.ts +11 -0
  153. package/dist/cli/subcommands/sessions.js +100 -0
  154. package/dist/codemode/capability.d.ts +37 -0
  155. package/dist/codemode/capability.js +55 -0
  156. package/dist/codemode/declarations.d.ts +44 -0
  157. package/dist/codemode/declarations.js +111 -0
  158. package/dist/codemode/host-side.d.ts +59 -0
  159. package/dist/codemode/host-side.js +253 -0
  160. package/dist/codemode/modes.d.ts +23 -0
  161. package/dist/codemode/modes.js +40 -0
  162. package/dist/codemode/protocol.d.ts +91 -0
  163. package/dist/codemode/protocol.js +114 -0
  164. package/dist/codemode/sandbox-entry.d.ts +25 -0
  165. package/dist/codemode/sandbox-entry.js +323 -0
  166. package/dist/codemode/store.d.ts +26 -0
  167. package/dist/codemode/store.js +53 -0
  168. package/dist/codemode/tool.d.ts +105 -0
  169. package/dist/codemode/tool.js +283 -0
  170. package/dist/compaction/branch-summary.d.ts +30 -0
  171. package/dist/compaction/branch-summary.js +79 -0
  172. package/dist/compaction/breaker.d.ts +32 -0
  173. package/dist/compaction/breaker.js +65 -0
  174. package/dist/compaction/cut-point.d.ts +23 -0
  175. package/dist/compaction/cut-point.js +70 -0
  176. package/dist/compaction/estimate.d.ts +30 -0
  177. package/dist/compaction/estimate.js +114 -0
  178. package/dist/compaction/prune-tier.d.ts +31 -0
  179. package/dist/compaction/prune-tier.js +83 -0
  180. package/dist/compaction/serialize.d.ts +20 -0
  181. package/dist/compaction/serialize.js +115 -0
  182. package/dist/compaction/summarize-tier.d.ts +111 -0
  183. package/dist/compaction/summarize-tier.js +305 -0
  184. package/dist/config/auth-file.d.ts +39 -0
  185. package/dist/config/auth-file.js +92 -0
  186. package/dist/config/context-files.d.ts +30 -0
  187. package/dist/config/context-files.js +77 -0
  188. package/dist/config/load.d.ts +45 -0
  189. package/dist/config/load.js +97 -0
  190. package/dist/config/merge.d.ts +73 -0
  191. package/dist/config/merge.js +248 -0
  192. package/dist/config/paths.d.ts +38 -0
  193. package/dist/config/paths.js +108 -0
  194. package/dist/config/profile.d.ts +27 -0
  195. package/dist/config/profile.js +65 -0
  196. package/dist/config/schema.d.ts +34 -0
  197. package/dist/config/schema.js +413 -0
  198. package/dist/config/trust.d.ts +42 -0
  199. package/dist/config/trust.js +122 -0
  200. package/dist/config/types.d.ts +172 -0
  201. package/dist/config/types.js +27 -0
  202. package/dist/config/write.d.ts +10 -0
  203. package/dist/config/write.js +25 -0
  204. package/dist/errors.d.ts +28 -0
  205. package/dist/errors.js +30 -0
  206. package/dist/hooks/config.d.ts +49 -0
  207. package/dist/hooks/config.js +102 -0
  208. package/dist/hooks/dispatcher.d.ts +41 -0
  209. package/dist/hooks/dispatcher.js +104 -0
  210. package/dist/hooks/matcher.d.ts +22 -0
  211. package/dist/hooks/matcher.js +108 -0
  212. package/dist/hooks/protocol.d.ts +33 -0
  213. package/dist/hooks/protocol.js +240 -0
  214. package/dist/hooks/runner.d.ts +30 -0
  215. package/dist/hooks/runner.js +143 -0
  216. package/dist/hooks/types.d.ts +147 -0
  217. package/dist/hooks/types.js +20 -0
  218. package/dist/host/api-impl.d.ts +75 -0
  219. package/dist/host/api-impl.js +173 -0
  220. package/dist/host/loader.d.ts +31 -0
  221. package/dist/host/loader.js +147 -0
  222. package/dist/host/types.d.ts +169 -0
  223. package/dist/host/types.js +14 -0
  224. package/dist/host.d.ts +5 -0
  225. package/dist/host.js +4 -0
  226. package/dist/index.d.ts +41 -0
  227. package/dist/index.js +28 -0
  228. package/dist/modes/commands-core.d.ts +44 -0
  229. package/dist/modes/commands-core.js +171 -0
  230. package/dist/modes/interactive/approval-dialog.d.ts +48 -0
  231. package/dist/modes/interactive/approval-dialog.js +202 -0
  232. package/dist/modes/interactive/commands.d.ts +41 -0
  233. package/dist/modes/interactive/commands.js +202 -0
  234. package/dist/modes/interactive/completion.d.ts +53 -0
  235. package/dist/modes/interactive/completion.js +157 -0
  236. package/dist/modes/interactive/interactive-mode.d.ts +46 -0
  237. package/dist/modes/interactive/interactive-mode.js +487 -0
  238. package/dist/modes/interactive/key-dispatch.d.ts +29 -0
  239. package/dist/modes/interactive/key-dispatch.js +107 -0
  240. package/dist/modes/interactive/line/line-editor.d.ts +50 -0
  241. package/dist/modes/interactive/line/line-editor.js +232 -0
  242. package/dist/modes/interactive/line/line-mode.d.ts +20 -0
  243. package/dist/modes/interactive/line/line-mode.js +216 -0
  244. package/dist/modes/interactive/line/line-render.d.ts +35 -0
  245. package/dist/modes/interactive/line/line-render.js +171 -0
  246. package/dist/modes/interactive/line/paste-state.d.ts +26 -0
  247. package/dist/modes/interactive/line/paste-state.js +72 -0
  248. package/dist/modes/interactive/message-view.d.ts +77 -0
  249. package/dist/modes/interactive/message-view.js +269 -0
  250. package/dist/modes/interactive/pickers.d.ts +42 -0
  251. package/dist/modes/interactive/pickers.js +115 -0
  252. package/dist/modes/interactive/startup-ui.d.ts +28 -0
  253. package/dist/modes/interactive/startup-ui.js +238 -0
  254. package/dist/modes/interactive/status-bar.d.ts +48 -0
  255. package/dist/modes/interactive/status-bar.js +139 -0
  256. package/dist/modes/interactive/tool-view.d.ts +95 -0
  257. package/dist/modes/interactive/tool-view.js +344 -0
  258. package/dist/modes/print/json-event.d.ts +15 -0
  259. package/dist/modes/print/json-event.js +39 -0
  260. package/dist/modes/print/print-mode.d.ts +15 -0
  261. package/dist/modes/print/print-mode.js +96 -0
  262. package/dist/modes/rpc/commands.d.ts +40 -0
  263. package/dist/modes/rpc/commands.js +258 -0
  264. package/dist/modes/rpc/jsonl.d.ts +16 -0
  265. package/dist/modes/rpc/jsonl.js +55 -0
  266. package/dist/modes/rpc/rpc-mode.d.ts +22 -0
  267. package/dist/modes/rpc/rpc-mode.js +153 -0
  268. package/dist/modes/session-report.d.ts +55 -0
  269. package/dist/modes/session-report.js +278 -0
  270. package/dist/modes/shared.d.ts +13 -0
  271. package/dist/modes/shared.js +52 -0
  272. package/dist/modes/startup-ui-text.d.ts +16 -0
  273. package/dist/modes/startup-ui-text.js +103 -0
  274. package/dist/permissions/broker.d.ts +47 -0
  275. package/dist/permissions/broker.js +107 -0
  276. package/dist/permissions/dangerous.d.ts +47 -0
  277. package/dist/permissions/dangerous.js +370 -0
  278. package/dist/permissions/pipeline.d.ts +51 -0
  279. package/dist/permissions/pipeline.js +181 -0
  280. package/dist/permissions/preview.d.ts +43 -0
  281. package/dist/permissions/preview.js +463 -0
  282. package/dist/permissions/rules.d.ts +58 -0
  283. package/dist/permissions/rules.js +249 -0
  284. package/dist/permissions/types.d.ts +100 -0
  285. package/dist/permissions/types.js +18 -0
  286. package/dist/rpc.d.ts +171 -0
  287. package/dist/rpc.js +13 -0
  288. package/dist/sdk.d.ts +98 -0
  289. package/dist/sdk.js +195 -0
  290. package/dist/session/manager.d.ts +70 -0
  291. package/dist/session/manager.js +278 -0
  292. package/dist/session/migrate.d.ts +19 -0
  293. package/dist/session/migrate.js +53 -0
  294. package/dist/session/projection.d.ts +50 -0
  295. package/dist/session/projection.js +180 -0
  296. package/dist/session/store.d.ts +47 -0
  297. package/dist/session/store.js +210 -0
  298. package/dist/session/tree.d.ts +21 -0
  299. package/dist/session/tree.js +88 -0
  300. package/dist/session/types.d.ts +199 -0
  301. package/dist/session/types.js +18 -0
  302. package/dist/skills/discover.d.ts +60 -0
  303. package/dist/skills/discover.js +160 -0
  304. package/dist/skills/expand.d.ts +35 -0
  305. package/dist/skills/expand.js +46 -0
  306. package/dist/skills/frontmatter.d.ts +27 -0
  307. package/dist/skills/frontmatter.js +157 -0
  308. package/dist/skills/index-prompt.d.ts +13 -0
  309. package/dist/skills/index-prompt.js +42 -0
  310. package/dist/skills/templates.d.ts +52 -0
  311. package/dist/skills/templates.js +177 -0
  312. package/dist/tools/bash.d.ts +49 -0
  313. package/dist/tools/bash.js +222 -0
  314. package/dist/tools/edit-fuzzy.d.ts +36 -0
  315. package/dist/tools/edit-fuzzy.js +129 -0
  316. package/dist/tools/edit.d.ts +38 -0
  317. package/dist/tools/edit.js +241 -0
  318. package/dist/tools/file-mutex.d.ts +8 -0
  319. package/dist/tools/file-mutex.js +29 -0
  320. package/dist/tools/glob.d.ts +44 -0
  321. package/dist/tools/glob.js +217 -0
  322. package/dist/tools/grep.d.ts +39 -0
  323. package/dist/tools/grep.js +179 -0
  324. package/dist/tools/ignore.d.ts +40 -0
  325. package/dist/tools/ignore.js +174 -0
  326. package/dist/tools/ls.d.ts +21 -0
  327. package/dist/tools/ls.js +96 -0
  328. package/dist/tools/output-accumulator.d.ts +48 -0
  329. package/dist/tools/output-accumulator.js +106 -0
  330. package/dist/tools/paths.d.ts +20 -0
  331. package/dist/tools/paths.js +58 -0
  332. package/dist/tools/presets.d.ts +71 -0
  333. package/dist/tools/presets.js +128 -0
  334. package/dist/tools/process-tree.d.ts +35 -0
  335. package/dist/tools/process-tree.js +125 -0
  336. package/dist/tools/read.d.ts +28 -0
  337. package/dist/tools/read.js +181 -0
  338. package/dist/tools/registry.d.ts +43 -0
  339. package/dist/tools/registry.js +106 -0
  340. package/dist/tools/shell.d.ts +38 -0
  341. package/dist/tools/shell.js +91 -0
  342. package/dist/tools/task.d.ts +29 -0
  343. package/dist/tools/task.js +107 -0
  344. package/dist/tools/todo.d.ts +28 -0
  345. package/dist/tools/todo.js +107 -0
  346. package/dist/tools/truncate.d.ts +44 -0
  347. package/dist/tools/truncate.js +175 -0
  348. package/dist/tools/types.d.ts +135 -0
  349. package/dist/tools/types.js +19 -0
  350. package/dist/tools/write.d.ts +20 -0
  351. package/dist/tools/write.js +84 -0
  352. package/dist/tui/ansi.d.ts +29 -0
  353. package/dist/tui/ansi.js +420 -0
  354. package/dist/tui/component.d.ts +38 -0
  355. package/dist/tui/component.js +13 -0
  356. package/dist/tui/components/box.d.ts +26 -0
  357. package/dist/tui/components/box.js +65 -0
  358. package/dist/tui/components/container.d.ts +14 -0
  359. package/dist/tui/components/container.js +39 -0
  360. package/dist/tui/components/editor-buffer.d.ts +67 -0
  361. package/dist/tui/components/editor-buffer.js +300 -0
  362. package/dist/tui/components/editor-paste.d.ts +29 -0
  363. package/dist/tui/components/editor-paste.js +64 -0
  364. package/dist/tui/components/editor.d.ts +114 -0
  365. package/dist/tui/components/editor.js +530 -0
  366. package/dist/tui/components/key-value.d.ts +29 -0
  367. package/dist/tui/components/key-value.js +48 -0
  368. package/dist/tui/components/loader.d.ts +35 -0
  369. package/dist/tui/components/loader.js +71 -0
  370. package/dist/tui/components/markdown.d.ts +90 -0
  371. package/dist/tui/components/markdown.js +462 -0
  372. package/dist/tui/components/meter.d.ts +29 -0
  373. package/dist/tui/components/meter.js +47 -0
  374. package/dist/tui/components/overlay.d.ts +24 -0
  375. package/dist/tui/components/overlay.js +52 -0
  376. package/dist/tui/components/select-list.d.ts +57 -0
  377. package/dist/tui/components/select-list.js +179 -0
  378. package/dist/tui/components/spacer.d.ts +11 -0
  379. package/dist/tui/components/spacer.js +16 -0
  380. package/dist/tui/components/text.d.ts +30 -0
  381. package/dist/tui/components/text.js +65 -0
  382. package/dist/tui/keybindings.d.ts +66 -0
  383. package/dist/tui/keybindings.js +120 -0
  384. package/dist/tui/keys.d.ts +38 -0
  385. package/dist/tui/keys.js +275 -0
  386. package/dist/tui/stdin-buffer.d.ts +41 -0
  387. package/dist/tui/stdin-buffer.js +206 -0
  388. package/dist/tui/terminal.d.ts +79 -0
  389. package/dist/tui/terminal.js +153 -0
  390. package/dist/tui/theme.d.ts +31 -0
  391. package/dist/tui/theme.js +199 -0
  392. package/dist/tui/tui.d.ts +103 -0
  393. package/dist/tui/tui.js +363 -0
  394. package/dist/tui/vt-screen.d.ts +46 -0
  395. package/dist/tui/vt-screen.js +251 -0
  396. package/dist/tui.d.ts +30 -0
  397. package/dist/tui.js +31 -0
  398. package/dist/version.d.ts +8 -0
  399. package/dist/version.js +24 -0
  400. package/docs/codemode.md +102 -0
  401. package/docs/hooks.md +196 -0
  402. package/docs/host-api.md +161 -0
  403. package/docs/providers.md +316 -0
  404. package/docs/rpc.md +253 -0
  405. package/docs/session-format.md +119 -0
  406. package/docs/tui.md +168 -0
  407. package/package.json +101 -4
@@ -0,0 +1,174 @@
1
+ /**
2
+ * `.gitignore` / `.ignore` 解析与匹配,以及尊重它们的目录遍历(设计 §5.2 grep / glob)。[B3]
3
+ *
4
+ * 规则语义(gitignore 子集):空行与 `#` 注释;`\#`、`\!`、`\ ` 转义;`!` 取反;末尾 `/` 只匹配目录;
5
+ * 中间或开头含 `/` 的模式锚定在 ignore 文件所在目录,否则匹配任意深度的名字;`**` 的三种位置;
6
+ * 同一路径**最后**命中的规则生效;被忽略的目录不再下钻(其下的取反规则无效,与 git 一致)。
7
+ * 嵌套:每个目录的 `.gitignore` 先、`.ignore` 后(后者优先);从搜索根向上到仓库根(含 `.git` 的
8
+ * 目录)的祖先 ignore 文件也生效。`.git` 目录永远跳过;目录符号链接不跟随。
9
+ */
10
+ import { readdir, readFile, stat } from "node:fs/promises";
11
+ import { dirname, join } from "node:path";
12
+ import { toPosix } from "./paths.js";
13
+ import { globBody } from "./glob.js";
14
+ export const IGNORE_FILES = [".gitignore", ".ignore"];
15
+ function trimTrailingSpaces(line) {
16
+ let end = line.length;
17
+ while (end > 0 && line[end - 1] === " " && line[end - 2] !== "\\")
18
+ end--;
19
+ return line.slice(0, end);
20
+ }
21
+ /** 解析一行;空 / 注释返回 undefined。 */
22
+ export function parseIgnoreLine(rawLine, base, nocase = false) {
23
+ let line = trimTrailingSpaces(rawLine.replace(/\r$/, ""));
24
+ if (line === "" || line.startsWith("#"))
25
+ return undefined;
26
+ let negate = false;
27
+ if (line.startsWith("!")) {
28
+ negate = true;
29
+ line = line.slice(1);
30
+ }
31
+ else if (line.startsWith("\\!") || line.startsWith("\\#")) {
32
+ line = line.slice(1);
33
+ }
34
+ let dirOnly = false;
35
+ if (line.endsWith("/") && !line.endsWith("\\/")) {
36
+ dirOnly = true;
37
+ line = line.replace(/\/+$/, "");
38
+ }
39
+ if (line === "")
40
+ return undefined;
41
+ const anchored = line.includes("/");
42
+ if (line.startsWith("/"))
43
+ line = line.slice(1);
44
+ const body = globBody(line, { braces: false });
45
+ const prefix = anchored || line.startsWith("**/") ? "" : "(?:[^/]*/)*";
46
+ return {
47
+ negate,
48
+ dirOnly,
49
+ regex: new RegExp(`^${prefix}${body}$`, nocase ? "i" : ""),
50
+ base: base.replace(/\/+$/, ""),
51
+ source: rawLine,
52
+ };
53
+ }
54
+ export function parseIgnoreFile(content, base, nocase = false) {
55
+ const rules = [];
56
+ for (const line of content.split("\n")) {
57
+ const rule = parseIgnoreLine(line, base, nocase);
58
+ if (rule)
59
+ rules.push(rule);
60
+ }
61
+ return rules;
62
+ }
63
+ /** `absPosix` 相对 `base` 的路径;不在其下返回 undefined。 */
64
+ function relativeTo(base, absPosix) {
65
+ if (base === "")
66
+ return absPosix.replace(/^\/+/, "");
67
+ if (absPosix === base)
68
+ return "";
69
+ const prefix = base.endsWith("/") ? base : `${base}/`;
70
+ return absPosix.startsWith(prefix) ? absPosix.slice(prefix.length) : undefined;
71
+ }
72
+ /** 按规则顺序求值,最后命中者生效。 */
73
+ export function isIgnoredBy(rules, absPath, isDir) {
74
+ const absPosix = toPosix(absPath);
75
+ let ignored = false;
76
+ for (const rule of rules) {
77
+ if (rule.dirOnly && !isDir)
78
+ continue;
79
+ const rel = relativeTo(rule.base, absPosix);
80
+ if (rel === undefined || rel === "")
81
+ continue;
82
+ if (rule.regex.test(rel))
83
+ ignored = !rule.negate;
84
+ }
85
+ return ignored;
86
+ }
87
+ async function readRules(dir, nocase) {
88
+ const rules = [];
89
+ for (const name of IGNORE_FILES) {
90
+ try {
91
+ const text = await readFile(join(dir, name), "utf8");
92
+ rules.push(...parseIgnoreFile(text, toPosix(dir), nocase));
93
+ }
94
+ catch {
95
+ // 不存在
96
+ }
97
+ }
98
+ return rules;
99
+ }
100
+ /** 搜索根之上、直到仓库根(含 `.git` 的目录)的祖先 ignore 规则,外层在前。 */
101
+ export async function ancestorRules(root, nocase = false) {
102
+ const chain = [];
103
+ let dir = root;
104
+ let foundRepo = await exists(join(root, ".git"));
105
+ while (!foundRepo) {
106
+ const parent = dirname(dir);
107
+ if (parent === dir)
108
+ return [];
109
+ dir = parent;
110
+ chain.unshift(dir);
111
+ foundRepo = await exists(join(dir, ".git"));
112
+ }
113
+ const rules = [];
114
+ for (const d of chain)
115
+ rules.push(...(await readRules(d, nocase)));
116
+ return rules;
117
+ }
118
+ async function exists(path) {
119
+ try {
120
+ await stat(path);
121
+ return true;
122
+ }
123
+ catch {
124
+ return false;
125
+ }
126
+ }
127
+ /** 深度优先、目录内按名字排序的遍历;产出文件与目录(目录先于其内容)。 */
128
+ export async function* walk(root, options = {}) {
129
+ const respect = options.respectIgnore ?? true;
130
+ const nocase = options.nocase ?? process.platform === "win32";
131
+ const base = respect ? await ancestorRules(root, nocase) : [];
132
+ yield* walkDir(root, "", base, respect, nocase, options.signal);
133
+ }
134
+ async function* walkDir(dir, rel, inherited, respect, nocase, signal) {
135
+ if (signal?.aborted)
136
+ return;
137
+ const rules = respect ? [...inherited, ...(await readRules(dir, nocase))] : inherited;
138
+ let entries;
139
+ try {
140
+ entries = await readdir(dir, { withFileTypes: true });
141
+ }
142
+ catch {
143
+ return;
144
+ }
145
+ entries.sort((a, b) => (a.name < b.name ? -1 : a.name > b.name ? 1 : 0));
146
+ for (const entry of entries) {
147
+ if (signal?.aborted)
148
+ return;
149
+ if (entry.name === ".git")
150
+ continue;
151
+ const abs = join(dir, entry.name);
152
+ const childRel = rel === "" ? entry.name : `${rel}/${entry.name}`;
153
+ let isDir = entry.isDirectory();
154
+ if (entry.isSymbolicLink()) {
155
+ // 链接到文件的照常产出;链接到目录的不跟随(避免环),作为普通条目跳过。
156
+ try {
157
+ if ((await stat(abs)).isDirectory())
158
+ continue;
159
+ }
160
+ catch {
161
+ continue;
162
+ }
163
+ isDir = false;
164
+ }
165
+ else if (!isDir && !entry.isFile()) {
166
+ continue;
167
+ }
168
+ if (respect && isIgnoredBy(rules, abs, isDir))
169
+ continue;
170
+ yield { abs, rel: childRel, isDir };
171
+ if (isDir)
172
+ yield* walkDir(abs, childRel, rules, respect, nocase, signal);
173
+ }
174
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * `ls` 工具(设计 §5.2)。[B3]
3
+ *
4
+ * 目录项按名字排序(目录与文件混排,与 `ls` 一致);目录写 `name/`,文件附大小,符号链接写
5
+ * `name -> target`;含点文件,不过滤 ignore;缺省上限 500。
6
+ */
7
+ import type { ToolContext, ToolDefinition, ToolResult } from "./types.js";
8
+ export interface LsInput {
9
+ path?: string;
10
+ limit?: number;
11
+ }
12
+ export declare const DEFAULT_LS_LIMIT = 500;
13
+ export interface LsEntry {
14
+ name: string;
15
+ type: "file" | "dir" | "symlink" | "other";
16
+ size?: number;
17
+ target?: string;
18
+ }
19
+ export declare function formatEntry(entry: LsEntry): string;
20
+ export declare function executeLs(input: LsInput, ctx: ToolContext): Promise<ToolResult>;
21
+ export declare function createLsTool(): ToolDefinition<LsInput>;
@@ -0,0 +1,96 @@
1
+ /**
2
+ * `ls` 工具(设计 §5.2)。[B3]
3
+ *
4
+ * 目录项按名字排序(目录与文件混排,与 `ls` 一致);目录写 `name/`,文件附大小,符号链接写
5
+ * `name -> target`;含点文件,不过滤 ignore;缺省上限 500。
6
+ */
7
+ import { lstat, readdir, readlink, stat } from "node:fs/promises";
8
+ import { join } from "node:path";
9
+ import { displayPath, resolvePath } from "./paths.js";
10
+ import { formatSize } from "./truncate.js";
11
+ export const DEFAULT_LS_LIMIT = 500;
12
+ async function describe(dir, name) {
13
+ const abs = join(dir, name);
14
+ try {
15
+ const info = await lstat(abs);
16
+ if (info.isSymbolicLink()) {
17
+ let target = "?";
18
+ try {
19
+ target = await readlink(abs);
20
+ }
21
+ catch {
22
+ // 保留 ?
23
+ }
24
+ let pointsToDir = false;
25
+ try {
26
+ pointsToDir = (await stat(abs)).isDirectory();
27
+ }
28
+ catch {
29
+ // 悬空链接
30
+ }
31
+ return { name: pointsToDir ? `${name}/` : name, type: "symlink", target };
32
+ }
33
+ if (info.isDirectory())
34
+ return { name: `${name}/`, type: "dir" };
35
+ if (info.isFile())
36
+ return { name, type: "file", size: info.size };
37
+ return { name, type: "other" };
38
+ }
39
+ catch {
40
+ return { name, type: "other" };
41
+ }
42
+ }
43
+ export function formatEntry(entry) {
44
+ if (entry.type === "symlink")
45
+ return `${entry.name} -> ${entry.target ?? "?"}`;
46
+ if (entry.type === "file")
47
+ return `${entry.name} (${formatSize(entry.size ?? 0)})`;
48
+ return entry.name;
49
+ }
50
+ export async function executeLs(input, ctx) {
51
+ const limit = input.limit ?? DEFAULT_LS_LIMIT;
52
+ if (!Number.isInteger(limit) || limit < 1) {
53
+ return { content: "limit must be an integer ≥ 1", isError: true };
54
+ }
55
+ const dir = resolvePath(input.path ?? ".", ctx.cwd);
56
+ const shown = displayPath(dir, ctx.cwd);
57
+ let names;
58
+ try {
59
+ if (!(await stat(dir)).isDirectory())
60
+ return { content: `${shown} is not a directory`, isError: true };
61
+ names = await readdir(dir);
62
+ }
63
+ catch {
64
+ return { content: `Directory not found: ${shown}`, isError: true };
65
+ }
66
+ names.sort((a, b) => a.localeCompare(b, "en"));
67
+ if (names.length === 0)
68
+ return { content: `(${shown} is empty)`, details: { count: 0 } };
69
+ const entries = await Promise.all(names.slice(0, limit).map((n) => describe(dir, n)));
70
+ let content = entries.map(formatEntry).join("\n");
71
+ if (names.length > limit) {
72
+ content += `\n\n[${names.length} entries; showing the first ${limit}. Raise limit to see more.]`;
73
+ }
74
+ return { content, details: { count: names.length, entries } };
75
+ }
76
+ export function createLsTool() {
77
+ return {
78
+ name: "ls",
79
+ label: "List",
80
+ description: "List a directory: subdirectories end with `/`, files show their size, symlinks show their " +
81
+ `target. Includes dotfiles. Default limit ${DEFAULT_LS_LIMIT}.`,
82
+ parameters: {
83
+ type: "object",
84
+ properties: {
85
+ path: { type: "string", description: "Directory (default: cwd)" },
86
+ limit: { type: "integer", description: `Maximum entries (default ${DEFAULT_LS_LIMIT})` },
87
+ },
88
+ additionalProperties: false,
89
+ },
90
+ permission: "read",
91
+ executionMode: "parallel",
92
+ annotations: { readOnly: true },
93
+ promptSnippet: "ls: list directory contents",
94
+ execute: executeLs,
95
+ };
96
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * 进程输出累积(设计 §5.2 bash)。[B3]
3
+ *
4
+ * - 保留滚动尾部(约 2 × maxBytes)用于流式 `onUpdate` 与最终尾截断;
5
+ * - 内存里最多攒 `memoryLimitBytes`,超出即把已有内容落文件,之后增量追加,内存只留尾部;
6
+ * - `finish()` 做尾截断(行数 + 字节);发生截断而尚未落盘时补写全文,给出 `fullOutputPath`;
7
+ * - 输出清洗:去 ANSI 转义与除 `\t\n` 外的控制字符,`\r\n` → `\n`。
8
+ */
9
+ export interface OutputAccumulatorOptions {
10
+ maxLines?: number;
11
+ maxBytes?: number;
12
+ /** 内存上限,缺省 1 MB。 */
13
+ memoryLimitBytes?: number;
14
+ /** 全文落盘路径(懒求值,只在需要时调用一次)。 */
15
+ spillPath(): string;
16
+ }
17
+ export interface AccumulatedOutput {
18
+ /** 尾截断后的输出。 */
19
+ output: string;
20
+ truncated: boolean;
21
+ fullOutputPath?: string;
22
+ totalBytes: number;
23
+ totalLines: number;
24
+ outputLines: number;
25
+ }
26
+ export declare function sanitizeOutput(text: string): string;
27
+ export declare class OutputAccumulator {
28
+ private readonly options;
29
+ private readonly maxLines;
30
+ private readonly maxBytes;
31
+ private readonly memoryLimit;
32
+ private readonly decoder;
33
+ private chunks;
34
+ private memoryBytes;
35
+ private tailText;
36
+ private spilledTo;
37
+ private bytes;
38
+ private newlines;
39
+ private lastChar;
40
+ constructor(options: OutputAccumulatorOptions);
41
+ get totalBytes(): number;
42
+ append(chunk: Buffer | string): void;
43
+ private pushText;
44
+ private spill;
45
+ /** 当前滚动尾部(已清洗、尾截断),给流式 onUpdate。 */
46
+ tail(maxLines?: number): string;
47
+ finish(): AccumulatedOutput;
48
+ }
@@ -0,0 +1,106 @@
1
+ /**
2
+ * 进程输出累积(设计 §5.2 bash)。[B3]
3
+ *
4
+ * - 保留滚动尾部(约 2 × maxBytes)用于流式 `onUpdate` 与最终尾截断;
5
+ * - 内存里最多攒 `memoryLimitBytes`,超出即把已有内容落文件,之后增量追加,内存只留尾部;
6
+ * - `finish()` 做尾截断(行数 + 字节);发生截断而尚未落盘时补写全文,给出 `fullOutputPath`;
7
+ * - 输出清洗:去 ANSI 转义与除 `\t\n` 外的控制字符,`\r\n` → `\n`。
8
+ */
9
+ import { appendFileSync, mkdirSync, writeFileSync } from "node:fs";
10
+ import { dirname } from "node:path";
11
+ import { StringDecoder } from "node:string_decoder";
12
+ import { DEFAULT_MAX_BYTES, DEFAULT_MAX_LINES, sliceTailBytes, truncateTail } from "./truncate.js";
13
+ const ANSI = /\x1b\[[0-?]*[ -/]*[@-~]|\x1b\][^\x07\x1b]*(?:\x07|\x1b\\)|\x1b[@-Z\\-_]/g;
14
+ const CONTROL = /[\x00-\x08\x0b\x0c\x0e-\x1f\x7f]/g;
15
+ export function sanitizeOutput(text) {
16
+ return text.replace(/\r\n/g, "\n").replace(ANSI, "").replace(/\r/g, "\n").replace(CONTROL, "");
17
+ }
18
+ export class OutputAccumulator {
19
+ options;
20
+ maxLines;
21
+ maxBytes;
22
+ memoryLimit;
23
+ decoder = new StringDecoder("utf8");
24
+ chunks = [];
25
+ memoryBytes = 0;
26
+ tailText = "";
27
+ spilledTo;
28
+ bytes = 0;
29
+ newlines = 0;
30
+ lastChar = "";
31
+ constructor(options) {
32
+ this.options = options;
33
+ this.maxLines = options.maxLines ?? DEFAULT_MAX_LINES;
34
+ this.maxBytes = options.maxBytes ?? DEFAULT_MAX_BYTES;
35
+ this.memoryLimit = options.memoryLimitBytes ?? 1024 * 1024;
36
+ }
37
+ get totalBytes() {
38
+ return this.bytes;
39
+ }
40
+ append(chunk) {
41
+ const raw = typeof chunk === "string" ? Buffer.from(chunk, "utf8") : chunk;
42
+ this.bytes += raw.length;
43
+ this.pushText(this.decoder.write(raw));
44
+ }
45
+ pushText(text) {
46
+ if (text === "")
47
+ return;
48
+ for (let i = 0; i < text.length; i++)
49
+ if (text.charCodeAt(i) === 10)
50
+ this.newlines++;
51
+ this.lastChar = text[text.length - 1] ?? this.lastChar;
52
+ this.tailText += text;
53
+ if (this.tailText.length > this.maxBytes * 4) {
54
+ this.tailText = sliceTailBytes(this.tailText, this.maxBytes * 2);
55
+ }
56
+ if (this.spilledTo !== undefined) {
57
+ appendFileSync(this.spilledTo, text);
58
+ return;
59
+ }
60
+ this.chunks.push(text);
61
+ this.memoryBytes += Buffer.byteLength(text, "utf8");
62
+ if (this.memoryBytes > this.memoryLimit)
63
+ this.spill();
64
+ }
65
+ spill() {
66
+ const target = this.options.spillPath();
67
+ mkdirSync(dirname(target), { recursive: true });
68
+ writeFileSync(target, this.chunks.join(""));
69
+ this.spilledTo = target;
70
+ this.chunks = [];
71
+ this.memoryBytes = 0;
72
+ }
73
+ /** 当前滚动尾部(已清洗、尾截断),给流式 onUpdate。 */
74
+ tail(maxLines = 50) {
75
+ return truncateTail(sanitizeOutput(this.tailText), { maxLines, maxBytes: this.maxBytes })
76
+ .content;
77
+ }
78
+ finish() {
79
+ this.pushText(this.decoder.end());
80
+ const totalLines = this.newlines + (this.bytes > 0 && this.lastChar !== "\n" ? 1 : 0);
81
+ let source;
82
+ if (this.spilledTo !== undefined) {
83
+ // 尾部可能从半行开始:去掉第一行残片。
84
+ const cut = this.tailText.indexOf("\n");
85
+ source = cut >= 0 ? this.tailText.slice(cut + 1) : this.tailText;
86
+ }
87
+ else {
88
+ source = this.chunks.join("");
89
+ }
90
+ const result = truncateTail(sanitizeOutput(source), {
91
+ maxLines: this.maxLines,
92
+ maxBytes: this.maxBytes,
93
+ });
94
+ const truncated = result.truncated || this.spilledTo !== undefined;
95
+ if (truncated && this.spilledTo === undefined)
96
+ this.spill();
97
+ return {
98
+ output: result.content,
99
+ truncated,
100
+ ...(truncated && this.spilledTo !== undefined ? { fullOutputPath: this.spilledTo } : {}),
101
+ totalBytes: this.bytes,
102
+ totalLines,
103
+ outputLines: result.outputLines,
104
+ };
105
+ }
106
+ }
@@ -0,0 +1,20 @@
1
+ /**
2
+ * 路径解析(设计 §5.2「通用安全」)。[B3]
3
+ *
4
+ * - 展开 `~` / `~/…`(`~user` 不展开);相对路径按 cwd 解析;结果是规范化绝对路径。
5
+ * - 含 NUL 的路径一律拒绝(AmaError invalid_arguments)。
6
+ * - 符号链接策略:**跟随**,不做沙箱(信任边界是容器 / VM)。规则匹配用词法路径,
7
+ * `realPathOrSelf()` 给需要真实路径的调用方(如 ls 标注链接目标)。
8
+ * - `toPosix()` 把路径统一成 `/` 分隔,供 glob / ignore / 权限规则匹配。
9
+ */
10
+ export declare function assertNoNul(path: string): void;
11
+ /** 展开 `~` 与 `~/…`、`~\…`。 */
12
+ export declare function expandHome(path: string, home?: string): string;
13
+ /** 解析为绝对路径;空串视为 cwd。 */
14
+ export declare function resolvePath(path: string, cwd: string, home?: string): string;
15
+ export declare function toPosix(path: string): string;
16
+ /** cwd 内给相对路径,cwd 外给绝对路径;统一 `/`。 */
17
+ export declare function displayPath(absolutePath: string, cwd: string): string;
18
+ /** 是否在 dir 之内(含 dir 本身)。 */
19
+ export declare function isWithin(dir: string, target: string): boolean;
20
+ export declare function realPathOrSelf(path: string): string;
@@ -0,0 +1,58 @@
1
+ /**
2
+ * 路径解析(设计 §5.2「通用安全」)。[B3]
3
+ *
4
+ * - 展开 `~` / `~/…`(`~user` 不展开);相对路径按 cwd 解析;结果是规范化绝对路径。
5
+ * - 含 NUL 的路径一律拒绝(AmaError invalid_arguments)。
6
+ * - 符号链接策略:**跟随**,不做沙箱(信任边界是容器 / VM)。规则匹配用词法路径,
7
+ * `realPathOrSelf()` 给需要真实路径的调用方(如 ls 标注链接目标)。
8
+ * - `toPosix()` 把路径统一成 `/` 分隔,供 glob / ignore / 权限规则匹配。
9
+ */
10
+ import { realpathSync } from "node:fs";
11
+ import { homedir } from "node:os";
12
+ import { isAbsolute, join, relative, resolve, sep } from "node:path";
13
+ import { AmaError } from "../errors.js";
14
+ export function assertNoNul(path) {
15
+ if (path.includes("\0")) {
16
+ throw new AmaError("invalid_arguments", "Path must not contain NUL characters");
17
+ }
18
+ }
19
+ /** 展开 `~` 与 `~/…`、`~\…`。 */
20
+ export function expandHome(path, home = homedir()) {
21
+ if (path === "~")
22
+ return home;
23
+ if (path.startsWith("~/") || path.startsWith("~\\"))
24
+ return join(home, path.slice(2));
25
+ return path;
26
+ }
27
+ /** 解析为绝对路径;空串视为 cwd。 */
28
+ export function resolvePath(path, cwd, home) {
29
+ assertNoNul(path);
30
+ const trimmed = path.trim() === "" ? "." : path;
31
+ const expanded = expandHome(trimmed, home);
32
+ return isAbsolute(expanded) ? resolve(expanded) : resolve(cwd, expanded);
33
+ }
34
+ export function toPosix(path) {
35
+ return sep === "\\" ? path.replace(/\\/g, "/") : path;
36
+ }
37
+ /** cwd 内给相对路径,cwd 外给绝对路径;统一 `/`。 */
38
+ export function displayPath(absolutePath, cwd) {
39
+ const rel = relative(cwd, absolutePath);
40
+ if (rel === "")
41
+ return ".";
42
+ if (rel.startsWith("..") || isAbsolute(rel))
43
+ return toPosix(absolutePath);
44
+ return toPosix(rel);
45
+ }
46
+ /** 是否在 dir 之内(含 dir 本身)。 */
47
+ export function isWithin(dir, target) {
48
+ const rel = relative(dir, target);
49
+ return rel === "" || (!rel.startsWith("..") && !isAbsolute(rel));
50
+ }
51
+ export function realPathOrSelf(path) {
52
+ try {
53
+ return realpathSync(path);
54
+ }
55
+ catch {
56
+ return path;
57
+ }
58
+ }
@@ -0,0 +1,71 @@
1
+ /**
2
+ * 工具预设(设计 §5.6):模型直接看到哪些内置工具。
3
+ *
4
+ * | 预设 | 模型直接看到 |
5
+ * | ------------- | ----------------------------------------- |
6
+ * | `default` | read、edit、write、bash、grep、glob |
7
+ * | `minimal` | read、edit、write、bash |
8
+ * | `codemode` | 只有 codemode(其余工具在脚本里调用) |
9
+ * | `coordinator` | read + 宿主注册的工具 |
10
+ *
11
+ * - 预设只管**内置**工具;宿主 / SDK 注册的工具(`canvas_*` 等)总在活动集里,除非用户
12
+ * `--tools a,b,c` 整组替换(之后只用列出的名字)。
13
+ * - `tools.default`:`+name` / `-name` 在预设上增减;不带前缀的名字整组替换预设的内置工具,
14
+ * 之后再应用带前缀的项。未注册的名字记 warning 并忽略。
15
+ * - codemode 开关跟随预设:`codemode` 预设 → `only`,其余 → `off`;`codemode.mode` 显式配置覆盖。
16
+ * - codemode 工具由 B10 经组装根的 `toolFactories` 注册(`codemode.mode` 为 off 时不注册);不可用
17
+ * (例如 `codemode.requireStrict` 而运行时 Node 不隔离网络)时 codemode 预设**回退到 default 并
18
+ * warning**(不报错:零配置用户不应因此起不来),`on` 同样忽略。
19
+ * - `only` 模式活动集独占:宿主 / SDK 工具也不直接暴露,只能在脚本里调用(`exclusive`)。
20
+ */
21
+ import type { AmaConfig, CodemodeMode, ToolsPreset } from "../config/types.js";
22
+ import { ToolRegistry } from "./registry.js";
23
+ import type { ToolDefinition, ToolSource } from "./types.js";
24
+ export declare const CODEMODE_TOOL = "codemode";
25
+ /** 各预设下模型直接看到的内置工具(codemode 预设见 `resolvePreset`)。 */
26
+ export declare const PRESET_TOOLS: Readonly<Record<ToolsPreset, readonly string[]>>;
27
+ /** 生效的 codemode 模式:显式配置优先,否则跟随预设。 */
28
+ export declare function effectiveCodemodeMode(config: Pick<AmaConfig, "tools" | "codemode">): CodemodeMode;
29
+ /**
30
+ * `tools.default` 微调:不带前缀的名字整组替换 `base`,再依次应用 `+name` / `-name`。
31
+ * 返回去重后的名字(保持首次出现顺序)。
32
+ */
33
+ export declare function applyToolAdjustments(base: readonly string[], adjustments: readonly string[] | undefined): string[];
34
+ export interface PresetResolution {
35
+ /** 生效的预设(codemode 工具缺失时回退为 default)。 */
36
+ preset: ToolsPreset;
37
+ codemode: CodemodeMode;
38
+ /** 活动的内置工具名(按名排序)。 */
39
+ builtin: string[];
40
+ warnings: string[];
41
+ }
42
+ export declare function resolvePreset(input: {
43
+ config: Pick<AmaConfig, "tools" | "codemode">;
44
+ /** 该名字是否已注册(且未禁用)。 */
45
+ available(name: string): boolean;
46
+ }): PresetResolution;
47
+ type RegisterListener = (tool: ToolDefinition, source: ToolSource) => void;
48
+ /**
49
+ * 带预设的注册表:活动集 = 预设里的内置工具 + 全部非内置工具;`setActive()`(`--tools`)之后
50
+ * 退回整组替换语义。`onRegister` 让组装根把会话创建之后才注册的宿主工具追加进会话。
51
+ */
52
+ export declare class PresetToolRegistry extends ToolRegistry {
53
+ private presetNames;
54
+ private exclusive;
55
+ private explicit;
56
+ private readonly listeners;
57
+ /**
58
+ * 设预设的内置工具;undefined = 全部内置工具。`exclusive`(codemode only):活动集只有这些名字,
59
+ * 宿主 / SDK 工具也不进活动集。
60
+ */
61
+ setPresetTools(names: readonly string[] | undefined, options?: {
62
+ exclusive?: boolean;
63
+ }): void;
64
+ /** 是否被 `setActive` 整组替换过。 */
65
+ get hasExplicitActive(): boolean;
66
+ setActive(names: readonly string[]): void;
67
+ active(): readonly ToolDefinition[];
68
+ register(tool: ToolDefinition, source: ToolSource): void;
69
+ onRegister(listener: RegisterListener): () => void;
70
+ }
71
+ export {};