@scotthuang/agent-knock-knock 0.12.11 → 0.12.13

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 (344) hide show
  1. package/CHANGELOG.md +40 -0
  2. package/README.md +43 -30
  3. package/dist/src/approval-policy.d.ts +11 -2
  4. package/dist/src/approval-policy.js +33 -7
  5. package/dist/src/approval-policy.js.map +1 -1
  6. package/dist/src/callback-cli-adapter.d.ts +47 -0
  7. package/dist/src/callback-cli-adapter.js +156 -0
  8. package/dist/src/callback-cli-adapter.js.map +1 -0
  9. package/dist/src/callback-outbox-policy.d.ts +95 -0
  10. package/dist/src/callback-outbox-policy.js +149 -0
  11. package/dist/src/callback-outbox-policy.js.map +1 -0
  12. package/dist/src/callback-outbox-service.d.ts +247 -0
  13. package/dist/src/callback-outbox-service.js +1053 -0
  14. package/dist/src/callback-outbox-service.js.map +1 -0
  15. package/dist/src/callback-outbox-settlement.d.ts +54 -0
  16. package/dist/src/callback-outbox-settlement.js +241 -0
  17. package/dist/src/callback-outbox-settlement.js.map +1 -0
  18. package/dist/src/canonical-json.d.ts +1 -0
  19. package/dist/src/canonical-json.js +14 -0
  20. package/dist/src/canonical-json.js.map +1 -0
  21. package/dist/src/claude-lifecycle-compatibility.js +15 -0
  22. package/dist/src/claude-lifecycle-compatibility.js.map +1 -1
  23. package/dist/src/claude-local-transcript-provider.d.ts +82 -1
  24. package/dist/src/claude-local-transcript-provider.js +873 -23
  25. package/dist/src/claude-local-transcript-provider.js.map +1 -1
  26. package/dist/src/cli-command-runtime.d.ts +14 -0
  27. package/dist/src/cli-command-runtime.js +164 -0
  28. package/dist/src/cli-command-runtime.js.map +1 -0
  29. package/dist/src/cli-core.d.ts +4 -42
  30. package/dist/src/cli-core.js +958 -28684
  31. package/dist/src/cli-core.js.map +1 -1
  32. package/dist/src/cli-runtime-context.d.ts +57 -0
  33. package/dist/src/cli-runtime-context.js +118 -0
  34. package/dist/src/cli-runtime-context.js.map +1 -0
  35. package/dist/src/codex-lifecycle-compatibility.js +2 -1
  36. package/dist/src/codex-lifecycle-compatibility.js.map +1 -1
  37. package/dist/src/codex-local-session-provider.d.ts +18 -0
  38. package/dist/src/codex-local-session-provider.js +67 -0
  39. package/dist/src/codex-local-session-provider.js.map +1 -1
  40. package/dist/src/codex-session-provider.js +1 -3
  41. package/dist/src/codex-session-provider.js.map +1 -1
  42. package/dist/src/conversation-trace.d.ts +30 -0
  43. package/dist/src/conversation-trace.js +185 -0
  44. package/dist/src/conversation-trace.js.map +1 -0
  45. package/dist/src/deferred-foreground-application-service.d.ts +84 -0
  46. package/dist/src/deferred-foreground-application-service.js +742 -0
  47. package/dist/src/deferred-foreground-application-service.js.map +1 -0
  48. package/dist/src/deferred-foreground-authority-cli-adapter.d.ts +78 -0
  49. package/dist/src/deferred-foreground-authority-cli-adapter.js +795 -0
  50. package/dist/src/deferred-foreground-authority-cli-adapter.js.map +1 -0
  51. package/dist/src/deferred-foreground-boundary.d.ts +61 -0
  52. package/dist/src/deferred-foreground-boundary.js +2 -0
  53. package/dist/src/deferred-foreground-boundary.js.map +1 -0
  54. package/dist/src/deferred-foreground-capability.d.ts +4 -0
  55. package/dist/src/deferred-foreground-capability.js +184 -0
  56. package/dist/src/deferred-foreground-capability.js.map +1 -0
  57. package/dist/src/deferred-foreground-preparation-cli-adapter.d.ts +53 -0
  58. package/dist/src/deferred-foreground-preparation-cli-adapter.js +210 -0
  59. package/dist/src/deferred-foreground-preparation-cli-adapter.js.map +1 -0
  60. package/dist/src/deferred-foreground-preparation-service.d.ts +72 -0
  61. package/dist/src/deferred-foreground-preparation-service.js +179 -0
  62. package/dist/src/deferred-foreground-preparation-service.js.map +1 -0
  63. package/dist/src/deferred-foreground-recovery-cli-adapter.d.ts +139 -0
  64. package/dist/src/deferred-foreground-recovery-cli-adapter.js +1125 -0
  65. package/dist/src/deferred-foreground-recovery-cli-adapter.js.map +1 -0
  66. package/dist/src/deferred-foreground-recovery-service.d.ts +48 -0
  67. package/dist/src/deferred-foreground-recovery-service.js +91 -0
  68. package/dist/src/deferred-foreground-recovery-service.js.map +1 -0
  69. package/dist/src/deferred-foreground-transfer-policy.d.ts +2 -0
  70. package/dist/src/deferred-foreground-transfer-policy.js +10 -0
  71. package/dist/src/deferred-foreground-transfer-policy.js.map +1 -0
  72. package/dist/src/deferred-foreground-transfer.js +46 -105
  73. package/dist/src/deferred-foreground-transfer.js.map +1 -1
  74. package/dist/src/doctor-capabilities.d.ts +9 -0
  75. package/dist/src/doctor-capabilities.js +22 -0
  76. package/dist/src/doctor-capabilities.js.map +1 -1
  77. package/dist/src/durable-json-file.d.ts +22 -0
  78. package/dist/src/durable-json-file.js +127 -0
  79. package/dist/src/durable-json-file.js.map +1 -0
  80. package/dist/src/file-lock-cli-adapter.d.ts +43 -0
  81. package/dist/src/file-lock-cli-adapter.js +150 -0
  82. package/dist/src/file-lock-cli-adapter.js.map +1 -0
  83. package/dist/src/herdr-terminal-control-provider.js +1 -3
  84. package/dist/src/herdr-terminal-control-provider.js.map +1 -1
  85. package/dist/src/install-doctor-command-adapter.d.ts +17 -0
  86. package/dist/src/install-doctor-command-adapter.js +225 -0
  87. package/dist/src/install-doctor-command-adapter.js.map +1 -0
  88. package/dist/src/live-lifecycle-evidence.js +76 -46
  89. package/dist/src/live-lifecycle-evidence.js.map +1 -1
  90. package/dist/src/live-lifecycle-smoke.js +74 -50
  91. package/dist/src/live-lifecycle-smoke.js.map +1 -1
  92. package/dist/src/managed-session.d.ts +2 -0
  93. package/dist/src/managed-session.js +24 -0
  94. package/dist/src/managed-session.js.map +1 -1
  95. package/dist/src/managed-turn-recovery-service.d.ts +86 -0
  96. package/dist/src/managed-turn-recovery-service.js +145 -0
  97. package/dist/src/managed-turn-recovery-service.js.map +1 -0
  98. package/dist/src/mutation-transaction.d.ts +48 -0
  99. package/dist/src/mutation-transaction.js +73 -0
  100. package/dist/src/mutation-transaction.js.map +1 -0
  101. package/dist/src/native-thread-lifecycle-cli-adapter.d.ts +154 -0
  102. package/dist/src/native-thread-lifecycle-cli-adapter.js +786 -0
  103. package/dist/src/native-thread-lifecycle-cli-adapter.js.map +1 -0
  104. package/dist/src/native-thread-lifecycle-ledger-cli-adapter.d.ts +25 -0
  105. package/dist/src/native-thread-lifecycle-ledger-cli-adapter.js +50 -0
  106. package/dist/src/native-thread-lifecycle-ledger-cli-adapter.js.map +1 -0
  107. package/dist/src/native-thread-lifecycle-query-service.d.ts +75 -0
  108. package/dist/src/native-thread-lifecycle-query-service.js +297 -0
  109. package/dist/src/native-thread-lifecycle-query-service.js.map +1 -0
  110. package/dist/src/native-thread-lifecycle-recovery-adapter.d.ts +45 -0
  111. package/dist/src/native-thread-lifecycle-recovery-adapter.js +154 -0
  112. package/dist/src/native-thread-lifecycle-recovery-adapter.js.map +1 -0
  113. package/dist/src/native-thread-lifecycle-recovery-service.d.ts +211 -0
  114. package/dist/src/native-thread-lifecycle-recovery-service.js +1093 -0
  115. package/dist/src/native-thread-lifecycle-recovery-service.js.map +1 -0
  116. package/dist/src/native-thread-resume-snapshot-policy.d.ts +73 -0
  117. package/dist/src/native-thread-resume-snapshot-policy.js +218 -0
  118. package/dist/src/native-thread-resume-snapshot-policy.js.map +1 -0
  119. package/dist/src/native-thread-resume-snapshot.d.ts +3 -61
  120. package/dist/src/native-thread-resume-snapshot.js +2 -143
  121. package/dist/src/native-thread-resume-snapshot.js.map +1 -1
  122. package/dist/src/native-thread-transition-application.d.ts +147 -0
  123. package/dist/src/native-thread-transition-application.js +974 -0
  124. package/dist/src/native-thread-transition-application.js.map +1 -0
  125. package/dist/src/native-thread-transition-policy.d.ts +127 -0
  126. package/dist/src/native-thread-transition-policy.js +154 -0
  127. package/dist/src/native-thread-transition-policy.js.map +1 -0
  128. package/dist/src/native-thread-transition-resource-adapter.d.ts +12 -0
  129. package/dist/src/native-thread-transition-resource-adapter.js +44 -0
  130. package/dist/src/native-thread-transition-resource-adapter.js.map +1 -0
  131. package/dist/src/native-thread-transition-settlement-service.d.ts +94 -0
  132. package/dist/src/native-thread-transition-settlement-service.js +134 -0
  133. package/dist/src/native-thread-transition-settlement-service.js.map +1 -0
  134. package/dist/src/native-thread-transition-verification-adapter.d.ts +62 -0
  135. package/dist/src/native-thread-transition-verification-adapter.js +451 -0
  136. package/dist/src/native-thread-transition-verification-adapter.js.map +1 -0
  137. package/dist/src/openclaw-callback-transport.d.ts +69 -0
  138. package/dist/src/openclaw-callback-transport.js +583 -0
  139. package/dist/src/openclaw-callback-transport.js.map +1 -0
  140. package/dist/src/openclaw-plugin-callback-adapter.d.ts +1 -0
  141. package/dist/src/openclaw-plugin-callback-adapter.js +423 -0
  142. package/dist/src/openclaw-plugin-callback-adapter.js.map +1 -0
  143. package/dist/src/openclaw-plugin-command-adapter.d.ts +16 -0
  144. package/dist/src/openclaw-plugin-command-adapter.js +1868 -0
  145. package/dist/src/openclaw-plugin-command-adapter.js.map +1 -0
  146. package/dist/src/openclaw-plugin-helpers.d.ts +27 -4
  147. package/dist/src/openclaw-plugin-helpers.js +356 -81
  148. package/dist/src/openclaw-plugin-helpers.js.map +1 -1
  149. package/dist/src/openclaw-plugin-schemas.d.ts +358 -0
  150. package/dist/src/openclaw-plugin-schemas.js +366 -0
  151. package/dist/src/openclaw-plugin-schemas.js.map +1 -0
  152. package/dist/src/openclaw-plugin-supervisor.d.ts +6 -0
  153. package/dist/src/openclaw-plugin-supervisor.js +123 -0
  154. package/dist/src/openclaw-plugin-supervisor.js.map +1 -0
  155. package/dist/src/openclaw-plugin.js +7 -2212
  156. package/dist/src/openclaw-plugin.js.map +1 -1
  157. package/dist/src/openclaw-private-authority-offers.d.ts +22 -0
  158. package/dist/src/openclaw-private-authority-offers.js +177 -0
  159. package/dist/src/openclaw-private-authority-offers.js.map +1 -0
  160. package/dist/src/protocol.d.ts +5 -0
  161. package/dist/src/protocol.js +59 -3
  162. package/dist/src/protocol.js.map +1 -1
  163. package/dist/src/session-store.d.ts +1 -0
  164. package/dist/src/session-store.js +84 -106
  165. package/dist/src/session-store.js.map +1 -1
  166. package/dist/src/store.d.ts +1 -0
  167. package/dist/src/store.js +5 -2
  168. package/dist/src/store.js.map +1 -1
  169. package/dist/src/terminal-acceptance-application-service.d.ts +65 -0
  170. package/dist/src/terminal-acceptance-application-service.js +63 -0
  171. package/dist/src/terminal-acceptance-application-service.js.map +1 -0
  172. package/dist/src/terminal-acceptance-cli-adapter.d.ts +210 -0
  173. package/dist/src/terminal-acceptance-cli-adapter.js +957 -0
  174. package/dist/src/terminal-acceptance-cli-adapter.js.map +1 -0
  175. package/dist/src/terminal-action-projection.d.ts +309 -0
  176. package/dist/src/terminal-action-projection.js +376 -0
  177. package/dist/src/terminal-action-projection.js.map +1 -0
  178. package/dist/src/terminal-agent-bridge.d.ts +3 -0
  179. package/dist/src/terminal-agent-bridge.js +29 -8
  180. package/dist/src/terminal-agent-bridge.js.map +1 -1
  181. package/dist/src/terminal-authority-policy.d.ts +141 -0
  182. package/dist/src/terminal-authority-policy.js +367 -0
  183. package/dist/src/terminal-authority-policy.js.map +1 -0
  184. package/dist/src/terminal-binding-authority.d.ts +118 -0
  185. package/dist/src/terminal-binding-authority.js +245 -0
  186. package/dist/src/terminal-binding-authority.js.map +1 -0
  187. package/dist/src/terminal-binding-reconciliation-service.d.ts +75 -0
  188. package/dist/src/terminal-binding-reconciliation-service.js +73 -0
  189. package/dist/src/terminal-binding-reconciliation-service.js.map +1 -0
  190. package/dist/src/terminal-command-cli-adapter.d.ts +380 -0
  191. package/dist/src/terminal-command-cli-adapter.js +3288 -0
  192. package/dist/src/terminal-command-cli-adapter.js.map +1 -0
  193. package/dist/src/terminal-control-ref.d.ts +4 -0
  194. package/dist/src/terminal-control-ref.js +11 -8
  195. package/dist/src/terminal-control-ref.js.map +1 -1
  196. package/dist/src/terminal-delegate-cli-adapter.d.ts +41 -0
  197. package/dist/src/terminal-delegate-cli-adapter.js +242 -0
  198. package/dist/src/terminal-delegate-cli-adapter.js.map +1 -0
  199. package/dist/src/terminal-dispatch-abort.d.ts +22 -0
  200. package/dist/src/terminal-dispatch-abort.js +30 -0
  201. package/dist/src/terminal-dispatch-abort.js.map +1 -0
  202. package/dist/src/terminal-dispatch-application.d.ts +115 -0
  203. package/dist/src/terminal-dispatch-application.js +478 -0
  204. package/dist/src/terminal-dispatch-application.js.map +1 -0
  205. package/dist/src/terminal-dispatch-capability.d.ts +63 -0
  206. package/dist/src/terminal-dispatch-capability.js +133 -0
  207. package/dist/src/terminal-dispatch-capability.js.map +1 -0
  208. package/dist/src/terminal-dispatch-completion-cli-adapter.d.ts +22 -0
  209. package/dist/src/terminal-dispatch-completion-cli-adapter.js +96 -0
  210. package/dist/src/terminal-dispatch-completion-cli-adapter.js.map +1 -0
  211. package/dist/src/terminal-dispatch-composition.d.ts +79 -0
  212. package/dist/src/terminal-dispatch-composition.js +2 -0
  213. package/dist/src/terminal-dispatch-composition.js.map +1 -0
  214. package/dist/src/terminal-dispatch-execution.d.ts +290 -0
  215. package/dist/src/terminal-dispatch-execution.js +916 -0
  216. package/dist/src/terminal-dispatch-execution.js.map +1 -0
  217. package/dist/src/terminal-dispatch-ledger-codec.d.ts +110 -0
  218. package/dist/src/terminal-dispatch-ledger-codec.js +399 -0
  219. package/dist/src/terminal-dispatch-ledger-codec.js.map +1 -0
  220. package/dist/src/terminal-dispatch-policy.d.ts +93 -0
  221. package/dist/src/terminal-dispatch-policy.js +122 -0
  222. package/dist/src/terminal-dispatch-policy.js.map +1 -0
  223. package/dist/src/terminal-dispatch-presenter.d.ts +65 -0
  224. package/dist/src/terminal-dispatch-presenter.js +258 -0
  225. package/dist/src/terminal-dispatch-presenter.js.map +1 -0
  226. package/dist/src/terminal-dispatch-receipt.d.ts +79 -0
  227. package/dist/src/terminal-dispatch-receipt.js +314 -0
  228. package/dist/src/terminal-dispatch-receipt.js.map +1 -0
  229. package/dist/src/terminal-dispatch-recovery-cli-adapter.d.ts +132 -0
  230. package/dist/src/terminal-dispatch-recovery-cli-adapter.js +1330 -0
  231. package/dist/src/terminal-dispatch-recovery-cli-adapter.js.map +1 -0
  232. package/dist/src/terminal-dispatch-recovery-service.d.ts +271 -0
  233. package/dist/src/terminal-dispatch-recovery-service.js +374 -0
  234. package/dist/src/terminal-dispatch-recovery-service.js.map +1 -0
  235. package/dist/src/terminal-dispatch-repository-cli-adapter.d.ts +35 -0
  236. package/dist/src/terminal-dispatch-repository-cli-adapter.js +483 -0
  237. package/dist/src/terminal-dispatch-repository-cli-adapter.js.map +1 -0
  238. package/dist/src/terminal-handoff-application-service.d.ts +7 -0
  239. package/dist/src/terminal-handoff-application-service.js +18 -0
  240. package/dist/src/terminal-handoff-application-service.js.map +1 -0
  241. package/dist/src/terminal-handoff-cli-adapter.d.ts +229 -0
  242. package/dist/src/terminal-handoff-cli-adapter.js +1389 -0
  243. package/dist/src/terminal-handoff-cli-adapter.js.map +1 -0
  244. package/dist/src/terminal-handoff-facts.d.ts +12 -0
  245. package/dist/src/terminal-handoff-facts.js +16 -0
  246. package/dist/src/terminal-handoff-facts.js.map +1 -0
  247. package/dist/src/terminal-identity-authority-cli-adapter.d.ts +318 -0
  248. package/dist/src/terminal-identity-authority-cli-adapter.js +1072 -0
  249. package/dist/src/terminal-identity-authority-cli-adapter.js.map +1 -0
  250. package/dist/src/terminal-identity-authority-service.d.ts +48 -0
  251. package/dist/src/terminal-identity-authority-service.js +45 -0
  252. package/dist/src/terminal-identity-authority-service.js.map +1 -0
  253. package/dist/src/terminal-list-cli-adapter.d.ts +274 -0
  254. package/dist/src/terminal-list-cli-adapter.js +2444 -0
  255. package/dist/src/terminal-list-cli-adapter.js.map +1 -0
  256. package/dist/src/terminal-list-renderer.d.ts +34 -0
  257. package/dist/src/terminal-list-renderer.js +643 -0
  258. package/dist/src/terminal-list-renderer.js.map +1 -0
  259. package/dist/src/terminal-maintenance-cli-adapter.d.ts +102 -0
  260. package/dist/src/terminal-maintenance-cli-adapter.js +1059 -0
  261. package/dist/src/terminal-maintenance-cli-adapter.js.map +1 -0
  262. package/dist/src/terminal-monitor-application-service.d.ts +275 -0
  263. package/dist/src/terminal-monitor-application-service.js +982 -0
  264. package/dist/src/terminal-monitor-application-service.js.map +1 -0
  265. package/dist/src/terminal-monitor-cli-adapter.d.ts +130 -0
  266. package/dist/src/terminal-monitor-cli-adapter.js +442 -0
  267. package/dist/src/terminal-monitor-cli-adapter.js.map +1 -0
  268. package/dist/src/terminal-monitor-decision-policy.d.ts +98 -0
  269. package/dist/src/terminal-monitor-decision-policy.js +246 -0
  270. package/dist/src/terminal-monitor-decision-policy.js.map +1 -0
  271. package/dist/src/terminal-monitor-launch-plan.d.ts +45 -0
  272. package/dist/src/terminal-monitor-launch-plan.js +94 -0
  273. package/dist/src/terminal-monitor-launch-plan.js.map +1 -0
  274. package/dist/src/terminal-monitor-ownership-policy.d.ts +31 -0
  275. package/dist/src/terminal-monitor-ownership-policy.js +64 -0
  276. package/dist/src/terminal-monitor-ownership-policy.js.map +1 -0
  277. package/dist/src/terminal-monitor-poll-policy.d.ts +48 -0
  278. package/dist/src/terminal-monitor-poll-policy.js +67 -0
  279. package/dist/src/terminal-monitor-poll-policy.js.map +1 -0
  280. package/dist/src/terminal-monitor-reconciliation-eligibility.d.ts +53 -0
  281. package/dist/src/terminal-monitor-reconciliation-eligibility.js +114 -0
  282. package/dist/src/terminal-monitor-reconciliation-eligibility.js.map +1 -0
  283. package/dist/src/terminal-monitor-state-cli-adapter.d.ts +106 -0
  284. package/dist/src/terminal-monitor-state-cli-adapter.js +1492 -0
  285. package/dist/src/terminal-monitor-state-cli-adapter.js.map +1 -0
  286. package/dist/src/terminal-monitor-state-reconciliation-service.d.ts +87 -0
  287. package/dist/src/terminal-monitor-state-reconciliation-service.js +106 -0
  288. package/dist/src/terminal-monitor-state-reconciliation-service.js.map +1 -0
  289. package/dist/src/terminal-monitor-supervision-cli-adapter.d.ts +122 -0
  290. package/dist/src/terminal-monitor-supervision-cli-adapter.js +685 -0
  291. package/dist/src/terminal-monitor-supervision-cli-adapter.js.map +1 -0
  292. package/dist/src/terminal-process-facts.d.ts +2 -0
  293. package/dist/src/terminal-process-facts.js +19 -0
  294. package/dist/src/terminal-process-facts.js.map +1 -0
  295. package/dist/src/terminal-process-source.d.ts +6 -4
  296. package/dist/src/terminal-process-source.js +25 -20
  297. package/dist/src/terminal-process-source.js.map +1 -1
  298. package/dist/src/terminal-runtime-cli-adapter.d.ts +80 -0
  299. package/dist/src/terminal-runtime-cli-adapter.js +488 -0
  300. package/dist/src/terminal-runtime-cli-adapter.js.map +1 -0
  301. package/dist/src/terminal-scoped-approval-authority.d.ts +62 -0
  302. package/dist/src/terminal-scoped-approval-authority.js +281 -0
  303. package/dist/src/terminal-scoped-approval-authority.js.map +1 -0
  304. package/dist/src/terminal-selector-projection-service.d.ts +26 -0
  305. package/dist/src/terminal-selector-projection-service.js +81 -0
  306. package/dist/src/terminal-selector-projection-service.js.map +1 -0
  307. package/dist/src/terminal-status-cli-adapter.d.ts +126 -0
  308. package/dist/src/terminal-status-cli-adapter.js +577 -0
  309. package/dist/src/terminal-status-cli-adapter.js.map +1 -0
  310. package/dist/src/terminal-status-facts.d.ts +56 -0
  311. package/dist/src/terminal-status-facts.js +199 -0
  312. package/dist/src/terminal-status-facts.js.map +1 -0
  313. package/dist/src/terminal-submission-acceptance.d.ts +62 -145
  314. package/dist/src/terminal-submission-acceptance.js +555 -222
  315. package/dist/src/terminal-submission-acceptance.js.map +1 -1
  316. package/dist/src/terminal-submission-facts.d.ts +123 -0
  317. package/dist/src/terminal-submission-facts.js +205 -0
  318. package/dist/src/terminal-submission-facts.js.map +1 -0
  319. package/dist/src/terminal-turn-binding-authority-cli-adapter.d.ts +14 -0
  320. package/dist/src/terminal-turn-binding-authority-cli-adapter.js +90 -0
  321. package/dist/src/terminal-turn-binding-authority-cli-adapter.js.map +1 -0
  322. package/dist/src/terminal-watch-callback-cli-adapter.d.ts +20 -0
  323. package/dist/src/terminal-watch-callback-cli-adapter.js +55 -0
  324. package/dist/src/terminal-watch-callback-cli-adapter.js.map +1 -0
  325. package/dist/src/terminal-watch-cli-adapter.d.ts +64 -0
  326. package/dist/src/terminal-watch-cli-adapter.js +508 -0
  327. package/dist/src/terminal-watch-cli-adapter.js.map +1 -0
  328. package/dist/src/terminal-watch-service.d.ts +97 -0
  329. package/dist/src/terminal-watch-service.js +714 -0
  330. package/dist/src/terminal-watch-service.js.map +1 -0
  331. package/dist/src/terminal-watch-store.d.ts +149 -0
  332. package/dist/src/terminal-watch-store.js +861 -0
  333. package/dist/src/terminal-watch-store.js.map +1 -0
  334. package/dist/src/value-guards.d.ts +4 -0
  335. package/dist/src/value-guards.js +12 -0
  336. package/dist/src/value-guards.js.map +1 -0
  337. package/dist/src/verified-dead-agent-policy.d.ts +192 -0
  338. package/dist/src/verified-dead-agent-policy.js +262 -0
  339. package/dist/src/verified-dead-agent-policy.js.map +1 -0
  340. package/docs/quickstart-herdr.md +8 -0
  341. package/docs/quickstart-tmux.md +33 -6
  342. package/openclaw.plugin.json +11 -3
  343. package/package.json +3 -1
  344. package/templates/openclaw-skills/agent-knock-knock/SKILL.md +58 -40
