@posthog/agent 1.24.2 → 1.26.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 (606) hide show
  1. package/dist/_virtual/_commonjsHelpers.js +6 -0
  2. package/dist/_virtual/_commonjsHelpers.js.map +1 -0
  3. package/dist/_virtual/_tslib.js +74 -0
  4. package/dist/_virtual/_tslib.js.map +1 -0
  5. package/dist/_virtual/additionalItems.js +4 -0
  6. package/dist/_virtual/additionalItems.js.map +1 -0
  7. package/dist/_virtual/additionalProperties.js +4 -0
  8. package/dist/_virtual/additionalProperties.js.map +1 -0
  9. package/dist/_virtual/ajv.js +4 -0
  10. package/dist/_virtual/ajv.js.map +1 -0
  11. package/dist/_virtual/allOf.js +4 -0
  12. package/dist/_virtual/allOf.js.map +1 -0
  13. package/dist/_virtual/anyOf.js +4 -0
  14. package/dist/_virtual/anyOf.js.map +1 -0
  15. package/dist/_virtual/applicability.js +4 -0
  16. package/dist/_virtual/applicability.js.map +1 -0
  17. package/dist/_virtual/boolSchema.js +4 -0
  18. package/dist/_virtual/boolSchema.js.map +1 -0
  19. package/dist/_virtual/code.js +4 -0
  20. package/dist/_virtual/code.js.map +1 -0
  21. package/dist/_virtual/code2.js +4 -0
  22. package/dist/_virtual/code2.js.map +1 -0
  23. package/dist/_virtual/const.js +4 -0
  24. package/dist/_virtual/const.js.map +1 -0
  25. package/dist/_virtual/contains.js +4 -0
  26. package/dist/_virtual/contains.js.map +1 -0
  27. package/dist/_virtual/core.js +4 -0
  28. package/dist/_virtual/core.js.map +1 -0
  29. package/dist/_virtual/dataType.js +4 -0
  30. package/dist/_virtual/dataType.js.map +1 -0
  31. package/dist/_virtual/defaults.js +4 -0
  32. package/dist/_virtual/defaults.js.map +1 -0
  33. package/dist/_virtual/dependencies.js +4 -0
  34. package/dist/_virtual/dependencies.js.map +1 -0
  35. package/dist/_virtual/draft7.js +4 -0
  36. package/dist/_virtual/draft7.js.map +1 -0
  37. package/dist/_virtual/enum.js +4 -0
  38. package/dist/_virtual/enum.js.map +1 -0
  39. package/dist/_virtual/equal.js +4 -0
  40. package/dist/_virtual/equal.js.map +1 -0
  41. package/dist/_virtual/errors.js +4 -0
  42. package/dist/_virtual/errors.js.map +1 -0
  43. package/dist/_virtual/format.js +4 -0
  44. package/dist/_virtual/format.js.map +1 -0
  45. package/dist/_virtual/formats.js +4 -0
  46. package/dist/_virtual/formats.js.map +1 -0
  47. package/dist/_virtual/id.js +4 -0
  48. package/dist/_virtual/id.js.map +1 -0
  49. package/dist/_virtual/if.js +4 -0
  50. package/dist/_virtual/if.js.map +1 -0
  51. package/dist/_virtual/index.js +4 -0
  52. package/dist/_virtual/index.js.map +1 -0
  53. package/dist/_virtual/index10.js +4 -0
  54. package/dist/_virtual/index10.js.map +1 -0
  55. package/dist/_virtual/index11.js +4 -0
  56. package/dist/_virtual/index11.js.map +1 -0
  57. package/dist/_virtual/index2.js +4 -0
  58. package/dist/_virtual/index2.js.map +1 -0
  59. package/dist/_virtual/index3.js +4 -0
  60. package/dist/_virtual/index3.js.map +1 -0
  61. package/dist/_virtual/index4.js +4 -0
  62. package/dist/_virtual/index4.js.map +1 -0
  63. package/dist/_virtual/index5.js +4 -0
  64. package/dist/_virtual/index5.js.map +1 -0
  65. package/dist/_virtual/index6.js +4 -0
  66. package/dist/_virtual/index6.js.map +1 -0
  67. package/dist/_virtual/index7.js +4 -0
  68. package/dist/_virtual/index7.js.map +1 -0
  69. package/dist/_virtual/index8.js +4 -0
  70. package/dist/_virtual/index8.js.map +1 -0
  71. package/dist/_virtual/index9.js +4 -0
  72. package/dist/_virtual/index9.js.map +1 -0
  73. package/dist/_virtual/items.js +4 -0
  74. package/dist/_virtual/items.js.map +1 -0
  75. package/dist/_virtual/items2020.js +4 -0
  76. package/dist/_virtual/items2020.js.map +1 -0
  77. package/dist/_virtual/keyword.js +4 -0
  78. package/dist/_virtual/keyword.js.map +1 -0
  79. package/dist/_virtual/limit.js +4 -0
  80. package/dist/_virtual/limit.js.map +1 -0
  81. package/dist/_virtual/limitItems.js +4 -0
  82. package/dist/_virtual/limitItems.js.map +1 -0
  83. package/dist/_virtual/limitLength.js +4 -0
  84. package/dist/_virtual/limitLength.js.map +1 -0
  85. package/dist/_virtual/limitNumber.js +4 -0
  86. package/dist/_virtual/limitNumber.js.map +1 -0
  87. package/dist/_virtual/limitProperties.js +4 -0
  88. package/dist/_virtual/limitProperties.js.map +1 -0
  89. package/dist/_virtual/metadata.js +4 -0
  90. package/dist/_virtual/metadata.js.map +1 -0
  91. package/dist/_virtual/multipleOf.js +4 -0
  92. package/dist/_virtual/multipleOf.js.map +1 -0
  93. package/dist/_virtual/names.js +4 -0
  94. package/dist/_virtual/names.js.map +1 -0
  95. package/dist/_virtual/not.js +4 -0
  96. package/dist/_virtual/not.js.map +1 -0
  97. package/dist/_virtual/oneOf.js +4 -0
  98. package/dist/_virtual/oneOf.js.map +1 -0
  99. package/dist/_virtual/pattern.js +4 -0
  100. package/dist/_virtual/pattern.js.map +1 -0
  101. package/dist/_virtual/patternProperties.js +4 -0
  102. package/dist/_virtual/patternProperties.js.map +1 -0
  103. package/dist/_virtual/prefixItems.js +4 -0
  104. package/dist/_virtual/prefixItems.js.map +1 -0
  105. package/dist/_virtual/properties.js +4 -0
  106. package/dist/_virtual/properties.js.map +1 -0
  107. package/dist/_virtual/propertyNames.js +4 -0
  108. package/dist/_virtual/propertyNames.js.map +1 -0
  109. package/dist/_virtual/ref.js +4 -0
  110. package/dist/_virtual/ref.js.map +1 -0
  111. package/dist/_virtual/ref_error.js +4 -0
  112. package/dist/_virtual/ref_error.js.map +1 -0
  113. package/dist/_virtual/required.js +4 -0
  114. package/dist/_virtual/required.js.map +1 -0
  115. package/dist/_virtual/resolve.js +4 -0
  116. package/dist/_virtual/resolve.js.map +1 -0
  117. package/dist/_virtual/rules.js +4 -0
  118. package/dist/_virtual/rules.js.map +1 -0
  119. package/dist/_virtual/scope.js +4 -0
  120. package/dist/_virtual/scope.js.map +1 -0
  121. package/dist/_virtual/subschema.js +4 -0
  122. package/dist/_virtual/subschema.js.map +1 -0
  123. package/dist/_virtual/thenElse.js +4 -0
  124. package/dist/_virtual/thenElse.js.map +1 -0
  125. package/dist/_virtual/types.js +4 -0
  126. package/dist/_virtual/types.js.map +1 -0
  127. package/dist/_virtual/ucs2length.js +4 -0
  128. package/dist/_virtual/ucs2length.js.map +1 -0
  129. package/dist/_virtual/uniqueItems.js +4 -0
  130. package/dist/_virtual/uniqueItems.js.map +1 -0
  131. package/dist/_virtual/uri.js +4 -0
  132. package/dist/_virtual/uri.js.map +1 -0
  133. package/dist/_virtual/util.js +4 -0
  134. package/dist/_virtual/util.js.map +1 -0
  135. package/dist/_virtual/validation_error.js +4 -0
  136. package/dist/_virtual/validation_error.js.map +1 -0
  137. package/dist/claude-cli/cli.js +2294 -2146
  138. package/dist/example-client.d.ts +3 -0
  139. package/dist/example-client.d.ts.map +1 -0
  140. package/dist/index.d.ts +19 -11
  141. package/dist/index.d.ts.map +1 -1
  142. package/dist/index.js +7 -3
  143. package/dist/index.js.map +1 -1
  144. package/dist/node_modules/@agentclientprotocol/sdk/dist/acp.js +891 -0
  145. package/dist/node_modules/@agentclientprotocol/sdk/dist/acp.js.map +1 -0
  146. package/dist/node_modules/@agentclientprotocol/sdk/dist/schema.js +876 -0
  147. package/dist/node_modules/@agentclientprotocol/sdk/dist/schema.js.map +1 -0
  148. package/dist/node_modules/@agentclientprotocol/sdk/dist/stream.js +66 -0
  149. package/dist/node_modules/@agentclientprotocol/sdk/dist/stream.js.map +1 -0
  150. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js +23 -0
  151. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/completable.js.map +1 -0
  152. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js +331 -0
  153. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/index.js.map +1 -0
  154. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js +717 -0
  155. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/mcp.js.map +1 -0
  156. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js +221 -0
  157. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-compat.js.map +1 -0
  158. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js +56 -0
  159. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/server/zod-json-schema-compat.js.map +1 -0
  160. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js +440 -0
  161. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/protocol.js.map +1 -0
  162. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js +94 -0
  163. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/shared/toolNameValidation.js.map +1 -0
  164. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js +1610 -0
  165. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/types.js.map +1 -0
  166. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js +91 -0
  167. package/dist/node_modules/@modelcontextprotocol/sdk/dist/esm/validation/ajv-provider.js.map +1 -0
  168. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/ZodError.js +133 -0
  169. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/ZodError.js.map +1 -0
  170. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/errors.js +9 -0
  171. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/errors.js.map +1 -0
  172. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/helpers/errorUtil.js +9 -0
  173. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/helpers/errorUtil.js.map +1 -0
  174. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/helpers/parseUtil.js +112 -0
  175. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/helpers/parseUtil.js.map +1 -0
  176. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/helpers/util.js +136 -0
  177. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/helpers/util.js.map +1 -0
  178. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/locales/en.js +112 -0
  179. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/locales/en.js.map +1 -0
  180. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/types.js +3297 -0
  181. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v3/types.js.map +1 -0
  182. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/errors.js +44 -0
  183. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/errors.js.map +1 -0
  184. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/iso.js +36 -0
  185. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/iso.js.map +1 -0
  186. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/parse.js +10 -0
  187. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/parse.js.map +1 -0
  188. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/schemas.js +657 -0
  189. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/classic/schemas.js.map +1 -0
  190. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/api.js +449 -0
  191. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/api.js.map +1 -0
  192. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/checks.js +413 -0
  193. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/checks.js.map +1 -0
  194. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/core.js +57 -0
  195. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/core.js.map +1 -0
  196. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/doc.js +38 -0
  197. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/doc.js.map +1 -0
  198. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/errors.js +86 -0
  199. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/errors.js.map +1 -0
  200. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/parse.js +61 -0
  201. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/parse.js.map +1 -0
  202. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/regexes.js +80 -0
  203. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/regexes.js.map +1 -0
  204. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/registries.js +52 -0
  205. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/registries.js.map +1 -0
  206. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/schemas.js +1307 -0
  207. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/schemas.js.map +1 -0
  208. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/to-json-schema.js +842 -0
  209. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/to-json-schema.js.map +1 -0
  210. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/util.js +335 -0
  211. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/util.js.map +1 -0
  212. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/versions.js +8 -0
  213. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/core/versions.js.map +1 -0
  214. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/mini/schemas.js +51 -0
  215. package/dist/node_modules/@modelcontextprotocol/sdk/node_modules/zod/v4/mini/schemas.js.map +1 -0
  216. package/dist/node_modules/ajv/dist/ajv.js +69 -0
  217. package/dist/node_modules/ajv/dist/ajv.js.map +1 -0
  218. package/dist/node_modules/ajv/dist/compile/codegen/code.js +169 -0
  219. package/dist/node_modules/ajv/dist/compile/codegen/code.js.map +1 -0
  220. package/dist/node_modules/ajv/dist/compile/codegen/index.js +712 -0
  221. package/dist/node_modules/ajv/dist/compile/codegen/index.js.map +1 -0
  222. package/dist/node_modules/ajv/dist/compile/codegen/scope.js +157 -0
  223. package/dist/node_modules/ajv/dist/compile/codegen/scope.js.map +1 -0
  224. package/dist/node_modules/ajv/dist/compile/errors.js +140 -0
  225. package/dist/node_modules/ajv/dist/compile/errors.js.map +1 -0
  226. package/dist/node_modules/ajv/dist/compile/index.js +253 -0
  227. package/dist/node_modules/ajv/dist/compile/index.js.map +1 -0
  228. package/dist/node_modules/ajv/dist/compile/names.js +40 -0
  229. package/dist/node_modules/ajv/dist/compile/names.js.map +1 -0
  230. package/dist/node_modules/ajv/dist/compile/ref_error.js +25 -0
  231. package/dist/node_modules/ajv/dist/compile/ref_error.js.map +1 -0
  232. package/dist/node_modules/ajv/dist/compile/resolve.js +162 -0
  233. package/dist/node_modules/ajv/dist/compile/resolve.js.map +1 -0
  234. package/dist/node_modules/ajv/dist/compile/rules.js +29 -0
  235. package/dist/node_modules/ajv/dist/compile/rules.js.map +1 -0
  236. package/dist/node_modules/ajv/dist/compile/util.js +183 -0
  237. package/dist/node_modules/ajv/dist/compile/util.js.map +1 -0
  238. package/dist/node_modules/ajv/dist/compile/validate/applicability.js +30 -0
  239. package/dist/node_modules/ajv/dist/compile/validate/applicability.js.map +1 -0
  240. package/dist/node_modules/ajv/dist/compile/validate/boolSchema.js +64 -0
  241. package/dist/node_modules/ajv/dist/compile/validate/boolSchema.js.map +1 -0
  242. package/dist/node_modules/ajv/dist/compile/validate/dataType.js +213 -0
  243. package/dist/node_modules/ajv/dist/compile/validate/dataType.js.map +1 -0
  244. package/dist/node_modules/ajv/dist/compile/validate/defaults.js +49 -0
  245. package/dist/node_modules/ajv/dist/compile/validate/defaults.js.map +1 -0
  246. package/dist/node_modules/ajv/dist/compile/validate/index.js +544 -0
  247. package/dist/node_modules/ajv/dist/compile/validate/index.js.map +1 -0
  248. package/dist/node_modules/ajv/dist/compile/validate/keyword.js +139 -0
  249. package/dist/node_modules/ajv/dist/compile/validate/keyword.js.map +1 -0
  250. package/dist/node_modules/ajv/dist/compile/validate/subschema.js +95 -0
  251. package/dist/node_modules/ajv/dist/compile/validate/subschema.js.map +1 -0
  252. package/dist/node_modules/ajv/dist/core.js +639 -0
  253. package/dist/node_modules/ajv/dist/core.js.map +1 -0
  254. package/dist/node_modules/ajv/dist/refs/data.json.js +31 -0
  255. package/dist/node_modules/ajv/dist/refs/data.json.js.map +1 -0
  256. package/dist/node_modules/ajv/dist/refs/json-schema-draft-07.json.js +254 -0
  257. package/dist/node_modules/ajv/dist/refs/json-schema-draft-07.json.js.map +1 -0
  258. package/dist/node_modules/ajv/dist/runtime/equal.js +9 -0
  259. package/dist/node_modules/ajv/dist/runtime/equal.js.map +1 -0
  260. package/dist/node_modules/ajv/dist/runtime/ucs2length.js +25 -0
  261. package/dist/node_modules/ajv/dist/runtime/ucs2length.js.map +1 -0
  262. package/dist/node_modules/ajv/dist/runtime/uri.js +8 -0
  263. package/dist/node_modules/ajv/dist/runtime/uri.js.map +1 -0
  264. package/dist/node_modules/ajv/dist/runtime/validation_error.js +22 -0
  265. package/dist/node_modules/ajv/dist/runtime/validation_error.js.map +1 -0
  266. package/dist/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js +53 -0
  267. package/dist/node_modules/ajv/dist/vocabularies/applicator/additionalItems.js.map +1 -0
  268. package/dist/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js +112 -0
  269. package/dist/node_modules/ajv/dist/vocabularies/applicator/additionalProperties.js.map +1 -0
  270. package/dist/node_modules/ajv/dist/vocabularies/applicator/allOf.js +26 -0
  271. package/dist/node_modules/ajv/dist/vocabularies/applicator/allOf.js.map +1 -0
  272. package/dist/node_modules/ajv/dist/vocabularies/applicator/anyOf.js +14 -0
  273. package/dist/node_modules/ajv/dist/vocabularies/applicator/anyOf.js.map +1 -0
  274. package/dist/node_modules/ajv/dist/vocabularies/applicator/contains.js +99 -0
  275. package/dist/node_modules/ajv/dist/vocabularies/applicator/contains.js.map +1 -0
  276. package/dist/node_modules/ajv/dist/vocabularies/applicator/dependencies.js +93 -0
  277. package/dist/node_modules/ajv/dist/vocabularies/applicator/dependencies.js.map +1 -0
  278. package/dist/node_modules/ajv/dist/vocabularies/applicator/if.js +70 -0
  279. package/dist/node_modules/ajv/dist/vocabularies/applicator/if.js.map +1 -0
  280. package/dist/node_modules/ajv/dist/vocabularies/applicator/index.js +77 -0
  281. package/dist/node_modules/ajv/dist/vocabularies/applicator/index.js.map +1 -0
  282. package/dist/node_modules/ajv/dist/vocabularies/applicator/items.js +57 -0
  283. package/dist/node_modules/ajv/dist/vocabularies/applicator/items.js.map +1 -0
  284. package/dist/node_modules/ajv/dist/vocabularies/applicator/items2020.js +37 -0
  285. package/dist/node_modules/ajv/dist/vocabularies/applicator/items2020.js.map +1 -0
  286. package/dist/node_modules/ajv/dist/vocabularies/applicator/not.js +29 -0
  287. package/dist/node_modules/ajv/dist/vocabularies/applicator/not.js.map +1 -0
  288. package/dist/node_modules/ajv/dist/vocabularies/applicator/oneOf.js +64 -0
  289. package/dist/node_modules/ajv/dist/vocabularies/applicator/oneOf.js.map +1 -0
  290. package/dist/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js +80 -0
  291. package/dist/node_modules/ajv/dist/vocabularies/applicator/patternProperties.js.map +1 -0
  292. package/dist/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js +15 -0
  293. package/dist/node_modules/ajv/dist/vocabularies/applicator/prefixItems.js.map +1 -0
  294. package/dist/node_modules/ajv/dist/vocabularies/applicator/properties.js +61 -0
  295. package/dist/node_modules/ajv/dist/vocabularies/applicator/properties.js.map +1 -0
  296. package/dist/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js +42 -0
  297. package/dist/node_modules/ajv/dist/vocabularies/applicator/propertyNames.js.map +1 -0
  298. package/dist/node_modules/ajv/dist/vocabularies/applicator/thenElse.js +16 -0
  299. package/dist/node_modules/ajv/dist/vocabularies/applicator/thenElse.js.map +1 -0
  300. package/dist/node_modules/ajv/dist/vocabularies/code.js +146 -0
  301. package/dist/node_modules/ajv/dist/vocabularies/code.js.map +1 -0
  302. package/dist/node_modules/ajv/dist/vocabularies/core/id.js +11 -0
  303. package/dist/node_modules/ajv/dist/vocabularies/core/id.js.map +1 -0
  304. package/dist/node_modules/ajv/dist/vocabularies/core/index.js +21 -0
  305. package/dist/node_modules/ajv/dist/vocabularies/core/index.js.map +1 -0
  306. package/dist/node_modules/ajv/dist/vocabularies/core/ref.js +131 -0
  307. package/dist/node_modules/ajv/dist/vocabularies/core/ref.js.map +1 -0
  308. package/dist/node_modules/ajv/dist/vocabularies/discriminator/index.js +113 -0
  309. package/dist/node_modules/ajv/dist/vocabularies/discriminator/index.js.map +1 -0
  310. package/dist/node_modules/ajv/dist/vocabularies/discriminator/types.js +12 -0
  311. package/dist/node_modules/ajv/dist/vocabularies/discriminator/types.js.map +1 -0
  312. package/dist/node_modules/ajv/dist/vocabularies/draft7.js +28 -0
  313. package/dist/node_modules/ajv/dist/vocabularies/draft7.js.map +1 -0
  314. package/dist/node_modules/ajv/dist/vocabularies/format/format.js +94 -0
  315. package/dist/node_modules/ajv/dist/vocabularies/format/format.js.map +1 -0
  316. package/dist/node_modules/ajv/dist/vocabularies/format/index.js +9 -0
  317. package/dist/node_modules/ajv/dist/vocabularies/format/index.js.map +1 -0
  318. package/dist/node_modules/ajv/dist/vocabularies/metadata.js +21 -0
  319. package/dist/node_modules/ajv/dist/vocabularies/metadata.js.map +1 -0
  320. package/dist/node_modules/ajv/dist/vocabularies/validation/const.js +31 -0
  321. package/dist/node_modules/ajv/dist/vocabularies/validation/const.js.map +1 -0
  322. package/dist/node_modules/ajv/dist/vocabularies/validation/enum.js +54 -0
  323. package/dist/node_modules/ajv/dist/vocabularies/validation/enum.js.map +1 -0
  324. package/dist/node_modules/ajv/dist/vocabularies/validation/index.js +54 -0
  325. package/dist/node_modules/ajv/dist/vocabularies/validation/index.js.map +1 -0
  326. package/dist/node_modules/ajv/dist/vocabularies/validation/limitItems.js +26 -0
  327. package/dist/node_modules/ajv/dist/vocabularies/validation/limitItems.js.map +1 -0
  328. package/dist/node_modules/ajv/dist/vocabularies/validation/limitLength.js +33 -0
  329. package/dist/node_modules/ajv/dist/vocabularies/validation/limitLength.js.map +1 -0
  330. package/dist/node_modules/ajv/dist/vocabularies/validation/limitNumber.js +29 -0
  331. package/dist/node_modules/ajv/dist/vocabularies/validation/limitNumber.js.map +1 -0
  332. package/dist/node_modules/ajv/dist/vocabularies/validation/limitProperties.js +26 -0
  333. package/dist/node_modules/ajv/dist/vocabularies/validation/limitProperties.js.map +1 -0
  334. package/dist/node_modules/ajv/dist/vocabularies/validation/multipleOf.js +28 -0
  335. package/dist/node_modules/ajv/dist/vocabularies/validation/multipleOf.js.map +1 -0
  336. package/dist/node_modules/ajv/dist/vocabularies/validation/pattern.js +27 -0
  337. package/dist/node_modules/ajv/dist/vocabularies/validation/pattern.js.map +1 -0
  338. package/dist/node_modules/ajv/dist/vocabularies/validation/required.js +84 -0
  339. package/dist/node_modules/ajv/dist/vocabularies/validation/required.js.map +1 -0
  340. package/dist/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js +72 -0
  341. package/dist/node_modules/ajv/dist/vocabularies/validation/uniqueItems.js.map +1 -0
  342. package/dist/node_modules/ajv-formats/dist/formats.js +212 -0
  343. package/dist/node_modules/ajv-formats/dist/formats.js.map +1 -0
  344. package/dist/node_modules/ajv-formats/dist/index.js +52 -0
  345. package/dist/node_modules/ajv-formats/dist/index.js.map +1 -0
  346. package/dist/node_modules/ajv-formats/dist/limit.js +75 -0
  347. package/dist/node_modules/ajv-formats/dist/limit.js.map +1 -0
  348. package/dist/node_modules/diff/libesm/diff/base.js +256 -0
  349. package/dist/node_modules/diff/libesm/diff/base.js.map +1 -0
  350. package/dist/node_modules/diff/libesm/diff/line.js +64 -0
  351. package/dist/node_modules/diff/libesm/diff/line.js.map +1 -0
  352. package/dist/node_modules/diff/libesm/patch/create.js +185 -0
  353. package/dist/node_modules/diff/libesm/patch/create.js.map +1 -0
  354. package/dist/node_modules/fast-deep-equal/index.js +47 -0
  355. package/dist/node_modules/fast-deep-equal/index.js.map +1 -0
  356. package/dist/node_modules/fast-uri/index.js +347 -0
  357. package/dist/node_modules/fast-uri/index.js.map +1 -0
  358. package/dist/node_modules/fast-uri/lib/schemes.js +255 -0
  359. package/dist/node_modules/fast-uri/lib/schemes.js.map +1 -0
  360. package/dist/node_modules/fast-uri/lib/utils.js +334 -0
  361. package/dist/node_modules/fast-uri/lib/utils.js.map +1 -0
  362. package/dist/node_modules/json-schema-traverse/index.js +98 -0
  363. package/dist/node_modules/json-schema-traverse/index.js.map +1 -0
  364. package/dist/node_modules/uuid/dist/rng.js +14 -0
  365. package/dist/node_modules/uuid/dist/rng.js.map +1 -0
  366. package/dist/node_modules/uuid/dist/stringify.js +29 -0
  367. package/dist/node_modules/uuid/dist/stringify.js.map +1 -0
  368. package/dist/node_modules/uuid/dist/v7.js +65 -0
  369. package/dist/node_modules/uuid/dist/v7.js.map +1 -0
  370. package/dist/node_modules/zod-to-json-schema/dist/esm/Options.js +37 -0
  371. package/dist/node_modules/zod-to-json-schema/dist/esm/Options.js.map +1 -0
  372. package/dist/node_modules/zod-to-json-schema/dist/esm/Refs.js +26 -0
  373. package/dist/node_modules/zod-to-json-schema/dist/esm/Refs.js.map +1 -0
  374. package/dist/node_modules/zod-to-json-schema/dist/esm/errorMessages.js +17 -0
  375. package/dist/node_modules/zod-to-json-schema/dist/esm/errorMessages.js.map +1 -0
  376. package/dist/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js +11 -0
  377. package/dist/node_modules/zod-to-json-schema/dist/esm/getRelativePath.js.map +1 -0
  378. package/dist/node_modules/zod-to-json-schema/dist/esm/parseDef.js +66 -0
  379. package/dist/node_modules/zod-to-json-schema/dist/esm/parseDef.js.map +1 -0
  380. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/any.js +21 -0
  381. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/any.js.map +1 -0
  382. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/array.js +30 -0
  383. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/array.js.map +1 -0
  384. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js +53 -0
  385. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/bigint.js.map +1 -0
  386. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js +8 -0
  387. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/boolean.js.map +1 -0
  388. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js +8 -0
  389. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/branded.js.map +1 -0
  390. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js +8 -0
  391. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/catch.js.map +1 -0
  392. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/date.js +50 -0
  393. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/date.js.map +1 -0
  394. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/default.js +11 -0
  395. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/default.js.map +1 -0
  396. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js +11 -0
  397. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/effects.js.map +1 -0
  398. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js +9 -0
  399. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/enum.js.map +1 -0
  400. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js +56 -0
  401. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/intersection.js.map +1 -0
  402. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js +24 -0
  403. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/literal.js.map +1 -0
  404. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/map.js +30 -0
  405. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/map.js.map +1 -0
  406. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js +19 -0
  407. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nativeEnum.js.map +1 -0
  408. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/never.js +15 -0
  409. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/never.js.map +1 -0
  410. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/null.js +13 -0
  411. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/null.js.map +1 -0
  412. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js +37 -0
  413. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/nullable.js.map +1 -0
  414. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/number.js +56 -0
  415. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/number.js.map +1 -0
  416. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/object.js +76 -0
  417. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/object.js.map +1 -0
  418. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js +25 -0
  419. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/optional.js.map +1 -0
  420. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js +24 -0
  421. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/pipeline.js.map +1 -0
  422. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js +8 -0
  423. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/promise.js.map +1 -0
  424. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js +8 -0
  425. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/readonly.js.map +1 -0
  426. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/record.js +65 -0
  427. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/record.js.map +1 -0
  428. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/set.js +24 -0
  429. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/set.js.map +1 -0
  430. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/string.js +350 -0
  431. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/string.js.map +1 -0
  432. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js +36 -0
  433. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/tuple.js.map +1 -0
  434. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js +10 -0
  435. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/undefined.js.map +1 -0
  436. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/union.js +84 -0
  437. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/union.js.map +1 -0
  438. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js +8 -0
  439. package/dist/node_modules/zod-to-json-schema/dist/esm/parsers/unknown.js.map +1 -0
  440. package/dist/node_modules/zod-to-json-schema/dist/esm/selectParser.js +109 -0
  441. package/dist/node_modules/zod-to-json-schema/dist/esm/selectParser.js.map +1 -0
  442. package/dist/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js +90 -0
  443. package/dist/node_modules/zod-to-json-schema/dist/esm/zodToJsonSchema.js.map +1 -0
  444. package/dist/node_modules/zod-to-json-schema/node_modules/zod/v3/types.js +42 -0
  445. package/dist/node_modules/zod-to-json-schema/node_modules/zod/v3/types.js.map +1 -0
  446. package/dist/package.json.js +8 -0
  447. package/dist/package.json.js.map +1 -0
  448. package/dist/src/acp-extensions.d.ts +91 -0
  449. package/dist/src/acp-extensions.d.ts.map +1 -0
  450. package/dist/src/acp-extensions.js +38 -0
  451. package/dist/src/acp-extensions.js.map +1 -0
  452. package/dist/src/adapters/claude/claude.d.ts +136 -0
  453. package/dist/src/adapters/claude/claude.d.ts.map +1 -0
  454. package/dist/src/adapters/claude/claude.js +1128 -0
  455. package/dist/src/adapters/claude/claude.js.map +1 -0
  456. package/dist/src/adapters/claude/mcp-server.d.ts +30 -0
  457. package/dist/src/adapters/claude/mcp-server.d.ts.map +1 -0
  458. package/dist/src/adapters/claude/mcp-server.js +668 -0
  459. package/dist/src/adapters/claude/mcp-server.js.map +1 -0
  460. package/dist/src/adapters/claude/tools.d.ts +35 -0
  461. package/dist/src/adapters/claude/tools.d.ts.map +1 -0
  462. package/dist/src/adapters/claude/tools.js +473 -0
  463. package/dist/src/adapters/claude/tools.js.map +1 -0
  464. package/dist/src/adapters/claude/utils.d.ts +48 -0
  465. package/dist/src/adapters/claude/utils.d.ts.map +1 -0
  466. package/dist/src/adapters/claude/utils.js +158 -0
  467. package/dist/src/adapters/claude/utils.js.map +1 -0
  468. package/dist/src/agent.d.ts +24 -28
  469. package/dist/src/agent.d.ts.map +1 -1
  470. package/dist/src/agent.js +343 -172
  471. package/dist/src/agent.js.map +1 -1
  472. package/dist/src/agents/execution.js.map +1 -1
  473. package/dist/src/agents/planning.js.map +1 -1
  474. package/dist/src/agents/research.js.map +1 -1
  475. package/dist/src/file-manager.d.ts +6 -6
  476. package/dist/src/file-manager.d.ts.map +1 -1
  477. package/dist/src/file-manager.js +72 -63
  478. package/dist/src/file-manager.js.map +1 -1
  479. package/dist/src/git-manager.d.ts +2 -1
  480. package/dist/src/git-manager.d.ts.map +1 -1
  481. package/dist/src/git-manager.js +105 -70
  482. package/dist/src/git-manager.js.map +1 -1
  483. package/dist/src/posthog-api.d.ts +8 -14
  484. package/dist/src/posthog-api.d.ts.map +1 -1
  485. package/dist/src/posthog-api.js +35 -23
  486. package/dist/src/posthog-api.js.map +1 -1
  487. package/dist/src/prompt-builder.d.ts +4 -4
  488. package/dist/src/prompt-builder.d.ts.map +1 -1
  489. package/dist/src/prompt-builder.js +129 -99
  490. package/dist/src/prompt-builder.js.map +1 -1
  491. package/dist/src/schemas.d.ts +980 -0
  492. package/dist/src/schemas.d.ts.map +1 -0
  493. package/dist/src/schemas.js +196 -0
  494. package/dist/src/schemas.js.map +1 -0
  495. package/dist/src/session-store.d.ts +58 -0
  496. package/dist/src/session-store.d.ts.map +1 -0
  497. package/dist/src/session-store.js +206 -0
  498. package/dist/src/session-store.js.map +1 -0
  499. package/dist/src/task-manager.d.ts +7 -7
  500. package/dist/src/task-manager.d.ts.map +1 -1
  501. package/dist/src/task-manager.js +19 -18
  502. package/dist/src/task-manager.js.map +1 -1
  503. package/dist/src/template-manager.d.ts +1 -1
  504. package/dist/src/template-manager.d.ts.map +1 -1
  505. package/dist/src/template-manager.js +30 -28
  506. package/dist/src/template-manager.js.map +1 -1
  507. package/dist/src/todo-manager.d.ts +5 -5
  508. package/dist/src/todo-manager.d.ts.map +1 -1
  509. package/dist/src/todo-manager.js +33 -24
  510. package/dist/src/todo-manager.js.map +1 -1
  511. package/dist/src/tools/registry.d.ts +1 -1
  512. package/dist/src/tools/registry.js +60 -60
  513. package/dist/src/tools/registry.js.map +1 -1
  514. package/dist/src/tools/types.d.ts +31 -31
  515. package/dist/src/types.d.ts +62 -167
  516. package/dist/src/types.d.ts.map +1 -1
  517. package/dist/src/types.js +1 -0
  518. package/dist/src/types.js.map +1 -1
  519. package/dist/src/utils/logger.d.ts +14 -6
  520. package/dist/src/utils/logger.d.ts.map +1 -1
  521. package/dist/src/utils/logger.js +37 -22
  522. package/dist/src/utils/logger.js.map +1 -1
  523. package/dist/src/utils/tapped-stream.d.ts +17 -0
  524. package/dist/src/utils/tapped-stream.d.ts.map +1 -0
  525. package/dist/src/utils/tapped-stream.js +45 -0
  526. package/dist/src/utils/tapped-stream.js.map +1 -0
  527. package/dist/src/workflow/config.d.ts +1 -1
  528. package/dist/src/workflow/config.d.ts.map +1 -1
  529. package/dist/src/workflow/config.js +18 -18
  530. package/dist/src/workflow/config.js.map +1 -1
  531. package/dist/src/workflow/steps/build.d.ts +1 -1
  532. package/dist/src/workflow/steps/build.d.ts.map +1 -1
  533. package/dist/src/workflow/steps/build.js +53 -39
  534. package/dist/src/workflow/steps/build.js.map +1 -1
  535. package/dist/src/workflow/steps/finalize.d.ts +1 -1
  536. package/dist/src/workflow/steps/finalize.d.ts.map +1 -1
  537. package/dist/src/workflow/steps/finalize.js +58 -52
  538. package/dist/src/workflow/steps/finalize.js.map +1 -1
  539. package/dist/src/workflow/steps/plan.d.ts +1 -1
  540. package/dist/src/workflow/steps/plan.d.ts.map +1 -1
  541. package/dist/src/workflow/steps/plan.js +69 -47
  542. package/dist/src/workflow/steps/plan.js.map +1 -1
  543. package/dist/src/workflow/steps/research.d.ts +1 -1
  544. package/dist/src/workflow/steps/research.d.ts.map +1 -1
  545. package/dist/src/workflow/steps/research.js +86 -67
  546. package/dist/src/workflow/steps/research.js.map +1 -1
  547. package/dist/src/workflow/types.d.ts +19 -14
  548. package/dist/src/workflow/types.d.ts.map +1 -1
  549. package/dist/src/workflow/utils.d.ts +1 -1
  550. package/dist/src/workflow/utils.d.ts.map +1 -1
  551. package/dist/src/workflow/utils.js +7 -4
  552. package/dist/src/workflow/utils.js.map +1 -1
  553. package/dist/src/worktree-manager.d.ts +39 -0
  554. package/dist/src/worktree-manager.d.ts.map +1 -0
  555. package/dist/src/worktree-manager.js +808 -0
  556. package/dist/src/worktree-manager.js.map +1 -0
  557. package/package.json +20 -16
  558. package/src/acp-extensions.ts +117 -0
  559. package/src/adapters/claude/claude.ts +1514 -0
  560. package/src/adapters/claude/mcp-server.ts +810 -0
  561. package/src/adapters/claude/tools.ts +616 -0
  562. package/src/adapters/claude/utils.ts +267 -0
  563. package/src/agent.ts +717 -441
  564. package/src/agents/execution.ts +1 -1
  565. package/src/agents/planning.ts +1 -1
  566. package/src/agents/research.ts +0 -1
  567. package/src/file-manager.ts +80 -70
  568. package/src/git-manager.ts +164 -88
  569. package/src/posthog-api.ts +155 -94
  570. package/src/prompt-builder.ts +196 -143
  571. package/src/schemas.ts +241 -0
  572. package/src/session-store.ts +259 -0
  573. package/src/task-manager.ts +41 -33
  574. package/src/template-manager.ts +98 -45
  575. package/src/todo-manager.ts +43 -32
  576. package/src/tools/registry.ts +62 -62
  577. package/src/tools/types.ts +36 -36
  578. package/src/types.ts +130 -239
  579. package/src/utils/logger.ts +89 -58
  580. package/src/utils/tapped-stream.ts +60 -0
  581. package/src/workflow/config.ts +48 -48
  582. package/src/workflow/steps/build.ts +127 -113
  583. package/src/workflow/steps/finalize.ts +207 -182
  584. package/src/workflow/steps/plan.ts +155 -130
  585. package/src/workflow/steps/research.ts +207 -187
  586. package/src/workflow/types.ts +47 -36
  587. package/src/workflow/utils.ts +37 -34
  588. package/src/worktree-manager.ts +881 -0
  589. package/dist/src/adapters/claude/claude-adapter.d.ts +0 -18
  590. package/dist/src/adapters/claude/claude-adapter.d.ts.map +0 -1
  591. package/dist/src/adapters/claude/claude-adapter.js +0 -311
  592. package/dist/src/adapters/claude/claude-adapter.js.map +0 -1
  593. package/dist/src/adapters/claude/tool-mapper.d.ts +0 -19
  594. package/dist/src/adapters/claude/tool-mapper.d.ts.map +0 -1
  595. package/dist/src/adapters/claude/tool-mapper.js +0 -44
  596. package/dist/src/adapters/claude/tool-mapper.js.map +0 -1
  597. package/dist/src/adapters/types.d.ts +0 -33
  598. package/dist/src/adapters/types.d.ts.map +0 -1
  599. package/dist/src/task-progress-reporter.d.ts +0 -43
  600. package/dist/src/task-progress-reporter.d.ts.map +0 -1
  601. package/dist/src/task-progress-reporter.js +0 -393
  602. package/dist/src/task-progress-reporter.js.map +0 -1
  603. package/src/adapters/claude/claude-adapter.ts +0 -338
  604. package/src/adapters/claude/tool-mapper.ts +0 -46
  605. package/src/adapters/types.ts +0 -37
  606. package/src/task-progress-reporter.ts +0 -443
