attocode 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 (488) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/LICENSE +21 -0
  3. package/README.md +164 -0
  4. package/dist/src/adapters.d.ts +83 -0
  5. package/dist/src/adapters.d.ts.map +1 -0
  6. package/dist/src/adapters.js +221 -0
  7. package/dist/src/adapters.js.map +1 -0
  8. package/dist/src/agent-tools/index.d.ts +7 -0
  9. package/dist/src/agent-tools/index.d.ts.map +1 -0
  10. package/dist/src/agent-tools/index.js +8 -0
  11. package/dist/src/agent-tools/index.js.map +1 -0
  12. package/dist/src/agent-tools/lsp-file-tools.d.ts +33 -0
  13. package/dist/src/agent-tools/lsp-file-tools.d.ts.map +1 -0
  14. package/dist/src/agent-tools/lsp-file-tools.js +200 -0
  15. package/dist/src/agent-tools/lsp-file-tools.js.map +1 -0
  16. package/dist/src/agent.d.ts +667 -0
  17. package/dist/src/agent.d.ts.map +1 -0
  18. package/dist/src/agent.js +2824 -0
  19. package/dist/src/agent.js.map +1 -0
  20. package/dist/src/cli.d.ts +36 -0
  21. package/dist/src/cli.d.ts.map +1 -0
  22. package/dist/src/cli.js +176 -0
  23. package/dist/src/cli.js.map +1 -0
  24. package/dist/src/commands/handler.d.ts +22 -0
  25. package/dist/src/commands/handler.d.ts.map +1 -0
  26. package/dist/src/commands/handler.js +1320 -0
  27. package/dist/src/commands/handler.js.map +1 -0
  28. package/dist/src/commands/init.d.ts +7 -0
  29. package/dist/src/commands/init.d.ts.map +1 -0
  30. package/dist/src/commands/init.js +153 -0
  31. package/dist/src/commands/init.js.map +1 -0
  32. package/dist/src/commands/types.d.ts +70 -0
  33. package/dist/src/commands/types.d.ts.map +1 -0
  34. package/dist/src/commands/types.js +8 -0
  35. package/dist/src/commands/types.js.map +1 -0
  36. package/dist/src/config.d.ts +22 -0
  37. package/dist/src/config.d.ts.map +1 -0
  38. package/dist/src/config.js +25 -0
  39. package/dist/src/config.js.map +1 -0
  40. package/dist/src/core/index.d.ts +32 -0
  41. package/dist/src/core/index.d.ts.map +1 -0
  42. package/dist/src/core/index.js +35 -0
  43. package/dist/src/core/index.js.map +1 -0
  44. package/dist/src/core/process-handlers.d.ts +43 -0
  45. package/dist/src/core/process-handlers.d.ts.map +1 -0
  46. package/dist/src/core/process-handlers.js +117 -0
  47. package/dist/src/core/process-handlers.js.map +1 -0
  48. package/dist/src/core/protocol/bridge.d.ts +117 -0
  49. package/dist/src/core/protocol/bridge.d.ts.map +1 -0
  50. package/dist/src/core/protocol/bridge.js +149 -0
  51. package/dist/src/core/protocol/bridge.js.map +1 -0
  52. package/dist/src/core/protocol/index.d.ts +8 -0
  53. package/dist/src/core/protocol/index.d.ts.map +1 -0
  54. package/dist/src/core/protocol/index.js +8 -0
  55. package/dist/src/core/protocol/index.js.map +1 -0
  56. package/dist/src/core/protocol/types.d.ts +539 -0
  57. package/dist/src/core/protocol/types.d.ts.map +1 -0
  58. package/dist/src/core/protocol/types.js +149 -0
  59. package/dist/src/core/protocol/types.js.map +1 -0
  60. package/dist/src/core/queues/atomic-counter.d.ts +36 -0
  61. package/dist/src/core/queues/atomic-counter.d.ts.map +1 -0
  62. package/dist/src/core/queues/atomic-counter.js +46 -0
  63. package/dist/src/core/queues/atomic-counter.js.map +1 -0
  64. package/dist/src/core/queues/event-queue.d.ts +126 -0
  65. package/dist/src/core/queues/event-queue.d.ts.map +1 -0
  66. package/dist/src/core/queues/event-queue.js +208 -0
  67. package/dist/src/core/queues/event-queue.js.map +1 -0
  68. package/dist/src/core/queues/index.d.ts +12 -0
  69. package/dist/src/core/queues/index.d.ts.map +1 -0
  70. package/dist/src/core/queues/index.js +15 -0
  71. package/dist/src/core/queues/index.js.map +1 -0
  72. package/dist/src/core/queues/submission-queue.d.ts +116 -0
  73. package/dist/src/core/queues/submission-queue.d.ts.map +1 -0
  74. package/dist/src/core/queues/submission-queue.js +236 -0
  75. package/dist/src/core/queues/submission-queue.js.map +1 -0
  76. package/dist/src/costs/index.d.ts +22 -0
  77. package/dist/src/costs/index.d.ts.map +1 -0
  78. package/dist/src/costs/index.js +22 -0
  79. package/dist/src/costs/index.js.map +1 -0
  80. package/dist/src/costs/model-registry.d.ts +80 -0
  81. package/dist/src/costs/model-registry.d.ts.map +1 -0
  82. package/dist/src/costs/model-registry.js +237 -0
  83. package/dist/src/costs/model-registry.js.map +1 -0
  84. package/dist/src/costs/types.d.ts +50 -0
  85. package/dist/src/costs/types.d.ts.map +1 -0
  86. package/dist/src/costs/types.js +2 -0
  87. package/dist/src/costs/types.js.map +1 -0
  88. package/dist/src/defaults.d.ts +114 -0
  89. package/dist/src/defaults.d.ts.map +1 -0
  90. package/dist/src/defaults.js +457 -0
  91. package/dist/src/defaults.js.map +1 -0
  92. package/dist/src/first-run.d.ts +35 -0
  93. package/dist/src/first-run.d.ts.map +1 -0
  94. package/dist/src/first-run.js +94 -0
  95. package/dist/src/first-run.js.map +1 -0
  96. package/dist/src/hello.d.ts +2 -0
  97. package/dist/src/hello.d.ts.map +1 -0
  98. package/dist/src/hello.js +4 -0
  99. package/dist/src/hello.js.map +1 -0
  100. package/dist/src/integrations/agent-registry.d.ts +160 -0
  101. package/dist/src/integrations/agent-registry.d.ts.map +1 -0
  102. package/dist/src/integrations/agent-registry.js +446 -0
  103. package/dist/src/integrations/agent-registry.js.map +1 -0
  104. package/dist/src/integrations/auto-compaction.d.ts +177 -0
  105. package/dist/src/integrations/auto-compaction.d.ts.map +1 -0
  106. package/dist/src/integrations/auto-compaction.js +428 -0
  107. package/dist/src/integrations/auto-compaction.js.map +1 -0
  108. package/dist/src/integrations/cancellation.d.ts +162 -0
  109. package/dist/src/integrations/cancellation.d.ts.map +1 -0
  110. package/dist/src/integrations/cancellation.js +339 -0
  111. package/dist/src/integrations/cancellation.js.map +1 -0
  112. package/dist/src/integrations/codebase-context.d.ts +319 -0
  113. package/dist/src/integrations/codebase-context.d.ts.map +1 -0
  114. package/dist/src/integrations/codebase-context.js +816 -0
  115. package/dist/src/integrations/codebase-context.js.map +1 -0
  116. package/dist/src/integrations/compaction.d.ts +192 -0
  117. package/dist/src/integrations/compaction.d.ts.map +1 -0
  118. package/dist/src/integrations/compaction.js +376 -0
  119. package/dist/src/integrations/compaction.js.map +1 -0
  120. package/dist/src/integrations/context-engineering.d.ts +246 -0
  121. package/dist/src/integrations/context-engineering.d.ts.map +1 -0
  122. package/dist/src/integrations/context-engineering.js +394 -0
  123. package/dist/src/integrations/context-engineering.js.map +1 -0
  124. package/dist/src/integrations/diff-utils.d.ts +105 -0
  125. package/dist/src/integrations/diff-utils.d.ts.map +1 -0
  126. package/dist/src/integrations/diff-utils.js +497 -0
  127. package/dist/src/integrations/diff-utils.js.map +1 -0
  128. package/dist/src/integrations/economics.d.ts +192 -0
  129. package/dist/src/integrations/economics.d.ts.map +1 -0
  130. package/dist/src/integrations/economics.js +431 -0
  131. package/dist/src/integrations/economics.js.map +1 -0
  132. package/dist/src/integrations/execution-policy.d.ts +189 -0
  133. package/dist/src/integrations/execution-policy.d.ts.map +1 -0
  134. package/dist/src/integrations/execution-policy.js +352 -0
  135. package/dist/src/integrations/execution-policy.js.map +1 -0
  136. package/dist/src/integrations/file-change-tracker.d.ts +161 -0
  137. package/dist/src/integrations/file-change-tracker.d.ts.map +1 -0
  138. package/dist/src/integrations/file-change-tracker.js +520 -0
  139. package/dist/src/integrations/file-change-tracker.js.map +1 -0
  140. package/dist/src/integrations/hierarchical-config.d.ts +212 -0
  141. package/dist/src/integrations/hierarchical-config.d.ts.map +1 -0
  142. package/dist/src/integrations/hierarchical-config.js +484 -0
  143. package/dist/src/integrations/hierarchical-config.js.map +1 -0
  144. package/dist/src/integrations/hooks.d.ts +114 -0
  145. package/dist/src/integrations/hooks.d.ts.map +1 -0
  146. package/dist/src/integrations/hooks.js +326 -0
  147. package/dist/src/integrations/hooks.js.map +1 -0
  148. package/dist/src/integrations/ignore.d.ts +143 -0
  149. package/dist/src/integrations/ignore.d.ts.map +1 -0
  150. package/dist/src/integrations/ignore.js +417 -0
  151. package/dist/src/integrations/ignore.js.map +1 -0
  152. package/dist/src/integrations/image-renderer.d.ts +119 -0
  153. package/dist/src/integrations/image-renderer.d.ts.map +1 -0
  154. package/dist/src/integrations/image-renderer.js +306 -0
  155. package/dist/src/integrations/image-renderer.js.map +1 -0
  156. package/dist/src/integrations/index.d.ts +42 -0
  157. package/dist/src/integrations/index.d.ts.map +1 -0
  158. package/dist/src/integrations/index.js +73 -0
  159. package/dist/src/integrations/index.js.map +1 -0
  160. package/dist/src/integrations/lsp.d.ts +196 -0
  161. package/dist/src/integrations/lsp.d.ts.map +1 -0
  162. package/dist/src/integrations/lsp.js +582 -0
  163. package/dist/src/integrations/lsp.js.map +1 -0
  164. package/dist/src/integrations/mcp-client.d.ts +270 -0
  165. package/dist/src/integrations/mcp-client.d.ts.map +1 -0
  166. package/dist/src/integrations/mcp-client.js +698 -0
  167. package/dist/src/integrations/mcp-client.js.map +1 -0
  168. package/dist/src/integrations/mcp-tool-search.d.ts +77 -0
  169. package/dist/src/integrations/mcp-tool-search.d.ts.map +1 -0
  170. package/dist/src/integrations/mcp-tool-search.js +220 -0
  171. package/dist/src/integrations/mcp-tool-search.js.map +1 -0
  172. package/dist/src/integrations/memory.d.ts +108 -0
  173. package/dist/src/integrations/memory.d.ts.map +1 -0
  174. package/dist/src/integrations/memory.js +288 -0
  175. package/dist/src/integrations/memory.js.map +1 -0
  176. package/dist/src/integrations/multi-agent.d.ts +150 -0
  177. package/dist/src/integrations/multi-agent.d.ts.map +1 -0
  178. package/dist/src/integrations/multi-agent.js +306 -0
  179. package/dist/src/integrations/multi-agent.js.map +1 -0
  180. package/dist/src/integrations/observability.d.ts +162 -0
  181. package/dist/src/integrations/observability.d.ts.map +1 -0
  182. package/dist/src/integrations/observability.js +406 -0
  183. package/dist/src/integrations/observability.js.map +1 -0
  184. package/dist/src/integrations/openrouter-pricing.d.ts +42 -0
  185. package/dist/src/integrations/openrouter-pricing.d.ts.map +1 -0
  186. package/dist/src/integrations/openrouter-pricing.js +124 -0
  187. package/dist/src/integrations/openrouter-pricing.js.map +1 -0
  188. package/dist/src/integrations/pending-plan.d.ts +171 -0
  189. package/dist/src/integrations/pending-plan.d.ts.map +1 -0
  190. package/dist/src/integrations/pending-plan.js +244 -0
  191. package/dist/src/integrations/pending-plan.js.map +1 -0
  192. package/dist/src/integrations/persistence.d.ts +48 -0
  193. package/dist/src/integrations/persistence.d.ts.map +1 -0
  194. package/dist/src/integrations/persistence.js +196 -0
  195. package/dist/src/integrations/persistence.js.map +1 -0
  196. package/dist/src/integrations/planning.d.ts +96 -0
  197. package/dist/src/integrations/planning.d.ts.map +1 -0
  198. package/dist/src/integrations/planning.js +338 -0
  199. package/dist/src/integrations/planning.js.map +1 -0
  200. package/dist/src/integrations/pty-shell.d.ts +169 -0
  201. package/dist/src/integrations/pty-shell.d.ts.map +1 -0
  202. package/dist/src/integrations/pty-shell.js +367 -0
  203. package/dist/src/integrations/pty-shell.js.map +1 -0
  204. package/dist/src/integrations/react.d.ts +139 -0
  205. package/dist/src/integrations/react.d.ts.map +1 -0
  206. package/dist/src/integrations/react.js +273 -0
  207. package/dist/src/integrations/react.js.map +1 -0
  208. package/dist/src/integrations/resources.d.ts +177 -0
  209. package/dist/src/integrations/resources.d.ts.map +1 -0
  210. package/dist/src/integrations/resources.js +311 -0
  211. package/dist/src/integrations/resources.js.map +1 -0
  212. package/dist/src/integrations/result-synthesizer.d.ts +389 -0
  213. package/dist/src/integrations/result-synthesizer.d.ts.map +1 -0
  214. package/dist/src/integrations/result-synthesizer.js +951 -0
  215. package/dist/src/integrations/result-synthesizer.js.map +1 -0
  216. package/dist/src/integrations/routing.d.ts +117 -0
  217. package/dist/src/integrations/routing.d.ts.map +1 -0
  218. package/dist/src/integrations/routing.js +347 -0
  219. package/dist/src/integrations/routing.js.map +1 -0
  220. package/dist/src/integrations/rules.d.ts +131 -0
  221. package/dist/src/integrations/rules.d.ts.map +1 -0
  222. package/dist/src/integrations/rules.js +284 -0
  223. package/dist/src/integrations/rules.js.map +1 -0
  224. package/dist/src/integrations/safety.d.ts +142 -0
  225. package/dist/src/integrations/safety.d.ts.map +1 -0
  226. package/dist/src/integrations/safety.js +342 -0
  227. package/dist/src/integrations/safety.js.map +1 -0
  228. package/dist/src/integrations/sandbox/basic.d.ts +74 -0
  229. package/dist/src/integrations/sandbox/basic.d.ts.map +1 -0
  230. package/dist/src/integrations/sandbox/basic.js +310 -0
  231. package/dist/src/integrations/sandbox/basic.js.map +1 -0
  232. package/dist/src/integrations/sandbox/docker.d.ts +94 -0
  233. package/dist/src/integrations/sandbox/docker.d.ts.map +1 -0
  234. package/dist/src/integrations/sandbox/docker.js +293 -0
  235. package/dist/src/integrations/sandbox/docker.js.map +1 -0
  236. package/dist/src/integrations/sandbox/index.d.ts +182 -0
  237. package/dist/src/integrations/sandbox/index.d.ts.map +1 -0
  238. package/dist/src/integrations/sandbox/index.js +382 -0
  239. package/dist/src/integrations/sandbox/index.js.map +1 -0
  240. package/dist/src/integrations/sandbox/landlock.d.ts +59 -0
  241. package/dist/src/integrations/sandbox/landlock.d.ts.map +1 -0
  242. package/dist/src/integrations/sandbox/landlock.js +326 -0
  243. package/dist/src/integrations/sandbox/landlock.js.map +1 -0
  244. package/dist/src/integrations/sandbox/seatbelt.d.ts +68 -0
  245. package/dist/src/integrations/sandbox/seatbelt.d.ts.map +1 -0
  246. package/dist/src/integrations/sandbox/seatbelt.js +298 -0
  247. package/dist/src/integrations/sandbox/seatbelt.js.map +1 -0
  248. package/dist/src/integrations/semantic-cache.d.ts +178 -0
  249. package/dist/src/integrations/semantic-cache.d.ts.map +1 -0
  250. package/dist/src/integrations/semantic-cache.js +372 -0
  251. package/dist/src/integrations/semantic-cache.js.map +1 -0
  252. package/dist/src/integrations/session-store.d.ts +183 -0
  253. package/dist/src/integrations/session-store.d.ts.map +1 -0
  254. package/dist/src/integrations/session-store.js +345 -0
  255. package/dist/src/integrations/session-store.js.map +1 -0
  256. package/dist/src/integrations/shared-blackboard.d.ts +403 -0
  257. package/dist/src/integrations/shared-blackboard.d.ts.map +1 -0
  258. package/dist/src/integrations/shared-blackboard.js +710 -0
  259. package/dist/src/integrations/shared-blackboard.js.map +1 -0
  260. package/dist/src/integrations/skills.d.ts +171 -0
  261. package/dist/src/integrations/skills.d.ts.map +1 -0
  262. package/dist/src/integrations/skills.js +403 -0
  263. package/dist/src/integrations/skills.js.map +1 -0
  264. package/dist/src/integrations/smart-decomposer.d.ts +322 -0
  265. package/dist/src/integrations/smart-decomposer.d.ts.map +1 -0
  266. package/dist/src/integrations/smart-decomposer.js +856 -0
  267. package/dist/src/integrations/smart-decomposer.js.map +1 -0
  268. package/dist/src/integrations/sourcegraph.d.ts +169 -0
  269. package/dist/src/integrations/sourcegraph.d.ts.map +1 -0
  270. package/dist/src/integrations/sourcegraph.js +379 -0
  271. package/dist/src/integrations/sourcegraph.js.map +1 -0
  272. package/dist/src/integrations/sqlite-store.d.ts +518 -0
  273. package/dist/src/integrations/sqlite-store.d.ts.map +1 -0
  274. package/dist/src/integrations/sqlite-store.js +1423 -0
  275. package/dist/src/integrations/sqlite-store.js.map +1 -0
  276. package/dist/src/integrations/streaming.d.ts +102 -0
  277. package/dist/src/integrations/streaming.d.ts.map +1 -0
  278. package/dist/src/integrations/streaming.js +362 -0
  279. package/dist/src/integrations/streaming.js.map +1 -0
  280. package/dist/src/integrations/thread-manager.d.ts +199 -0
  281. package/dist/src/integrations/thread-manager.d.ts.map +1 -0
  282. package/dist/src/integrations/thread-manager.js +357 -0
  283. package/dist/src/integrations/thread-manager.js.map +1 -0
  284. package/dist/src/main.d.ts +26 -0
  285. package/dist/src/main.d.ts.map +1 -0
  286. package/dist/src/main.js +170 -0
  287. package/dist/src/main.js.map +1 -0
  288. package/dist/src/modes/index.d.ts +10 -0
  289. package/dist/src/modes/index.d.ts.map +1 -0
  290. package/dist/src/modes/index.js +10 -0
  291. package/dist/src/modes/index.js.map +1 -0
  292. package/dist/src/modes/repl.d.ts +19 -0
  293. package/dist/src/modes/repl.d.ts.map +1 -0
  294. package/dist/src/modes/repl.js +393 -0
  295. package/dist/src/modes/repl.js.map +1 -0
  296. package/dist/src/modes/tui.d.ts +29 -0
  297. package/dist/src/modes/tui.d.ts.map +1 -0
  298. package/dist/src/modes/tui.js +272 -0
  299. package/dist/src/modes/tui.js.map +1 -0
  300. package/dist/src/modes.d.ts +179 -0
  301. package/dist/src/modes.d.ts.map +1 -0
  302. package/dist/src/modes.js +385 -0
  303. package/dist/src/modes.js.map +1 -0
  304. package/dist/src/observability/tracer.d.ts +111 -0
  305. package/dist/src/observability/tracer.d.ts.map +1 -0
  306. package/dist/src/observability/tracer.js +300 -0
  307. package/dist/src/observability/tracer.js.map +1 -0
  308. package/dist/src/observability/types.d.ts +271 -0
  309. package/dist/src/observability/types.d.ts.map +1 -0
  310. package/dist/src/observability/types.js +24 -0
  311. package/dist/src/observability/types.js.map +1 -0
  312. package/dist/src/paths.d.ts +101 -0
  313. package/dist/src/paths.d.ts.map +1 -0
  314. package/dist/src/paths.js +148 -0
  315. package/dist/src/paths.js.map +1 -0
  316. package/dist/src/persistence/index.d.ts +38 -0
  317. package/dist/src/persistence/index.d.ts.map +1 -0
  318. package/dist/src/persistence/index.js +48 -0
  319. package/dist/src/persistence/index.js.map +1 -0
  320. package/dist/src/persistence/migrator.d.ts +135 -0
  321. package/dist/src/persistence/migrator.d.ts.map +1 -0
  322. package/dist/src/persistence/migrator.js +303 -0
  323. package/dist/src/persistence/migrator.js.map +1 -0
  324. package/dist/src/persistence/schema.d.ts +101 -0
  325. package/dist/src/persistence/schema.d.ts.map +1 -0
  326. package/dist/src/persistence/schema.js +395 -0
  327. package/dist/src/persistence/schema.js.map +1 -0
  328. package/dist/src/providers/adapters/anthropic.d.ts +20 -0
  329. package/dist/src/providers/adapters/anthropic.d.ts.map +1 -0
  330. package/dist/src/providers/adapters/anthropic.js +124 -0
  331. package/dist/src/providers/adapters/anthropic.js.map +1 -0
  332. package/dist/src/providers/adapters/mock.d.ts +25 -0
  333. package/dist/src/providers/adapters/mock.d.ts.map +1 -0
  334. package/dist/src/providers/adapters/mock.js +133 -0
  335. package/dist/src/providers/adapters/mock.js.map +1 -0
  336. package/dist/src/providers/adapters/openai.d.ts +21 -0
  337. package/dist/src/providers/adapters/openai.d.ts.map +1 -0
  338. package/dist/src/providers/adapters/openai.js +126 -0
  339. package/dist/src/providers/adapters/openai.js.map +1 -0
  340. package/dist/src/providers/adapters/openrouter.d.ts +49 -0
  341. package/dist/src/providers/adapters/openrouter.d.ts.map +1 -0
  342. package/dist/src/providers/adapters/openrouter.js +363 -0
  343. package/dist/src/providers/adapters/openrouter.js.map +1 -0
  344. package/dist/src/providers/provider.d.ts +54 -0
  345. package/dist/src/providers/provider.d.ts.map +1 -0
  346. package/dist/src/providers/provider.js +111 -0
  347. package/dist/src/providers/provider.js.map +1 -0
  348. package/dist/src/providers/resilient-fetch.d.ts +99 -0
  349. package/dist/src/providers/resilient-fetch.d.ts.map +1 -0
  350. package/dist/src/providers/resilient-fetch.js +208 -0
  351. package/dist/src/providers/resilient-fetch.js.map +1 -0
  352. package/dist/src/providers/types.d.ts +227 -0
  353. package/dist/src/providers/types.d.ts.map +1 -0
  354. package/dist/src/providers/types.js +24 -0
  355. package/dist/src/providers/types.js.map +1 -0
  356. package/dist/src/session-picker.d.ts +28 -0
  357. package/dist/src/session-picker.d.ts.map +1 -0
  358. package/dist/src/session-picker.js +256 -0
  359. package/dist/src/session-picker.js.map +1 -0
  360. package/dist/src/test-sqlite.d.ts +2 -0
  361. package/dist/src/test-sqlite.d.ts.map +1 -0
  362. package/dist/src/test-sqlite.js +114 -0
  363. package/dist/src/test-sqlite.js.map +1 -0
  364. package/dist/src/tools/agent.d.ts +44 -0
  365. package/dist/src/tools/agent.d.ts.map +1 -0
  366. package/dist/src/tools/agent.js +110 -0
  367. package/dist/src/tools/agent.js.map +1 -0
  368. package/dist/src/tools/bash.d.ts +52 -0
  369. package/dist/src/tools/bash.d.ts.map +1 -0
  370. package/dist/src/tools/bash.js +141 -0
  371. package/dist/src/tools/bash.js.map +1 -0
  372. package/dist/src/tools/file.d.ts +47 -0
  373. package/dist/src/tools/file.d.ts.map +1 -0
  374. package/dist/src/tools/file.js +263 -0
  375. package/dist/src/tools/file.js.map +1 -0
  376. package/dist/src/tools/permission.d.ts +43 -0
  377. package/dist/src/tools/permission.d.ts.map +1 -0
  378. package/dist/src/tools/permission.js +216 -0
  379. package/dist/src/tools/permission.js.map +1 -0
  380. package/dist/src/tools/registry.d.ts +63 -0
  381. package/dist/src/tools/registry.d.ts.map +1 -0
  382. package/dist/src/tools/registry.js +250 -0
  383. package/dist/src/tools/registry.js.map +1 -0
  384. package/dist/src/tools/standard.d.ts +57 -0
  385. package/dist/src/tools/standard.d.ts.map +1 -0
  386. package/dist/src/tools/standard.js +113 -0
  387. package/dist/src/tools/standard.js.map +1 -0
  388. package/dist/src/tools/types.d.ts +146 -0
  389. package/dist/src/tools/types.d.ts.map +1 -0
  390. package/dist/src/tools/types.js +28 -0
  391. package/dist/src/tools/types.js.map +1 -0
  392. package/dist/src/tools/undo.d.ts +71 -0
  393. package/dist/src/tools/undo.d.ts.map +1 -0
  394. package/dist/src/tools/undo.js +123 -0
  395. package/dist/src/tools/undo.js.map +1 -0
  396. package/dist/src/tracing/cache-boundary-tracker.d.ts +189 -0
  397. package/dist/src/tracing/cache-boundary-tracker.d.ts.map +1 -0
  398. package/dist/src/tracing/cache-boundary-tracker.js +411 -0
  399. package/dist/src/tracing/cache-boundary-tracker.js.map +1 -0
  400. package/dist/src/tracing/trace-collector.d.ts +274 -0
  401. package/dist/src/tracing/trace-collector.d.ts.map +1 -0
  402. package/dist/src/tracing/trace-collector.js +727 -0
  403. package/dist/src/tracing/trace-collector.js.map +1 -0
  404. package/dist/src/tracing/types.d.ts +657 -0
  405. package/dist/src/tracing/types.d.ts.map +1 -0
  406. package/dist/src/tracing/types.js +39 -0
  407. package/dist/src/tracing/types.js.map +1 -0
  408. package/dist/src/tricks/failure-evidence.d.ts +268 -0
  409. package/dist/src/tricks/failure-evidence.d.ts.map +1 -0
  410. package/dist/src/tricks/failure-evidence.js +544 -0
  411. package/dist/src/tricks/failure-evidence.js.map +1 -0
  412. package/dist/src/tricks/json-utils.d.ts +77 -0
  413. package/dist/src/tricks/json-utils.d.ts.map +1 -0
  414. package/dist/src/tricks/json-utils.js +247 -0
  415. package/dist/src/tricks/json-utils.js.map +1 -0
  416. package/dist/src/tricks/kv-cache-context.d.ts +227 -0
  417. package/dist/src/tricks/kv-cache-context.d.ts.map +1 -0
  418. package/dist/src/tricks/kv-cache-context.js +377 -0
  419. package/dist/src/tricks/kv-cache-context.js.map +1 -0
  420. package/dist/src/tricks/recitation.d.ts +208 -0
  421. package/dist/src/tricks/recitation.d.ts.map +1 -0
  422. package/dist/src/tricks/recitation.js +374 -0
  423. package/dist/src/tricks/recitation.js.map +1 -0
  424. package/dist/src/tricks/reversible-compaction.d.ts +251 -0
  425. package/dist/src/tricks/reversible-compaction.d.ts.map +1 -0
  426. package/dist/src/tricks/reversible-compaction.js +555 -0
  427. package/dist/src/tricks/reversible-compaction.js.map +1 -0
  428. package/dist/src/tricks/serialization-diversity.d.ts +197 -0
  429. package/dist/src/tricks/serialization-diversity.d.ts.map +1 -0
  430. package/dist/src/tricks/serialization-diversity.js +460 -0
  431. package/dist/src/tricks/serialization-diversity.js.map +1 -0
  432. package/dist/src/tui/app.d.ts +42 -0
  433. package/dist/src/tui/app.d.ts.map +1 -0
  434. package/dist/src/tui/app.js +1076 -0
  435. package/dist/src/tui/app.js.map +1 -0
  436. package/dist/src/tui/components/ApprovalDialog.d.ts +28 -0
  437. package/dist/src/tui/components/ApprovalDialog.d.ts.map +1 -0
  438. package/dist/src/tui/components/ApprovalDialog.js +59 -0
  439. package/dist/src/tui/components/ApprovalDialog.js.map +1 -0
  440. package/dist/src/tui/components/InputArea.d.ts +35 -0
  441. package/dist/src/tui/components/InputArea.d.ts.map +1 -0
  442. package/dist/src/tui/components/InputArea.js +144 -0
  443. package/dist/src/tui/components/InputArea.js.map +1 -0
  444. package/dist/src/tui/components/MessageItem.d.ts +28 -0
  445. package/dist/src/tui/components/MessageItem.d.ts.map +1 -0
  446. package/dist/src/tui/components/MessageItem.js +27 -0
  447. package/dist/src/tui/components/MessageItem.js.map +1 -0
  448. package/dist/src/tui/components/ScrollableBox.d.ts +41 -0
  449. package/dist/src/tui/components/ScrollableBox.d.ts.map +1 -0
  450. package/dist/src/tui/components/ScrollableBox.js +101 -0
  451. package/dist/src/tui/components/ScrollableBox.js.map +1 -0
  452. package/dist/src/tui/components/ToolCallItem.d.ts +33 -0
  453. package/dist/src/tui/components/ToolCallItem.d.ts.map +1 -0
  454. package/dist/src/tui/components/ToolCallItem.js +91 -0
  455. package/dist/src/tui/components/ToolCallItem.js.map +1 -0
  456. package/dist/src/tui/components/index.d.ts +13 -0
  457. package/dist/src/tui/components/index.d.ts.map +1 -0
  458. package/dist/src/tui/components/index.js +15 -0
  459. package/dist/src/tui/components/index.js.map +1 -0
  460. package/dist/src/tui/event-display.d.ts +19 -0
  461. package/dist/src/tui/event-display.d.ts.map +1 -0
  462. package/dist/src/tui/event-display.js +178 -0
  463. package/dist/src/tui/event-display.js.map +1 -0
  464. package/dist/src/tui/index.d.ts +105 -0
  465. package/dist/src/tui/index.d.ts.map +1 -0
  466. package/dist/src/tui/index.js +214 -0
  467. package/dist/src/tui/index.js.map +1 -0
  468. package/dist/src/tui/input/CommandPalette.d.ts +55 -0
  469. package/dist/src/tui/input/CommandPalette.d.ts.map +1 -0
  470. package/dist/src/tui/input/CommandPalette.js +135 -0
  471. package/dist/src/tui/input/CommandPalette.js.map +1 -0
  472. package/dist/src/tui/input/index.d.ts +7 -0
  473. package/dist/src/tui/input/index.d.ts.map +1 -0
  474. package/dist/src/tui/input/index.js +7 -0
  475. package/dist/src/tui/input/index.js.map +1 -0
  476. package/dist/src/tui/theme/index.d.ts +45 -0
  477. package/dist/src/tui/theme/index.d.ts.map +1 -0
  478. package/dist/src/tui/theme/index.js +215 -0
  479. package/dist/src/tui/theme/index.js.map +1 -0
  480. package/dist/src/tui/types.d.ts +214 -0
  481. package/dist/src/tui/types.d.ts.map +1 -0
  482. package/dist/src/tui/types.js +27 -0
  483. package/dist/src/tui/types.js.map +1 -0
  484. package/dist/src/types.d.ts +905 -0
  485. package/dist/src/types.d.ts.map +1 -0
  486. package/dist/src/types.js +9 -0
  487. package/dist/src/types.js.map +1 -0
  488. package/package.json +89 -0
