groundswell 0.0.2 → 1.0.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 (554) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -9
  3. package/dist/cache/cache-key.d.ts +86 -0
  4. package/dist/cache/cache-key.d.ts.map +1 -0
  5. package/dist/cache/cache-key.js +204 -0
  6. package/dist/cache/cache-key.js.map +1 -0
  7. package/dist/cache/cache.d.ts +104 -0
  8. package/dist/cache/cache.d.ts.map +1 -0
  9. package/dist/cache/cache.js +179 -0
  10. package/dist/cache/cache.js.map +1 -0
  11. package/{src/cache/index.ts → dist/cache/index.d.ts} +1 -1
  12. package/dist/cache/index.d.ts.map +1 -0
  13. package/dist/cache/index.js +6 -0
  14. package/dist/cache/index.js.map +1 -0
  15. package/dist/core/agent.d.ts +203 -0
  16. package/dist/core/agent.d.ts.map +1 -0
  17. package/dist/core/agent.js +833 -0
  18. package/dist/core/agent.js.map +1 -0
  19. package/{src/core/context.ts → dist/core/context.d.ts} +16 -67
  20. package/dist/core/context.d.ts.map +1 -0
  21. package/dist/core/context.js +80 -0
  22. package/dist/core/context.js.map +1 -0
  23. package/dist/core/event-tree.d.ts +72 -0
  24. package/dist/core/event-tree.d.ts.map +1 -0
  25. package/dist/core/event-tree.js +211 -0
  26. package/dist/core/event-tree.js.map +1 -0
  27. package/{src/core/factory.ts → dist/core/factory.d.ts} +6 -27
  28. package/dist/core/factory.d.ts.map +1 -0
  29. package/dist/core/factory.js +110 -0
  30. package/dist/core/factory.js.map +1 -0
  31. package/{src/core/index.ts → dist/core/index.d.ts} +2 -10
  32. package/dist/core/index.d.ts.map +1 -0
  33. package/dist/core/index.js +9 -0
  34. package/dist/core/index.js.map +1 -0
  35. package/dist/core/logger.d.ts +50 -0
  36. package/dist/core/logger.d.ts.map +1 -0
  37. package/dist/core/logger.js +91 -0
  38. package/dist/core/logger.js.map +1 -0
  39. package/dist/core/mcp-handler.d.ts +127 -0
  40. package/dist/core/mcp-handler.d.ts.map +1 -0
  41. package/dist/core/mcp-handler.js +323 -0
  42. package/dist/core/mcp-handler.js.map +1 -0
  43. package/dist/core/prompt.d.ts +80 -0
  44. package/dist/core/prompt.d.ts.map +1 -0
  45. package/dist/core/prompt.js +120 -0
  46. package/dist/core/prompt.js.map +1 -0
  47. package/dist/core/workflow-context.d.ts +61 -0
  48. package/dist/core/workflow-context.d.ts.map +1 -0
  49. package/dist/core/workflow-context.js +358 -0
  50. package/dist/core/workflow-context.js.map +1 -0
  51. package/dist/core/workflow.d.ts +543 -0
  52. package/dist/core/workflow.d.ts.map +1 -0
  53. package/dist/core/workflow.js +986 -0
  54. package/dist/core/workflow.js.map +1 -0
  55. package/dist/debugger/event-replayer.d.ts +422 -0
  56. package/dist/debugger/event-replayer.d.ts.map +1 -0
  57. package/dist/debugger/event-replayer.js +639 -0
  58. package/dist/debugger/event-replayer.js.map +1 -0
  59. package/dist/debugger/index.d.ts +2 -0
  60. package/dist/debugger/index.d.ts.map +1 -0
  61. package/{src/debugger/index.ts → dist/debugger/index.js} +1 -0
  62. package/dist/debugger/index.js.map +1 -0
  63. package/dist/debugger/tree-debugger.d.ts +240 -0
  64. package/dist/debugger/tree-debugger.d.ts.map +1 -0
  65. package/dist/debugger/tree-debugger.js +620 -0
  66. package/dist/debugger/tree-debugger.js.map +1 -0
  67. package/dist/decorators/index.d.ts +4 -0
  68. package/dist/decorators/index.d.ts.map +1 -0
  69. package/{src/decorators/index.ts → dist/decorators/index.js} +1 -0
  70. package/dist/decorators/index.js.map +1 -0
  71. package/dist/decorators/observed-state.d.ts +32 -0
  72. package/dist/decorators/observed-state.d.ts.map +1 -0
  73. package/dist/decorators/observed-state.js +79 -0
  74. package/dist/decorators/observed-state.js.map +1 -0
  75. package/dist/decorators/step.d.ts +15 -0
  76. package/dist/decorators/step.d.ts.map +1 -0
  77. package/dist/decorators/step.js +192 -0
  78. package/dist/decorators/step.js.map +1 -0
  79. package/dist/decorators/task.d.ts +50 -0
  80. package/dist/decorators/task.d.ts.map +1 -0
  81. package/dist/decorators/task.js +118 -0
  82. package/dist/decorators/task.js.map +1 -0
  83. package/dist/examples/index.d.ts +3 -0
  84. package/dist/examples/index.d.ts.map +1 -0
  85. package/{src/examples/index.ts → dist/examples/index.js} +1 -0
  86. package/dist/examples/index.js.map +1 -0
  87. package/dist/examples/tdd-orchestrator.d.ts +15 -0
  88. package/dist/examples/tdd-orchestrator.d.ts.map +1 -0
  89. package/dist/examples/tdd-orchestrator.js +121 -0
  90. package/dist/examples/tdd-orchestrator.js.map +1 -0
  91. package/dist/examples/test-cycle-workflow.d.ts +14 -0
  92. package/dist/examples/test-cycle-workflow.d.ts.map +1 -0
  93. package/dist/examples/test-cycle-workflow.js +116 -0
  94. package/dist/examples/test-cycle-workflow.js.map +1 -0
  95. package/dist/harnesses/claude-code-harness.d.ts +391 -0
  96. package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
  97. package/dist/harnesses/claude-code-harness.js +1076 -0
  98. package/dist/harnesses/claude-code-harness.js.map +1 -0
  99. package/dist/harnesses/harness-registry.d.ts +440 -0
  100. package/dist/harnesses/harness-registry.d.ts.map +1 -0
  101. package/dist/harnesses/harness-registry.js +543 -0
  102. package/dist/harnesses/harness-registry.js.map +1 -0
  103. package/dist/harnesses/index.d.ts +12 -0
  104. package/dist/harnesses/index.d.ts.map +1 -0
  105. package/dist/harnesses/index.js +11 -0
  106. package/dist/harnesses/index.js.map +1 -0
  107. package/dist/harnesses/pi-harness.d.ts +219 -0
  108. package/dist/harnesses/pi-harness.d.ts.map +1 -0
  109. package/dist/harnesses/pi-harness.js +676 -0
  110. package/dist/harnesses/pi-harness.js.map +1 -0
  111. package/dist/harnesses/pi-schema-converter.d.ts +24 -0
  112. package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
  113. package/dist/harnesses/pi-schema-converter.js +81 -0
  114. package/dist/harnesses/pi-schema-converter.js.map +1 -0
  115. package/dist/harnesses/register-defaults.d.ts +24 -0
  116. package/dist/harnesses/register-defaults.d.ts.map +1 -0
  117. package/dist/harnesses/register-defaults.js +40 -0
  118. package/dist/harnesses/register-defaults.js.map +1 -0
  119. package/dist/harnesses/session-store.d.ts +201 -0
  120. package/dist/harnesses/session-store.d.ts.map +1 -0
  121. package/dist/harnesses/session-store.js +254 -0
  122. package/dist/harnesses/session-store.js.map +1 -0
  123. package/dist/index.d.ts +37 -0
  124. package/dist/index.d.ts.map +1 -0
  125. package/dist/index.js +57 -0
  126. package/dist/index.js.map +1 -0
  127. package/dist/reflection/index.d.ts +5 -0
  128. package/dist/reflection/index.d.ts.map +1 -0
  129. package/{src/reflection/index.ts → dist/reflection/index.js} +1 -1
  130. package/dist/reflection/index.js.map +1 -0
  131. package/dist/reflection/reflection.d.ts +84 -0
  132. package/dist/reflection/reflection.d.ts.map +1 -0
  133. package/dist/reflection/reflection.js +344 -0
  134. package/dist/reflection/reflection.js.map +1 -0
  135. package/dist/tools/index.d.ts +6 -0
  136. package/dist/tools/index.d.ts.map +1 -0
  137. package/dist/tools/index.js +11 -0
  138. package/dist/tools/index.js.map +1 -0
  139. package/dist/tools/introspection.d.ts +165 -0
  140. package/dist/tools/introspection.d.ts.map +1 -0
  141. package/dist/tools/introspection.js +324 -0
  142. package/dist/tools/introspection.js.map +1 -0
  143. package/dist/types/agent.d.ts +1317 -0
  144. package/dist/types/agent.d.ts.map +1 -0
  145. package/dist/types/agent.js +423 -0
  146. package/dist/types/agent.js.map +1 -0
  147. package/dist/types/decorators.d.ts +40 -0
  148. package/dist/types/decorators.d.ts.map +1 -0
  149. package/dist/types/decorators.js +2 -0
  150. package/dist/types/decorators.js.map +1 -0
  151. package/dist/types/error-strategy.d.ts +13 -0
  152. package/dist/types/error-strategy.d.ts.map +1 -0
  153. package/dist/types/error-strategy.js +2 -0
  154. package/dist/types/error-strategy.js.map +1 -0
  155. package/dist/types/error.d.ts +20 -0
  156. package/dist/types/error.d.ts.map +1 -0
  157. package/dist/types/error.js +2 -0
  158. package/dist/types/error.js.map +1 -0
  159. package/dist/types/events.d.ts +113 -0
  160. package/dist/types/events.d.ts.map +1 -0
  161. package/dist/types/events.js +2 -0
  162. package/dist/types/events.js.map +1 -0
  163. package/dist/types/harnesses.d.ts +474 -0
  164. package/dist/types/harnesses.d.ts.map +1 -0
  165. package/dist/types/harnesses.js +2 -0
  166. package/dist/types/harnesses.js.map +1 -0
  167. package/dist/types/index.d.ts +23 -0
  168. package/dist/types/index.d.ts.map +1 -0
  169. package/dist/types/index.js +8 -0
  170. package/dist/types/index.js.map +1 -0
  171. package/dist/types/logging.d.ts +24 -0
  172. package/dist/types/logging.d.ts.map +1 -0
  173. package/dist/types/logging.js +2 -0
  174. package/dist/types/logging.js.map +1 -0
  175. package/dist/types/observer.d.ts +18 -0
  176. package/dist/types/observer.d.ts.map +1 -0
  177. package/dist/types/observer.js +2 -0
  178. package/dist/types/observer.js.map +1 -0
  179. package/dist/types/prompt.d.ts +31 -0
  180. package/dist/types/prompt.d.ts.map +1 -0
  181. package/dist/types/prompt.js +6 -0
  182. package/dist/types/prompt.js.map +1 -0
  183. package/dist/types/providers.d.ts +691 -0
  184. package/dist/types/providers.d.ts.map +1 -0
  185. package/dist/types/providers.js +14 -0
  186. package/dist/types/providers.js.map +1 -0
  187. package/dist/types/reflection.d.ts +96 -0
  188. package/dist/types/reflection.d.ts.map +1 -0
  189. package/dist/types/reflection.js +24 -0
  190. package/dist/types/reflection.js.map +1 -0
  191. package/dist/types/restart.d.ts +132 -0
  192. package/dist/types/restart.d.ts.map +1 -0
  193. package/dist/types/restart.js +2 -0
  194. package/dist/types/restart.js.map +1 -0
  195. package/dist/types/sdk-primitives.d.ts +118 -0
  196. package/dist/types/sdk-primitives.d.ts.map +1 -0
  197. package/dist/types/sdk-primitives.js +6 -0
  198. package/dist/types/sdk-primitives.js.map +1 -0
  199. package/{src/types/snapshot.ts → dist/types/snapshot.d.ts} +5 -5
  200. package/dist/types/snapshot.d.ts.map +1 -0
  201. package/dist/types/snapshot.js +2 -0
  202. package/dist/types/snapshot.js.map +1 -0
  203. package/dist/types/streaming.d.ts +194 -0
  204. package/dist/types/streaming.d.ts.map +1 -0
  205. package/dist/types/streaming.js +67 -0
  206. package/dist/types/streaming.js.map +1 -0
  207. package/dist/types/workflow-context.d.ts +275 -0
  208. package/dist/types/workflow-context.d.ts.map +1 -0
  209. package/dist/types/workflow-context.js +8 -0
  210. package/dist/types/workflow-context.js.map +1 -0
  211. package/dist/types/workflow.d.ts +30 -0
  212. package/dist/types/workflow.d.ts.map +1 -0
  213. package/dist/types/workflow.js +2 -0
  214. package/dist/types/workflow.js.map +1 -0
  215. package/dist/utils/agent-validation.d.ts +88 -0
  216. package/dist/utils/agent-validation.d.ts.map +1 -0
  217. package/dist/utils/agent-validation.js +87 -0
  218. package/dist/utils/agent-validation.js.map +1 -0
  219. package/dist/utils/delay.d.ts +7 -0
  220. package/dist/utils/delay.d.ts.map +1 -0
  221. package/dist/utils/delay.js +9 -0
  222. package/dist/utils/delay.js.map +1 -0
  223. package/dist/utils/harness-config.d.ts +180 -0
  224. package/dist/utils/harness-config.d.ts.map +1 -0
  225. package/dist/utils/harness-config.js +311 -0
  226. package/dist/utils/harness-config.js.map +1 -0
  227. package/dist/utils/id.d.ts +6 -0
  228. package/dist/utils/id.d.ts.map +1 -0
  229. package/dist/utils/id.js +12 -0
  230. package/dist/utils/id.js.map +1 -0
  231. package/dist/utils/index.d.ts +13 -0
  232. package/dist/utils/index.d.ts.map +1 -0
  233. package/dist/utils/index.js +11 -0
  234. package/dist/utils/index.js.map +1 -0
  235. package/dist/utils/model-spec.d.ts +110 -0
  236. package/dist/utils/model-spec.d.ts.map +1 -0
  237. package/dist/utils/model-spec.js +149 -0
  238. package/dist/utils/model-spec.js.map +1 -0
  239. package/dist/utils/observable.d.ts +54 -0
  240. package/dist/utils/observable.d.ts.map +1 -0
  241. package/dist/utils/observable.js +82 -0
  242. package/dist/utils/observable.js.map +1 -0
  243. package/dist/utils/provider-config.d.ts +10 -0
  244. package/dist/utils/provider-config.d.ts.map +1 -0
  245. package/dist/utils/provider-config.js +10 -0
  246. package/dist/utils/provider-config.js.map +1 -0
  247. package/dist/utils/restart-analysis.d.ts +202 -0
  248. package/dist/utils/restart-analysis.d.ts.map +1 -0
  249. package/dist/utils/restart-analysis.js +426 -0
  250. package/dist/utils/restart-analysis.js.map +1 -0
  251. package/dist/utils/session-serialization.d.ts +118 -0
  252. package/dist/utils/session-serialization.d.ts.map +1 -0
  253. package/dist/utils/session-serialization.js +217 -0
  254. package/dist/utils/session-serialization.js.map +1 -0
  255. package/dist/utils/workflow-error-utils.d.ts +22 -0
  256. package/dist/utils/workflow-error-utils.d.ts.map +1 -0
  257. package/dist/utils/workflow-error-utils.js +45 -0
  258. package/dist/utils/workflow-error-utils.js.map +1 -0
  259. package/package.json +34 -5
  260. package/.claude/commands/subtask-planning/prp-base-create.md +0 -120
  261. package/.claude/commands/subtask-planning/prp-base-execute.md +0 -65
  262. package/.claude/commands/task-breakdown.md +0 -94
  263. package/.claude/settings.local.json +0 -9
  264. package/.claude/system_prompts/task-breakdown.md +0 -101
  265. package/CHANGELOG.md +0 -188
  266. package/PRD.md +0 -543
  267. package/PRPs/001-hierarchical-workflow-engine.md +0 -2438
  268. package/PRPs/PRDs/002-agent-prompt.md +0 -390
  269. package/PRPs/PRDs/003-agent-prompt.md +0 -943
  270. package/PRPs/PRDs/004-agent-prompt.md +0 -1136
  271. package/PRPs/PRDs/tasks-001.json +0 -492
  272. package/PRPs/README.md +0 -83
  273. package/PRPs/templates/prp_base.md +0 -222
  274. package/docs/agent.md +0 -422
  275. package/docs/prompt.md +0 -419
  276. package/docs/workflow.md +0 -600
  277. package/examples/README.md +0 -258
  278. package/examples/examples/01-basic-workflow.ts +0 -100
  279. package/examples/examples/02-decorator-options.ts +0 -217
  280. package/examples/examples/03-parent-child.ts +0 -241
  281. package/examples/examples/04-observers-debugger.ts +0 -340
  282. package/examples/examples/05-error-handling.ts +0 -387
  283. package/examples/examples/06-concurrent-tasks.ts +0 -352
  284. package/examples/examples/07-agent-loops.ts +0 -432
  285. package/examples/examples/08-sdk-features.ts +0 -667
  286. package/examples/examples/09-reflection.ts +0 -573
  287. package/examples/examples/10-introspection.ts +0 -550
  288. package/examples/examples/11-reparenting-workflows.ts +0 -269
  289. package/examples/index.ts +0 -147
  290. package/examples/utils/helpers.ts +0 -57
  291. package/package-lock.json +0 -2398
  292. package/plan/001_d3bb02af4886/TEST_RESULTS.md +0 -259
  293. package/plan/001_d3bb02af4886/backlog.json +0 -867
  294. package/plan/001_d3bb02af4886/bug_fix_tasks.json +0 -484
  295. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S1/PRP.md +0 -488
  296. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S2/PRP.md +0 -581
  297. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M1T1S3/PRP.md +0 -687
  298. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S1/PRP.md +0 -492
  299. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/PRP.md +0 -932
  300. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/concurrent_error_testing_patterns.md +0 -1109
  301. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/vitest_concurrent_testing.md +0 -802
  302. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T1S3/research/workflow_engine_test_references.md +0 -603
  303. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S1/PRP.md +0 -564
  304. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S3/PRP.md +0 -518
  305. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T2S4/PRP.md +0 -1252
  306. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/PRP.md +0 -364
  307. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/CODEBASE_INVENTORY.md +0 -114
  308. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/DECORATOR_DOCUMENTATION_PATTERNS.md +0 -205
  309. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/PRD_LOCATION_ANALYSIS.md +0 -199
  310. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M2T3S1/research/ULTRATHINK_PRP_PLAN.md +0 -134
  311. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/PRP.md +0 -495
  312. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S1/research/console_error_inventory.md +0 -435
  313. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S2/PRP.md +0 -506
  314. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T1S3/PRP.md +0 -612
  315. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/PRP.md +0 -558
  316. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T2S2/research/external_research.md +0 -788
  317. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S2/PRP.md +0 -460
  318. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T3S3/PRP.md +0 -454
  319. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/PRP.md +0 -520
  320. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/RECOMMENDATION.md +0 -417
  321. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/external_workflow_engines_research.md +0 -760
  322. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S1/research/security_implications_analysis.md +0 -245
  323. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M3T4S2/PRP.md +0 -792
  324. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/PRP.md +0 -535
  325. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S1/TEST_EXECUTION_REPORT.md +0 -190
  326. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/PRP.md +0 -654
  327. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/TEST_FIX_REPORT.md +0 -227
  328. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/KEY_FINDINGS.md +0 -345
  329. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/QUICK_REFERENCE.md +0 -193
  330. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T1S2/research/test_maintenance_research.md +0 -1323
  331. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/BREAKING_CHANGES_AUDIT.md +0 -1011
  332. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S1/PRP.md +0 -927
  333. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/P1M4T3S2/PRP.md +0 -505
  334. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/architecture/logger_child_signature_analysis.md +0 -401
  335. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/child_implementation_research.md +0 -142
  336. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/test_patterns_research.md +0 -112
  337. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S3/vitest_patterns_research.md +0 -159
  338. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/PRP.md +0 -549
  339. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/VERIFICATION_REPORT.md +0 -368
  340. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/edge_case_analysis.md +0 -172
  341. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M1T1S4/usage_inventory.md +0 -175
  342. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S2/PRP.md +0 -696
  343. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T1S4/PRP.md +0 -860
  344. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/PRP.md +0 -1066
  345. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01-testing-aggregated-errors.md +0 -1103
  346. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/01_typescript_error_aggregation_patterns.md +0 -789
  347. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02-error-merge-strategy-testing-guide.md +0 -1098
  348. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/02_aggregate_error_patterns.md +0 -1037
  349. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03-promise-allsettled-testing-patterns.md +0 -916
  350. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/03_error_merging_strategies.md +0 -1045
  351. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/04_github_stackoverflow_examples.md +0 -890
  352. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/05_comprehensive_summary.md +0 -822
  353. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/INDEX.md +0 -668
  354. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/QUICK_REFERENCE.md +0 -706
  355. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/README.md +0 -265
  356. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S2/research/RESEARCH_REPORT.md +0 -655
  357. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T2S4/research/vitest_testing_patterns.md +0 -1103
  358. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M2T3S2/PRP.md +0 -426
  359. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/PRP.md +0 -506
  360. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/QUICK_REFERENCE.md +0 -114
  361. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/RESEARCH_SUMMARY.md +0 -316
  362. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S2/research/vitest_observer_error_logging_best_practices.md +0 -754
  363. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T1S3/PRP.md +0 -612
  364. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/PRP.md +0 -719
  365. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/README.md +0 -215
  366. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S1/analysis.md +0 -765
  367. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T2S3/PRP.md +0 -718
  368. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/DECISION.md +0 -149
  369. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/PRP.md +0 -470
  370. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/ULTRATHINK_PLAN.md +0 -332
  371. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/codebase_workflow_name_analysis.md +0 -167
  372. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/external_best_practices.md +0 -265
  373. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T3S1/research/validation_patterns.md +0 -273
  374. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S1/workflow_engine_ancestry_api_research.md +0 -760
  375. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M3T4S3-PRP.md +0 -434
  376. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S1/PRP.md +0 -717
  377. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/PRP.md +0 -472
  378. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/VALIDATION_REPORT.md +0 -125
  379. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/P1M4T2S2/research/ULTRATHINK_PRP_PLAN.md +0 -301
  380. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/error-logging-best-practices.md +0 -1170
  381. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/research_typescript_partial_and_overloads.md +0 -940
  382. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-quick-reference.md +0 -151
  383. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/docs/vitest-research.md +0 -650
  384. package/plan/001_d3bb02af4886/bugfix/001_e8e04329daf3/prd_snapshot.md +0 -259
  385. package/plan/001_d3bb02af4886/bugfix/P1M1T1S1/PRP.md +0 -457
  386. package/plan/001_d3bb02af4886/bugfix/RESEARCH_SUMMARY.md +0 -346
  387. package/plan/001_d3bb02af4886/bugfix/architecture/codebase_structure.md +0 -311
  388. package/plan/001_d3bb02af4886/bugfix/architecture/concurrent_execution_best_practices.md +0 -1565
  389. package/plan/001_d3bb02af4886/bugfix/architecture/error_handling_patterns.md +0 -288
  390. package/plan/001_d3bb02af4886/bugfix/architecture/promise_all_analysis.md +0 -741
  391. package/plan/001_d3bb02af4886/docs/PRP/P1M1T1S4-functional-workflow-error-state-capture-test.md +0 -652
  392. package/plan/001_d3bb02af4886/docs/PRP/P1P2-PRP.md +0 -527
  393. package/plan/001_d3bb02af4886/docs/PRP/P3P4-PRP.md +0 -1388
  394. package/plan/001_d3bb02af4886/docs/PRP/P4P5-PRP.md +0 -1136
  395. package/plan/001_d3bb02af4886/docs/PRP/PRP.md +0 -527
  396. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S1-PRP.md +0 -415
  397. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S2-PRP.md +0 -378
  398. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M1T2S4-PRP.md +0 -713
  399. package/plan/001_d3bb02af4886/docs/PRP/bugfix/P1M2T1S4-PRP.md +0 -370
  400. package/plan/001_d3bb02af4886/docs/PRP_P1M3T1S3.md +0 -499
  401. package/plan/001_d3bb02af4886/docs/TEST_RESULTS.md +0 -230
  402. package/plan/001_d3bb02af4886/docs/architecture/external_deps.md +0 -358
  403. package/plan/001_d3bb02af4886/docs/architecture/system_context.md +0 -242
  404. package/plan/001_d3bb02af4886/docs/bugfix/ANALYSIS_PRD_VS_IMPLEMENTATION.md +0 -1134
  405. package/plan/001_d3bb02af4886/docs/bugfix/GAP_ANALYSIS_SUMMARY.md +0 -179
  406. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/PRP.md +0 -629
  407. package/plan/001_d3bb02af4886/docs/bugfix/P1M4T2S1/validation-report.md +0 -214
  408. package/plan/001_d3bb02af4886/docs/bugfix/PRP_P1M4T2S3.md +0 -629
  409. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_PRP.md +0 -529
  410. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_QUICK_REFERENCE.md +0 -142
  411. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_README.md +0 -304
  412. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_TEST_RESULTS.md +0 -558
  413. package/plan/001_d3bb02af4886/docs/bugfix/bugfix_VALIDATION_SUMMARY.md +0 -256
  414. package/plan/001_d3bb02af4886/docs/bugfix/system_context.md +0 -346
  415. package/plan/001_d3bb02af4886/docs/bugfix-architecture/bug_analysis.md +0 -415
  416. package/plan/001_d3bb02af4886/docs/bugfix-architecture/implementation_patterns.md +0 -489
  417. package/plan/001_d3bb02af4886/docs/bugfix-architecture/system_context.md +0 -218
  418. package/plan/001_d3bb02af4886/docs/bugfix_INITIATION_SUMMARY.md +0 -380
  419. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_PATTERNS.md +0 -1923
  420. package/plan/001_d3bb02af4886/docs/research/CYCLE_DETECTION_QUICK_REF.md +0 -319
  421. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/codebase-context.md +0 -115
  422. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/cycle-detection-algorithms.md +0 -134
  423. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/test-patterns.md +0 -153
  424. package/plan/001_d3bb02af4886/docs/research/P1M1T2S1/workflow-class.md +0 -132
  425. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_BEST_PRACTICES.md +0 -716
  426. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/DECORATOR_DOCUMENTATION_QUICK_REF.md +0 -186
  427. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/GROUNDSWELL_DECORATOR_EXAMPLES.md +0 -604
  428. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/INDEX.md +0 -213
  429. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/codebase_structure.md +0 -30
  430. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/existing_test_pattern.md +0 -56
  431. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/getRootObservers_implementation.md +0 -53
  432. package/plan/001_d3bb02af4886/docs/research/P1M2T1S4/test_conventions.md +0 -49
  433. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/PRP.md +0 -958
  434. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/QUICK_REFERENCE.md +0 -339
  435. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/README.md +0 -305
  436. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/SUMMARY.md +0 -433
  437. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/bidirectional-tree-consistency-testing.md +0 -1574
  438. package/plan/001_d3bb02af4886/docs/research/P1M3T1S4/test-pattern-examples.md +0 -1014
  439. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_BEST_PRACTICES.md +0 -1929
  440. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_CODE_PATTERNS.md +0 -857
  441. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_INTEGRATION_GUIDE.md +0 -738
  442. package/plan/001_d3bb02af4886/docs/research/P1P2/LRU_CACHE_RESEARCH_INDEX.md +0 -424
  443. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_INDEX.md +0 -291
  444. package/plan/001_d3bb02af4886/docs/research/P1P2/REFLECTION_RESEARCH_REPORT.md +0 -1342
  445. package/plan/001_d3bb02af4886/docs/research/P1P2/RESEARCH_SUMMARY.md +0 -342
  446. package/plan/001_d3bb02af4886/docs/research/P1P2/anthropic-sdk.md +0 -174
  447. package/plan/001_d3bb02af4886/docs/research/P1P2/async-local-storage.md +0 -200
  448. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-code-patterns.md +0 -1205
  449. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-decision-matrix.md +0 -421
  450. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-implementation-guide.md +0 -1341
  451. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-integration-guide.md +0 -834
  452. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-patterns.md +0 -1468
  453. package/plan/001_d3bb02af4886/docs/research/P1P2/reflection-quick-reference.md +0 -558
  454. package/plan/001_d3bb02af4886/docs/research/P1P2/zod-schema.md +0 -152
  455. package/plan/001_d3bb02af4886/docs/research/P3P4/caching-lru.md +0 -116
  456. package/plan/001_d3bb02af4886/docs/research/P3P4/introspection-tools.md +0 -177
  457. package/plan/001_d3bb02af4886/docs/research/P3P4/reflection-patterns.md +0 -117
  458. package/plan/001_d3bb02af4886/docs/research/P4P5/RESEARCH_SUMMARY.md +0 -151
  459. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_QUICK_REF.md +0 -376
  460. package/plan/001_d3bb02af4886/docs/research/PROMISE_ALLSETTLED_RESEARCH.md +0 -1507
  461. package/plan/001_d3bb02af4886/docs/research/bugfix_typescript_patterns.md +0 -949
  462. package/plan/001_d3bb02af4886/docs/research/error-testing-research.md +0 -619
  463. package/plan/001_d3bb02af4886/docs/research/error_handling_patterns.md +0 -723
  464. package/plan/001_d3bb02af4886/docs/research/general/INTROSPECTION_RESEARCH_SUMMARY.md +0 -378
  465. package/plan/001_d3bb02af4886/docs/research/general/README-INTROSPECTION.md +0 -352
  466. package/plan/001_d3bb02af4886/docs/research/general/agent-introspection-patterns.md +0 -1085
  467. package/plan/001_d3bb02af4886/docs/research/general/introspection-security-guide.md +0 -984
  468. package/plan/001_d3bb02af4886/docs/research/general/introspection-tool-examples.md +0 -875
  469. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/PRP_TEMPLATE.md +0 -460
  470. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/QUICK_REFERENCE.md +0 -324
  471. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/README.md +0 -175
  472. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/RESEARCH_REPORT.md +0 -499
  473. package/plan/001_d3bb02af4886/docs/research/incremental-tree-map-updates/SUMMARY.md +0 -163
  474. package/plan/001_d3bb02af4886/prd_snapshot.md +0 -543
  475. package/plan/bugfix/BUG_FIX_SUMMARY.md +0 -961
  476. package/scripts/generate-llms-full.ts +0 -206
  477. package/src/__tests__/adversarial/attachChild-performance.test.ts +0 -216
  478. package/src/__tests__/adversarial/circular-reference.test.ts +0 -101
  479. package/src/__tests__/adversarial/complex-circular-reference.test.ts +0 -139
  480. package/src/__tests__/adversarial/concurrent-task-failures.test.ts +0 -571
  481. package/src/__tests__/adversarial/deep-analysis.test.ts +0 -729
  482. package/src/__tests__/adversarial/deep-hierarchy-stress.test.ts +0 -213
  483. package/src/__tests__/adversarial/e2e-prd-validation.test.ts +0 -448
  484. package/src/__tests__/adversarial/edge-case.test.ts +0 -703
  485. package/src/__tests__/adversarial/error-merge-strategy.test.ts +0 -760
  486. package/src/__tests__/adversarial/incremental-performance.test.ts +0 -140
  487. package/src/__tests__/adversarial/node-map-update-benchmarks.test.ts +0 -457
  488. package/src/__tests__/adversarial/observer-propagation.test.ts +0 -487
  489. package/src/__tests__/adversarial/parent-validation.test.ts +0 -143
  490. package/src/__tests__/adversarial/prd-12-2-compliance.test.ts +0 -611
  491. package/src/__tests__/adversarial/prd-compliance.test.ts +0 -731
  492. package/src/__tests__/compatibility/backward-compatibility.test.ts +0 -1572
  493. package/src/__tests__/helpers/index.ts +0 -18
  494. package/src/__tests__/helpers/tree-verification.ts +0 -257
  495. package/src/__tests__/integration/agent-workflow.test.ts +0 -256
  496. package/src/__tests__/integration/bidirectional-consistency.test.ts +0 -847
  497. package/src/__tests__/integration/observer-logging.test.ts +0 -643
  498. package/src/__tests__/integration/tree-mirroring.test.ts +0 -151
  499. package/src/__tests__/integration/workflow-reparenting.test.ts +0 -303
  500. package/src/__tests__/unit/agent.test.ts +0 -169
  501. package/src/__tests__/unit/cache-key.test.ts +0 -182
  502. package/src/__tests__/unit/cache.test.ts +0 -172
  503. package/src/__tests__/unit/context.test.ts +0 -217
  504. package/src/__tests__/unit/decorators.test.ts +0 -100
  505. package/src/__tests__/unit/introspection-tools.test.ts +0 -277
  506. package/src/__tests__/unit/logger.test.ts +0 -293
  507. package/src/__tests__/unit/observable.test.ts +0 -321
  508. package/src/__tests__/unit/prompt.test.ts +0 -135
  509. package/src/__tests__/unit/reflection.test.ts +0 -210
  510. package/src/__tests__/unit/tree-debugger-incremental.test.ts +0 -170
  511. package/src/__tests__/unit/tree-debugger.test.ts +0 -85
  512. package/src/__tests__/unit/utils/workflow-error-utils.test.ts +0 -209
  513. package/src/__tests__/unit/workflow-detachChild.test.ts +0 -100
  514. package/src/__tests__/unit/workflow-emitEvent-childDetached.test.ts +0 -153
  515. package/src/__tests__/unit/workflow-isDescendantOf.test.ts +0 -180
  516. package/src/__tests__/unit/workflow.test.ts +0 -357
  517. package/src/cache/cache-key.ts +0 -244
  518. package/src/cache/cache.ts +0 -236
  519. package/src/core/agent.ts +0 -593
  520. package/src/core/event-tree.ts +0 -260
  521. package/src/core/logger.ts +0 -112
  522. package/src/core/mcp-handler.ts +0 -184
  523. package/src/core/prompt.ts +0 -150
  524. package/src/core/workflow-context.ts +0 -351
  525. package/src/core/workflow.ts +0 -540
  526. package/src/debugger/tree-debugger.ts +0 -255
  527. package/src/decorators/observed-state.ts +0 -95
  528. package/src/decorators/step.ts +0 -139
  529. package/src/decorators/task.ts +0 -159
  530. package/src/examples/tdd-orchestrator.ts +0 -65
  531. package/src/examples/test-cycle-workflow.ts +0 -64
  532. package/src/index.ts +0 -142
  533. package/src/reflection/reflection.ts +0 -407
  534. package/src/tools/index.ts +0 -36
  535. package/src/tools/introspection.ts +0 -464
  536. package/src/types/agent.ts +0 -90
  537. package/src/types/decorators.ts +0 -32
  538. package/src/types/error-strategy.ts +0 -13
  539. package/src/types/error.ts +0 -20
  540. package/src/types/events.ts +0 -75
  541. package/src/types/index.ts +0 -55
  542. package/src/types/logging.ts +0 -24
  543. package/src/types/observer.ts +0 -18
  544. package/src/types/prompt.ts +0 -40
  545. package/src/types/reflection.ts +0 -117
  546. package/src/types/sdk-primitives.ts +0 -128
  547. package/src/types/workflow-context.ts +0 -163
  548. package/src/types/workflow.ts +0 -37
  549. package/src/utils/id.ts +0 -11
  550. package/src/utils/index.ts +0 -4
  551. package/src/utils/observable.ts +0 -106
  552. package/src/utils/workflow-error-utils.ts +0 -56
  553. package/tsconfig.json +0 -22
  554. package/vitest.config.ts +0 -16
