@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,230 @@
1
+ "use strict";
2
+ /**
3
+ * Streaming Diff — generates and emits diff chunks in real-time as edits are applied.
4
+ *
5
+ * Instead of computing the entire diff at once and returning it,
6
+ * StreamingDiff emits line-level diff events via a callback, enabling
7
+ * UIs to render changes incrementally (e.g., green/red highlighting as
8
+ * each hunk is processed).
9
+ *
10
+ * Supports three strategies:
11
+ * 1. Deterministic — line-by-line Myers diff (always correct, synchronous)
12
+ * 2. Unified diff — parse and stream hunk-by-hunk from a unified diff string
13
+ * 3. Streaming — emit chunks as they arrive from an LLM token stream
14
+ */
15
+ Object.defineProperty(exports, "__esModule", { value: true });
16
+ exports.StreamingDiffAccumulator = void 0;
17
+ exports.streamDeterministicDiff = streamDeterministicDiff;
18
+ exports.streamUnifiedDiff = streamUnifiedDiff;
19
+ /**
20
+ * Compute a line-level diff between two strings and emit chunks via callback.
21
+ * Uses a simple LCS-based diff algorithm.
22
+ */
23
+ function streamDeterministicDiff(oldContent, newContent, filePath, onChunk) {
24
+ const oldLines = oldContent.split("\n");
25
+ const newLines = newContent.split("\n");
26
+ // Emit file headers
27
+ onChunk({ type: "file-header", content: `--- a/${filePath}` });
28
+ onChunk({ type: "file-header", content: `+++ b/${filePath}` });
29
+ // Compute LCS for line-level diff
30
+ const diff = computeLineDiff(oldLines, newLines);
31
+ // Group into hunks
32
+ const hunks = groupIntoHunks(diff, oldLines.length, newLines.length);
33
+ for (const hunk of hunks) {
34
+ onChunk({
35
+ type: "hunk-header",
36
+ content: `@@ -${hunk.oldStart + 1},${hunk.oldCount} +${hunk.newStart + 1},${hunk.newCount} @@`,
37
+ });
38
+ for (const entry of hunk.entries) {
39
+ onChunk(entry);
40
+ }
41
+ }
42
+ }
43
+ /**
44
+ * Simple line diff using longest common subsequence.
45
+ */
46
+ function computeLineDiff(oldLines, newLines) {
47
+ const m = oldLines.length;
48
+ const n = newLines.length;
49
+ // Build LCS table
50
+ const dp = Array.from({ length: m + 1 }, () => new Array(n + 1).fill(0));
51
+ for (let i = 1; i <= m; i++) {
52
+ for (let j = 1; j <= n; j++) {
53
+ if (oldLines[i - 1] === newLines[j - 1]) {
54
+ dp[i][j] = dp[i - 1][j - 1] + 1;
55
+ }
56
+ else {
57
+ dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
58
+ }
59
+ }
60
+ }
61
+ // Backtrack to produce diff
62
+ const result = [];
63
+ let i = m, j = n;
64
+ while (i > 0 || j > 0) {
65
+ if (i > 0 && j > 0 && oldLines[i - 1] === newLines[j - 1]) {
66
+ result.unshift({ type: "context", content: oldLines[i - 1], oldLine: i, newLine: j });
67
+ i--;
68
+ j--;
69
+ }
70
+ else if (j > 0 && (i === 0 || dp[i][j - 1] >= dp[i - 1][j])) {
71
+ result.unshift({ type: "add", content: newLines[j - 1], newLine: j });
72
+ j--;
73
+ }
74
+ else {
75
+ result.unshift({ type: "remove", content: oldLines[i - 1], oldLine: i });
76
+ i--;
77
+ }
78
+ }
79
+ return result;
80
+ }
81
+ /**
82
+ * Group diff entries into hunks with context lines.
83
+ */
84
+ function groupIntoHunks(diff, oldTotal, newTotal, contextLines = 3) {
85
+ if (diff.length === 0)
86
+ return [];
87
+ // Find ranges of changes
88
+ const changeIndices = [];
89
+ for (let i = 0; i < diff.length; i++) {
90
+ if (diff[i].type !== "context") {
91
+ changeIndices.push(i);
92
+ }
93
+ }
94
+ if (changeIndices.length === 0)
95
+ return [];
96
+ // Group changes that are within contextLines*2 of each other
97
+ const groups = [];
98
+ let groupStart = changeIndices[0];
99
+ let groupEnd = changeIndices[0];
100
+ for (let i = 1; i < changeIndices.length; i++) {
101
+ if (changeIndices[i] - groupEnd <= contextLines * 2 + 1) {
102
+ groupEnd = changeIndices[i];
103
+ }
104
+ else {
105
+ groups.push({ start: groupStart, end: groupEnd });
106
+ groupStart = changeIndices[i];
107
+ groupEnd = changeIndices[i];
108
+ }
109
+ }
110
+ groups.push({ start: groupStart, end: groupEnd });
111
+ // Build hunks with context
112
+ const hunks = [];
113
+ for (const group of groups) {
114
+ const hunkStart = Math.max(0, group.start - contextLines);
115
+ const hunkEnd = Math.min(diff.length - 1, group.end + contextLines);
116
+ const entries = [];
117
+ let oldStart = Infinity, newStart = Infinity;
118
+ let oldCount = 0, newCount = 0;
119
+ for (let i = hunkStart; i <= hunkEnd; i++) {
120
+ const d = diff[i];
121
+ const lineNum = d.oldLine ?? d.newLine;
122
+ if (d.type === "context") {
123
+ entries.push({ type: "context", content: ` ${d.content}`, lineNumber: lineNum });
124
+ if (d.oldLine !== undefined && d.oldLine < oldStart)
125
+ oldStart = d.oldLine;
126
+ if (d.newLine !== undefined && d.newLine < newStart)
127
+ newStart = d.newLine;
128
+ oldCount++;
129
+ newCount++;
130
+ }
131
+ else if (d.type === "remove") {
132
+ entries.push({ type: "remove", content: `-${d.content}`, lineNumber: d.oldLine });
133
+ if (d.oldLine !== undefined && d.oldLine < oldStart)
134
+ oldStart = d.oldLine;
135
+ oldCount++;
136
+ }
137
+ else {
138
+ entries.push({ type: "add", content: `+${d.content}`, lineNumber: d.newLine });
139
+ if (d.newLine !== undefined && d.newLine < newStart)
140
+ newStart = d.newLine;
141
+ newCount++;
142
+ }
143
+ }
144
+ if (oldStart === Infinity)
145
+ oldStart = 1;
146
+ if (newStart === Infinity)
147
+ newStart = 1;
148
+ hunks.push({
149
+ oldStart: oldStart - 1,
150
+ oldCount,
151
+ newStart: newStart - 1,
152
+ newCount,
153
+ entries,
154
+ });
155
+ }
156
+ return hunks;
157
+ }
158
+ /**
159
+ * Stream a unified diff string hunk-by-hunk via callback.
160
+ */
161
+ function streamUnifiedDiff(diffText, onChunk) {
162
+ const lines = diffText.split("\n");
163
+ for (const line of lines) {
164
+ if (line.startsWith("---") || line.startsWith("+++")) {
165
+ onChunk({ type: "file-header", content: line });
166
+ }
167
+ else if (line.startsWith("@@")) {
168
+ onChunk({ type: "hunk-header", content: line });
169
+ }
170
+ else if (line.startsWith("+")) {
171
+ onChunk({ type: "add", content: line });
172
+ }
173
+ else if (line.startsWith("-")) {
174
+ onChunk({ type: "remove", content: line });
175
+ }
176
+ else {
177
+ onChunk({ type: "context", content: line });
178
+ }
179
+ }
180
+ }
181
+ /**
182
+ * StreamingDiffAccumulator — collects tokens from an LLM stream and emits
183
+ * diff chunks as complete lines are formed. Used for real-time diff display
184
+ * while the model is still generating.
185
+ */
186
+ class StreamingDiffAccumulator {
187
+ buffer = "";
188
+ onChunk;
189
+ lineNumber = 1;
190
+ constructor(onChunk) {
191
+ this.onChunk = onChunk;
192
+ }
193
+ /** Feed a token from the LLM stream */
194
+ addToken(token) {
195
+ this.buffer += token;
196
+ // Emit complete lines
197
+ while (this.buffer.includes("\n")) {
198
+ const newlineIdx = this.buffer.indexOf("\n");
199
+ const line = this.buffer.substring(0, newlineIdx);
200
+ this.buffer = this.buffer.substring(newlineIdx + 1);
201
+ this.emitLine(line);
202
+ }
203
+ }
204
+ /** Flush any remaining content */
205
+ flush() {
206
+ if (this.buffer.length > 0) {
207
+ this.emitLine(this.buffer);
208
+ this.buffer = "";
209
+ }
210
+ }
211
+ emitLine(line) {
212
+ if (line.startsWith("---") || line.startsWith("+++")) {
213
+ this.onChunk({ type: "file-header", content: line });
214
+ }
215
+ else if (line.startsWith("@@")) {
216
+ this.onChunk({ type: "hunk-header", content: line });
217
+ }
218
+ else if (line.startsWith("+")) {
219
+ this.onChunk({ type: "add", content: line, lineNumber: this.lineNumber++ });
220
+ }
221
+ else if (line.startsWith("-")) {
222
+ this.onChunk({ type: "remove", content: line, lineNumber: this.lineNumber++ });
223
+ }
224
+ else {
225
+ this.onChunk({ type: "context", content: line, lineNumber: this.lineNumber++ });
226
+ }
227
+ }
228
+ }
229
+ exports.StreamingDiffAccumulator = StreamingDiffAccumulator;
230
+ //# sourceMappingURL=streaming-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"streaming-diff.js","sourceRoot":"","sources":["../../src/utils/streaming-diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,47 @@
1
+ /**
2
+ * Todo/Task Manager
3
+ *
4
+ * Allows the LLM to create, update, and track tasks during a session.
5
+ * Tasks have a status: pending, in_progress, completed, or blocked.
6
+ */
7
+ export type TodoStatus = "pending" | "in_progress" | "completed" | "blocked";
8
+ export interface TodoItem {
9
+ id: string;
10
+ subject: string;
11
+ description?: string;
12
+ status: TodoStatus;
13
+ createdAt: number;
14
+ updatedAt: number;
15
+ blockedBy?: string[];
16
+ }
17
+ export declare class TodoStore {
18
+ private todos;
19
+ private nextId;
20
+ /** Create a new todo item */
21
+ create(subject: string, description?: string): TodoItem;
22
+ /** Get a todo by ID */
23
+ get(id: string): TodoItem | undefined;
24
+ /** Update a todo's status */
25
+ updateStatus(id: string, status: TodoStatus): TodoItem | undefined;
26
+ /** Update a todo's details */
27
+ update(id: string, updates: Partial<Pick<TodoItem, "subject" | "description" | "status" | "blockedBy">>): TodoItem | undefined;
28
+ /** Delete a todo */
29
+ delete(id: string): boolean;
30
+ /** Get all todos */
31
+ getAll(): TodoItem[];
32
+ /** Get todos by status */
33
+ getByStatus(status: TodoStatus): TodoItem[];
34
+ /** Get summary counts */
35
+ getSummary(): {
36
+ pending: number;
37
+ in_progress: number;
38
+ completed: number;
39
+ blocked: number;
40
+ total: number;
41
+ };
42
+ /** Clear all todos */
43
+ clear(): void;
44
+ /** Check if there are any active (non-completed) todos */
45
+ hasActiveTodos(): boolean;
46
+ }
47
+ //# sourceMappingURL=todo.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo.d.ts","sourceRoot":"","sources":["../../src/utils/todo.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,MAAM,UAAU,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,GAAG,SAAS,CAAC;AAE7E,MAAM,WAAW,QAAQ;IACvB,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,UAAU,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,qBAAa,SAAS;IACpB,OAAO,CAAC,KAAK,CAAoC;IACjD,OAAO,CAAC,MAAM,CAAK;IAEnB,6BAA6B;IAC7B,MAAM,CAAC,OAAO,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM,GAAG,QAAQ;IAcvD,uBAAuB;IACvB,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,QAAQ,GAAG,SAAS;IAIrC,6BAA6B;IAC7B,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,GAAG,QAAQ,GAAG,SAAS;IASlE,8BAA8B;IAC9B,MAAM,CAAC,EAAE,EAAE,MAAM,EAAE,OAAO,EAAE,OAAO,CAAC,IAAI,CAAC,QAAQ,EAAE,SAAS,GAAG,aAAa,GAAG,QAAQ,GAAG,WAAW,CAAC,CAAC,GAAG,QAAQ,GAAG,SAAS;IAY9H,oBAAoB;IACpB,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO;IAI3B,oBAAoB;IACpB,MAAM,IAAI,QAAQ,EAAE;IAepB,0BAA0B;IAC1B,WAAW,CAAC,MAAM,EAAE,UAAU,GAAG,QAAQ,EAAE;IAI3C,yBAAyB;IACzB,UAAU,IAAI;QAAE,OAAO,EAAE,MAAM,CAAC;QAAC,WAAW,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE;IAWzG,sBAAsB;IACtB,KAAK,IAAI,IAAI;IAKb,0DAA0D;IAC1D,cAAc,IAAI,OAAO;CAG1B"}
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ /**
3
+ * Todo/Task Manager
4
+ *
5
+ * Allows the LLM to create, update, and track tasks during a session.
6
+ * Tasks have a status: pending, in_progress, completed, or blocked.
7
+ */
8
+ Object.defineProperty(exports, "__esModule", { value: true });
9
+ exports.TodoStore = void 0;
10
+ class TodoStore {
11
+ todos = new Map();
12
+ nextId = 1;
13
+ /** Create a new todo item */
14
+ create(subject, description) {
15
+ const id = String(this.nextId++);
16
+ const todo = {
17
+ id,
18
+ subject,
19
+ description,
20
+ status: "pending",
21
+ createdAt: Date.now(),
22
+ updatedAt: Date.now(),
23
+ };
24
+ this.todos.set(id, todo);
25
+ return todo;
26
+ }
27
+ /** Get a todo by ID */
28
+ get(id) {
29
+ return this.todos.get(id);
30
+ }
31
+ /** Update a todo's status */
32
+ updateStatus(id, status) {
33
+ const todo = this.todos.get(id);
34
+ if (todo) {
35
+ todo.status = status;
36
+ todo.updatedAt = Date.now();
37
+ }
38
+ return todo;
39
+ }
40
+ /** Update a todo's details */
41
+ update(id, updates) {
42
+ const todo = this.todos.get(id);
43
+ if (todo) {
44
+ if (updates.subject !== undefined)
45
+ todo.subject = updates.subject;
46
+ if (updates.description !== undefined)
47
+ todo.description = updates.description;
48
+ if (updates.status !== undefined)
49
+ todo.status = updates.status;
50
+ if (updates.blockedBy !== undefined)
51
+ todo.blockedBy = updates.blockedBy;
52
+ todo.updatedAt = Date.now();
53
+ }
54
+ return todo;
55
+ }
56
+ /** Delete a todo */
57
+ delete(id) {
58
+ return this.todos.delete(id);
59
+ }
60
+ /** Get all todos */
61
+ getAll() {
62
+ return Array.from(this.todos.values()).sort((a, b) => {
63
+ // Sort by status priority: in_progress > pending > blocked > completed
64
+ const statusOrder = {
65
+ in_progress: 0,
66
+ pending: 1,
67
+ blocked: 2,
68
+ completed: 3,
69
+ };
70
+ const statusDiff = statusOrder[a.status] - statusOrder[b.status];
71
+ if (statusDiff !== 0)
72
+ return statusDiff;
73
+ return a.createdAt - b.createdAt;
74
+ });
75
+ }
76
+ /** Get todos by status */
77
+ getByStatus(status) {
78
+ return this.getAll().filter(t => t.status === status);
79
+ }
80
+ /** Get summary counts */
81
+ getSummary() {
82
+ const todos = this.getAll();
83
+ return {
84
+ pending: todos.filter(t => t.status === "pending").length,
85
+ in_progress: todos.filter(t => t.status === "in_progress").length,
86
+ completed: todos.filter(t => t.status === "completed").length,
87
+ blocked: todos.filter(t => t.status === "blocked").length,
88
+ total: todos.length,
89
+ };
90
+ }
91
+ /** Clear all todos */
92
+ clear() {
93
+ this.todos.clear();
94
+ this.nextId = 1;
95
+ }
96
+ /** Check if there are any active (non-completed) todos */
97
+ hasActiveTodos() {
98
+ return this.getAll().some(t => t.status !== "completed");
99
+ }
100
+ }
101
+ exports.TodoStore = TodoStore;
102
+ //# sourceMappingURL=todo.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"todo.js","sourceRoot":"","sources":["../../src/utils/todo.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,23 @@
1
+ {
2
+ "name": "@cdoing/core",
3
+ "version": "0.1.0",
4
+ "main": "dist/index.js",
5
+ "types": "dist/index.d.ts",
6
+ "scripts": {
7
+ "build": "tsc",
8
+ "dev": "tsc --watch",
9
+ "clean": "rm -rf dist"
10
+ },
11
+ "dependencies": {
12
+ "better-sqlite3": "^12.8.0",
13
+ "chalk": "^5.4.1",
14
+ "glob": "^11.0.1",
15
+ "minimatch": "^9.0.4"
16
+ },
17
+ "devDependencies": {
18
+ "@types/better-sqlite3": "^7.6.13",
19
+ "@types/minimatch": "^5.1.2",
20
+ "@types/node": "^22.13.10",
21
+ "typescript": "^5.8.2"
22
+ }
23
+ }
@@ -0,0 +1,240 @@
1
+ /**
2
+ * Multi-Agent Coordinator — Orchestrates multiple sub-agents for complex tasks.
3
+ *
4
+ * The coordinator pattern splits complex tasks into subtasks, assigns each
5
+ * to a specialized sub-agent, and merges results.
6
+ *
7
+ * Architecture:
8
+ * User Request
9
+ * │
10
+ * ┌───▼───┐
11
+ * │Coordinator│ ← Breaks task into subtasks
12
+ * └───┬───┘
13
+ * │
14
+ * ┌───┼───┬───┐
15
+ * │ │ │ │
16
+ * ▼ ▼ ▼ ▼
17
+ * Agent Agent Agent Agent ← Run in parallel
18
+ * │ │ │ │
19
+ * └───┼───┴───┘
20
+ * │
21
+ * ┌───▼───┐
22
+ * │ Merge │ ← Combine results
23
+ * └───────┘
24
+ *
25
+ * Learning note: This is the Scatter-Gather pattern. The coordinator
26
+ * "scatters" work to sub-agents and "gathers" their results. This is
27
+ * particularly effective for:
28
+ * - Searching across many files simultaneously
29
+ * - Making independent changes to different files
30
+ * - Running analysis tasks that don't depend on each other
31
+ */
32
+
33
+ /**
34
+ * A subtask assigned to a sub-agent.
35
+ */
36
+ export interface Subtask {
37
+ /** Unique subtask ID */
38
+ id: string;
39
+
40
+ /** Description of what this subtask should accomplish */
41
+ description: string;
42
+
43
+ /** System prompt override for this subtask's agent */
44
+ systemPrompt?: string;
45
+
46
+ /** Whether this subtask can run in parallel with others */
47
+ parallel: boolean;
48
+
49
+ /** Dependencies: IDs of subtasks that must complete first */
50
+ dependsOn: string[];
51
+
52
+ /** Current status */
53
+ status: "pending" | "running" | "completed" | "failed";
54
+
55
+ /** Result of the subtask (populated after completion) */
56
+ result?: string;
57
+
58
+ /** Error message if the subtask failed */
59
+ error?: string;
60
+ }
61
+
62
+ /**
63
+ * Callback interface for coordinator events.
64
+ */
65
+ export interface CoordinatorCallbacks {
66
+ /** Called when a subtask starts */
67
+ onSubtaskStart: (subtask: Subtask) => void;
68
+
69
+ /** Called when a subtask completes */
70
+ onSubtaskComplete: (subtask: Subtask) => void;
71
+
72
+ /** Called when a subtask fails */
73
+ onSubtaskError: (subtask: Subtask, error: Error) => void;
74
+
75
+ /** Called when all subtasks are complete */
76
+ onAllComplete: (results: Subtask[]) => void;
77
+ }
78
+
79
+ /**
80
+ * The function signature for running a sub-agent.
81
+ * This is provided by the AgentRunner — we don't import it directly
82
+ * to avoid circular dependencies between core and ai packages.
83
+ */
84
+ export type SubAgentRunner = (prompt: string, systemPrompt?: string) => Promise<string>;
85
+
86
+ export class AgentCoordinator {
87
+ private subtasks: Subtask[] = [];
88
+ private runAgent: SubAgentRunner;
89
+
90
+ constructor(runAgent: SubAgentRunner) {
91
+ this.runAgent = runAgent;
92
+ }
93
+
94
+ /**
95
+ * Add a subtask to the coordinator.
96
+ */
97
+ addSubtask(
98
+ description: string,
99
+ options?: {
100
+ systemPrompt?: string;
101
+ parallel?: boolean;
102
+ dependsOn?: string[];
103
+ },
104
+ ): Subtask {
105
+ const subtask: Subtask = {
106
+ id: `subtask_${this.subtasks.length + 1}`,
107
+ description,
108
+ systemPrompt: options?.systemPrompt,
109
+ parallel: options?.parallel ?? true,
110
+ dependsOn: options?.dependsOn || [],
111
+ status: "pending",
112
+ };
113
+
114
+ this.subtasks.push(subtask);
115
+ return subtask;
116
+ }
117
+
118
+ /**
119
+ * Execute all subtasks respecting dependencies and parallelism.
120
+ *
121
+ * Algorithm:
122
+ * 1. Find all subtasks whose dependencies are met
123
+ * 2. Run parallel-safe ones concurrently
124
+ * 3. Run sequential ones in order
125
+ * 4. Repeat until all done
126
+ *
127
+ * Learning note: This is a topological sort execution — we process
128
+ * subtasks in dependency order, maximizing parallelism where possible.
129
+ */
130
+ async execute(callbacks?: Partial<CoordinatorCallbacks>): Promise<Subtask[]> {
131
+ const completed = new Set<string>();
132
+
133
+ while (completed.size < this.subtasks.length) {
134
+ // Find ready subtasks (all dependencies met)
135
+ const ready = this.subtasks.filter(
136
+ (t) =>
137
+ t.status === "pending" &&
138
+ t.dependsOn.every((dep) => completed.has(dep)),
139
+ );
140
+
141
+ if (ready.length === 0) {
142
+ // No ready tasks but not all complete — there's a dependency cycle
143
+ const stuck = this.subtasks.filter((t) => t.status === "pending");
144
+ for (const t of stuck) {
145
+ t.status = "failed";
146
+ t.error = "Dependency cycle detected";
147
+ }
148
+ break;
149
+ }
150
+
151
+ // Separate parallel and sequential tasks
152
+ const parallelTasks = ready.filter((t) => t.parallel);
153
+ const sequentialTasks = ready.filter((t) => !t.parallel);
154
+
155
+ // Run parallel tasks concurrently
156
+ if (parallelTasks.length > 0) {
157
+ await Promise.all(
158
+ parallelTasks.map((task) => this.runSubtask(task, callbacks)),
159
+ );
160
+
161
+ for (const task of parallelTasks) {
162
+ if (task.status === "completed") {
163
+ completed.add(task.id);
164
+ }
165
+ }
166
+ }
167
+
168
+ // Run sequential tasks one at a time
169
+ for (const task of sequentialTasks) {
170
+ await this.runSubtask(task, callbacks);
171
+ if (task.status === "completed") {
172
+ completed.add(task.id);
173
+ }
174
+ }
175
+ }
176
+
177
+ callbacks?.onAllComplete?.(this.subtasks);
178
+ return this.subtasks;
179
+ }
180
+
181
+ /**
182
+ * Run a single subtask using the sub-agent runner.
183
+ */
184
+ private async runSubtask(
185
+ subtask: Subtask,
186
+ callbacks?: Partial<CoordinatorCallbacks>,
187
+ ): Promise<void> {
188
+ subtask.status = "running";
189
+ callbacks?.onSubtaskStart?.(subtask);
190
+
191
+ try {
192
+ const result = await this.runAgent(subtask.description, subtask.systemPrompt);
193
+ subtask.result = result;
194
+ subtask.status = "completed";
195
+ callbacks?.onSubtaskComplete?.(subtask);
196
+ } catch (err) {
197
+ subtask.status = "failed";
198
+ subtask.error = err instanceof Error ? err.message : String(err);
199
+ callbacks?.onSubtaskError?.(subtask, err instanceof Error ? err : new Error(String(err)));
200
+ }
201
+ }
202
+
203
+ /**
204
+ * Get all subtask results as a formatted summary.
205
+ */
206
+ getSummary(): string {
207
+ const lines: string[] = ["## Agent Coordinator Results\n"];
208
+
209
+ for (const task of this.subtasks) {
210
+ const icon = task.status === "completed" ? "✅"
211
+ : task.status === "failed" ? "❌"
212
+ : task.status === "running" ? "⏳"
213
+ : "⬜";
214
+
215
+ lines.push(`${icon} **${task.description}**`);
216
+ if (task.result) {
217
+ lines.push(` ${task.result.substring(0, 200)}`);
218
+ }
219
+ if (task.error) {
220
+ lines.push(` Error: ${task.error}`);
221
+ }
222
+ }
223
+
224
+ return lines.join("\n");
225
+ }
226
+
227
+ /**
228
+ * Get all subtasks.
229
+ */
230
+ getSubtasks(): Subtask[] {
231
+ return [...this.subtasks];
232
+ }
233
+
234
+ /**
235
+ * Clear all subtasks.
236
+ */
237
+ clear(): void {
238
+ this.subtasks = [];
239
+ }
240
+ }