@@ -4,7 +4,8 @@ import os from "node:os";
4
4
  import path from "node:path";
5
5
  import { claudeLifecycleBehaviorProfile, claudeLifecycleSourceVersionSupported, DEFAULT_CLAUDE_LIFECYCLE_VERSION, supportedClaudeLifecycleVersions } from "./claude-lifecycle-compatibility.js";
6
6
  import { redactString } from "./runtime-log.js";
7
- import { validateTerminalSubmissionAcceptanceEvidence } from "./terminal-submission-acceptance.js";
7
+ import { isRecord } from "./value-guards.js";
8
+ import { validateTerminalSubmissionAcceptanceEvidence } from "./terminal-submission-facts.js";
8
9
  const CLAUDE_TRANSCRIPT_ANCHOR_VERSION = 1;
9
10
  const CLAUDE_TRANSCRIPT_MAX_TURN_BYTES = 64 * 1024 * 1024;
10
11
  const CLAUDE_SESSION_ID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/iu;
@@ -429,6 +430,770 @@ export function captureClaudeTranscriptAnchor(options) {
429
430
  fs.closeSync(located.fd);
430
431
  }
431
432
  }
433
+ /** Capture the latest exact, unfinished root prompt in a live Claude process. */
434
+ export function captureClaudeHumanStartedActiveTaskAnchor(options) {
435
+ const sessionId = nonEmptyString(options.sessionId);
436
+ const cwd = nonEmptyString(options.cwd);
437
+ const pid = positiveInteger(options.pid);
438
+ if (!sessionId || !cwd || pid === undefined || !CLAUDE_SESSION_ID_PATTERN.test(sessionId)) {
439
+ return undefined;
440
+ }
441
+ const agent = exactInteractiveAgent(options.agentRows, pid);
442
+ const agentStartedAtMs = positiveInteger(agent?.startedAt);
443
+ if (!agent ||
444
+ agentStartedAtMs === undefined ||
445
+ agent.sessionId !== sessionId ||
446
+ normalizePath(agent.cwd) !== normalizePath(cwd) ||
447
+ !isActiveClaudeAgentState(agent)) {
448
+ return undefined;
449
+ }
450
+ const projectsRoot = projectsRootPath(path.resolve(options.claudeHome ?? defaultClaudeHome()));
451
+ if (!isRealDirectory(projectsRoot)) {
452
+ return undefined;
453
+ }
454
+ const opened = locateTranscript(projectsRoot, sessionId);
455
+ if (!opened) {
456
+ return undefined;
457
+ }
458
+ try {
459
+ const before = opened.stat;
460
+ const maxBytes = positiveClaudeByteLimit(options.maxTurnBytes);
461
+ if (before.size === 0) {
462
+ return undefined;
463
+ }
464
+ if (!fileEndsWithNewline(opened.fd, before.size)) {
465
+ throw new Error("Claude active-task transcript has an incomplete JSONL tail; retry");
466
+ }
467
+ const recordEntries = readBoundedCompleteJsonlTail(opened.fd, before.size, maxBytes);
468
+ const records = recordEntries.map((entry) => entry.record);
469
+ const after = fs.fstatSync(opened.fd);
470
+ if (!sameStableTranscriptFile(before, after)) {
471
+ throw new Error("Claude active-task transcript changed while it was captured; retry");
472
+ }
473
+ const promptEntry = latestClaudeRootHumanPromptEntry(recordEntries);
474
+ if (!promptEntry) {
475
+ if (before.size > maxBytes) {
476
+ throw new Error("Claude active task exceeded the bounded local read limit");
477
+ }
478
+ return undefined;
479
+ }
480
+ const prompt = promptEntry.record;
481
+ assertSupportedRecord(prompt, sessionId, cwd);
482
+ const promptUuid = uuidValue(prompt.uuid);
483
+ const promptText = userPromptText(prompt);
484
+ const requestHash = exactRequestFingerprint(promptText);
485
+ const claudeVersion = nonEmptyString(prompt.version);
486
+ if (!promptUuid || !promptText || !requestHash || !claudeVersion) {
487
+ throw new Error("Claude active root prompt has no exact supported identity");
488
+ }
489
+ const device = String(before.dev);
490
+ const inode = String(before.ino);
491
+ const fileId = transcriptFileId(sessionId, `${device}:${inode}`);
492
+ const transcriptAnchor = {
493
+ schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
494
+ session_id: sessionId,
495
+ cwd: path.resolve(cwd),
496
+ pid,
497
+ agent_started_at_ms: agentStartedAtMs,
498
+ captured_at: (options.now ?? new Date()).toISOString(),
499
+ relative_path: opened.relativePath,
500
+ offset_bytes: 0,
501
+ file_existed: true,
502
+ device,
503
+ inode
504
+ };
505
+ const snapshot = {
506
+ anchor: transcriptAnchor,
507
+ sessionId,
508
+ cwd,
509
+ expectedRequestHash: requestHash,
510
+ expectedPromptUuid: promptUuid,
511
+ records,
512
+ transcriptFileId: fileId,
513
+ observedEndOffsetBytes: before.size
514
+ };
515
+ if (completionFromRecords(snapshot, {
516
+ requireVerifiableCompletionSignal: false
517
+ })) {
518
+ return undefined;
519
+ }
520
+ if (!pendingApprovalTurn(snapshot)) {
521
+ throw new Error("Claude active root prompt has no unique unfinished foreground chain");
522
+ }
523
+ const base = {
524
+ schema: "agent-knock-knock/claude-human-started-active-task-anchor",
525
+ version: 1,
526
+ session_id: sessionId,
527
+ cwd: path.resolve(cwd),
528
+ pid,
529
+ agent_started_at_ms: agentStartedAtMs,
530
+ captured_at: transcriptAnchor.captured_at,
531
+ relative_path: opened.relativePath,
532
+ device,
533
+ inode,
534
+ prompt_uuid: promptUuid,
535
+ request_hash: requestHash,
536
+ claude_version: claudeVersion,
537
+ transcript_file_id: fileId,
538
+ turn_start_offset_bytes: promptEntry.offsetBytes,
539
+ observed_end_offset_bytes: before.size
540
+ };
541
+ return {
542
+ ...base,
543
+ anchor_fingerprint: sha256Hex(JSON.stringify(base))
544
+ };
545
+ }
546
+ finally {
547
+ fs.closeSync(opened.fd);
548
+ }
549
+ }
550
+ /** Observe only the exact root prompt named by a human-started task anchor. */
551
+ export function observeClaudeHumanStartedActiveTask(options) {
552
+ try {
553
+ const anchor = validateClaudeHumanStartedActiveTaskAnchor(options.anchor);
554
+ const checkpoint = claudeActiveTaskObservationCheckpoint(anchor, options);
555
+ const resumeOffsetBytes = checkpoint.safe_resume_offset_bytes;
556
+ const projectsRoot = projectsRootPath(path.resolve(options.claudeHome ?? defaultClaudeHome()));
557
+ if (!isRealDirectory(projectsRoot)) {
558
+ return claudeActiveTaskUnavailable("Claude transcript projects directory is unavailable");
559
+ }
560
+ let opened;
561
+ try {
562
+ opened = openAnchoredTranscript(projectsRoot, claudeTranscriptAnchorForHumanStartedTask(anchor));
563
+ }
564
+ catch (error) {
565
+ if (isRetryableClaudeProviderIoError(error) ||
566
+ (error instanceof Error &&
567
+ error.message === "Claude transcript disappeared after the managed send")) {
568
+ return claudeActiveTaskUnavailable(error instanceof Error ? error.message : String(error));
569
+ }
570
+ throw error;
571
+ }
572
+ if (!opened) {
573
+ return claudeActiveTaskUnavailable("the anchored Claude transcript is unavailable");
574
+ }
575
+ try {
576
+ const before = opened.stat;
577
+ if (String(before.dev) !== anchor.device ||
578
+ String(before.ino) !== anchor.inode) {
579
+ throw new Error("Claude active-task transcript identity changed after capture");
580
+ }
581
+ if (before.size < anchor.observed_end_offset_bytes ||
582
+ before.size <= anchor.turn_start_offset_bytes) {
583
+ throw new Error("Claude active-task transcript was truncated after capture");
584
+ }
585
+ if (before.size < resumeOffsetBytes) {
586
+ throw new Error("Claude active-task transcript was truncated after observation");
587
+ }
588
+ assertClaudeActiveTaskResumeBoundary(opened.fd, resumeOffsetBytes);
589
+ const maxTurnBytes = positiveClaudeByteLimit(options.maxTurnBytes);
590
+ const availableBytes = before.size - resumeOffsetBytes;
591
+ const bytesToRead = Math.min(availableBytes, maxTurnBytes);
592
+ if (bytesToRead === 0) {
593
+ assertObservableClaudeActiveTaskAgent(options.agentRows, anchor);
594
+ return {
595
+ status: "pending",
596
+ observedEndOffsetBytes: before.size,
597
+ safeResumeOffsetBytes: resumeOffsetBytes,
598
+ checkpoint
599
+ };
600
+ }
601
+ const suffixBuffer = readExactTranscriptBytes(opened.fd, resumeOffsetBytes, bytesToRead);
602
+ const completeLength = completeTranscriptJsonlPrefixLength(suffixBuffer);
603
+ if (completeLength === 0 && availableBytes > maxTurnBytes) {
604
+ throw new Error("Claude active-task JSONL record exceeded the bounded local read limit");
605
+ }
606
+ const safeResumeOffsetBytes = resumeOffsetBytes + completeLength;
607
+ const suffixRecords = readCompleteJsonlRecordEntries(opened.fd, resumeOffsetBytes, completeLength, { preReadBuffer: suffixBuffer.subarray(0, completeLength) }).map((entry) => entry.record);
608
+ const after = fs.fstatSync(opened.fd);
609
+ if (!sameStableTranscriptFile(before, after)) {
610
+ assertObservableClaudeActiveTaskAgent(options.agentRows, anchor);
611
+ return {
612
+ status: "pending",
613
+ observedEndOffsetBytes: after.size,
614
+ safeResumeOffsetBytes: resumeOffsetBytes,
615
+ checkpoint
616
+ };
617
+ }
618
+ const advanced = advanceClaudeHumanStartedActiveTaskCheckpoint(anchor, checkpoint, suffixRecords, safeResumeOffsetBytes);
619
+ if (advanced.completion) {
620
+ return { status: "completed", completion: advanced.completion };
621
+ }
622
+ assertObservableClaudeActiveTaskAgent(options.agentRows, anchor);
623
+ return {
624
+ status: "pending",
625
+ observedEndOffsetBytes: before.size,
626
+ safeResumeOffsetBytes,
627
+ checkpoint: advanced.checkpoint
628
+ };
629
+ }
630
+ finally {
631
+ fs.closeSync(opened.fd);
632
+ }
633
+ }
634
+ catch (error) {
635
+ if (isRetryableClaudeProviderIoError(error)) {
636
+ return claudeActiveTaskUnavailable(error instanceof Error ? error.message : String(error));
637
+ }
638
+ return {
639
+ status: "invalidated",
640
+ reason: error instanceof Error ? error.message : String(error)
641
+ };
642
+ }
643
+ }
644
+ export function validateClaudeHumanStartedActiveTaskAnchor(value) {
645
+ if (!isRecord(value) ||
646
+ value.schema !==
647
+ "agent-knock-knock/claude-human-started-active-task-anchor" ||
648
+ value.version !== 1) {
649
+ throw new Error("Claude human-started active-task anchor is invalid");
650
+ }
651
+ const allowedKeys = new Set([
652
+ "schema", "version", "session_id", "cwd", "pid", "agent_started_at_ms",
653
+ "captured_at", "relative_path", "device", "inode", "prompt_uuid",
654
+ "request_hash", "claude_version", "transcript_file_id",
655
+ "turn_start_offset_bytes", "observed_end_offset_bytes", "anchor_fingerprint"
656
+ ]);
657
+ if (Object.keys(value).some((key) => !allowedKeys.has(key))) {
658
+ throw new Error("Claude human-started active-task anchor has unsupported fields");
659
+ }
660
+ const sessionId = uuidValue(value.session_id);
661
+ const promptUuid = uuidValue(value.prompt_uuid);
662
+ const cwd = nonEmptyString(value.cwd);
663
+ const pid = positiveInteger(value.pid);
664
+ const startedAt = positiveInteger(value.agent_started_at_ms);
665
+ const relativePath = nonEmptyString(value.relative_path);
666
+ const device = nonEmptyString(value.device);
667
+ const inode = nonEmptyString(value.inode);
668
+ const turnStartOffset = nonNegativeInteger(value.turn_start_offset_bytes);
669
+ const observedEndOffset = positiveInteger(value.observed_end_offset_bytes);
670
+ const capturedAt = typeof value.captured_at === "string"
671
+ ? value.captured_at
672
+ : undefined;
673
+ if (!sessionId ||
674
+ sessionId !== value.session_id ||
675
+ !promptUuid ||
676
+ promptUuid !== value.prompt_uuid ||
677
+ !cwd ||
678
+ !path.isAbsolute(cwd) ||
679
+ path.resolve(cwd) !== cwd ||
680
+ typeof value.pid !== "number" ||
681
+ pid === undefined ||
682
+ typeof value.agent_started_at_ms !== "number" ||
683
+ startedAt === undefined ||
684
+ !capturedAt ||
685
+ validTimestampMs(capturedAt) === undefined ||
686
+ new Date(capturedAt).toISOString() !== capturedAt ||
687
+ !relativePath ||
688
+ relativePath.includes("\0") ||
689
+ path.posix.isAbsolute(relativePath) ||
690
+ path.win32.isAbsolute(relativePath) ||
691
+ relativePath.split(/[\\/]/u).length !== 2 ||
692
+ relativePath.split(/[\\/]/u).some((segment) => !segment || segment === "." || segment === "..") ||
693
+ path.basename(relativePath) !== `${sessionId}.jsonl` ||
694
+ typeof value.turn_start_offset_bytes !== "number" ||
695
+ turnStartOffset === undefined ||
696
+ typeof value.observed_end_offset_bytes !== "number" ||
697
+ observedEndOffset === undefined ||
698
+ turnStartOffset >= observedEndOffset ||
699
+ !decimalFileIdentity(device) ||
700
+ !decimalFileIdentity(inode) ||
701
+ !/^[0-9a-f]{64}$/u.test(String(value.request_hash)) ||
702
+ !isCompatibleClaudeVersion(value.claude_version) ||
703
+ !/^[0-9a-f]{24}$/u.test(String(value.transcript_file_id)) ||
704
+ !/^[0-9a-f]{64}$/u.test(String(value.anchor_fingerprint))) {
705
+ throw new Error("Claude human-started active-task anchor identity is invalid");
706
+ }
707
+ const { anchor_fingerprint: _anchorFingerprint, ...base } = value;
708
+ if (sha256Hex(JSON.stringify(base)) !== value.anchor_fingerprint) {
709
+ throw new Error("Claude human-started active-task anchor fingerprint does not match");
710
+ }
711
+ const expectedFileId = transcriptFileId(sessionId, `${device}:${inode}`);
712
+ if (expectedFileId !== value.transcript_file_id) {
713
+ throw new Error("Claude human-started active-task transcript identity is invalid");
714
+ }
715
+ return value;
716
+ }
717
+ function claudeTranscriptAnchorForHumanStartedTask(anchor) {
718
+ return {
719
+ schema_version: CLAUDE_TRANSCRIPT_ANCHOR_VERSION,
720
+ session_id: anchor.session_id,
721
+ cwd: anchor.cwd,
722
+ pid: anchor.pid,
723
+ agent_started_at_ms: anchor.agent_started_at_ms,
724
+ captured_at: anchor.captured_at,
725
+ relative_path: anchor.relative_path,
726
+ offset_bytes: 0,
727
+ file_existed: true,
728
+ device: anchor.device,
729
+ inode: anchor.inode
730
+ };
731
+ }
732
+ function latestClaudeRootHumanPromptEntry(entries) {
733
+ return [...entries].reverse().find((entry) => isClaudeRootHumanPrompt(entry.record));
734
+ }
735
+ function isClaudeRootHumanPrompt(record) {
736
+ return record.type === "user" &&
737
+ isRecord(record.message) &&
738
+ record.message.role === "user" &&
739
+ record.isSidechain !== true &&
740
+ nonEmptyString(record.agentId) === undefined &&
741
+ userPromptText(record) !== undefined;
742
+ }
743
+ function isActiveClaudeAgentState(agent) {
744
+ return agent.status === "working" ||
745
+ agent.status === "busy" ||
746
+ (agent.status === "waiting" && agent.waitingFor === "dialog open");
747
+ }
748
+ function isObservableClaudeAgentState(agent) {
749
+ return agent.status === "idle" || isActiveClaudeAgentState(agent);
750
+ }
751
+ function assertObservableClaudeActiveTaskAgent(rows, anchor) {
752
+ const agent = exactInteractiveAgent(rows, anchor.pid);
753
+ if (!agent ||
754
+ agent.startedAt !== anchor.agent_started_at_ms ||
755
+ agent.sessionId !== anchor.session_id ||
756
+ normalizePath(agent.cwd) !== normalizePath(anchor.cwd) ||
757
+ !isObservableClaudeAgentState(agent)) {
758
+ throw new Error("Claude process identity changed after active-task capture");
759
+ }
760
+ }
761
+ function positiveClaudeByteLimit(value) {
762
+ const result = value ?? CLAUDE_TRANSCRIPT_MAX_TURN_BYTES;
763
+ if (!Number.isSafeInteger(result) || result <= 0) {
764
+ throw new Error("Claude active-task byte limit is invalid");
765
+ }
766
+ return result;
767
+ }
768
+ const CLAUDE_ACTIVE_TASK_CHECKPOINT_SCHEMA = "agent-knock-knock/claude-human-started-active-task-checkpoint";
769
+ const CLAUDE_ACTIVE_TASK_MAX_UNRESOLVED_TOOLS = 64;
770
+ const CLAUDE_ACTIVE_TASK_MAX_OPAQUE_ID_LENGTH = 256;
771
+ export function initialClaudeHumanStartedActiveTaskCheckpoint(value) {
772
+ const anchor = validateClaudeHumanStartedActiveTaskAnchor(value);
773
+ return signedClaudeActiveTaskCheckpoint({
774
+ schema: CLAUDE_ACTIVE_TASK_CHECKPOINT_SCHEMA,
775
+ version: 1,
776
+ anchor_fingerprint: anchor.anchor_fingerprint,
777
+ safe_resume_offset_bytes: anchor.turn_start_offset_bytes,
778
+ last_record_uuid: anchor.prompt_uuid,
779
+ record_count: 0,
780
+ chain_fingerprint: sha256Hex(`claude-active-task-checkpoint\0${anchor.anchor_fingerprint}`),
781
+ unresolved_tool_uses: []
782
+ });
783
+ }
784
+ export function validateClaudeHumanStartedActiveTaskCheckpoint(value, anchorValue) {
785
+ const anchor = validateClaudeHumanStartedActiveTaskAnchor(anchorValue);
786
+ if (!isRecord(value)) {
787
+ throw new Error("Claude active-task checkpoint is invalid");
788
+ }
789
+ const allowedKeys = new Set([
790
+ "schema", "version", "anchor_fingerprint", "safe_resume_offset_bytes",
791
+ "last_record_uuid", "record_count", "chain_fingerprint",
792
+ "unresolved_tool_uses", "assistant_message_id", "assistant_text",
793
+ "end_turn_message_id", "end_turn_assistant_uuid",
794
+ "checkpoint_fingerprint"
795
+ ]);
796
+ if (Object.keys(value).some((key) => !allowedKeys.has(key))) {
797
+ throw new Error("Claude active-task checkpoint has unsupported fields");
798
+ }
799
+ const safeOffset = nonNegativeInteger(value.safe_resume_offset_bytes);
800
+ const recordCount = nonNegativeInteger(value.record_count);
801
+ const lastRecordUuid = uuidValue(value.last_record_uuid);
802
+ const assistantMessageId = value.assistant_message_id === undefined
803
+ ? undefined
804
+ : uuidValue(value.assistant_message_id);
805
+ const endTurnMessageId = value.end_turn_message_id === undefined
806
+ ? undefined
807
+ : uuidValue(value.end_turn_message_id);
808
+ const endTurnAssistantUuid = value.end_turn_assistant_uuid === undefined
809
+ ? undefined
810
+ : uuidValue(value.end_turn_assistant_uuid);
811
+ const assistantText = value.assistant_text;
812
+ if (value.schema !== CLAUDE_ACTIVE_TASK_CHECKPOINT_SCHEMA ||
813
+ value.version !== 1 ||
814
+ value.anchor_fingerprint !== anchor.anchor_fingerprint ||
815
+ typeof value.safe_resume_offset_bytes !== "number" ||
816
+ safeOffset === undefined ||
817
+ safeOffset < anchor.turn_start_offset_bytes ||
818
+ typeof value.record_count !== "number" ||
819
+ recordCount === undefined ||
820
+ !lastRecordUuid ||
821
+ lastRecordUuid !== value.last_record_uuid ||
822
+ (recordCount === 0 && lastRecordUuid !== anchor.prompt_uuid) ||
823
+ !sha256String(value.chain_fingerprint) ||
824
+ !sha256String(value.checkpoint_fingerprint) ||
825
+ (value.assistant_message_id !== undefined && !assistantMessageId) ||
826
+ (value.end_turn_message_id !== undefined && !endTurnMessageId) ||
827
+ (value.end_turn_assistant_uuid !== undefined && !endTurnAssistantUuid) ||
828
+ (endTurnMessageId === undefined) !== (endTurnAssistantUuid === undefined) ||
829
+ (endTurnMessageId !== undefined &&
830
+ assistantMessageId !== endTurnMessageId) ||
831
+ (assistantText !== undefined &&
832
+ (typeof assistantText !== "string" ||
833
+ !assistantText ||
834
+ assistantText.length > 4000 ||
835
+ boundedRedactedText(assistantText) !== assistantText ||
836
+ assistantMessageId === undefined))) {
837
+ throw new Error("Claude active-task checkpoint identity is invalid");
838
+ }
839
+ if (!Array.isArray(value.unresolved_tool_uses) ||
840
+ value.unresolved_tool_uses.length >
841
+ CLAUDE_ACTIVE_TASK_MAX_UNRESOLVED_TOOLS) {
842
+ throw new Error("Claude active-task checkpoint tool state is invalid");
843
+ }
844
+ const seenToolIds = new Set();
845
+ for (const entry of value.unresolved_tool_uses) {
846
+ if (!isRecord(entry) ||
847
+ Object.keys(entry).some((key) => key !== "tool_use_id" && key !== "owner_uuid") ||
848
+ !checkpointOpaqueId(entry.tool_use_id) ||
849
+ !uuidValue(entry.owner_uuid) ||
850
+ uuidValue(entry.owner_uuid) !== entry.owner_uuid ||
851
+ seenToolIds.has(String(entry.tool_use_id))) {
852
+ throw new Error("Claude active-task checkpoint tool state is invalid");
853
+ }
854
+ seenToolIds.add(String(entry.tool_use_id));
855
+ }
856
+ const candidate = value;
857
+ if (claudeActiveTaskCheckpointFingerprint(candidate) !==
858
+ candidate.checkpoint_fingerprint) {
859
+ throw new Error("Claude active-task checkpoint fingerprint does not match");
860
+ }
861
+ return candidate;
862
+ }
863
+ function claudeActiveTaskObservationCheckpoint(anchor, options) {
864
+ const checkpoint = options.checkpoint === undefined
865
+ ? initialClaudeHumanStartedActiveTaskCheckpoint(anchor)
866
+ : validateClaudeHumanStartedActiveTaskCheckpoint(options.checkpoint, anchor);
867
+ if (options.resumeOffsetBytes !== undefined &&
868
+ (!Number.isSafeInteger(options.resumeOffsetBytes) ||
869
+ options.resumeOffsetBytes !== checkpoint.safe_resume_offset_bytes)) {
870
+ throw new Error("Claude active-task resume offset does not match its continuation checkpoint");
871
+ }
872
+ return checkpoint;
873
+ }
874
+ function signedClaudeActiveTaskCheckpoint(base) {
875
+ const checkpoint = {
876
+ ...base,
877
+ checkpoint_fingerprint: ""
878
+ };
879
+ return {
880
+ ...checkpoint,
881
+ checkpoint_fingerprint: claudeActiveTaskCheckpointFingerprint(checkpoint)
882
+ };
883
+ }
884
+ function claudeActiveTaskCheckpointFingerprint(value) {
885
+ return sha256Hex(JSON.stringify({
886
+ schema: value.schema,
887
+ version: value.version,
888
+ anchor_fingerprint: value.anchor_fingerprint,
889
+ safe_resume_offset_bytes: value.safe_resume_offset_bytes,
890
+ last_record_uuid: value.last_record_uuid,
891
+ record_count: value.record_count,
892
+ chain_fingerprint: value.chain_fingerprint,
893
+ unresolved_tool_uses: value.unresolved_tool_uses,
894
+ ...(value.assistant_message_id === undefined
895
+ ? {}
896
+ : { assistant_message_id: value.assistant_message_id }),
897
+ ...(value.assistant_text === undefined
898
+ ? {}
899
+ : { assistant_text: value.assistant_text }),
900
+ ...(value.end_turn_message_id === undefined
901
+ ? {}
902
+ : { end_turn_message_id: value.end_turn_message_id }),
903
+ ...(value.end_turn_assistant_uuid === undefined
904
+ ? {}
905
+ : { end_turn_assistant_uuid: value.end_turn_assistant_uuid })
906
+ }));
907
+ }
908
+ function sha256String(value) {
909
+ return typeof value === "string" && /^[0-9a-f]{64}$/u.test(value);
910
+ }
911
+ function checkpointOpaqueId(value) {
912
+ return typeof value === "string" &&
913
+ value.length > 0 &&
914
+ value.length <= CLAUDE_ACTIVE_TASK_MAX_OPAQUE_ID_LENGTH &&
915
+ /^[A-Za-z0-9_.:-]+$/u.test(value);
916
+ }
917
+ function advanceClaudeHumanStartedActiveTaskCheckpoint(anchor, checkpoint, records, safeResumeOffsetBytes) {
918
+ let lastRecordUuid = checkpoint.last_record_uuid;
919
+ let recordCount = checkpoint.record_count;
920
+ let chainFingerprint = checkpoint.chain_fingerprint;
921
+ const unresolvedToolUses = new Map(checkpoint.unresolved_tool_uses.map((entry) => [entry.tool_use_id, {
922
+ tool_use_id: entry.tool_use_id,
923
+ owner_uuid: entry.owner_uuid
924
+ }]));
925
+ let assistantMessageId = checkpoint.assistant_message_id;
926
+ let assistantText = checkpoint.assistant_text;
927
+ let endTurnMessageId = checkpoint.end_turn_message_id;
928
+ let endTurnAssistantUuid = checkpoint.end_turn_assistant_uuid;
929
+ let completion;
930
+ let durationSeen = false;
931
+ for (const record of records) {
932
+ if (recordCount === 0) {
933
+ assertClaudeActiveTaskCheckpointPrompt(record, anchor);
934
+ lastRecordUuid = anchor.prompt_uuid;
935
+ ({ recordCount, chainFingerprint } = advanceClaudeCheckpointDigest(recordCount, chainFingerprint, record));
936
+ continue;
937
+ }
938
+ if (isClaudeRootHumanPrompt(record)) {
939
+ if (completion) {
940
+ break;
941
+ }
942
+ throw new Error("a later Claude human prompt appeared before the anchored task completed");
943
+ }
944
+ const recordUuid = claudeCheckpointRecordUuid(record, anchor, lastRecordUuid);
945
+ if (recordUuid) {
946
+ lastRecordUuid = recordUuid;
947
+ }
948
+ if (hasUnresolvedBackgroundWork(record) ||
949
+ record.subtype === "stop_hook_summary") {
950
+ throw new Error("Claude anchored task acquired unsupported background or stop-hook work");
951
+ }
952
+ advanceClaudeCheckpointToolState(record, recordUuid, unresolvedToolUses);
953
+ if (record.type === "assistant") {
954
+ const message = isRecord(record.message) ? record.message : undefined;
955
+ if (message?.role !== "assistant") {
956
+ throw new Error("Claude assistant record has an unsupported message role");
957
+ }
958
+ const rawMessageId = nonEmptyString(message.id);
959
+ const messageId = rawMessageId === undefined
960
+ ? undefined
961
+ : uuidValue(rawMessageId);
962
+ if (rawMessageId !== undefined && !messageId) {
963
+ throw new Error("Claude assistant message has no stable UUID");
964
+ }
965
+ if (messageId && messageId !== assistantMessageId) {
966
+ if (endTurnMessageId !== undefined) {
967
+ throw new Error("Claude assistant message changed after an end-turn signal");
968
+ }
969
+ assistantMessageId = messageId;
970
+ assistantText = undefined;
971
+ }
972
+ const recordText = textFromAssistantRecord(record);
973
+ if (recordText) {
974
+ if (!messageId || messageId !== assistantMessageId) {
975
+ throw new Error("Claude assistant text has no stable message identity");
976
+ }
977
+ assistantText = appendBoundedRedactedClaudeText(assistantText, recordText);
978
+ }
979
+ if (record.isApiErrorMessage === true) {
980
+ if (!recordUuid || validTimestampMs(record.timestamp) === undefined) {
981
+ throw new Error("Claude API-error completion identity is invalid");
982
+ }
983
+ if (unresolvedToolUses.size > 0) {
984
+ throw new Error("Claude API error left unresolved tool use state");
985
+ }
986
+ const error = safeErrorCode(record.error);
987
+ completion = {
988
+ source: "durable",
989
+ outcome: "failure",
990
+ text: assistantText || `Claude Code stopped with ${error}.`,
991
+ timestamp: nonEmptyString(record.timestamp),
992
+ id: recordUuid,
993
+ confidence: "high",
994
+ metadata: {
995
+ match: "claude_transcript_api_error",
996
+ session_id: anchor.session_id,
997
+ prompt_uuid: anchor.prompt_uuid,
998
+ error,
999
+ transcript_schema: "claude_code_jsonl_v2",
1000
+ transcript_file_id: anchor.transcript_file_id
1001
+ }
1002
+ };
1003
+ }
1004
+ else {
1005
+ const stopReason = nonEmptyString(message.stop_reason);
1006
+ if (stopReason === "end_turn") {
1007
+ if (!recordUuid || !messageId) {
1008
+ throw new Error("Claude end-turn signal has no stable identity");
1009
+ }
1010
+ if (endTurnMessageId !== undefined &&
1011
+ endTurnMessageId !== messageId) {
1012
+ throw new Error("Claude active task contains multiple end-turn message identities");
1013
+ }
1014
+ endTurnMessageId = messageId;
1015
+ endTurnAssistantUuid = recordUuid;
1016
+ }
1017
+ else if (stopReason !== undefined && stopReason !== "tool_use") {
1018
+ throw new Error("Claude active task contains an unsupported terminal stop reason");
1019
+ }
1020
+ }
1021
+ }
1022
+ if (record.type === "system" && record.subtype === "turn_duration") {
1023
+ if (durationSeen) {
1024
+ throw new Error("Claude transcript turn contains multiple turn_duration records");
1025
+ }
1026
+ durationSeen = true;
1027
+ if (!recordUuid ||
1028
+ validTimestampMs(record.timestamp) === undefined ||
1029
+ !endTurnMessageId ||
1030
+ !endTurnAssistantUuid ||
1031
+ assistantMessageId !== endTurnMessageId ||
1032
+ !assistantText ||
1033
+ unresolvedToolUses.size > 0) {
1034
+ throw new Error("Claude turn_duration has no complete incremental completion chain");
1035
+ }
1036
+ completion = {
1037
+ source: "durable",
1038
+ outcome: "success",
1039
+ text: assistantText,
1040
+ timestamp: nonEmptyString(record.timestamp),
1041
+ id: recordUuid,
1042
+ confidence: "high",
1043
+ metadata: {
1044
+ match: "claude_transcript_turn_duration",
1045
+ session_id: anchor.session_id,
1046
+ prompt_uuid: anchor.prompt_uuid,
1047
+ assistant_message_id: endTurnMessageId,
1048
+ claude_version: anchor.claude_version,
1049
+ transcript_schema: "claude_code_jsonl_v2",
1050
+ transcript_file_id: anchor.transcript_file_id
1051
+ }
1052
+ };
1053
+ }
1054
+ ({ recordCount, chainFingerprint } = advanceClaudeCheckpointDigest(recordCount, chainFingerprint, record));
1055
+ }
1056
+ const nextCheckpoint = signedClaudeActiveTaskCheckpoint({
1057
+ schema: CLAUDE_ACTIVE_TASK_CHECKPOINT_SCHEMA,
1058
+ version: 1,
1059
+ anchor_fingerprint: anchor.anchor_fingerprint,
1060
+ safe_resume_offset_bytes: safeResumeOffsetBytes,
1061
+ last_record_uuid: lastRecordUuid,
1062
+ record_count: recordCount,
1063
+ chain_fingerprint: chainFingerprint,
1064
+ unresolved_tool_uses: [...unresolvedToolUses.values()],
1065
+ ...(assistantMessageId === undefined
1066
+ ? {}
1067
+ : { assistant_message_id: assistantMessageId }),
1068
+ ...(assistantText === undefined ? {} : { assistant_text: assistantText }),
1069
+ ...(endTurnMessageId === undefined
1070
+ ? {}
1071
+ : { end_turn_message_id: endTurnMessageId }),
1072
+ ...(endTurnAssistantUuid === undefined
1073
+ ? {}
1074
+ : { end_turn_assistant_uuid: endTurnAssistantUuid })
1075
+ });
1076
+ return { checkpoint: nextCheckpoint, ...(completion ? { completion } : {}) };
1077
+ }
1078
+ function assertClaudeActiveTaskCheckpointPrompt(record, anchor) {
1079
+ assertSupportedRecord(record, anchor.session_id, anchor.cwd);
1080
+ const promptText = userPromptText(record);
1081
+ if (!isClaudeRootHumanPrompt(record) ||
1082
+ uuidValue(record.uuid) !== anchor.prompt_uuid ||
1083
+ exactRequestFingerprint(promptText) !== anchor.request_hash ||
1084
+ nonEmptyString(record.version) !== anchor.claude_version) {
1085
+ throw new Error("Claude anchored root prompt identity changed");
1086
+ }
1087
+ }
1088
+ function claudeCheckpointRecordUuid(record, anchor, expectedParentUuid) {
1089
+ assertSupportedRecord(record, anchor.session_id, anchor.cwd);
1090
+ const recordUuid = uuidValue(record.uuid);
1091
+ const requiresIdentity = record.type === "user" ||
1092
+ record.type === "assistant" ||
1093
+ record.type === "system" ||
1094
+ record.type === "attachment" ||
1095
+ hasTurnCompletionSignal(record);
1096
+ if (!recordUuid) {
1097
+ if (requiresIdentity) {
1098
+ throw new Error("Claude active-task record has no stable UUID");
1099
+ }
1100
+ return undefined;
1101
+ }
1102
+ if (nonEmptyString(record.version) !== anchor.claude_version) {
1103
+ throw new Error("Claude transcript turn changed schema versions while it was running");
1104
+ }
1105
+ if (uuidValue(record.parentUuid) !== expectedParentUuid) {
1106
+ throw new Error("Claude active-task record is not the next exact descendant");
1107
+ }
1108
+ return recordUuid;
1109
+ }
1110
+ function advanceClaudeCheckpointToolState(record, recordUuid, unresolved) {
1111
+ const message = isRecord(record.message) ? record.message : undefined;
1112
+ const content = Array.isArray(message?.content) ? message.content : [];
1113
+ for (const block of content) {
1114
+ if (!isRecord(block)) {
1115
+ continue;
1116
+ }
1117
+ if (block.type === "tool_use") {
1118
+ const id = checkpointOpaqueId(block.id) ? block.id : undefined;
1119
+ if (!id || !recordUuid || unresolved.has(id)) {
1120
+ throw new Error("Claude active task contains invalid tool-use identity");
1121
+ }
1122
+ if (unresolved.size >= CLAUDE_ACTIVE_TASK_MAX_UNRESOLVED_TOOLS) {
1123
+ throw new Error("Claude active task has too many unresolved tool uses");
1124
+ }
1125
+ unresolved.set(id, { tool_use_id: id, owner_uuid: recordUuid });
1126
+ }
1127
+ if (block.type === "tool_result") {
1128
+ const id = checkpointOpaqueId(block.tool_use_id)
1129
+ ? block.tool_use_id
1130
+ : undefined;
1131
+ const pending = id ? unresolved.get(id) : undefined;
1132
+ if (!id ||
1133
+ !pending ||
1134
+ uuidValue(record.parentUuid) !== pending.owner_uuid ||
1135
+ uuidValue(record.sourceToolAssistantUUID) !== pending.owner_uuid) {
1136
+ throw new Error("Claude active task contains invalid tool-result identity");
1137
+ }
1138
+ unresolved.delete(id);
1139
+ }
1140
+ }
1141
+ }
1142
+ function advanceClaudeCheckpointDigest(recordCount, chainFingerprint, record) {
1143
+ if (recordCount >= Number.MAX_SAFE_INTEGER) {
1144
+ throw new Error("Claude active-task checkpoint record count overflowed");
1145
+ }
1146
+ return {
1147
+ recordCount: recordCount + 1,
1148
+ chainFingerprint: sha256Hex(`${chainFingerprint}\0${sha256Hex(JSON.stringify(record))}`)
1149
+ };
1150
+ }
1151
+ function appendBoundedRedactedClaudeText(current, value) {
1152
+ const redacted = boundedRedactedText(value);
1153
+ if (!redacted) {
1154
+ return current;
1155
+ }
1156
+ return boundedRedactedText(current ? `${current}\n${redacted}` : redacted);
1157
+ }
1158
+ function assertClaudeActiveTaskResumeBoundary(fd, offset) {
1159
+ if (offset > 0 && byteAt(fd, offset - 1) !== 0x0a) {
1160
+ throw new Error("Claude active-task resume offset is not a JSONL boundary");
1161
+ }
1162
+ }
1163
+ function readExactTranscriptBytes(fd, offset, length) {
1164
+ const buffer = Buffer.allocUnsafe(length);
1165
+ let readTotal = 0;
1166
+ while (readTotal < length) {
1167
+ const bytesRead = fs.readSync(fd, buffer, readTotal, length - readTotal, offset + readTotal);
1168
+ if (bytesRead === 0) {
1169
+ break;
1170
+ }
1171
+ readTotal += bytesRead;
1172
+ }
1173
+ if (readTotal !== length) {
1174
+ throw new Error("Claude transcript changed while it was being read");
1175
+ }
1176
+ return buffer;
1177
+ }
1178
+ function completeTranscriptJsonlPrefixLength(buffer) {
1179
+ if (buffer.length === 0) {
1180
+ return 0;
1181
+ }
1182
+ const newline = buffer.lastIndexOf(0x0a);
1183
+ return newline < 0 ? 0 : newline + 1;
1184
+ }
1185
+ function claudeActiveTaskUnavailable(reason) {
1186
+ return { status: "unavailable", reason, retryable: true };
1187
+ }
1188
+ function isRetryableClaudeProviderIoError(error) {
1189
+ if (!isRecord(error) || typeof error.code !== "string") {
1190
+ return false;
1191
+ }
1192
+ return new Set([
1193
+ "EACCES", "EAGAIN", "EBUSY", "EIO", "EMFILE", "ENFILE", "ENOENT",
1194
+ "EPERM", "ESTALE", "ETIMEDOUT"
1195
+ ]).has(error.code);
1196
+ }
432
1197
  /**
433
1198
  * Detects one completed Claude Code turn from the append-only local transcript.
434
1199
  * The detector intentionally fails closed on identity, schema, rotation, prompt,
@@ -675,6 +1440,10 @@ function readClaudeTranscriptTurnSnapshot(request, options, requiredAgentStatus,
675
1440
  function matchingManagedPrompt(snapshot) {
676
1441
  const promptCandidates = snapshot.records.filter((record) => {
677
1442
  const promptText = userPromptText(record);
1443
+ const exactPromptIdentity = snapshot.expectedPromptUuid
1444
+ ? uuidValue(record.uuid) === snapshot.expectedPromptUuid
1445
+ : snapshot.expectedPromptText !== undefined &&
1446
+ exactPromptText(promptText) === snapshot.expectedPromptText;
678
1447
  return record.type === "user" &&
679
1448
  isRecord(record.message) &&
680
1449
  record.message.role === "user" &&
@@ -684,7 +1453,7 @@ function matchingManagedPrompt(snapshot) {
684
1453
  normalizePath(record.cwd) === normalizePath(snapshot.cwd) &&
685
1454
  validTimestampMs(record.timestamp) !== undefined &&
686
1455
  promptText !== undefined &&
687
- exactPromptText(promptText) === snapshot.expectedPromptText &&
1456
+ exactPromptIdentity &&
688
1457
  exactRequestFingerprint(promptText) === snapshot.expectedRequestHash;
689
1458
  });
690
1459
  if (promptCandidates.length === 0) {
@@ -860,6 +1629,17 @@ function completionFromRecords(snapshot, options = {}) {
860
1629
  };
861
1630
  }
862
1631
  function pendingApprovalFromRecords(snapshot) {
1632
+ const turn = pendingApprovalTurn(snapshot);
1633
+ if (!turn) {
1634
+ return undefined;
1635
+ }
1636
+ const pending = pendingApprovalToolUse(turn.descendants);
1637
+ if (!pending) {
1638
+ return undefined;
1639
+ }
1640
+ return pendingApprovalEvidence(snapshot, turn.promptUuid, turn.lastDescendant, pending);
1641
+ }
1642
+ function pendingApprovalTurn(snapshot) {
863
1643
  const prompt = matchingManagedPrompt(snapshot);
864
1644
  if (!prompt) {
865
1645
  return undefined;
@@ -916,8 +1696,12 @@ function pendingApprovalFromRecords(snapshot) {
916
1696
  hasUnresolvedBackgroundWork(record))) {
917
1697
  return undefined;
918
1698
  }
919
- if (descendants.some((record) => hasTurnCompletionSignal(record) ||
920
- record.subtype === "stop_hook_summary")) {
1699
+ if (descendants.some((record) => record.subtype === "stop_hook_summary")) {
1700
+ return undefined;
1701
+ }
1702
+ const completionSignals = descendants.filter(hasTurnCompletionSignal);
1703
+ if (completionSignals.length > 0 &&
1704
+ !isPendingClaudeTurnDurationAppend(descendants, completionSignals)) {
921
1705
  return undefined;
922
1706
  }
923
1707
  const lastDescendant = descendants.at(-1);
@@ -928,6 +1712,32 @@ function pendingApprovalFromRecords(snapshot) {
928
1712
  if (!linearChain || linearChain.length !== descendants.length) {
929
1713
  return undefined;
930
1714
  }
1715
+ return { promptUuid, descendants, lastDescendant };
1716
+ }
1717
+ function isPendingClaudeTurnDurationAppend(descendants, completionSignals) {
1718
+ if (completionSignals.length === 0 || hasUnresolvedToolUse(descendants)) {
1719
+ return false;
1720
+ }
1721
+ const messageIds = new Set();
1722
+ for (const candidate of completionSignals) {
1723
+ const message = isRecord(candidate.message) ? candidate.message : undefined;
1724
+ const messageId = uuidValue(message?.id);
1725
+ if (candidate.type !== "assistant" ||
1726
+ candidate.isApiErrorMessage === true ||
1727
+ message?.role !== "assistant" ||
1728
+ message.stop_reason !== "end_turn" ||
1729
+ uuidValue(candidate.uuid) === undefined ||
1730
+ !messageId) {
1731
+ return false;
1732
+ }
1733
+ messageIds.add(messageId);
1734
+ }
1735
+ const finalSignal = completionSignals.at(-1);
1736
+ return messageIds.size === 1 &&
1737
+ finalSignal === descendants.at(-1) &&
1738
+ finalSignal !== undefined;
1739
+ }
1740
+ function pendingApprovalToolUse(descendants) {
931
1741
  const toolUses = new Map();
932
1742
  const toolResults = new Map();
933
1743
  for (const record of descendants) {
@@ -988,7 +1798,9 @@ function pendingApprovalFromRecords(snapshot) {
988
1798
  if (unresolved.length !== 1) {
989
1799
  return undefined;
990
1800
  }
991
- const pending = unresolved[0];
1801
+ return unresolved[0];
1802
+ }
1803
+ function pendingApprovalEvidence(snapshot, promptUuid, lastDescendant, pending) {
992
1804
  const pendingMessage = isRecord(pending.owner.message)
993
1805
  ? pending.owner.message
994
1806
  : undefined;
@@ -1191,24 +2003,59 @@ function openRelativeTranscript(projectsRoot, relativePath) {
1191
2003
  }
1192
2004
  }
1193
2005
  function readCompleteJsonlRecords(fd, offset, length) {
1194
- const buffer = Buffer.allocUnsafe(length);
1195
- let readTotal = 0;
1196
- while (readTotal < length) {
1197
- const bytesRead = fs.readSync(fd, buffer, readTotal, length - readTotal, offset + readTotal);
1198
- if (bytesRead === 0) {
1199
- break;
1200
- }
1201
- readTotal += bytesRead;
1202
- }
1203
- if (readTotal !== length) {
1204
- throw new Error("Claude transcript changed while it was being read");
2006
+ return readCompleteJsonlRecordEntries(fd, offset, length)
2007
+ .map((entry) => entry.record);
2008
+ }
2009
+ function readBoundedCompleteJsonlTail(fd, endOffset, maxBytes) {
2010
+ const offset = Math.max(0, endOffset - maxBytes);
2011
+ return readCompleteJsonlRecordEntries(fd, offset, endOffset - offset, {
2012
+ allowLeadingPartial: offset > 0
2013
+ });
2014
+ }
2015
+ function readCompleteJsonlRecordEntries(fd, offset, length, options = {}) {
2016
+ const buffer = options.preReadBuffer ??
2017
+ readExactTranscriptBytes(fd, offset, length);
2018
+ if (buffer.length !== length) {
2019
+ throw new Error("Claude transcript pre-read boundary is invalid");
1205
2020
  }
1206
- if (buffer.length === 0 || buffer[buffer.length - 1] !== 0x0a) {
2021
+ if (buffer.length === 0) {
1207
2022
  return [];
1208
2023
  }
1209
- const text = buffer.subarray(0, buffer.length - 1).toString("utf8");
2024
+ let start = 0;
2025
+ if (options.allowLeadingPartial === true &&
2026
+ offset > 0 &&
2027
+ byteAt(fd, offset - 1) !== 0x0a) {
2028
+ const firstNewline = buffer.indexOf(0x0a);
2029
+ if (firstNewline < 0) {
2030
+ return [];
2031
+ }
2032
+ start = firstNewline + 1;
2033
+ }
2034
+ let end = buffer.length;
2035
+ if (buffer[end - 1] !== 0x0a) {
2036
+ if (options.allowTrailingPartial !== true) {
2037
+ return [];
2038
+ }
2039
+ const lastNewline = buffer.lastIndexOf(0x0a);
2040
+ if (lastNewline < start) {
2041
+ return [];
2042
+ }
2043
+ end = lastNewline + 1;
2044
+ }
1210
2045
  const records = [];
1211
- for (const line of text.split("\n")) {
2046
+ let lineStart = start;
2047
+ while (lineStart < end) {
2048
+ const newline = buffer.indexOf(0x0a, lineStart);
2049
+ if (newline < 0 || newline >= end) {
2050
+ break;
2051
+ }
2052
+ let lineBuffer = buffer.subarray(lineStart, newline);
2053
+ const recordOffset = offset + lineStart;
2054
+ lineStart = newline + 1;
2055
+ if (lineBuffer.at(-1) === 0x0d) {
2056
+ lineBuffer = lineBuffer.subarray(0, lineBuffer.length - 1);
2057
+ }
2058
+ const line = lineBuffer.toString("utf8");
1212
2059
  if (!line.trim()) {
1213
2060
  continue;
1214
2061
  }
@@ -1222,10 +2069,16 @@ function readCompleteJsonlRecords(fd, offset, length) {
1222
2069
  if (!isRecord(parsed)) {
1223
2070
  throw new Error("Claude transcript contains a non-object JSONL record");
1224
2071
  }
1225
- records.push(parsed);
2072
+ records.push({ record: parsed, offsetBytes: recordOffset });
1226
2073
  }
1227
2074
  return records;
1228
2075
  }
2076
+ function byteAt(fd, offset) {
2077
+ const buffer = Buffer.allocUnsafe(1);
2078
+ return fs.readSync(fd, buffer, 0, 1, offset) === 1
2079
+ ? buffer[0]
2080
+ : undefined;
2081
+ }
1229
2082
  function descendantRecords(records, recordsByUuid, ancestorUuid, predicate) {
1230
2083
  return records.filter((record) => predicate(record) &&
1231
2084
  descendantChain(recordsByUuid, ancestorUuid, record) !== undefined);
@@ -1594,7 +2447,4 @@ function uuidValue(value) {
1594
2447
  function nonEmptyString(value) {
1595
2448
  return typeof value === "string" && value.trim().length > 0 ? value : undefined;
1596
2449
  }
1597
- function isRecord(value) {
1598
- return value !== null && typeof value === "object" && !Array.isArray(value);
1599
- }
1600
2450
  //# sourceMappingURL=claude-local-transcript-provider.js.map