@@ -0,0 +1,1076 @@
1
+ /**
2
+ * Claude Code harness implementation (PRD §7.1)
3
+ *
4
+ * Wraps the @anthropic-ai/claude-agent-sdk to provide Anthropic Claude
5
+ * model access through the unified Harness interface.
6
+ *
7
+ * ## Capabilities
8
+ *
9
+ * - **MCP**: Model Context Protocol integration via createSdkMcpServer
10
+ * - **Skills**: System prompt-based skill loading
11
+ * - **LSP**: Language Server Protocol via MCP plugins
12
+ * - **Streaming**: Streaming response support
13
+ * - **Sessions**: Session-based state via abstraction layer
14
+ * - **Extended Thinking**: maxThinkingTokens for extended reasoning
15
+ *
16
+ * ## SDK Integration
17
+ *
18
+ * Uses lazy loading for the Anthropic SDK. The SDK is imported dynamically
19
+ * in the initialize() method to support optional dependencies.
20
+ *
21
+ * @example
22
+ * ```ts
23
+ * import { ClaudeCodeHarness } from 'groundswell';
24
+ *
25
+ * const harness = new ClaudeCodeHarness();
26
+ * await harness.initialize({ apiKey: 'sk-...' });
27
+ *
28
+ * const result = await harness.execute(
29
+ * { prompt: 'Hello, Claude!', options: {} },
30
+ * toolExecutor
31
+ * );
32
+ * ```
33
+ *
34
+ * @see {@link https://docs.anthropic.com/en/api/messages | Anthropic Messages API}
35
+ * @see {@link https://www.npmjs.com/package/@anthropic-ai/claude-agent-sdk | Agent SDK Package}
36
+ */
37
+ import { createSuccessResponse, createErrorResponse, AGENT_ERROR_CODES } from "../types/agent.js";
38
+ import { MemorySessionStore, FileSessionStore, } from "./session-store.js";
39
+ import { MCPHandler } from "../core/mcp-handler.js";
40
+ import { parseModelSpec } from "../utils/model-spec.js";
41
+ import { readFile } from "fs/promises";
42
+ import { join } from "path";
43
+ /**
44
+ * Thrown when a harness receives a configuration it cannot honour — e.g. a model
45
+ * provider it cannot run (ClaudeCodeHarness + non-anthropic, PRD §7.8). Carries a
46
+ * machine-readable `code` (default `AGENT_ERROR_CODES.CONFIG_ERROR`) so callers and
47
+ * Agent retry logic can branch structurally rather than parsing message text.
48
+ *
49
+ * @see AGENT_ERROR_CODES
50
+ */
51
+ export class ConfigError extends Error {
52
+ code;
53
+ details;
54
+ constructor(message, options = {}) {
55
+ super(message);
56
+ this.name = 'ConfigError';
57
+ this.code = options.code ?? AGENT_ERROR_CODES.CONFIG_ERROR;
58
+ this.details = options.details;
59
+ }
60
+ }
61
+ export class ClaudeCodeHarness {
62
+ /**
63
+ * Unique harness identifier (PRD §7.2)
64
+ *
65
+ * @readonly
66
+ */
67
+ id = "claude-code";
68
+ /**
69
+ * Provider capability flags
70
+ *
71
+ * Anthropic SDK v0.1.77 capabilities:
72
+ * - MCP via createSdkMcpServer
73
+ * - Skills via system prompt
74
+ * - LSP via MCP plugins
75
+ * - Streaming responses
76
+ * - No native sessions (stateless)
77
+ * - Extended thinking via maxThinkingTokens
78
+ *
79
+ * @readonly
80
+ */
81
+ capabilities = {
82
+ /** MCP server connections via createSdkMcpServer */
83
+ mcp: true,
84
+ /** Skill loading via system prompt */
85
+ skills: true,
86
+ /** LSP integration via MCP plugins */
87
+ lsp: true,
88
+ /** Streaming response support */
89
+ streaming: true,
90
+ /** Session-based state (via abstraction layer) */
91
+ sessions: true,
92
+ /** Extended thinking via maxThinkingTokens */
93
+ extendedThinking: true,
94
+ };
95
+ /**
96
+ * Check if a specific capability is supported
97
+ *
98
+ * @param capability - The capability to check
99
+ * @returns true if the capability is supported
100
+ */
101
+ supports(capability) {
102
+ return this.capabilities[capability];
103
+ }
104
+ /**
105
+ * Check if all specified features are supported
106
+ *
107
+ * @param features - Array of capability keys to check
108
+ * @returns true if all features are supported
109
+ */
110
+ requiresFeatures(features) {
111
+ return features.every(f => this.capabilities[f]);
112
+ }
113
+ /**
114
+ * Anthropic SDK module (lazy loaded)
115
+ *
116
+ * Dynamically imported in initialize() to support optional dependencies.
117
+ * Typed using typeof import() pattern for accurate module types.
118
+ *
119
+ * @internal
120
+ */
121
+ sdk = null;
122
+ /**
123
+ * MCP handler for server registration and tool management
124
+ *
125
+ * Manages MCP server connections and converts tools to SDK format.
126
+ * Created on first use and reused for subsequent registrations.
127
+ *
128
+ * @internal
129
+ */
130
+ mcpHandler = new MCPHandler();
131
+ /**
132
+ * SDK MCP server configuration for use in execute()
133
+ *
134
+ * Stores the converted SDK server config from registerMCPs().
135
+ * Used in sdkOptions.mcpServers during execute() calls.
136
+ *
137
+ * @internal
138
+ */
139
+ mcpServerConfig = null;
140
+ /**
141
+ * Combined skills prompt for injection into system prompts
142
+ *
143
+ * Stores the formatted skills content from loadSkills() for injection
144
+ * into system prompts during execute() calls. Skills are combined with
145
+ * markdown headers and separators.
146
+ *
147
+ * @internal
148
+ */
149
+ skillsPrompt = "";
150
+ /**
151
+ * Session storage backend
152
+ *
153
+ * Manages session state using pluggable storage backends. Defaults to
154
+ * in-memory storage but can be configured with file-based, Redis, or
155
+ * custom implementations via ProviderOptions or setSessionStore().
156
+ *
157
+ * @internal
158
+ */
159
+ sessionStore = new MemorySessionStore();
160
+ /**
161
+ * Session TTL in milliseconds from ProviderOptions
162
+ *
163
+ * @internal
164
+ */
165
+ sessionTtl;
166
+ /**
167
+ * Initialize the Anthropic provider
168
+ *
169
+ * Loads the Anthropic SDK and initializes the client.
170
+ *
171
+ * @param options - Optional provider configuration (apiKey, endpoint, sessionPersistence, etc.)
172
+ * @remarks Session storage defaults to MemorySessionStore if not specified.
173
+ * Implemented in P2.M1.T1.S2
174
+ */
175
+ async initialize(options) {
176
+ // Idempotent check: if SDK is already loaded, return immediately
177
+ if (this.sdk) {
178
+ return;
179
+ }
180
+ // Dynamic import of the Anthropic SDK for lazy loading
181
+ // This allows optional dependencies and faster startup
182
+ try {
183
+ this.sdk = await import("@anthropic-ai/claude-agent-sdk");
184
+ }
185
+ catch (error) {
186
+ // Rethrow with descriptive message for ProviderRegistry to track
187
+ throw new Error(`Failed to load @anthropic-ai/claude-agent-sdk: ${error instanceof Error ? error.message : "Unknown error"}`);
188
+ }
189
+ // Validate import succeeded
190
+ if (!this.sdk) {
191
+ throw new Error("Failed to load @anthropic-ai/claude-agent-sdk: Import returned null");
192
+ }
193
+ // Handle session store configuration
194
+ // Priority: sessionStore (direct injection) > sessionPersistence (declarative)
195
+ if (options?.sessionStore) {
196
+ // Direct injection (backward compatibility)
197
+ this.sessionStore = options.sessionStore;
198
+ // Store sessionTtl for cleanup operations
199
+ this.sessionTtl = options.sessionTtl ?? 86400000; // 24 hours default
200
+ }
201
+ else if (options?.sessionPersistence) {
202
+ // Create SessionStore from sessionPersistence option
203
+ switch (options.sessionPersistence) {
204
+ case "memory":
205
+ this.sessionStore = new MemorySessionStore();
206
+ break;
207
+ case "file": {
208
+ const path = options.sessionPath ?? "./sessions";
209
+ const ttl = options.sessionTtl ?? 86400000; // 24 hours default
210
+ this.sessionTtl = ttl;
211
+ this.sessionStore = new FileSessionStore(path, ttl);
212
+ break;
213
+ }
214
+ case "redis":
215
+ throw new Error('Redis session storage not yet implemented. Use sessionPersistence: "memory" or "file", or provide a custom sessionStore instance.');
216
+ default: {
217
+ // Exhaustive check - TypeScript will error if missing case
218
+ const _exhaustiveCheck = options.sessionPersistence;
219
+ throw new Error(`Unknown session persistence type: ${_exhaustiveCheck}`);
220
+ }
221
+ }
222
+ }
223
+ else {
224
+ // If neither sessionStore nor sessionPersistence provided, keep existing default (MemorySessionStore)
225
+ this.sessionTtl = options?.sessionTtl ?? 86400000; // 24 hours default
226
+ }
227
+ // Restore sessions from persistent store (non-memory stores)
228
+ // For persistent stores (File, Redis, custom), verify the store is accessible
229
+ if (!(this.sessionStore instanceof MemorySessionStore)) {
230
+ const sessionIds = await this.sessionStore.list();
231
+ // Sessions are already in store - no need to load into memory
232
+ // Just verify store is accessible by listing sessions
233
+ // Cleanup expired sessions on initialization for persistent stores
234
+ if (this.sessionTtl !== undefined && 'deleteExpired' in this.sessionStore) {
235
+ const deletedIds = await this.sessionStore.deleteExpired(this.sessionTtl);
236
+ if (deletedIds.length > 0) {
237
+ // Log cleanup (optional, for debugging)
238
+ console.debug(`Cleaned up ${deletedIds.length} expired sessions`);
239
+ }
240
+ }
241
+ }
242
+ // Note: Options are stored for later use in execute() method
243
+ // The actual SDK client creation happens when execute() is called
244
+ // This is because SDK may need different clients per-request (e.g., custom endpoint)
245
+ //
246
+ // Relevant options for Anthropic (stored implicitly via options parameter):
247
+ // - options.apiKey: Will be used in execute() for SDK client
248
+ // - options.endpoint: Will be used in execute() for custom endpoint
249
+ // - options.timeout: Will be used in execute() for request timeout
250
+ // - options.headers: Will be used in execute() for custom headers
251
+ // - options.sessionStore: Configured above for persistent storage
252
+ // - options.sessionPersistence: Creates appropriate SessionStore instance
253
+ // - options.sessionPath: Custom path for FileSessionStore
254
+ // - options.sessionTtl: Reserved for future TTL enforcement (P2.M2.T2.S2)
255
+ //
256
+ // Note: No internal initialization flag needed - ProviderRegistry manages state externally
257
+ }
258
+ /**
259
+ * Terminate the provider and cleanup resources
260
+ *
261
+ * Clears the SDK module reference to allow garbage collection.
262
+ * The Anthropic SDK is stateless and manages its own resources internally.
263
+ *
264
+ * @remarks
265
+ * Implemented in P2.M1.T1.S3
266
+ */
267
+ async terminate() {
268
+ // Idempotent check: if SDK is already null, return immediately
269
+ // FOLLOW: initialize() pattern at lines 107-110 (if (this.sdk) { return; })
270
+ if (this.sdk === null) {
271
+ return;
272
+ }
273
+ // Clear SDK reference to allow garbage collection
274
+ // CRITICAL: No other cleanup needed - SDK is stateless (see research/anthropic_sdk_cleanup.md)
275
+ // CRITICAL: SDK manages its own resources - Query objects auto-cleanup on completion
276
+ // CRITICAL: ProviderRegistry manages initialization state externally
277
+ this.sdk = null;
278
+ // Clear MCP server configuration (from P2.M1.T1.S7)
279
+ this.mcpServerConfig = null;
280
+ // Clear skills prompt (from P2.M1.T1.S8)
281
+ this.skillsPrompt = "";
282
+ // Clear session storage only for MemorySessionStore
283
+ // Persistent stores (File, Redis, custom) keep sessions after termination
284
+ if (this.sessionStore instanceof MemorySessionStore) {
285
+ await this.sessionStore.clear();
286
+ }
287
+ // For persistent stores, sessions remain in storage
288
+ // GOTCHA: No return value needed - Promise<void> is implicit
289
+ // GOTCHA: No throws possible from null check and assignment
290
+ }
291
+ /**
292
+ * Execute a prompt request
293
+ *
294
+ * Constructs the SDK query from ProviderRequest and executes it via the Anthropic SDK.
295
+ *
296
+ * When options.streaming is true, returns an AsyncGenerator that yields StreamEvent objects.
297
+ * When options.streaming is false or undefined, returns a complete AgentResponse.
298
+ *
299
+ * @param request - Provider request with prompt and options
300
+ * @param toolExecutor - Callback for executing tools (used in P2.M1.T1.S6)
301
+ * @param hooks - Optional lifecycle hooks (adapter in P2.M1.T2.S1)
302
+ * @returns Typed agent response or AsyncGenerator for streaming
303
+ * @throws {ConfigError} (code CONFIG_ERROR) if request.options.model resolves to a
304
+ * non-anthropic provider (PRD §7.8) — enforced via normalizeModel.
305
+ * @remarks
306
+ * P2.M1.T1.S5: Query construction - builds AgentSDKOptions and calls SDK query()
307
+ * P2.M1.T1.S6: Message iteration - iterates AsyncGenerator and builds AgentResponse
308
+ * Streaming: Returns AsyncGenerator<StreamEvent> when options.streaming = true
309
+ */
310
+ execute(request, toolExecutor, hooks) {
311
+ // STREAMING MODE: Check if streaming is enabled
312
+ // When options.streaming is true, return an AsyncGenerator that yields StreamEvent objects
313
+ if (request.options.streaming) {
314
+ // PATTERN: SDK initialization check (follow initialize() pattern at lines 107-110)
315
+ // CRITICAL: Validate SDK is loaded before attempting to use it
316
+ if (!this.sdk) {
317
+ throw new Error("SDK not initialized. Call initialize() first.");
318
+ }
319
+ return this.executeStreaming(request, toolExecutor, hooks);
320
+ }
321
+ // NON-STREAMING MODE: Wrap in async IIFE to return Promise<AgentResponse<T>>
322
+ // Note: This function is not 'async' because it needs to return either Promise or AsyncGenerator
323
+ // The non-streaming path is wrapped in an async IIFE to return a Promise
324
+ return (async () => {
325
+ // PATTERN: SDK initialization check (follow initialize() pattern at lines 107-110)
326
+ // CRITICAL: Validate SDK is loaded before attempting to use it
327
+ if (!this.sdk) {
328
+ throw new Error("SDK not initialized. Call initialize() first.");
329
+ }
330
+ // P2.M2.T1.S2: Session detection and retrieval
331
+ // Extract sessionId from request options and retrieve session state
332
+ const sessionId = request.options.sessionId;
333
+ let session;
334
+ let isContinuation = false;
335
+ if (sessionId) {
336
+ session = await this.getSession(sessionId);
337
+ // Check if this is a continuation (existing history)
338
+ // Only continue if session exists and has history
339
+ if (session && session.history.length > 0) {
340
+ isContinuation = true;
341
+ }
342
+ // P2.M2.T1.S2: Create session if it doesn't exist (lazy session creation)
343
+ // Session will be populated with user messages during message iteration
344
+ if (!session) {
345
+ await this.createSession(sessionId);
346
+ session = await this.getSession(sessionId);
347
+ }
348
+ }
349
+ // PATTERN: Model resolution using normalizeModel()
350
+ // FROM: src/harnesses/anthropic-provider.ts:246-259
351
+ // Default model from src/core/agent.ts:320
352
+ const modelSpec = this.normalizeModel(request.options.model ?? "claude-sonnet-4-20250514");
353
+ // PATTERN: Convert Provider hooks to SDK hooks
354
+ // Adapts ProviderHookEvents to SDK-compatible format for use in query()
355
+ const sdkHooks = this.buildAgentSDKHooks(hooks);
356
+ // PATTERN: AgentSDKOptions construction (EXACT pattern from src/core/agent.ts:397-426)
357
+ // CRITICAL: Map ProviderRequest fields to SDK Options format
358
+ const sdkOptions = {
359
+ // Model mapping
360
+ model: modelSpec.model,
361
+ // System prompt mapping (from src/core/agent.ts:317-318)
362
+ // CRITICAL: Inject loaded skills via buildSystemPromptWithSkills() helper
363
+ systemPrompt: this.buildSystemPromptWithSkills(request.options.systemPrompt),
364
+ // P2.M2.T1.S2: Continue flag for session continuation
365
+ // CRITICAL: When continuing, SDK expects continue: true AND streamInput() with history
366
+ ...(isContinuation && { continue: true }),
367
+ // Tools mapping to allowedTools (string[])
368
+ // CRITICAL: Map tool objects to tool names (from src/core/agent.ts:405-407)
369
+ ...(request.options.tools &&
370
+ request.options.tools.length > 0 && {
371
+ allowedTools: request.options.tools.map((t) => t.name),
372
+ }),
373
+ // MCP servers integration (from P2.M1.T1.S7)
374
+ // Include registered MCP servers if available
375
+ ...(this.mcpServerConfig && {
376
+ mcpServers: {
377
+ "groundswell-mcp": this.mcpServerConfig,
378
+ },
379
+ }),
380
+ // Hooks integration (from P2.M1.T2.S1)
381
+ // Include converted hooks if any were mapped
382
+ ...(Object.keys(sdkHooks).length > 0 && {
383
+ hooks: sdkHooks,
384
+ }),
385
+ };
386
+ // PATTERN: Start time tracking for duration calculation
387
+ // FROM: src/core/agent.ts line 406
388
+ const startTime = Date.now();
389
+ // PATTERN: SDK query() call (EXACT pattern from src/core/agent.ts:431)
390
+ // CRITICAL: query() returns AsyncGenerator<SDKMessage> (not Promise!)
391
+ // Do NOT await the query() call - it returns the generator synchronously
392
+ // P2.M2.T1.S2: For continuation, use empty prompt (history comes via streamInput)
393
+ const queryResult = this.sdk.query({
394
+ prompt: isContinuation ? "" : request.prompt,
395
+ options: sdkOptions,
396
+ });
397
+ // P2.M2.T1.S2: Stream session history for continuation
398
+ // CRITICAL: continue: true alone is insufficient - must also call streamInput() with history
399
+ if (isContinuation && session) {
400
+ await queryResult.streamInput((async function* historyStream() {
401
+ for (const msg of session.history) {
402
+ yield msg;
403
+ }
404
+ })());
405
+ // Stream new user message for continuation
406
+ // CRITICAL: New message also goes via streamInput(), not prompt parameter
407
+ await queryResult.streamInput((async function* newMessageStream() {
408
+ yield {
409
+ type: "user",
410
+ message: { content: request.prompt },
411
+ parent_tool_use_id: null,
412
+ session_id: session.history[0]?.session_id ?? "",
413
+ };
414
+ })());
415
+ }
416
+ // PATTERN: Message iteration and AgentResponse construction
417
+ // FROM: src/core/agent.ts lines 437-492
418
+ let resultMessage = null;
419
+ let toolCallCount = 0;
420
+ // Iterate over the AsyncGenerator of SDK messages
421
+ for await (const message of queryResult) {
422
+ // Count tool uses from assistant messages
423
+ if (message.type === "assistant") {
424
+ const content = message.message?.content;
425
+ if (Array.isArray(content)) {
426
+ for (const block of content) {
427
+ if (block.type === "tool_use") {
428
+ toolCallCount++;
429
+ // Note: Hooks adapter will be implemented in P2.M1.T2.S1
430
+ }
431
+ }
432
+ }
433
+ }
434
+ // P2.M2.T1.S2: Capture user messages and append to session history
435
+ // CRITICAL: User messages must be accumulated for next turn's streamInput()
436
+ if (message.type === "user" && session && sessionId) {
437
+ session.history.push(message);
438
+ // CRITICAL: Save back to store for persistent stores
439
+ // FileSessionStore returns copies - must save after mutation
440
+ if (!(this.sessionStore instanceof MemorySessionStore)) {
441
+ await this.sessionStore.save(sessionId, session);
442
+ }
443
+ }
444
+ // Capture the final result message
445
+ if (message.type === "result") {
446
+ resultMessage =
447
+ message;
448
+ // P2.M2.T1.S2: Update session lastResult with latest execution result
449
+ if (session && sessionId) {
450
+ session.lastResult = resultMessage;
451
+ // CRITICAL: Save back to store for persistent stores
452
+ if (!(this.sessionStore instanceof MemorySessionStore)) {
453
+ await this.sessionStore.save(sessionId, session);
454
+ }
455
+ }
456
+ }
457
+ }
458
+ // Calculate duration from start time
459
+ const duration = Date.now() - startTime;
460
+ // Handle missing result message
461
+ if (!resultMessage) {
462
+ return createErrorResponse("INVALID_RESPONSE_FORMAT", "No result message received from Agent SDK", { duration }, false);
463
+ }
464
+ // Handle error subtypes (error_during_execution, error_max_turns)
465
+ if (resultMessage.subtype !== "success") {
466
+ const errorResult = resultMessage;
467
+ return createErrorResponse("EXECUTION_FAILED", `Agent SDK execution failed: ${errorResult.subtype}`, {
468
+ errors: errorResult.errors ?? [],
469
+ subtype: errorResult.subtype,
470
+ }, errorResult.subtype === "error_max_turns");
471
+ }
472
+ // Extract usage from result
473
+ const usage = {
474
+ input_tokens: resultMessage.usage?.input_tokens ?? 0,
475
+ output_tokens: resultMessage.usage?.output_tokens ?? 0,
476
+ };
477
+ // Extract data from result (prefer structured_output, fallback to result)
478
+ const data = (resultMessage.structured_output ??
479
+ resultMessage.result);
480
+ // Return success response with metadata
481
+ return createSuccessResponse(data, {
482
+ agentId: this.id,
483
+ timestamp: Date.now(),
484
+ duration,
485
+ usage,
486
+ toolCalls: toolCallCount,
487
+ });
488
+ })();
489
+ }
490
+ /**
491
+ * Execute a prompt request with streaming
492
+ *
493
+ * Returns an AsyncGenerator that yields StreamEvent objects during execution.
494
+ * Implements streaming mode for real-time response generation.
495
+ *
496
+ * @param request - Provider request with prompt and options
497
+ * @param toolExecutor - Callback for executing tools
498
+ * @param hooks - Optional lifecycle hooks
499
+ * @returns AsyncGenerator yielding StreamEvent objects, returning final AgentResponse
500
+ * @private
501
+ * @remarks
502
+ * Streaming mode implementation following PRP P4.M2.T1.S4 specification.
503
+ */
504
+ async *executeStreaming(request, toolExecutor, hooks) {
505
+ // SDK initialization check (required by TypeScript strict mode)
506
+ // The caller (execute) already checks this, but we need to assert here
507
+ // for TypeScript's control flow analysis across method boundaries
508
+ if (!this.sdk) {
509
+ throw new Error("SDK not initialized. Call initialize() first.");
510
+ }
511
+ // P2.M2.T1.S2: Session detection and retrieval
512
+ const sessionId = request.options.sessionId;
513
+ let session;
514
+ let isContinuation = false;
515
+ if (sessionId) {
516
+ session = await this.getSession(sessionId);
517
+ if (session && session.history.length > 0) {
518
+ isContinuation = true;
519
+ }
520
+ if (!session) {
521
+ await this.createSession(sessionId);
522
+ session = await this.getSession(sessionId);
523
+ }
524
+ }
525
+ // Model resolution
526
+ const modelSpec = this.normalizeModel(request.options.model ?? "claude-sonnet-4-20250514");
527
+ // Build SDK hooks
528
+ const sdkHooks = this.buildAgentSDKHooks(hooks);
529
+ // Build SDK options
530
+ const sdkOptions = {
531
+ model: modelSpec.model,
532
+ systemPrompt: this.buildSystemPromptWithSkills(request.options.systemPrompt),
533
+ ...(isContinuation && { continue: true }),
534
+ ...(request.options.tools &&
535
+ request.options.tools.length > 0 && {
536
+ allowedTools: request.options.tools.map((t) => t.name),
537
+ }),
538
+ ...(this.mcpServerConfig && {
539
+ mcpServers: {
540
+ "groundswell-mcp": this.mcpServerConfig,
541
+ },
542
+ }),
543
+ ...(Object.keys(sdkHooks).length > 0 && {
544
+ hooks: sdkHooks,
545
+ }),
546
+ };
547
+ const startTime = Date.now();
548
+ // Yield metadata event first
549
+ yield {
550
+ type: "metadata",
551
+ metadata: {
552
+ requestId: `${this.id}-${Date.now()}`,
553
+ model: modelSpec.model,
554
+ provider: modelSpec.provider,
555
+ },
556
+ };
557
+ // Create SDK query
558
+ const queryResult = this.sdk.query({
559
+ prompt: isContinuation ? "" : request.prompt,
560
+ options: sdkOptions,
561
+ });
562
+ // Stream session history for continuation
563
+ if (isContinuation && session) {
564
+ await queryResult.streamInput((async function* historyStream() {
565
+ for (const msg of session.history) {
566
+ yield msg;
567
+ }
568
+ })());
569
+ await queryResult.streamInput((async function* newMessageStream() {
570
+ yield {
571
+ type: "user",
572
+ message: { content: request.prompt },
573
+ parent_tool_use_id: null,
574
+ session_id: session.history[0]?.session_id ?? "",
575
+ };
576
+ })());
577
+ }
578
+ let resultMessage = null;
579
+ let toolCallCount = 0;
580
+ let fullText = "";
581
+ let textIndex = 0;
582
+ // Iterate over the AsyncGenerator of SDK messages
583
+ for await (const message of queryResult) {
584
+ // Process assistant messages for text content
585
+ if (message.type === "assistant") {
586
+ const content = message.message?.content;
587
+ if (Array.isArray(content)) {
588
+ for (const block of content) {
589
+ if (block.type === "text") {
590
+ // Yield text delta event
591
+ const text = block.text;
592
+ if (text && text !== fullText) {
593
+ const delta = text.slice(fullText.length);
594
+ fullText = text;
595
+ yield {
596
+ type: "text_delta",
597
+ delta,
598
+ index: textIndex++,
599
+ };
600
+ }
601
+ }
602
+ else if (block.type === "tool_use") {
603
+ toolCallCount++;
604
+ // Yield tool call start event
605
+ yield {
606
+ type: "tool_call_start",
607
+ id: block.id,
608
+ name: block.name,
609
+ index: 0,
610
+ };
611
+ // Tool execution happens via SDK, toolExecutor is called through hooks
612
+ // Yield tool call done event
613
+ yield {
614
+ type: "tool_call_done",
615
+ id: block.id,
616
+ result: null, // Results come back in subsequent messages
617
+ };
618
+ }
619
+ }
620
+ }
621
+ }
622
+ // Capture user messages for session history
623
+ if (message.type === "user" && session && sessionId) {
624
+ session.history.push(message);
625
+ // CRITICAL: Save back to store for persistent stores
626
+ if (!(this.sessionStore instanceof MemorySessionStore)) {
627
+ await this.sessionStore.save(sessionId, session);
628
+ }
629
+ }
630
+ // Capture the final result message
631
+ if (message.type === "result") {
632
+ resultMessage =
633
+ message;
634
+ if (session && sessionId) {
635
+ session.lastResult = resultMessage;
636
+ // CRITICAL: Save back to store for persistent stores
637
+ if (!(this.sessionStore instanceof MemorySessionStore)) {
638
+ await this.sessionStore.save(sessionId, session);
639
+ }
640
+ }
641
+ }
642
+ }
643
+ const duration = Date.now() - startTime;
644
+ // Handle missing result message
645
+ if (!resultMessage) {
646
+ yield {
647
+ type: "error",
648
+ error: new Error("No result message received from Agent SDK"),
649
+ code: "INVALID_RESPONSE_FORMAT",
650
+ retryable: false,
651
+ };
652
+ throw new Error("No result message received from Agent SDK");
653
+ }
654
+ // Handle error subtypes
655
+ if (resultMessage.subtype !== "success") {
656
+ const errorResult = resultMessage;
657
+ yield {
658
+ type: "error",
659
+ error: new Error(`Agent SDK execution failed: ${errorResult.subtype}`),
660
+ code: "EXECUTION_FAILED",
661
+ retryable: errorResult.subtype === "error_max_turns",
662
+ };
663
+ throw new Error(`Agent SDK execution failed: ${errorResult.subtype}`);
664
+ }
665
+ // Yield usage event
666
+ if (resultMessage.usage) {
667
+ yield {
668
+ type: "usage",
669
+ inputTokens: resultMessage.usage.input_tokens ?? 0,
670
+ outputTokens: resultMessage.usage.output_tokens ?? 0,
671
+ cacheTokens: resultMessage.usage.cache_read_tokens ??
672
+ resultMessage.usage.cache_write_tokens,
673
+ };
674
+ }
675
+ // Yield done event
676
+ yield {
677
+ type: "done",
678
+ finishReason: "stop",
679
+ };
680
+ // Extract data and return final AgentResponse
681
+ const data = (resultMessage.structured_output ?? resultMessage.result);
682
+ return createSuccessResponse(data, {
683
+ agentId: this.id,
684
+ timestamp: Date.now(),
685
+ duration,
686
+ usage: {
687
+ input_tokens: resultMessage.usage?.input_tokens ?? 0,
688
+ output_tokens: resultMessage.usage?.output_tokens ?? 0,
689
+ },
690
+ toolCalls: toolCallCount,
691
+ });
692
+ }
693
+ /**
694
+ * Register MCP servers and return available tools
695
+ *
696
+ * Registers MCP servers with the internal MCPHandler and returns
697
+ * discovered tools in MCP format. Also converts tools to SDK format
698
+ * and stores the configuration for use in execute().
699
+ *
700
+ * @param servers - Array of MCP server configurations (required)
701
+ * @returns Array of discovered tools in MCP format (serverName__toolName)
702
+ * @remarks Modifies internal MCP handler state, converts tools to SDK format.
703
+ * Implemented in P2.M1.T1.S7
704
+ *
705
+ * @example
706
+ * ```ts
707
+ * const provider = new AnthropicProvider();
708
+ * await provider.initialize();
709
+ *
710
+ * const tools = await provider.registerMCPs([
711
+ * {
712
+ * name: 'filesystem',
713
+ * transport: 'inprocess',
714
+ * tools: [
715
+ * {
716
+ * name: 'read_file',
717
+ * description: 'Read a file',
718
+ * input_schema: {
719
+ * type: 'object',
720
+ * properties: { path: { type: 'string' } },
721
+ * required: ['path']
722
+ * }
723
+ * }
724
+ * ]
725
+ * }
726
+ * ]);
727
+ *
728
+ * console.log(tools); // [{ name: 'filesystem__read_file', ... }]
729
+ * ```
730
+ */
731
+ async registerMCPs(servers) {
732
+ // PATTERN: SDK initialization check (follow execute() pattern at lines 197-199)
733
+ // CRITICAL: Validate SDK is loaded before attempting to use it
734
+ if (!this.sdk) {
735
+ throw new Error("SDK not initialized. Call initialize() first.");
736
+ }
737
+ // Register each server with the MCPHandler
738
+ // MCPHandler will:
739
+ // - Validate server name uniqueness (throws if duplicate)
740
+ // - Register tools with fullName pattern: serverName__toolName
741
+ // - Create tool executors based on transport type
742
+ for (const server of servers) {
743
+ this.mcpHandler.registerServer(server);
744
+ }
745
+ // Convert to SDK format and store for execute() method
746
+ // toAgentSDKServer() returns McpServerConfig | null
747
+ const sdkConfig = this.mcpHandler.toAgentSDKServer();
748
+ if (sdkConfig) {
749
+ this.mcpServerConfig = sdkConfig;
750
+ }
751
+ // Return discovered tools in MCP format (NOT SDK format)
752
+ // Tools have: { name, description, input_schema }
753
+ // Tool names are prefixed: serverName__toolName
754
+ return this.mcpHandler.getTools();
755
+ }
756
+ /**
757
+ * Load skills into the provider
758
+ *
759
+ * Skills are read from SKILL.md files in each skill directory and combined
760
+ * into a formatted system prompt fragment for injection during execute().
761
+ *
762
+ * @param skills - Array of skill definitions with name and path (empty array clears existing skills)
763
+ * @throws {Error} When SDK is not initialized
764
+ * @throws {Error} When SKILL.md file cannot be read
765
+ * @remarks Each skill directory must contain a SKILL.md file. Skills are combined
766
+ * with markdown headers (### Skill Name) and separators (---).
767
+ *
768
+ * @example
769
+ * ```ts
770
+ * const provider = new AnthropicProvider();
771
+ * await provider.initialize();
772
+ * await provider.loadSkills([
773
+ * { name: 'math-expert', path: '/skills/math' },
774
+ * { name: 'code-reviewer', path: '/skills/code' }
775
+ * ]);
776
+ * ```
777
+ */
778
+ async loadSkills(skills) {
779
+ // PATTERN: SDK initialization check (follow execute() pattern at lines 219-223)
780
+ // CRITICAL: Validate SDK is loaded before proceeding
781
+ if (!this.sdk) {
782
+ throw new Error("SDK not initialized. Call initialize() first.");
783
+ }
784
+ // Handle empty skills array - nothing to load
785
+ if (skills.length === 0) {
786
+ this.skillsPrompt = "";
787
+ return;
788
+ }
789
+ // Load each skill's SKILL.md content
790
+ const skillContents = [];
791
+ for (const skill of skills) {
792
+ try {
793
+ // GOTCHA: Skill.path is directory, must join with 'SKILL.md'
794
+ const skillMdPath = join(skill.path, "SKILL.md");
795
+ const content = await readFile(skillMdPath, "utf-8");
796
+ // Format skill with markdown header
797
+ skillContents.push(`### ${skill.name}\n\n${content.trim()}`);
798
+ }
799
+ catch (error) {
800
+ // PATTERN: Wrap errors with context (follow registerMCPs pattern)
801
+ throw new Error(`Failed to load skill '${skill.name}' from ${skill.path}: ` +
802
+ `${error instanceof Error ? error.message : "Unknown error"}`);
803
+ }
804
+ }
805
+ // Combine all skills with markdown separator
806
+ // PATTERN: Use "\n\n---\n\n" for visual clarity (horizontal rule)
807
+ this.skillsPrompt = skillContents.join("\n\n---\n\n");
808
+ }
809
+ /**
810
+ * Build system prompt with skills injected
811
+ *
812
+ * Combines the base system prompt with loaded skills for injection into
813
+ * the Anthropic SDK's systemPrompt parameter.
814
+ *
815
+ * @param baseSystemPrompt - Optional base system prompt to enhance with skills
816
+ * @returns Enhanced system prompt with skills section, or base prompt unchanged if no skills loaded
817
+ * @internal
818
+ * @remarks
819
+ * Three handling cases:
820
+ * 1. No skills loaded - returns basePrompt unchanged
821
+ * 2. No base prompt - returns skills-only prompt with default header
822
+ * 3. Both exist - combines with "## Available Skills" section
823
+ */
824
+ buildSystemPromptWithSkills(baseSystemPrompt) {
825
+ // Case 1: No skills loaded - return base prompt unchanged
826
+ if (!this.skillsPrompt) {
827
+ return baseSystemPrompt ?? "";
828
+ }
829
+ // Case 2: No base prompt - return skills with default header
830
+ if (!baseSystemPrompt) {
831
+ return `You are a helpful assistant.
832
+
833
+ ## Available Skills
834
+
835
+ ${this.skillsPrompt}
836
+
837
+ ## Instructions
838
+ Leverage the available skills above when responding to requests.
839
+ `;
840
+ }
841
+ // Case 3: Both exist - combine with skills section
842
+ return `${baseSystemPrompt}
843
+
844
+ ## Available Skills
845
+
846
+ ${this.skillsPrompt}
847
+
848
+ ## Skill Usage
849
+ When responding, leverage the available skills above.
850
+ Each skill provides specific capabilities and guidelines.
851
+ `;
852
+ }
853
+ /**
854
+ * Build Agent SDK hooks from Provider hook events
855
+ *
856
+ * Adapts ProviderHookEvents to Anthropic Agent SDK-compatible hook format.
857
+ * Transforms signatures between Provider and SDK hook formats and handles
858
+ * async/sync hook execution.
859
+ *
860
+ * @param hooks - Optional provider hook events to adapt
861
+ * @returns SDK-compatible hooks object with HookCallbackMatcher arrays
862
+ * @internal
863
+ * @remarks
864
+ * Hook mapping:
865
+ * - onToolStart → PreToolUse
866
+ * - onToolEnd → PostToolUse
867
+ * - onSessionStart → SessionStart
868
+ * - onSessionEnd → SessionEnd
869
+ *
870
+ * Each adapter returns { continue: true } for SDK compatibility.
871
+ * Duration values are set to 0 as SDK doesn't provide them in hook input.
872
+ */
873
+ buildAgentSDKHooks(hooks) {
874
+ // Early return: no hooks to convert
875
+ if (!hooks) {
876
+ return {};
877
+ }
878
+ const sdkHooks = {};
879
+ // Map onToolStart → PreToolUse
880
+ if (hooks.onToolStart) {
881
+ sdkHooks["PreToolUse"] = [
882
+ {
883
+ hooks: [
884
+ async (input, _toolUseID, _options) => {
885
+ const preInput = input;
886
+ const toolRequest = {
887
+ name: preInput.tool_name,
888
+ input: preInput.tool_input,
889
+ };
890
+ await hooks.onToolStart(toolRequest);
891
+ return { continue: true };
892
+ },
893
+ ],
894
+ },
895
+ ];
896
+ }
897
+ // Map onToolEnd → PostToolUse
898
+ if (hooks.onToolEnd) {
899
+ sdkHooks["PostToolUse"] = [
900
+ {
901
+ hooks: [
902
+ async (input, _toolUseID, _options) => {
903
+ const postInput = input;
904
+ const toolRequest = {
905
+ name: postInput.tool_name,
906
+ input: postInput.tool_input,
907
+ };
908
+ const toolResult = {
909
+ content: postInput.tool_response,
910
+ isError: false, // SDK limitation - always false
911
+ };
912
+ const duration = 0; // SDK limitation - duration not available
913
+ await hooks.onToolEnd(toolRequest, toolResult, duration);
914
+ return { continue: true };
915
+ },
916
+ ],
917
+ },
918
+ ];
919
+ }
920
+ // Map onSessionStart → SessionStart
921
+ if (hooks.onSessionStart) {
922
+ sdkHooks["SessionStart"] = [
923
+ {
924
+ hooks: [
925
+ async (_input, _toolUseID, _options) => {
926
+ await hooks.onSessionStart();
927
+ return { continue: true };
928
+ },
929
+ ],
930
+ },
931
+ ];
932
+ }
933
+ // Map onSessionEnd → SessionEnd
934
+ if (hooks.onSessionEnd) {
935
+ sdkHooks["SessionEnd"] = [
936
+ {
937
+ hooks: [
938
+ async (_input, _toolUseID, _options) => {
939
+ const totalDuration = 0; // SDK limitation - duration not available
940
+ await hooks.onSessionEnd(totalDuration);
941
+ return { continue: true };
942
+ },
943
+ ],
944
+ },
945
+ ];
946
+ }
947
+ return sdkHooks;
948
+ }
949
+ /**
950
+ * Normalize a model string to a ModelSpec
951
+ *
952
+ * Parses model strings in two formats:
953
+ * - Plain: "claude-sonnet-4" → { provider: 'anthropic', model: 'claude-sonnet-4', raw: 'claude-sonnet-4' }
954
+ * - Qualified: "anthropic/claude-opus-4" → { provider: 'anthropic', model: 'claude-opus-4', raw: 'anthropic/claude-opus-4' }
955
+ *
956
+ * Delegates to {@link parseModelSpec} for parsing and validation.
957
+ * Validates that the provider is 'anthropic'.
958
+ *
959
+ * @param model - Model string to normalize (required)
960
+ * @returns Parsed ModelSpec with provider='anthropic'
961
+ * @throws {Error} When model specification is invalid (delegated to parseModelSpec)
962
+ * @throws {ConfigError} When provider is not 'anthropic' (code === AGENT_ERROR_CODES.CONFIG_ERROR)
963
+ *
964
+ * @example
965
+ * ```ts
966
+ * const provider = new AnthropicProvider();
967
+ *
968
+ * // Plain format
969
+ * provider.normalizeModel('claude-sonnet-4');
970
+ * // Returns: { provider: 'anthropic', model: 'claude-sonnet-4', raw: 'claude-sonnet-4' }
971
+ *
972
+ * // Qualified format
973
+ * provider.normalizeModel('anthropic/claude-opus-4');
974
+ * // Returns: { provider: 'anthropic', model: 'claude-opus-4', raw: 'anthropic/claude-opus-4' }
975
+ *
976
+ * // Error: wrong provider
977
+ * provider.normalizeModel('openai/gpt-4');
978
+ * // Throws: "Cannot normalize openai/gpt-4 with ClaudeCodeHarness..."
979
+ * ```
980
+ */
981
+ normalizeModel(model) {
982
+ // Delegate to existing utility function
983
+ const spec = parseModelSpec(model, "anthropic");
984
+ // PRD §7.8 — claude-code can ONLY run anthropic/* models.
985
+ // Compare against the literal LLM-host 'anthropic', NOT this.id (which is the harness id
986
+ // 'claude-code' — a different axis). A naive `!== this.id` would throw on every call.
987
+ if (spec.provider !== "anthropic") {
988
+ throw new ConfigError(`Cannot normalize ${spec.provider}/${spec.model} with ClaudeCodeHarness. ` +
989
+ `The claude-code harness only supports anthropic/* models (PRD §7.8). ` +
990
+ `Use HarnessRegistry to select a harness that supports the '${spec.provider}' provider.`, {
991
+ code: AGENT_ERROR_CODES.CONFIG_ERROR,
992
+ details: { provider: spec.provider, model: spec.model, harnessId: this.id },
993
+ });
994
+ }
995
+ return spec;
996
+ }
997
+ /**
998
+ * Create a new session with the specified ID
999
+ *
1000
+ * Initializes empty session state for the given session ID.
1001
+ * If session already exists, this is a no-op (idempotent).
1002
+ *
1003
+ * @param sessionId - Unique identifier for the session (required)
1004
+ * @throws {Error} If SDK is not initialized
1005
+ * @remarks Idempotent: if session exists, this is a no-op.
1006
+ * Session will be used when execute() receives matching sessionId in options.
1007
+ */
1008
+ async createSession(sessionId) {
1009
+ // PATTERN: SDK initialization check (follow execute() pattern at lines 219-223)
1010
+ if (!this.sdk) {
1011
+ throw new Error("SDK not initialized. Call initialize() first.");
1012
+ }
1013
+ // PATTERN: Idempotent operation (follow initialize() pattern)
1014
+ // Only create if doesn't exist
1015
+ const exists = await this.sessionStore.has(sessionId);
1016
+ if (!exists) {
1017
+ const now = Date.now();
1018
+ const emptyState = {
1019
+ history: [],
1020
+ lastResult: null,
1021
+ createdAt: now,
1022
+ lastAccessedAt: now,
1023
+ };
1024
+ await this.sessionStore.save(sessionId, emptyState);
1025
+ }
1026
+ // If exists, do nothing (idempotent)
1027
+ }
1028
+ /**
1029
+ * Get session state for the specified ID
1030
+ *
1031
+ * Retrieves the current session state including conversation history
1032
+ * and last result. Returns undefined if session doesn't exist.
1033
+ *
1034
+ * @param sessionId - Session identifier to retrieve (required)
1035
+ * @returns Session state or undefined if not found
1036
+ * @remarks Updates lastAccessedAt timestamp and saves back to persistent stores.
1037
+ */
1038
+ async getSession(sessionId) {
1039
+ const state = await this.sessionStore.load(sessionId);
1040
+ if (state) {
1041
+ // Update lastAccessedAt timestamp
1042
+ state.lastAccessedAt = Date.now();
1043
+ // Save back to store for persistent stores
1044
+ if (!(this.sessionStore instanceof MemorySessionStore)) {
1045
+ await this.sessionStore.save(sessionId, state);
1046
+ }
1047
+ }
1048
+ // Convert null to undefined for consistency
1049
+ return state ?? undefined;
1050
+ }
1051
+ /**
1052
+ * Delete a session
1053
+ *
1054
+ * Removes the session from storage. If the session doesn't exist,
1055
+ * returns false.
1056
+ *
1057
+ * @param sessionId - Session identifier to delete (required)
1058
+ * @returns true if deleted, false if not found
1059
+ * @throws {Error} If SDK is not initialized
1060
+ * @remarks Destructive operation: deleted sessions cannot be recovered
1061
+ * unless the store has backup/retention policies.
1062
+ */
1063
+ async deleteSession(sessionId) {
1064
+ // PATTERN: SDK initialization check
1065
+ if (!this.sdk) {
1066
+ throw new Error("SDK not initialized. Call initialize() first.");
1067
+ }
1068
+ return await this.sessionStore.delete(sessionId);
1069
+ }
1070
+ }
1071
+ /**
1072
+ * @deprecated Since v1.2. Use {@link ClaudeCodeHarness}. Renamed as part of the
1073
+ * Harness/Provider split (PRD §7). Identity preserved for backward compatibility.
1074
+ */
1075
+ export const AnthropicProvider = ClaudeCodeHarness;
1076
+ //# sourceMappingURL=claude-code-harness.js.map