lonny-agent 0.2.6 → 0.2.7

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 (475) hide show
  1. package/.github/workflows/ci.yml +21 -0
  2. package/AGENTS.md +106 -0
  3. package/CHANGELOG.md +24 -0
  4. package/dist/agent/__tests__/session-restore.test.d.ts +2 -0
  5. package/dist/agent/__tests__/session-restore.test.d.ts.map +1 -0
  6. package/dist/agent/__tests__/session-restore.test.js +260 -0
  7. package/dist/agent/__tests__/session-restore.test.js.map +1 -0
  8. package/dist/agent/commands.d.ts +26 -0
  9. package/dist/agent/commands.d.ts.map +1 -0
  10. package/dist/agent/commands.js +253 -0
  11. package/dist/agent/commands.js.map +1 -0
  12. package/dist/agent/compaction.js +8 -1
  13. package/dist/agent/compaction.js.map +1 -1
  14. package/dist/agent/index.d.ts +2 -1
  15. package/dist/agent/index.d.ts.map +1 -1
  16. package/dist/agent/index.js +2 -2
  17. package/dist/agent/index.js.map +1 -1
  18. package/dist/agent/memory.d.ts +12 -0
  19. package/dist/agent/memory.d.ts.map +1 -0
  20. package/dist/agent/memory.js +51 -0
  21. package/dist/agent/memory.js.map +1 -0
  22. package/dist/agent/prompt-builder.d.ts +6 -1
  23. package/dist/agent/prompt-builder.d.ts.map +1 -1
  24. package/dist/agent/prompt-builder.js +89 -26
  25. package/dist/agent/prompt-builder.js.map +1 -1
  26. package/dist/agent/providers/openai.d.ts +1 -0
  27. package/dist/agent/providers/openai.d.ts.map +1 -1
  28. package/dist/agent/providers/openai.js +16 -3
  29. package/dist/agent/providers/openai.js.map +1 -1
  30. package/dist/agent/session-chat.d.ts +3 -0
  31. package/dist/agent/session-chat.d.ts.map +1 -0
  32. package/dist/agent/session-chat.js +384 -0
  33. package/dist/agent/session-chat.js.map +1 -0
  34. package/dist/agent/session-display.d.ts +29 -0
  35. package/dist/agent/session-display.d.ts.map +1 -0
  36. package/dist/agent/session-display.js +179 -0
  37. package/dist/agent/session-display.js.map +1 -0
  38. package/dist/agent/session-persistence.d.ts +55 -0
  39. package/dist/agent/session-persistence.d.ts.map +1 -0
  40. package/dist/agent/session-persistence.js +101 -0
  41. package/dist/agent/session-persistence.js.map +1 -0
  42. package/dist/agent/session-utils.d.ts +5 -0
  43. package/dist/agent/session-utils.d.ts.map +1 -0
  44. package/dist/agent/session-utils.js +51 -0
  45. package/dist/agent/session-utils.js.map +1 -0
  46. package/dist/agent/session.d.ts +15 -17
  47. package/dist/agent/session.d.ts.map +1 -1
  48. package/dist/agent/session.js +226 -608
  49. package/dist/agent/session.js.map +1 -1
  50. package/dist/cli/index.d.ts +4 -0
  51. package/dist/cli/index.d.ts.map +1 -1
  52. package/dist/cli/index.js +67 -2
  53. package/dist/cli/index.js.map +1 -1
  54. package/dist/config/index.d.ts +2 -2
  55. package/dist/config/index.d.ts.map +1 -1
  56. package/dist/index.js +24 -3
  57. package/dist/index.js.map +1 -1
  58. package/dist/tools/__tests__/bash.test.js +168 -1
  59. package/dist/tools/__tests__/bash.test.js.map +1 -1
  60. package/dist/tools/__tests__/edit.test.js +253 -6
  61. package/dist/tools/__tests__/edit.test.js.map +1 -1
  62. package/dist/tools/__tests__/fetch.test.js +1 -1
  63. package/dist/tools/__tests__/fetch.test.js.map +1 -1
  64. package/dist/tools/__tests__/glob.test.js +1 -1
  65. package/dist/tools/__tests__/glob.test.js.map +1 -1
  66. package/dist/tools/__tests__/grep.test.js +1 -1
  67. package/dist/tools/__tests__/grep.test.js.map +1 -1
  68. package/dist/tools/__tests__/ls.test.js +1 -1
  69. package/dist/tools/__tests__/ls.test.js.map +1 -1
  70. package/dist/tools/__tests__/read.test.js +1 -1
  71. package/dist/tools/__tests__/read.test.js.map +1 -1
  72. package/dist/tools/__tests__/registry.test.js +313 -0
  73. package/dist/tools/__tests__/registry.test.js.map +1 -1
  74. package/dist/tools/__tests__/write_plan.test.js +1 -1
  75. package/dist/tools/__tests__/write_plan.test.js.map +1 -1
  76. package/dist/tools/bash.d.ts.map +1 -1
  77. package/dist/tools/bash.js +659 -39
  78. package/dist/tools/bash.js.map +1 -1
  79. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.d.ts +2 -0
  80. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.d.ts.map +1 -0
  81. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.js +7 -0
  82. package/dist/tools/codebase/ast/__tests__/ast-edit-demo.js.map +1 -0
  83. package/dist/tools/codebase/ast/__tests__/ast-edit-final.d.ts +6 -0
  84. package/dist/tools/codebase/ast/__tests__/ast-edit-final.d.ts.map +1 -0
  85. package/dist/tools/codebase/ast/__tests__/ast-edit-final.js +11 -0
  86. package/dist/tools/codebase/ast/__tests__/ast-edit-final.js.map +1 -0
  87. package/dist/tools/codebase/ast/__tests__/ast-edit-test.d.ts +2 -0
  88. package/dist/tools/codebase/ast/__tests__/ast-edit-test.d.ts.map +1 -0
  89. package/dist/tools/codebase/ast/__tests__/ast-edit-test.js +9 -0
  90. package/dist/tools/codebase/ast/__tests__/ast-edit-test.js.map +1 -0
  91. package/dist/tools/codebase/ast/__tests__/integration.test.d.ts +2 -0
  92. package/dist/tools/codebase/ast/__tests__/integration.test.d.ts.map +1 -0
  93. package/dist/tools/codebase/ast/__tests__/integration.test.js +415 -0
  94. package/dist/tools/codebase/ast/__tests__/integration.test.js.map +1 -0
  95. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.d.ts +2 -0
  96. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.d.ts.map +1 -0
  97. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.js +414 -0
  98. package/dist/tools/codebase/ast/__tests__/tree-sitter.test.js.map +1 -0
  99. package/dist/tools/codebase/ast/adapter.d.ts +23 -0
  100. package/dist/tools/codebase/ast/adapter.d.ts.map +1 -0
  101. package/dist/tools/codebase/ast/adapter.js +11 -0
  102. package/dist/tools/codebase/ast/adapter.js.map +1 -0
  103. package/dist/tools/codebase/ast/tools.d.ts +3 -0
  104. package/dist/tools/codebase/ast/tools.d.ts.map +1 -0
  105. package/dist/tools/codebase/ast/tools.js +286 -0
  106. package/dist/tools/codebase/ast/tools.js.map +1 -0
  107. package/dist/tools/codebase/ast/tree-sitter-adapter.d.ts +3 -0
  108. package/dist/tools/codebase/ast/tree-sitter-adapter.d.ts.map +1 -0
  109. package/dist/tools/codebase/ast/tree-sitter-adapter.js +412 -0
  110. package/dist/tools/codebase/ast/tree-sitter-adapter.js.map +1 -0
  111. package/dist/tools/codebase/ast/tree-sitter-converters.d.ts +4 -0
  112. package/dist/tools/codebase/ast/tree-sitter-converters.d.ts.map +1 -0
  113. package/dist/tools/codebase/ast/tree-sitter-converters.js +447 -0
  114. package/dist/tools/codebase/ast/tree-sitter-converters.js.map +1 -0
  115. package/dist/tools/codebase/ast/types.d.ts +103 -0
  116. package/dist/tools/codebase/ast/types.d.ts.map +1 -0
  117. package/dist/tools/codebase/ast/types.js +2 -0
  118. package/dist/tools/codebase/ast/types.js.map +1 -0
  119. package/dist/tools/codebase/ast/wasm/tree-sitter-python.wasm +0 -0
  120. package/dist/tools/codebase/ast/wasm/tree-sitter-tsx.wasm +0 -0
  121. package/dist/tools/codebase/ast/wasm/tree-sitter-typescript.wasm +0 -0
  122. package/dist/tools/codebase/ast/wasm/tree-sitter.wasm +0 -0
  123. package/dist/tools/codebase/ast/wasm/web-tree-sitter.wasm +0 -0
  124. package/dist/tools/codebase/find.d.ts +3 -0
  125. package/dist/tools/codebase/find.d.ts.map +1 -0
  126. package/dist/tools/codebase/find.js +61 -0
  127. package/dist/tools/codebase/find.js.map +1 -0
  128. package/dist/tools/codebase/glob.d.ts +3 -0
  129. package/dist/tools/codebase/glob.d.ts.map +1 -0
  130. package/dist/tools/codebase/glob.js +37 -0
  131. package/dist/tools/codebase/glob.js.map +1 -0
  132. package/dist/tools/codebase/grep.d.ts +3 -0
  133. package/dist/tools/codebase/grep.d.ts.map +1 -0
  134. package/dist/tools/codebase/grep.js +169 -0
  135. package/dist/tools/codebase/grep.js.map +1 -0
  136. package/dist/tools/codebase/ls.d.ts +3 -0
  137. package/dist/tools/codebase/ls.d.ts.map +1 -0
  138. package/dist/tools/codebase/ls.js +39 -0
  139. package/dist/tools/codebase/ls.js.map +1 -0
  140. package/dist/tools/codebase/read.d.ts +10 -0
  141. package/dist/tools/codebase/read.d.ts.map +1 -0
  142. package/dist/tools/codebase/read.js +81 -0
  143. package/dist/tools/codebase/read.js.map +1 -0
  144. package/dist/tools/delete_memory.d.ts +3 -0
  145. package/dist/tools/delete_memory.d.ts.map +1 -0
  146. package/dist/tools/delete_memory.js +46 -0
  147. package/dist/tools/delete_memory.js.map +1 -0
  148. package/dist/tools/edit/diff-compute.d.ts +4 -0
  149. package/dist/tools/edit/diff-compute.d.ts.map +1 -0
  150. package/dist/tools/edit/diff-compute.js +18 -0
  151. package/dist/tools/edit/diff-compute.js.map +1 -0
  152. package/dist/tools/edit/diff-render.d.ts +18 -0
  153. package/dist/tools/edit/diff-render.d.ts.map +1 -0
  154. package/dist/tools/edit/diff-render.js +128 -0
  155. package/dist/tools/edit/diff-render.js.map +1 -0
  156. package/dist/tools/edit/edit.d.ts +4 -0
  157. package/dist/tools/edit/edit.d.ts.map +1 -0
  158. package/dist/tools/edit/edit.js +440 -0
  159. package/dist/tools/edit/edit.js.map +1 -0
  160. package/dist/tools/edit/matcher.d.ts +24 -0
  161. package/dist/tools/edit/matcher.d.ts.map +1 -0
  162. package/dist/tools/edit/matcher.js +66 -0
  163. package/dist/tools/edit/matcher.js.map +1 -0
  164. package/dist/tools/edit/parser.d.ts +10 -0
  165. package/dist/tools/edit/parser.d.ts.map +1 -0
  166. package/dist/tools/edit/parser.js +120 -0
  167. package/dist/tools/edit/parser.js.map +1 -0
  168. package/dist/tools/edit/types.d.ts +16 -0
  169. package/dist/tools/edit/types.d.ts.map +1 -0
  170. package/dist/tools/edit/types.js +2 -0
  171. package/dist/tools/edit/types.js.map +1 -0
  172. package/dist/tools/edit/write_plan.d.ts +5 -0
  173. package/dist/tools/edit/write_plan.d.ts.map +1 -0
  174. package/dist/tools/edit/write_plan.js +98 -0
  175. package/dist/tools/edit/write_plan.js.map +1 -0
  176. package/dist/tools/edit.d.ts.map +1 -1
  177. package/dist/tools/edit.js +66 -1
  178. package/dist/tools/edit.js.map +1 -1
  179. package/dist/tools/execute/bash/constants.d.ts +24 -0
  180. package/dist/tools/execute/bash/constants.d.ts.map +1 -0
  181. package/dist/tools/execute/bash/constants.js +88 -0
  182. package/dist/tools/execute/bash/constants.js.map +1 -0
  183. package/dist/tools/execute/bash/errors.d.ts +39 -0
  184. package/dist/tools/execute/bash/errors.d.ts.map +1 -0
  185. package/dist/tools/execute/bash/errors.js +249 -0
  186. package/dist/tools/execute/bash/errors.js.map +1 -0
  187. package/dist/tools/execute/bash/execution.d.ts +18 -0
  188. package/dist/tools/execute/bash/execution.d.ts.map +1 -0
  189. package/dist/tools/execute/bash/execution.js +207 -0
  190. package/dist/tools/execute/bash/execution.js.map +1 -0
  191. package/dist/tools/execute/bash/index.d.ts +3 -0
  192. package/dist/tools/execute/bash/index.d.ts.map +1 -0
  193. package/dist/tools/execute/bash/index.js +117 -0
  194. package/dist/tools/execute/bash/index.js.map +1 -0
  195. package/dist/tools/execute/bash/platform.d.ts +6 -0
  196. package/dist/tools/execute/bash/platform.d.ts.map +1 -0
  197. package/dist/tools/execute/bash/platform.js +64 -0
  198. package/dist/tools/execute/bash/platform.js.map +1 -0
  199. package/dist/tools/execute/bash/security.d.ts +12 -0
  200. package/dist/tools/execute/bash/security.d.ts.map +1 -0
  201. package/dist/tools/execute/bash/security.js +26 -0
  202. package/dist/tools/execute/bash/security.js.map +1 -0
  203. package/dist/tools/execute/bash/validation.d.ts +16 -0
  204. package/dist/tools/execute/bash/validation.d.ts.map +1 -0
  205. package/dist/tools/execute/bash/validation.js +57 -0
  206. package/dist/tools/execute/bash/validation.js.map +1 -0
  207. package/dist/tools/execute/bash.d.ts +3 -0
  208. package/dist/tools/execute/bash.d.ts.map +1 -0
  209. package/dist/tools/execute/bash.js +728 -0
  210. package/dist/tools/execute/bash.js.map +1 -0
  211. package/dist/tools/execute/git.d.ts +3 -0
  212. package/dist/tools/execute/git.d.ts.map +1 -0
  213. package/dist/tools/execute/git.js +183 -0
  214. package/dist/tools/execute/git.js.map +1 -0
  215. package/dist/tools/execute/task_complete.d.ts +7 -0
  216. package/dist/tools/execute/task_complete.d.ts.map +1 -0
  217. package/dist/tools/execute/task_complete.js +38 -0
  218. package/dist/tools/execute/task_complete.js.map +1 -0
  219. package/dist/tools/fetch.d.ts.map +1 -1
  220. package/dist/tools/fetch.js +2 -0
  221. package/dist/tools/fetch.js.map +1 -1
  222. package/dist/tools/find.d.ts.map +1 -1
  223. package/dist/tools/find.js +2 -0
  224. package/dist/tools/find.js.map +1 -1
  225. package/dist/tools/git.d.ts.map +1 -1
  226. package/dist/tools/git.js +2 -0
  227. package/dist/tools/git.js.map +1 -1
  228. package/dist/tools/glob.d.ts.map +1 -1
  229. package/dist/tools/glob.js +2 -0
  230. package/dist/tools/glob.js.map +1 -1
  231. package/dist/tools/grep.d.ts.map +1 -1
  232. package/dist/tools/grep.js +2 -0
  233. package/dist/tools/grep.js.map +1 -1
  234. package/dist/tools/install/clawhub.d.ts +26 -0
  235. package/dist/tools/install/clawhub.d.ts.map +1 -0
  236. package/dist/tools/install/clawhub.js +182 -0
  237. package/dist/tools/install/clawhub.js.map +1 -0
  238. package/dist/tools/install/constants.d.ts +5 -0
  239. package/dist/tools/install/constants.d.ts.map +1 -0
  240. package/dist/tools/install/constants.js +5 -0
  241. package/dist/tools/install/constants.js.map +1 -0
  242. package/dist/tools/install/install_skill.d.ts +3 -0
  243. package/dist/tools/install/install_skill.d.ts.map +1 -0
  244. package/dist/tools/install/install_skill.js +132 -0
  245. package/dist/tools/install/install_skill.js.map +1 -0
  246. package/dist/tools/install/npm.d.ts +8 -0
  247. package/dist/tools/install/npm.d.ts.map +1 -0
  248. package/dist/tools/install/npm.js +52 -0
  249. package/dist/tools/install/npm.js.map +1 -0
  250. package/dist/tools/install/skill-content.d.ts +9 -0
  251. package/dist/tools/install/skill-content.d.ts.map +1 -0
  252. package/dist/tools/install/skill-content.js +89 -0
  253. package/dist/tools/install/skill-content.js.map +1 -0
  254. package/dist/tools/install_skill.d.ts.map +1 -1
  255. package/dist/tools/install_skill.js +2 -0
  256. package/dist/tools/install_skill.js.map +1 -1
  257. package/dist/tools/list_memory.d.ts +3 -0
  258. package/dist/tools/list_memory.d.ts.map +1 -0
  259. package/dist/tools/list_memory.js +55 -0
  260. package/dist/tools/list_memory.js.map +1 -0
  261. package/dist/tools/ls.d.ts.map +1 -1
  262. package/dist/tools/ls.js +2 -0
  263. package/dist/tools/ls.js.map +1 -1
  264. package/dist/tools/memory/delete_memory.d.ts +3 -0
  265. package/dist/tools/memory/delete_memory.d.ts.map +1 -0
  266. package/dist/tools/memory/delete_memory.js +46 -0
  267. package/dist/tools/memory/delete_memory.js.map +1 -0
  268. package/dist/tools/memory/list_memory.d.ts +3 -0
  269. package/dist/tools/memory/list_memory.d.ts.map +1 -0
  270. package/dist/tools/memory/list_memory.js +55 -0
  271. package/dist/tools/memory/list_memory.js.map +1 -0
  272. package/dist/tools/memory/save_memory.d.ts +3 -0
  273. package/dist/tools/memory/save_memory.d.ts.map +1 -0
  274. package/dist/tools/memory/save_memory.js +45 -0
  275. package/dist/tools/memory/save_memory.js.map +1 -0
  276. package/dist/tools/read.d.ts.map +1 -1
  277. package/dist/tools/read.js +2 -0
  278. package/dist/tools/read.js.map +1 -1
  279. package/dist/tools/registry.d.ts +7 -2
  280. package/dist/tools/registry.d.ts.map +1 -1
  281. package/dist/tools/registry.js +112 -17
  282. package/dist/tools/registry.js.map +1 -1
  283. package/dist/tools/save_memory.d.ts +3 -0
  284. package/dist/tools/save_memory.d.ts.map +1 -0
  285. package/dist/tools/save_memory.js +45 -0
  286. package/dist/tools/save_memory.js.map +1 -0
  287. package/dist/tools/search.d.ts.map +1 -1
  288. package/dist/tools/search.js +2 -0
  289. package/dist/tools/search.js.map +1 -1
  290. package/dist/tools/tree.d.ts +12 -0
  291. package/dist/tools/tree.d.ts.map +1 -0
  292. package/dist/tools/tree.js +87 -0
  293. package/dist/tools/tree.js.map +1 -0
  294. package/dist/tools/types.d.ts +12 -0
  295. package/dist/tools/types.d.ts.map +1 -1
  296. package/dist/tools/web/fetch.d.ts +3 -0
  297. package/dist/tools/web/fetch.d.ts.map +1 -0
  298. package/dist/tools/web/fetch.js +49 -0
  299. package/dist/tools/web/fetch.js.map +1 -0
  300. package/dist/tools/web/search.d.ts +3 -0
  301. package/dist/tools/web/search.d.ts.map +1 -0
  302. package/dist/tools/web/search.js +134 -0
  303. package/dist/tools/web/search.js.map +1 -0
  304. package/dist/tools/write_plan.d.ts.map +1 -1
  305. package/dist/tools/write_plan.js +2 -0
  306. package/dist/tools/write_plan.js.map +1 -1
  307. package/dist/tui/commands.d.ts +4 -0
  308. package/dist/tui/commands.d.ts.map +1 -0
  309. package/dist/tui/commands.js +118 -0
  310. package/dist/tui/commands.js.map +1 -0
  311. package/dist/tui/components/colors.d.ts +36 -0
  312. package/dist/tui/components/colors.d.ts.map +1 -0
  313. package/dist/tui/components/colors.js +48 -0
  314. package/dist/tui/components/colors.js.map +1 -0
  315. package/dist/tui/components/header-bar.d.ts +26 -0
  316. package/dist/tui/components/header-bar.d.ts.map +1 -0
  317. package/dist/tui/components/header-bar.js +78 -0
  318. package/dist/tui/components/header-bar.js.map +1 -0
  319. package/dist/tui/components/index.d.ts +9 -0
  320. package/dist/tui/components/index.d.ts.map +1 -0
  321. package/dist/tui/components/index.js +9 -0
  322. package/dist/tui/components/index.js.map +1 -0
  323. package/dist/tui/components/landing-screen.d.ts +12 -0
  324. package/dist/tui/components/landing-screen.d.ts.map +1 -0
  325. package/dist/tui/components/landing-screen.js +53 -0
  326. package/dist/tui/components/landing-screen.js.map +1 -0
  327. package/dist/tui/components/pixel-logo.d.ts +5 -0
  328. package/dist/tui/components/pixel-logo.d.ts.map +1 -0
  329. package/dist/tui/components/pixel-logo.js +27 -0
  330. package/dist/tui/components/pixel-logo.js.map +1 -0
  331. package/dist/tui/components/plan-utils.d.ts +11 -0
  332. package/dist/tui/components/plan-utils.d.ts.map +1 -0
  333. package/dist/tui/components/plan-utils.js +62 -0
  334. package/dist/tui/components/plan-utils.js.map +1 -0
  335. package/dist/tui/components/plans-list.d.ts +18 -0
  336. package/dist/tui/components/plans-list.d.ts.map +1 -0
  337. package/dist/tui/components/plans-list.js +46 -0
  338. package/dist/tui/components/plans-list.js.map +1 -0
  339. package/dist/tui/components/rich-footer.d.ts +29 -0
  340. package/dist/tui/components/rich-footer.d.ts.map +1 -0
  341. package/dist/tui/components/rich-footer.js +124 -0
  342. package/dist/tui/components/rich-footer.js.map +1 -0
  343. package/dist/tui/components/todo-panel.d.ts +14 -0
  344. package/dist/tui/components/todo-panel.d.ts.map +1 -0
  345. package/dist/tui/components/todo-panel.js +83 -0
  346. package/dist/tui/components/todo-panel.js.map +1 -0
  347. package/dist/tui/components.d.ts.map +1 -1
  348. package/dist/tui/components.js +14 -7
  349. package/dist/tui/components.js.map +1 -1
  350. package/dist/tui/index.d.ts +2 -1
  351. package/dist/tui/index.d.ts.map +1 -1
  352. package/dist/tui/index.js +99 -505
  353. package/dist/tui/index.js.map +1 -1
  354. package/dist/tui/overlays.d.ts +28 -0
  355. package/dist/tui/overlays.d.ts.map +1 -0
  356. package/dist/tui/overlays.js +154 -0
  357. package/dist/tui/overlays.js.map +1 -0
  358. package/dist/tui/themes.d.ts +5 -0
  359. package/dist/tui/themes.d.ts.map +1 -0
  360. package/dist/tui/themes.js +38 -0
  361. package/dist/tui/themes.js.map +1 -0
  362. package/dist/web/index.d.ts.map +1 -1
  363. package/dist/web/index.js +60 -122
  364. package/dist/web/index.js.map +1 -1
  365. package/dist/web/public/index.html +1 -1
  366. package/dist/web/public/messages.js +41 -25
  367. package/dist/web/public/state.js +72 -72
  368. package/dist/web/public/style.css +1126 -996
  369. package/dist/web/public/websocket.js +267 -267
  370. package/dist/web/session-bridge.d.ts.map +1 -1
  371. package/dist/web/session-bridge.js +82 -3
  372. package/dist/web/session-bridge.js.map +1 -1
  373. package/docs/ast-tools.md +117 -0
  374. package/package.json +60 -55
  375. package/scripts/check-line-count.mjs +53 -0
  376. package/scripts/copy-ast-wasm.mjs +32 -0
  377. package/src/agent/__tests__/session-restore.test.ts +284 -0
  378. package/src/agent/commands.ts +274 -0
  379. package/src/agent/compaction.ts +9 -2
  380. package/src/agent/index.ts +30 -25
  381. package/src/agent/memory.ts +60 -0
  382. package/src/agent/prompt-builder.ts +100 -26
  383. package/src/agent/providers/anthropic.ts +179 -179
  384. package/src/agent/providers/google.ts +210 -210
  385. package/src/agent/providers/ollama.ts +186 -186
  386. package/src/agent/providers/openai.ts +18 -3
  387. package/src/agent/session-chat.ts +480 -0
  388. package/src/agent/session-display.ts +195 -0
  389. package/src/agent/session-persistence.ts +146 -0
  390. package/src/agent/session-utils.ts +54 -0
  391. package/src/agent/session.ts +261 -718
  392. package/src/cli/index.ts +73 -4
  393. package/src/config/index.ts +342 -342
  394. package/src/index.ts +30 -3
  395. package/src/tools/__tests__/bash.test.ts +187 -1
  396. package/src/tools/__tests__/edit.test.ts +275 -11
  397. package/src/tools/__tests__/fetch.test.ts +1 -1
  398. package/src/tools/__tests__/glob.test.ts +1 -1
  399. package/src/tools/__tests__/grep.test.ts +1 -1
  400. package/src/tools/__tests__/ls.test.ts +1 -1
  401. package/src/tools/__tests__/read.test.ts +1 -1
  402. package/src/tools/__tests__/registry.test.ts +332 -0
  403. package/src/tools/__tests__/write_plan.test.ts +1 -1
  404. package/src/tools/codebase/ast/__tests__/integration.test.ts +452 -0
  405. package/src/tools/codebase/ast/__tests__/tree-sitter.test.ts +466 -0
  406. package/src/tools/codebase/ast/adapter.ts +44 -0
  407. package/src/tools/codebase/ast/tools.ts +322 -0
  408. package/src/tools/codebase/ast/tree-sitter-adapter.ts +468 -0
  409. package/src/tools/codebase/ast/tree-sitter-converters.ts +480 -0
  410. package/src/tools/codebase/ast/types.ts +102 -0
  411. package/src/tools/codebase/ast/wasm/tree-sitter-python.wasm +0 -0
  412. package/src/tools/codebase/ast/wasm/tree-sitter-tsx.wasm +0 -0
  413. package/src/tools/codebase/ast/wasm/tree-sitter-typescript.wasm +0 -0
  414. package/src/tools/codebase/ast/wasm/tree-sitter.wasm +0 -0
  415. package/src/tools/codebase/ast/wasm/web-tree-sitter.wasm +0 -0
  416. package/src/tools/{find.ts → codebase/find.ts} +4 -2
  417. package/src/tools/{glob.ts → codebase/glob.ts} +4 -2
  418. package/src/tools/{grep.ts → codebase/grep.ts} +4 -2
  419. package/src/tools/{ls.ts → codebase/ls.ts} +4 -2
  420. package/src/tools/{read.ts → codebase/read.ts} +5 -3
  421. package/src/tools/edit/diff-compute.ts +21 -0
  422. package/src/tools/edit/diff-render.ts +145 -0
  423. package/src/tools/edit/edit.ts +468 -0
  424. package/src/tools/edit/matcher.ts +70 -0
  425. package/src/tools/edit/parser.ts +131 -0
  426. package/src/tools/edit/types.ts +19 -0
  427. package/src/tools/{write_plan.ts → edit/write_plan.ts} +4 -2
  428. package/src/tools/execute/bash/constants.ts +93 -0
  429. package/src/tools/execute/bash/errors.ts +304 -0
  430. package/src/tools/execute/bash/execution.ts +211 -0
  431. package/src/tools/execute/bash/index.ts +131 -0
  432. package/src/tools/execute/bash/platform.ts +65 -0
  433. package/src/tools/execute/bash/security.ts +28 -0
  434. package/src/tools/execute/bash/validation.ts +78 -0
  435. package/src/tools/execute/git.ts +209 -0
  436. package/src/tools/execute/task_complete.ts +40 -0
  437. package/src/tools/install/clawhub.ts +222 -0
  438. package/src/tools/install/constants.ts +4 -0
  439. package/src/tools/install/install_skill.ts +150 -0
  440. package/src/tools/install/npm.ts +60 -0
  441. package/src/tools/install/skill-content.ts +108 -0
  442. package/src/tools/memory/delete_memory.ts +46 -0
  443. package/src/tools/memory/list_memory.ts +53 -0
  444. package/src/tools/memory/save_memory.ts +45 -0
  445. package/src/tools/registry.ts +119 -19
  446. package/src/tools/tree.ts +103 -0
  447. package/src/tools/types.ts +13 -0
  448. package/src/tools/{fetch.ts → web/fetch.ts} +4 -2
  449. package/src/tools/{search.ts → web/search.ts} +4 -2
  450. package/src/tui/commands.ts +135 -0
  451. package/src/tui/components/colors.ts +52 -0
  452. package/src/tui/components/header-bar.ts +88 -0
  453. package/src/tui/components/index.ts +8 -0
  454. package/src/tui/components/landing-screen.ts +67 -0
  455. package/src/tui/components/pixel-logo.ts +33 -0
  456. package/src/tui/components/plan-utils.ts +69 -0
  457. package/src/tui/components/plans-list.ts +55 -0
  458. package/src/tui/components/rich-footer.ts +146 -0
  459. package/src/tui/components/todo-panel.ts +95 -0
  460. package/src/tui/index.ts +335 -786
  461. package/src/tui/overlays.ts +203 -0
  462. package/src/tui/themes.ts +41 -0
  463. package/src/web/index.ts +64 -127
  464. package/src/web/public/index.html +1 -1
  465. package/src/web/public/messages.js +41 -25
  466. package/src/web/public/state.js +72 -72
  467. package/src/web/public/style.css +1126 -996
  468. package/src/web/public/websocket.js +267 -267
  469. package/src/web/session-bridge.ts +272 -193
  470. package/AGENT.md +0 -99
  471. package/src/tools/bash.ts +0 -125
  472. package/src/tools/edit.ts +0 -747
  473. package/src/tools/git.ts +0 -76
  474. package/src/tools/install_skill.ts +0 -539
  475. package/src/tui/components.ts +0 -635
