@edspencer/paddock 0.0.1 → 0.56.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 (294) hide show
  1. package/README.md +69 -0
  2. package/install-notice.mjs +29 -0
  3. package/package.json +58 -5
  4. package/packages/server/dist/adoptable.d.ts +127 -0
  5. package/packages/server/dist/adoptable.js +315 -0
  6. package/packages/server/dist/app.d.ts +67 -0
  7. package/packages/server/dist/app.js +325 -0
  8. package/packages/server/dist/archive.d.ts +42 -0
  9. package/packages/server/dist/archive.js +125 -0
  10. package/packages/server/dist/attachments-config.d.ts +114 -0
  11. package/packages/server/dist/attachments-config.js +165 -0
  12. package/packages/server/dist/attachments-hint.d.ts +53 -0
  13. package/packages/server/dist/attachments-hint.js +140 -0
  14. package/packages/server/dist/attachments.d.ts +33 -0
  15. package/packages/server/dist/attachments.js +117 -0
  16. package/packages/server/dist/auth.d.ts +84 -0
  17. package/packages/server/dist/auth.js +247 -0
  18. package/packages/server/dist/background.d.ts +36 -0
  19. package/packages/server/dist/background.js +137 -0
  20. package/packages/server/dist/bind-safety.d.ts +56 -0
  21. package/packages/server/dist/bind-safety.js +51 -0
  22. package/packages/server/dist/brand.d.ts +44 -0
  23. package/packages/server/dist/brand.js +88 -0
  24. package/packages/server/dist/chat-dto.d.ts +210 -0
  25. package/packages/server/dist/chat-dto.js +308 -0
  26. package/packages/server/dist/cli/import-chats.d.ts +21 -0
  27. package/packages/server/dist/cli/import-chats.js +197 -0
  28. package/packages/server/dist/cli/paddock.d.ts +2 -0
  29. package/packages/server/dist/cli/paddock.js +247 -0
  30. package/packages/server/dist/concurrency.d.ts +57 -0
  31. package/packages/server/dist/concurrency.js +71 -0
  32. package/packages/server/dist/config.d.ts +512 -0
  33. package/packages/server/dist/config.js +593 -0
  34. package/packages/server/dist/curation-config.d.ts +55 -0
  35. package/packages/server/dist/curation-config.js +64 -0
  36. package/packages/server/dist/event-bus.d.ts +87 -0
  37. package/packages/server/dist/event-bus.js +48 -0
  38. package/packages/server/dist/git.d.ts +128 -0
  39. package/packages/server/dist/git.js +446 -0
  40. package/packages/server/dist/github-auth.d.ts +44 -0
  41. package/packages/server/dist/github-auth.js +169 -0
  42. package/packages/server/dist/herdctl-agent-config.d.ts +98 -0
  43. package/packages/server/dist/herdctl-agent-config.js +331 -0
  44. package/packages/server/dist/herdctl-agent-names.d.ts +172 -0
  45. package/packages/server/dist/herdctl-agent-names.js +228 -0
  46. package/packages/server/dist/herdctl-jobs-index.d.ts +65 -0
  47. package/packages/server/dist/herdctl-jobs-index.js +225 -0
  48. package/packages/server/dist/herdctl-jobs.d.ts +98 -0
  49. package/packages/server/dist/herdctl-jobs.js +225 -0
  50. package/packages/server/dist/herdctl.d.ts +572 -0
  51. package/packages/server/dist/herdctl.js +1218 -0
  52. package/packages/server/dist/hook-config.d.ts +217 -0
  53. package/packages/server/dist/hook-config.js +224 -0
  54. package/packages/server/dist/http-bytes.d.ts +24 -0
  55. package/packages/server/dist/http-bytes.js +52 -0
  56. package/packages/server/dist/index.d.ts +1 -0
  57. package/packages/server/dist/index.js +14 -0
  58. package/packages/server/dist/instance-config.d.ts +135 -0
  59. package/packages/server/dist/instance-config.js +345 -0
  60. package/packages/server/dist/localcommand.d.ts +23 -0
  61. package/packages/server/dist/localcommand.js +140 -0
  62. package/packages/server/dist/management-auth.d.ts +99 -0
  63. package/packages/server/dist/management-auth.js +165 -0
  64. package/packages/server/dist/management-config.d.ts +164 -0
  65. package/packages/server/dist/management-config.js +286 -0
  66. package/packages/server/dist/management-mcp-server.d.ts +20 -0
  67. package/packages/server/dist/management-mcp-server.js +95 -0
  68. package/packages/server/dist/management-metadata.d.ts +67 -0
  69. package/packages/server/dist/management-metadata.js +56 -0
  70. package/packages/server/dist/management-ops.d.ts +110 -0
  71. package/packages/server/dist/management-ops.js +449 -0
  72. package/packages/server/dist/management-policy.d.ts +172 -0
  73. package/packages/server/dist/management-policy.js +259 -0
  74. package/packages/server/dist/message-provenance.d.ts +112 -0
  75. package/packages/server/dist/message-provenance.js +260 -0
  76. package/packages/server/dist/models.d.ts +164 -0
  77. package/packages/server/dist/models.js +208 -0
  78. package/packages/server/dist/openapi.d.ts +66 -0
  79. package/packages/server/dist/openapi.js +183 -0
  80. package/packages/server/dist/parent-detach.d.ts +30 -0
  81. package/packages/server/dist/parent-detach.js +109 -0
  82. package/packages/server/dist/preload.d.ts +43 -0
  83. package/packages/server/dist/preload.js +55 -0
  84. package/packages/server/dist/project-files.d.ts +76 -0
  85. package/packages/server/dist/project-files.js +191 -0
  86. package/packages/server/dist/project-mime.d.ts +35 -0
  87. package/packages/server/dist/project-mime.js +55 -0
  88. package/packages/server/dist/project-paths.d.ts +88 -0
  89. package/packages/server/dist/project-paths.js +126 -0
  90. package/packages/server/dist/project-types.d.ts +316 -0
  91. package/packages/server/dist/project-types.js +48 -0
  92. package/packages/server/dist/projects.d.ts +202 -0
  93. package/packages/server/dist/projects.js +894 -0
  94. package/packages/server/dist/queued-message.d.ts +35 -0
  95. package/packages/server/dist/queued-message.js +116 -0
  96. package/packages/server/dist/read-state.d.ts +46 -0
  97. package/packages/server/dist/read-state.js +139 -0
  98. package/packages/server/dist/recovery-config.d.ts +111 -0
  99. package/packages/server/dist/recovery-config.js +105 -0
  100. package/packages/server/dist/recovery.d.ts +262 -0
  101. package/packages/server/dist/recovery.js +490 -0
  102. package/packages/server/dist/resume-drain.d.ts +122 -0
  103. package/packages/server/dist/resume-drain.js +158 -0
  104. package/packages/server/dist/route-context.d.ts +168 -0
  105. package/packages/server/dist/route-context.js +39 -0
  106. package/packages/server/dist/route-errors.d.ts +8 -0
  107. package/packages/server/dist/route-errors.js +13 -0
  108. package/packages/server/dist/routes/chats.d.ts +12 -0
  109. package/packages/server/dist/routes/chats.js +1406 -0
  110. package/packages/server/dist/routes/git.d.ts +13 -0
  111. package/packages/server/dist/routes/git.js +236 -0
  112. package/packages/server/dist/routes/mcp.d.ts +83 -0
  113. package/packages/server/dist/routes/mcp.js +250 -0
  114. package/packages/server/dist/routes/meta.d.ts +15 -0
  115. package/packages/server/dist/routes/meta.js +447 -0
  116. package/packages/server/dist/routes/projects.d.ts +25 -0
  117. package/packages/server/dist/routes/projects.js +736 -0
  118. package/packages/server/dist/routes/triggers.d.ts +21 -0
  119. package/packages/server/dist/routes/triggers.js +324 -0
  120. package/packages/server/dist/routes/workspace-mount.d.ts +48 -0
  121. package/packages/server/dist/routes/workspace-mount.js +32 -0
  122. package/packages/server/dist/routes.d.ts +26 -0
  123. package/packages/server/dist/routes.js +29 -0
  124. package/packages/server/dist/run-provenance.d.ts +109 -0
  125. package/packages/server/dist/run-provenance.js +206 -0
  126. package/packages/server/dist/runs.d.ts +92 -0
  127. package/packages/server/dist/runs.js +72 -0
  128. package/packages/server/dist/schedule-config.d.ts +68 -0
  129. package/packages/server/dist/schedule-config.js +75 -0
  130. package/packages/server/dist/schedule-session.d.ts +34 -0
  131. package/packages/server/dist/schedule-session.js +120 -0
  132. package/packages/server/dist/self-mcp-descriptions.d.ts +20 -0
  133. package/packages/server/dist/self-mcp-descriptions.js +145 -0
  134. package/packages/server/dist/self-mcp-read.d.ts +15 -0
  135. package/packages/server/dist/self-mcp-read.js +97 -0
  136. package/packages/server/dist/self-mcp-triggers.d.ts +30 -0
  137. package/packages/server/dist/self-mcp-triggers.js +144 -0
  138. package/packages/server/dist/self-mcp-types.d.ts +248 -0
  139. package/packages/server/dist/self-mcp-types.js +10 -0
  140. package/packages/server/dist/self-mcp-util.d.ts +73 -0
  141. package/packages/server/dist/self-mcp-util.js +157 -0
  142. package/packages/server/dist/self-mcp-write.d.ts +35 -0
  143. package/packages/server/dist/self-mcp-write.js +215 -0
  144. package/packages/server/dist/self-mcp.d.ts +95 -0
  145. package/packages/server/dist/self-mcp.js +448 -0
  146. package/packages/server/dist/send-file-mcp.d.ts +46 -0
  147. package/packages/server/dist/send-file-mcp.js +281 -0
  148. package/packages/server/dist/session-hub.d.ts +186 -0
  149. package/packages/server/dist/session-hub.js +291 -0
  150. package/packages/server/dist/spawn-capability.d.ts +99 -0
  151. package/packages/server/dist/spawn-capability.js +106 -0
  152. package/packages/server/dist/star.d.ts +26 -0
  153. package/packages/server/dist/star.js +94 -0
  154. package/packages/server/dist/start.d.ts +1 -0
  155. package/packages/server/dist/start.js +21 -0
  156. package/packages/server/dist/subagents.d.ts +337 -0
  157. package/packages/server/dist/subagents.js +626 -0
  158. package/packages/server/dist/sweep.d.ts +122 -0
  159. package/packages/server/dist/sweep.js +696 -0
  160. package/packages/server/dist/tooldetails.d.ts +33 -0
  161. package/packages/server/dist/tooldetails.js +466 -0
  162. package/packages/server/dist/transcribe.d.ts +69 -0
  163. package/packages/server/dist/transcribe.js +119 -0
  164. package/packages/server/dist/transcripts.d.ts +42 -0
  165. package/packages/server/dist/transcripts.js +164 -0
  166. package/packages/server/dist/trigger-config.d.ts +278 -0
  167. package/packages/server/dist/trigger-config.js +417 -0
  168. package/packages/server/dist/trigger-runtime.d.ts +94 -0
  169. package/packages/server/dist/trigger-runtime.js +82 -0
  170. package/packages/server/dist/trigger-session.d.ts +34 -0
  171. package/packages/server/dist/trigger-session.js +122 -0
  172. package/packages/server/dist/triggers.d.ts +83 -0
  173. package/packages/server/dist/triggers.js +124 -0
  174. package/packages/server/dist/trusted-proxy.d.ts +57 -0
  175. package/packages/server/dist/trusted-proxy.js +157 -0
  176. package/packages/server/dist/turn-notice.d.ts +154 -0
  177. package/packages/server/dist/turn-notice.js +271 -0
  178. package/packages/server/dist/unread.d.ts +36 -0
  179. package/packages/server/dist/unread.js +123 -0
  180. package/packages/server/dist/usage.d.ts +66 -0
  181. package/packages/server/dist/usage.js +243 -0
  182. package/packages/server/dist/wake-injection.d.ts +156 -0
  183. package/packages/server/dist/wake-injection.js +136 -0
  184. package/packages/server/dist/whisper-local.d.ts +9 -0
  185. package/packages/server/dist/whisper-local.js +122 -0
  186. package/packages/server/dist/ws-context.d.ts +158 -0
  187. package/packages/server/dist/ws-context.js +1 -0
  188. package/packages/server/dist/ws-protocol.d.ts +423 -0
  189. package/packages/server/dist/ws-protocol.js +251 -0
  190. package/packages/server/dist/ws-self-mcp.d.ts +52 -0
  191. package/packages/server/dist/ws-self-mcp.js +28 -0
  192. package/packages/server/dist/ws-triggers.d.ts +29 -0
  193. package/packages/server/dist/ws-triggers.js +261 -0
  194. package/packages/server/dist/ws-turn.d.ts +86 -0
  195. package/packages/server/dist/ws-turn.js +751 -0
  196. package/packages/server/dist/ws.d.ts +62 -0
  197. package/packages/server/dist/ws.js +1024 -0
  198. package/packages/server/package.json +6 -0
  199. package/packages/web/dist/assets/InstanceConfigPage-4cQGTj9Y.js +2 -0
  200. package/packages/web/dist/assets/MarkdownRenderer-CJZFLj_8.js +30 -0
  201. package/packages/web/dist/assets/ProjectRedirect-BHwVbbqB.js +2 -0
  202. package/packages/web/dist/assets/ProjectView-BOvuAITg.js +13 -0
  203. package/packages/web/dist/assets/ProjectsGrid-BCojZOGY.js +2 -0
  204. package/packages/web/dist/assets/arc-BVyxvnkl.js +2 -0
  205. package/packages/web/dist/assets/architectureDiagram-3BPJPVTR-Cd9Puqg1.js +37 -0
  206. package/packages/web/dist/assets/bash-I8pq0VWm.js +2 -0
  207. package/packages/web/dist/assets/blockDiagram-GPEHLZMM-B_AQt_Rx.js +133 -0
  208. package/packages/web/dist/assets/c-D2F1sQUL.js +2 -0
  209. package/packages/web/dist/assets/c4Diagram-AAUBKEIU-7e0TQtXB.js +11 -0
  210. package/packages/web/dist/assets/channel-C_1aISNn.js +2 -0
  211. package/packages/web/dist/assets/chunk-2J33WTMH-Dz4WZmUZ.js +2 -0
  212. package/packages/web/dist/assets/chunk-4BX2VUAB-DVWYldo6.js +2 -0
  213. package/packages/web/dist/assets/chunk-55IACEB6-BIMrizQd.js +2 -0
  214. package/packages/web/dist/assets/chunk-727SXJPM-CL2q9fF1.js +207 -0
  215. package/packages/web/dist/assets/chunk-AQP2D5EJ-BSq3HlQ9.js +232 -0
  216. package/packages/web/dist/assets/chunk-FMBD7UC4-Bgt64pLE.js +16 -0
  217. package/packages/web/dist/assets/chunk-ND2GUHAM-C8Pr2A38.js +2 -0
  218. package/packages/web/dist/assets/chunk-QZHKN3VN-BAOqh-MN.js +2 -0
  219. package/packages/web/dist/assets/classDiagram-4FO5ZUOK-B8JE7cHJ.js +2 -0
  220. package/packages/web/dist/assets/classDiagram-v2-Q7XG4LA2-B8JE7cHJ.js +2 -0
  221. package/packages/web/dist/assets/core-lJeGACQg.js +4 -0
  222. package/packages/web/dist/assets/cose-bilkent-S5V4N54A-BF4tameA.js +2 -0
  223. package/packages/web/dist/assets/cpp-Bm3ii6kY.js +2 -0
  224. package/packages/web/dist/assets/csharp-BNpuYZMG.js +2 -0
  225. package/packages/web/dist/assets/css-DazXZka4.js +2 -0
  226. package/packages/web/dist/assets/cytoscape.esm-CUqq0XTU.js +332 -0
  227. package/packages/web/dist/assets/dagre-BM42HDAG-DdsLM6ql.js +5 -0
  228. package/packages/web/dist/assets/defaultLocale-DX6XiGOO.js +2 -0
  229. package/packages/web/dist/assets/diagram-2AECGRRQ-BQ78S_RM.js +44 -0
  230. package/packages/web/dist/assets/diagram-5GNKFQAL-CAKE6nHE.js +11 -0
  231. package/packages/web/dist/assets/diagram-KO2AKTUF-fEvHRXgr.js +4 -0
  232. package/packages/web/dist/assets/diagram-LMA3HP47-CtWsgeSm.js +25 -0
  233. package/packages/web/dist/assets/diagram-OG6HWLK6-Buog8k7_.js +25 -0
  234. package/packages/web/dist/assets/erDiagram-TEJ5UH35-CWvVVPZS.js +86 -0
  235. package/packages/web/dist/assets/flowDiagram-I6XJVG4X-DsCGXtp4.js +163 -0
  236. package/packages/web/dist/assets/format-DamJQ9LO.js +2 -0
  237. package/packages/web/dist/assets/ganttDiagram-6RSMTGT7-CsdwIvvC.js +293 -0
  238. package/packages/web/dist/assets/gitGraphDiagram-PVQCEYII-hZvrX1sD.js +107 -0
  239. package/packages/web/dist/assets/go-BPx_y7j8.js +2 -0
  240. package/packages/web/dist/assets/graph-BlwPajkw.js +2 -0
  241. package/packages/web/dist/assets/index-CGbZdrm8.js +71 -0
  242. package/packages/web/dist/assets/index-DJDQ210-.css +1 -0
  243. package/packages/web/dist/assets/infoDiagram-5YYISTIA-nE_Vtz_l.js +3 -0
  244. package/packages/web/dist/assets/ini-B3BVgEsG.js +2 -0
  245. package/packages/web/dist/assets/init-Gi6I4Gst.js +2 -0
  246. package/packages/web/dist/assets/ishikawaDiagram-YF4QCWOH-2Nlqs0oH.js +71 -0
  247. package/packages/web/dist/assets/java-B5VKqtH2.js +2 -0
  248. package/packages/web/dist/assets/javascript-BKRaQes9.js +2 -0
  249. package/packages/web/dist/assets/journeyDiagram-JHISSGLW-mjU1fMc4.js +140 -0
  250. package/packages/web/dist/assets/json-DIYVocXf.js +2 -0
  251. package/packages/web/dist/assets/kanban-definition-UN3LZRKU-C_9xNaa3.js +90 -0
  252. package/packages/web/dist/assets/katex-C5jXJg4s.js +258 -0
  253. package/packages/web/dist/assets/kotlin-Cw-eF_bm.js +3 -0
  254. package/packages/web/dist/assets/lastTab-CU1zsF0j.js +2 -0
  255. package/packages/web/dist/assets/layout-Boy8vhSP.js +2 -0
  256. package/packages/web/dist/assets/linear-BxKd91ho.js +2 -0
  257. package/packages/web/dist/assets/mermaid.core-C-CuhD8I.js +310 -0
  258. package/packages/web/dist/assets/mindmap-definition-RKZ34NQL-Bs6yfcZv.js +97 -0
  259. package/packages/web/dist/assets/ordinal-Cboi1Yqb.js +2 -0
  260. package/packages/web/dist/assets/php-CRdd4dfS.js +3 -0
  261. package/packages/web/dist/assets/pieDiagram-4H26LBE5-DNdqX7O5.js +31 -0
  262. package/packages/web/dist/assets/python-kSlZHhJb.js +2 -0
  263. package/packages/web/dist/assets/quadrantDiagram-W4KKPZXB-ZMJl9OdZ.js +8 -0
  264. package/packages/web/dist/assets/queued-LamEU0GH.js +2 -0
  265. package/packages/web/dist/assets/requirementDiagram-4Y6WPE33-RmxMdm2q.js +85 -0
  266. package/packages/web/dist/assets/ruby-7T4ktxyv.js +2 -0
  267. package/packages/web/dist/assets/rust-HC3MBUhY.js +2 -0
  268. package/packages/web/dist/assets/sankeyDiagram-5OEKKPKP-OAAhWcfK.js +41 -0
  269. package/packages/web/dist/assets/scss-DZLA7YXz.js +2 -0
  270. package/packages/web/dist/assets/sequenceDiagram-3UESZ5HK-BWF7rCyN.js +163 -0
  271. package/packages/web/dist/assets/sql-BC88IN-V.js +2 -0
  272. package/packages/web/dist/assets/stateDiagram-AJRCARHV-M3b_zqqo.js +2 -0
  273. package/packages/web/dist/assets/stateDiagram-v2-BHNVJYJU-CI7saFDa.js +2 -0
  274. package/packages/web/dist/assets/swift-Dn8kKO_1.js +2 -0
  275. package/packages/web/dist/assets/timeline-definition-PNZ67QCA-BpOCh63N.js +121 -0
  276. package/packages/web/dist/assets/typescript-C2FFdlUC.js +2 -0
  277. package/packages/web/dist/assets/vennDiagram-CIIHVFJN-D_iPH45Q.js +35 -0
  278. package/packages/web/dist/assets/wardley-L42UT6IY-DVD9I2Om.js +174 -0
  279. package/packages/web/dist/assets/wardleyDiagram-YWT4CUSO-Bn1IKwjn.js +79 -0
  280. package/packages/web/dist/assets/xml-BXBhIUeX.js +2 -0
  281. package/packages/web/dist/assets/xychartDiagram-2RQKCTM6-DwtI0bkR.js +8 -0
  282. package/packages/web/dist/assets/yaml-drsDnIKT.js +2 -0
  283. package/packages/web/dist/favicon.ico +0 -0
  284. package/packages/web/dist/fonts/inter-latin.woff2 +0 -0
  285. package/packages/web/dist/fonts/jetbrains-mono-latin.woff2 +0 -0
  286. package/packages/web/dist/icons/apple-touch-icon.png +0 -0
  287. package/packages/web/dist/icons/favicon-16.png +0 -0
  288. package/packages/web/dist/icons/favicon-32.png +0 -0
  289. package/packages/web/dist/icons/icon-192.png +0 -0
  290. package/packages/web/dist/icons/icon-512.png +0 -0
  291. package/packages/web/dist/icons/maskable-512.png +0 -0
  292. package/packages/web/dist/index.html +56 -0
  293. package/packages/web/dist/manifest.webmanifest +32 -0
  294. package/packages/web/dist/sw.js +139 -0
