@cdoing/core 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (378) hide show
  1. package/dist/agents/coordinator.d.ts +114 -0
  2. package/dist/agents/coordinator.d.ts.map +1 -0
  3. package/dist/agents/coordinator.js +158 -0
  4. package/dist/agents/coordinator.js.map +1 -0
  5. package/dist/context-providers/clipboard.d.ts +13 -0
  6. package/dist/context-providers/clipboard.d.ts.map +1 -0
  7. package/dist/context-providers/clipboard.js +53 -0
  8. package/dist/context-providers/clipboard.js.map +1 -0
  9. package/dist/context-providers/codebase.d.ts +46 -0
  10. package/dist/context-providers/codebase.d.ts.map +1 -0
  11. package/dist/context-providers/codebase.js +273 -0
  12. package/dist/context-providers/codebase.js.map +1 -0
  13. package/dist/context-providers/diff.d.ts +18 -0
  14. package/dist/context-providers/diff.d.ts.map +1 -0
  15. package/dist/context-providers/diff.js +63 -0
  16. package/dist/context-providers/diff.js.map +1 -0
  17. package/dist/context-providers/docs.d.ts +21 -0
  18. package/dist/context-providers/docs.d.ts.map +1 -0
  19. package/dist/context-providers/docs.js +180 -0
  20. package/dist/context-providers/docs.js.map +1 -0
  21. package/dist/context-providers/file-include.d.ts +13 -0
  22. package/dist/context-providers/file-include.d.ts.map +1 -0
  23. package/dist/context-providers/file-include.js +82 -0
  24. package/dist/context-providers/file-include.js.map +1 -0
  25. package/dist/context-providers/folder.d.ts +19 -0
  26. package/dist/context-providers/folder.d.ts.map +1 -0
  27. package/dist/context-providers/folder.js +130 -0
  28. package/dist/context-providers/folder.js.map +1 -0
  29. package/dist/context-providers/git.d.ts +19 -0
  30. package/dist/context-providers/git.d.ts.map +1 -0
  31. package/dist/context-providers/git.js +74 -0
  32. package/dist/context-providers/git.js.map +1 -0
  33. package/dist/context-providers/index.d.ts +26 -0
  34. package/dist/context-providers/index.d.ts.map +1 -0
  35. package/dist/context-providers/index.js +37 -0
  36. package/dist/context-providers/index.js.map +1 -0
  37. package/dist/context-providers/open-files.d.ts +25 -0
  38. package/dist/context-providers/open-files.d.ts.map +1 -0
  39. package/dist/context-providers/open-files.js +134 -0
  40. package/dist/context-providers/open-files.js.map +1 -0
  41. package/dist/context-providers/problems.d.ts +24 -0
  42. package/dist/context-providers/problems.d.ts.map +1 -0
  43. package/dist/context-providers/problems.js +97 -0
  44. package/dist/context-providers/problems.js.map +1 -0
  45. package/dist/context-providers/registry.d.ts +61 -0
  46. package/dist/context-providers/registry.d.ts.map +1 -0
  47. package/dist/context-providers/registry.js +92 -0
  48. package/dist/context-providers/registry.js.map +1 -0
  49. package/dist/context-providers/terminal.d.ts +25 -0
  50. package/dist/context-providers/terminal.d.ts.map +1 -0
  51. package/dist/context-providers/terminal.js +55 -0
  52. package/dist/context-providers/terminal.js.map +1 -0
  53. package/dist/context-providers/tree.d.ts +29 -0
  54. package/dist/context-providers/tree.d.ts.map +1 -0
  55. package/dist/context-providers/tree.js +172 -0
  56. package/dist/context-providers/tree.js.map +1 -0
  57. package/dist/context-providers/types.d.ts +72 -0
  58. package/dist/context-providers/types.d.ts.map +1 -0
  59. package/dist/context-providers/types.js +10 -0
  60. package/dist/context-providers/types.js.map +1 -0
  61. package/dist/context-providers/url.d.ts +27 -0
  62. package/dist/context-providers/url.d.ts.map +1 -0
  63. package/dist/context-providers/url.js +131 -0
  64. package/dist/context-providers/url.js.map +1 -0
  65. package/dist/effort/index.d.ts +78 -0
  66. package/dist/effort/index.d.ts.map +1 -0
  67. package/dist/effort/index.js +146 -0
  68. package/dist/effort/index.js.map +1 -0
  69. package/dist/hooks/index.d.ts +47 -0
  70. package/dist/hooks/index.d.ts.map +1 -0
  71. package/dist/hooks/index.js +151 -0
  72. package/dist/hooks/index.js.map +1 -0
  73. package/dist/index.d.ts +75 -0
  74. package/dist/index.d.ts.map +1 -0
  75. package/dist/index.js +152 -0
  76. package/dist/index.js.map +1 -0
  77. package/dist/indexing/chunker.d.ts +25 -0
  78. package/dist/indexing/chunker.d.ts.map +1 -0
  79. package/dist/indexing/chunker.js +217 -0
  80. package/dist/indexing/chunker.js.map +1 -0
  81. package/dist/indexing/database.d.ts +49 -0
  82. package/dist/indexing/database.d.ts.map +1 -0
  83. package/dist/indexing/database.js +287 -0
  84. package/dist/indexing/database.js.map +1 -0
  85. package/dist/indexing/index.d.ts +9 -0
  86. package/dist/indexing/index.d.ts.map +1 -0
  87. package/dist/indexing/index.js +13 -0
  88. package/dist/indexing/index.js.map +1 -0
  89. package/dist/indexing/indexer.d.ts +63 -0
  90. package/dist/indexing/indexer.d.ts.map +1 -0
  91. package/dist/indexing/indexer.js +352 -0
  92. package/dist/indexing/indexer.js.map +1 -0
  93. package/dist/indexing/recent-edits-cache.d.ts +77 -0
  94. package/dist/indexing/recent-edits-cache.d.ts.map +1 -0
  95. package/dist/indexing/recent-edits-cache.js +123 -0
  96. package/dist/indexing/recent-edits-cache.js.map +1 -0
  97. package/dist/indexing/types.d.ts +39 -0
  98. package/dist/indexing/types.d.ts.map +1 -0
  99. package/dist/indexing/types.js +6 -0
  100. package/dist/indexing/types.js.map +1 -0
  101. package/dist/mcp/index.d.ts +33 -0
  102. package/dist/mcp/index.d.ts.map +1 -0
  103. package/dist/mcp/index.js +37 -0
  104. package/dist/mcp/index.js.map +1 -0
  105. package/dist/mcp/manager.d.ts +123 -0
  106. package/dist/mcp/manager.d.ts.map +1 -0
  107. package/dist/mcp/manager.js +331 -0
  108. package/dist/mcp/manager.js.map +1 -0
  109. package/dist/oauth.d.ts +33 -0
  110. package/dist/oauth.d.ts.map +1 -0
  111. package/dist/oauth.js +312 -0
  112. package/dist/oauth.js.map +1 -0
  113. package/dist/permissions/index.d.ts +216 -0
  114. package/dist/permissions/index.d.ts.map +1 -0
  115. package/dist/permissions/index.js +938 -0
  116. package/dist/permissions/index.js.map +1 -0
  117. package/dist/plan/index.d.ts +20 -0
  118. package/dist/plan/index.d.ts.map +1 -0
  119. package/dist/plan/index.js +24 -0
  120. package/dist/plan/index.js.map +1 -0
  121. package/dist/plan/manager.d.ts +101 -0
  122. package/dist/plan/manager.d.ts.map +1 -0
  123. package/dist/plan/manager.js +170 -0
  124. package/dist/plan/manager.js.map +1 -0
  125. package/dist/rules/index.d.ts +28 -0
  126. package/dist/rules/index.d.ts.map +1 -0
  127. package/dist/rules/index.js +31 -0
  128. package/dist/rules/index.js.map +1 -0
  129. package/dist/rules/manager.d.ts +77 -0
  130. package/dist/rules/manager.d.ts.map +1 -0
  131. package/dist/rules/manager.js +279 -0
  132. package/dist/rules/manager.js.map +1 -0
  133. package/dist/rules/types.d.ts +34 -0
  134. package/dist/rules/types.d.ts.map +1 -0
  135. package/dist/rules/types.js +9 -0
  136. package/dist/rules/types.js.map +1 -0
  137. package/dist/sandbox/filesystem.d.ts +20 -0
  138. package/dist/sandbox/filesystem.d.ts.map +1 -0
  139. package/dist/sandbox/filesystem.js +141 -0
  140. package/dist/sandbox/filesystem.js.map +1 -0
  141. package/dist/sandbox/index.d.ts +4 -0
  142. package/dist/sandbox/index.d.ts.map +1 -0
  143. package/dist/sandbox/index.js +8 -0
  144. package/dist/sandbox/index.js.map +1 -0
  145. package/dist/sandbox/manager.d.ts +47 -0
  146. package/dist/sandbox/manager.d.ts.map +1 -0
  147. package/dist/sandbox/manager.js +220 -0
  148. package/dist/sandbox/manager.js.map +1 -0
  149. package/dist/sandbox/network.d.ts +14 -0
  150. package/dist/sandbox/network.d.ts.map +1 -0
  151. package/dist/sandbox/network.js +87 -0
  152. package/dist/sandbox/network.js.map +1 -0
  153. package/dist/sandbox/types.d.ts +42 -0
  154. package/dist/sandbox/types.d.ts.map +1 -0
  155. package/dist/sandbox/types.js +25 -0
  156. package/dist/sandbox/types.js.map +1 -0
  157. package/dist/tools/ast-edit.d.ts +57 -0
  158. package/dist/tools/ast-edit.d.ts.map +1 -0
  159. package/dist/tools/ast-edit.js +443 -0
  160. package/dist/tools/ast-edit.js.map +1 -0
  161. package/dist/tools/code-verify.d.ts +8 -0
  162. package/dist/tools/code-verify.d.ts.map +1 -0
  163. package/dist/tools/code-verify.js +159 -0
  164. package/dist/tools/code-verify.js.map +1 -0
  165. package/dist/tools/codebase-search.d.ts +17 -0
  166. package/dist/tools/codebase-search.d.ts.map +1 -0
  167. package/dist/tools/codebase-search.js +104 -0
  168. package/dist/tools/codebase-search.js.map +1 -0
  169. package/dist/tools/file-delete.d.ts +26 -0
  170. package/dist/tools/file-delete.d.ts.map +1 -0
  171. package/dist/tools/file-delete.js +179 -0
  172. package/dist/tools/file-delete.js.map +1 -0
  173. package/dist/tools/file-edit.d.ts +10 -0
  174. package/dist/tools/file-edit.d.ts.map +1 -0
  175. package/dist/tools/file-edit.js +138 -0
  176. package/dist/tools/file-edit.js.map +1 -0
  177. package/dist/tools/file-read.d.ts +12 -0
  178. package/dist/tools/file-read.d.ts.map +1 -0
  179. package/dist/tools/file-read.js +211 -0
  180. package/dist/tools/file-read.js.map +1 -0
  181. package/dist/tools/file-run.d.ts +10 -0
  182. package/dist/tools/file-run.d.ts.map +1 -0
  183. package/dist/tools/file-run.js +179 -0
  184. package/dist/tools/file-run.js.map +1 -0
  185. package/dist/tools/file-write.d.ts +10 -0
  186. package/dist/tools/file-write.d.ts.map +1 -0
  187. package/dist/tools/file-write.js +134 -0
  188. package/dist/tools/file-write.js.map +1 -0
  189. package/dist/tools/glob-search.d.ts +8 -0
  190. package/dist/tools/glob-search.d.ts.map +1 -0
  191. package/dist/tools/glob-search.js +108 -0
  192. package/dist/tools/glob-search.js.map +1 -0
  193. package/dist/tools/grep-search.d.ts +8 -0
  194. package/dist/tools/grep-search.d.ts.map +1 -0
  195. package/dist/tools/grep-search.js +139 -0
  196. package/dist/tools/grep-search.js.map +1 -0
  197. package/dist/tools/list-dir.d.ts +16 -0
  198. package/dist/tools/list-dir.d.ts.map +1 -0
  199. package/dist/tools/list-dir.js +183 -0
  200. package/dist/tools/list-dir.js.map +1 -0
  201. package/dist/tools/multi-edit.d.ts +16 -0
  202. package/dist/tools/multi-edit.d.ts.map +1 -0
  203. package/dist/tools/multi-edit.js +163 -0
  204. package/dist/tools/multi-edit.js.map +1 -0
  205. package/dist/tools/notebook-edit.d.ts +31 -0
  206. package/dist/tools/notebook-edit.d.ts.map +1 -0
  207. package/dist/tools/notebook-edit.js +321 -0
  208. package/dist/tools/notebook-edit.js.map +1 -0
  209. package/dist/tools/registry.d.ts +16 -0
  210. package/dist/tools/registry.d.ts.map +1 -0
  211. package/dist/tools/registry.js +41 -0
  212. package/dist/tools/registry.js.map +1 -0
  213. package/dist/tools/shell-exec.d.ts +12 -0
  214. package/dist/tools/shell-exec.d.ts.map +1 -0
  215. package/dist/tools/shell-exec.js +261 -0
  216. package/dist/tools/shell-exec.js.map +1 -0
  217. package/dist/tools/sub-agent-manager.d.ts +57 -0
  218. package/dist/tools/sub-agent-manager.d.ts.map +1 -0
  219. package/dist/tools/sub-agent-manager.js +153 -0
  220. package/dist/tools/sub-agent-manager.js.map +1 -0
  221. package/dist/tools/sub-agent-status.d.ts +12 -0
  222. package/dist/tools/sub-agent-status.d.ts.map +1 -0
  223. package/dist/tools/sub-agent-status.js +59 -0
  224. package/dist/tools/sub-agent-status.js.map +1 -0
  225. package/dist/tools/sub-agent-terminate.d.ts +12 -0
  226. package/dist/tools/sub-agent-terminate.d.ts.map +1 -0
  227. package/dist/tools/sub-agent-terminate.js +55 -0
  228. package/dist/tools/sub-agent-terminate.js.map +1 -0
  229. package/dist/tools/sub-agent.d.ts +34 -0
  230. package/dist/tools/sub-agent.d.ts.map +1 -0
  231. package/dist/tools/sub-agent.js +140 -0
  232. package/dist/tools/sub-agent.js.map +1 -0
  233. package/dist/tools/system-info.d.ts +24 -0
  234. package/dist/tools/system-info.d.ts.map +1 -0
  235. package/dist/tools/system-info.js +220 -0
  236. package/dist/tools/system-info.js.map +1 -0
  237. package/dist/tools/todo.d.ts +16 -0
  238. package/dist/tools/todo.d.ts.map +1 -0
  239. package/dist/tools/todo.js +144 -0
  240. package/dist/tools/todo.js.map +1 -0
  241. package/dist/tools/types.d.ts +20 -0
  242. package/dist/tools/types.d.ts.map +1 -0
  243. package/dist/tools/types.js +3 -0
  244. package/dist/tools/types.js.map +1 -0
  245. package/dist/tools/view-diff.d.ts +11 -0
  246. package/dist/tools/view-diff.d.ts.map +1 -0
  247. package/dist/tools/view-diff.js +88 -0
  248. package/dist/tools/view-diff.js.map +1 -0
  249. package/dist/tools/view-repo-map.d.ts +18 -0
  250. package/dist/tools/view-repo-map.d.ts.map +1 -0
  251. package/dist/tools/view-repo-map.js +245 -0
  252. package/dist/tools/view-repo-map.js.map +1 -0
  253. package/dist/tools/web-fetch.d.ts +13 -0
  254. package/dist/tools/web-fetch.d.ts.map +1 -0
  255. package/dist/tools/web-fetch.js +106 -0
  256. package/dist/tools/web-fetch.js.map +1 -0
  257. package/dist/tools/web-search.d.ts +10 -0
  258. package/dist/tools/web-search.d.ts.map +1 -0
  259. package/dist/tools/web-search.js +106 -0
  260. package/dist/tools/web-search.js.map +1 -0
  261. package/dist/utils/gitignore.d.ts +10 -0
  262. package/dist/utils/gitignore.d.ts.map +1 -0
  263. package/dist/utils/gitignore.js +104 -0
  264. package/dist/utils/gitignore.js.map +1 -0
  265. package/dist/utils/lazy-apply.d.ts +45 -0
  266. package/dist/utils/lazy-apply.d.ts.map +1 -0
  267. package/dist/utils/lazy-apply.js +164 -0
  268. package/dist/utils/lazy-apply.js.map +1 -0
  269. package/dist/utils/memory.d.ts +36 -0
  270. package/dist/utils/memory.d.ts.map +1 -0
  271. package/dist/utils/memory.js +136 -0
  272. package/dist/utils/memory.js.map +1 -0
  273. package/dist/utils/path-matching.d.ts +24 -0
  274. package/dist/utils/path-matching.d.ts.map +1 -0
  275. package/dist/utils/path-matching.js +116 -0
  276. package/dist/utils/path-matching.js.map +1 -0
  277. package/dist/utils/path-safety.d.ts +13 -0
  278. package/dist/utils/path-safety.d.ts.map +1 -0
  279. package/dist/utils/path-safety.js +54 -0
  280. package/dist/utils/path-safety.js.map +1 -0
  281. package/dist/utils/project-config.d.ts +18 -0
  282. package/dist/utils/project-config.d.ts.map +1 -0
  283. package/dist/utils/project-config.js +76 -0
  284. package/dist/utils/project-config.js.map +1 -0
  285. package/dist/utils/search-match.d.ts +63 -0
  286. package/dist/utils/search-match.d.ts.map +1 -0
  287. package/dist/utils/search-match.js +426 -0
  288. package/dist/utils/search-match.js.map +1 -0
  289. package/dist/utils/shell-paths.d.ts +17 -0
  290. package/dist/utils/shell-paths.d.ts.map +1 -0
  291. package/dist/utils/shell-paths.js +107 -0
  292. package/dist/utils/shell-paths.js.map +1 -0
  293. package/dist/utils/streaming-diff.d.ts +45 -0
  294. package/dist/utils/streaming-diff.d.ts.map +1 -0
  295. package/dist/utils/streaming-diff.js +230 -0
  296. package/dist/utils/streaming-diff.js.map +1 -0
  297. package/dist/utils/todo.d.ts +47 -0
  298. package/dist/utils/todo.d.ts.map +1 -0
  299. package/dist/utils/todo.js +102 -0
  300. package/dist/utils/todo.js.map +1 -0
  301. package/package.json +23 -0
  302. package/src/agents/coordinator.ts +240 -0
  303. package/src/context-providers/clipboard.ts +48 -0
  304. package/src/context-providers/codebase.ts +274 -0
  305. package/src/context-providers/diff.ts +66 -0
  306. package/src/context-providers/docs.ts +160 -0
  307. package/src/context-providers/file-include.ts +54 -0
  308. package/src/context-providers/folder.ts +106 -0
  309. package/src/context-providers/git.ts +72 -0
  310. package/src/context-providers/index.ts +26 -0
  311. package/src/context-providers/open-files.ts +113 -0
  312. package/src/context-providers/problems.ts +100 -0
  313. package/src/context-providers/registry.ts +99 -0
  314. package/src/context-providers/terminal.ts +58 -0
  315. package/src/context-providers/tree.ts +161 -0
  316. package/src/context-providers/types.ts +84 -0
  317. package/src/context-providers/url.ts +138 -0
  318. package/src/effort/index.ts +177 -0
  319. package/src/hooks/index.ts +148 -0
  320. package/src/index.ts +114 -0
  321. package/src/indexing/README.md +267 -0
  322. package/src/indexing/chunker.ts +206 -0
  323. package/src/indexing/database.ts +299 -0
  324. package/src/indexing/index.ts +15 -0
  325. package/src/indexing/indexer.ts +383 -0
  326. package/src/indexing/recent-edits-cache.ts +150 -0
  327. package/src/indexing/types.ts +44 -0
  328. package/src/mcp/index.ts +33 -0
  329. package/src/mcp/manager.ts +385 -0
  330. package/src/oauth.ts +330 -0
  331. package/src/permissions/index.ts +1011 -0
  332. package/src/plan/index.ts +20 -0
  333. package/src/plan/manager.ts +233 -0
  334. package/src/rules/index.ts +28 -0
  335. package/src/rules/manager.ts +276 -0
  336. package/src/rules/types.ts +40 -0
  337. package/src/sandbox/filesystem.ts +135 -0
  338. package/src/sandbox/index.ts +9 -0
  339. package/src/sandbox/manager.ts +213 -0
  340. package/src/sandbox/network.ts +101 -0
  341. package/src/sandbox/types.ts +63 -0
  342. package/src/tools/ast-edit.ts +493 -0
  343. package/src/tools/code-verify.ts +143 -0
  344. package/src/tools/codebase-search.ts +117 -0
  345. package/src/tools/file-delete.ts +155 -0
  346. package/src/tools/file-edit.ts +115 -0
  347. package/src/tools/file-read.ts +195 -0
  348. package/src/tools/file-run.ts +158 -0
  349. package/src/tools/file-write.ts +104 -0
  350. package/src/tools/glob-search.ts +80 -0
  351. package/src/tools/grep-search.ts +120 -0
  352. package/src/tools/list-dir.ts +172 -0
  353. package/src/tools/multi-edit.ts +138 -0
  354. package/src/tools/notebook-edit.ts +342 -0
  355. package/src/tools/registry.ts +43 -0
  356. package/src/tools/shell-exec.ts +251 -0
  357. package/src/tools/sub-agent-manager.ts +183 -0
  358. package/src/tools/sub-agent-status.ts +67 -0
  359. package/src/tools/sub-agent-terminate.ts +62 -0
  360. package/src/tools/sub-agent.ts +162 -0
  361. package/src/tools/system-info.ts +248 -0
  362. package/src/tools/todo.ts +149 -0
  363. package/src/tools/types.ts +21 -0
  364. package/src/tools/view-diff.ts +99 -0
  365. package/src/tools/view-repo-map.ts +249 -0
  366. package/src/tools/web-fetch.ts +118 -0
  367. package/src/tools/web-search.ts +129 -0
  368. package/src/utils/gitignore.ts +73 -0
  369. package/src/utils/lazy-apply.ts +189 -0
  370. package/src/utils/memory.ts +124 -0
  371. package/src/utils/path-matching.ts +84 -0
  372. package/src/utils/path-safety.ts +19 -0
  373. package/src/utils/project-config.ts +41 -0
  374. package/src/utils/search-match.ts +495 -0
  375. package/src/utils/shell-paths.ts +79 -0
  376. package/src/utils/streaming-diff.ts +260 -0
  377. package/src/utils/todo.ts +115 -0
  378. package/tsconfig.json +18 -0
