groundswell 0.0.3 → 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 (292) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +26 -9
  3. package/dist/cache/cache-key.d.ts +20 -0
  4. package/dist/cache/cache-key.d.ts.map +1 -1
  5. package/dist/cache/cache-key.js +9 -0
  6. package/dist/cache/cache-key.js.map +1 -1
  7. package/dist/core/agent.d.ts +120 -29
  8. package/dist/core/agent.d.ts.map +1 -1
  9. package/dist/core/agent.js +584 -177
  10. package/dist/core/agent.js.map +1 -1
  11. package/dist/core/mcp-handler.d.ts +63 -5
  12. package/dist/core/mcp-handler.d.ts.map +1 -1
  13. package/dist/core/mcp-handler.js +184 -4
  14. package/dist/core/mcp-handler.js.map +1 -1
  15. package/dist/core/workflow-context.d.ts +6 -2
  16. package/dist/core/workflow-context.d.ts.map +1 -1
  17. package/dist/core/workflow-context.js +99 -4
  18. package/dist/core/workflow-context.js.map +1 -1
  19. package/dist/core/workflow.d.ts +315 -13
  20. package/dist/core/workflow.d.ts.map +1 -1
  21. package/dist/core/workflow.js +552 -30
  22. package/dist/core/workflow.js.map +1 -1
  23. package/dist/debugger/event-replayer.d.ts +422 -0
  24. package/dist/debugger/event-replayer.d.ts.map +1 -0
  25. package/dist/debugger/event-replayer.js +639 -0
  26. package/dist/debugger/event-replayer.js.map +1 -0
  27. package/dist/debugger/tree-debugger.d.ts +170 -1
  28. package/dist/debugger/tree-debugger.d.ts.map +1 -1
  29. package/dist/debugger/tree-debugger.js +423 -1
  30. package/dist/debugger/tree-debugger.js.map +1 -1
  31. package/dist/decorators/step.d.ts.map +1 -1
  32. package/dist/decorators/step.js +129 -47
  33. package/dist/decorators/step.js.map +1 -1
  34. package/dist/harnesses/claude-code-harness.d.ts +391 -0
  35. package/dist/harnesses/claude-code-harness.d.ts.map +1 -0
  36. package/dist/harnesses/claude-code-harness.js +1076 -0
  37. package/dist/harnesses/claude-code-harness.js.map +1 -0
  38. package/dist/harnesses/harness-registry.d.ts +440 -0
  39. package/dist/harnesses/harness-registry.d.ts.map +1 -0
  40. package/dist/harnesses/harness-registry.js +543 -0
  41. package/dist/harnesses/harness-registry.js.map +1 -0
  42. package/dist/harnesses/index.d.ts +12 -0
  43. package/dist/harnesses/index.d.ts.map +1 -0
  44. package/dist/harnesses/index.js +11 -0
  45. package/dist/harnesses/index.js.map +1 -0
  46. package/dist/harnesses/pi-harness.d.ts +219 -0
  47. package/dist/harnesses/pi-harness.d.ts.map +1 -0
  48. package/dist/harnesses/pi-harness.js +676 -0
  49. package/dist/harnesses/pi-harness.js.map +1 -0
  50. package/dist/harnesses/pi-schema-converter.d.ts +24 -0
  51. package/dist/harnesses/pi-schema-converter.d.ts.map +1 -0
  52. package/dist/harnesses/pi-schema-converter.js +81 -0
  53. package/dist/harnesses/pi-schema-converter.js.map +1 -0
  54. package/dist/harnesses/register-defaults.d.ts +24 -0
  55. package/dist/harnesses/register-defaults.d.ts.map +1 -0
  56. package/dist/harnesses/register-defaults.js +40 -0
  57. package/dist/harnesses/register-defaults.js.map +1 -0
  58. package/dist/harnesses/session-store.d.ts +201 -0
  59. package/dist/harnesses/session-store.d.ts.map +1 -0
  60. package/dist/harnesses/session-store.js +254 -0
  61. package/dist/harnesses/session-store.js.map +1 -0
  62. package/dist/index.d.ts +12 -2
  63. package/dist/index.d.ts.map +1 -1
  64. package/dist/index.js +17 -0
  65. package/dist/index.js.map +1 -1
  66. package/dist/reflection/reflection.d.ts.map +1 -1
  67. package/dist/reflection/reflection.js +19 -4
  68. package/dist/reflection/reflection.js.map +1 -1
  69. package/dist/types/agent.d.ts +1253 -2
  70. package/dist/types/agent.d.ts.map +1 -1
  71. package/dist/types/agent.js +418 -1
  72. package/dist/types/agent.js.map +1 -1
  73. package/dist/types/decorators.d.ts +10 -1
  74. package/dist/types/decorators.d.ts.map +1 -1
  75. package/dist/types/events.d.ts +26 -0
  76. package/dist/types/events.d.ts.map +1 -1
  77. package/dist/types/harnesses.d.ts +474 -0
  78. package/dist/types/harnesses.d.ts.map +1 -0
  79. package/dist/types/harnesses.js +2 -0
  80. package/dist/types/harnesses.js.map +1 -0
  81. package/dist/types/index.d.ts +9 -1
  82. package/dist/types/index.d.ts.map +1 -1
  83. package/dist/types/index.js +6 -0
  84. package/dist/types/index.js.map +1 -1
  85. package/dist/types/providers.d.ts +691 -0
  86. package/dist/types/providers.d.ts.map +1 -0
  87. package/dist/types/providers.js +14 -0
  88. package/dist/types/providers.js.map +1 -0
  89. package/dist/types/restart.d.ts +132 -0
  90. package/dist/types/restart.d.ts.map +1 -0
  91. package/dist/types/restart.js +2 -0
  92. package/dist/types/restart.js.map +1 -0
  93. package/dist/types/streaming.d.ts +194 -0
  94. package/dist/types/streaming.d.ts.map +1 -0
  95. package/dist/types/streaming.js +67 -0
  96. package/dist/types/streaming.js.map +1 -0
  97. package/dist/types/workflow-context.d.ts +137 -1
  98. package/dist/types/workflow-context.d.ts.map +1 -1
  99. package/dist/utils/agent-validation.d.ts +88 -0
  100. package/dist/utils/agent-validation.d.ts.map +1 -0
  101. package/dist/utils/agent-validation.js +87 -0
  102. package/dist/utils/agent-validation.js.map +1 -0
  103. package/dist/utils/delay.d.ts +7 -0
  104. package/dist/utils/delay.d.ts.map +1 -0
  105. package/dist/utils/delay.js +9 -0
  106. package/dist/utils/delay.js.map +1 -0
  107. package/dist/utils/harness-config.d.ts +180 -0
  108. package/dist/utils/harness-config.d.ts.map +1 -0
  109. package/dist/utils/harness-config.js +311 -0
  110. package/dist/utils/harness-config.js.map +1 -0
  111. package/dist/utils/index.d.ts +9 -1
  112. package/dist/utils/index.d.ts.map +1 -1
  113. package/dist/utils/index.js +8 -1
  114. package/dist/utils/index.js.map +1 -1
  115. package/dist/utils/model-spec.d.ts +110 -0
  116. package/dist/utils/model-spec.d.ts.map +1 -0
  117. package/dist/utils/model-spec.js +149 -0
  118. package/dist/utils/model-spec.js.map +1 -0
  119. package/dist/utils/provider-config.d.ts +10 -0
  120. package/dist/utils/provider-config.d.ts.map +1 -0
  121. package/dist/utils/provider-config.js +10 -0
  122. package/dist/utils/provider-config.js.map +1 -0
  123. package/dist/utils/restart-analysis.d.ts +202 -0
  124. package/dist/utils/restart-analysis.d.ts.map +1 -0
  125. package/dist/utils/restart-analysis.js +426 -0
  126. package/dist/utils/restart-analysis.js.map +1 -0
  127. package/dist/utils/session-serialization.d.ts +118 -0
  128. package/dist/utils/session-serialization.d.ts.map +1 -0
  129. package/dist/utils/session-serialization.js +217 -0
  130. package/dist/utils/session-serialization.js.map +1 -0
  131. package/package.json +31 -5
  132. package/CHANGELOG.md +0 -188
  133. package/dist/__tests__/adversarial/attachChild-performance.test.d.ts +0 -16
  134. package/dist/__tests__/adversarial/attachChild-performance.test.d.ts.map +0 -1
  135. package/dist/__tests__/adversarial/attachChild-performance.test.js +0 -187
  136. package/dist/__tests__/adversarial/attachChild-performance.test.js.map +0 -1
  137. package/dist/__tests__/adversarial/circular-reference.test.d.ts +0 -13
  138. package/dist/__tests__/adversarial/circular-reference.test.d.ts.map +0 -1
  139. package/dist/__tests__/adversarial/circular-reference.test.js +0 -92
  140. package/dist/__tests__/adversarial/circular-reference.test.js.map +0 -1
  141. package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts +0 -16
  142. package/dist/__tests__/adversarial/complex-circular-reference.test.d.ts.map +0 -1
  143. package/dist/__tests__/adversarial/complex-circular-reference.test.js +0 -127
  144. package/dist/__tests__/adversarial/complex-circular-reference.test.js.map +0 -1
  145. package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts +0 -21
  146. package/dist/__tests__/adversarial/concurrent-task-failures.test.d.ts.map +0 -1
  147. package/dist/__tests__/adversarial/concurrent-task-failures.test.js +0 -667
  148. package/dist/__tests__/adversarial/concurrent-task-failures.test.js.map +0 -1
  149. package/dist/__tests__/adversarial/deep-analysis.test.d.ts +0 -6
  150. package/dist/__tests__/adversarial/deep-analysis.test.d.ts.map +0 -1
  151. package/dist/__tests__/adversarial/deep-analysis.test.js +0 -877
  152. package/dist/__tests__/adversarial/deep-analysis.test.js.map +0 -1
  153. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts +0 -13
  154. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.d.ts.map +0 -1
  155. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js +0 -186
  156. package/dist/__tests__/adversarial/deep-hierarchy-stress.test.js.map +0 -1
  157. package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts +0 -6
  158. package/dist/__tests__/adversarial/e2e-prd-validation.test.d.ts.map +0 -1
  159. package/dist/__tests__/adversarial/e2e-prd-validation.test.js +0 -626
  160. package/dist/__tests__/adversarial/e2e-prd-validation.test.js.map +0 -1
  161. package/dist/__tests__/adversarial/edge-case.test.d.ts +0 -6
  162. package/dist/__tests__/adversarial/edge-case.test.d.ts.map +0 -1
  163. package/dist/__tests__/adversarial/edge-case.test.js +0 -857
  164. package/dist/__tests__/adversarial/edge-case.test.js.map +0 -1
  165. package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts +0 -20
  166. package/dist/__tests__/adversarial/error-merge-strategy.test.d.ts.map +0 -1
  167. package/dist/__tests__/adversarial/error-merge-strategy.test.js +0 -907
  168. package/dist/__tests__/adversarial/error-merge-strategy.test.js.map +0 -1
  169. package/dist/__tests__/adversarial/incremental-performance.test.d.ts +0 -2
  170. package/dist/__tests__/adversarial/incremental-performance.test.d.ts.map +0 -1
  171. package/dist/__tests__/adversarial/incremental-performance.test.js +0 -113
  172. package/dist/__tests__/adversarial/incremental-performance.test.js.map +0 -1
  173. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts +0 -22
  174. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.d.ts.map +0 -1
  175. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js +0 -383
  176. package/dist/__tests__/adversarial/node-map-update-benchmarks.test.js.map +0 -1
  177. package/dist/__tests__/adversarial/observer-propagation.test.d.ts +0 -21
  178. package/dist/__tests__/adversarial/observer-propagation.test.d.ts.map +0 -1
  179. package/dist/__tests__/adversarial/observer-propagation.test.js +0 -404
  180. package/dist/__tests__/adversarial/observer-propagation.test.js.map +0 -1
  181. package/dist/__tests__/adversarial/parent-validation.test.d.ts +0 -13
  182. package/dist/__tests__/adversarial/parent-validation.test.d.ts.map +0 -1
  183. package/dist/__tests__/adversarial/parent-validation.test.js +0 -128
  184. package/dist/__tests__/adversarial/parent-validation.test.js.map +0 -1
  185. package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts +0 -20
  186. package/dist/__tests__/adversarial/prd-12-2-compliance.test.d.ts.map +0 -1
  187. package/dist/__tests__/adversarial/prd-12-2-compliance.test.js +0 -482
  188. package/dist/__tests__/adversarial/prd-12-2-compliance.test.js.map +0 -1
  189. package/dist/__tests__/adversarial/prd-compliance.test.d.ts +0 -6
  190. package/dist/__tests__/adversarial/prd-compliance.test.d.ts.map +0 -1
  191. package/dist/__tests__/adversarial/prd-compliance.test.js +0 -886
  192. package/dist/__tests__/adversarial/prd-compliance.test.js.map +0 -1
  193. package/dist/__tests__/compatibility/backward-compatibility.test.d.ts +0 -22
  194. package/dist/__tests__/compatibility/backward-compatibility.test.d.ts.map +0 -1
  195. package/dist/__tests__/compatibility/backward-compatibility.test.js +0 -1843
  196. package/dist/__tests__/compatibility/backward-compatibility.test.js.map +0 -1
  197. package/dist/__tests__/helpers/index.d.ts +0 -10
  198. package/dist/__tests__/helpers/index.d.ts.map +0 -1
  199. package/dist/__tests__/helpers/index.js +0 -10
  200. package/dist/__tests__/helpers/index.js.map +0 -1
  201. package/dist/__tests__/helpers/tree-verification.d.ts +0 -90
  202. package/dist/__tests__/helpers/tree-verification.d.ts.map +0 -1
  203. package/dist/__tests__/helpers/tree-verification.js +0 -202
  204. package/dist/__tests__/helpers/tree-verification.js.map +0 -1
  205. package/dist/__tests__/integration/agent-workflow.test.d.ts +0 -2
  206. package/dist/__tests__/integration/agent-workflow.test.d.ts.map +0 -1
  207. package/dist/__tests__/integration/agent-workflow.test.js +0 -256
  208. package/dist/__tests__/integration/agent-workflow.test.js.map +0 -1
  209. package/dist/__tests__/integration/bidirectional-consistency.test.d.ts +0 -14
  210. package/dist/__tests__/integration/bidirectional-consistency.test.d.ts.map +0 -1
  211. package/dist/__tests__/integration/bidirectional-consistency.test.js +0 -668
  212. package/dist/__tests__/integration/bidirectional-consistency.test.js.map +0 -1
  213. package/dist/__tests__/integration/observer-logging.test.d.ts +0 -2
  214. package/dist/__tests__/integration/observer-logging.test.d.ts.map +0 -1
  215. package/dist/__tests__/integration/observer-logging.test.js +0 -517
  216. package/dist/__tests__/integration/observer-logging.test.js.map +0 -1
  217. package/dist/__tests__/integration/tree-mirroring.test.d.ts +0 -2
  218. package/dist/__tests__/integration/tree-mirroring.test.d.ts.map +0 -1
  219. package/dist/__tests__/integration/tree-mirroring.test.js +0 -117
  220. package/dist/__tests__/integration/tree-mirroring.test.js.map +0 -1
  221. package/dist/__tests__/integration/workflow-reparenting.test.d.ts +0 -12
  222. package/dist/__tests__/integration/workflow-reparenting.test.d.ts.map +0 -1
  223. package/dist/__tests__/integration/workflow-reparenting.test.js +0 -239
  224. package/dist/__tests__/integration/workflow-reparenting.test.js.map +0 -1
  225. package/dist/__tests__/unit/agent.test.d.ts +0 -2
  226. package/dist/__tests__/unit/agent.test.d.ts.map +0 -1
  227. package/dist/__tests__/unit/agent.test.js +0 -143
  228. package/dist/__tests__/unit/agent.test.js.map +0 -1
  229. package/dist/__tests__/unit/cache-key.test.d.ts +0 -5
  230. package/dist/__tests__/unit/cache-key.test.d.ts.map +0 -1
  231. package/dist/__tests__/unit/cache-key.test.js +0 -145
  232. package/dist/__tests__/unit/cache-key.test.js.map +0 -1
  233. package/dist/__tests__/unit/cache.test.d.ts +0 -5
  234. package/dist/__tests__/unit/cache.test.d.ts.map +0 -1
  235. package/dist/__tests__/unit/cache.test.js +0 -132
  236. package/dist/__tests__/unit/cache.test.js.map +0 -1
  237. package/dist/__tests__/unit/context.test.d.ts +0 -2
  238. package/dist/__tests__/unit/context.test.d.ts.map +0 -1
  239. package/dist/__tests__/unit/context.test.js +0 -220
  240. package/dist/__tests__/unit/context.test.js.map +0 -1
  241. package/dist/__tests__/unit/decorators.test.d.ts +0 -2
  242. package/dist/__tests__/unit/decorators.test.d.ts.map +0 -1
  243. package/dist/__tests__/unit/decorators.test.js +0 -162
  244. package/dist/__tests__/unit/decorators.test.js.map +0 -1
  245. package/dist/__tests__/unit/introspection-tools.test.d.ts +0 -5
  246. package/dist/__tests__/unit/introspection-tools.test.d.ts.map +0 -1
  247. package/dist/__tests__/unit/introspection-tools.test.js +0 -191
  248. package/dist/__tests__/unit/introspection-tools.test.js.map +0 -1
  249. package/dist/__tests__/unit/logger.test.d.ts +0 -2
  250. package/dist/__tests__/unit/logger.test.d.ts.map +0 -1
  251. package/dist/__tests__/unit/logger.test.js +0 -241
  252. package/dist/__tests__/unit/logger.test.js.map +0 -1
  253. package/dist/__tests__/unit/observable.test.d.ts +0 -2
  254. package/dist/__tests__/unit/observable.test.d.ts.map +0 -1
  255. package/dist/__tests__/unit/observable.test.js +0 -251
  256. package/dist/__tests__/unit/observable.test.js.map +0 -1
  257. package/dist/__tests__/unit/prompt.test.d.ts +0 -2
  258. package/dist/__tests__/unit/prompt.test.d.ts.map +0 -1
  259. package/dist/__tests__/unit/prompt.test.js +0 -113
  260. package/dist/__tests__/unit/prompt.test.js.map +0 -1
  261. package/dist/__tests__/unit/reflection.test.d.ts +0 -5
  262. package/dist/__tests__/unit/reflection.test.d.ts.map +0 -1
  263. package/dist/__tests__/unit/reflection.test.js +0 -160
  264. package/dist/__tests__/unit/reflection.test.js.map +0 -1
  265. package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts +0 -2
  266. package/dist/__tests__/unit/tree-debugger-incremental.test.d.ts.map +0 -1
  267. package/dist/__tests__/unit/tree-debugger-incremental.test.js +0 -136
  268. package/dist/__tests__/unit/tree-debugger-incremental.test.js.map +0 -1
  269. package/dist/__tests__/unit/tree-debugger.test.d.ts +0 -2
  270. package/dist/__tests__/unit/tree-debugger.test.d.ts.map +0 -1
  271. package/dist/__tests__/unit/tree-debugger.test.js +0 -69
  272. package/dist/__tests__/unit/tree-debugger.test.js.map +0 -1
  273. package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts +0 -2
  274. package/dist/__tests__/unit/utils/workflow-error-utils.test.d.ts.map +0 -1
  275. package/dist/__tests__/unit/utils/workflow-error-utils.test.js +0 -154
  276. package/dist/__tests__/unit/utils/workflow-error-utils.test.js.map +0 -1
  277. package/dist/__tests__/unit/workflow-detachChild.test.d.ts +0 -2
  278. package/dist/__tests__/unit/workflow-detachChild.test.d.ts.map +0 -1
  279. package/dist/__tests__/unit/workflow-detachChild.test.js +0 -76
  280. package/dist/__tests__/unit/workflow-detachChild.test.js.map +0 -1
  281. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts +0 -2
  282. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.d.ts.map +0 -1
  283. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js +0 -122
  284. package/dist/__tests__/unit/workflow-emitEvent-childDetached.test.js.map +0 -1
  285. package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts +0 -2
  286. package/dist/__tests__/unit/workflow-isDescendantOf.test.d.ts.map +0 -1
  287. package/dist/__tests__/unit/workflow-isDescendantOf.test.js +0 -140
  288. package/dist/__tests__/unit/workflow-isDescendantOf.test.js.map +0 -1
  289. package/dist/__tests__/unit/workflow.test.d.ts +0 -2
  290. package/dist/__tests__/unit/workflow.test.d.ts.map +0 -1
  291. package/dist/__tests__/unit/workflow.test.js +0 -330
  292. package/dist/__tests__/unit/workflow.test.js.map +0 -1