@@ -0,0 +1,262 @@
1
+ import { type RecoveryConfig } from "./recovery-config.js";
2
+ import type { Project } from "./projects.js";
3
+ /**
4
+ * The kinds of transcript entry the hang detector cares about. Everything that
5
+ * isn't a keeper `assistant` turn or a terminated `<task-notification>` (system
6
+ * lines, attachments, queue-operations, tool_result user turns, clean/running
7
+ * notifications, …) is `other` and doesn't move the pending state.
8
+ */
9
+ export type TailEvent = "assistant" | "terminated-notification" | "other";
10
+ /** A minimal structural view of one parsed transcript JSONL entry. */
11
+ interface TranscriptEntry {
12
+ type?: string;
13
+ message?: {
14
+ role?: string;
15
+ content?: unknown;
16
+ };
17
+ /** Present on a `type:"queue-operation"` entry (`enqueue`/`dequeue`). */
18
+ operation?: string;
19
+ /** The payload of a `queue-operation` enqueue — for a killed background task
20
+ * this IS the `<task-notification>` (string, or an array of text blocks). #347 */
21
+ content?: unknown;
22
+ }
23
+ /**
24
+ * Classify one already-parsed transcript entry as the hang detector sees it.
25
+ *
26
+ * A terminated `<task-notification>` reaches the transcript in TWO shapes, and we
27
+ * must catch both (issue #347):
28
+ * - As a materialised `type:"user"` entry — but that only appears once a LATER
29
+ * turn flushes the SDK's input queue, often tens of seconds after the kill.
30
+ * - At the moment of the kill, as a `type:"queue-operation"` `enqueue` whose
31
+ * `content` IS the notification. This is the one that lands inside the watch
32
+ * window; missing it (the original bug) let every real hang go undetected.
33
+ *
34
+ * A keeper reply is `assistant`; a killed/stopped notification in either shape is
35
+ * `terminated-notification`; everything else (system lines, attachments, a
36
+ * `dequeue`, a completed/running notification, plain user text) is `other`.
37
+ */
38
+ export declare function classifyEntry(entry: TranscriptEntry): TailEvent;
39
+ /**
40
+ * Parse one raw JSONL line into its {@link TailEvent} plus, for a terminated
41
+ * notification, its human-readable `<summary>` (used by the live surface frame).
42
+ * Unparseable/blank → `other`.
43
+ */
44
+ export declare function parseTailLine(line: string): {
45
+ event: TailEvent;
46
+ summary?: string;
47
+ };
48
+ /** Classify one raw JSONL line (unparseable/blank → `other`). */
49
+ export declare function classifyLine(line: string): TailEvent;
50
+ /**
51
+ * Reduce an ordered stream of tail events to whether the transcript currently ends
52
+ * (logically) with an un-answered terminated task-notification — the hung
53
+ * signature. An `assistant` entry clears any pending notification (the keeper
54
+ * woke); a terminated notification sets it; `other` entries are inert. True iff a
55
+ * terminated notification is still pending after the last event.
56
+ */
57
+ export declare function detectHang(events: Iterable<TailEvent>): boolean;
58
+ /** A scheduled-timer handle — opaque; produced by `setTimer`, passed to `clearTimer`. */
59
+ export type TimerHandle = ReturnType<typeof setTimeout>;
60
+ /** Appended-transcript reader result: the new text and the file's current size. */
61
+ export interface TranscriptTail {
62
+ /** UTF-8 text appended since the requested offset (may be empty). */
63
+ text: string;
64
+ /** The file's current size in bytes (the next offset to read from). */
65
+ size: number;
66
+ }
67
+ /** Injectable primitives so the timing-sensitive watch is deterministically testable. */
68
+ export interface RecoveryEngineDeps {
69
+ /** Resolve the recovery config for a dispatch — instance default here; the engine
70
+ * layers the per-project override on top via {@link resolveRecoveryConfig}. */
71
+ cfg: {
72
+ recovery: RecoveryConfig;
73
+ };
74
+ /** Look up the target project (for its `.chats/` dir + `recovery` override). Throws
75
+ * for an unknown/deleted project — the engine treats that as "nothing to recover". */
76
+ getProject: (slug: string) => Promise<Project>;
77
+ /** Inject the recovery nudge into the still-alive session (Layer 2's exact path:
78
+ * `startAgentTurn({ resume, prompt: RECOVERY_NUDGE, sender: { kind: "recovery" } })`). */
79
+ reDrive: (project: Project, sessionId: string) => Promise<void>;
80
+ /** Surface the detected kill to any attached client LIVE (Layer 2 `surfaceKilledTask`)
81
+ * so the "keeper is idle / Continue" affordance appears WITHOUT a refresh — the
82
+ * notification is otherwise trapped in the SDK input queue until the next turn
83
+ * flushes it (issue #347). `summary` is the notification's `<summary>`, if any.
84
+ * Default no-op (surfacing off). */
85
+ surface?: (project: Project, sessionId: string, summary: string | undefined) => void;
86
+ /**
87
+ * Is a live turn ALREADY driving this session? (issue #352 — double-dispatch
88
+ * guard.) When the watch decides a keeper is hung, something else may have begun
89
+ * driving the same session in the meantime — a human message, a queued-message
90
+ * drain, or a prior recovery nudge. Under session-mode `chatSession(resume)` a
91
+ * SECOND resume interrupts the first, so an auto re-drive fired into a live turn
92
+ * would be swallowed (the "first message swallowed" symptom, #350/#347). If this
93
+ * reports the session busy, the engine DEFERS (see {@link sdkSessionLive}) rather
94
+ * than firing — the keeper is not idle. Default: never busy (so the pure
95
+ * unit-tested engine behaviour is unchanged).
96
+ */
97
+ isBusy?: (sessionId: string) => boolean;
98
+ /**
99
+ * Is a `claude` SUBPROCESS still alive on this session at the herdctl/SDK layer?
100
+ * (issue #397.) {@link isBusy} only reflects turns PADDOCK's hub started, so it
101
+ * is BLIND to a session herdctl's `SessionReaper` is keeping alive for a killed
102
+ * background task (keepAlive) or holding through its ~15s re-invocation grace —
103
+ * throughout which `reaper.isSessionLive` is TRUE. Auto re-drive resumes via a
104
+ * FRESH `openChatSession` = a NEW subprocess on the same session id; firing while
105
+ * a prior subprocess is still live spawns a COMPETING concurrent resume that the
106
+ * SDK resolves by interrupting the in-flight turn (`[Request interrupted by
107
+ * user]`) — the recovery turn then produces nothing and the user is still stuck.
108
+ * Wired in prod to `getSessionLifecycle()?.reaper.isSessionLive(sessionId)`;
109
+ * default `() => false` keeps the pure engine behaviour unchanged (batch mode /
110
+ * no reaper). Treated as a busy signal ORed with {@link isBusy}; when EITHER is
111
+ * set the engine DEFERS the fire (not a permanent stand-down — see {@link
112
+ * DEFAULT_SETTLE_WINDOW_MS}) so the nudge lands exactly once, after the session
113
+ * is genuinely idle (reaper reaped, hub not running).
114
+ */
115
+ sdkSessionLive?: (sessionId: string) => boolean;
116
+ /** Wall clock (ms). Default `Date.now`. */
117
+ now?: () => number;
118
+ /** Schedule a one-shot timer. Default `setTimeout`. */
119
+ setTimer?: (fn: () => void, ms: number) => TimerHandle;
120
+ /** Cancel a scheduled timer. Default `clearTimeout`. */
121
+ clearTimer?: (h: TimerHandle) => void;
122
+ /** Read the transcript bytes appended since `offset`. Default reads `<dir>/.chats/<id>.jsonl`. */
123
+ readTail?: (file: string, offset: number) => Promise<TranscriptTail>;
124
+ /**
125
+ * Cheap current size (bytes) of the transcript, for the arm-time baseline — a
126
+ * `stat`, NOT a full read. Called once per armed watch on EVERY session-mode
127
+ * keeper turn, so it must not slurp the (multi-MB) transcript. A missing file
128
+ * (turn wrote none yet) → 0. Default `fsp.stat(file).size`.
129
+ */
130
+ fileSize?: (file: string) => Promise<number>;
131
+ /** Poll cadence (ms) while watching. Default {@link DEFAULT_POLL_MS}. */
132
+ pollMs?: number;
133
+ /** Extra window (ms) beyond `debounceMs` to allow the kill to land. Default {@link DEFAULT_KILL_GRACE_MS}. */
134
+ killGraceMs?: number;
135
+ /**
136
+ * Cadence (ms) at which a DEFERRED fire re-checks liveness while the session is
137
+ * still held live by the hub or the reaper (issue #397). Default {@link
138
+ * DEFAULT_SETTLE_POLL_MS}.
139
+ */
140
+ settlePollMs?: number;
141
+ /**
142
+ * Total budget (ms) to keep deferring a fire while the session stays live before
143
+ * giving up, so a session the reaper never releases can't defer forever (issue
144
+ * #397). Default {@link DEFAULT_SETTLE_WINDOW_MS}.
145
+ */
146
+ settleWindowMs?: number;
147
+ /** Optional structured-log sink for observability; default no-op. */
148
+ log?: (msg: string, meta?: Record<string, unknown>) => void;
149
+ }
150
+ /** Default poll cadence — brisk enough to catch the kill+debounce, cheap enough to ignore. */
151
+ export declare const DEFAULT_POLL_MS = 750;
152
+ /**
153
+ * How long past `debounceMs` we keep watching for the kill to land. herdctl#374's
154
+ * teardown fires ~2–8s after the turn boundary, so the notification can appear late;
155
+ * this grace ensures its full `debounceMs` quiet window still fits inside the watch.
156
+ */
157
+ export declare const DEFAULT_KILL_GRACE_MS = 12000;
158
+ /**
159
+ * Cadence (ms) at which a deferred fire re-checks whether the session has gone
160
+ * idle (issue #397). Brisk enough to fire promptly once the reaper releases,
161
+ * cheap enough to ignore.
162
+ */
163
+ export declare const DEFAULT_SETTLE_POLL_MS = 1000;
164
+ /**
165
+ * How long (ms) the engine keeps DEFERRING an otherwise-ready fire while the
166
+ * session is still live (hub or reaper) before standing down (issue #397). Must
167
+ * comfortably exceed herdctl's `DEFAULT_REINVOCATION_GRACE_MS` (15s) — the reaper
168
+ * holds a just-killed-task session live for that grace — plus margin, so the
169
+ * deferred nudge lands once the reaper reaps rather than giving up early. Bounds
170
+ * the defer so a session the reaper never releases can't retry forever.
171
+ */
172
+ export declare const DEFAULT_SETTLE_WINDOW_MS = 30000;
173
+ /**
174
+ * Layer 3 automatic-recovery engine (issue #301). Arm a post-turn transcript watch
175
+ * after each session-mode keeper turn; if a killed-at-turn-boundary notification
176
+ * appears with no keeper response, auto-inject a recovery nudge — guarded by
177
+ * debounce + a per-session retry cap, and cleared when a human next messages.
178
+ */
179
+ export declare class RecoveryEngine {
180
+ private readonly deps;
181
+ private readonly now;
182
+ private readonly setTimer;
183
+ private readonly clearTimer;
184
+ private readonly readTail;
185
+ private readonly fileSize;
186
+ private readonly pollMs;
187
+ private readonly killGraceMs;
188
+ private readonly settlePollMs;
189
+ private readonly settleWindowMs;
190
+ private readonly log;
191
+ private readonly surface;
192
+ private readonly isBusy;
193
+ private readonly sdkSessionLive;
194
+ /** Per-session retry/debounce bookkeeping — cleared on a human message. */
195
+ private readonly guards;
196
+ /** In-flight watches keyed by session id — re-arming or a human message cancels one. */
197
+ private readonly watches;
198
+ constructor(deps: RecoveryEngineDeps);
199
+ /**
200
+ * Arm (or re-arm) a post-turn watch for a just-completed SESSION-mode keeper turn.
201
+ * No-op unless SOMETHING wants it for this project: Layer 2 `surfaceKilledTask`
202
+ * (surface the kill live) or Layer 3 `autoReDrive` (auto re-drive, while the
203
+ * session has retries left). Re-arming cancels any prior watch for the same
204
+ * session. Safe to call fire-and-forget; never throws (a lookup/IO failure just
205
+ * declines to watch).
206
+ */
207
+ armWatch(input: {
208
+ slug: string;
209
+ sessionId: string;
210
+ }): void;
211
+ private armWatchAsync;
212
+ /**
213
+ * A detected turn-boundary kill is ready to recover — kick off the fire, giving
214
+ * it a bounded {@link settleWindowMs} budget to wait out any still-live session.
215
+ * See {@link fireWhenIdle} for the surface/re-drive actions and the defer guard.
216
+ */
217
+ private fire;
218
+ /**
219
+ * Handle a detected turn-boundary kill. Two independent, resolved-config-gated
220
+ * actions, in order:
221
+ * 1. `surfaceKilledTask` — push the kill to attached clients LIVE so the
222
+ * "keeper is idle / Continue" affordance appears without a refresh. Never
223
+ * throws; a bad sink can't wedge the engine.
224
+ * 2. `autoReDrive` (under the retry cap) — bump the session's retry bookkeeping
225
+ * FIRST (so a re-drive that itself hangs can't exceed the cap), then inject
226
+ * the recovery nudge via the shared Layer 2 path. A failed inject is logged.
227
+ *
228
+ * Liveness guard + defer (issues #352 / #397). Two busy signals mean the session
229
+ * is NOT idle and firing would collide with a live `claude` subprocess:
230
+ * - {@link isBusy} (hub) — a live turn PADDOCK itself started (a human message,
231
+ * a queued-message drain, or a prior recovery nudge).
232
+ * - {@link sdkSessionLive} (reaper) — a subprocess herdctl is keeping alive for
233
+ * the just-killed background task, or holding through its ~15s re-invocation
234
+ * grace. `isBusy` is BLIND to this, which is what let the auto re-drive fire a
235
+ * COMPETING resume and get interrupted (`[Request interrupted by user]`, #397).
236
+ *
237
+ * When EITHER is set we must NOT fire — but standing down *permanently* leaves
238
+ * recovery incomplete: the reaper reaps SILENTLY (no turn completes, so nothing
239
+ * re-arms a watch), and the user stays stuck. So instead we DEFER: re-check after
240
+ * {@link settlePollMs} and fire exactly once the session is genuinely idle
241
+ * (reaper reaped, hub not running). The deferral is bounded by
242
+ * {@link settleWindowMs} so a session that never releases can't retry forever, and
243
+ * is tracked in {@link watches} so a completing turn ({@link armWatch}) or a human
244
+ * message ({@link onHumanMessage}) supersedes/cancels it — no double fire.
245
+ */
246
+ private fireWhenIdle;
247
+ /**
248
+ * A human just messaged this session — clear its retry/debounce bookkeeping and
249
+ * cancel any in-flight watch, so a genuinely-new later hang is recovered fresh
250
+ * (the retry cap counts auto re-drives BETWEEN human messages).
251
+ */
252
+ onHumanMessage(sessionId: string): void;
253
+ /** Cancel the in-flight watch for a session, if any (idempotent). */
254
+ private cancelWatch;
255
+ /** Cancel every in-flight watch (e.g. on shutdown). */
256
+ stopAll(): void;
257
+ /** Test/inspection helper: the current retry count for a session (0 if untracked). */
258
+ retryCountFor(sessionId: string): number;
259
+ /** Test/inspection helper: whether a watch is currently armed for a session. */
260
+ isWatching(sessionId: string): boolean;
261
+ }
262
+ export {};