harnery 0.34.1 → 0.36.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 (692) hide show
  1. package/dist/commander.d.ts +30 -5
  2. package/dist/commander.d.ts.map +1 -1
  3. package/dist/commander.js +124 -94
  4. package/dist/commands/agents.d.ts +37 -6
  5. package/dist/commands/agents.d.ts.map +1 -1
  6. package/dist/commands/agents.js +466 -371
  7. package/dist/commands/backup.d.ts.map +1 -1
  8. package/dist/commands/backup.js +10 -10
  9. package/dist/commands/browse-session.d.ts.map +1 -1
  10. package/dist/commands/browse-session.js +12 -0
  11. package/dist/commands/browse.d.ts +1 -1
  12. package/dist/commands/browse.d.ts.map +1 -1
  13. package/dist/commands/browse.js +31 -6
  14. package/dist/commands/conversations.d.ts +10 -0
  15. package/dist/commands/conversations.d.ts.map +1 -0
  16. package/dist/commands/conversations.js +201 -0
  17. package/dist/commands/decision.d.ts.map +1 -1
  18. package/dist/commands/decision.js +2 -2
  19. package/dist/commands/deinit.d.ts.map +1 -1
  20. package/dist/commands/deinit.js +5 -0
  21. package/dist/commands/docs.d.ts.map +1 -1
  22. package/dist/commands/docs.js +13 -2
  23. package/dist/commands/doctor.d.ts +5 -0
  24. package/dist/commands/doctor.d.ts.map +1 -1
  25. package/dist/commands/doctor.js +51 -7
  26. package/dist/commands/events.d.ts.map +1 -1
  27. package/dist/commands/events.js +18 -1
  28. package/dist/commands/fetch.js +6 -5
  29. package/dist/commands/files.d.ts +22 -0
  30. package/dist/commands/files.d.ts.map +1 -0
  31. package/dist/commands/files.js +113 -0
  32. package/dist/commands/governor.js +14 -12
  33. package/dist/commands/inbox.d.ts +5 -0
  34. package/dist/commands/inbox.d.ts.map +1 -0
  35. package/dist/commands/inbox.js +57 -0
  36. package/dist/commands/init.d.ts +4 -5
  37. package/dist/commands/init.d.ts.map +1 -1
  38. package/dist/commands/init.js +63 -13
  39. package/dist/commands/ledger-v3.d.ts.map +1 -1
  40. package/dist/commands/ledger-v3.js +347 -1
  41. package/dist/commands/logs.d.ts +4 -0
  42. package/dist/commands/logs.d.ts.map +1 -0
  43. package/dist/commands/logs.js +169 -0
  44. package/dist/commands/messages.d.ts +5 -0
  45. package/dist/commands/messages.d.ts.map +1 -0
  46. package/dist/commands/messages.js +45 -0
  47. package/dist/commands/outline.d.ts +1 -1
  48. package/dist/commands/outline.d.ts.map +1 -1
  49. package/dist/commands/outline.js +2 -2
  50. package/dist/commands/presence.d.ts.map +1 -1
  51. package/dist/commands/presence.js +2 -2
  52. package/dist/commands/read.d.ts +1 -1
  53. package/dist/commands/read.d.ts.map +1 -1
  54. package/dist/commands/read.js +2 -2
  55. package/dist/commands/semantic.d.ts +4 -0
  56. package/dist/commands/semantic.d.ts.map +1 -0
  57. package/dist/commands/semantic.js +199 -0
  58. package/dist/commands/storage.d.ts +4 -0
  59. package/dist/commands/storage.d.ts.map +1 -0
  60. package/dist/commands/storage.js +238 -0
  61. package/dist/commands/tunnel.d.ts +5 -1
  62. package/dist/commands/tunnel.d.ts.map +1 -1
  63. package/dist/commands/tunnel.js +44 -31
  64. package/dist/commands/web.d.ts +3 -0
  65. package/dist/commands/web.d.ts.map +1 -1
  66. package/dist/commands/web.js +84 -7
  67. package/dist/commands/work.js +3 -3
  68. package/dist/commands/workflow.js +13 -13
  69. package/dist/core/adapters/profiles.d.ts +1 -1
  70. package/dist/core/agents/canonical-emit.d.ts +3 -0
  71. package/dist/core/agents/canonical-emit.d.ts.map +1 -1
  72. package/dist/core/agents/canonical-emit.js +12 -0
  73. package/dist/core/agents/claim-path.d.ts +11 -0
  74. package/dist/core/agents/claim-path.d.ts.map +1 -0
  75. package/dist/core/agents/claim-path.js +22 -0
  76. package/dist/core/agents/cli.js +209 -39
  77. package/dist/core/agents/coord-client.d.ts +29 -3
  78. package/dist/core/agents/coord-client.d.ts.map +1 -1
  79. package/dist/core/agents/coord-client.js +88 -9
  80. package/dist/core/agents/live-authority-v3.d.ts +47 -1
  81. package/dist/core/agents/live-authority-v3.d.ts.map +1 -1
  82. package/dist/core/agents/live-authority-v3.js +245 -13
  83. package/dist/core/agents/live-lifecycle-v3.js +9 -4
  84. package/dist/core/agents/live-observation-v3.d.ts.map +1 -1
  85. package/dist/core/agents/live-observation-v3.js +8 -3
  86. package/dist/core/agents/render/prompt-context.d.ts +9 -3
  87. package/dist/core/agents/render/prompt-context.d.ts.map +1 -1
  88. package/dist/core/agents/render/prompt-context.js +36 -17
  89. package/dist/core/agents/rules/stop-hook.d.ts +2 -0
  90. package/dist/core/agents/rules/stop-hook.d.ts.map +1 -1
  91. package/dist/core/agents/rules/stop-hook.js +115 -22
  92. package/dist/core/agents/rules/verdict.d.ts +1 -0
  93. package/dist/core/agents/rules/verdict.d.ts.map +1 -1
  94. package/dist/core/agents/session-events.d.ts.map +1 -1
  95. package/dist/core/agents/session-events.js +4 -0
  96. package/dist/core/agents/session-finalization-state-v3.js +1 -1
  97. package/dist/core/agents/session-finalizer-v3.js +5 -1
  98. package/dist/core/agents/session-name-display.d.ts +1 -0
  99. package/dist/core/agents/session-name-display.d.ts.map +1 -1
  100. package/dist/core/agents/session-name-display.js +8 -1
  101. package/dist/core/agents/state/activity-log.d.ts +3 -0
  102. package/dist/core/agents/state/activity-log.d.ts.map +1 -1
  103. package/dist/core/agents/state/activity-log.js +6 -3
  104. package/dist/core/agents/state/heartbeat-reader.d.ts +46 -0
  105. package/dist/core/agents/state/heartbeat-reader.d.ts.map +1 -0
  106. package/dist/core/agents/state/heartbeat-reader.js +25 -0
  107. package/dist/core/agents/state/heartbeat-writer.d.ts +9 -48
  108. package/dist/core/agents/state/heartbeat-writer.d.ts.map +1 -1
  109. package/dist/core/agents/state/heartbeat-writer.js +34 -34
  110. package/dist/core/agents/state/live-coordination-view.d.ts +6 -8
  111. package/dist/core/agents/state/live-coordination-view.d.ts.map +1 -1
  112. package/dist/core/agents/state/live-coordination-view.js +16 -67
  113. package/dist/core/agents/state/live-coordination-writer.d.ts +12 -0
  114. package/dist/core/agents/state/live-coordination-writer.d.ts.map +1 -0
  115. package/dist/core/agents/state/live-coordination-writer.js +92 -0
  116. package/dist/core/agents/state/names.d.ts +9 -1
  117. package/dist/core/agents/state/names.d.ts.map +1 -1
  118. package/dist/core/agents/state/names.js +190 -182
  119. package/dist/core/agents/state/stale-sweep.d.ts.map +1 -1
  120. package/dist/core/agents/state/stale-sweep.js +23 -5
  121. package/dist/core/artifacts/constants.d.ts +5 -0
  122. package/dist/core/artifacts/constants.d.ts.map +1 -0
  123. package/dist/core/artifacts/constants.js +4 -0
  124. package/dist/core/artifacts/index.d.ts +24 -3
  125. package/dist/core/artifacts/index.d.ts.map +1 -1
  126. package/dist/core/artifacts/index.js +96 -8
  127. package/dist/core/config.d.ts +62 -4
  128. package/dist/core/config.d.ts.map +1 -1
  129. package/dist/core/config.js +98 -4
  130. package/dist/core/conversations/archive.d.ts +49 -0
  131. package/dist/core/conversations/archive.d.ts.map +1 -0
  132. package/dist/core/conversations/archive.js +136 -0
  133. package/dist/core/conversations/catalog.d.ts +10 -0
  134. package/dist/core/conversations/catalog.d.ts.map +1 -0
  135. package/dist/core/conversations/catalog.js +72 -0
  136. package/dist/core/conversations/context-pack.d.ts +6 -0
  137. package/dist/core/conversations/context-pack.d.ts.map +1 -0
  138. package/dist/core/conversations/context-pack.js +60 -0
  139. package/dist/core/conversations/contract.d.ts +155 -0
  140. package/dist/core/conversations/contract.d.ts.map +1 -0
  141. package/dist/core/conversations/contract.js +1 -0
  142. package/dist/core/conversations/evaluation.d.ts +16 -0
  143. package/dist/core/conversations/evaluation.d.ts.map +1 -0
  144. package/dist/core/conversations/evaluation.js +9 -0
  145. package/dist/core/conversations/index.d.ts +10 -0
  146. package/dist/core/conversations/index.d.ts.map +1 -0
  147. package/dist/core/conversations/index.js +9 -0
  148. package/dist/core/conversations/lifecycle.d.ts +28 -0
  149. package/dist/core/conversations/lifecycle.d.ts.map +1 -0
  150. package/dist/core/conversations/lifecycle.js +29 -0
  151. package/dist/core/conversations/normalize.d.ts +14 -0
  152. package/dist/core/conversations/normalize.d.ts.map +1 -0
  153. package/dist/core/conversations/normalize.js +82 -0
  154. package/dist/core/conversations/query.d.ts +8 -0
  155. package/dist/core/conversations/query.d.ts.map +1 -0
  156. package/dist/core/conversations/query.js +280 -0
  157. package/dist/core/conversations/search-index.d.ts +9 -0
  158. package/dist/core/conversations/search-index.d.ts.map +1 -0
  159. package/dist/core/conversations/search-index.js +29 -0
  160. package/dist/core/events/legacy-storage/canary.d.ts +18 -0
  161. package/dist/core/events/legacy-storage/canary.d.ts.map +1 -0
  162. package/dist/core/events/legacy-storage/canary.js +150 -0
  163. package/dist/core/events/legacy-storage/fence.d.ts +15 -0
  164. package/dist/core/events/legacy-storage/fence.d.ts.map +1 -0
  165. package/dist/core/events/legacy-storage/fence.js +115 -0
  166. package/dist/core/events/legacy-storage/index.d.ts +6 -0
  167. package/dist/core/events/legacy-storage/index.d.ts.map +1 -0
  168. package/dist/core/events/legacy-storage/index.js +5 -0
  169. package/dist/core/events/legacy-storage/inventory.d.ts +10 -0
  170. package/dist/core/events/legacy-storage/inventory.d.ts.map +1 -0
  171. package/dist/core/events/legacy-storage/inventory.js +40 -0
  172. package/dist/core/events/legacy-storage/manifest.d.ts +23 -0
  173. package/dist/core/events/legacy-storage/manifest.d.ts.map +1 -0
  174. package/dist/core/events/legacy-storage/manifest.js +108 -0
  175. package/dist/core/events/legacy-storage/reader.d.ts +15 -0
  176. package/dist/core/events/legacy-storage/reader.d.ts.map +1 -0
  177. package/dist/core/events/legacy-storage/reader.js +154 -0
  178. package/dist/core/events/v3/authority-outbox.d.ts +7 -2
  179. package/dist/core/events/v3/authority-outbox.d.ts.map +1 -1
  180. package/dist/core/events/v3/authority-outbox.js +16 -3
  181. package/dist/core/events/v3/base-contract.d.ts +851 -16
  182. package/dist/core/events/v3/base-contract.d.ts.map +1 -1
  183. package/dist/core/events/v3/base-contract.js +50 -7
  184. package/dist/core/events/v3/bootstrap.d.ts +39 -0
  185. package/dist/core/events/v3/bootstrap.d.ts.map +1 -1
  186. package/dist/core/events/v3/bootstrap.js +167 -3
  187. package/dist/core/events/v3/capabilities.d.ts +11 -0
  188. package/dist/core/events/v3/capabilities.d.ts.map +1 -1
  189. package/dist/core/events/v3/capabilities.js +26 -3
  190. package/dist/core/events/v3/control-witness.d.ts +44 -0
  191. package/dist/core/events/v3/control-witness.d.ts.map +1 -0
  192. package/dist/core/events/v3/control-witness.js +233 -0
  193. package/dist/core/events/v3/control-writer.d.ts +4 -0
  194. package/dist/core/events/v3/control-writer.d.ts.map +1 -0
  195. package/dist/core/events/v3/control-writer.js +16 -0
  196. package/dist/core/events/v3/control.d.ts +8 -2
  197. package/dist/core/events/v3/control.d.ts.map +1 -1
  198. package/dist/core/events/v3/control.js +46 -18
  199. package/dist/core/events/v3/coordination-transaction-recovery.d.ts +42 -0
  200. package/dist/core/events/v3/coordination-transaction-recovery.d.ts.map +1 -0
  201. package/dist/core/events/v3/coordination-transaction-recovery.js +342 -0
  202. package/dist/core/events/v3/coordination-view.d.ts.map +1 -1
  203. package/dist/core/events/v3/coordination-view.js +16 -1
  204. package/dist/core/events/v3/generated.d.ts +1 -1
  205. package/dist/core/events/v3/generated.js +1 -1
  206. package/dist/core/events/v3/index.d.ts +8 -5
  207. package/dist/core/events/v3/index.d.ts.map +1 -1
  208. package/dist/core/events/v3/index.js +7 -4
  209. package/dist/core/events/v3/latency.d.ts +31 -1
  210. package/dist/core/events/v3/latency.d.ts.map +1 -1
  211. package/dist/core/events/v3/latency.js +127 -3
  212. package/dist/core/events/v3/live-route-observer.d.ts +31 -0
  213. package/dist/core/events/v3/live-route-observer.d.ts.map +1 -0
  214. package/dist/core/events/v3/live-route-observer.js +58 -0
  215. package/dist/core/events/v3/live-routing.d.ts +42 -20
  216. package/dist/core/events/v3/live-routing.d.ts.map +1 -1
  217. package/dist/core/events/v3/live-routing.js +153 -41
  218. package/dist/core/events/v3/producers/command-recorder.d.ts.map +1 -1
  219. package/dist/core/events/v3/producers/command-recorder.js +10 -1
  220. package/dist/core/events/v3/producers/coordination-recorder.d.ts +11 -1
  221. package/dist/core/events/v3/producers/coordination-recorder.d.ts.map +1 -1
  222. package/dist/core/events/v3/producers/coordination-recorder.js +90 -13
  223. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts +129 -0
  224. package/dist/core/events/v3/producers/diagnostic-summaries.d.ts.map +1 -0
  225. package/dist/core/events/v3/producers/diagnostic-summaries.js +499 -0
  226. package/dist/core/events/v3/producers/hook-base.d.ts +17 -1
  227. package/dist/core/events/v3/producers/hook-base.d.ts.map +1 -1
  228. package/dist/core/events/v3/producers/hook-base.js +83 -2
  229. package/dist/core/events/v3/producers/intake.d.ts +13 -0
  230. package/dist/core/events/v3/producers/intake.d.ts.map +1 -1
  231. package/dist/core/events/v3/producers/intake.js +36 -2
  232. package/dist/core/events/v3/producers/producer-state-observer.d.ts +8 -0
  233. package/dist/core/events/v3/producers/producer-state-observer.d.ts.map +1 -0
  234. package/dist/core/events/v3/producers/producer-state-observer.js +45 -0
  235. package/dist/core/events/v3/producers/recorder.d.ts +117 -1
  236. package/dist/core/events/v3/producers/recorder.d.ts.map +1 -1
  237. package/dist/core/events/v3/producers/recorder.js +992 -27
  238. package/dist/core/events/v3/reader.d.ts +51 -0
  239. package/dist/core/events/v3/reader.d.ts.map +1 -1
  240. package/dist/core/events/v3/reader.js +181 -1
  241. package/dist/core/events/v3/rotation-config.d.ts +9 -0
  242. package/dist/core/events/v3/rotation-config.d.ts.map +1 -0
  243. package/dist/core/events/v3/rotation-config.js +91 -0
  244. package/dist/core/events/v3/runtime-build.d.ts +11 -0
  245. package/dist/core/events/v3/runtime-build.d.ts.map +1 -0
  246. package/dist/core/events/v3/runtime-build.js +39 -0
  247. package/dist/core/events/v3/runtime-identity.d.ts +5 -0
  248. package/dist/core/events/v3/runtime-identity.d.ts.map +1 -0
  249. package/dist/core/events/v3/runtime-identity.js +18 -0
  250. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts +52 -0
  251. package/dist/core/events/v3/runtime-telemetry-capabilities.d.ts.map +1 -0
  252. package/dist/core/events/v3/runtime-telemetry-capabilities.js +54 -0
  253. package/dist/core/events/v3/support-storage/classify.d.ts +46 -0
  254. package/dist/core/events/v3/support-storage/classify.d.ts.map +1 -0
  255. package/dist/core/events/v3/support-storage/classify.js +149 -0
  256. package/dist/core/events/v3/support-storage/eligibility.d.ts +29 -0
  257. package/dist/core/events/v3/support-storage/eligibility.d.ts.map +1 -0
  258. package/dist/core/events/v3/support-storage/eligibility.js +35 -0
  259. package/dist/core/events/v3/support-storage/index.d.ts +10 -0
  260. package/dist/core/events/v3/support-storage/index.d.ts.map +1 -0
  261. package/dist/core/events/v3/support-storage/index.js +9 -0
  262. package/dist/core/events/v3/support-storage/inventory.d.ts +30 -0
  263. package/dist/core/events/v3/support-storage/inventory.d.ts.map +1 -0
  264. package/dist/core/events/v3/support-storage/inventory.js +94 -0
  265. package/dist/core/events/v3/support-storage/logical-authority.d.ts +14 -0
  266. package/dist/core/events/v3/support-storage/logical-authority.d.ts.map +1 -0
  267. package/dist/core/events/v3/support-storage/logical-authority.js +104 -0
  268. package/dist/core/events/v3/support-storage/maintenance.d.ts +98 -0
  269. package/dist/core/events/v3/support-storage/maintenance.d.ts.map +1 -0
  270. package/dist/core/events/v3/support-storage/maintenance.js +352 -0
  271. package/dist/core/events/v3/support-storage/pack-contract.d.ts +59 -0
  272. package/dist/core/events/v3/support-storage/pack-contract.d.ts.map +1 -0
  273. package/dist/core/events/v3/support-storage/pack-contract.js +249 -0
  274. package/dist/core/events/v3/support-storage/pack-reader.d.ts +34 -0
  275. package/dist/core/events/v3/support-storage/pack-reader.d.ts.map +1 -0
  276. package/dist/core/events/v3/support-storage/pack-reader.js +258 -0
  277. package/dist/core/events/v3/support-storage/pack-writer.d.ts +30 -0
  278. package/dist/core/events/v3/support-storage/pack-writer.d.ts.map +1 -0
  279. package/dist/core/events/v3/support-storage/pack-writer.js +268 -0
  280. package/dist/core/events/v3/support-storage/recovery.d.ts +15 -0
  281. package/dist/core/events/v3/support-storage/recovery.d.ts.map +1 -0
  282. package/dist/core/events/v3/support-storage/recovery.js +22 -0
  283. package/dist/core/events/v3/turn-telemetry.d.ts +21 -6
  284. package/dist/core/events/v3/turn-telemetry.d.ts.map +1 -1
  285. package/dist/core/events/v3/turn-telemetry.js +32 -2
  286. package/dist/core/events/v3/writer.d.ts +13 -1
  287. package/dist/core/events/v3/writer.d.ts.map +1 -1
  288. package/dist/core/events/v3/writer.js +126 -12
  289. package/dist/core/governor/plan-read.d.ts.map +1 -1
  290. package/dist/core/governor/plan-read.js +5 -21
  291. package/dist/core/governor/planning.js +6 -8
  292. package/dist/core/governor/service-read.d.ts +12 -0
  293. package/dist/core/governor/service-read.d.ts.map +1 -1
  294. package/dist/core/governor/service-read.js +266 -2
  295. package/dist/core/governor/service.d.ts +1 -0
  296. package/dist/core/governor/service.d.ts.map +1 -1
  297. package/dist/core/governor/service.js +53 -18
  298. package/dist/core/guard/evidence-v3.d.ts.map +1 -1
  299. package/dist/core/guard/evidence-v3.js +2 -0
  300. package/dist/core/hooks/adapter/events.d.ts.map +1 -1
  301. package/dist/core/hooks/adapter/events.js +1 -0
  302. package/dist/core/hooks/adapter/output.d.ts +4 -2
  303. package/dist/core/hooks/adapter/output.d.ts.map +1 -1
  304. package/dist/core/hooks/adapter/output.js +13 -5
  305. package/dist/core/hooks/adapter/parse.d.ts +3 -0
  306. package/dist/core/hooks/adapter/parse.d.ts.map +1 -1
  307. package/dist/core/hooks/adapter/parse.js +14 -0
  308. package/dist/core/hooks/adapter/runtime-telemetry.d.ts +142 -0
  309. package/dist/core/hooks/adapter/runtime-telemetry.d.ts.map +1 -0
  310. package/dist/core/hooks/adapter/runtime-telemetry.js +869 -0
  311. package/dist/core/hooks/cli.js +318 -61
  312. package/dist/core/hooks/effects/image-capture.d.ts +1 -1
  313. package/dist/core/hooks/effects/image-capture.d.ts.map +1 -1
  314. package/dist/core/hooks/effects/image-capture.js +4 -2
  315. package/dist/core/hooks/remediation-cap.d.ts +39 -0
  316. package/dist/core/hooks/remediation-cap.d.ts.map +1 -0
  317. package/dist/core/hooks/remediation-cap.js +63 -0
  318. package/dist/core/hooks/resolve/coord-root.d.ts +22 -9
  319. package/dist/core/hooks/resolve/coord-root.d.ts.map +1 -1
  320. package/dist/core/hooks/resolve/coord-root.js +92 -11
  321. package/dist/core/hooks/resolve/owner.d.ts.map +1 -1
  322. package/dist/core/hooks/resolve/owner.js +5 -0
  323. package/dist/core/hooks/resolve/transcript.d.ts +33 -9
  324. package/dist/core/hooks/resolve/transcript.d.ts.map +1 -1
  325. package/dist/core/hooks/resolve/transcript.js +33 -10
  326. package/dist/core/inbox/contract.d.ts +64 -0
  327. package/dist/core/inbox/contract.d.ts.map +1 -0
  328. package/dist/core/inbox/contract.js +13 -0
  329. package/dist/core/inbox/index.d.ts +5 -0
  330. package/dist/core/inbox/index.d.ts.map +1 -0
  331. package/dist/core/inbox/index.js +4 -0
  332. package/dist/core/inbox/lifecycle.d.ts +22 -0
  333. package/dist/core/inbox/lifecycle.d.ts.map +1 -0
  334. package/dist/core/inbox/lifecycle.js +41 -0
  335. package/dist/core/inbox/service.d.ts +36 -0
  336. package/dist/core/inbox/service.d.ts.map +1 -0
  337. package/dist/core/inbox/service.js +210 -0
  338. package/dist/core/inbox/watcher.d.ts +7 -0
  339. package/dist/core/inbox/watcher.d.ts.map +1 -0
  340. package/dist/core/inbox/watcher.js +26 -0
  341. package/dist/core/presence/codec-digest.d.ts.map +1 -1
  342. package/dist/core/presence/codec-digest.js +14 -3
  343. package/dist/core/presence/relay-client.d.ts +1 -0
  344. package/dist/core/presence/relay-client.d.ts.map +1 -1
  345. package/dist/core/presence/relay-client.js +52 -8
  346. package/dist/core/semantic/adapters.d.ts +37 -0
  347. package/dist/core/semantic/adapters.d.ts.map +1 -0
  348. package/dist/core/semantic/adapters.js +360 -0
  349. package/dist/core/semantic/contract.d.ts +1072 -0
  350. package/dist/core/semantic/contract.d.ts.map +1 -0
  351. package/dist/core/semantic/contract.js +331 -0
  352. package/dist/core/semantic/evidence.d.ts +11 -0
  353. package/dist/core/semantic/evidence.d.ts.map +1 -0
  354. package/dist/core/semantic/evidence.js +262 -0
  355. package/dist/core/semantic/index.d.ts +14 -0
  356. package/dist/core/semantic/index.d.ts.map +1 -0
  357. package/dist/core/semantic/index.js +13 -0
  358. package/dist/core/semantic/once.d.ts +38 -0
  359. package/dist/core/semantic/once.d.ts.map +1 -0
  360. package/dist/core/semantic/once.js +364 -0
  361. package/dist/core/semantic/prompt.d.ts +12 -0
  362. package/dist/core/semantic/prompt.d.ts.map +1 -0
  363. package/dist/core/semantic/prompt.js +83 -0
  364. package/dist/core/semantic/review.d.ts +144 -0
  365. package/dist/core/semantic/review.d.ts.map +1 -0
  366. package/dist/core/semantic/review.js +544 -0
  367. package/dist/core/semantic/routes.d.ts +10 -0
  368. package/dist/core/semantic/routes.d.ts.map +1 -0
  369. package/dist/core/semantic/routes.js +21 -0
  370. package/dist/core/semantic/scheduler.d.ts +27 -0
  371. package/dist/core/semantic/scheduler.d.ts.map +1 -0
  372. package/dist/core/semantic/scheduler.js +91 -0
  373. package/dist/core/semantic/service-status.d.ts +51 -0
  374. package/dist/core/semantic/service-status.d.ts.map +1 -0
  375. package/dist/core/semantic/service-status.js +140 -0
  376. package/dist/core/semantic/service.d.ts +52 -0
  377. package/dist/core/semantic/service.d.ts.map +1 -0
  378. package/dist/core/semantic/service.js +559 -0
  379. package/dist/core/semantic/soak.d.ts +75 -0
  380. package/dist/core/semantic/soak.d.ts.map +1 -0
  381. package/dist/core/semantic/soak.js +476 -0
  382. package/dist/core/semantic/storage.d.ts +81 -0
  383. package/dist/core/semantic/storage.d.ts.map +1 -0
  384. package/dist/core/semantic/storage.js +180 -0
  385. package/dist/core/semantic/usage.d.ts +43 -0
  386. package/dist/core/semantic/usage.d.ts.map +1 -0
  387. package/dist/core/semantic/usage.js +193 -0
  388. package/dist/core/semantic/validate.d.ts +18 -0
  389. package/dist/core/semantic/validate.d.ts.map +1 -0
  390. package/dist/core/semantic/validate.js +207 -0
  391. package/dist/core/storage/buffer.d.ts +28 -0
  392. package/dist/core/storage/buffer.d.ts.map +1 -0
  393. package/dist/core/storage/buffer.js +101 -0
  394. package/dist/core/storage/builtins.d.ts +3 -0
  395. package/dist/core/storage/builtins.d.ts.map +1 -0
  396. package/dist/core/storage/builtins.js +683 -0
  397. package/dist/core/storage/catalog.d.ts +19 -0
  398. package/dist/core/storage/catalog.d.ts.map +1 -0
  399. package/dist/core/storage/catalog.js +365 -0
  400. package/dist/core/storage/config.d.ts +16 -0
  401. package/dist/core/storage/config.d.ts.map +1 -0
  402. package/dist/core/storage/config.js +311 -0
  403. package/dist/core/storage/contract.d.ts +275 -0
  404. package/dist/core/storage/contract.d.ts.map +1 -0
  405. package/dist/core/storage/contract.js +3 -0
  406. package/dist/core/storage/durable-history.d.ts +36 -0
  407. package/dist/core/storage/durable-history.d.ts.map +1 -0
  408. package/dist/core/storage/durable-history.js +606 -0
  409. package/dist/core/storage/health.d.ts +4 -0
  410. package/dist/core/storage/health.d.ts.map +1 -0
  411. package/dist/core/storage/health.js +65 -0
  412. package/dist/core/storage/index.d.ts +16 -0
  413. package/dist/core/storage/index.d.ts.map +1 -0
  414. package/dist/core/storage/index.js +15 -0
  415. package/dist/core/storage/inventory.d.ts +25 -0
  416. package/dist/core/storage/inventory.d.ts.map +1 -0
  417. package/dist/core/storage/inventory.js +666 -0
  418. package/dist/core/storage/jsonl.d.ts +52 -0
  419. package/dist/core/storage/jsonl.d.ts.map +1 -0
  420. package/dist/core/storage/jsonl.js +156 -0
  421. package/dist/core/storage/log-retention.d.ts +52 -0
  422. package/dist/core/storage/log-retention.d.ts.map +1 -0
  423. package/dist/core/storage/log-retention.js +419 -0
  424. package/dist/core/storage/logger.d.ts +82 -0
  425. package/dist/core/storage/logger.d.ts.map +1 -0
  426. package/dist/core/storage/logger.js +411 -0
  427. package/dist/core/storage/maintenance-providers.d.ts +26 -0
  428. package/dist/core/storage/maintenance-providers.d.ts.map +1 -0
  429. package/dist/core/storage/maintenance-providers.js +141 -0
  430. package/dist/core/storage/maintenance.d.ts +125 -0
  431. package/dist/core/storage/maintenance.d.ts.map +1 -0
  432. package/dist/core/storage/maintenance.js +609 -0
  433. package/dist/core/storage/metrics.d.ts +60 -0
  434. package/dist/core/storage/metrics.d.ts.map +1 -0
  435. package/dist/core/storage/metrics.js +134 -0
  436. package/dist/core/storage/policy.d.ts +7 -0
  437. package/dist/core/storage/policy.d.ts.map +1 -0
  438. package/dist/core/storage/policy.js +110 -0
  439. package/dist/core/storage/process-log.d.ts +38 -0
  440. package/dist/core/storage/process-log.d.ts.map +1 -0
  441. package/dist/core/storage/process-log.js +165 -0
  442. package/dist/core/storage/query.d.ts +34 -0
  443. package/dist/core/storage/query.d.ts.map +1 -0
  444. package/dist/core/storage/query.js +295 -0
  445. package/dist/core/storage/receipts.d.ts +23 -0
  446. package/dist/core/storage/receipts.d.ts.map +1 -0
  447. package/dist/core/storage/receipts.js +117 -0
  448. package/dist/core/storage/segments.d.ts +84 -0
  449. package/dist/core/storage/segments.d.ts.map +1 -0
  450. package/dist/core/storage/segments.js +542 -0
  451. package/dist/core/storage/sink-graph.d.ts +65 -0
  452. package/dist/core/storage/sink-graph.d.ts.map +1 -0
  453. package/dist/core/storage/sink-graph.js +213 -0
  454. package/dist/core/storage/storm-control.d.ts +23 -0
  455. package/dist/core/storage/storm-control.d.ts.map +1 -0
  456. package/dist/core/storage/storm-control.js +59 -0
  457. package/dist/core/work/state.d.ts.map +1 -1
  458. package/dist/core/work/state.js +10 -14
  459. package/dist/core/workflow/live-session-v3.d.ts.map +1 -1
  460. package/dist/core/workflow/live-session-v3.js +2 -1
  461. package/dist/index.d.ts +2 -0
  462. package/dist/index.d.ts.map +1 -1
  463. package/dist/index.js +2 -0
  464. package/dist/lazy-commands.d.ts +26 -0
  465. package/dist/lazy-commands.d.ts.map +1 -0
  466. package/dist/lazy-commands.js +210 -0
  467. package/dist/lib/browser/client.d.ts +11 -0
  468. package/dist/lib/browser/client.d.ts.map +1 -1
  469. package/dist/lib/browser/client.js +13 -0
  470. package/dist/lib/browser/index.d.ts +1 -0
  471. package/dist/lib/browser/index.d.ts.map +1 -1
  472. package/dist/lib/browser/standalone-html.d.ts +25 -0
  473. package/dist/lib/browser/standalone-html.d.ts.map +1 -0
  474. package/dist/lib/browser/standalone-html.js +284 -0
  475. package/dist/lib/docs-lint.d.ts +2 -0
  476. package/dist/lib/docs-lint.d.ts.map +1 -1
  477. package/dist/lib/docs-lint.js +45 -80
  478. package/dist/lib/docs-metadata-audit.d.ts +3 -0
  479. package/dist/lib/docs-metadata-audit.d.ts.map +1 -1
  480. package/dist/lib/docs-metadata-audit.js +13 -23
  481. package/dist/lib/docs-metadata-sync.d.ts +1 -0
  482. package/dist/lib/docs-metadata-sync.d.ts.map +1 -1
  483. package/dist/lib/docs-metadata-sync.js +28 -10
  484. package/dist/lib/docs-repository-view.d.ts +22 -0
  485. package/dist/lib/docs-repository-view.d.ts.map +1 -0
  486. package/dist/lib/docs-repository-view.js +185 -0
  487. package/dist/lib/http/client.d.ts +11 -5
  488. package/dist/lib/http/client.d.ts.map +1 -1
  489. package/dist/lib/http/client.js +22 -4
  490. package/dist/lib/http/index.d.ts +1 -1
  491. package/dist/lib/http/index.d.ts.map +1 -1
  492. package/dist/lib/http/index.js +1 -1
  493. package/dist/lib/indexer-exclusions.d.ts +27 -0
  494. package/dist/lib/indexer-exclusions.d.ts.map +1 -0
  495. package/dist/lib/indexer-exclusions.js +176 -0
  496. package/dist/lib/instructions/apply.d.ts.map +1 -1
  497. package/dist/lib/instructions/apply.js +1 -0
  498. package/dist/lib/instructions/templates.d.ts +2 -0
  499. package/dist/lib/instructions/templates.d.ts.map +1 -1
  500. package/dist/lib/instructions/templates.js +149 -4
  501. package/dist/lib/local-file-url.d.ts +9 -0
  502. package/dist/lib/local-file-url.d.ts.map +1 -0
  503. package/dist/lib/local-file-url.js +20 -0
  504. package/dist/lib/web-performance.d.ts +118 -0
  505. package/dist/lib/web-performance.d.ts.map +1 -0
  506. package/dist/lib/web-performance.js +192 -0
  507. package/package.json +34 -2
  508. package/schemas/config.schema.json +58 -0
  509. package/schemas/event-v3.schema.json +3073 -581
  510. package/src/commander.ts +462 -93
  511. package/src/commands/agents.ts +617 -355
  512. package/src/commands/backup.ts +18 -14
  513. package/src/commands/browse-session.ts +12 -0
  514. package/src/commands/browse.ts +31 -9
  515. package/src/commands/conversations.ts +279 -0
  516. package/src/commands/decision.ts +8 -2
  517. package/src/commands/deinit.ts +6 -0
  518. package/src/commands/docs.ts +25 -6
  519. package/src/commands/doctor.ts +75 -9
  520. package/src/commands/events.ts +21 -1
  521. package/src/commands/fetch.ts +7 -6
  522. package/src/commands/files.ts +143 -0
  523. package/src/commands/governor.ts +13 -12
  524. package/src/commands/inbox.ts +61 -0
  525. package/src/commands/init.ts +78 -16
  526. package/src/commands/ledger-v3.ts +421 -1
  527. package/src/commands/logs.ts +224 -0
  528. package/src/commands/messages.ts +61 -0
  529. package/src/commands/outline.ts +6 -2
  530. package/src/commands/presence.ts +7 -2
  531. package/src/commands/read.ts +6 -2
  532. package/src/commands/semantic.ts +244 -0
  533. package/src/commands/storage.ts +310 -0
  534. package/src/commands/tunnel.ts +66 -52
  535. package/src/commands/web.ts +92 -7
  536. package/src/commands/work.ts +3 -3
  537. package/src/commands/workflow.ts +13 -13
  538. package/src/core/agents/canonical-emit.ts +15 -0
  539. package/src/core/agents/claim-path.ts +23 -0
  540. package/src/core/agents/cli.ts +259 -53
  541. package/src/core/agents/coord-client.ts +92 -8
  542. package/src/core/agents/live-authority-v3.ts +342 -14
  543. package/src/core/agents/live-lifecycle-v3.ts +14 -4
  544. package/src/core/agents/live-observation-v3.ts +13 -3
  545. package/src/core/agents/render/prompt-context.ts +40 -16
  546. package/src/core/agents/rules/stop-hook.ts +129 -25
  547. package/src/core/agents/rules/verdict.ts +1 -0
  548. package/src/core/agents/session-events.ts +4 -0
  549. package/src/core/agents/session-finalization-state-v3.ts +1 -1
  550. package/src/core/agents/session-finalizer-v3.ts +4 -1
  551. package/src/core/agents/session-name-display.ts +9 -1
  552. package/src/core/agents/state/activity-log.ts +7 -2
  553. package/src/core/agents/state/heartbeat-reader.ts +69 -0
  554. package/src/core/agents/state/heartbeat-writer.ts +47 -84
  555. package/src/core/agents/state/live-coordination-view.ts +17 -81
  556. package/src/core/agents/state/live-coordination-writer.ts +141 -0
  557. package/src/core/agents/state/names.ts +190 -182
  558. package/src/core/agents/state/stale-sweep.ts +25 -5
  559. package/src/core/artifacts/constants.ts +4 -0
  560. package/src/core/artifacts/index.ts +113 -8
  561. package/src/core/config.ts +126 -5
  562. package/src/core/conversations/archive.ts +237 -0
  563. package/src/core/conversations/catalog.ts +79 -0
  564. package/src/core/conversations/context-pack.ts +72 -0
  565. package/src/core/conversations/contract.ts +178 -0
  566. package/src/core/conversations/evaluation.ts +30 -0
  567. package/src/core/conversations/index.ts +9 -0
  568. package/src/core/conversations/lifecycle.ts +63 -0
  569. package/src/core/conversations/normalize.ts +105 -0
  570. package/src/core/conversations/query.ts +318 -0
  571. package/src/core/conversations/search-index.ts +48 -0
  572. package/src/core/events/legacy-storage/canary.ts +177 -0
  573. package/src/core/events/legacy-storage/fence.ts +129 -0
  574. package/src/core/events/legacy-storage/index.ts +5 -0
  575. package/src/core/events/legacy-storage/inventory.ts +51 -0
  576. package/src/core/events/legacy-storage/manifest.ts +136 -0
  577. package/src/core/events/legacy-storage/reader.ts +178 -0
  578. package/src/core/events/v3/authority-outbox.ts +22 -1
  579. package/src/core/events/v3/base-contract.ts +56 -7
  580. package/src/core/events/v3/bootstrap.ts +195 -2
  581. package/src/core/events/v3/capabilities.ts +37 -3
  582. package/src/core/events/v3/control-witness.ts +339 -0
  583. package/src/core/events/v3/control-writer.ts +16 -0
  584. package/src/core/events/v3/control.ts +54 -18
  585. package/src/core/events/v3/coordination-transaction-recovery.ts +477 -0
  586. package/src/core/events/v3/coordination-view.ts +17 -1
  587. package/src/core/events/v3/generated.ts +1 -1
  588. package/src/core/events/v3/index.ts +26 -2
  589. package/src/core/events/v3/latency.ts +213 -2
  590. package/src/core/events/v3/live-route-observer.ts +80 -0
  591. package/src/core/events/v3/live-routing.ts +182 -45
  592. package/src/core/events/v3/producers/command-recorder.ts +10 -1
  593. package/src/core/events/v3/producers/coordination-recorder.ts +112 -15
  594. package/src/core/events/v3/producers/diagnostic-summaries.ts +593 -0
  595. package/src/core/events/v3/producers/hook-base.ts +116 -2
  596. package/src/core/events/v3/producers/intake.ts +48 -2
  597. package/src/core/events/v3/producers/producer-state-observer.ts +52 -0
  598. package/src/core/events/v3/producers/recorder.ts +1403 -30
  599. package/src/core/events/v3/reader.ts +243 -2
  600. package/src/core/events/v3/rotation-config.ts +98 -0
  601. package/src/core/events/v3/runtime-build.ts +41 -0
  602. package/src/core/events/v3/runtime-identity.ts +16 -0
  603. package/src/core/events/v3/runtime-telemetry-capabilities.ts +143 -0
  604. package/src/core/events/v3/support-storage/classify.ts +209 -0
  605. package/src/core/events/v3/support-storage/eligibility.ts +58 -0
  606. package/src/core/events/v3/support-storage/index.ts +9 -0
  607. package/src/core/events/v3/support-storage/inventory.ts +135 -0
  608. package/src/core/events/v3/support-storage/logical-authority.ts +117 -0
  609. package/src/core/events/v3/support-storage/maintenance.ts +501 -0
  610. package/src/core/events/v3/support-storage/pack-contract.ts +337 -0
  611. package/src/core/events/v3/support-storage/pack-reader.ts +346 -0
  612. package/src/core/events/v3/support-storage/pack-writer.ts +352 -0
  613. package/src/core/events/v3/support-storage/recovery.ts +43 -0
  614. package/src/core/events/v3/turn-telemetry.ts +66 -5
  615. package/src/core/events/v3/writer.ts +168 -16
  616. package/src/core/governor/plan-read.ts +5 -18
  617. package/src/core/governor/planning.ts +5 -8
  618. package/src/core/governor/service-read.ts +320 -2
  619. package/src/core/governor/service.ts +49 -22
  620. package/src/core/guard/evidence-v3.ts +1 -0
  621. package/src/core/hooks/adapter/events.ts +1 -0
  622. package/src/core/hooks/adapter/output.ts +12 -5
  623. package/src/core/hooks/adapter/parse.ts +16 -0
  624. package/src/core/hooks/adapter/runtime-telemetry.ts +1200 -0
  625. package/src/core/hooks/cli.ts +342 -64
  626. package/src/core/hooks/effects/image-capture.ts +4 -1
  627. package/src/core/hooks/remediation-cap.ts +83 -0
  628. package/src/core/hooks/resolve/coord-root.ts +91 -11
  629. package/src/core/hooks/resolve/owner.ts +4 -0
  630. package/src/core/hooks/resolve/transcript.ts +55 -11
  631. package/src/core/inbox/contract.ts +81 -0
  632. package/src/core/inbox/index.ts +4 -0
  633. package/src/core/inbox/lifecycle.ts +104 -0
  634. package/src/core/inbox/service.ts +305 -0
  635. package/src/core/inbox/watcher.ts +36 -0
  636. package/src/core/presence/codec-digest.ts +15 -9
  637. package/src/core/presence/relay-client.ts +55 -7
  638. package/src/core/semantic/adapters.ts +452 -0
  639. package/src/core/semantic/contract.ts +430 -0
  640. package/src/core/semantic/evidence.ts +336 -0
  641. package/src/core/semantic/index.ts +201 -0
  642. package/src/core/semantic/once.ts +496 -0
  643. package/src/core/semantic/prompt.ts +96 -0
  644. package/src/core/semantic/review.ts +803 -0
  645. package/src/core/semantic/routes.ts +30 -0
  646. package/src/core/semantic/scheduler.ts +151 -0
  647. package/src/core/semantic/service-status.ts +212 -0
  648. package/src/core/semantic/service.ts +681 -0
  649. package/src/core/semantic/soak.ts +638 -0
  650. package/src/core/semantic/storage.ts +300 -0
  651. package/src/core/semantic/usage.ts +272 -0
  652. package/src/core/semantic/validate.ts +243 -0
  653. package/src/core/storage/buffer.ts +124 -0
  654. package/src/core/storage/builtins.ts +916 -0
  655. package/src/core/storage/catalog.ts +467 -0
  656. package/src/core/storage/config.ts +423 -0
  657. package/src/core/storage/contract.ts +342 -0
  658. package/src/core/storage/durable-history.ts +738 -0
  659. package/src/core/storage/health.ts +76 -0
  660. package/src/core/storage/index.ts +15 -0
  661. package/src/core/storage/inventory.ts +859 -0
  662. package/src/core/storage/jsonl.ts +213 -0
  663. package/src/core/storage/log-retention.ts +555 -0
  664. package/src/core/storage/logger.ts +546 -0
  665. package/src/core/storage/maintenance-providers.ts +200 -0
  666. package/src/core/storage/maintenance.ts +929 -0
  667. package/src/core/storage/metrics.ts +199 -0
  668. package/src/core/storage/policy.ts +141 -0
  669. package/src/core/storage/process-log.ts +203 -0
  670. package/src/core/storage/query.ts +360 -0
  671. package/src/core/storage/receipts.ts +162 -0
  672. package/src/core/storage/segments.ts +721 -0
  673. package/src/core/storage/sink-graph.ts +343 -0
  674. package/src/core/storage/storm-control.ts +91 -0
  675. package/src/core/work/state.ts +12 -21
  676. package/src/core/workflow/live-session-v3.ts +2 -4
  677. package/src/index.ts +2 -0
  678. package/src/lazy-commands.ts +294 -0
  679. package/src/lib/browser/client.ts +21 -0
  680. package/src/lib/browser/index.ts +4 -0
  681. package/src/lib/browser/standalone-html.ts +312 -0
  682. package/src/lib/docs-lint.ts +58 -77
  683. package/src/lib/docs-metadata-audit.ts +26 -21
  684. package/src/lib/docs-metadata-sync.ts +32 -9
  685. package/src/lib/docs-repository-view.ts +220 -0
  686. package/src/lib/http/client.ts +44 -8
  687. package/src/lib/http/index.ts +6 -1
  688. package/src/lib/indexer-exclusions.ts +173 -0
  689. package/src/lib/instructions/apply.ts +1 -0
  690. package/src/lib/instructions/templates.ts +154 -4
  691. package/src/lib/local-file-url.ts +31 -0
  692. package/src/lib/web-performance.ts +335 -0