@@ -0,0 +1,698 @@
1
+ /**
2
+ * Lesson 25: MCP Client
3
+ *
4
+ * Connects to Model Context Protocol (MCP) servers to extend agent capabilities.
5
+ * Supports stdio-based servers (spawned as child processes).
6
+ */
7
+ import { spawn } from 'node:child_process';
8
+ import { readFile } from 'node:fs/promises';
9
+ import { existsSync } from 'node:fs';
10
+ import { createInterface } from 'node:readline';
11
+ // =============================================================================
12
+ // MCP CLIENT
13
+ // =============================================================================
14
+ /**
15
+ * MCP Client manages connections to MCP servers.
16
+ */
17
+ export class MCPClient {
18
+ config;
19
+ servers = new Map();
20
+ listeners = [];
21
+ constructor(config = {}) {
22
+ this.config = {
23
+ configPath: config.configPath || '.mcp.json',
24
+ configPaths: config.configPaths ?? [],
25
+ requestTimeout: config.requestTimeout ?? 30000,
26
+ autoConnect: config.autoConnect ?? true,
27
+ lazyLoading: config.lazyLoading ?? false,
28
+ alwaysLoadTools: config.alwaysLoadTools ?? [],
29
+ summaryDescriptionLimit: config.summaryDescriptionLimit ?? 100,
30
+ maxToolsPerSearch: config.maxToolsPerSearch ?? 5,
31
+ };
32
+ }
33
+ /**
34
+ * Load servers from config file.
35
+ */
36
+ async loadFromConfig(configPath) {
37
+ const path = configPath || this.config.configPath;
38
+ if (!existsSync(path)) {
39
+ return; // No config file, silently skip
40
+ }
41
+ try {
42
+ const content = await readFile(path, 'utf-8');
43
+ const mcpConfig = JSON.parse(content);
44
+ for (const [name, serverConfig] of Object.entries(mcpConfig.servers)) {
45
+ // Expand environment variables in config
46
+ const expandedConfig = this.expandEnvVars(serverConfig);
47
+ this.registerServer(name, expandedConfig);
48
+ if (this.config.autoConnect) {
49
+ await this.connectServer(name).catch(err => {
50
+ console.warn(`[MCP] Failed to connect to ${name}:`, err.message);
51
+ });
52
+ }
53
+ }
54
+ }
55
+ catch (err) {
56
+ console.warn(`[MCP] Failed to load config from ${path}:`, err);
57
+ }
58
+ }
59
+ /**
60
+ * Load servers from multiple config files (hierarchical).
61
+ * Later configs override earlier ones for the same server name.
62
+ * Servers from all configs are merged together.
63
+ */
64
+ async loadFromHierarchicalConfigs(configPaths) {
65
+ const mergedServers = {};
66
+ // Load and merge all configs
67
+ for (const configPath of configPaths) {
68
+ if (!existsSync(configPath)) {
69
+ continue;
70
+ }
71
+ try {
72
+ const content = await readFile(configPath, 'utf-8');
73
+ const mcpConfig = JSON.parse(content);
74
+ // Merge servers (later overrides earlier)
75
+ for (const [name, serverConfig] of Object.entries(mcpConfig.servers)) {
76
+ mergedServers[name] = this.expandEnvVars(serverConfig);
77
+ }
78
+ }
79
+ catch (err) {
80
+ console.warn(`[MCP] Failed to load config from ${configPath}:`, err);
81
+ }
82
+ }
83
+ // Register all merged servers
84
+ for (const [name, config] of Object.entries(mergedServers)) {
85
+ this.registerServer(name, config);
86
+ if (this.config.autoConnect) {
87
+ await this.connectServer(name).catch(err => {
88
+ console.warn(`[MCP] Failed to connect to ${name}:`, err.message);
89
+ });
90
+ }
91
+ }
92
+ }
93
+ /**
94
+ * Expand environment variables in config.
95
+ */
96
+ expandEnvVars(config) {
97
+ const expand = (str) => {
98
+ return str.replace(/\$\{(\w+)\}/g, (_, name) => process.env[name] || '');
99
+ };
100
+ return {
101
+ command: expand(config.command),
102
+ args: config.args?.map(expand),
103
+ env: config.env
104
+ ? Object.fromEntries(Object.entries(config.env).map(([k, v]) => [k, expand(v)]))
105
+ : undefined,
106
+ cwd: config.cwd ? expand(config.cwd) : undefined,
107
+ };
108
+ }
109
+ /**
110
+ * Register a server (without connecting).
111
+ */
112
+ registerServer(name, config) {
113
+ this.servers.set(name, {
114
+ name,
115
+ config,
116
+ process: null,
117
+ readline: null,
118
+ tools: [],
119
+ status: 'disconnected',
120
+ pendingRequests: new Map(),
121
+ nextRequestId: 1,
122
+ loadedTools: new Set(),
123
+ });
124
+ }
125
+ /**
126
+ * Connect to a registered server.
127
+ */
128
+ async connectServer(name) {
129
+ const server = this.servers.get(name);
130
+ if (!server) {
131
+ throw new Error(`Server not registered: ${name}`);
132
+ }
133
+ if (server.status === 'connected') {
134
+ return; // Already connected
135
+ }
136
+ server.status = 'connecting';
137
+ this.emit({ type: 'server.connecting', name });
138
+ try {
139
+ // Spawn the server process
140
+ const proc = spawn(server.config.command, server.config.args || [], {
141
+ env: { ...process.env, ...server.config.env },
142
+ cwd: server.config.cwd,
143
+ stdio: ['pipe', 'pipe', 'pipe'],
144
+ });
145
+ server.process = proc;
146
+ // Set up readline for stdout
147
+ server.readline = createInterface({
148
+ input: proc.stdout,
149
+ crlfDelay: Infinity,
150
+ });
151
+ // Handle incoming messages
152
+ server.readline.on('line', (line) => {
153
+ this.handleServerMessage(server, line);
154
+ });
155
+ // Handle errors
156
+ proc.stderr?.on('data', (data) => {
157
+ console.error(`[MCP ${name}] stderr:`, data.toString());
158
+ });
159
+ proc.on('error', (err) => {
160
+ server.status = 'error';
161
+ server.error = err.message;
162
+ // CRITICAL: Reject ALL pending requests before clearing
163
+ const errorMsg = new Error(`MCP server "${name}" process error: ${err.message}`);
164
+ for (const [_id, pending] of server.pendingRequests) {
165
+ pending.reject(errorMsg);
166
+ }
167
+ server.pendingRequests.clear();
168
+ this.emit({ type: 'server.error', name, error: err.message });
169
+ });
170
+ proc.on('exit', (code, signal) => {
171
+ // CRITICAL: Reject ALL pending requests before clearing
172
+ // This prevents orphaned promises that never resolve
173
+ const exitError = new Error(`MCP server "${name}" exited unexpectedly (code: ${code}, signal: ${signal})`);
174
+ for (const [_id, pending] of server.pendingRequests) {
175
+ pending.reject(exitError);
176
+ }
177
+ server.pendingRequests.clear();
178
+ server.status = 'disconnected';
179
+ server.process = null;
180
+ server.readline = null;
181
+ this.emit({ type: 'server.disconnected', name });
182
+ });
183
+ // Initialize the connection
184
+ await this.initializeServer(server);
185
+ server.status = 'connected';
186
+ this.emit({ type: 'server.connected', name, toolCount: server.tools.length });
187
+ }
188
+ catch (err) {
189
+ server.status = 'error';
190
+ server.error = err instanceof Error ? err.message : String(err);
191
+ this.emit({ type: 'server.error', name, error: server.error });
192
+ throw err;
193
+ }
194
+ }
195
+ /**
196
+ * Initialize MCP protocol with server.
197
+ */
198
+ async initializeServer(server) {
199
+ // Send initialize request
200
+ const initResult = await this.sendRequest(server, 'initialize', {
201
+ protocolVersion: '2024-11-05',
202
+ capabilities: {},
203
+ clientInfo: {
204
+ name: 'first-principles-agent',
205
+ version: '1.0.0',
206
+ },
207
+ });
208
+ // Send initialized notification
209
+ this.sendNotification(server, 'notifications/initialized', {});
210
+ // List available tools
211
+ const toolsResult = await this.sendRequest(server, 'tools/list', {});
212
+ server.tools = toolsResult.tools || [];
213
+ }
214
+ /**
215
+ * Send a JSON-RPC request and wait for response.
216
+ */
217
+ sendRequest(server, method, params) {
218
+ return new Promise((resolve, reject) => {
219
+ const id = server.nextRequestId++;
220
+ const request = {
221
+ jsonrpc: '2.0',
222
+ id,
223
+ method,
224
+ params,
225
+ };
226
+ server.pendingRequests.set(id, { resolve, reject });
227
+ // Set timeout
228
+ const timeout = setTimeout(() => {
229
+ server.pendingRequests.delete(id);
230
+ reject(new Error(`Request timeout: ${method}`));
231
+ }, this.config.requestTimeout);
232
+ // Store timeout to clear later
233
+ const originalResolve = resolve;
234
+ server.pendingRequests.set(id, {
235
+ resolve: (result) => {
236
+ clearTimeout(timeout);
237
+ originalResolve(result);
238
+ },
239
+ reject: (error) => {
240
+ clearTimeout(timeout);
241
+ reject(error);
242
+ },
243
+ });
244
+ // Send request
245
+ server.process?.stdin?.write(JSON.stringify(request) + '\n');
246
+ });
247
+ }
248
+ /**
249
+ * Send a JSON-RPC notification (no response expected).
250
+ */
251
+ sendNotification(server, method, params) {
252
+ const notification = {
253
+ jsonrpc: '2.0',
254
+ method,
255
+ params,
256
+ };
257
+ server.process?.stdin?.write(JSON.stringify(notification) + '\n');
258
+ }
259
+ /**
260
+ * Handle incoming message from server.
261
+ */
262
+ handleServerMessage(server, line) {
263
+ let message;
264
+ try {
265
+ message = JSON.parse(line);
266
+ }
267
+ catch (parseError) {
268
+ // Log malformed JSON instead of silently ignoring
269
+ // This helps diagnose protocol desync issues
270
+ const preview = line.length > 100 ? line.substring(0, 100) + '...' : line;
271
+ console.error(`[MCP ${server.name}] Malformed JSON-RPC message: ${preview}`);
272
+ this.emit({ type: 'server.error', name: server.name, error: 'Protocol error: malformed JSON' });
273
+ return; // Don't crash, just skip this malformed message
274
+ }
275
+ // Handle response
276
+ if (message.id !== undefined) {
277
+ const pending = server.pendingRequests.get(message.id);
278
+ if (pending) {
279
+ server.pendingRequests.delete(message.id);
280
+ if (message.error) {
281
+ pending.reject(new Error(message.error.message || 'Unknown error'));
282
+ }
283
+ else {
284
+ pending.resolve(message.result);
285
+ }
286
+ }
287
+ }
288
+ // Handle notifications from server (if any)
289
+ // MCP servers can send notifications for things like resource updates
290
+ }
291
+ /**
292
+ * Disconnect from a server.
293
+ */
294
+ async disconnectServer(name) {
295
+ const server = this.servers.get(name);
296
+ if (!server) {
297
+ return;
298
+ }
299
+ if (server.process) {
300
+ server.process.kill();
301
+ server.process = null;
302
+ }
303
+ if (server.readline) {
304
+ server.readline.close();
305
+ server.readline = null;
306
+ }
307
+ server.status = 'disconnected';
308
+ server.tools = [];
309
+ this.emit({ type: 'server.disconnected', name });
310
+ }
311
+ /**
312
+ * Call a tool on a specific server.
313
+ */
314
+ async callTool(serverName, toolName, args) {
315
+ const server = this.servers.get(serverName);
316
+ if (!server) {
317
+ throw new Error(`Server not found: ${serverName}`);
318
+ }
319
+ if (server.status !== 'connected') {
320
+ throw new Error(`Server not connected: ${serverName}`);
321
+ }
322
+ this.emit({ type: 'tool.call', server: serverName, tool: toolName });
323
+ try {
324
+ const result = await this.sendRequest(server, 'tools/call', {
325
+ name: toolName,
326
+ arguments: args,
327
+ });
328
+ this.emit({ type: 'tool.result', server: serverName, tool: toolName, success: true });
329
+ // Extract text content from result
330
+ const textContent = result.content
331
+ ?.filter(c => c.type === 'text')
332
+ .map(c => c.text)
333
+ .join('\n');
334
+ return textContent || result;
335
+ }
336
+ catch (err) {
337
+ this.emit({ type: 'tool.result', server: serverName, tool: toolName, success: false });
338
+ throw err;
339
+ }
340
+ }
341
+ /**
342
+ * List all servers and their status.
343
+ */
344
+ listServers() {
345
+ return Array.from(this.servers.values()).map(s => ({
346
+ name: s.name,
347
+ status: s.status,
348
+ toolCount: s.tools.length,
349
+ error: s.error,
350
+ }));
351
+ }
352
+ /**
353
+ * Get tools from a specific server.
354
+ */
355
+ getServerTools(serverName) {
356
+ const server = this.servers.get(serverName);
357
+ return server?.tools || [];
358
+ }
359
+ // ===========================================================================
360
+ // LAZY LOADING METHODS
361
+ // ===========================================================================
362
+ /**
363
+ * Get lightweight summaries for all tools (low token cost).
364
+ * Use this for initial context, then load full definitions on-demand.
365
+ */
366
+ getAllToolSummaries() {
367
+ const summaries = [];
368
+ const descLimit = this.config.summaryDescriptionLimit;
369
+ for (const server of this.servers.values()) {
370
+ if (server.status !== 'connected')
371
+ continue;
372
+ for (const tool of server.tools) {
373
+ const fullName = `mcp_${server.name}_${tool.name}`;
374
+ const desc = tool.description || `MCP tool: ${tool.name}`;
375
+ summaries.push({
376
+ name: fullName,
377
+ description: desc.length > descLimit ? desc.slice(0, descLimit) + '...' : desc,
378
+ serverName: server.name,
379
+ originalName: tool.name,
380
+ });
381
+ }
382
+ }
383
+ return summaries;
384
+ }
385
+ /**
386
+ * Search tools by name or description with BM25-style scoring.
387
+ * Returns matching tool summaries sorted by relevance.
388
+ */
389
+ searchTools(query, options = {}) {
390
+ const { limit = this.config.maxToolsPerSearch, regex = false } = options;
391
+ const summaries = this.getAllToolSummaries();
392
+ if (!query.trim()) {
393
+ return summaries.slice(0, limit);
394
+ }
395
+ // Normalize query
396
+ const queryLower = query.toLowerCase();
397
+ const queryTerms = queryLower.split(/\s+/).filter(t => t.length > 0);
398
+ // Score each tool
399
+ const scored = summaries.map(summary => {
400
+ let score = 0;
401
+ const nameLower = summary.name.toLowerCase();
402
+ const descLower = summary.description.toLowerCase();
403
+ const originalLower = summary.originalName.toLowerCase();
404
+ if (regex) {
405
+ try {
406
+ const re = new RegExp(query, 'i');
407
+ if (re.test(summary.name))
408
+ score += 10;
409
+ if (re.test(summary.description))
410
+ score += 5;
411
+ if (re.test(summary.originalName))
412
+ score += 8;
413
+ }
414
+ catch {
415
+ // Invalid regex, fall back to substring matching
416
+ }
417
+ }
418
+ // BM25-style term frequency scoring
419
+ for (const term of queryTerms) {
420
+ // Exact match bonuses
421
+ if (originalLower === term)
422
+ score += 20;
423
+ if (nameLower.includes(term))
424
+ score += 10;
425
+ if (originalLower.includes(term))
426
+ score += 8;
427
+ if (descLower.includes(term))
428
+ score += 3;
429
+ // Partial match (prefix)
430
+ if (originalLower.startsWith(term))
431
+ score += 5;
432
+ }
433
+ // Boost if all terms appear
434
+ const allTermsInName = queryTerms.every(t => nameLower.includes(t));
435
+ const allTermsInDesc = queryTerms.every(t => descLower.includes(t));
436
+ if (allTermsInName)
437
+ score += 15;
438
+ if (allTermsInDesc)
439
+ score += 5;
440
+ return { summary, score };
441
+ });
442
+ // Filter and sort by score
443
+ const results = scored
444
+ .filter(s => s.score > 0)
445
+ .sort((a, b) => b.score - a.score)
446
+ .slice(0, limit)
447
+ .map(s => s.summary);
448
+ this.emit({ type: 'tool.search', query, resultCount: results.length });
449
+ return results;
450
+ }
451
+ /**
452
+ * Get full tool definition for a specific tool.
453
+ * Marks the tool as loaded for context tracking.
454
+ */
455
+ getFullToolDefinition(toolName) {
456
+ // Parse tool name: mcp_{serverName}_{originalToolName}
457
+ const match = toolName.match(/^mcp_([^_]+)_(.+)$/);
458
+ if (!match)
459
+ return null;
460
+ const [, serverName, originalName] = match;
461
+ const server = this.servers.get(serverName);
462
+ if (!server || server.status !== 'connected')
463
+ return null;
464
+ const mcpTool = server.tools.find(t => t.name === originalName);
465
+ if (!mcpTool)
466
+ return null;
467
+ // Mark as loaded
468
+ server.loadedTools.add(originalName);
469
+ this.emit({ type: 'tool.dynamicLoad', name: toolName, serverName });
470
+ return {
471
+ name: toolName,
472
+ description: mcpTool.description || `MCP tool: ${mcpTool.name} (from ${serverName})`,
473
+ parameters: mcpTool.inputSchema || { type: 'object', properties: {} },
474
+ execute: async (args) => {
475
+ return this.callTool(serverName, originalName, args);
476
+ },
477
+ };
478
+ }
479
+ /**
480
+ * Batch load multiple tools by name.
481
+ * Returns array of loaded ToolDefinitions.
482
+ */
483
+ loadTools(toolNames) {
484
+ const loaded = [];
485
+ for (const name of toolNames) {
486
+ const tool = this.getFullToolDefinition(name);
487
+ if (tool) {
488
+ loaded.push(tool);
489
+ }
490
+ }
491
+ return loaded;
492
+ }
493
+ /**
494
+ * Get context statistics for MCP tools.
495
+ * Useful for monitoring token usage with lazy loading.
496
+ */
497
+ getContextStats() {
498
+ let summaryCount = 0;
499
+ let loadedCount = 0;
500
+ let summaryTokens = 0;
501
+ let definitionTokens = 0;
502
+ for (const server of this.servers.values()) {
503
+ if (server.status !== 'connected')
504
+ continue;
505
+ for (const tool of server.tools) {
506
+ const isLoaded = server.loadedTools.has(tool.name);
507
+ if (isLoaded) {
508
+ loadedCount++;
509
+ // Full definition tokens: name + description + schema
510
+ const schemaStr = tool.inputSchema ? JSON.stringify(tool.inputSchema) : '{}';
511
+ const defChars = (tool.name.length) +
512
+ (tool.description?.length || 0) +
513
+ schemaStr.length;
514
+ definitionTokens += Math.ceil(defChars / 4); // ~4 chars per token
515
+ }
516
+ else {
517
+ summaryCount++;
518
+ // Summary tokens: name + truncated description
519
+ const descLen = Math.min(tool.description?.length || 0, this.config.summaryDescriptionLimit);
520
+ const sumChars = tool.name.length + descLen + server.name.length;
521
+ summaryTokens += Math.ceil(sumChars / 4);
522
+ }
523
+ }
524
+ }
525
+ return {
526
+ summaryTokens,
527
+ definitionTokens,
528
+ summaryCount,
529
+ loadedCount,
530
+ totalTools: summaryCount + loadedCount,
531
+ };
532
+ }
533
+ /**
534
+ * Check if a tool is fully loaded (has schema in context).
535
+ */
536
+ isToolLoaded(toolName) {
537
+ const match = toolName.match(/^mcp_([^_]+)_(.+)$/);
538
+ if (!match)
539
+ return false;
540
+ const [, serverName, originalName] = match;
541
+ const server = this.servers.get(serverName);
542
+ return server?.loadedTools.has(originalName) ?? false;
543
+ }
544
+ /**
545
+ * Get all tools with lazy loading support.
546
+ * When lazyMode is true, only returns always-loaded tools + previously loaded tools.
547
+ * When lazyMode is false (default), returns all tools with full definitions.
548
+ */
549
+ getAllTools(options = {}) {
550
+ const { lazyMode = this.config.lazyLoading } = options;
551
+ if (!lazyMode) {
552
+ // Original behavior: return all tools with full definitions
553
+ const tools = [];
554
+ for (const server of this.servers.values()) {
555
+ if (server.status !== 'connected')
556
+ continue;
557
+ for (const tool of server.tools) {
558
+ tools.push({
559
+ name: `mcp_${server.name}_${tool.name}`,
560
+ description: tool.description || `MCP tool: ${tool.name} (from ${server.name})`,
561
+ parameters: tool.inputSchema || { type: 'object', properties: {} },
562
+ execute: async (args) => {
563
+ return this.callTool(server.name, tool.name, args);
564
+ },
565
+ });
566
+ }
567
+ }
568
+ return tools;
569
+ }
570
+ // Lazy mode: only return always-loaded tools + previously loaded tools
571
+ const tools = [];
572
+ for (const server of this.servers.values()) {
573
+ if (server.status !== 'connected')
574
+ continue;
575
+ for (const tool of server.tools) {
576
+ const fullName = `mcp_${server.name}_${tool.name}`;
577
+ const isAlwaysLoaded = this.config.alwaysLoadTools.some(pattern => fullName.includes(pattern) || tool.name.includes(pattern));
578
+ const isPreviouslyLoaded = server.loadedTools.has(tool.name);
579
+ if (isAlwaysLoaded || isPreviouslyLoaded) {
580
+ // Mark as loaded
581
+ server.loadedTools.add(tool.name);
582
+ tools.push({
583
+ name: fullName,
584
+ description: tool.description || `MCP tool: ${tool.name} (from ${server.name})`,
585
+ parameters: tool.inputSchema || { type: 'object', properties: {} },
586
+ execute: async (args) => {
587
+ return this.callTool(server.name, tool.name, args);
588
+ },
589
+ });
590
+ }
591
+ }
592
+ }
593
+ return tools;
594
+ }
595
+ /**
596
+ * Check if a server is connected.
597
+ */
598
+ isConnected(serverName) {
599
+ const server = this.servers.get(serverName);
600
+ return server?.status === 'connected';
601
+ }
602
+ /**
603
+ * Subscribe to events.
604
+ */
605
+ on(listener) {
606
+ this.listeners.push(listener);
607
+ return () => {
608
+ const idx = this.listeners.indexOf(listener);
609
+ if (idx >= 0)
610
+ this.listeners.splice(idx, 1);
611
+ };
612
+ }
613
+ /**
614
+ * Emit an event.
615
+ */
616
+ emit(event) {
617
+ for (const listener of this.listeners) {
618
+ try {
619
+ listener(event);
620
+ }
621
+ catch {
622
+ // Ignore listener errors
623
+ }
624
+ }
625
+ }
626
+ /**
627
+ * Cleanup - disconnect all servers.
628
+ */
629
+ async cleanup() {
630
+ for (const name of this.servers.keys()) {
631
+ await this.disconnectServer(name);
632
+ }
633
+ this.servers.clear();
634
+ }
635
+ }
636
+ // =============================================================================
637
+ // FACTORY
638
+ // =============================================================================
639
+ /**
640
+ * Create and initialize an MCP client.
641
+ */
642
+ export async function createMCPClient(config) {
643
+ const client = new MCPClient(config);
644
+ // Use hierarchical loading if configPaths provided, otherwise single config
645
+ if (config?.configPaths && config.configPaths.length > 0) {
646
+ await client.loadFromHierarchicalConfigs(config.configPaths);
647
+ }
648
+ else {
649
+ await client.loadFromConfig();
650
+ }
651
+ return client;
652
+ }
653
+ // =============================================================================
654
+ // UTILITIES
655
+ // =============================================================================
656
+ /**
657
+ * Format server list for display.
658
+ */
659
+ export function formatServerList(servers) {
660
+ if (servers.length === 0) {
661
+ return 'No MCP servers configured.';
662
+ }
663
+ const lines = ['MCP Servers:'];
664
+ for (const server of servers) {
665
+ const statusIcon = server.status === 'connected' ? '✓' : server.status === 'error' ? '✗' : '○';
666
+ const statusColor = server.status === 'connected' ? 'green' : server.status === 'error' ? 'red' : 'dim';
667
+ lines.push(` ${statusIcon} ${server.name} (${server.status}) - ${server.toolCount} tools`);
668
+ if (server.error) {
669
+ lines.push(` Error: ${server.error}`);
670
+ }
671
+ }
672
+ return lines.join('\n');
673
+ }
674
+ /**
675
+ * Create a sample .mcp.json config file content.
676
+ */
677
+ export function getSampleMCPConfig() {
678
+ return JSON.stringify({
679
+ servers: {
680
+ filesystem: {
681
+ command: 'npx',
682
+ args: ['-y', '@anthropic/mcp-server-filesystem', '/path/to/allowed/dir'],
683
+ },
684
+ sqlite: {
685
+ command: 'npx',
686
+ args: ['-y', '@anthropic/mcp-server-sqlite', '~/database.db'],
687
+ },
688
+ github: {
689
+ command: 'npx',
690
+ args: ['-y', '@anthropic/mcp-server-github'],
691
+ env: {
692
+ GITHUB_TOKEN: '${GITHUB_TOKEN}',
693
+ },
694
+ },
695
+ },
696
+ }, null, 2);
697
+ }
698
+ //# sourceMappingURL=mcp-client.js.map