@@ -0,0 +1,219 @@
1
+ import type { Harness, HarnessId, HarnessCapabilities, HarnessOptions, HarnessRequest, HarnessHookEvents, ToolExecutionRequest, ToolExecutionResult, ModelSpec } from "../types/harnesses.js";
2
+ import type { Tool, MCPServer, Skill } from "../types/sdk-primitives.js";
3
+ import type { AgentResponse } from "../types/agent.js";
4
+ import type { StreamEvent } from "../types/streaming.js";
5
+ import { ModelRegistry } from "@earendil-works/pi-coding-agent";
6
+ /**
7
+ * The Pi `Model<Api>` element type, derived from the re-exported ModelRegistry so
8
+ * NO import from the non-hoisted `@earendil-works/pi-ai` is needed (Decision 4).
9
+ * Structurally identical to Model<Api>; assignable to Model<any> for createAgentSession.
10
+ */
11
+ type PiModel = NonNullable<ReturnType<ModelRegistry["find"]>>;
12
+ /**
13
+ * Pi harness implementation (PRD §7.1).
14
+ *
15
+ * Wraps `@earendil-works/pi-coding-agent` (the vendor-neutral default runtime). This file is the
16
+ * S2 implementation: it wires the SDK via lazy import in `initialize()`, builds a headless
17
+ * `ModelRegistry`, and provides `resolveModel()` to map `ModelSpec` → Pi `Model<Api>`.
18
+ * Tools/streaming/hooks/skills land in P2.M3/P2.M4.
19
+ *
20
+ * ## Capabilities (PRD §7.4 `pi` column — ALL supported)
21
+ * - **MCP**: via Groundswell `MCPHandler` (tools registered with the harness)
22
+ * - **Skills**: native agentskills.io
23
+ * - **LSP**: via MCP plugins through `MCPHandler`
24
+ * - **Streaming**: `session.subscribe` (`MessageUpdateEvent`)
25
+ * - **Sessions**: `SessionManager` (fork/switch/clone)
26
+ * - **Extended Thinking**: model-dependent
27
+ *
28
+ * Pi is vendor-neutral: it runs ANY LLM provider (PRD §7.4/§7.8), so `normalizeModel` applies NO
29
+ * provider constraint (unlike `ClaudeCodeHarness`).
30
+ *
31
+ * @example
32
+ * ```ts
33
+ * import { PiHarness } from './harnesses/pi-harness.js';
34
+ * const harness = new PiHarness();
35
+ * await harness.initialize({ apiKey: 'sk-...' });
36
+ * const spec = harness.normalizeModel('anthropic/claude-sonnet-4');
37
+ * const model = harness.resolveModel(spec); // Model<Api>
38
+ * ```
39
+ */
40
+ export declare class PiHarness implements Harness {
41
+ /** Harness identifier (PRD §7.2). */
42
+ readonly id: HarnessId;
43
+ /** Capability flags — PRD §7.4 `pi` column (all true; vendor-neutral runtime). */
44
+ readonly capabilities: HarnessCapabilities;
45
+ /** Lazily-imported Pi SDK module (mirrors ClaudeCodeHarness.sdk). Null until initialize(). */
46
+ private sdk;
47
+ /** Headless auth store (env/runtime API-key resolution). Null until initialize(). */
48
+ private authStorage;
49
+ /** Model registry (built-in + custom models; per-provider auth). Null until initialize(). */
50
+ private modelRegistry;
51
+ /** Caller-supplied options (apiKey forwarded per-provider at resolveModel time). */
52
+ private options;
53
+ /** MCP tool registry — mirrors ClaudeCodeHarness L177. */
54
+ private mcpHandler;
55
+ /**
56
+ * Combined skills prompt (agentskills.io XML) from loadSkills(), injected into the session's system
57
+ * prompt during execute() via a DefaultResourceLoader.appendSystemPrompt (parity with
58
+ * ClaudeCodeHarness.skillsPrompt). Empty string when no skills are loaded (loadSkills not called, or
59
+ * called with []). When empty, execute() omits the resourceLoader → Pi builds its own default loader
60
+ * (current behavior preserved — no regression).
61
+ * @internal
62
+ */
63
+ private skillsPrompt;
64
+ /**
65
+ * Initialize the Pi harness (PRD §7.3).
66
+ *
67
+ * Lazily `await import`s the Pi SDK, builds a headless `ModelRegistry.inMemory(...)`, and stores
68
+ * the caller's options. Does NOT call `createAgentSession` — that is T2 (P2.M2.T2.S1), which
69
+ * consumes `this.sdk`, `this.modelRegistry`, and `this.resolveModel(spec)`.
70
+ *
71
+ * Idempotent: a no-op if already initialized. API keys are resolved per-provider at
72
+ * `resolveModel` time (the provider is unknown until a model string is parsed — GOTCHA #8).
73
+ */
74
+ initialize(options?: HarnessOptions): Promise<void>;
75
+ /**
76
+ * Terminate the harness and release references (PRD §7.3).
77
+ *
78
+ * Idempotent. Nulls sdk/authStorage/modelRegistry/options to allow GC. The Pi SDK manages its
79
+ * own resources internally; no session exists at this layer (createAgentSession is T2).
80
+ */
81
+ terminate(): Promise<void>;
82
+ /**
83
+ * Resolve a parsed {@link ModelSpec} to a Pi `Model<Api>` via the registry (PRD §7.8).
84
+ *
85
+ * Uses `modelRegistry.find(provider, model)` — the open-set, registry/auth-aware seam (NOT
86
+ * `getModel`, which is generic-constrained to known providers/models and not importable —
87
+ * research/model-resolution-path.md). T2 passes the result to `createAgentSession({ model })`.
88
+ *
89
+ * @throws {Error} if initialize() has not been called.
90
+ * @throws {ConfigError} (code CONFIG_ERROR) if the model is not in the registry.
91
+ */
92
+ resolveModel(spec: ModelSpec): PiModel;
93
+ /**
94
+ * Execute a prompt and return a structured AgentResponse (PRD §7.3, §7.11, §7.14.4).
95
+ *
96
+ * Creates a Pi AgentSession via createAgentSession, drives one prompt through session.prompt(),
97
+ * aggregates the terminal assistant text + token usage + tool-call count from the event stream
98
+ * (session.subscribe), fires session lifecycle hooks, and returns an AgentResponse<T>.
99
+ *
100
+ * Non-streaming path (P2.M2.T2.S1): returns Promise<AgentResponse<T>>.
101
+ * Streaming path: delegates to executeStreaming() (P2.M3.T2.S1) — returns AsyncGenerator<StreamEvent, AgentResponse<T>>.
102
+ * Tool delegation: customTools wired via buildCustomTools (P2.M3.T1).
103
+ * All hooks fire: session hooks inline (S1/P2.M2.T2.S1); tool/stream hooks via fireHookEvents() (P2.M3.T2.S2).
104
+ */
105
+ execute<T>(request: HarnessRequest, toolExecutor: (req: ToolExecutionRequest) => Promise<ToolExecutionResult>, hooks?: HarnessHookEvents): Promise<AgentResponse<T>> | AsyncGenerator<StreamEvent, AgentResponse<T>, unknown>;
106
+ /**
107
+ * Stream a Pi turn as `StreamEvent`s (PRD §7.3, §7.4, §7.14.4).
108
+ *
109
+ * Pi's `session.subscribe(listener)` is SYNCHRONOUS — a listener cannot `yield`. This method
110
+ * bridges sync callbacks → async generator via an internal queue: the listener `enqueue`s events
111
+ * (and resolves a parked drain), the generator `dequeue`s/maps/`yield`s. `session.prompt()` runs
112
+ * detached; its resolution flips the terminal condition.
113
+ *
114
+ * Mapping (PRD §7.11): message_update→text_delta (snapshot-diff), tool_execution_start→tool_call_start,
115
+ * tool_execution_end→tool_call_done, turn_end→usage, terminal→done, errors→error.
116
+ *
117
+ * Hooks (Decision 5): session lifecycle hooks (onSessionStart/onSessionEnd) fire for parity with
118
+ * the non-streaming path. onToolStart/onToolEnd/onStream are P2.M3.T2.S2 (NOT wired here).
119
+ */
120
+ private executeStreaming;
121
+ /**
122
+ * Dispatch the three harness hooks owned by P2.M3.T2.S2 (PRD §7.11):
123
+ * tool_execution_start → onToolStart({name, input})
124
+ * tool_execution_end → onToolEnd({name, input}, {content, isError}, duration)
125
+ * message_update → onStream(delta) [snapshot-diff; assistant text only]
126
+ *
127
+ * Session hooks (onSessionStart/onSessionEnd) are NOT handled here — they stay inline in the
128
+ * listeners as S1/P2.M2.T2.S1 wrote them (no scope overlap, no merge conflict).
129
+ *
130
+ * Pi fidelity advantage over claude-code (item note): onToolEnd observes the REAL isError
131
+ * (ToolExecutionEndEvent.isError) and a REAL duration (computed from the stashed start timestamp);
132
+ * claude-code's PostToolUse cannot (always isError:false, duration:0).
133
+ *
134
+ * Hooks are FIRE-AND-TRACK (`void`): the Pi listener runs SYNCHRONOUSLY during session.prompt()
135
+ * and cannot `await` a hook Promise (would block/reorder the SDK event loop). Matches the existing
136
+ * `void hooks?.onSessionStart?.()` pattern. Tests use sync vi.fn() hooks for deterministic assertions.
137
+ *
138
+ * @param event Pi session event (structurally cast — transitive types are non-importable).
139
+ * @param hooks Optional HarnessHookEvents. Early-returns on `!hooks` (cheap no-op).
140
+ * @param ctx Mutable accumulators (toolStarts for duration/input reconstruction; streamText for onStream).
141
+ */
142
+ private fireHookEvents;
143
+ registerMCPs(servers: MCPServer[]): Promise<Tool[]>;
144
+ /**
145
+ * Build Pi `ToolDefinition[]` from the registered MCPHandler tools (PRD §7.10, §7.12, §7.14.1).
146
+ *
147
+ * Delegates to `MCPHandler.toPiCustomTools()` (P2.M4.T1.S2) which produces schema-faithful
148
+ * ToolDefinitions with REAL TypeBox `parameters` (converted via `jsonSchemaToTypebox`) and
149
+ * `execute` delegating to `registered.executor` (Claude parity).
150
+ *
151
+ * When `toolExecutor` is provided (PRD §7.10 bridge), forwards it to `toPiCustomTools` so
152
+ * each tool's `execute` dispatches through the caller-supplied executor instead of the
153
+ * harness's internal `registered.executor`.
154
+ */
155
+ private buildCustomTools;
156
+ /**
157
+ * Load skills via Pi's NATIVE agentskills.io implementation (PRD §7.12, §7.14.2).
158
+ *
159
+ * For each Groundswell {@link Skill} ({name, path}), calls Pi's `loadSkillsFromDir({dir: path,
160
+ * source: name})` (which reads SKILL.md from the dir), collects all returned Pi Skills, then formats
161
+ * them to agentskills.io XML via `formatSkillsForPrompt` and stores the result in {@link skillsPrompt}.
162
+ *
163
+ * ## No session re-init required
164
+ * PiHarness creates a FRESH AgentSession per execute()/executeStreaming() call (P2.M2.T2.S1 /
165
+ * P2.M3.T2.S1), so this stored skillsPrompt is consumed on the NEXT execute() when
166
+ * buildSkillsResourceLoader() builds the DefaultResourceLoader. This mirrors how registerMCPs()
167
+ * state is consumed when execute() builds customTools. (A long-lived-session model would need an
168
+ * explicit rebuild; not the case here.)
169
+ *
170
+ * ## Parity with ClaudeCodeHarness
171
+ * ClaudeCodeHarness reads each SKILL.md and joins with markdown; PiHarness uses Pi's native loaders
172
+ * and emits the agentskills.io XML format. Both store the result in a `skillsPrompt` field and inject
173
+ * at BOTH execute sites. EFFECT is identical: the skill's SKILL.md content reaches the model's system
174
+ * prompt.
175
+ *
176
+ * @param skills - Groundswell portable Skill list ({name, path}). path = dir containing SKILL.md.
177
+ * @throws {Error} /not initialized/i if initialize() has not been called.
178
+ * @throws {Error} "Failed to load skill '<name>' from <path>: <msg>" if loadSkillsFromDir throws.
179
+ */
180
+ loadSkills(skills: Skill[]): Promise<void>;
181
+ /**
182
+ * Build a DefaultResourceLoader that appends the loaded skills ({@link skillsPrompt}) to the
183
+ * session's system prompt (PRD §7.12, §7.14.2).
184
+ *
185
+ * Returns `undefined` when no skills are loaded (`skillsPrompt === ""`), so execute() OMITS the
186
+ * `resourceLoader` option and Pi builds its own default loader — current behavior is preserved
187
+ * (zero regression in the execute/streaming suites).
188
+ *
189
+ * ## Parity: noSkills: true
190
+ * Suppresses Pi's DEFAULT skill discovery (~/.pi/agent/skills, cwd-local) so the session's skills are
191
+ * EXACTLY Groundswell's portable Skill[] (parity with ClaudeCodeHarness, which builds its prompt only
192
+ * from the passed skills). `appendSystemPrompt` is INDEPENDENT of `noSkills`, so our pre-formatted
193
+ * agentskills.io XML is still appended to the system prompt.
194
+ *
195
+ * createAgentSession uses a caller-provided loader AS-IS (no reload), so we `await loader.reload()`.
196
+ *
197
+ * @returns A configured DefaultResourceLoader, or undefined when no skills are loaded.
198
+ * @throws {Error} /not initialized/i if called before initialize() (defensive — execute() guards too).
199
+ */
200
+ private buildSkillsResourceLoader;
201
+ /**
202
+ * Parse a model string into a ModelSpec (PRD §7.8).
203
+ *
204
+ * Pi is vendor-neutral — ANY provider is valid (PRD §7.4 "LLM providers: any"). Unlike
205
+ * `ClaudeCodeHarness`, there is NO anthropic-only constraint here. Delegates to `parseModelSpec`
206
+ * (open `ModelProviderId` set; rejects harness-qualified 3-segment strings per PRD §7.8).
207
+ *
208
+ * Threads the global `defaultModelProvider` when configured (backward-compatible — when unset,
209
+ * `defaultModelProvider` is `undefined`, so `parseModelSpec` defaults to `'anthropic'` exactly
210
+ * as S1 does).
211
+ *
212
+ * This is the string→ModelSpec layer. `resolveModel()` owns the ModelSpec→Pi `Model<Api>` step.
213
+ */
214
+ normalizeModel(model: string): ModelSpec;
215
+ supports(capability: keyof HarnessCapabilities): boolean;
216
+ requiresFeatures(features: (keyof HarnessCapabilities)[]): boolean;
217
+ }
218
+ export {};
219
+ //# sourceMappingURL=pi-harness.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pi-harness.d.ts","sourceRoot":"","sources":["../../src/harnesses/pi-harness.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,OAAO,EACP,SAAS,EACT,mBAAmB,EACnB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,EACnB,SAAS,EACV,MAAM,uBAAuB,CAAC;AAC/B,OAAO,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,4BAA4B,CAAC;AAEzE,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AACvD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAYzD,OAAO,EAAE,aAAa,EAAe,MAAM,iCAAiC,CAAC;AAE7E;;;;GAIG;AACH,KAAK,OAAO,GAAG,WAAW,CAAC,UAAU,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;AAa9D;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,qBAAa,SAAU,YAAW,OAAO;IACvC,qCAAqC;IACrC,QAAQ,CAAC,EAAE,EAAE,SAAS,CAAQ;IAE9B,kFAAkF;IAClF,QAAQ,CAAC,YAAY,EAAE,mBAAmB,CAOV;IAGhC,8FAA8F;IAC9F,OAAO,CAAC,GAAG,CAAiE;IAC5E,qFAAqF;IACrF,OAAO,CAAC,WAAW,CAA4B;IAC/C,6FAA6F;IAC7F,OAAO,CAAC,aAAa,CAA8B;IACnD,oFAAoF;IACpF,OAAO,CAAC,OAAO,CAA+B;IAC9C,0DAA0D;IAC1D,OAAO,CAAC,UAAU,CAAgC;IAClD;;;;;;;OAOG;IACH,OAAO,CAAC,YAAY,CAAc;IAGlC;;;;;;;;;OASG;IACG,UAAU,CAAC,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC;IA2BzD;;;;;OAKG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAUhC;;;;;;;;;OASG;IACH,YAAY,CAAC,IAAI,EAAE,SAAS,GAAG,OAAO;IAuBtC;;;;;;;;;;;OAWG;IACH,OAAO,CAAC,CAAC,EACP,OAAO,EAAE,cAAc,EACvB,YAAY,EAAE,CAAC,GAAG,EAAE,oBAAoB,KAAK,OAAO,CAAC,mBAAmB,CAAC,EACzE,KAAK,CAAC,EAAE,iBAAiB,GACxB,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,GAAG,cAAc,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC;IAwHrF;;;;;;;;;;;;;OAaG;YACY,gBAAgB;IAgN/B;;;;;;;;;;;;;;;;;;;;OAoBG;IACH,OAAO,CAAC,cAAc;IAmEhB,YAAY,CAAC,OAAO,EAAE,SAAS,EAAE,GAAG,OAAO,CAAC,IAAI,EAAE,CAAC;IAUzD;;;;;;;;;;OAUG;IACH,OAAO,CAAC,gBAAgB;IAMxB;;;;;;;;;;;;;;;;;;;;;;;OAuBG;IACG,UAAU,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;IAkChD;;;;;;;;;;;;;;;;;;OAkBG;YACW,yBAAyB;IA6BvC;;;;;;;;;;;;OAYG;IACH,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS;IAKxC,QAAQ,CAAC,UAAU,EAAE,MAAM,mBAAmB,GAAG,OAAO;IAIxD,gBAAgB,CAAC,QAAQ,EAAE,CAAC,MAAM,mBAAmB,CAAC,EAAE,GAAG,OAAO;CAGnE"}