@@ -0,0 +1,480 @@
1
+ import type * as WTS from 'web-tree-sitter'
2
+
3
+ import type { Class, ClassMember, FuncDecl, Import, Statement, Variable } from './types.js'
4
+
5
+ /** Export-related node types that may wrap function/class/variable declarations */
6
+ const EXPORT_NODE_TYPES = new Set([
7
+ 'export_statement',
8
+ 'export_named_statement',
9
+ 'export_default_statement',
10
+ 'export_default',
11
+ ])
12
+
13
+ export function walkStatements(node: WTS.Node, lang: string): Statement[] {
14
+ const statements: Statement[] = []
15
+ for (const child of node.children) {
16
+ const stmt = convertNode(child, lang)
17
+ if (stmt) {
18
+ statements.push(stmt)
19
+ }
20
+ // Extract inline functions from variable declarations (e.g. `const fn = () => {}`)
21
+ if (lang !== 'python') {
22
+ for (const decl of child.children) {
23
+ if (decl.type === 'variable_declarator') {
24
+ for (const valChild of decl.children) {
25
+ if (valChild.type === 'arrow_function' || valChild.type === 'function') {
26
+ statements.push(convertFunction(valChild))
27
+ }
28
+ }
29
+ }
30
+ }
31
+ }
32
+ // Recursively extract exports' inner declarations (function/class/variable)
33
+ // so `export function foo()` is captured both as Export and as FuncDecl.
34
+ if (EXPORT_NODE_TYPES.has(child.type)) {
35
+ const subStatements = walkStatements(child, lang)
36
+ for (const sub of subStatements) {
37
+ if (
38
+ !statements.some(
39
+ s => s.type === sub.type && 'name' in s && 'name' in sub && s.name === sub.name,
40
+ )
41
+ ) {
42
+ statements.push(sub)
43
+ }
44
+ }
45
+ // Handle `export { foo, bar }` / `export type { Foo }` named export lists
46
+ for (const clause of child.namedChildren) {
47
+ if (clause.type === 'export_clause' || clause.type === 'named_exports') {
48
+ for (const spec of clause.namedChildren) {
49
+ if (spec.type === 'export_specifier') {
50
+ const exportedName =
51
+ spec.childForFieldName('alias')?.text || // export { x as y } → y
52
+ spec.childForFieldName('name')?.text || // export { x } → x
53
+ spec.text
54
+ if (
55
+ !statements.some(s => s.type === 'Export' && 'name' in s && s.name === exportedName)
56
+ ) {
57
+ statements.push({ type: 'Export' as const, name: exportedName })
58
+ }
59
+ }
60
+ }
61
+ }
62
+ }
63
+ }
64
+ }
65
+ return statements
66
+ }
67
+
68
+ function convertNode(node: WTS.Node, lang: string): Statement | null {
69
+ const type = node.type
70
+
71
+ if (lang === 'typescript' || lang === 'javascript') {
72
+ if (type === 'function_declaration') return convertFunction(node)
73
+ if (type === 'arrow_function') return convertFunction(node)
74
+ if (type === 'class_declaration') return convertClass(node)
75
+ if (type === 'lexical_declaration') return convertLexicalDeclaration(node)
76
+ if (type === 'variable_declaration') return convertVariableDeclaration(node)
77
+ if (type === 'var_declaration') return convertVariableDeclaration(node)
78
+ if (type === 'import_statement') return convertImport(node)
79
+ if (type === 'import_declaration') return convertImport(node)
80
+ if (type === 'export_statement' || type === 'export_named_statement') return convertExport(node)
81
+ if (type === 'export_default_statement' || type === 'export_default')
82
+ return convertExportDefault(node)
83
+ if (type === 'generator_function_declaration') return convertFunction(node)
84
+ if (type === 'generator_function') return convertFunction(node)
85
+ }
86
+
87
+ if (lang === 'python') {
88
+ if (type === 'function_definition') return convertPythonFunction(node)
89
+ if (type === 'class_definition') return convertPythonClass(node)
90
+ if (type === 'assignment') return convertPythonAssignment(node)
91
+ if (type === 'import_statement') return convertPythonImport(node)
92
+ if (type === 'import_from_statement') return convertPythonImportFrom(node)
93
+ if (type === 'decorated_definition') return convertDecoratedDefinition(node)
94
+ }
95
+
96
+ return null
97
+ }
98
+
99
+ function convertFunction(node: WTS.Node): FuncDecl {
100
+ const nameNode = node.childForFieldName('name')
101
+ const paramsNode = node.childForFieldName('parameters')
102
+ const returnTypeNode = node.childForFieldName('return_type')
103
+ const asyncNode = node.children.find(c => c.type === 'async')
104
+ const isGenerator =
105
+ node.type === 'generator_function_declaration' ||
106
+ !!node.children.find(c => c.type === '*' || c.type === 'yield')
107
+
108
+ const parameters: { name: string }[] = []
109
+ if (paramsNode) {
110
+ for (const param of paramsNode.children) {
111
+ if (
112
+ param.type === 'identifier' ||
113
+ param.type === 'required_parameter' ||
114
+ param.type === 'optional_parameter'
115
+ ) {
116
+ const name =
117
+ param.childForFieldName('pattern')?.text ||
118
+ param.childForFieldName('name')?.text ||
119
+ param.text
120
+ parameters.push({ name })
121
+ } else if (param.type === 'assignment_pattern') {
122
+ const left = param.childForFieldName('left')
123
+ if (left) parameters.push({ name: left.text })
124
+ }
125
+ }
126
+ }
127
+
128
+ return {
129
+ type: 'Function',
130
+ name: nameNode?.text || null,
131
+ parameters,
132
+ returnType: returnTypeNode?.text || undefined,
133
+ isAsync: !!asyncNode,
134
+ isGenerator,
135
+ startLine: node.startPosition.row + 1,
136
+ endLine: node.endPosition.row + 1,
137
+ }
138
+ }
139
+
140
+ function convertMethod(node: WTS.Node): ClassMember {
141
+ const nameNode = node.childForFieldName('name')
142
+ const staticNode = node.namedChildren.find(c => c.type === 'static')
143
+ const modifierNode = node.namedChildren.find(c => c.type === 'accessibility_modifier')
144
+ const name = nameNode?.text || ''
145
+ const isConstructor =
146
+ name === 'constructor' || node.type === 'constructor_declaration' || node.type === 'constructor'
147
+
148
+ // Detect getter/setter by looking for `get`/`set` keyword children,
149
+ // not by fragile `includes()` on the node type string.
150
+ // `get`/`set` are unnamed keyword children, not named children.
151
+ const isGetter = node.children.some(c => c.type === 'get')
152
+ const isSetter = node.children.some(c => c.type === 'set')
153
+
154
+ return {
155
+ type: 'Method',
156
+ name,
157
+ kind: isConstructor ? 'constructor' : isGetter ? 'getter' : isSetter ? 'setter' : 'method',
158
+ visibility:
159
+ (modifierNode?.namedChildren[0]?.text as 'public' | 'private' | 'protected') || 'public',
160
+ isStatic: !!staticNode,
161
+ startLine: node.startPosition.row + 1,
162
+ endLine: node.endPosition.row + 1,
163
+ }
164
+ }
165
+
166
+ function convertClass(node: WTS.Node): Class {
167
+ const nameNode = node.childForFieldName('name')
168
+ const superNode = node.childForFieldName('superclass') || node.childForFieldName('super_class')
169
+ const bodyNode = node.childForFieldName('body')
170
+
171
+ const members: ClassMember[] = []
172
+ if (bodyNode) {
173
+ for (const child of bodyNode.namedChildren) {
174
+ if (child.type === 'method_definition' || child.type === 'method_signature') {
175
+ members.push(convertMethod(child))
176
+ } else if (
177
+ child.type === 'public_field_definition' ||
178
+ child.type === 'property_definition' ||
179
+ child.type === 'field_definition'
180
+ ) {
181
+ const mName = child.childForFieldName('name')
182
+ const staticNode = child.namedChildren.find(c => c.type === 'static')
183
+ members.push({
184
+ type: 'Property',
185
+ name: mName?.text || child.text,
186
+ kind: 'property',
187
+ visibility: 'public',
188
+ isStatic: !!staticNode,
189
+ startLine: child.startPosition.row + 1,
190
+ endLine: child.endPosition.row + 1,
191
+ })
192
+ }
193
+ }
194
+ }
195
+
196
+ return {
197
+ type: 'Class',
198
+ name: nameNode?.text || '',
199
+ superClass: superNode?.text || undefined,
200
+ members,
201
+ startLine: node.startPosition.row + 1,
202
+ endLine: node.endPosition.row + 1,
203
+ }
204
+ }
205
+
206
+ function convertLexicalDeclaration(node: WTS.Node): Variable | null {
207
+ const kind =
208
+ node.children.find(c => c.type === 'const' || c.type === 'let' || c.type === 'var')?.text ||
209
+ 'const'
210
+ for (const declarator of node.children) {
211
+ if (declarator.type === 'variable_declarator') {
212
+ const nameNode =
213
+ declarator.childForFieldName('name') ||
214
+ declarator.children.find(c => c.type === 'identifier')
215
+ if (nameNode) {
216
+ return {
217
+ type: 'Variable',
218
+ name: nameNode.text,
219
+ kind: kind as 'const' | 'let' | 'var',
220
+ startLine: node.startPosition.row + 1,
221
+ endLine: node.endPosition.row + 1,
222
+ }
223
+ }
224
+ }
225
+ }
226
+ return null
227
+ }
228
+
229
+ function convertVariableDeclaration(node: WTS.Node): Variable | null {
230
+ for (const decl of node.children) {
231
+ if (decl.type === 'variable_declarator') {
232
+ const nameNode =
233
+ decl.childForFieldName('name') || decl.children.find(c => c.type === 'identifier')
234
+ if (nameNode) {
235
+ return {
236
+ type: 'Variable',
237
+ name: nameNode.text,
238
+ kind: 'var',
239
+ startLine: node.startPosition.row + 1,
240
+ endLine: node.endPosition.row + 1,
241
+ }
242
+ }
243
+ }
244
+ }
245
+ return null
246
+ }
247
+
248
+ function convertImport(node: WTS.Node): Import {
249
+ const sourceNode = node.children.find(c => c.type === 'string' || c.type === 'template_string')
250
+ const specifiers: { type: 'ImportSpecifier'; localName: string; importedName: string }[] = []
251
+
252
+ function extractSpecifiers(container: WTS.Node): void {
253
+ for (const c of container.children) {
254
+ if (c.type === 'import_specifier') {
255
+ const name = c.childForFieldName('name')
256
+ const alias = c.childForFieldName('alias')
257
+ const imported = name?.text || c.text
258
+ const local = alias?.text || imported
259
+ specifiers.push({ type: 'ImportSpecifier', localName: local, importedName: imported })
260
+ } else if (c.type === 'identifier') {
261
+ specifiers.push({ type: 'ImportSpecifier', localName: c.text, importedName: c.text })
262
+ } else if (c.type === 'namespace_import') {
263
+ const ns = c.namedChildren.find(n => n.type === 'identifier')
264
+ if (ns) specifiers.push({ type: 'ImportSpecifier', localName: ns.text, importedName: '*' })
265
+ } else if (c.type === 'named_imports' || c.type === 'import_clause') {
266
+ extractSpecifiers(c)
267
+ }
268
+ }
269
+ }
270
+
271
+ extractSpecifiers(node)
272
+
273
+ // Detect `import type { ... }` syntax
274
+ const isTypeOnly =
275
+ node.children.some(c => c.type === 'type') ||
276
+ node.namedChildren.some(
277
+ c => c.type === 'import_clause' && c.namedChildren.some(cc => cc.type === 'type'),
278
+ )
279
+
280
+ return {
281
+ type: 'Import',
282
+ source: sourceNode?.text || node.text,
283
+ specifiers,
284
+ isTypeOnly: isTypeOnly || undefined,
285
+ }
286
+ }
287
+
288
+ function convertExport(node: WTS.Node): { type: 'Export'; name: string } | null {
289
+ const sourceNode = node.namedChildren.find(
290
+ c => c.type === 'string' || c.type === 'template_string',
291
+ )
292
+ if (sourceNode) {
293
+ return { type: 'Export', name: sourceNode.text }
294
+ }
295
+ for (const child of node.namedChildren) {
296
+ if (child.type === 'function_declaration' || child.type === 'class_declaration') {
297
+ const nameNode = child.childForFieldName('name')
298
+ return { type: 'Export', name: nameNode?.text || '(unnamed)' }
299
+ }
300
+ if (child.type === 'lexical_declaration' || child.type === 'variable_declaration') {
301
+ const decl = child.namedChildren.find(c => c.type === 'variable_declarator')
302
+ const nameNode = decl?.childForFieldName('name')
303
+ return { type: 'Export', name: nameNode?.text || '(anonymous)' }
304
+ }
305
+ if (child.type === 'assignment') {
306
+ const left = child.childForFieldName('left')
307
+ return { type: 'Export', name: left?.text || '(assignment)' }
308
+ }
309
+ // Handle `export interface Foo { ... }` and `export type Foo = ...`
310
+ if (child.type === 'interface_declaration' || child.type === 'type_alias_declaration') {
311
+ const nameNode = child.childForFieldName('name')
312
+ return { type: 'Export', name: nameNode?.text || '(anonymous)' }
313
+ }
314
+ }
315
+ return { type: 'Export', name: '(anonymous)' }
316
+ }
317
+
318
+ function convertExportDefault(node: WTS.Node): { type: 'Export'; name: string } | null {
319
+ const valueNode = node.childForFieldName('value')
320
+ if (valueNode) {
321
+ const nameNode = valueNode.childForFieldName('name')
322
+ return { type: 'Export', name: nameNode?.text || 'default' }
323
+ }
324
+ return { type: 'Export', name: 'default' }
325
+ }
326
+
327
+ function convertPythonFunction(node: WTS.Node): FuncDecl {
328
+ const nameNode = node.childForFieldName('name')
329
+ const paramsNode = node.childForFieldName('parameters')
330
+ const returnTypeNode = node.childForFieldName('return_type')
331
+ const asyncNode = node.children.find(c => c.type === 'async')
332
+
333
+ const parameters: { name: string }[] = []
334
+ if (paramsNode) {
335
+ for (const param of paramsNode.children) {
336
+ if (param.type === 'identifier') {
337
+ parameters.push({ name: param.text })
338
+ } else if (param.type === 'typed_parameter' || param.type === 'default_parameter') {
339
+ const name = param.childForFieldName('name')?.text || param.text
340
+ parameters.push({ name })
341
+ } else if (param.type === 'list_splat_pattern') {
342
+ const name = param.childForFieldName('name')?.text || param.text
343
+ parameters.push({ name: `*${name}` })
344
+ } else if (param.type === 'keyword_splat_pattern') {
345
+ const name = param.childForFieldName('name')?.text || param.text
346
+ parameters.push({ name: `**${name}` })
347
+ }
348
+ }
349
+ }
350
+
351
+ return {
352
+ type: 'Function',
353
+ name: nameNode?.text || null,
354
+ parameters,
355
+ returnType: returnTypeNode?.text || undefined,
356
+ isAsync: !!asyncNode,
357
+ isGenerator: false,
358
+ startLine: node.startPosition.row + 1,
359
+ endLine: node.endPosition.row + 1,
360
+ }
361
+ }
362
+
363
+ function convertPythonClass(node: WTS.Node): Class {
364
+ const nameNode = node.childForFieldName('name')
365
+ const superNode = node.childForFieldName('superclasses')
366
+ const bodyNode = node.childForFieldName('body')
367
+
368
+ const members: ClassMember[] = []
369
+ if (bodyNode) {
370
+ for (const child of bodyNode.children) {
371
+ if (child.type === 'function_definition' || child.type === 'decorated_definition') {
372
+ const fnNode =
373
+ child.type === 'decorated_definition'
374
+ ? child.children.find(c => c.type === 'function_definition')
375
+ : child
376
+ const mName = fnNode?.childForFieldName('name')?.text || child.text
377
+ const isCtor = mName === '__init__' || mName === '__new__'
378
+ members.push({
379
+ type: 'Method',
380
+ name: mName,
381
+ kind: isCtor ? 'constructor' : 'method',
382
+ visibility: mName.startsWith('__') ? 'private' : 'public',
383
+ isStatic: false,
384
+ startLine: child.startPosition.row + 1,
385
+ endLine: child.endPosition.row + 1,
386
+ })
387
+ }
388
+ }
389
+ }
390
+
391
+ return {
392
+ type: 'Class',
393
+ name: nameNode?.text || '',
394
+ superClass: superNode?.text || undefined,
395
+ members,
396
+ startLine: node.startPosition.row + 1,
397
+ endLine: node.endPosition.row + 1,
398
+ }
399
+ }
400
+
401
+ function convertPythonAssignment(node: WTS.Node): Variable | null {
402
+ const leftNode = node.childForFieldName('left')
403
+ if (leftNode && leftNode.type === 'identifier') {
404
+ return {
405
+ type: 'Variable',
406
+ name: leftNode.text,
407
+ kind: 'let',
408
+ startLine: node.startPosition.row + 1,
409
+ endLine: node.endPosition.row + 1,
410
+ }
411
+ }
412
+ if (leftNode && leftNode.type === 'pattern_list') {
413
+ const first = leftNode.children.find(c => c.type === 'identifier')
414
+ if (first) {
415
+ return {
416
+ type: 'Variable',
417
+ name: first.text,
418
+ kind: 'let',
419
+ startLine: node.startPosition.row + 1,
420
+ endLine: node.endPosition.row + 1,
421
+ }
422
+ }
423
+ }
424
+ return null
425
+ }
426
+
427
+ function convertPythonImport(node: WTS.Node): Import {
428
+ const specifiers: Import['specifiers'] = []
429
+ const nameNode = node.childForFieldName('name')
430
+ if (nameNode) {
431
+ for (const child of nameNode.children) {
432
+ if (child.type === 'aliased_import') {
433
+ const original = child.childForFieldName('name')?.text || child.text
434
+ const alias = child.childForFieldName('alias')?.text || original
435
+ specifiers.push({ type: 'ImportSpecifier', localName: alias, importedName: original })
436
+ } else if (child.type === 'identifier') {
437
+ specifiers.push({
438
+ type: 'ImportSpecifier',
439
+ localName: child.text,
440
+ importedName: child.text,
441
+ })
442
+ }
443
+ }
444
+ }
445
+ return { type: 'Import', source: '', specifiers }
446
+ }
447
+
448
+ function convertPythonImportFrom(node: WTS.Node): Import {
449
+ const sourceNode = node.childForFieldName('module_name')
450
+ const nameNode = node.childForFieldName('name')
451
+ const names: { type: 'ImportSpecifier'; localName: string; importedName: string }[] = []
452
+
453
+ if (nameNode) {
454
+ for (const child of nameNode.children) {
455
+ if (child.type === 'aliased_import') {
456
+ const original = child.childForFieldName('name')?.text || child.text
457
+ const alias = child.childForFieldName('alias')?.text || original
458
+ names.push({ type: 'ImportSpecifier', localName: alias, importedName: original })
459
+ } else if (child.type === 'identifier') {
460
+ names.push({ type: 'ImportSpecifier', localName: child.text, importedName: child.text })
461
+ } else if (child.type === 'wildcard_import') {
462
+ names.push({ type: 'ImportSpecifier', localName: '*', importedName: '*' })
463
+ }
464
+ }
465
+ }
466
+
467
+ return {
468
+ type: 'Import',
469
+ source: sourceNode?.text || '',
470
+ specifiers: names,
471
+ }
472
+ }
473
+
474
+ function convertDecoratedDefinition(node: WTS.Node): Statement | null {
475
+ const inner = node.children.find(
476
+ c => c.type === 'function_definition' || c.type === 'class_definition',
477
+ )
478
+ if (inner) return convertNode(inner, 'python')
479
+ return null
480
+ }
@@ -0,0 +1,102 @@
1
+ export interface Module {
2
+ type: 'Module'
3
+ filePath: string
4
+ language: 'typescript' | 'javascript' | 'python'
5
+ imports: Import[]
6
+ body: Statement[]
7
+ exports: string[]
8
+ }
9
+
10
+ export interface Import {
11
+ type: 'Import'
12
+ source: string
13
+ specifiers: ImportSpecifier[]
14
+ isTypeOnly?: boolean
15
+ }
16
+
17
+ export interface ImportSpecifier {
18
+ type: 'ImportSpecifier'
19
+ localName: string
20
+ importedName: string
21
+ }
22
+
23
+ export interface FuncDecl {
24
+ type: 'Function'
25
+ name: string | null
26
+ parameters: Parameter[]
27
+ returnType?: string
28
+ isAsync: boolean
29
+ isGenerator: boolean
30
+ startLine: number
31
+ endLine: number
32
+ }
33
+
34
+ export interface Parameter {
35
+ name: string
36
+ }
37
+
38
+ export interface Class {
39
+ type: 'Class'
40
+ name: string
41
+ superClass?: string
42
+ members: ClassMember[]
43
+ startLine: number
44
+ endLine: number
45
+ }
46
+
47
+ export interface Variable {
48
+ type: 'Variable'
49
+ name: string
50
+ kind: 'const' | 'let' | 'var'
51
+ startLine: number
52
+ endLine: number
53
+ }
54
+
55
+ export interface ClassMember {
56
+ type: 'Property' | 'Method'
57
+ name: string
58
+ kind: 'constructor' | 'method' | 'getter' | 'setter' | 'property'
59
+ visibility: 'public' | 'private' | 'protected'
60
+ isStatic: boolean
61
+ startLine: number
62
+ endLine: number
63
+ }
64
+
65
+ export interface Reference {
66
+ type: 'Reference'
67
+ name: string
68
+ line: number
69
+ column: number
70
+ context: string
71
+ }
72
+
73
+ export interface StructureOverview {
74
+ filePath: string
75
+ language: string
76
+ imports: { source: string; names: string[] }[]
77
+ exports: string[]
78
+ functions: { name: string | null; line: number }[]
79
+ classes: { name: string; line: number; methods: string[] }[]
80
+ variables: { name: string; line: number }[]
81
+ }
82
+
83
+ export interface AstEdit {
84
+ type: 'insert' | 'replace' | 'delete'
85
+ startOffset: number
86
+ endOffset?: number
87
+ text?: string
88
+ }
89
+
90
+ export interface TextEditResult {
91
+ success: boolean
92
+ source: string
93
+ editsApplied: number
94
+ error?: string
95
+ }
96
+
97
+ export type Statement = FuncDecl | Class | Variable | Import | Export
98
+
99
+ export interface Export {
100
+ type: 'Export'
101
+ name: string
102
+ }
@@ -1,9 +1,11 @@
1
- import { fmtErr } from './errors.js'
2
- import type { Tool, ToolDefinition } from './types.js'
1
+ import { fmtErr } from '../errors.js'
2
+ import type { Tool, ToolDefinition } from '../types.js'
3
3
 