@@ -0,0 +1,869 @@
1
+ import { createHash } from "node:crypto";
2
+ import { closeSync, existsSync, openSync, readdirSync, readSync, statSync } from "node:fs";
3
+ import { homedir } from "node:os";
4
+ import { basename, join, resolve } from "node:path";
5
+ import { transcriptPathCandidates } from "../resolve/transcript.js";
6
+ const DEFAULT_TAIL_BYTES = 256 * 1024;
7
+ /**
8
+ * An active turn can accumulate enough tool traffic to push its native turn
9
+ * ancestor beyond the ordinary status tail. Keep attribution bounded while
10
+ * giving long-running interactive turns a larger matching window.
11
+ */
12
+ const ACTIVE_TURN_TAIL_BYTES = 4 * 1024 * 1024;
13
+ const DEFAULT_MAX_SAMPLE_AGE_MS = 30_000;
14
+ const DEFAULT_MAX_CURSOR_DATABASES = 8;
15
+ const SESSION_CACHE_LIMIT = 128;
16
+ const codexTranscriptCache = new Map();
17
+ const cursorDatabaseCache = new Map();
18
+ /**
19
+ * Read privacy-safe context telemetry from a local runtime transcript.
20
+ *
21
+ * The returned union contains only numeric measurements, timestamps, bounded
22
+ * I/O counters, and a privacy-safe witness. Transcript bodies and paths never
23
+ * cross this interface.
24
+ */
25
+ export function readRuntimeContextTelemetry(request, options = {}) {
26
+ const startedAt = performance.now();
27
+ if (!request.session_id)
28
+ return unsupported("runtime_session_id_not_reported", startedAt);
29
+ if (request.mode !== "status" && !request.turn_id && request.adapter !== "cursor") {
30
+ return unsupported("runtime_turn_id_not_reported", startedAt);
31
+ }
32
+ if (request.adapter === "codex")
33
+ return readCodexContext(request, options, startedAt);
34
+ if (request.adapter === "claude-code")
35
+ return readClaudeContext(request, options, startedAt);
36
+ if (request.adapter === "cursor")
37
+ return readCursorContext(request, options, startedAt);
38
+ return unsupported("runtime_adapter_not_supported", startedAt);
39
+ }
40
+ /**
41
+ * Locate a Codex rollout transcript for a session when the hook payload
42
+ * carries no transcript_path. Codex omits the path on its hook events, which
43
+ * leaves transcript-backed evidence unavailable unless Harnery resolves the
44
+ * rollout itself. Discovery reuses the telemetry scanner's roots (native
45
+ * ~/.codex plus WSL-mounted Windows homes) and its process cache, and returns
46
+ * undefined on zero or ambiguous matches.
47
+ *
48
+ * Callers on repeated hook paths must retain the verified result in their
49
+ * owner-only session state. The process cache bounds repeated reads inside one
50
+ * process, but hook processes are intentionally short-lived.
51
+ */
52
+ export function discoverCodexSessionTranscript(sessionId, transcriptPath, options = {}) {
53
+ if (!sessionId || !/^[0-9a-f][0-9a-f-]{14,62}[0-9a-f]$/i.test(sessionId))
54
+ return undefined;
55
+ const resolution = resolveCodexTranscript({ adapter: "codex", session_id: sessionId, transcript_path: transcriptPath, mode: "status" }, options);
56
+ return resolution.state === "found" ? resolution.path : undefined;
57
+ }
58
+ /** Status compatibility wrapper: exact pairs render; partial values do not. */
59
+ export function readRuntimeContextUsage(adapter, sessionId, options = {}) {
60
+ const result = readRuntimeContextTelemetry({ adapter, session_id: sessionId, mode: "status" }, options);
61
+ return result.state === "observed" && "used_tokens" in result
62
+ ? { used: result.used_tokens, window: result.limit_tokens }
63
+ : null;
64
+ }
65
+ export function clearRuntimeTelemetryCachesForTest() {
66
+ codexTranscriptCache.clear();
67
+ cursorDatabaseCache.clear();
68
+ }
69
+ /**
70
+ * Read the newest observed tuning (effort, and speed where reported) for a
71
+ * session from its local runtime transcript.
72
+ *
73
+ * Codex: the newest `turn_context` row carries the EFFECTIVE per-turn effort,
74
+ * including `-c model_reasoning_effort` overrides (the config default is
75
+ * deliberately not consulted — it is the default, not the effective value).
76
+ * CC: the newest assistant row carries effort at the row's top level and
77
+ * speed inside `message.usage`; model, effort, and speed are read from the
78
+ * SAME row so a mid-session model swap cannot blend two rows' values.
79
+ *
80
+ * Same bounded tail-read and privacy posture as `readRuntimeContextTelemetry`:
81
+ * only tokens, timestamps, and I/O counters cross this interface.
82
+ */
83
+ export function readRuntimeTuning(request, options = {}) {
84
+ const startedAt = performance.now();
85
+ if (request.adapter === "codex") {
86
+ if (!request.session_id)
87
+ return unsupported("runtime_session_id_not_reported", startedAt);
88
+ return readCodexTuning(request, options, startedAt);
89
+ }
90
+ if (request.adapter === "claude-code")
91
+ return readClaudeTuning(request, options, startedAt);
92
+ return unsupported("runtime_adapter_not_supported", startedAt);
93
+ }
94
+ function readCodexTuning(request, options, startedAt) {
95
+ const resolved = resolveCodexTranscript({
96
+ adapter: "codex",
97
+ session_id: request.session_id,
98
+ transcript_path: request.transcript_path,
99
+ mode: "status",
100
+ }, options);
101
+ if (resolved.state === "missing") {
102
+ return unsupported("runtime_context_telemetry_unavailable", startedAt);
103
+ }
104
+ if (resolved.state === "ambiguous") {
105
+ return tuningPartial("codex_transcript_ambiguous", 0, startedAt);
106
+ }
107
+ if (resolved.state === "mismatch") {
108
+ return tuningPartial("codex_transcript_session_mismatch", 0, startedAt);
109
+ }
110
+ const tail = readTail(resolved.path, options.maxTailBytes ?? DEFAULT_TAIL_BYTES);
111
+ if (!tail)
112
+ return tuningPartial("codex_transcript_unreadable", 0, startedAt);
113
+ const fromTail = newestTurnContextTuning(parseRuntimeRows(tail.text), tail.bytes, startedAt);
114
+ if (fromTail)
115
+ return fromTail;
116
+ // `turn_context` is written at the START of a turn, so one long turn pushes
117
+ // it past the bounded tail. The front of the file is then the reliable
118
+ // place, but not a fixed-size head: a real interactive rollout opens with
119
+ // hundreds of KB of session_meta, instruction, and world_state rows before
120
+ // the first turn_context (observed live: 272KB in a desktop session). Scan
121
+ // forward in bounded chunks and keep the LAST match inside the cap; rows
122
+ // between the cap and the tail window stay unscanned, and the stop-time
123
+ // re-read heals any staleness that gap could cause.
124
+ const forward = scanForwardTurnContext(resolved.path, TUNING_FORWARD_SCAN_MAX_BYTES);
125
+ if (forward.row) {
126
+ const fromForward = newestTurnContextTuning([forward.row], tail.bytes + forward.bytes, startedAt);
127
+ if (fromForward)
128
+ return fromForward;
129
+ }
130
+ return tuningPartial("codex_transcript_turn_context_missing", tail.bytes + forward.bytes, startedAt);
131
+ }
132
+ /** Forward-scan budget for the first turn_context; generous against
133
+ * instruction/world_state bloat while still bounding a runaway file. */
134
+ const TUNING_FORWARD_SCAN_MAX_BYTES = 4 * 1024 * 1024;
135
+ const TUNING_FORWARD_CHUNK_BYTES = 256 * 1024;
136
+ /** Stream the file from the start in bounded chunks, returning the last
137
+ * parseable `turn_context` row inside the budget and the bytes read. */
138
+ function scanForwardTurnContext(path, maxBytes) {
139
+ let fd;
140
+ let bytesRead = 0;
141
+ let remainder = "";
142
+ let match;
143
+ try {
144
+ fd = openSync(path, "r");
145
+ const buffer = Buffer.alloc(TUNING_FORWARD_CHUNK_BYTES);
146
+ while (bytesRead < maxBytes) {
147
+ const read = readSync(fd, buffer, 0, buffer.length, bytesRead);
148
+ if (read <= 0)
149
+ break;
150
+ bytesRead += read;
151
+ const text = remainder + buffer.subarray(0, read).toString("utf8");
152
+ const lines = text.split("\n");
153
+ remainder = lines.pop() ?? "";
154
+ for (const line of lines) {
155
+ if (!line.includes('"turn_context"'))
156
+ continue;
157
+ const rows = parseRuntimeRows(line);
158
+ const row = rows.find((candidate) => candidate.type === "turn_context");
159
+ if (row)
160
+ match = row;
161
+ }
162
+ if (read < buffer.length)
163
+ break;
164
+ }
165
+ return { row: match, bytes: bytesRead };
166
+ }
167
+ catch {
168
+ return { row: match, bytes: bytesRead };
169
+ }
170
+ finally {
171
+ if (fd !== undefined)
172
+ closeSync(fd);
173
+ }
174
+ }
175
+ function newestTurnContextTuning(rows, bytesRead, startedAt) {
176
+ for (let index = rows.length - 1; index >= 0; index--) {
177
+ const row = rows[index];
178
+ if (row.type !== "turn_context")
179
+ continue;
180
+ const effort = row.payload?.effort;
181
+ const model = row.payload?.model;
182
+ if (typeof effort !== "string" || effort.length === 0)
183
+ continue;
184
+ return {
185
+ state: "observed",
186
+ effort,
187
+ ...(typeof model === "string" && model.length > 0 ? { model } : {}),
188
+ ...(row.timestamp ? { measured_at: row.timestamp } : {}),
189
+ method: "codex_transcript_turn_context",
190
+ source_event: "codex.rollout_turn_context",
191
+ bytes_read: bytesRead,
192
+ io_duration_ms: elapsed(startedAt),
193
+ };
194
+ }
195
+ return undefined;
196
+ }
197
+ function readClaudeTuning(request, options, startedAt) {
198
+ const readablePath = transcriptPathCandidates(request.transcript_path).find((candidate) => existsSync(candidate));
199
+ if (!readablePath)
200
+ return unsupported("runtime_context_telemetry_unavailable", startedAt);
201
+ const tail = readTail(readablePath, options.maxTailBytes ?? DEFAULT_TAIL_BYTES);
202
+ if (!tail)
203
+ return tuningPartial("claude_transcript_unreadable", 0, startedAt);
204
+ const rows = parseRuntimeRows(tail.text);
205
+ for (let index = rows.length - 1; index >= 0; index--) {
206
+ const row = rows[index];
207
+ if (row.type !== "assistant")
208
+ continue;
209
+ const model = row.payload?.model;
210
+ if (typeof model !== "string" || model.length === 0 || model.startsWith("<"))
211
+ continue;
212
+ const usage = objectValue(row.payload?.usage);
213
+ const speed = usage?.speed;
214
+ return {
215
+ state: "observed",
216
+ model,
217
+ ...(row.effort ? { effort: row.effort } : {}),
218
+ ...(typeof speed === "string" && speed.length > 0 ? { speed } : {}),
219
+ ...(row.timestamp ? { measured_at: row.timestamp } : {}),
220
+ method: "claude_transcript_assistant_row",
221
+ source_event: "claude-code.transcript_assistant_row",
222
+ bytes_read: tail.bytes,
223
+ io_duration_ms: elapsed(startedAt),
224
+ };
225
+ }
226
+ return tuningPartial("claude_transcript_assistant_row_missing", tail.bytes, startedAt);
227
+ }
228
+ function tuningPartial(reason, bytesRead, startedAt) {
229
+ return {
230
+ state: "partial",
231
+ reason,
232
+ bytes_read: bytesRead,
233
+ io_duration_ms: elapsed(startedAt),
234
+ };
235
+ }
236
+ function readCodexContext(request, options, startedAt) {
237
+ const resolved = resolveCodexTranscript(request, options);
238
+ if (resolved.state === "missing") {
239
+ return unsupported("runtime_context_telemetry_unavailable", startedAt);
240
+ }
241
+ if (resolved.state === "ambiguous") {
242
+ return partial("codex_transcript_ambiguous", 0, startedAt);
243
+ }
244
+ if (resolved.state === "mismatch") {
245
+ return partial("codex_transcript_session_mismatch", 0, startedAt);
246
+ }
247
+ const tail = readTail(resolved.path, options.maxTailBytes ??
248
+ (request.mode === "active_turn" ? ACTIVE_TURN_TAIL_BYTES : DEFAULT_TAIL_BYTES));
249
+ if (!tail)
250
+ return partial("codex_transcript_unreadable", 0, startedAt);
251
+ const rows = parseRuntimeRows(tail.text);
252
+ if (request.mode === "status") {
253
+ const token = newestCodexToken(rows);
254
+ return codexObservation(request, token, undefined, tail.bytes, options, startedAt);
255
+ }
256
+ if (request.mode === "active_turn") {
257
+ const active = tokenWithinActiveTurn(rows, request.turn_id);
258
+ const token = active.state === "found" ? active.token : tokenAtOrAfter(rows, request.turn_started_at);
259
+ if (active.state === "turn_missing" && !token) {
260
+ return partial("codex_transcript_turn_not_found", tail.bytes, startedAt);
261
+ }
262
+ return codexObservation(request, token, undefined, tail.bytes, options, startedAt);
263
+ }
264
+ const turnId = request.turn_id;
265
+ const terminalIndex = findCodexTurnTerminal(rows, turnId);
266
+ if (terminalIndex < 0) {
267
+ const sawStart = rows.some((row) => row.type === "event_msg" &&
268
+ row.payload?.type === "task_started" &&
269
+ row.payload.turn_id === turnId);
270
+ return partial(sawStart ? "codex_transcript_turn_not_terminal" : "codex_transcript_turn_not_found", tail.bytes, startedAt);
271
+ }
272
+ const terminal = rows[terminalIndex];
273
+ const token = tokenBeforeTerminal(rows, terminalIndex);
274
+ return codexObservation(request, token, terminal, tail.bytes, options, startedAt);
275
+ }
276
+ function codexObservation(request, token, terminal, bytesRead, options, startedAt) {
277
+ if (!token)
278
+ return partial("codex_transcript_token_count_missing", bytesRead, startedAt);
279
+ if (token.used_tokens === undefined) {
280
+ return partial("context_used_tokens_not_reported", bytesRead, startedAt);
281
+ }
282
+ if (token.limit_tokens === undefined) {
283
+ return partial("context_limit_tokens_not_reported", bytesRead, startedAt, token);
284
+ }
285
+ if (token.limit_tokens <= 0) {
286
+ return partial("context_limit_tokens_invalid", bytesRead, startedAt, token);
287
+ }
288
+ if (!token.measured_at || !Number.isFinite(Date.parse(token.measured_at))) {
289
+ return partial("codex_transcript_token_count_missing", bytesRead, startedAt);
290
+ }
291
+ if (terminal?.timestamp) {
292
+ const age = Date.parse(terminal.timestamp) - Date.parse(token.measured_at);
293
+ if (age < 0 || age > (options.maxSampleAgeMs ?? DEFAULT_MAX_SAMPLE_AGE_MS)) {
294
+ return partial("codex_transcript_sample_stale", bytesRead, startedAt, token);
295
+ }
296
+ }
297
+ if (request.mode === "active_turn" && request.observed_at) {
298
+ const age = Date.parse(request.observed_at) - Date.parse(token.measured_at);
299
+ if (!Number.isFinite(age) ||
300
+ age < -5_000 ||
301
+ age > (options.maxSampleAgeMs ?? DEFAULT_MAX_SAMPLE_AGE_MS)) {
302
+ return partial("codex_transcript_sample_stale", bytesRead, startedAt, token);
303
+ }
304
+ }
305
+ const witness = [
306
+ request.session_id,
307
+ request.turn_id ?? "status",
308
+ token.ordinal ?? "unknown",
309
+ token.measured_at,
310
+ token.used_tokens,
311
+ token.limit_tokens,
312
+ ].join("\0");
313
+ return {
314
+ state: "observed",
315
+ used_tokens: token.used_tokens,
316
+ limit_tokens: token.limit_tokens,
317
+ measured_at: token.measured_at,
318
+ method: "codex_transcript_token_count",
319
+ source_event: "codex.rollout_token_count",
320
+ source_witness: createHash("sha256").update(witness).digest("hex"),
321
+ attestation: "derived",
322
+ confidence: "exact",
323
+ bytes_read: bytesRead,
324
+ io_duration_ms: elapsed(startedAt),
325
+ };
326
+ }
327
+ function readClaudeContext(request, options, startedAt) {
328
+ const readablePath = transcriptPathCandidates(request.transcript_path).find((candidate) => existsSync(candidate));
329
+ if (!readablePath)
330
+ return unsupported("runtime_context_telemetry_unavailable", startedAt);
331
+ const tail = readTail(readablePath, options.maxTailBytes ??
332
+ (request.mode === "active_turn" ? ACTIVE_TURN_TAIL_BYTES : DEFAULT_TAIL_BYTES));
333
+ if (!tail)
334
+ return partial("claude_transcript_unreadable", 0, startedAt);
335
+ const rows = parseRuntimeRows(tail.text);
336
+ const sessionRows = rows.filter((row) => row.session_id === undefined || row.session_id === request.session_id);
337
+ if (rows.some((row) => row.session_id !== undefined) && sessionRows.length === 0) {
338
+ return partial("claude_transcript_session_mismatch", tail.bytes, startedAt);
339
+ }
340
+ const turnAttributed = request.mode === "turn" || request.mode === "active_turn";
341
+ const candidateRows = turnAttributed
342
+ ? claudeAssistantRowsForTurn(sessionRows, request.turn_id)
343
+ : sessionRows.filter((row) => row.type === "assistant");
344
+ if (turnAttributed && candidateRows.length === 0) {
345
+ return partial("claude_transcript_turn_not_found", tail.bytes, startedAt);
346
+ }
347
+ for (let index = candidateRows.length - 1; index >= 0; index--) {
348
+ const row = candidateRows[index];
349
+ if (row.type !== "assistant")
350
+ continue;
351
+ const message = row.payload;
352
+ const usage = objectValue(message?.usage);
353
+ if (!usage)
354
+ continue;
355
+ const used = sumNumbers(usage.input_tokens, usage.cache_creation_input_tokens, usage.cache_read_input_tokens);
356
+ if (used === undefined) {
357
+ return partial("context_used_tokens_not_reported", tail.bytes, startedAt);
358
+ }
359
+ const model = stringValue(message?.model);
360
+ const capability = model ? claudeModelContextCapability(model) : undefined;
361
+ if (capability && row.timestamp) {
362
+ if (request.mode === "active_turn" && request.observed_at) {
363
+ const age = Date.parse(request.observed_at) - Date.parse(row.timestamp);
364
+ if (!Number.isFinite(age) ||
365
+ age < -5_000 ||
366
+ age > (options.maxSampleAgeMs ?? DEFAULT_MAX_SAMPLE_AGE_MS)) {
367
+ return partial("claude_transcript_sample_stale", tail.bytes, startedAt, {
368
+ used_tokens: used,
369
+ measured_at: row.timestamp,
370
+ });
371
+ }
372
+ }
373
+ const witness = [
374
+ request.session_id,
375
+ request.turn_id ?? "status",
376
+ row.timestamp,
377
+ used,
378
+ model,
379
+ capability.limit_tokens,
380
+ capability.authority,
381
+ ].join("\0");
382
+ return {
383
+ state: "observed",
384
+ used_tokens: used,
385
+ limit_tokens: capability.limit_tokens,
386
+ measured_at: row.timestamp,
387
+ method: "claude_transcript_usage_model_capability",
388
+ source_event: "claude.transcript_usage_model_capability",
389
+ source_witness: createHash("sha256").update(witness).digest("hex"),
390
+ attestation: "inferred",
391
+ confidence: "high",
392
+ bytes_read: tail.bytes,
393
+ io_duration_ms: elapsed(startedAt),
394
+ };
395
+ }
396
+ return partial("claude_context_limit_tokens_not_reported", tail.bytes, startedAt, {
397
+ used_tokens: used,
398
+ measured_at: row.timestamp,
399
+ });
400
+ }
401
+ return partial("context_used_tokens_not_reported", tail.bytes, startedAt);
402
+ }
403
+ /**
404
+ * Versioned exact-name families from Anthropic's published model capability
405
+ * table. Unknown aliases deliberately stay missing: matching a product label
406
+ * or guessing from a family name would turn an estimate into fake precision.
407
+ */
408
+ function claudeModelContextCapability(model) {
409
+ const normalized = model.toLowerCase();
410
+ const oneMillionTokenModels = new Set([
411
+ "claude-fable-5",
412
+ "claude-opus-5",
413
+ "claude-sonnet-5",
414
+ "claude-opus-4-8",
415
+ "claude-opus-4-7",
416
+ "claude-opus-4-6",
417
+ "claude-sonnet-4-6",
418
+ ]);
419
+ if (oneMillionTokenModels.has(normalized)) {
420
+ return { limit_tokens: 1_000_000, authority: "anthropic_model_capabilities_2026_08" };
421
+ }
422
+ if (normalized === "claude-haiku-4-5" || normalized === "claude-haiku-4-5-20251001") {
423
+ return { limit_tokens: 200_000, authority: "anthropic_model_capabilities_2026_08" };
424
+ }
425
+ return undefined;
426
+ }
427
+ function readCursorContext(request, options, startedAt) {
428
+ const cached = cursorDatabaseCache.get(request.session_id);
429
+ if (cached && existsSync(cached)) {
430
+ const sample = readCursorDatabase(cached, request.session_id);
431
+ if (sample.state === "found") {
432
+ return cursorObservation(request, sample.sample, options, startedAt);
433
+ }
434
+ cursorDatabaseCache.delete(request.session_id);
435
+ }
436
+ const databases = cursorDatabasePaths(options);
437
+ if (databases.length === 0) {
438
+ return partial("cursor_context_database_unavailable", 0, startedAt);
439
+ }
440
+ const matches = [];
441
+ let bytesRead = 0;
442
+ let unreadable = 0;
443
+ for (const databasePath of databases) {
444
+ const result = readCursorDatabase(databasePath, request.session_id);
445
+ bytesRead += result.state === "found" ? result.sample.bytes_read : result.bytes_read;
446
+ if (result.state === "unreadable")
447
+ unreadable += 1;
448
+ if (result.state !== "found")
449
+ continue;
450
+ matches.push(result.sample);
451
+ }
452
+ if (matches.length === 0) {
453
+ return partial(unreadable === databases.length
454
+ ? "cursor_context_database_unreadable"
455
+ : "cursor_context_session_not_found", bytesRead, startedAt);
456
+ }
457
+ matches.sort((left, right) => Date.parse(right.measured_at) - Date.parse(left.measured_at));
458
+ const newest = matches[0];
459
+ const tied = matches.filter((sample) => sample.measured_at === newest.measured_at);
460
+ if (tied.some((sample) => sample.used_percent !== newest.used_percent)) {
461
+ return partial("cursor_context_sample_ambiguous", bytesRead, startedAt);
462
+ }
463
+ cacheCursorDatabase(request.session_id, newest.database_path);
464
+ return cursorObservation(request, newest, options, startedAt);
465
+ }
466
+ function cursorObservation(request, sample, options, startedAt) {
467
+ if (!Number.isFinite(sample.used_percent) ||
468
+ sample.used_percent < 0 ||
469
+ sample.used_percent > 100) {
470
+ return partial("cursor_context_usage_invalid", sample.bytes_read, startedAt);
471
+ }
472
+ const sampleMs = Date.parse(sample.measured_at);
473
+ if (!Number.isFinite(sampleMs)) {
474
+ return partial("cursor_context_sample_time_not_reported", sample.bytes_read, startedAt);
475
+ }
476
+ if ((request.mode === "turn" || request.mode === "active_turn") && request.observed_at) {
477
+ const observedMs = Date.parse(request.observed_at);
478
+ const age = observedMs - sampleMs;
479
+ if (!Number.isFinite(observedMs) ||
480
+ age < -5_000 ||
481
+ age > (options.maxSampleAgeMs ?? DEFAULT_MAX_SAMPLE_AGE_MS)) {
482
+ return partial("cursor_context_sample_stale", sample.bytes_read, startedAt);
483
+ }
484
+ }
485
+ const witness = [request.session_id, sample.measured_at, sample.used_percent].join("\0");
486
+ return {
487
+ state: "observed",
488
+ used_percent: sample.used_percent,
489
+ measured_at: sample.measured_at,
490
+ method: "cursor_composer_context_percent",
491
+ source_event: "cursor.composer_context_percent",
492
+ source_witness: createHash("sha256").update(witness).digest("hex"),
493
+ attestation: "derived",
494
+ confidence: "high",
495
+ bytes_read: sample.bytes_read,
496
+ io_duration_ms: elapsed(startedAt),
497
+ };
498
+ }
499
+ function readCursorDatabase(databasePath, sessionId) {
500
+ try {
501
+ // Bun is the primary hook runtime. Node fallback processes fail closed here
502
+ // instead of importing a Bun-only module at startup.
503
+ // eslint-disable-next-line @typescript-eslint/no-require-imports
504
+ const { Database } = require("bun:sqlite");
505
+ const database = new Database(databasePath, { readonly: true });
506
+ const row = database
507
+ .query("SELECT value FROM ItemTable WHERE key = 'composer.composerData'")
508
+ .get();
509
+ database.close();
510
+ if (!row?.value)
511
+ return { state: "missing", bytes_read: 0 };
512
+ const text = typeof row.value === "string" ? row.value : Buffer.from(row.value).toString("utf8");
513
+ const bytesRead = Buffer.byteLength(text);
514
+ const parsed = objectValue(JSON.parse(text));
515
+ const composers = Array.isArray(parsed?.allComposers) ? parsed.allComposers : [];
516
+ for (const candidate of composers) {
517
+ const composer = objectValue(candidate);
518
+ if (stringValue(composer?.composerId) !== sessionId)
519
+ continue;
520
+ const usedPercent = numberValue(composer?.contextUsagePercent);
521
+ if (usedPercent === undefined)
522
+ return { state: "missing", bytes_read: bytesRead };
523
+ const measuredAt = cursorMeasuredAt(composer?.lastUpdatedAt);
524
+ if (!measuredAt)
525
+ return { state: "missing", bytes_read: bytesRead };
526
+ return {
527
+ state: "found",
528
+ sample: {
529
+ used_percent: usedPercent,
530
+ measured_at: measuredAt,
531
+ bytes_read: bytesRead,
532
+ database_path: databasePath,
533
+ },
534
+ };
535
+ }
536
+ return { state: "missing", bytes_read: bytesRead };
537
+ }
538
+ catch {
539
+ return { state: "unreadable", bytes_read: 0 };
540
+ }
541
+ }
542
+ function cursorMeasuredAt(value) {
543
+ if (typeof value === "string" && Number.isFinite(Date.parse(value))) {
544
+ return new Date(value).toISOString();
545
+ }
546
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0)
547
+ return undefined;
548
+ const milliseconds = value < 10_000_000_000 ? value * 1_000 : value;
549
+ const date = new Date(milliseconds);
550
+ return Number.isFinite(date.getTime()) ? date.toISOString() : undefined;
551
+ }
552
+ function cursorDatabasePaths(options) {
553
+ const roots = options.cursorRoots ?? defaultCursorRoots();
554
+ const limit = Math.max(1, Math.floor(options.maxCursorDatabases ?? DEFAULT_MAX_CURSOR_DATABASES));
555
+ const candidates = [];
556
+ for (const root of roots) {
557
+ let names;
558
+ try {
559
+ names = readdirSync(root).sort();
560
+ }
561
+ catch {
562
+ continue;
563
+ }
564
+ for (const name of names) {
565
+ const databasePath = join(root, name, "state.vscdb");
566
+ try {
567
+ candidates.push({ path: databasePath, modified_ms: statSync(databasePath).mtimeMs });
568
+ }
569
+ catch {
570
+ // Removed or unreadable workspaces are not candidates.
571
+ }
572
+ }
573
+ }
574
+ return candidates
575
+ .sort((left, right) => right.modified_ms - left.modified_ms)
576
+ .slice(0, limit)
577
+ .map((candidate) => candidate.path);
578
+ }
579
+ function defaultCursorRoots() {
580
+ const roots = [resolve(homedir(), ".config", "Cursor", "User", "workspaceStorage")];
581
+ try {
582
+ if (existsSync("/mnt/c/Users")) {
583
+ for (const user of readdirSync("/mnt/c/Users")) {
584
+ roots.push(`/mnt/c/Users/${user}/AppData/Roaming/Cursor/User/workspaceStorage`);
585
+ }
586
+ }
587
+ }
588
+ catch {
589
+ // Non-WSL hosts do not expose this mount.
590
+ }
591
+ return roots;
592
+ }
593
+ function cacheCursorDatabase(sessionId, databasePath) {
594
+ cursorDatabaseCache.delete(sessionId);
595
+ cursorDatabaseCache.set(sessionId, databasePath);
596
+ while (cursorDatabaseCache.size > SESSION_CACHE_LIMIT) {
597
+ cursorDatabaseCache.delete(cursorDatabaseCache.keys().next().value);
598
+ }
599
+ }
600
+ /** Join assistant rows to the native CC prompt id through the transcript's
601
+ * parent UUID chain. No UUID or prompt value crosses the reader boundary. */
602
+ function claudeAssistantRowsForTurn(rows, turnId) {
603
+ const byUuid = new Map(rows.filter((row) => row.uuid).map((row) => [row.uuid, row]));
604
+ return rows.filter((row) => {
605
+ if (row.type !== "assistant")
606
+ return false;
607
+ let parentUuid = row.parent_uuid;
608
+ const seen = new Set();
609
+ for (let depth = 0; parentUuid && depth < 64 && !seen.has(parentUuid); depth += 1) {
610
+ seen.add(parentUuid);
611
+ const parent = byUuid.get(parentUuid);
612
+ if (!parent)
613
+ return false;
614
+ if (parent.type === "user" && parent.prompt_id)
615
+ return parent.prompt_id === turnId;
616
+ parentUuid = parent.parent_uuid;
617
+ }
618
+ return false;
619
+ });
620
+ }
621
+ function newestCodexToken(rows) {
622
+ for (let index = rows.length - 1; index >= 0; index--) {
623
+ const token = codexToken(rows[index]);
624
+ if (token)
625
+ return token;
626
+ }
627
+ return undefined;
628
+ }
629
+ function tokenWithinActiveTurn(rows, turnId) {
630
+ let startIndex = -1;
631
+ for (let index = rows.length - 1; index >= 0; index -= 1) {
632
+ const row = rows[index];
633
+ if (row.type === "event_msg" &&
634
+ row.payload?.type === "task_started" &&
635
+ row.payload.turn_id === turnId) {
636
+ startIndex = index;
637
+ break;
638
+ }
639
+ }
640
+ if (startIndex < 0)
641
+ return { state: "turn_missing" };
642
+ let token;
643
+ for (let index = startIndex + 1; index < rows.length; index += 1) {
644
+ const row = rows[index];
645
+ if (row.type === "event_msg" &&
646
+ (row.payload?.type === "task_started" || row.payload?.type === "task_complete")) {
647
+ break;
648
+ }
649
+ token = codexToken(row) ?? token;
650
+ }
651
+ return { state: "found", token };
652
+ }
653
+ function tokenAtOrAfter(rows, turnStartedAt) {
654
+ if (!turnStartedAt || !Number.isFinite(Date.parse(turnStartedAt)))
655
+ return undefined;
656
+ const token = newestCodexToken(rows);
657
+ if (!token?.measured_at)
658
+ return undefined;
659
+ return Date.parse(token.measured_at) >= Date.parse(turnStartedAt) ? token : undefined;
660
+ }
661
+ function tokenBeforeTerminal(rows, terminalIndex) {
662
+ for (let index = terminalIndex - 1; index >= 0; index--) {
663
+ const row = rows[index];
664
+ const type = row.payload?.type;
665
+ if (type === "task_started" || type === "task_complete")
666
+ break;
667
+ const token = codexToken(row);
668
+ if (token)
669
+ return token;
670
+ }
671
+ return undefined;
672
+ }
673
+ function codexToken(row) {
674
+ if (row.type !== "event_msg" || row.payload?.type !== "token_count")
675
+ return undefined;
676
+ const info = objectValue(row.payload.info);
677
+ const usage = objectValue(info?.last_token_usage);
678
+ return {
679
+ used_tokens: safeInteger(usage?.input_tokens),
680
+ limit_tokens: safeInteger(info?.model_context_window),
681
+ measured_at: timestamp(row.timestamp),
682
+ ordinal: safeInteger(row.ordinal),
683
+ };
684
+ }
685
+ function findCodexTurnTerminal(rows, turnId) {
686
+ for (let index = rows.length - 1; index >= 0; index--) {
687
+ const row = rows[index];
688
+ if (row.type === "event_msg" &&
689
+ row.payload?.type === "task_complete" &&
690
+ row.payload.turn_id === turnId) {
691
+ return index;
692
+ }
693
+ }
694
+ return -1;
695
+ }
696
+ function parseRuntimeRows(text) {
697
+ const rows = [];
698
+ for (const line of text.split("\n")) {
699
+ if (!line.trim())
700
+ continue;
701
+ try {
702
+ const value = JSON.parse(line);
703
+ const row = objectValue(value);
704
+ if (!row)
705
+ continue;
706
+ rows.push({
707
+ timestamp: timestamp(row.timestamp),
708
+ ordinal: safeInteger(row.ordinal),
709
+ type: typeof row.type === "string" ? row.type : undefined,
710
+ uuid: stringValue(row.uuid),
711
+ parent_uuid: stringValue(row.parentUuid),
712
+ prompt_id: stringValue(row.promptId) ?? stringValue(row.prompt_id),
713
+ session_id: stringValue(row.sessionId) ?? stringValue(row.session_id),
714
+ ...(typeof row.effort === "string" && row.effort.length > 0 ? { effort: row.effort } : {}),
715
+ payload: objectValue(row.payload) ?? objectValue(row.message) ?? undefined,
716
+ });
717
+ }
718
+ catch {
719
+ // The first line may be cut by the bounded tail or a writer may be mid-flush.
720
+ }
721
+ }
722
+ return rows;
723
+ }
724
+ function stringValue(value) {
725
+ return typeof value === "string" && value.length > 0 ? value : undefined;
726
+ }
727
+ function numberValue(value) {
728
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
729
+ }
730
+ function readTail(path, maxBytes) {
731
+ let fd;
732
+ try {
733
+ const size = statSync(path).size;
734
+ const bytes = Math.max(0, Math.min(size, Math.max(1, Math.floor(maxBytes))));
735
+ const start = size - bytes;
736
+ fd = openSync(path, "r");
737
+ const buffer = Buffer.alloc(bytes);
738
+ const read = readSync(fd, buffer, 0, bytes, start);
739
+ const text = buffer.subarray(0, read).toString("utf8");
740
+ return {
741
+ text: start > 0 ? text.slice(Math.max(0, text.indexOf("\n") + 1)) : text,
742
+ bytes: read,
743
+ };
744
+ }
745
+ catch {
746
+ return undefined;
747
+ }
748
+ finally {
749
+ if (fd !== undefined)
750
+ closeSync(fd);
751
+ }
752
+ }
753
+ function resolveCodexTranscript(request, options) {
754
+ const sessionId = request.session_id;
755
+ const cached = codexTranscriptCache.get(sessionId);
756
+ if (cached && existsSync(cached))
757
+ return { state: "found", path: cached };
758
+ const supplied = transcriptPathCandidates(request.transcript_path).filter((candidate) => existsSync(candidate));
759
+ const verifiedSupplied = supplied.filter((candidate) => transcriptMatches(candidate, sessionId));
760
+ if (verifiedSupplied.length === 1)
761
+ return cacheTranscript(sessionId, verifiedSupplied[0]);
762
+ if (verifiedSupplied.length > 1)
763
+ return { state: "ambiguous" };
764
+ if (supplied.length > 0)
765
+ return { state: "mismatch" };
766
+ const matches = codexRoots(options)
767
+ .flatMap((root) => findTranscriptMatches(root, sessionId))
768
+ .filter((path, index, values) => values.indexOf(path) === index);
769
+ if (matches.length === 1)
770
+ return cacheTranscript(sessionId, matches[0]);
771
+ if (matches.length > 1)
772
+ return { state: "ambiguous" };
773
+ return { state: "missing" };
774
+ }
775
+ function cacheTranscript(sessionId, path) {
776
+ codexTranscriptCache.delete(sessionId);
777
+ codexTranscriptCache.set(sessionId, path);
778
+ while (codexTranscriptCache.size > SESSION_CACHE_LIMIT) {
779
+ codexTranscriptCache.delete(codexTranscriptCache.keys().next().value);
780
+ }
781
+ return { state: "found", path };
782
+ }
783
+ function codexRoots(options) {
784
+ if (options.codexRoots)
785
+ return options.codexRoots;
786
+ const roots = [resolve(homedir(), ".codex", "sessions")];
787
+ try {
788
+ if (existsSync("/mnt/c/Users")) {
789
+ for (const user of readdirSync("/mnt/c/Users")) {
790
+ roots.push(`/mnt/c/Users/${user}/.codex/sessions`);
791
+ }
792
+ }
793
+ }
794
+ catch {
795
+ // Non-WSL hosts do not expose this mount.
796
+ }
797
+ return roots;
798
+ }
799
+ function findTranscriptMatches(root, sessionId) {
800
+ if (!existsSync(root))
801
+ return [];
802
+ const matches = [];
803
+ const stack = [{ path: root, depth: 0 }];
804
+ while (stack.length > 0) {
805
+ const current = stack.pop();
806
+ if (current.depth > 4)
807
+ continue;
808
+ let names;
809
+ try {
810
+ names = readdirSync(current.path);
811
+ }
812
+ catch {
813
+ continue;
814
+ }
815
+ for (const name of names) {
816
+ const path = join(current.path, name);
817
+ try {
818
+ const stat = statSync(path);
819
+ if (stat.isDirectory())
820
+ stack.push({ path, depth: current.depth + 1 });
821
+ else if (transcriptMatches(path, sessionId))
822
+ matches.push(path);
823
+ }
824
+ catch {
825
+ // A concurrently removed partition is simply unavailable.
826
+ }
827
+ }
828
+ }
829
+ return matches;
830
+ }
831
+ function transcriptMatches(path, sessionId) {
832
+ return basename(path).endsWith(`-${sessionId}.jsonl`);
833
+ }
834
+ /** Narrow return: this exact shape is a member of both telemetry unions. */
835
+ function unsupported(reason, startedAt) {
836
+ return { state: "unsupported", reason, bytes_read: 0, io_duration_ms: elapsed(startedAt) };
837
+ }
838
+ function partial(reason, bytesRead, startedAt, sample) {
839
+ return {
840
+ state: "partial",
841
+ reason,
842
+ ...(sample?.used_tokens !== undefined ? { used_tokens: sample.used_tokens } : {}),
843
+ ...(sample?.measured_at ? { measured_at: sample.measured_at } : {}),
844
+ bytes_read: bytesRead,
845
+ io_duration_ms: elapsed(startedAt),
846
+ };
847
+ }
848
+ function elapsed(startedAt) {
849
+ return Math.max(0, Math.round((performance.now() - startedAt) * 1000) / 1000);
850
+ }
851
+ function objectValue(value) {
852
+ return typeof value === "object" && value !== null && !Array.isArray(value)
853
+ ? value
854
+ : null;
855
+ }
856
+ function safeInteger(value) {
857
+ return typeof value === "number" && Number.isSafeInteger(value) && value >= 0 ? value : undefined;
858
+ }
859
+ function timestamp(value) {
860
+ if (typeof value !== "string" || !Number.isFinite(Date.parse(value)))
861
+ return undefined;
862
+ return new Date(value).toISOString();
863
+ }
864
+ function sumNumbers(...values) {
865
+ const numbers = values.map(safeInteger);
866
+ return numbers.some((value) => value !== undefined)
867
+ ? numbers.reduce((total, value) => total + (value ?? 0), 0)
868
+ : undefined;
869
+ }