@@ -0,0 +1,249 @@
1
+ /**
2
+ * View Repo Map Tool — generate a structural overview of the repository.
3
+ *
4
+ * Shows the project layout: directories, key files, entry points,
5
+ * config files, and a summary of the codebase structure.
6
+ */
7
+
8
+ import * as fs from "fs";
9
+ import * as path from "path";
10
+ import { exec } from "child_process";
11
+ import type { BaseTool, ToolDefinition, ToolResult } from "./types";
12
+ import { loadIgnorePatterns } from "../utils/gitignore";
13
+
14
+ const ALWAYS_IGNORE = new Set([
15
+ "node_modules", ".git", "dist", "build", "out", ".next", ".nuxt",
16
+ "__pycache__", ".cache", ".turbo", "coverage", "venv", ".venv",
17
+ "target", "vendor", ".idea", ".vscode", ".DS_Store", "*.pyc",
18
+ ]);
19
+
20
+ const CONFIG_FILES = new Set([
21
+ "package.json", "tsconfig.json", "tsconfig.base.json",
22
+ ".eslintrc.js", ".eslintrc.json", ".prettierrc",
23
+ "jest.config.js", "jest.config.ts", "vitest.config.ts",
24
+ "webpack.config.js", "vite.config.ts", "vite.config.js",
25
+ "rollup.config.js", "esbuild.config.js",
26
+ "Dockerfile", "docker-compose.yml", "docker-compose.yaml",
27
+ "Makefile", "CMakeLists.txt",
28
+ ".env.example", ".gitignore", ".dockerignore",
29
+ "pyproject.toml", "setup.py", "setup.cfg", "requirements.txt",
30
+ "Cargo.toml", "go.mod", "Gemfile", "composer.json",
31
+ "turbo.json", "lerna.json", "nx.json",
32
+ ]);
33
+
34
+ const ENTRY_PATTERNS = [
35
+ "index.ts", "index.js", "main.ts", "main.js", "app.ts", "app.js",
36
+ "server.ts", "server.js", "cli.ts", "cli.js",
37
+ "index.py", "main.py", "app.py", "__main__.py",
38
+ "main.go", "main.rs", "lib.rs",
39
+ ];
40
+
41
+ interface RepoStats {
42
+ totalFiles: number;
43
+ totalDirs: number;
44
+ languages: Map<string, number>;
45
+ configFiles: string[];
46
+ entryPoints: string[];
47
+ }
48
+
49
+ export class ViewRepoMapTool implements BaseTool {
50
+ definition: ToolDefinition = {
51
+ name: "view_repo_map",
52
+ description:
53
+ `Generate a structural overview of the repository. Shows:
54
+ - Directory tree (top 2 levels)
55
+ - Detected languages and file counts
56
+ - Config files found
57
+ - Likely entry points
58
+ - Git branch and recent commits
59
+
60
+ Use this to understand a new project before diving into code.`,
61
+ inputSchema: {
62
+ type: "object",
63
+ properties: {
64
+ directory: {
65
+ type: "string",
66
+ description: "Subdirectory to focus on. Defaults to project root.",
67
+ },
68
+ },
69
+ required: [],
70
+ },
71
+ requiresPermission: false,
72
+ };
73
+
74
+ private workingDir: string;
75
+
76
+ constructor(workingDir: string) {
77
+ this.workingDir = workingDir;
78
+ }
79
+
80
+ async execute(input: Record<string, unknown>): Promise<ToolResult> {
81
+ const subdir = (input.directory as string) || "";
82
+ const rootDir = subdir ? path.resolve(this.workingDir, subdir) : this.workingDir;
83
+
84
+ if (!fs.existsSync(rootDir) || !fs.statSync(rootDir).isDirectory()) {
85
+ return { success: false, output: "", error: `Directory not found: ${rootDir}` };
86
+ }
87
+
88
+ const sections: string[] = [];
89
+
90
+ // 1. Header
91
+ sections.push(`# Repository Map: ${path.basename(rootDir)}`);
92
+ sections.push(`Path: ${rootDir}`);
93
+
94
+ // 2. Git info
95
+ const gitInfo = await this.getGitInfo(rootDir);
96
+ if (gitInfo) sections.push(gitInfo);
97
+
98
+ // 3. Directory tree (2 levels)
99
+ const tree = this.buildTree(rootDir, 2);
100
+ sections.push("\n## Directory Structure\n```\n" + tree + "\n```");
101
+
102
+ // 4. Stats
103
+ const stats = this.collectStats(rootDir);
104
+ sections.push(this.formatStats(stats));
105
+
106
+ return { success: true, output: sections.join("\n") };
107
+ }
108
+
109
+ private buildTree(dir: string, maxDepth: number, prefix = "", depth = 0): string {
110
+ if (depth > maxDepth) return "";
111
+
112
+ let entries: fs.Dirent[];
113
+ try {
114
+ entries = fs.readdirSync(dir, { withFileTypes: true });
115
+ } catch {
116
+ return "";
117
+ }
118
+
119
+ entries = entries
120
+ .filter((e) => !ALWAYS_IGNORE.has(e.name) && !e.name.startsWith("."))
121
+ .sort((a, b) => {
122
+ if (a.isDirectory() && !b.isDirectory()) return -1;
123
+ if (!a.isDirectory() && b.isDirectory()) return 1;
124
+ return a.name.localeCompare(b.name);
125
+ });
126
+
127
+ const lines: string[] = [];
128
+ for (let i = 0; i < entries.length; i++) {
129
+ const entry = entries[i];
130
+ const isLast = i === entries.length - 1;
131
+ const connector = isLast ? "└── " : "├── ";
132
+ const childPrefix = isLast ? " " : "│ ";
133
+
134
+ if (entry.isDirectory()) {
135
+ lines.push(`${prefix}${connector}${entry.name}/`);
136
+ const subtree = this.buildTree(
137
+ path.join(dir, entry.name),
138
+ maxDepth,
139
+ prefix + childPrefix,
140
+ depth + 1,
141
+ );
142
+ if (subtree) lines.push(subtree);
143
+ } else {
144
+ lines.push(`${prefix}${connector}${entry.name}`);
145
+ }
146
+ }
147
+
148
+ return lines.join("\n");
149
+ }
150
+
151
+ private collectStats(dir: string, stats?: RepoStats, depth = 0): RepoStats {
152
+ if (!stats) {
153
+ stats = { totalFiles: 0, totalDirs: 0, languages: new Map(), configFiles: [], entryPoints: [] };
154
+ }
155
+ if (depth > 10 || stats.totalFiles > 5000) return stats;
156
+
157
+ let entries: fs.Dirent[];
158
+ try {
159
+ entries = fs.readdirSync(dir, { withFileTypes: true });
160
+ } catch {
161
+ return stats;
162
+ }
163
+
164
+ for (const entry of entries) {
165
+ if (ALWAYS_IGNORE.has(entry.name)) continue;
166
+
167
+ if (entry.isDirectory()) {
168
+ stats.totalDirs++;
169
+ this.collectStats(path.join(dir, entry.name), stats, depth + 1);
170
+ } else {
171
+ stats.totalFiles++;
172
+
173
+ // Track language
174
+ const ext = path.extname(entry.name).toLowerCase();
175
+ if (ext) {
176
+ stats.languages.set(ext, (stats.languages.get(ext) || 0) + 1);
177
+ }
178
+
179
+ // Config files
180
+ if (CONFIG_FILES.has(entry.name) && depth <= 2) {
181
+ const rel = path.relative(this.workingDir, path.join(dir, entry.name));
182
+ stats.configFiles.push(rel);
183
+ }
184
+
185
+ // Entry points
186
+ if (ENTRY_PATTERNS.includes(entry.name) && depth <= 3) {
187
+ const rel = path.relative(this.workingDir, path.join(dir, entry.name));
188
+ stats.entryPoints.push(rel);
189
+ }
190
+ }
191
+ }
192
+
193
+ return stats;
194
+ }
195
+
196
+ private formatStats(stats: RepoStats): string {
197
+ const lines: string[] = ["\n## Summary"];
198
+ lines.push(`- **${stats.totalFiles}** files in **${stats.totalDirs}** directories`);
199
+
200
+ // Languages (top 10)
201
+ if (stats.languages.size > 0) {
202
+ const sorted = [...stats.languages.entries()]
203
+ .sort((a, b) => b[1] - a[1])
204
+ .slice(0, 10);
205
+ const langStr = sorted.map(([ext, count]) => `${ext} (${count})`).join(", ");
206
+ lines.push(`- **Languages:** ${langStr}`);
207
+ }
208
+
209
+ // Config files
210
+ if (stats.configFiles.length > 0) {
211
+ lines.push(`\n### Config Files`);
212
+ for (const f of stats.configFiles.slice(0, 20)) lines.push(`- ${f}`);
213
+ }
214
+
215
+ // Entry points
216
+ if (stats.entryPoints.length > 0) {
217
+ lines.push(`\n### Entry Points`);
218
+ for (const f of stats.entryPoints.slice(0, 20)) lines.push(`- ${f}`);
219
+ }
220
+
221
+ return lines.join("\n");
222
+ }
223
+
224
+ private getGitInfo(dir: string): Promise<string | null> {
225
+ return new Promise((resolve) => {
226
+ exec(
227
+ 'git branch --show-current && echo "---" && git log --oneline -5 2>/dev/null',
228
+ { cwd: dir, timeout: 5000 },
229
+ (error, stdout) => {
230
+ if (error || !stdout.trim()) {
231
+ resolve(null);
232
+ return;
233
+ }
234
+ const parts = stdout.split("---");
235
+ const branch = parts[0]?.trim();
236
+ const commits = parts[1]?.trim();
237
+ const lines = [`Branch: **${branch}**`];
238
+ if (commits) {
239
+ lines.push("\nRecent commits:");
240
+ for (const c of commits.split("\n").slice(0, 5)) {
241
+ lines.push(` ${c.trim()}`);
242
+ }
243
+ }
244
+ resolve(lines.join("\n"));
245
+ },
246
+ );
247
+ });
248
+ }
249
+ }
@@ -0,0 +1,118 @@
1
+ /**
2
+ * Web Fetch Tool — fetch content from URLs.
3
+ * Supports HTML pages (extracts text), JSON APIs, and plain text.
4
+ */
5
+
6
+ import type { BaseTool, ToolDefinition, ToolResult } from "./types";
7
+ import type { SandboxManager } from "../sandbox";
8
+
9
+ export class WebFetchTool implements BaseTool {
10
+ definition: ToolDefinition = {
11
+ name: "web_fetch",
12
+ description:
13
+ "Fetch content from a URL. Returns the text content of the page. Useful for reading documentation, APIs, or web pages. Requires user permission. Network access is controlled by sandbox domain rules — requests to non-allowed domains may be blocked.",
14
+ inputSchema: {
15
+ type: "object",
16
+ properties: {
17
+ url: {
18
+ type: "string",
19
+ description: "The URL to fetch",
20
+ },
21
+ max_length: {
22
+ type: "number",
23
+ description: "Maximum characters to return. Default: 10000.",
24
+ },
25
+ },
26
+ required: ["url"],
27
+ },
28
+ requiresPermission: true,
29
+ permissionMessage: (input) => `Fetch URL: ${input.url}`,
30
+ };
31
+
32
+ private sandboxManager?: SandboxManager;
33
+
34
+ constructor(sandboxManager?: SandboxManager) {
35
+ this.sandboxManager = sandboxManager;
36
+ }
37
+
38
+ async execute(input: Record<string, unknown>): Promise<ToolResult> {
39
+ const url = input.url as string;
40
+ const maxLength = (input.max_length as number) || 10000;
41
+
42
+ // Validate URL
43
+ try {
44
+ new URL(url);
45
+ } catch {
46
+ return { success: false, output: "", error: `Invalid URL: ${url}` };
47
+ }
48
+
49
+ // Sandbox network check
50
+ if (this.sandboxManager) {
51
+ const check = await this.sandboxManager.checkNetworkAccess(url);
52
+ if (!check.allowed) {
53
+ return { success: false, output: "", error: check.reason || "Sandbox: network access denied" };
54
+ }
55
+ }
56
+
57
+ try {
58
+ const controller = new AbortController();
59
+ const timeout = setTimeout(() => controller.abort(), 30000);
60
+
61
+ const response = await fetch(url, {
62
+ signal: controller.signal,
63
+ headers: {
64
+ "User-Agent": "Cdoing-Agent/0.1.0",
65
+ "Accept": "text/html,application/json,text/plain,*/*",
66
+ },
67
+ });
68
+
69
+ clearTimeout(timeout);
70
+
71
+ if (!response.ok) {
72
+ return {
73
+ success: false,
74
+ output: "",
75
+ error: `HTTP ${response.status}: ${response.statusText}`,
76
+ };
77
+ }
78
+
79
+ const contentType = response.headers.get("content-type") || "";
80
+ let text = await response.text();
81
+
82
+ // If HTML, strip tags and extract text content
83
+ if (contentType.includes("text/html")) {
84
+ text = stripHtml(text);
85
+ }
86
+
87
+ // Truncate if too long
88
+ if (text.length > maxLength) {
89
+ text = text.substring(0, maxLength) + `\n\n... [truncated at ${maxLength} characters]`;
90
+ }
91
+
92
+ return { success: true, output: text || "(empty response)" };
93
+ } catch (err) {
94
+ const message = err instanceof Error ? err.message : String(err);
95
+ return { success: false, output: "", error: `Fetch failed: ${message}` };
96
+ }
97
+ }
98
+ }
99
+
100
+ /** Simple HTML-to-text: remove tags, decode common entities, collapse whitespace */
101
+ function stripHtml(html: string): string {
102
+ return html
103
+ // Remove script and style blocks
104
+ .replace(/<script[^>]*>[\s\S]*?<\/script>/gi, "")
105
+ .replace(/<style[^>]*>[\s\S]*?<\/style>/gi, "")
106
+ // Remove HTML tags
107
+ .replace(/<[^>]+>/g, " ")
108
+ // Decode common entities
109
+ .replace(/&amp;/g, "&")
110
+ .replace(/&lt;/g, "<")
111
+ .replace(/&gt;/g, ">")
112
+ .replace(/&quot;/g, '"')
113
+ .replace(/&#39;/g, "'")
114
+ .replace(/&nbsp;/g, " ")
115
+ // Collapse whitespace
116
+ .replace(/\s+/g, " ")
117
+ .trim();
118
+ }
@@ -0,0 +1,129 @@
1
+ /**
2
+ * Web Search Tool — search the web using DuckDuckGo's HTML page.
3
+ * No API key required — uses DDG's lite HTML interface.
4
+ */
5
+
6
+ import type { BaseTool, ToolDefinition, ToolResult } from "./types";
7
+
8
+ export class WebSearchTool implements BaseTool {
9
+ definition: ToolDefinition = {
10
+ name: "web_search",
11
+ description:
12
+ "Search the web for information. Returns search results with titles, URLs, and snippets. Useful for finding documentation, solutions, or current information.",
13
+ inputSchema: {
14
+ type: "object",
15
+ properties: {
16
+ query: {
17
+ type: "string",
18
+ description: "The search query",
19
+ },
20
+ max_results: {
21
+ type: "number",
22
+ description: "Maximum number of results. Default: 5.",
23
+ },
24
+ },
25
+ required: ["query"],
26
+ },
27
+ requiresPermission: true,
28
+ permissionMessage: (input) => `Web search: ${input.query}`,
29
+ };
30
+
31
+ async execute(input: Record<string, unknown>): Promise<ToolResult> {
32
+ const query = input.query as string;
33
+ const maxResults = (input.max_results as number) || 5;
34
+
35
+ try {
36
+ const encodedQuery = encodeURIComponent(query);
37
+ const url = `https://lite.duckduckgo.com/lite/?q=${encodedQuery}`;
38
+
39
+ const controller = new AbortController();
40
+ const timeout = setTimeout(() => controller.abort(), 15000);
41
+
42
+ const response = await fetch(url, {
43
+ signal: controller.signal,
44
+ headers: {
45
+ "User-Agent": "Cdoing-Agent/0.1.0",
46
+ "Accept": "text/html",
47
+ },
48
+ });
49
+
50
+ clearTimeout(timeout);
51
+
52
+ if (!response.ok) {
53
+ return {
54
+ success: false,
55
+ output: "",
56
+ error: `Search failed: HTTP ${response.status}`,
57
+ };
58
+ }
59
+
60
+ const html = await response.text();
61
+ const results = parseSearchResults(html, maxResults);
62
+
63
+ if (results.length === 0) {
64
+ return { success: true, output: "No results found." };
65
+ }
66
+
67
+ const formatted = results
68
+ .map((r, i) => `${i + 1}. **${r.title}**\n ${r.url}\n ${r.snippet}`)
69
+ .join("\n\n");
70
+
71
+ return {
72
+ success: true,
73
+ output: `Search results for "${query}":\n\n${formatted}`,
74
+ };
75
+ } catch (err) {
76
+ const message = err instanceof Error ? err.message : String(err);
77
+ return { success: false, output: "", error: `Search failed: ${message}` };
78
+ }
79
+ }
80
+ }
81
+
82
+ interface SearchResult {
83
+ title: string;
84
+ url: string;
85
+ snippet: string;
86
+ }
87
+
88
+ /** Parse DDG lite HTML for search results */
89
+ function parseSearchResults(html: string, maxResults: number): SearchResult[] {
90
+ const results: SearchResult[] = [];
91
+
92
+ // DDG lite puts results in table rows with class "result-link" for titles
93
+ // and "result-snippet" for descriptions
94
+ const linkRegex = /<a[^>]+class="result-link"[^>]*href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi;
95
+ const snippetRegex = /<td[^>]+class="result-snippet"[^>]*>([\s\S]*?)<\/td>/gi;
96
+
97
+ const links: { url: string; title: string }[] = [];
98
+ const snippets: string[] = [];
99
+
100
+ let match;
101
+ while ((match = linkRegex.exec(html)) !== null) {
102
+ links.push({
103
+ url: match[1].replace(/&amp;/g, "&"),
104
+ title: match[2].replace(/<[^>]+>/g, "").trim(),
105
+ });
106
+ }
107
+
108
+ while ((match = snippetRegex.exec(html)) !== null) {
109
+ snippets.push(
110
+ match[1]
111
+ .replace(/<[^>]+>/g, "")
112
+ .replace(/&amp;/g, "&")
113
+ .replace(/&lt;/g, "<")
114
+ .replace(/&gt;/g, ">")
115
+ .replace(/&quot;/g, '"')
116
+ .trim()
117
+ );
118
+ }
119
+
120
+ for (let i = 0; i < Math.min(links.length, maxResults); i++) {
121
+ results.push({
122
+ title: links[i].title || "(untitled)",
123
+ url: links[i].url,
124
+ snippet: snippets[i] || "",
125
+ });
126
+ }
127
+
128
+ return results;
129
+ }
@@ -0,0 +1,73 @@
1
+ /**
2
+ * Gitignore-aware file filtering.
3
+ * Reads .gitignore and applies patterns to glob/grep searches.
4
+ */
5
+
6
+ import * as fs from "fs";
7
+ import * as path from "path";
8
+
9
+ /** Default patterns to always ignore */
10
+ const DEFAULT_IGNORE = [
11
+ "**/node_modules/**",
12
+ "**/dist/**",
13
+ "**/.git/**",
14
+ "**/*.lock",
15
+ "**/build/**",
16
+ "**/.next/**",
17
+ "**/.nuxt/**",
18
+ "**/coverage/**",
19
+ "**/__pycache__/**",
20
+ "**/.venv/**",
21
+ "**/venv/**",
22
+ "**/.env",
23
+ "**/.DS_Store",
24
+ ];
25
+
26
+ /**
27
+ * Load ignore patterns from .gitignore + defaults.
28
+ * Converts .gitignore patterns to glob-compatible patterns.
29
+ */
30
+ export function loadIgnorePatterns(workingDir: string): string[] {
31
+ const patterns = [...DEFAULT_IGNORE];
32
+ const gitignorePath = path.join(workingDir, ".gitignore");
33
+
34
+ try {
35
+ if (fs.existsSync(gitignorePath)) {
36
+ const content = fs.readFileSync(gitignorePath, "utf-8");
37
+ const lines = content.split("\n");
38
+
39
+ for (let line of lines) {
40
+ line = line.trim();
41
+ // Skip empty lines and comments
42
+ if (!line || line.startsWith("#")) continue;
43
+ // Skip negation patterns (complex to handle)
44
+ if (line.startsWith("!")) continue;
45
+
46
+ // Convert to glob pattern
47
+ let pattern = line;
48
+
49
+ // If it ends with /, it's a directory — add **
50
+ if (pattern.endsWith("/")) {
51
+ pattern = `**/${pattern}**`;
52
+ }
53
+ // If it doesn't contain a slash, it can match anywhere
54
+ else if (!pattern.includes("/")) {
55
+ pattern = `**/${pattern}`;
56
+ }
57
+ // If it starts with /, it's relative to root
58
+ else if (pattern.startsWith("/")) {
59
+ pattern = pattern.substring(1);
60
+ }
61
+
62
+ // Avoid duplicates
63
+ if (!patterns.includes(pattern)) {
64
+ patterns.push(pattern);
65
+ }
66
+ }
67
+ }
68
+ } catch {
69
+ // Silently ignore read errors
70
+ }
71
+
72
+ return patterns;
73
+ }