@@ -0,0 +1,1514 @@
1
+ /**
2
+ * The claude adapter has been based on the original claude-code-acp adapter,
3
+ * and could use some cleanup.
4
+ *
5
+ * https://github.com/zed-industries/claude-code-acp
6
+ */
7
+
8
+ import * as fs from "node:fs";
9
+ import * as os from "node:os";
10
+ import * as path from "node:path";
11
+ import {
12
+ type Agent,
13
+ AgentSideConnection,
14
+ type AuthenticateRequest,
15
+ type AvailableCommand,
16
+ type CancelNotification,
17
+ type ClientCapabilities,
18
+ type InitializeRequest,
19
+ type InitializeResponse,
20
+ type LoadSessionRequest,
21
+ type LoadSessionResponse,
22
+ type NewSessionRequest,
23
+ type NewSessionResponse,
24
+ ndJsonStream,
25
+ type PromptRequest,
26
+ type PromptResponse,
27
+ type ReadTextFileRequest,
28
+ type ReadTextFileResponse,
29
+ RequestError,
30
+ type SessionModelState,
31
+ type SessionNotification,
32
+ type SetSessionModelRequest,
33
+ type SetSessionModeRequest,
34
+ type SetSessionModeResponse,
35
+ type TerminalHandle,
36
+ type TerminalOutputResponse,
37
+ type WriteTextFileRequest,
38
+ type WriteTextFileResponse,
39
+ } from "@agentclientprotocol/sdk";
40
+ import {
41
+ type CanUseTool,
42
+ type McpServerConfig,
43
+ type Options,
44
+ type PermissionMode,
45
+ type Query,
46
+ query,
47
+ type SDKPartialAssistantMessage,
48
+ type SDKUserMessage,
49
+ } from "@anthropic-ai/claude-agent-sdk";
50
+ import type { ContentBlockParam } from "@anthropic-ai/sdk/resources";
51
+ import type {
52
+ BetaContentBlock,
53
+ BetaRawContentBlockDelta,
54
+ } from "@anthropic-ai/sdk/resources/beta.mjs";
55
+ import { v7 as uuidv7 } from "uuid";
56
+ import type {
57
+ SessionPersistenceConfig,
58
+ SessionStore,
59
+ } from "@/session-store.js";
60
+ import { Logger } from "@/utils/logger.js";
61
+ import { createTappedWritableStream } from "@/utils/tapped-stream.js";
62
+ import packageJson from "../../../package.json" with { type: "json" };
63
+ import { createMcpServer, EDIT_TOOL_NAMES, toolNames } from "./mcp-server.js";
64
+ import {
65
+ type ClaudePlanEntry,
66
+ createPostToolUseHook,
67
+ planEntries,
68
+ registerHookCallback,
69
+ toolInfoFromToolUse,
70
+ toolUpdateFromToolResult,
71
+ } from "./tools.js";
72
+ import {
73
+ createBidirectionalStreams,
74
+ Pushable,
75
+ type StreamPair,
76
+ unreachable,
77
+ } from "./utils.js";
78
+
79
+ /**
80
+ * Clears the statsig cache to work around a claude-agent-sdk bug where cached
81
+ * tool definitions include input_examples which causes API errors.
82
+ * See: https://github.com/anthropics/claude-code/issues/11678
83
+ */
84
+ function clearStatsigCache(): void {
85
+ const configDir =
86
+ process.env.CLAUDE_CONFIG_DIR || path.join(os.homedir(), ".claude");
87
+ const statsigPath = path.join(configDir, "statsig");
88
+
89
+ try {
90
+ if (fs.existsSync(statsigPath)) {
91
+ fs.rmSync(statsigPath, { recursive: true, force: true });
92
+ }
93
+ } catch {
94
+ // Ignore errors - cache clearing is best-effort
95
+ }
96
+ }
97
+
98
+ type Session = {
99
+ query: Query;
100
+ input: Pushable<SDKUserMessage>;
101
+ cancelled: boolean;
102
+ permissionMode: PermissionMode;
103
+ notificationHistory: SessionNotification[];
104
+ sdkSessionId?: string;
105
+ };
106
+
107
+ type BackgroundTerminal =
108
+ | {
109
+ handle: TerminalHandle;
110
+ status: "started";
111
+ lastOutput: TerminalOutputResponse | null;
112
+ }
113
+ | {
114
+ status: "aborted" | "exited" | "killed" | "timedOut";
115
+ pendingOutput: TerminalOutputResponse;
116
+ };
117
+
118
+ /**
119
+ * Extra metadata that can be given to Claude Code when creating a new session.
120
+ */
121
+ export type NewSessionMeta = {
122
+ claudeCode?: {
123
+ /**
124
+ * Options forwarded to Claude Code when starting a new session.
125
+ * Those parameters will be ignored and managed by ACP:
126
+ * - cwd
127
+ * - includePartialMessages
128
+ * - allowDangerouslySkipPermissions
129
+ * - permissionMode
130
+ * - canUseTool
131
+ * - executable
132
+ * Those parameters will be used and updated to work with ACP:
133
+ * - hooks (merged with ACP's hooks)
134
+ * - mcpServers (merged with ACP's mcpServers)
135
+ */
136
+ options?: Options;
137
+ };
138
+ };
139
+
140
+ /**
141
+ * Extra metadata that the agent provides for each tool_call / tool_update update.
142
+ */
143
+ export type ToolUpdateMeta = {
144
+ claudeCode?: {
145
+ /* The name of the tool that was used in Claude Code. */
146
+ toolName: string;
147
+ /* The structured output provided by Claude Code. */
148
+ toolResponse?: unknown;
149
+ };
150
+ };
151
+
152
+ type ToolUseCache = {
153
+ [key: string]: {
154
+ type: "tool_use" | "server_tool_use" | "mcp_tool_use";
155
+ id: string;
156
+ name: string;
157
+ input: any;
158
+ };
159
+ };
160
+
161
+ // Bypass Permissions doesn't work if we are a root/sudo user
162
+ const IS_ROOT = (process.geteuid?.() ?? process.getuid?.()) === 0;
163
+
164
+ // Implement the ACP Agent interface
165
+ export class ClaudeAcpAgent implements Agent {
166
+ sessions: {
167
+ [key: string]: Session;
168
+ };
169
+ client: AgentSideConnection;
170
+ toolUseCache: ToolUseCache;
171
+ fileContentCache: { [key: string]: string };
172
+ backgroundTerminals: { [key: string]: BackgroundTerminal } = {};
173
+ clientCapabilities?: ClientCapabilities;
174
+ logger: Logger = new Logger({ debug: true, prefix: "[ClaudeAcpAgent]" });
175
+ sessionStore?: SessionStore;
176
+
177
+ constructor(client: AgentSideConnection, sessionStore?: SessionStore) {
178
+ this.sessions = {};
179
+ this.client = client;
180
+ this.toolUseCache = {};
181
+ this.fileContentCache = {};
182
+ this.sessionStore = sessionStore;
183
+ }
184
+
185
+ createSession(
186
+ sessionId: string,
187
+ q: Query,
188
+ input: Pushable<SDKUserMessage>,
189
+ permissionMode: PermissionMode,
190
+ ): Session {
191
+ const session: Session = {
192
+ query: q,
193
+ input,
194
+ cancelled: false,
195
+ permissionMode,
196
+ notificationHistory: [],
197
+ };
198
+ this.sessions[sessionId] = session;
199
+ return session;
200
+ }
201
+
202
+ appendNotification(
203
+ sessionId: string,
204
+ notification: SessionNotification,
205
+ ): void {
206
+ // In-memory only - S3 persistence is now automatic via tapped stream
207
+ this.sessions[sessionId]?.notificationHistory.push(notification);
208
+ }
209
+
210
+ async initialize(request: InitializeRequest): Promise<InitializeResponse> {
211
+ this.clientCapabilities = request.clientCapabilities;
212
+
213
+ // Default authMethod
214
+ const authMethod: any = {
215
+ description: "Run `claude /login` in the terminal",
216
+ name: "Log in with Claude Code",
217
+ id: "claude-login",
218
+ };
219
+
220
+ // If client supports terminal-auth capability, use that instead.
221
+ // if (request.clientCapabilities?._meta?.["terminal-auth"] === true) {
222
+ // const cliPath = fileURLToPath(import.meta.resolve("@anthropic-ai/claude-agent-sdk/cli.js"));
223
+
224
+ // authMethod._meta = {
225
+ // "terminal-auth": {
226
+ // command: "node",
227
+ // args: [cliPath, "/login"],
228
+ // label: "Claude Code Login",
229
+ // },
230
+ // };
231
+ // }
232
+
233
+ return {
234
+ protocolVersion: 1,
235
+ agentCapabilities: {
236
+ promptCapabilities: {
237
+ image: true,
238
+ embeddedContext: true,
239
+ },
240
+ mcpCapabilities: {
241
+ http: true,
242
+ sse: true,
243
+ },
244
+ loadSession: true,
245
+ _meta: {
246
+ posthog: {
247
+ resumeSession: true,
248
+ },
249
+ },
250
+ },
251
+ agentInfo: {
252
+ name: packageJson.name,
253
+ title: "Claude Code",
254
+ version: packageJson.version,
255
+ },
256
+ authMethods: [authMethod],
257
+ };
258
+ }
259
+ async newSession(params: NewSessionRequest): Promise<NewSessionResponse> {
260
+ if (
261
+ fs.existsSync(path.resolve(os.homedir(), ".claude.json.backup")) &&
262
+ !fs.existsSync(path.resolve(os.homedir(), ".claude.json"))
263
+ ) {
264
+ throw RequestError.authRequired();
265
+ }
266
+
267
+ // Allow caller to specify sessionId via _meta (e.g. taskRunId in our case)
268
+ const sessionId =
269
+ (params._meta as { sessionId?: string } | undefined)?.sessionId ||
270
+ uuidv7();
271
+ const input = new Pushable<SDKUserMessage>();
272
+
273
+ const mcpServers: Record<string, McpServerConfig> = {};
274
+ if (Array.isArray(params.mcpServers)) {
275
+ for (const server of params.mcpServers) {
276
+ if ("type" in server) {
277
+ mcpServers[server.name] = {
278
+ type: server.type,
279
+ url: server.url,
280
+ headers: server.headers
281
+ ? Object.fromEntries(server.headers.map((e) => [e.name, e.value]))
282
+ : undefined,
283
+ };
284
+ } else {
285
+ mcpServers[server.name] = {
286
+ type: "stdio",
287
+ command: server.command,
288
+ args: server.args,
289
+ env: server.env
290
+ ? Object.fromEntries(server.env.map((e) => [e.name, e.value]))
291
+ : undefined,
292
+ };
293
+ }
294
+ }
295
+ }
296
+
297
+ // Only add the acp MCP server if built-in tools are not disabled
298
+ if (!params._meta?.disableBuiltInTools) {
299
+ const server = createMcpServer(this, sessionId, this.clientCapabilities);
300
+ mcpServers.acp = {
301
+ type: "sdk",
302
+ name: "acp",
303
+ instance: server,
304
+ };
305
+ }
306
+
307
+ let systemPrompt: Options["systemPrompt"] = {
308
+ type: "preset",
309
+ preset: "claude_code",
310
+ };
311
+ if (params._meta?.systemPrompt) {
312
+ const customPrompt = params._meta.systemPrompt;
313
+ if (typeof customPrompt === "string") {
314
+ systemPrompt = customPrompt;
315
+ } else if (
316
+ typeof customPrompt === "object" &&
317
+ "append" in customPrompt &&
318
+ typeof customPrompt.append === "string"
319
+ ) {
320
+ systemPrompt.append = customPrompt.append;
321
+ }
322
+ }
323
+
324
+ const permissionMode = "default";
325
+
326
+ // Extract options from _meta if provided
327
+ const userProvidedOptions = (params._meta as NewSessionMeta | undefined)
328
+ ?.claudeCode?.options;
329
+
330
+ const options: Options = {
331
+ systemPrompt,
332
+ settingSources: ["user", "project", "local"],
333
+ stderr: (err) => this.logger.error(err),
334
+ ...userProvidedOptions,
335
+ // Override certain fields that must be controlled by ACP
336
+ cwd: params.cwd,
337
+ includePartialMessages: true,
338
+ mcpServers: { ...(userProvidedOptions?.mcpServers || {}), ...mcpServers },
339
+ // If we want bypassPermissions to be an option, we have to allow it here.
340
+ // But it doesn't work in root mode, so we only activate it if it will work.
341
+ allowDangerouslySkipPermissions: !IS_ROOT,
342
+ permissionMode,
343
+ canUseTool: this.canUseTool(sessionId),
344
+ // Use "node" to resolve via PATH where a symlink to Electron exists.
345
+ // This avoids launching the Electron binary directly from the app bundle,
346
+ // which can cause dock icons to appear on macOS even with ELECTRON_RUN_AS_NODE.
347
+ executable: "node",
348
+ // Prevent spawned Electron processes from showing in dock/tray.
349
+ // Must merge with process.env since SDK replaces rather than merges.
350
+ env: { ...process.env, ELECTRON_RUN_AS_NODE: "1" },
351
+ ...(process.env.CLAUDE_CODE_EXECUTABLE && {
352
+ pathToClaudeCodeExecutable: process.env.CLAUDE_CODE_EXECUTABLE,
353
+ }),
354
+ hooks: {
355
+ ...userProvidedOptions?.hooks,
356
+ PostToolUse: [
357
+ ...(userProvidedOptions?.hooks?.PostToolUse || []),
358
+ {
359
+ hooks: [createPostToolUseHook(this.logger)],
360
+ },
361
+ ],
362
+ },
363
+ };
364
+
365
+ const allowedTools = [];
366
+ const disallowedTools = [];
367
+
368
+ // Check if built-in tools should be disabled
369
+ const disableBuiltInTools = params._meta?.disableBuiltInTools === true;
370
+
371
+ if (!disableBuiltInTools) {
372
+ if (this.clientCapabilities?.fs?.readTextFile) {
373
+ allowedTools.push(toolNames.read);
374
+ disallowedTools.push("Read");
375
+ }
376
+ if (this.clientCapabilities?.fs?.writeTextFile) {
377
+ disallowedTools.push("Write", "Edit");
378
+ }
379
+ if (this.clientCapabilities?.terminal) {
380
+ allowedTools.push(toolNames.bashOutput, toolNames.killShell);
381
+ disallowedTools.push("Bash", "BashOutput", "KillShell");
382
+ }
383
+ } else {
384
+ // When built-in tools are disabled, explicitly disallow all of them
385
+ disallowedTools.push(
386
+ toolNames.read,
387
+ toolNames.write,
388
+ toolNames.edit,
389
+ toolNames.bash,
390
+ toolNames.bashOutput,
391
+ toolNames.killShell,
392
+ "Read",
393
+ "Write",
394
+ "Edit",
395
+ "Bash",
396
+ "BashOutput",
397
+ "KillShell",
398
+ "Glob",
399
+ "Grep",
400
+ "Task",
401
+ "TodoWrite",
402
+ "ExitPlanMode",
403
+ "WebSearch",
404
+ "WebFetch",
405
+ "AskUserQuestion",
406
+ "SlashCommand",
407
+ "Skill",
408
+ "NotebookEdit",
409
+ );
410
+ }
411
+
412
+ if (allowedTools.length > 0) {
413
+ options.allowedTools = allowedTools;
414
+ }
415
+ if (disallowedTools.length > 0) {
416
+ options.disallowedTools = disallowedTools;
417
+ }
418
+
419
+ // Handle abort controller from meta options
420
+ const abortController = userProvidedOptions?.abortController;
421
+ if (abortController?.signal.aborted) {
422
+ throw new Error("Cancelled");
423
+ }
424
+
425
+ // Clear statsig cache before creating query to avoid input_examples bug
426
+ clearStatsigCache();
427
+
428
+ const q = query({
429
+ prompt: input,
430
+ options,
431
+ });
432
+
433
+ this.createSession(sessionId, q, input, permissionMode);
434
+
435
+ // Register for S3 persistence if config provided
436
+ const persistence = params._meta?.persistence as
437
+ | SessionPersistenceConfig
438
+ | undefined;
439
+ if (persistence && this.sessionStore) {
440
+ this.sessionStore.register(sessionId, persistence);
441
+ }
442
+
443
+ const availableCommands = await getAvailableSlashCommands(q);
444
+ const models = await getAvailableModels(q);
445
+
446
+ // Needs to happen after we return the session
447
+ setTimeout(() => {
448
+ this.client.sessionUpdate({
449
+ sessionId,
450
+ update: {
451
+ sessionUpdate: "available_commands_update",
452
+ availableCommands,
453
+ },
454
+ });
455
+ }, 0);
456
+
457
+ const availableModes = [
458
+ {
459
+ id: "default",
460
+ name: "Always Ask",
461
+ description: "Prompts for permission on first use of each tool",
462
+ },
463
+ {
464
+ id: "acceptEdits",
465
+ name: "Accept Edits",
466
+ description:
467
+ "Automatically accepts file edit permissions for the session",
468
+ },
469
+ {
470
+ id: "plan",
471
+ name: "Plan Mode",
472
+ description:
473
+ "Claude can analyze but not modify files or execute commands",
474
+ },
475
+ ];
476
+ // Only works in non-root mode
477
+ if (!IS_ROOT) {
478
+ availableModes.push({
479
+ id: "bypassPermissions",
480
+ name: "Bypass Permissions",
481
+ description: "Skips all permission prompts",
482
+ });
483
+ }
484
+
485
+ return {
486
+ sessionId,
487
+ models,
488
+ modes: {
489
+ currentModeId: permissionMode,
490
+ availableModes,
491
+ },
492
+ };
493
+ }
494
+
495
+ async authenticate(_params: AuthenticateRequest): Promise<void> {
496
+ throw new Error("Method not implemented.");
497
+ }
498
+
499
+ async prompt(params: PromptRequest): Promise<PromptResponse> {
500
+ if (!this.sessions[params.sessionId]) {
501
+ throw new Error("Session not found");
502
+ }
503
+
504
+ this.sessions[params.sessionId].cancelled = false;
505
+
506
+ const { query, input } = this.sessions[params.sessionId];
507
+
508
+ // Capture and store user message for replay
509
+ for (const chunk of params.prompt) {
510
+ const userNotification: SessionNotification = {
511
+ sessionId: params.sessionId,
512
+ update: {
513
+ sessionUpdate: "user_message_chunk",
514
+ content: chunk,
515
+ },
516
+ };
517
+ await this.client.sessionUpdate(userNotification);
518
+ this.appendNotification(params.sessionId, userNotification);
519
+ }
520
+
521
+ input.push(promptToClaude(params));
522
+ while (true) {
523
+ const { value: message, done } = await query.next();
524
+ if (done || !message) {
525
+ if (this.sessions[params.sessionId].cancelled) {
526
+ return { stopReason: "cancelled" };
527
+ }
528
+ break;
529
+ }
530
+ this.logger.debug("SDK message received", {
531
+ type: message.type,
532
+ subtype: (message as any).subtype,
533
+ });
534
+
535
+ switch (message.type) {
536
+ case "system":
537
+ switch (message.subtype) {
538
+ case "init":
539
+ // Capture SDK session ID and notify client for persistence
540
+ if (message.session_id) {
541
+ const session = this.sessions[params.sessionId];
542
+ if (session && !session.sdkSessionId) {
543
+ session.sdkSessionId = message.session_id;
544
+ this.client.extNotification("_posthog/sdk_session", {
545
+ sessionId: params.sessionId,
546
+ sdkSessionId: message.session_id,
547
+ });
548
+ }
549
+ }
550
+ break;
551
+ case "compact_boundary":
552
+ case "hook_response":
553
+ case "status":
554
+ // Todo: process via status api: https://docs.claude.com/en/docs/claude-code/hooks#hook-output
555
+ break;
556
+ default:
557
+ unreachable(message, this.logger);
558
+ break;
559
+ }
560
+ break;
561
+ case "result": {
562
+ if (this.sessions[params.sessionId].cancelled) {
563
+ return { stopReason: "cancelled" };
564
+ }
565
+
566
+ switch (message.subtype) {
567
+ case "success": {
568
+ if (message.result.includes("Please run /login")) {
569
+ throw RequestError.authRequired();
570
+ }
571
+ if (message.is_error) {
572
+ throw RequestError.internalError(undefined, message.result);
573
+ }
574
+ return { stopReason: "end_turn" };
575
+ }
576
+ case "error_during_execution":
577
+ if (message.is_error) {
578
+ throw RequestError.internalError(
579
+ undefined,
580
+ message.errors.join(", ") || message.subtype,
581
+ );
582
+ }
583
+ return { stopReason: "end_turn" };
584
+ case "error_max_budget_usd":
585
+ case "error_max_turns":
586
+ case "error_max_structured_output_retries":
587
+ if (message.is_error) {
588
+ throw RequestError.internalError(
589
+ undefined,
590
+ message.errors.join(", ") || message.subtype,
591
+ );
592
+ }
593
+ return { stopReason: "max_turn_requests" };
594
+ default:
595
+ unreachable(message, this.logger);
596
+ break;
597
+ }
598
+ break;
599
+ }
600
+ case "stream_event": {
601
+ this.logger.debug("Stream event", { eventType: message.event?.type });
602
+ for (const notification of streamEventToAcpNotifications(
603
+ message,
604
+ params.sessionId,
605
+ this.toolUseCache,
606
+ this.fileContentCache,
607
+ this.client,
608
+ this.logger,
609
+ )) {
610
+ await this.client.sessionUpdate(notification);
611
+ this.appendNotification(params.sessionId, notification);
612
+ }
613
+ break;
614
+ }
615
+ case "user":
616
+ case "assistant": {
617
+ if (this.sessions[params.sessionId].cancelled) {
618
+ break;
619
+ }
620
+
621
+ // Slash commands like /compact can generate invalid output... doesn't match
622
+ // their own docs: https://docs.anthropic.com/en/docs/claude-code/sdk/sdk-slash-commands#%2Fcompact-compact-conversation-history
623
+ if (
624
+ typeof message.message.content === "string" &&
625
+ message.message.content.includes("<local-command-stdout>")
626
+ ) {
627
+ this.logger.info(message.message.content);
628
+ break;
629
+ }
630
+
631
+ if (
632
+ typeof message.message.content === "string" &&
633
+ message.message.content.includes("<local-command-stderr>")
634
+ ) {
635
+ this.logger.error(message.message.content);
636
+ break;
637
+ }
638
+ // Skip these user messages for now, since they seem to just be messages we don't want in the feed
639
+ if (
640
+ message.type === "user" &&
641
+ (typeof message.message.content === "string" ||
642
+ (Array.isArray(message.message.content) &&
643
+ message.message.content.length === 1 &&
644
+ message.message.content[0].type === "text"))
645
+ ) {
646
+ break;
647
+ }
648
+
649
+ if (
650
+ message.type === "assistant" &&
651
+ message.message.model === "<synthetic>" &&
652
+ Array.isArray(message.message.content) &&
653
+ message.message.content.length === 1 &&
654
+ message.message.content[0].type === "text" &&
655
+ message.message.content[0].text.includes("Please run /login")
656
+ ) {
657
+ throw RequestError.authRequired();
658
+ }
659
+
660
+ // For assistant messages, text/thinking are normally streamed via stream_event.
661
+ // But some gateways (like LiteLLM) don't stream, so we process all content.
662
+ const content = message.message.content;
663
+
664
+ for (const notification of toAcpNotifications(
665
+ content,
666
+ message.message.role,
667
+ params.sessionId,
668
+ this.toolUseCache,
669
+ this.fileContentCache,
670
+ this.client,
671
+ this.logger,
672
+ )) {
673
+ await this.client.sessionUpdate(notification);
674
+ this.appendNotification(params.sessionId, notification);
675
+ }
676
+ break;
677
+ }
678
+ case "tool_progress":
679
+ break;
680
+ case "auth_status":
681
+ break;
682
+ default:
683
+ unreachable(message, this.logger);
684
+ break;
685
+ }
686
+ }
687
+ throw new Error("Session did not end in result");
688
+ }
689
+
690
+ async cancel(params: CancelNotification): Promise<void> {
691
+ if (!this.sessions[params.sessionId]) {
692
+ throw new Error("Session not found");
693
+ }
694
+ this.sessions[params.sessionId].cancelled = true;
695
+ await this.sessions[params.sessionId].query.interrupt();
696
+ }
697
+
698
+ async setSessionModel(params: SetSessionModelRequest) {
699
+ if (!this.sessions[params.sessionId]) {
700
+ throw new Error("Session not found");
701
+ }
702
+ await this.sessions[params.sessionId].query.setModel(params.modelId);
703
+ }
704
+
705
+ async setSessionMode(
706
+ params: SetSessionModeRequest,
707
+ ): Promise<SetSessionModeResponse> {
708
+ if (!this.sessions[params.sessionId]) {
709
+ throw new Error("Session not found");
710
+ }
711
+
712
+ switch (params.modeId) {
713
+ case "default":
714
+ case "acceptEdits":
715
+ case "bypassPermissions":
716
+ case "plan":
717
+ this.sessions[params.sessionId].permissionMode = params.modeId;
718
+ try {
719
+ await this.sessions[params.sessionId].query.setPermissionMode(
720
+ params.modeId,
721
+ );
722
+ } catch (error) {
723
+ const errorMessage =
724
+ error instanceof Error && error.message
725
+ ? error.message
726
+ : "Invalid Mode";
727
+
728
+ throw new Error(errorMessage);
729
+ }
730
+ return {};
731
+ default:
732
+ throw new Error("Invalid Mode");
733
+ }
734
+ }
735
+
736
+ async readTextFile(
737
+ params: ReadTextFileRequest,
738
+ ): Promise<ReadTextFileResponse> {
739
+ const response = await this.client.readTextFile(params);
740
+ if (!params.limit && !params.line) {
741
+ this.fileContentCache[params.path] = response.content;
742
+ }
743
+ return response;
744
+ }
745
+
746
+ async writeTextFile(
747
+ params: WriteTextFileRequest,
748
+ ): Promise<WriteTextFileResponse> {
749
+ const response = await this.client.writeTextFile(params);
750
+ this.fileContentCache[params.path] = params.content;
751
+ return response;
752
+ }
753
+
754
+ /**
755
+ * Load session delegates to resumeSession since we have no need to replay history.
756
+ * Client is responsible for fetching and rendering history from S3.
757
+ */
758
+ async loadSession(params: LoadSessionRequest): Promise<LoadSessionResponse> {
759
+ return this.resumeSession(params);
760
+ }
761
+
762
+ canUseTool(sessionId: string): CanUseTool {
763
+ return async (toolName, toolInput, { suggestions, toolUseID }) => {
764
+ const session = this.sessions[sessionId];
765
+ if (!session) {
766
+ return {
767
+ behavior: "deny",
768
+ message: "Session not found",
769
+ interrupt: true,
770
+ };
771
+ }
772
+
773
+ if (toolName === "ExitPlanMode") {
774
+ const response = await this.client.requestPermission({
775
+ options: [
776
+ {
777
+ kind: "allow_always",
778
+ name: "Yes, and auto-accept edits",
779
+ optionId: "acceptEdits",
780
+ },
781
+ {
782
+ kind: "allow_once",
783
+ name: "Yes, and manually approve edits",
784
+ optionId: "default",
785
+ },
786
+ {
787
+ kind: "reject_once",
788
+ name: "No, keep planning",
789
+ optionId: "plan",
790
+ },
791
+ ],
792
+ sessionId,
793
+ toolCall: {
794
+ toolCallId: toolUseID,
795
+ rawInput: toolInput,
796
+ title: toolInfoFromToolUse(
797
+ { name: toolName, input: toolInput },
798
+ this.fileContentCache,
799
+ this.logger,
800
+ ).title,
801
+ },
802
+ });
803
+
804
+ if (
805
+ response.outcome?.outcome === "selected" &&
806
+ (response.outcome.optionId === "default" ||
807
+ response.outcome.optionId === "acceptEdits")
808
+ ) {
809
+ session.permissionMode = response.outcome.optionId;
810
+ await this.client.sessionUpdate({
811
+ sessionId,
812
+ update: {
813
+ sessionUpdate: "current_mode_update",
814
+ currentModeId: response.outcome.optionId,
815
+ },
816
+ });
817
+
818
+ return {
819
+ behavior: "allow",
820
+ updatedInput: toolInput,
821
+ updatedPermissions: suggestions ?? [
822
+ {
823
+ type: "setMode",
824
+ mode: response.outcome.optionId,
825
+ destination: "session",
826
+ },
827
+ ],
828
+ };
829
+ } else {
830
+ return {
831
+ behavior: "deny",
832
+ message: "User rejected request to exit plan mode.",
833
+ interrupt: true,
834
+ };
835
+ }
836
+ }
837
+
838
+ if (
839
+ session.permissionMode === "bypassPermissions" ||
840
+ (session.permissionMode === "acceptEdits" &&
841
+ EDIT_TOOL_NAMES.includes(toolName))
842
+ ) {
843
+ return {
844
+ behavior: "allow",
845
+ updatedInput: toolInput,
846
+ updatedPermissions: suggestions ?? [
847
+ {
848
+ type: "addRules",
849
+ rules: [{ toolName }],
850
+ behavior: "allow",
851
+ destination: "session",
852
+ },
853
+ ],
854
+ };
855
+ }
856
+
857
+ const response = await this.client.requestPermission({
858
+ options: [
859
+ {
860
+ kind: "allow_always",
861
+ name: "Always Allow",
862
+ optionId: "allow_always",
863
+ },
864
+ { kind: "allow_once", name: "Allow", optionId: "allow" },
865
+ { kind: "reject_once", name: "Reject", optionId: "reject" },
866
+ ],
867
+ sessionId,
868
+ toolCall: {
869
+ toolCallId: toolUseID,
870
+ rawInput: toolInput,
871
+ title: toolInfoFromToolUse(
872
+ { name: toolName, input: toolInput },
873
+ this.fileContentCache,
874
+ this.logger,
875
+ ).title,
876
+ },
877
+ });
878
+ if (
879
+ response.outcome?.outcome === "selected" &&
880
+ (response.outcome.optionId === "allow" ||
881
+ response.outcome.optionId === "allow_always")
882
+ ) {
883
+ // If Claude Code has suggestions, it will update their settings already
884
+ if (response.outcome.optionId === "allow_always") {
885
+ return {
886
+ behavior: "allow",
887
+ updatedInput: toolInput,
888
+ updatedPermissions: suggestions ?? [
889
+ {
890
+ type: "addRules",
891
+ rules: [{ toolName }],
892
+ behavior: "allow",
893
+ destination: "session",
894
+ },
895
+ ],
896
+ };
897
+ }
898
+ return {
899
+ behavior: "allow",
900
+ updatedInput: toolInput,
901
+ };
902
+ } else {
903
+ return {
904
+ behavior: "deny",
905
+ message: "User refused permission to run tool",
906
+ interrupt: true,
907
+ };
908
+ }
909
+ };
910
+ }
911
+
912
+ /**
913
+ * Handle custom extension methods.
914
+ * Per ACP spec, extension methods start with underscore.
915
+ */
916
+ async extMethod(
917
+ method: string,
918
+ params: Record<string, unknown>,
919
+ ): Promise<Record<string, unknown>> {
920
+ if (method === "_posthog/session/resume") {
921
+ await this.resumeSession(params as unknown as LoadSessionRequest);
922
+ return {};
923
+ }
924
+
925
+ throw RequestError.methodNotFound(method);
926
+ }
927
+
928
+ /**
929
+ * Resume a session without replaying history.
930
+ * Client is responsible for fetching and rendering history from S3.
931
+ * This basically implemetns the ACP session/resume RFD:
932
+ * https://agentclientprotocol.com/rfds/session-resume
933
+ */
934
+ async resumeSession(
935
+ params: LoadSessionRequest,
936
+ ): Promise<LoadSessionResponse> {
937
+ this.logger.info("[RESUME] Resuming session", { params });
938
+ const { sessionId } = params;
939
+
940
+ // Extract persistence config and SDK session ID from _meta
941
+ const persistence = params._meta?.persistence as
942
+ | SessionPersistenceConfig
943
+ | undefined;
944
+ const sdkSessionId = params._meta?.sdkSessionId as string | undefined;
945
+
946
+ if (!this.sessions[sessionId]) {
947
+ const input = new Pushable<SDKUserMessage>();
948
+
949
+ const mcpServers: Record<string, McpServerConfig> = {};
950
+ if (Array.isArray(params.mcpServers)) {
951
+ for (const server of params.mcpServers) {
952
+ if ("type" in server) {
953
+ mcpServers[server.name] = {
954
+ type: server.type,
955
+ url: server.url,
956
+ headers: server.headers
957
+ ? Object.fromEntries(
958
+ server.headers.map((e) => [e.name, e.value]),
959
+ )
960
+ : undefined,
961
+ };
962
+ } else {
963
+ mcpServers[server.name] = {
964
+ type: "stdio",
965
+ command: server.command,
966
+ args: server.args,
967
+ env: server.env
968
+ ? Object.fromEntries(server.env.map((e) => [e.name, e.value]))
969
+ : undefined,
970
+ };
971
+ }
972
+ }
973
+ }
974
+
975
+ const server = createMcpServer(this, sessionId, this.clientCapabilities);
976
+ mcpServers.acp = {
977
+ type: "sdk",
978
+ name: "acp",
979
+ instance: server,
980
+ };
981
+
982
+ const permissionMode = "default";
983
+
984
+ this.logger.info("Resuming session", {
985
+ cwd: params.cwd,
986
+ sdkSessionId,
987
+ persistence,
988
+ });
989
+ const options: Options = {
990
+ cwd: params.cwd,
991
+ includePartialMessages: true,
992
+ mcpServers,
993
+ systemPrompt: { type: "preset", preset: "claude_code" },
994
+ settingSources: ["user", "project", "local"],
995
+ allowDangerouslySkipPermissions: !IS_ROOT,
996
+ permissionMode,
997
+ canUseTool: this.canUseTool(sessionId),
998
+ stderr: (err) => this.logger.error(err),
999
+ // Use "node" to resolve via PATH where a symlink to Electron exists.
1000
+ // This avoids launching the Electron binary directly from the app bundle,
1001
+ // which can cause dock icons to appear on macOS even with ELECTRON_RUN_AS_NODE.
1002
+ executable: "node",
1003
+ // Prevent spawned Electron processes from showing in dock/tray.
1004
+ // Must merge with process.env since SDK replaces rather than merges.
1005
+ env: { ...process.env, ELECTRON_RUN_AS_NODE: "1" },
1006
+ ...(process.env.CLAUDE_CODE_EXECUTABLE && {
1007
+ pathToClaudeCodeExecutable: process.env.CLAUDE_CODE_EXECUTABLE,
1008
+ }),
1009
+ // Resume from SDK session if available
1010
+ ...(sdkSessionId && { resume: sdkSessionId }),
1011
+ hooks: {
1012
+ PostToolUse: [
1013
+ {
1014
+ hooks: [createPostToolUseHook(this.logger)],
1015
+ },
1016
+ ],
1017
+ },
1018
+ };
1019
+
1020
+ // Clear statsig cache before creating query to avoid input_examples bug
1021
+ clearStatsigCache();
1022
+
1023
+ const q = query({
1024
+ prompt: input,
1025
+ options,
1026
+ });
1027
+
1028
+ const availableCommands = await getAvailableSlashCommands(q);
1029
+
1030
+ const newSession = this.createSession(
1031
+ sessionId,
1032
+ q,
1033
+ input,
1034
+ permissionMode,
1035
+ );
1036
+
1037
+ // Store SDK session ID if resuming
1038
+ if (sdkSessionId) {
1039
+ newSession.sdkSessionId = sdkSessionId;
1040
+ }
1041
+
1042
+ // Register for future persistence
1043
+ if (persistence && this.sessionStore) {
1044
+ this.sessionStore.register(sessionId, persistence);
1045
+ }
1046
+
1047
+ setTimeout(() => {
1048
+ this.client.sessionUpdate({
1049
+ sessionId,
1050
+ update: {
1051
+ sessionUpdate: "available_commands_update",
1052
+ availableCommands,
1053
+ },
1054
+ });
1055
+ }, 0);
1056
+ }
1057
+
1058
+ return {};
1059
+ }
1060
+ }
1061
+
1062
+ async function getAvailableModels(query: Query): Promise<SessionModelState> {
1063
+ const models = await query.supportedModels();
1064
+
1065
+ // Query doesn't give us access to the currently selected model, so we just choose the first model in the list.
1066
+ const currentModel = models[0];
1067
+ await query.setModel(currentModel.value);
1068
+
1069
+ const availableModels = models.map((model) => ({
1070
+ modelId: model.value,
1071
+ name: model.displayName,
1072
+ description: model.description,
1073
+ }));
1074
+
1075
+ return {
1076
+ availableModels,
1077
+ currentModelId: currentModel.value,
1078
+ };
1079
+ }
1080
+
1081
+ async function getAvailableSlashCommands(
1082
+ query: Query,
1083
+ ): Promise<AvailableCommand[]> {
1084
+ const UNSUPPORTED_COMMANDS = [
1085
+ "context",
1086
+ "cost",
1087
+ "login",
1088
+ "logout",
1089
+ "output-style:new",
1090
+ "release-notes",
1091
+ "todos",
1092
+ ];
1093
+ const commands = await query.supportedCommands();
1094
+
1095
+ return commands
1096
+ .map((command) => {
1097
+ const input = command.argumentHint
1098
+ ? { hint: command.argumentHint }
1099
+ : null;
1100
+ let name = command.name;
1101
+ if (command.name.endsWith(" (MCP)")) {
1102
+ name = `mcp:${name.replace(" (MCP)", "")}`;
1103
+ }
1104
+ return {
1105
+ name,
1106
+ description: command.description || "",
1107
+ input,
1108
+ };
1109
+ })
1110
+ .filter(
1111
+ (command: AvailableCommand) =>
1112
+ !UNSUPPORTED_COMMANDS.includes(command.name),
1113
+ );
1114
+ }
1115
+
1116
+ function formatUriAsLink(uri: string): string {
1117
+ try {
1118
+ if (uri.startsWith("file://")) {
1119
+ const path = uri.slice(7); // Remove "file://"
1120
+ const name = path.split("/").pop() || path;
1121
+ return `[@${name}](${uri})`;
1122
+ } else if (uri.startsWith("zed://")) {
1123
+ const parts = uri.split("/");
1124
+ const name = parts[parts.length - 1] || uri;
1125
+ return `[@${name}](${uri})`;
1126
+ }
1127
+ return uri;
1128
+ } catch {
1129
+ return uri;
1130
+ }
1131
+ }
1132
+
1133
+ export function promptToClaude(prompt: PromptRequest): SDKUserMessage {
1134
+ const content: any[] = [];
1135
+ const context: any[] = [];
1136
+
1137
+ for (const chunk of prompt.prompt) {
1138
+ switch (chunk.type) {
1139
+ case "text": {
1140
+ let text = chunk.text;
1141
+ // change /mcp:server:command args -> /server:command (MCP) args
1142
+ const mcpMatch = text.match(/^\/mcp:([^:\s]+):(\S+)(\s+.*)?$/);
1143
+ if (mcpMatch) {
1144
+ const [, server, command, args] = mcpMatch;
1145
+ text = `/${server}:${command} (MCP)${args || ""}`;
1146
+ }
1147
+ content.push({ type: "text", text });
1148
+ break;
1149
+ }
1150
+ case "resource_link": {
1151
+ const formattedUri = formatUriAsLink(chunk.uri);
1152
+ content.push({
1153
+ type: "text",
1154
+ text: formattedUri,
1155
+ });
1156
+ break;
1157
+ }
1158
+ case "resource": {
1159
+ if ("text" in chunk.resource) {
1160
+ const formattedUri = formatUriAsLink(chunk.resource.uri);
1161
+ content.push({
1162
+ type: "text",
1163
+ text: formattedUri,
1164
+ });
1165
+ context.push({
1166
+ type: "text",
1167
+ text: `\n<context ref="${chunk.resource.uri}">\n${chunk.resource.text}\n</context>`,
1168
+ });
1169
+ }
1170
+ // Ignore blob resources (unsupported)
1171
+ break;
1172
+ }
1173
+ case "image":
1174
+ if (chunk.data) {
1175
+ content.push({
1176
+ type: "image",
1177
+ source: {
1178
+ type: "base64",
1179
+ data: chunk.data,
1180
+ media_type: chunk.mimeType,
1181
+ },
1182
+ });
1183
+ } else if (chunk.uri?.startsWith("http")) {
1184
+ content.push({
1185
+ type: "image",
1186
+ source: {
1187
+ type: "url",
1188
+ url: chunk.uri,
1189
+ },
1190
+ });
1191
+ }
1192
+ break;
1193
+ // Ignore audio and other unsupported types
1194
+ default:
1195
+ break;
1196
+ }
1197
+ }
1198
+
1199
+ content.push(...context);
1200
+
1201
+ return {
1202
+ type: "user",
1203
+ message: {
1204
+ role: "user",
1205
+ content: content,
1206
+ },
1207
+ session_id: prompt.sessionId,
1208
+ parent_tool_use_id: null,
1209
+ };
1210
+ }
1211
+
1212
+ /**
1213
+ * Convert an SDKAssistantMessage (Claude) to a SessionNotification (ACP).
1214
+ * Only handles text, image, and thinking chunks for now.
1215
+ */
1216
+ export function toAcpNotifications(
1217
+ content:
1218
+ | string
1219
+ | ContentBlockParam[]
1220
+ | BetaContentBlock[]
1221
+ | BetaRawContentBlockDelta[],
1222
+ role: "assistant" | "user",
1223
+ sessionId: string,
1224
+ toolUseCache: ToolUseCache,
1225
+ fileContentCache: { [key: string]: string },
1226
+ client: AgentSideConnection,
1227
+ logger: Logger,
1228
+ ): SessionNotification[] {
1229
+ if (typeof content === "string") {
1230
+ return [
1231
+ {
1232
+ sessionId,
1233
+ update: {
1234
+ sessionUpdate:
1235
+ role === "assistant" ? "agent_message_chunk" : "user_message_chunk",
1236
+ content: {
1237
+ type: "text",
1238
+ text: content,
1239
+ },
1240
+ },
1241
+ },
1242
+ ];
1243
+ }
1244
+
1245
+ const output = [];
1246
+ // Only handle the first chunk for streaming; extend as needed for batching
1247
+ for (const chunk of content) {
1248
+ let update: SessionNotification["update"] | null = null;
1249
+ switch (chunk.type) {
1250
+ case "text":
1251
+ case "text_delta":
1252
+ update = {
1253
+ sessionUpdate:
1254
+ role === "assistant" ? "agent_message_chunk" : "user_message_chunk",
1255
+ content: {
1256
+ type: "text",
1257
+ text: chunk.text,
1258
+ },
1259
+ };
1260
+ break;
1261
+ case "image":
1262
+ update = {
1263
+ sessionUpdate:
1264
+ role === "assistant" ? "agent_message_chunk" : "user_message_chunk",
1265
+ content: {
1266
+ type: "image",
1267
+ data: chunk.source.type === "base64" ? chunk.source.data : "",
1268
+ mimeType:
1269
+ chunk.source.type === "base64" ? chunk.source.media_type : "",
1270
+ uri: chunk.source.type === "url" ? chunk.source.url : undefined,
1271
+ },
1272
+ };
1273
+ break;
1274
+ case "thinking":
1275
+ case "thinking_delta":
1276
+ update = {
1277
+ sessionUpdate: "agent_thought_chunk",
1278
+ content: {
1279
+ type: "text",
1280
+ text: chunk.thinking,
1281
+ },
1282
+ };
1283
+ break;
1284
+ case "tool_use":
1285
+ case "server_tool_use":
1286
+ case "mcp_tool_use": {
1287
+ toolUseCache[chunk.id] = chunk;
1288
+ if (chunk.name === "TodoWrite") {
1289
+ // @ts-expect-error - sometimes input is empty object
1290
+ if (Array.isArray(chunk.input.todos)) {
1291
+ update = {
1292
+ sessionUpdate: "plan",
1293
+ entries: planEntries(chunk.input as { todos: ClaudePlanEntry[] }),
1294
+ };
1295
+ }
1296
+ } else {
1297
+ // Register hook callback to receive the structured output from the hook
1298
+ registerHookCallback(chunk.id, {
1299
+ onPostToolUseHook: async (toolUseId, _toolInput, toolResponse) => {
1300
+ const toolUse = toolUseCache[toolUseId];
1301
+ if (toolUse) {
1302
+ const update: SessionNotification["update"] = {
1303
+ _meta: {
1304
+ claudeCode: {
1305
+ toolResponse,
1306
+ toolName: toolUse.name,
1307
+ },
1308
+ } satisfies ToolUpdateMeta,
1309
+ toolCallId: toolUseId,
1310
+ sessionUpdate: "tool_call_update",
1311
+ };
1312
+ await client.sessionUpdate({
1313
+ sessionId,
1314
+ update,
1315
+ });
1316
+ } else {
1317
+ logger.error(
1318
+ `[claude-code-acp] Got a tool response for tool use that wasn't tracked: ${toolUseId}`,
1319
+ );
1320
+ }
1321
+ },
1322
+ });
1323
+
1324
+ let rawInput: Record<string, unknown> | undefined;
1325
+ try {
1326
+ rawInput = JSON.parse(JSON.stringify(chunk.input));
1327
+ } catch {
1328
+ // ignore if we can't turn it to JSON
1329
+ }
1330
+ update = {
1331
+ _meta: {
1332
+ claudeCode: {
1333
+ toolName: chunk.name,
1334
+ },
1335
+ } satisfies ToolUpdateMeta,
1336
+ toolCallId: chunk.id,
1337
+ sessionUpdate: "tool_call",
1338
+ rawInput,
1339
+ status: "pending",
1340
+ ...toolInfoFromToolUse(chunk, fileContentCache, logger),
1341
+ };
1342
+ }
1343
+ break;
1344
+ }
1345
+
1346
+ case "tool_result":
1347
+ case "tool_search_tool_result":
1348
+ case "web_fetch_tool_result":
1349
+ case "web_search_tool_result":
1350
+ case "code_execution_tool_result":
1351
+ case "bash_code_execution_tool_result":
1352
+ case "text_editor_code_execution_tool_result":
1353
+ case "mcp_tool_result": {
1354
+ const toolUse = toolUseCache[chunk.tool_use_id];
1355
+ if (!toolUse) {
1356
+ logger.error(
1357
+ `[claude-code-acp] Got a tool result for tool use that wasn't tracked: ${chunk.tool_use_id}`,
1358
+ );
1359
+ break;
1360
+ }
1361
+
1362
+ if (toolUse.name !== "TodoWrite") {
1363
+ update = {
1364
+ _meta: {
1365
+ claudeCode: {
1366
+ toolName: toolUse.name,
1367
+ },
1368
+ } satisfies ToolUpdateMeta,
1369
+ toolCallId: chunk.tool_use_id,
1370
+ sessionUpdate: "tool_call_update",
1371
+ status:
1372
+ "is_error" in chunk && chunk.is_error ? "failed" : "completed",
1373
+ ...toolUpdateFromToolResult(chunk, toolUseCache[chunk.tool_use_id]),
1374
+ };
1375
+ }
1376
+ break;
1377
+ }
1378
+
1379
+ case "document":
1380
+ case "search_result":
1381
+ case "redacted_thinking":
1382
+ case "input_json_delta":
1383
+ case "citations_delta":
1384
+ case "signature_delta":
1385
+ case "container_upload":
1386
+ break;
1387
+
1388
+ default:
1389
+ unreachable(chunk, logger);
1390
+ break;
1391
+ }
1392
+ if (update) {
1393
+ output.push({ sessionId, update });
1394
+ }
1395
+ }
1396
+
1397
+ return output;
1398
+ }
1399
+
1400
+ export function streamEventToAcpNotifications(
1401
+ message: SDKPartialAssistantMessage,
1402
+ sessionId: string,
1403
+ toolUseCache: ToolUseCache,
1404
+ fileContentCache: { [key: string]: string },
1405
+ client: AgentSideConnection,
1406
+ logger: Logger,
1407
+ ): SessionNotification[] {
1408
+ const event = message.event;
1409
+ switch (event.type) {
1410
+ case "content_block_start":
1411
+ return toAcpNotifications(
1412
+ [event.content_block],
1413
+ "assistant",
1414
+ sessionId,
1415
+ toolUseCache,
1416
+ fileContentCache,
1417
+ client,
1418
+ logger,
1419
+ );
1420
+ case "content_block_delta":
1421
+ return toAcpNotifications(
1422
+ [event.delta],
1423
+ "assistant",
1424
+ sessionId,
1425
+ toolUseCache,
1426
+ fileContentCache,
1427
+ client,
1428
+ logger,
1429
+ );
1430
+ // No content
1431
+ case "message_start":
1432
+ case "message_delta":
1433
+ case "message_stop":
1434
+ case "content_block_stop":
1435
+ return [];
1436
+
1437
+ default:
1438
+ unreachable(event, logger);
1439
+ return [];
1440
+ }
1441
+ }
1442
+
1443
+ export type AcpConnectionConfig = {
1444
+ sessionStore?: SessionStore;
1445
+ sessionId?: string;
1446
+ taskId?: string;
1447
+ };
1448
+
1449
+ export type InProcessAcpConnection = {
1450
+ agentConnection: AgentSideConnection;
1451
+ clientStreams: StreamPair;
1452
+ };
1453
+
1454
+ export function createAcpConnection(
1455
+ config: AcpConnectionConfig = {},
1456
+ ): InProcessAcpConnection {
1457
+ const logger = new Logger({ debug: true, prefix: "[AcpConnection]" });
1458
+ const streams = createBidirectionalStreams();
1459
+
1460
+ const { sessionStore } = config;
1461
+
1462
+ // Tap both streams for automatic persistence
1463
+ // All messages (bidirectional) will be persisted as they flow through
1464
+ let agentWritable = streams.agent.writable;
1465
+ let clientWritable = streams.client.writable;
1466
+
1467
+ if (config.sessionId && sessionStore) {
1468
+ // Register session for persistence BEFORE tapping streams
1469
+ // This ensures all messages from the start get persisted
1470
+ if (!sessionStore.isRegistered(config.sessionId)) {
1471
+ sessionStore.register(config.sessionId, {
1472
+ taskId: config.taskId ?? config.sessionId,
1473
+ runId: config.sessionId,
1474
+ logUrl: "", // Will be updated when we get the real logUrl
1475
+ });
1476
+ }
1477
+
1478
+ // Tap agent→client stream
1479
+ agentWritable = createTappedWritableStream(streams.agent.writable, {
1480
+ onMessage: (line) => {
1481
+ sessionStore.appendRawLine(config.sessionId!, line);
1482
+ },
1483
+ logger,
1484
+ });
1485
+
1486
+ // Tap client→agent stream
1487
+ clientWritable = createTappedWritableStream(streams.client.writable, {
1488
+ onMessage: (line) => {
1489
+ sessionStore.appendRawLine(config.sessionId!, line);
1490
+ },
1491
+ logger,
1492
+ });
1493
+ } else {
1494
+ logger.info("Tapped streams NOT enabled", {
1495
+ hasSessionId: !!config.sessionId,
1496
+ hasSessionStore: !!sessionStore,
1497
+ });
1498
+ }
1499
+
1500
+ const agentStream = ndJsonStream(agentWritable, streams.agent.readable);
1501
+
1502
+ const agentConnection = new AgentSideConnection(
1503
+ (client) => new ClaudeAcpAgent(client, sessionStore),
1504
+ agentStream,
1505
+ );
1506
+
1507
+ return {
1508
+ agentConnection,
1509
+ clientStreams: {
1510
+ readable: streams.client.readable,
1511
+ writable: clientWritable,
1512
+ },
1513
+ };
1514
+ }