4
4
  export const createFindTool = (cwd: string): Tool => {
5
5
  const definition: ToolDefinition = {
6
6
  name: 'find',
7
+ category: 'Codebase',
8
+ group: 'Search/By Pattern',
7
9
  description: 'Find files by name pattern. Uses glob internally. Returns matching file paths.',
8
10
  parameters: {
9
11
  pattern: {
@@ -1,10 +1,12 @@
1
1
  import { glob } from 'node:fs/promises'
2
- import { fmtErr } from './errors.js'
3
- import type { Tool, ToolResult } from './types.js'
2
+ import { fmtErr } from '../errors.js'
3
+ import type { Tool, ToolResult } from '../types.js'
4
4
 
5
5
  export const globTool: Tool = {
6
6
  definition: {
7
7
  name: 'glob',
8
+ category: 'Codebase',
9
+ group: 'Search/By Pattern',
8
10
  description: 'Find files by glob pattern (e.g. "src/**/*.ts"). Returns matching file paths.',
9
11
  parameters: {
10
12
  pattern: { type: 'string', description: 'Glob pattern to search for', required: true },
@@ -1,8 +1,8 @@
1
1
  import { execFileSync } from 'node:child_process'
2
2
  import * as fs from 'node:fs/promises'
3
3
  import * as path from 'node:path'
4
- import { fmtErr } from './errors.js'
5
- import type { Tool, ToolResult } from './types.js'
4
+ import { fmtErr } from '../errors.js'
5
+ import type { Tool, ToolResult } from '../types.js'
6
6
 
7
7
  let _hasRg: boolean | undefined
8
8
 
@@ -120,6 +120,8 @@ export function createGrepTool(cwd: string): Tool {
120
120
  return {
121
121
  definition: {
122
122
  name: 'grep',
123
+ category: 'Codebase',
124
+ group: 'Search/By Content',
123
125
  description: 'Search file contents using a regular expression. Supports full regex syntax.',
124
126
  parameters: {
125
127
  pattern: { type: 'string', description: 'Regex pattern to search for', required: true },
@@ -1,12 +1,14 @@
1
1
  import * as fs from 'node:fs'
2
2
  import * as path from 'node:path'
3
- import { fmtErr } from './errors.js'
4
- import type { Tool, ToolResult } from './types.js'
3
+ import { fmtErr } from '../errors.js'
4
+ import type { Tool, ToolResult } from '../types.js'
5
5
 
6
6
  export function createLsTool(cwd: string): Tool {
7
7
  return {
8
8
  definition: {
9
9
  name: 'ls',
10
+ category: 'Codebase',
11
+ group: 'List',
10
12
  description: 'List files and directories at a given path.',
11
13
  parameters: {
12
14
  path: { type: 'string', description: 'Directory path to list (default: cwd)' },
@@ -1,8 +1,8 @@
1
1
  import * as fs from 'node:fs/promises'
2
2
  import * as path from 'node:path'
3
- import type { FileReadTracker } from '../diff/apply.js'
4
- import { fmtErr } from './errors.js'
5
- import type { Tool, ToolResult } from './types.js'
3
+ import type { FileReadTracker } from '../../diff/apply.js'
4
+ import { fmtErr } from '../errors.js'
5
+ import type { Tool, ToolResult } from '../types.js'
6
6
 
7
7
  // ── Configuration ─────────────────────────────────────────────────────────
8
8
  const MAX_FILE_SIZE = 1_000_000 // 1MB
@@ -27,6 +27,8 @@ export function createReadTool(applier: FileReadTracker, cwd: string): Tool {
27
27
  return {
28
28
  definition: {
29
29
  name: 'read',
30
+ category: 'Codebase',
31
+ group: 'Read',
30
32
  description:
31
33
  'Read the contents of one or more files. Always read a file before editing it. Each line is prefixed with "<lineNumber>: " for accurate line references; the prefix is a display aid only — do NOT include it in batch_edit patch content. Supports pagination via startLine and maxLines for large files.',
32
34
  parameters: {