@sentropic/h2a-cli 0.75.0 → 0.78.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 (350) hide show
  1. package/dist/index.d.ts +1 -37
  2. package/dist/index.d.ts.map +1 -1
  3. package/dist/index.js +2 -41
  4. package/dist/index.js.map +1 -1
  5. package/package.json +4 -15
  6. package/dist/bin.d.ts +0 -3
  7. package/dist/bin.d.ts.map +0 -1
  8. package/dist/bin.js +0 -83
  9. package/dist/bin.js.map +0 -1
  10. package/dist/cli-contract.d.ts +0 -62
  11. package/dist/cli-contract.d.ts.map +0 -1
  12. package/dist/cli-contract.js +0 -794
  13. package/dist/cli-contract.js.map +0 -1
  14. package/dist/cli.d.ts +0 -254
  15. package/dist/cli.d.ts.map +0 -1
  16. package/dist/cli.js +0 -4672
  17. package/dist/cli.js.map +0 -1
  18. package/dist/hosts/agy.d.ts +0 -14
  19. package/dist/hosts/agy.d.ts.map +0 -1
  20. package/dist/hosts/agy.js +0 -47
  21. package/dist/hosts/agy.js.map +0 -1
  22. package/dist/hosts/claude.d.ts +0 -12
  23. package/dist/hosts/claude.d.ts.map +0 -1
  24. package/dist/hosts/claude.js +0 -46
  25. package/dist/hosts/claude.js.map +0 -1
  26. package/dist/hosts/codex.d.ts +0 -65
  27. package/dist/hosts/codex.d.ts.map +0 -1
  28. package/dist/hosts/codex.js +0 -45
  29. package/dist/hosts/codex.js.map +0 -1
  30. package/dist/hosts/gemini.d.ts +0 -12
  31. package/dist/hosts/gemini.d.ts.map +0 -1
  32. package/dist/hosts/gemini.js +0 -46
  33. package/dist/hosts/gemini.js.map +0 -1
  34. package/dist/hosts/plugin.d.ts +0 -151
  35. package/dist/hosts/plugin.d.ts.map +0 -1
  36. package/dist/hosts/plugin.js +0 -188
  37. package/dist/hosts/plugin.js.map +0 -1
  38. package/dist/mcp.d.ts +0 -2
  39. package/dist/mcp.d.ts.map +0 -1
  40. package/dist/mcp.js +0 -32
  41. package/dist/mcp.js.map +0 -1
  42. package/dist/runtime/blockage/index.d.ts +0 -3
  43. package/dist/runtime/blockage/index.d.ts.map +0 -1
  44. package/dist/runtime/blockage/index.js +0 -3
  45. package/dist/runtime/blockage/index.js.map +0 -1
  46. package/dist/runtime/blockage/notifiers.d.ts +0 -52
  47. package/dist/runtime/blockage/notifiers.d.ts.map +0 -1
  48. package/dist/runtime/blockage/notifiers.js +0 -74
  49. package/dist/runtime/blockage/notifiers.js.map +0 -1
  50. package/dist/runtime/blockage/registry.d.ts +0 -30
  51. package/dist/runtime/blockage/registry.d.ts.map +0 -1
  52. package/dist/runtime/blockage/registry.js +0 -86
  53. package/dist/runtime/blockage/registry.js.map +0 -1
  54. package/dist/runtime/deploy/k8s-sidecar.d.ts +0 -92
  55. package/dist/runtime/deploy/k8s-sidecar.d.ts.map +0 -1
  56. package/dist/runtime/deploy/k8s-sidecar.js +0 -166
  57. package/dist/runtime/deploy/k8s-sidecar.js.map +0 -1
  58. package/dist/runtime/deploy/k8s-tenant.d.ts +0 -86
  59. package/dist/runtime/deploy/k8s-tenant.d.ts.map +0 -1
  60. package/dist/runtime/deploy/k8s-tenant.js +0 -255
  61. package/dist/runtime/deploy/k8s-tenant.js.map +0 -1
  62. package/dist/runtime/drive/inbox-wake.d.ts +0 -36
  63. package/dist/runtime/drive/inbox-wake.d.ts.map +0 -1
  64. package/dist/runtime/drive/inbox-wake.js +0 -50
  65. package/dist/runtime/drive/inbox-wake.js.map +0 -1
  66. package/dist/runtime/drive/index.d.ts +0 -173
  67. package/dist/runtime/drive/index.d.ts.map +0 -1
  68. package/dist/runtime/drive/index.js +0 -503
  69. package/dist/runtime/drive/index.js.map +0 -1
  70. package/dist/runtime/drumbeat/deciders.d.ts +0 -32
  71. package/dist/runtime/drumbeat/deciders.d.ts.map +0 -1
  72. package/dist/runtime/drumbeat/deciders.js +0 -65
  73. package/dist/runtime/drumbeat/deciders.js.map +0 -1
  74. package/dist/runtime/drumbeat/decisions.d.ts +0 -19
  75. package/dist/runtime/drumbeat/decisions.d.ts.map +0 -1
  76. package/dist/runtime/drumbeat/decisions.js +0 -34
  77. package/dist/runtime/drumbeat/decisions.js.map +0 -1
  78. package/dist/runtime/drumbeat/inbox-relance.d.ts +0 -29
  79. package/dist/runtime/drumbeat/inbox-relance.d.ts.map +0 -1
  80. package/dist/runtime/drumbeat/inbox-relance.js +0 -101
  81. package/dist/runtime/drumbeat/inbox-relance.js.map +0 -1
  82. package/dist/runtime/drumbeat/index.d.ts +0 -8
  83. package/dist/runtime/drumbeat/index.d.ts.map +0 -1
  84. package/dist/runtime/drumbeat/index.js +0 -8
  85. package/dist/runtime/drumbeat/index.js.map +0 -1
  86. package/dist/runtime/drumbeat/registry.d.ts +0 -60
  87. package/dist/runtime/drumbeat/registry.d.ts.map +0 -1
  88. package/dist/runtime/drumbeat/registry.js +0 -115
  89. package/dist/runtime/drumbeat/registry.js.map +0 -1
  90. package/dist/runtime/drumbeat/relaunchers.d.ts +0 -111
  91. package/dist/runtime/drumbeat/relaunchers.d.ts.map +0 -1
  92. package/dist/runtime/drumbeat/relaunchers.js +0 -260
  93. package/dist/runtime/drumbeat/relaunchers.js.map +0 -1
  94. package/dist/runtime/drumbeat/scan.d.ts +0 -36
  95. package/dist/runtime/drumbeat/scan.d.ts.map +0 -1
  96. package/dist/runtime/drumbeat/scan.js +0 -41
  97. package/dist/runtime/drumbeat/scan.js.map +0 -1
  98. package/dist/runtime/drumbeat/watch.d.ts +0 -74
  99. package/dist/runtime/drumbeat/watch.d.ts.map +0 -1
  100. package/dist/runtime/drumbeat/watch.js +0 -216
  101. package/dist/runtime/drumbeat/watch.js.map +0 -1
  102. package/dist/runtime/escalation/index.d.ts +0 -2
  103. package/dist/runtime/escalation/index.d.ts.map +0 -1
  104. package/dist/runtime/escalation/index.js +0 -2
  105. package/dist/runtime/escalation/index.js.map +0 -1
  106. package/dist/runtime/escalation/registry.d.ts +0 -44
  107. package/dist/runtime/escalation/registry.d.ts.map +0 -1
  108. package/dist/runtime/escalation/registry.js +0 -79
  109. package/dist/runtime/escalation/registry.js.map +0 -1
  110. package/dist/runtime/governance/claims.d.ts +0 -43
  111. package/dist/runtime/governance/claims.d.ts.map +0 -1
  112. package/dist/runtime/governance/claims.js +0 -93
  113. package/dist/runtime/governance/claims.js.map +0 -1
  114. package/dist/runtime/governance/conductor.d.ts +0 -79
  115. package/dist/runtime/governance/conductor.d.ts.map +0 -1
  116. package/dist/runtime/governance/conductor.js +0 -106
  117. package/dist/runtime/governance/conductor.js.map +0 -1
  118. package/dist/runtime/governance/index.d.ts +0 -5
  119. package/dist/runtime/governance/index.d.ts.map +0 -1
  120. package/dist/runtime/governance/index.js +0 -5
  121. package/dist/runtime/governance/index.js.map +0 -1
  122. package/dist/runtime/governance/launch-check.d.ts +0 -93
  123. package/dist/runtime/governance/launch-check.d.ts.map +0 -1
  124. package/dist/runtime/governance/launch-check.js +0 -113
  125. package/dist/runtime/governance/launch-check.js.map +0 -1
  126. package/dist/runtime/governance/spawns.d.ts +0 -50
  127. package/dist/runtime/governance/spawns.d.ts.map +0 -1
  128. package/dist/runtime/governance/spawns.js +0 -91
  129. package/dist/runtime/governance/spawns.js.map +0 -1
  130. package/dist/runtime/identity/bindings.d.ts +0 -84
  131. package/dist/runtime/identity/bindings.d.ts.map +0 -1
  132. package/dist/runtime/identity/bindings.js +0 -112
  133. package/dist/runtime/identity/bindings.js.map +0 -1
  134. package/dist/runtime/identity/index.d.ts +0 -11
  135. package/dist/runtime/identity/index.d.ts.map +0 -1
  136. package/dist/runtime/identity/index.js +0 -6
  137. package/dist/runtime/identity/index.js.map +0 -1
  138. package/dist/runtime/identity/live.d.ts +0 -26
  139. package/dist/runtime/identity/live.d.ts.map +0 -1
  140. package/dist/runtime/identity/live.js +0 -232
  141. package/dist/runtime/identity/live.js.map +0 -1
  142. package/dist/runtime/identity/migration.d.ts +0 -55
  143. package/dist/runtime/identity/migration.d.ts.map +0 -1
  144. package/dist/runtime/identity/migration.js +0 -100
  145. package/dist/runtime/identity/migration.js.map +0 -1
  146. package/dist/runtime/identity/readers.d.ts +0 -42
  147. package/dist/runtime/identity/readers.d.ts.map +0 -1
  148. package/dist/runtime/identity/readers.js +0 -248
  149. package/dist/runtime/identity/readers.js.map +0 -1
  150. package/dist/runtime/identity/resolver.d.ts +0 -50
  151. package/dist/runtime/identity/resolver.d.ts.map +0 -1
  152. package/dist/runtime/identity/resolver.js +0 -61
  153. package/dist/runtime/identity/resolver.js.map +0 -1
  154. package/dist/runtime/identity/workspace-id.d.ts +0 -43
  155. package/dist/runtime/identity/workspace-id.d.ts.map +0 -1
  156. package/dist/runtime/identity/workspace-id.js +0 -138
  157. package/dist/runtime/identity/workspace-id.js.map +0 -1
  158. package/dist/runtime/local-files/index.d.ts +0 -8
  159. package/dist/runtime/local-files/index.d.ts.map +0 -1
  160. package/dist/runtime/local-files/index.js +0 -8
  161. package/dist/runtime/local-files/index.js.map +0 -1
  162. package/dist/runtime/local-files/lease.d.ts +0 -62
  163. package/dist/runtime/local-files/lease.d.ts.map +0 -1
  164. package/dist/runtime/local-files/lease.js +0 -249
  165. package/dist/runtime/local-files/lease.js.map +0 -1
  166. package/dist/runtime/local-files/locks.d.ts +0 -43
  167. package/dist/runtime/local-files/locks.d.ts.map +0 -1
  168. package/dist/runtime/local-files/locks.js +0 -197
  169. package/dist/runtime/local-files/locks.js.map +0 -1
  170. package/dist/runtime/local-files/migrate.d.ts +0 -31
  171. package/dist/runtime/local-files/migrate.d.ts.map +0 -1
  172. package/dist/runtime/local-files/migrate.js +0 -104
  173. package/dist/runtime/local-files/migrate.js.map +0 -1
  174. package/dist/runtime/local-files/paths.d.ts +0 -146
  175. package/dist/runtime/local-files/paths.d.ts.map +0 -1
  176. package/dist/runtime/local-files/paths.js +0 -233
  177. package/dist/runtime/local-files/paths.js.map +0 -1
  178. package/dist/runtime/local-files/presence.d.ts +0 -80
  179. package/dist/runtime/local-files/presence.d.ts.map +0 -1
  180. package/dist/runtime/local-files/presence.js +0 -250
  181. package/dist/runtime/local-files/presence.js.map +0 -1
  182. package/dist/runtime/local-files/schema.d.ts +0 -47
  183. package/dist/runtime/local-files/schema.d.ts.map +0 -1
  184. package/dist/runtime/local-files/schema.js +0 -77
  185. package/dist/runtime/local-files/schema.js.map +0 -1
  186. package/dist/runtime/local-files/store.d.ts +0 -132
  187. package/dist/runtime/local-files/store.d.ts.map +0 -1
  188. package/dist/runtime/local-files/store.js +0 -997
  189. package/dist/runtime/local-files/store.js.map +0 -1
  190. package/dist/runtime/loop/index.d.ts +0 -73
  191. package/dist/runtime/loop/index.d.ts.map +0 -1
  192. package/dist/runtime/loop/index.js +0 -107
  193. package/dist/runtime/loop/index.js.map +0 -1
  194. package/dist/runtime/mcp/handlers.d.ts +0 -196
  195. package/dist/runtime/mcp/handlers.d.ts.map +0 -1
  196. package/dist/runtime/mcp/handlers.js +0 -1025
  197. package/dist/runtime/mcp/handlers.js.map +0 -1
  198. package/dist/runtime/mcp/index.d.ts +0 -7
  199. package/dist/runtime/mcp/index.d.ts.map +0 -1
  200. package/dist/runtime/mcp/index.js +0 -7
  201. package/dist/runtime/mcp/index.js.map +0 -1
  202. package/dist/runtime/mcp/notifications.d.ts +0 -47
  203. package/dist/runtime/mcp/notifications.d.ts.map +0 -1
  204. package/dist/runtime/mcp/notifications.js +0 -204
  205. package/dist/runtime/mcp/notifications.js.map +0 -1
  206. package/dist/runtime/mcp/server.d.ts +0 -45
  207. package/dist/runtime/mcp/server.d.ts.map +0 -1
  208. package/dist/runtime/mcp/server.js +0 -94
  209. package/dist/runtime/mcp/server.js.map +0 -1
  210. package/dist/runtime/mcp/sessions.d.ts +0 -68
  211. package/dist/runtime/mcp/sessions.d.ts.map +0 -1
  212. package/dist/runtime/mcp/sessions.js +0 -152
  213. package/dist/runtime/mcp/sessions.js.map +0 -1
  214. package/dist/runtime/mcp/stdio.d.ts +0 -72
  215. package/dist/runtime/mcp/stdio.d.ts.map +0 -1
  216. package/dist/runtime/mcp/stdio.js +0 -274
  217. package/dist/runtime/mcp/stdio.js.map +0 -1
  218. package/dist/runtime/mcp/tools.d.ts +0 -19
  219. package/dist/runtime/mcp/tools.d.ts.map +0 -1
  220. package/dist/runtime/mcp/tools.js +0 -525
  221. package/dist/runtime/mcp/tools.js.map +0 -1
  222. package/dist/runtime/mcp-http/app.d.ts +0 -33
  223. package/dist/runtime/mcp-http/app.d.ts.map +0 -1
  224. package/dist/runtime/mcp-http/app.js +0 -162
  225. package/dist/runtime/mcp-http/app.js.map +0 -1
  226. package/dist/runtime/mcp-http/hosted-mcp-server.d.ts +0 -14
  227. package/dist/runtime/mcp-http/hosted-mcp-server.d.ts.map +0 -1
  228. package/dist/runtime/mcp-http/hosted-mcp-server.js +0 -38
  229. package/dist/runtime/mcp-http/hosted-mcp-server.js.map +0 -1
  230. package/dist/runtime/mcp-http/index.d.ts +0 -18
  231. package/dist/runtime/mcp-http/index.d.ts.map +0 -1
  232. package/dist/runtime/mcp-http/index.js +0 -18
  233. package/dist/runtime/mcp-http/index.js.map +0 -1
  234. package/dist/runtime/mcp-http/main.d.ts +0 -2
  235. package/dist/runtime/mcp-http/main.d.ts.map +0 -1
  236. package/dist/runtime/mcp-http/main.js +0 -14
  237. package/dist/runtime/mcp-http/main.js.map +0 -1
  238. package/dist/runtime/mcp-http/oauth/broker-login.d.ts +0 -50
  239. package/dist/runtime/mcp-http/oauth/broker-login.d.ts.map +0 -1
  240. package/dist/runtime/mcp-http/oauth/broker-login.js +0 -41
  241. package/dist/runtime/mcp-http/oauth/broker-login.js.map +0 -1
  242. package/dist/runtime/mcp-http/oauth/broker-routes.d.ts +0 -45
  243. package/dist/runtime/mcp-http/oauth/broker-routes.d.ts.map +0 -1
  244. package/dist/runtime/mcp-http/oauth/broker-routes.js +0 -54
  245. package/dist/runtime/mcp-http/oauth/broker-routes.js.map +0 -1
  246. package/dist/runtime/mcp-http/oauth/config.d.ts +0 -49
  247. package/dist/runtime/mcp-http/oauth/config.d.ts.map +0 -1
  248. package/dist/runtime/mcp-http/oauth/config.js +0 -69
  249. package/dist/runtime/mcp-http/oauth/config.js.map +0 -1
  250. package/dist/runtime/mcp-http/oauth/crypto.d.ts +0 -14
  251. package/dist/runtime/mcp-http/oauth/crypto.d.ts.map +0 -1
  252. package/dist/runtime/mcp-http/oauth/crypto.js +0 -29
  253. package/dist/runtime/mcp-http/oauth/crypto.js.map +0 -1
  254. package/dist/runtime/mcp-http/oauth/file-store.d.ts +0 -48
  255. package/dist/runtime/mcp-http/oauth/file-store.d.ts.map +0 -1
  256. package/dist/runtime/mcp-http/oauth/file-store.js +0 -101
  257. package/dist/runtime/mcp-http/oauth/file-store.js.map +0 -1
  258. package/dist/runtime/mcp-http/oauth/hono-oauth-router.d.ts +0 -5
  259. package/dist/runtime/mcp-http/oauth/hono-oauth-router.d.ts.map +0 -1
  260. package/dist/runtime/mcp-http/oauth/hono-oauth-router.js +0 -92
  261. package/dist/runtime/mcp-http/oauth/hono-oauth-router.js.map +0 -1
  262. package/dist/runtime/mcp-http/oauth/oidc-rp.d.ts +0 -56
  263. package/dist/runtime/mcp-http/oauth/oidc-rp.d.ts.map +0 -1
  264. package/dist/runtime/mcp-http/oauth/oidc-rp.js +0 -63
  265. package/dist/runtime/mcp-http/oauth/oidc-rp.js.map +0 -1
  266. package/dist/runtime/mcp-http/oauth/redirect-uri.d.ts +0 -11
  267. package/dist/runtime/mcp-http/oauth/redirect-uri.d.ts.map +0 -1
  268. package/dist/runtime/mcp-http/oauth/redirect-uri.js +0 -29
  269. package/dist/runtime/mcp-http/oauth/redirect-uri.js.map +0 -1
  270. package/dist/runtime/mcp-http/oauth/single-tenant-provider.d.ts +0 -70
  271. package/dist/runtime/mcp-http/oauth/single-tenant-provider.d.ts.map +0 -1
  272. package/dist/runtime/mcp-http/oauth/single-tenant-provider.js +0 -247
  273. package/dist/runtime/mcp-http/oauth/single-tenant-provider.js.map +0 -1
  274. package/dist/runtime/mcp-http/oauth/tenancy.d.ts +0 -3
  275. package/dist/runtime/mcp-http/oauth/tenancy.d.ts.map +0 -1
  276. package/dist/runtime/mcp-http/oauth/tenancy.js +0 -18
  277. package/dist/runtime/mcp-http/oauth/tenancy.js.map +0 -1
  278. package/dist/runtime/mcp-http/readonly-allowlist.d.ts +0 -24
  279. package/dist/runtime/mcp-http/readonly-allowlist.d.ts.map +0 -1
  280. package/dist/runtime/mcp-http/readonly-allowlist.js +0 -43
  281. package/dist/runtime/mcp-http/readonly-allowlist.js.map +0 -1
  282. package/dist/runtime/mcp-http/serve.d.ts +0 -39
  283. package/dist/runtime/mcp-http/serve.d.ts.map +0 -1
  284. package/dist/runtime/mcp-http/serve.js +0 -100
  285. package/dist/runtime/mcp-http/serve.js.map +0 -1
  286. package/dist/runtime/mirror/accept.d.ts +0 -57
  287. package/dist/runtime/mirror/accept.d.ts.map +0 -1
  288. package/dist/runtime/mirror/accept.js +0 -70
  289. package/dist/runtime/mirror/accept.js.map +0 -1
  290. package/dist/runtime/mirror/build.d.ts +0 -44
  291. package/dist/runtime/mirror/build.d.ts.map +0 -1
  292. package/dist/runtime/mirror/build.js +0 -37
  293. package/dist/runtime/mirror/build.js.map +0 -1
  294. package/dist/runtime/mirror/index.d.ts +0 -9
  295. package/dist/runtime/mirror/index.d.ts.map +0 -1
  296. package/dist/runtime/mirror/index.js +0 -9
  297. package/dist/runtime/mirror/index.js.map +0 -1
  298. package/dist/runtime/mirror/serve.d.ts +0 -21
  299. package/dist/runtime/mirror/serve.d.ts.map +0 -1
  300. package/dist/runtime/mirror/serve.js +0 -141
  301. package/dist/runtime/mirror/serve.js.map +0 -1
  302. package/dist/runtime/nhi.d.ts +0 -15
  303. package/dist/runtime/nhi.d.ts.map +0 -1
  304. package/dist/runtime/nhi.js +0 -26
  305. package/dist/runtime/nhi.js.map +0 -1
  306. package/dist/runtime/remote/accept.d.ts +0 -50
  307. package/dist/runtime/remote/accept.d.ts.map +0 -1
  308. package/dist/runtime/remote/accept.js +0 -54
  309. package/dist/runtime/remote/accept.js.map +0 -1
  310. package/dist/runtime/remote/client.d.ts +0 -27
  311. package/dist/runtime/remote/client.d.ts.map +0 -1
  312. package/dist/runtime/remote/client.js +0 -34
  313. package/dist/runtime/remote/client.js.map +0 -1
  314. package/dist/runtime/remote/index.d.ts +0 -5
  315. package/dist/runtime/remote/index.d.ts.map +0 -1
  316. package/dist/runtime/remote/index.js +0 -5
  317. package/dist/runtime/remote/index.js.map +0 -1
  318. package/dist/runtime/remote/serve.d.ts +0 -27
  319. package/dist/runtime/remote/serve.d.ts.map +0 -1
  320. package/dist/runtime/remote/serve.js +0 -26
  321. package/dist/runtime/remote/serve.js.map +0 -1
  322. package/dist/runtime/remote/server.d.ts +0 -36
  323. package/dist/runtime/remote/server.d.ts.map +0 -1
  324. package/dist/runtime/remote/server.js +0 -100
  325. package/dist/runtime/remote/server.js.map +0 -1
  326. package/dist/runtime/sysml/client.d.ts +0 -44
  327. package/dist/runtime/sysml/client.d.ts.map +0 -1
  328. package/dist/runtime/sysml/client.js +0 -52
  329. package/dist/runtime/sysml/client.js.map +0 -1
  330. package/dist/runtime/sysml/disclosure.d.ts +0 -23
  331. package/dist/runtime/sysml/disclosure.d.ts.map +0 -1
  332. package/dist/runtime/sysml/disclosure.js +0 -53
  333. package/dist/runtime/sysml/disclosure.js.map +0 -1
  334. package/dist/runtime/sysml/index.d.ts +0 -4
  335. package/dist/runtime/sysml/index.d.ts.map +0 -1
  336. package/dist/runtime/sysml/index.js +0 -4
  337. package/dist/runtime/sysml/index.js.map +0 -1
  338. package/dist/runtime/sysml/verify.d.ts +0 -32
  339. package/dist/runtime/sysml/verify.d.ts.map +0 -1
  340. package/dist/runtime/sysml/verify.js +0 -67
  341. package/dist/runtime/sysml/verify.js.map +0 -1
  342. package/dist/runtime/upgrade/index.d.ts +0 -96
  343. package/dist/runtime/upgrade/index.d.ts.map +0 -1
  344. package/dist/runtime/upgrade/index.js +0 -185
  345. package/dist/runtime/upgrade/index.js.map +0 -1
  346. package/dist/runtime/version/agent-version.d.ts +0 -15
  347. package/dist/runtime/version/agent-version.d.ts.map +0 -1
  348. package/dist/runtime/version/agent-version.js +0 -53
  349. package/dist/runtime/version/agent-version.js.map +0 -1
  350. package/skills/h2a/SKILL.md +0 -345
@@ -1,260 +0,0 @@
1
- /**
2
- * Drumbeat relauncher adapters (DEC-091, slice D3). D2 shipped the dumb daemon
3
- * + the `H2ARelauncher` interface with only a logging adapter; D3 supplies the
4
- * two **local** adapters that actually revive a stalled agent:
5
- *
6
- * - **local-tmux**: `tmux send-keys` the resume/launch command into the pane
7
- * captured at launch (DEC-085 `launchContext.tmux`). The natural revive for a
8
- * user-local agent — it lands back in its original terminal.
9
- * - **headless**: detached background respawn of the captured command + a
10
- * notification (the PRINCIPAL escalation is wired fully in D7).
11
- *
12
- * `chainRelauncher` composes them (try tmux, fall back to headless) — the
13
- * "local-tmux adapter + headless fallback" of D3. The actual process I/O is
14
- * behind an injectable `RelauncherRuntime` so the adapters are unit-testable
15
- * with no real tmux or child processes. The remote adapter is D4.
16
- */
17
- import { spawn, spawnSync } from "node:child_process";
18
- import { randomBytes } from "node:crypto";
19
- import { H2A_DRUMBEAT_RESUME_BODY_KIND, createEnvelope } from "@sentropic/h2a";
20
- import { createLocalStore } from "../local-files/store.js";
21
- import { sendRemoteEnvelope } from "../remote/client.js";
22
- export const defaultRelauncherRuntime = {
23
- run(file, args) {
24
- const res = spawnSync(file, [...args], { stdio: "ignore" });
25
- return res.status === 0;
26
- },
27
- capture(file, args) {
28
- try {
29
- const res = spawnSync(file, [...args], {
30
- encoding: "utf8",
31
- stdio: ["ignore", "pipe", "ignore"]
32
- });
33
- return res.status === 0 ? res.stdout : undefined;
34
- }
35
- catch {
36
- return undefined;
37
- }
38
- },
39
- spawnDetached(command, options) {
40
- try {
41
- const child = typeof command === "string"
42
- ? spawn(command, {
43
- cwd: options.cwd,
44
- shell: true,
45
- detached: true,
46
- stdio: "ignore"
47
- })
48
- : spawn(command.file, [...command.args], {
49
- cwd: command.cwd ?? options.cwd,
50
- detached: true,
51
- stdio: "ignore"
52
- });
53
- child.unref();
54
- return child.pid !== undefined;
55
- }
56
- catch {
57
- return false;
58
- }
59
- }
60
- };
61
- const deferredRelaunchers = new WeakSet();
62
- function markDeferred(relauncher, deferred) {
63
- if (deferred) {
64
- deferredRelaunchers.add(relauncher);
65
- }
66
- else {
67
- deferredRelaunchers.delete(relauncher);
68
- }
69
- }
70
- /**
71
- * Build a tmux target-pane spec from a captured `launchContext.tmux`. With a
72
- * window it is `session:window.pane`; otherwise the pane is assumed to be a
73
- * unique tmux pane id (`%N`, captured via `#{pane_id}` by the D6 plugins) and
74
- * targeted directly.
75
- */
76
- export function tmuxTarget(t) {
77
- return t.window !== undefined ? `${t.session}:${t.window}.${t.pane}` : t.pane;
78
- }
79
- /**
80
- * Type `text` into a tmux pane AND submit it. Sends the text literally (`-l`, so
81
- * spaces / special chars aren't interpreted as tmux key names) then Enter as a
82
- * SEPARATE send-keys. A combined `send-keys "text" Enter` (or one without `-l`)
83
- * leaves the line in the input but **never commits** on modern TUIs
84
- * (codex/claude) — the bug behind "the line is written but no Enter fires". A
85
- * second Enter covers TUIs that buffer the first. The single shared submit path
86
- * for both the drumbeat relauncher and the EVO-1 wake/drive local-tmux driver.
87
- */
88
- export function tmuxSendSubmit(runtime, target, text) {
89
- const typed = runtime.run("tmux", ["send-keys", "-t", target, "-l", text]);
90
- const enter1 = runtime.run("tmux", ["send-keys", "-t", target, "Enter"]);
91
- const enter2 = runtime.run("tmux", ["send-keys", "-t", target, "Enter"]);
92
- return typed && enter1 && enter2;
93
- }
94
- /**
95
- * Default window (ms): if a tmux client attached to the pane's session was
96
- * active within this window, a wake/relance is DEFERRED so it does not clobber
97
- * a human typing in the pane. Override via `H2A_WAKE_DEFER_ACTIVITY_MS` (0 = off).
98
- */
99
- export const H2A_WAKE_DEFER_ACTIVITY_DEFAULT_MS = 4000;
100
- function activityWindowMs() {
101
- const raw = process.env.H2A_WAKE_DEFER_ACTIVITY_MS;
102
- if (raw !== undefined) {
103
- const n = Number.parseInt(raw, 10);
104
- if (Number.isFinite(n) && n >= 0)
105
- return n;
106
- }
107
- return H2A_WAKE_DEFER_ACTIVITY_DEFAULT_MS;
108
- }
109
- /**
110
- * True iff a tmux CLIENT attached to `target`'s session had activity within the
111
- * defer window — i.e. a human is (probably) typing/looking RIGHT NOW, so a wake
112
- * that types into the pane would clobber their in-progress input. TUI-agnostic
113
- * (uses tmux `client_activity`, not any TUI's composer state). Fail-OPEN: if the
114
- * probe can't be read (no `capture`, no tmux, detached/no client), returns false
115
- * so waking still works — the guard only fires on a POSITIVE recent-activity read.
116
- */
117
- export function paneHasRecentHumanActivity(runtime, target, opts = {}) {
118
- if (!runtime.capture)
119
- return false;
120
- const windowMs = opts.windowMs ?? activityWindowMs();
121
- if (windowMs <= 0)
122
- return false; // disabled
123
- const now = opts.now ?? Date.now();
124
- const sessionRaw = runtime.capture("tmux", [
125
- "display-message",
126
- "-p",
127
- "-t",
128
- target,
129
- "#{session_name}"
130
- ]);
131
- const session = sessionRaw?.trim();
132
- if (!session)
133
- return false;
134
- const clientsRaw = runtime.capture("tmux", [
135
- "list-clients",
136
- "-t",
137
- `=${session}`,
138
- "-F",
139
- "#{client_activity}"
140
- ]);
141
- if (!clientsRaw)
142
- return false; // no attached client → no human → don't defer
143
- let mostRecentSec = 0;
144
- for (const line of clientsRaw.split("\n")) {
145
- const epoch = Number.parseInt(line.trim(), 10);
146
- if (Number.isFinite(epoch) && epoch > mostRecentSec)
147
- mostRecentSec = epoch;
148
- }
149
- if (mostRecentSec === 0)
150
- return false;
151
- const ageMs = now - mostRecentSec * 1000; // client_activity is epoch SECONDS
152
- return ageMs >= 0 && ageMs < windowMs;
153
- }
154
- /** Revive a stalled agent by sending its resume/launch command into its pane. */
155
- export function localTmuxRelauncher(options = {}) {
156
- const runtime = options.runtime ?? defaultRelauncherRuntime;
157
- const relauncher = {
158
- relance(finding) {
159
- markDeferred(relauncher, false);
160
- const lc = finding.launchContext;
161
- if (!lc?.tmux)
162
- return false; // not a tmux-launched agent — let the chain fall through
163
- const command = lc.resumeCommand ?? lc.command;
164
- const target = tmuxTarget(lc.tmux);
165
- if (paneHasRecentHumanActivity(runtime, target)) {
166
- markDeferred(relauncher, true);
167
- options.log?.(`drumbeat[local-tmux]: relance ${finding.instance} → ${target} DEFERRED (human active in pane)`);
168
- return false;
169
- }
170
- // literal command + separate Enter(s) — a combined `send-keys cmd Enter`
171
- // doesn't commit in a TUI (the reported "line written, no Enter") and
172
- // without -l the command keys can be misread as tmux key names.
173
- const ok = tmuxSendSubmit(runtime, target, command);
174
- options.log?.(`drumbeat[local-tmux]: relance ${finding.instance} → tmux send-keys -t ${target} (${ok ? "ok" : "failed"})`);
175
- return ok;
176
- }
177
- };
178
- return relauncher;
179
- }
180
- /** Fallback: detached background respawn of the captured command + notify. */
181
- export function headlessRelauncher(options = {}) {
182
- const runtime = options.runtime ?? defaultRelauncherRuntime;
183
- return {
184
- relance(finding) {
185
- const lc = finding.launchContext;
186
- const command = lc?.resumeCommand ?? lc?.command;
187
- if (!command)
188
- return false; // nothing to respawn
189
- const ok = runtime.spawnDetached(command, { cwd: lc?.cwd });
190
- const note = `drumbeat[headless]: relance ${finding.instance} → detached "${command}" (${ok ? "spawned" : "failed"})`;
191
- options.log?.(note);
192
- runtime.notify?.(note);
193
- return ok;
194
- }
195
- };
196
- }
197
- /** Try each adapter in order; the first to issue a relance wins (D3 fallback). */
198
- export function chainRelauncher(...relaunchers) {
199
- return {
200
- async relance(finding) {
201
- for (const r of relaunchers) {
202
- if (await r.relance(finding))
203
- return true;
204
- if (deferredRelaunchers.has(r))
205
- return false;
206
- }
207
- return false;
208
- }
209
- };
210
- }
211
- function envelopeId(now) {
212
- return `env:${now}:${randomBytes(4).toString("hex")}`;
213
- }
214
- /**
215
- * D4 remote adapter: sign a `drumbeat.resume` envelope and deliver it to the
216
- * target instance's declared remote endpoint. It never executes remote code.
217
- */
218
- export function remoteRelauncher(options) {
219
- const store = options.root ? createLocalStore({ root: options.root }) : undefined;
220
- const resolveEndpoint = options.resolveEndpoint ??
221
- ((instance) => store?.findInstance(instance)?.endpoints.find((e) => e.kind === "remote")?.uri);
222
- const sendImpl = options.sendImpl ?? sendRemoteEnvelope;
223
- return {
224
- async relance(finding) {
225
- const endpoint = await resolveEndpoint(finding.instance);
226
- if (!endpoint) {
227
- options.log?.(`drumbeat[remote]: no remote endpoint for ${finding.instance}`);
228
- return false;
229
- }
230
- const now = options.now?.() ?? Date.now();
231
- const envelope = createEnvelope({
232
- id: envelopeId(now),
233
- type: "event",
234
- actor: options.actor,
235
- target: { instance: finding.instance },
236
- body: {
237
- kind: H2A_DRUMBEAT_RESUME_BODY_KIND,
238
- target: finding.instance,
239
- reason: finding.reason,
240
- requestedBy: options.actor.instance
241
- },
242
- createdAt: new Date(now).toISOString()
243
- });
244
- try {
245
- const result = await sendImpl(endpoint, envelope, {
246
- by: options.actor.instance,
247
- privateKeyPem: options.privateKeyPem
248
- });
249
- const ok = result.status >= 200 && result.status < 300;
250
- options.log?.(`drumbeat[remote]: relay ${finding.instance} -> ${endpoint} (${result.status}${ok ? " ok" : " failed"})`);
251
- return ok;
252
- }
253
- catch (error) {
254
- options.log?.(`drumbeat[remote]: relay ${finding.instance} -> ${endpoint} failed (${error.message})`);
255
- return false;
256
- }
257
- }
258
- };
259
- }
260
- //# sourceMappingURL=relaunchers.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"relaunchers.js","sourceRoot":"","sources":["../../../src/runtime/drumbeat/relaunchers.ts"],"names":[],"mappings":"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"}
@@ -1,36 +0,0 @@
1
- /**
2
- * Drumbeat scan (DEC-086, slice D2). Reads the durable registry and decides,
3
- * per stopped agent, whether it is a relance candidate, has exhausted its
4
- * relance budget (→ escalate, D7), or finished (→ ignore/clear).
5
- */
6
- import type { H2AWorkStatus } from "@sentropic/h2a";
7
- import { type H2ADrumbeatEntry } from "./registry.js";
8
- /** Default number of relances before escalating to the PRINCIPAL (DEC-084). */
9
- export declare const H2A_DEFAULT_MAX_RELANCES = 3;
10
- export type H2ADrumbeatReason = "stopped" | "out-of-tokens";
11
- export interface H2ADrumbeatFinding {
12
- readonly instance: string;
13
- readonly reason: H2ADrumbeatReason;
14
- readonly workStatus: H2AWorkStatus;
15
- readonly launchContext?: H2ADrumbeatEntry["launchContext"];
16
- readonly relanceCount: number;
17
- }
18
- export interface H2ADrumbeatScanResult {
19
- /** Stopped agents that should be relanced. */
20
- readonly findings: readonly H2ADrumbeatFinding[];
21
- /** Entries that hit the relance cap — hand to escalation (D7). */
22
- readonly exhausted: readonly H2ADrumbeatEntry[];
23
- }
24
- export interface ScanDrumbeatOptions {
25
- readonly maxRelances?: number;
26
- /** Instances already handled by a pre-scan D4 inbox consume pass. */
27
- readonly skipInstances?: readonly string[];
28
- }
29
- /**
30
- * Classify the registry: `done` entries are skipped (a clean finish);
31
- * entries at/over `maxRelances` are `exhausted` (escalate, don't loop);
32
- * everything else is a relance `finding` (reason `out-of-tokens` when that is
33
- * the recorded status, else `stopped`).
34
- */
35
- export declare function scanDrumbeat(root: string, options?: ScanDrumbeatOptions): H2ADrumbeatScanResult;
36
- //# sourceMappingURL=scan.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scan.d.ts","sourceRoot":"","sources":["../../../src/runtime/drumbeat/scan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gBAAgB,CAAC;AAEpD,OAAO,EAAgB,KAAK,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAEpE,+EAA+E;AAC/E,eAAO,MAAM,wBAAwB,IAAI,CAAC;AAE1C,MAAM,MAAM,iBAAiB,GAAG,SAAS,GAAG,eAAe,CAAC;AAE5D,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,UAAU,EAAE,aAAa,CAAC;IACnC,QAAQ,CAAC,aAAa,CAAC,EAAE,gBAAgB,CAAC,eAAe,CAAC,CAAC;IAC3D,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;CAC/B;AAED,MAAM,WAAW,qBAAqB;IACpC,8CAA8C;IAC9C,QAAQ,CAAC,QAAQ,EAAE,SAAS,kBAAkB,EAAE,CAAC;IACjD,kEAAkE;IAClE,QAAQ,CAAC,SAAS,EAAE,SAAS,gBAAgB,EAAE,CAAC;CACjD;AAED,MAAM,WAAW,mBAAmB;IAClC,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;IAC9B,qEAAqE;IACrE,QAAQ,CAAC,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CAC5C;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAC1B,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,mBAAwB,GAChC,qBAAqB,CAsBvB"}
@@ -1,41 +0,0 @@
1
- /**
2
- * Drumbeat scan (DEC-086, slice D2). Reads the durable registry and decides,
3
- * per stopped agent, whether it is a relance candidate, has exhausted its
4
- * relance budget (→ escalate, D7), or finished (→ ignore/clear).
5
- */
6
- import { listDrumbeat } from "./registry.js";
7
- /** Default number of relances before escalating to the PRINCIPAL (DEC-084). */
8
- export const H2A_DEFAULT_MAX_RELANCES = 3;
9
- /**
10
- * Classify the registry: `done` entries are skipped (a clean finish);
11
- * entries at/over `maxRelances` are `exhausted` (escalate, don't loop);
12
- * everything else is a relance `finding` (reason `out-of-tokens` when that is
13
- * the recorded status, else `stopped`).
14
- */
15
- export function scanDrumbeat(root, options = {}) {
16
- const maxRelances = options.maxRelances ?? H2A_DEFAULT_MAX_RELANCES;
17
- const skip = new Set(options.skipInstances ?? []);
18
- const findings = [];
19
- const exhausted = [];
20
- for (const entry of listDrumbeat(root)) {
21
- if (skip.has(entry.instance))
22
- continue;
23
- if (entry.workStatus === "done")
24
- continue;
25
- if (entry.terminal)
26
- continue; // D5: a watchdog terminal action already resolved this
27
- if (entry.relanceCount >= maxRelances) {
28
- exhausted.push(entry);
29
- continue;
30
- }
31
- findings.push({
32
- instance: entry.instance,
33
- reason: entry.workStatus === "out-of-tokens" ? "out-of-tokens" : "stopped",
34
- workStatus: entry.workStatus,
35
- ...(entry.launchContext ? { launchContext: entry.launchContext } : {}),
36
- relanceCount: entry.relanceCount
37
- });
38
- }
39
- return { findings, exhausted };
40
- }
41
- //# sourceMappingURL=scan.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"scan.js","sourceRoot":"","sources":["../../../src/runtime/drumbeat/scan.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,EAAE,YAAY,EAAyB,MAAM,eAAe,CAAC;AAEpE,+EAA+E;AAC/E,MAAM,CAAC,MAAM,wBAAwB,GAAG,CAAC,CAAC;AAyB1C;;;;;GAKG;AACH,MAAM,UAAU,YAAY,CAC1B,IAAY,EACZ,UAA+B,EAAE;IAEjC,MAAM,WAAW,GAAG,OAAO,CAAC,WAAW,IAAI,wBAAwB,CAAC;IACpE,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,OAAO,CAAC,aAAa,IAAI,EAAE,CAAC,CAAC;IAClD,MAAM,QAAQ,GAAyB,EAAE,CAAC;IAC1C,MAAM,SAAS,GAAuB,EAAE,CAAC;IACzC,KAAK,MAAM,KAAK,IAAI,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;QACvC,IAAI,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,QAAQ,CAAC;YAAE,SAAS;QACvC,IAAI,KAAK,CAAC,UAAU,KAAK,MAAM;YAAE,SAAS;QAC1C,IAAI,KAAK,CAAC,QAAQ;YAAE,SAAS,CAAC,uDAAuD;QACrF,IAAI,KAAK,CAAC,YAAY,IAAI,WAAW,EAAE,CAAC;YACtC,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;YACtB,SAAS;QACX,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC;YACZ,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,MAAM,EAAE,KAAK,CAAC,UAAU,KAAK,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;YAC1E,UAAU,EAAE,KAAK,CAAC,UAAU;YAC5B,GAAG,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,KAAK,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACtE,YAAY,EAAE,KAAK,CAAC,YAAY;SACjC,CAAC,CAAC;IACL,CAAC;IACD,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;AACjC,CAAC"}
@@ -1,74 +0,0 @@
1
- /**
2
- * Drumbeat daemon core (DEC-086, slice D2): the dumb, always-on anchor that
3
- * `/loop` provides only on Claude. It scans the registry and, for each stalled
4
- * agent, calls a **relauncher adapter** (concrete adapters — local-tmux,
5
- * remote, headless — are slice D3/D4). It performs no LLM work and never
6
- * relaunches by itself; it just detects + dispatches + caps the relances.
7
- */
8
- import type { H2AReflexiveDecision } from "@sentropic/h2a";
9
- import { type H2ADrumbeatFinding, type ScanDrumbeatOptions } from "./scan.js";
10
- import { type H2ADrumbeatEntry } from "./registry.js";
11
- import type { ReflexiveDecider } from "./deciders.js";
12
- /** Adapter that actually re-invokes a stalled agent (slice D3/D4). */
13
- export interface H2ARelauncher {
14
- /** Returns true if a relance was issued (counts against the cap). */
15
- relance(finding: H2ADrumbeatFinding): boolean | Promise<boolean>;
16
- }
17
- /** A relauncher that only logs — the D2 default until real adapters land. */
18
- export declare function loggingRelauncher(write: (line: string) => void): H2ARelauncher;
19
- export interface DrumbeatTickOptions extends ScanDrumbeatOptions {
20
- /** D4: optional pre-scan hook, used by watch to consume remote resume inboxes. */
21
- beforeScan?: () => readonly string[] | Promise<readonly string[]>;
22
- /** Hook for entries that hit the relance cap → escalate to PRINCIPAL (D7). */
23
- onExhausted?: (entry: H2ADrumbeatEntry) => void | Promise<void>;
24
- now?: number;
25
- /** D5: reflexive watchdog. Consulted once `relanceCount >= deciderAfter`. */
26
- decider?: ReflexiveDecider;
27
- /** D5: minimum relanceCount before consulting the decider (default 1). */
28
- deciderAfter?: number;
29
- /** D5: apply the decision (true) or just log it and do the safe default (false). */
30
- enforce?: boolean;
31
- /** D5: label recorded in the decision log (default "logging"). */
32
- deciderLabel?: string;
33
- /** D5: effect hooks (cli.ts wires escalation), keeping watch.ts store-free. */
34
- onEscalate?: (finding: H2ADrumbeatFinding, decision: H2AReflexiveDecision) => void | Promise<void>;
35
- onReroute?: (finding: H2ADrumbeatFinding, decision: H2AReflexiveDecision) => void | Promise<void>;
36
- /**
37
- * WP-7: store root for the reach-guard. When provided, each finding is
38
- * checked via `reachGuard` before reaching: phantom / ambiguous / malformed
39
- * targets are SKIPPED (never relanced). When absent the guard is bypassed
40
- * and the tick behaves exactly as today — backward-compatible.
41
- */
42
- root?: string;
43
- /**
44
- * WP-7: optional log sink for reach-guard skip messages. Defaults to a
45
- * no-op; pass a `(line: string) => void` to surface the skip reason.
46
- */
47
- log?: (line: string) => void;
48
- /**
49
- * Gov D2/D4: the instance id of the agent running this drumbeat. When
50
- * absent, BOTH governance checks (D2 conductor-ownership, D4 cross-workspace
51
- * CoI advisory) are SKIPPED entirely — fully backward-compatible; all
52
- * existing callers that do not pass this option are unaffected.
53
- */
54
- selfInstance?: string;
55
- }
56
- export interface DrumbeatTickResult {
57
- readonly relanced: readonly string[];
58
- readonly exhausted: readonly string[];
59
- }
60
- /** One scan→dispatch pass (no timers) — the testable unit of the loop. */
61
- export declare function drumbeatTick(root: string, relauncher: H2ARelauncher, options?: DrumbeatTickOptions): Promise<DrumbeatTickResult>;
62
- export interface DrumbeatWatchOptions extends DrumbeatTickOptions {
63
- /** Beat interval in ms. Default 30s. */
64
- intervalMs?: number;
65
- /** Stop the loop. */
66
- signal?: AbortSignal;
67
- onTick?: (result: DrumbeatTickResult) => void | Promise<void>;
68
- }
69
- /**
70
- * Run the drumbeat loop until `signal` aborts. Each beat: scan → relance via
71
- * the adapter → cap. The anchor that codex/agy/gemini lack.
72
- */
73
- export declare function runDrumbeatWatch(root: string, relauncher: H2ARelauncher, options?: DrumbeatWatchOptions): Promise<void>;
74
- //# sourceMappingURL=watch.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../../src/runtime/drumbeat/watch.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAsB,oBAAoB,EAAE,MAAM,gBAAgB,CAAC;AAO/E,OAAO,EAAgB,KAAK,kBAAkB,EAAE,KAAK,mBAAmB,EAAE,MAAM,WAAW,CAAC;AAC5F,OAAO,EAIL,KAAK,gBAAgB,EACtB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAGtD,sEAAsE;AACtE,MAAM,WAAW,aAAa;IAC5B,qEAAqE;IACrE,OAAO,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;CAClE;AAED,6EAA6E;AAC7E,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAAG,aAAa,CAS9E;AAED,MAAM,WAAW,mBAAoB,SAAQ,mBAAmB;IAC9D,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,SAAS,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,MAAM,EAAE,CAAC,CAAC;IAClE,8EAA8E;IAC9E,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,gBAAgB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,6EAA6E;IAC7E,OAAO,CAAC,EAAE,gBAAgB,CAAC;IAC3B,0EAA0E;IAC1E,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,oFAAoF;IACpF,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kEAAkE;IAClE,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,+EAA+E;IAC/E,UAAU,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACnG,SAAS,CAAC,EAAE,CAAC,OAAO,EAAE,kBAAkB,EAAE,QAAQ,EAAE,oBAAoB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAClG;;;;;OAKG;IACH,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;OAGG;IACH,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B;;;;;OAKG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,CAAC,QAAQ,EAAE,SAAS,MAAM,EAAE,CAAC;IACrC,QAAQ,CAAC,SAAS,EAAE,SAAS,MAAM,EAAE,CAAC;CACvC;AAED,0EAA0E;AAC1E,wBAAsB,YAAY,CAChC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,aAAa,EACzB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CAmL7B;AAED,MAAM,WAAW,oBAAqB,SAAQ,mBAAmB;IAC/D,wCAAwC;IACxC,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,qBAAqB;IACrB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,MAAM,CAAC,EAAE,CAAC,MAAM,EAAE,kBAAkB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/D;AAiBD;;;GAGG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE,aAAa,EACzB,OAAO,GAAE,oBAAyB,GACjC,OAAO,CAAC,IAAI,CAAC,CAQf"}
@@ -1,216 +0,0 @@
1
- /**
2
- * Drumbeat daemon core (DEC-086, slice D2): the dumb, always-on anchor that
3
- * `/loop` provides only on Claude. It scans the registry and, for each stalled
4
- * agent, calls a **relauncher adapter** (concrete adapters — local-tmux,
5
- * remote, headless — are slice D3/D4). It performs no LLM work and never
6
- * relaunches by itself; it just detects + dispatches + caps the relances.
7
- */
8
- import { canonicalAddress } from "../local-files/index.js";
9
- import { reachGuard } from "../local-files/paths.js";
10
- import { listPresence } from "../local-files/presence.js";
11
- import { createLocalStore } from "../local-files/store.js";
12
- import { conductorFor } from "../governance/conductor.js";
13
- import { scanDrumbeat } from "./scan.js";
14
- import { markRelanced, clearDrumbeatEntry, markDrumbeatTerminal } from "./registry.js";
15
- import { recordDrumbeatDecision } from "./decisions.js";
16
- /** A relauncher that only logs — the D2 default until real adapters land. */
17
- export function loggingRelauncher(write) {
18
- return {
19
- relance(finding) {
20
- write(`drumbeat: would relance ${finding.instance} (reason=${finding.reason}, tries=${finding.relanceCount})`);
21
- return true;
22
- }
23
- };
24
- }
25
- /** One scan→dispatch pass (no timers) — the testable unit of the loop. */
26
- export async function drumbeatTick(root, relauncher, options = {}) {
27
- const preRelanced = await options.beforeScan?.();
28
- const { findings, exhausted } = scanDrumbeat(root, {
29
- maxRelances: options.maxRelances,
30
- skipInstances: [...(options.skipInstances ?? []), ...(preRelanced ?? [])]
31
- });
32
- // WP-7: Build reach-guard sets once per tick (avoid repeated I/O).
33
- // When `options.root` is absent the guard is skipped — backward-compatible.
34
- let guardRoot = options.root;
35
- let liveInstances;
36
- let registeredInstances;
37
- let allSessions;
38
- if (guardRoot !== undefined) {
39
- allSessions = listPresence(guardRoot, options.now !== undefined ? { now: options.now } : {});
40
- liveInstances = allSessions.map((s) => s.instance);
41
- registeredInstances = createLocalStore({ root: guardRoot })
42
- .listInstances()
43
- .map((i) => i.instance);
44
- }
45
- // Gov D2/D4: resolve wSelf (self's workspace) once per tick if selfInstance known.
46
- // undefined = unknown/skip advisory.
47
- const selfInstance = options.selfInstance;
48
- let wSelf;
49
- if (selfInstance !== undefined && guardRoot !== undefined) {
50
- const selfSessions = (allSessions ?? []).filter((s) => canonicalAddress(s.instance) === canonicalAddress(selfInstance));
51
- if (selfSessions.length > 0 && selfSessions[0].workspace?.id !== undefined) {
52
- wSelf = selfSessions[0].workspace.id;
53
- }
54
- else {
55
- try {
56
- const reg = createLocalStore({ root: guardRoot }).findInstance(selfInstance);
57
- if (reg?.workspace?.id !== undefined) {
58
- wSelf = reg.workspace.id;
59
- }
60
- }
61
- catch {
62
- // if registry unreadable, wSelf stays undefined → D4 advisory skipped
63
- }
64
- }
65
- }
66
- const relanced = [];
67
- const k = options.deciderAfter ?? 1;
68
- for (const finding of findings) {
69
- // ── REACH-GUARD CHOKEPOINT ──────────────────────────────────────────────
70
- // Governance gates (D2 conductor-ownership, D4 CoI advisory) hook HERE so
71
- // every reach path inherits them.
72
- if (guardRoot !== undefined) {
73
- const guard = reachGuard({
74
- target: finding.instance,
75
- liveInstances: liveInstances,
76
- registeredInstances: registeredInstances
77
- });
78
- if (!guard.ok) {
79
- options.log?.(`drumbeat: skipping relance of ${finding.instance} — ${guard.reason}`);
80
- continue;
81
- }
82
- }
83
- // ── GOV D2: conductor owns relances (opt-in, default-allow) ────────────
84
- // Suppression only when ALL of:
85
- // (a) selfInstance and options.root are known
86
- // (b) wTarget (the finding's workspace) is resolvable
87
- // (c) a live conductor is claimed for that workspace
88
- // (d) self is NOT that conductor
89
- // (e) relanceCount === 0 (fresh stall — failsafe: if relanceCount >= 1
90
- // the conductor has already missed the window; peer steps in so
91
- // a workspace is never frozen by a stuck conductor)
92
- // Also used by D4 CoI advisory below.
93
- let wTarget;
94
- if (selfInstance !== undefined && guardRoot !== undefined) {
95
- // Resolve finding's workspace from live sessions first, then registry.
96
- const targetSession = (allSessions ?? []).find((s) => canonicalAddress(s.instance) === canonicalAddress(finding.instance));
97
- if (targetSession?.workspace?.id !== undefined) {
98
- wTarget = targetSession.workspace.id;
99
- }
100
- else {
101
- try {
102
- const reg = createLocalStore({ root: guardRoot }).findInstance(finding.instance);
103
- if (reg?.workspace?.id !== undefined) {
104
- wTarget = reg.workspace.id;
105
- }
106
- }
107
- catch {
108
- // registry unreadable → wTarget stays undefined → ALLOW
109
- }
110
- }
111
- if (wTarget !== undefined) {
112
- const res = conductorFor({
113
- root: guardRoot,
114
- workspaceId: wTarget,
115
- ...(options.now !== undefined ? { now: options.now } : {})
116
- });
117
- if (res.conductor !== null &&
118
- canonicalAddress(res.conductor) !== canonicalAddress(selfInstance) &&
119
- finding.relanceCount === 0) {
120
- options.log?.(`drumbeat: ${finding.instance} in ${wTarget} owned by conductor ${res.conductor}; deferring relance`);
121
- continue; // D2 suppression
122
- }
123
- }
124
- }
125
- // ── END GOV D2 ──────────────────────────────────────────────────────────
126
- // ── GOV D4: cross-workspace CoI advisory (warn only, never skip) ────────
127
- if (selfInstance !== undefined &&
128
- wSelf !== undefined &&
129
- wTarget !== undefined &&
130
- canonicalAddress(wSelf) !== canonicalAddress(wTarget)) {
131
- options.log?.(`drumbeat: cross-workspace relance of ${finding.instance} (workspace ${wTarget}) by ${selfInstance} (workspace ${wSelf}) — no target-conductor mandate (advisory)`);
132
- }
133
- // ── END GOV D4 ──────────────────────────────────────────────────────────
134
- // ────────────────────────────────────────────────────────────────────────
135
- // Cost guard: relance cheaply until K relances, then consult the decider.
136
- if (!options.decider || finding.relanceCount < k) {
137
- if (await relauncher.relance(finding)) {
138
- markRelanced(root, finding.instance, options.now);
139
- relanced.push(finding.instance);
140
- }
141
- continue;
142
- }
143
- const decision = await options.decider.decide(finding);
144
- let applied = decision.action;
145
- if (!options.enforce) {
146
- applied = "relance"; // advisory-first: log the verdict, do the safe default
147
- }
148
- else if (decision.action === "finish" && finding.workStatus !== "done") {
149
- applied = "escalate"; // `done` is the only safe-to-finish status (else never abandon)
150
- }
151
- switch (applied) {
152
- case "relance":
153
- if (await relauncher.relance(finding)) {
154
- markRelanced(root, finding.instance, options.now);
155
- relanced.push(finding.instance);
156
- }
157
- break;
158
- case "finish":
159
- clearDrumbeatEntry(root, finding.instance); // workStatus === "done": genuinely complete
160
- break;
161
- case "escalate":
162
- await options.onEscalate?.(finding, decision);
163
- markDrumbeatTerminal(root, finding.instance, "escalate", options.now);
164
- break;
165
- case "reroute":
166
- await options.onReroute?.(finding, decision);
167
- markDrumbeatTerminal(root, finding.instance, "reroute", options.now);
168
- break;
169
- }
170
- recordDrumbeatDecision(root, {
171
- instance: finding.instance,
172
- decided: decision.action,
173
- applied,
174
- ...(decision.reason ? { reason: decision.reason } : {}),
175
- decider: options.deciderLabel ?? "logging",
176
- enforced: options.enforce === true,
177
- at: new Date(options.now ?? Date.now()).toISOString()
178
- });
179
- }
180
- const escalated = [];
181
- for (const entry of exhausted) {
182
- await options.onExhausted?.(entry);
183
- escalated.push(entry.instance);
184
- }
185
- return { relanced, exhausted: escalated };
186
- }
187
- function delay(ms, signal) {
188
- return new Promise((resolve) => {
189
- if (signal?.aborted)
190
- return resolve();
191
- const timer = setTimeout(() => {
192
- signal?.removeEventListener("abort", onAbort);
193
- resolve();
194
- }, ms);
195
- function onAbort() {
196
- clearTimeout(timer);
197
- resolve();
198
- }
199
- signal?.addEventListener("abort", onAbort, { once: true });
200
- });
201
- }
202
- /**
203
- * Run the drumbeat loop until `signal` aborts. Each beat: scan → relance via
204
- * the adapter → cap. The anchor that codex/agy/gemini lack.
205
- */
206
- export async function runDrumbeatWatch(root, relauncher, options = {}) {
207
- const intervalMs = options.intervalMs ?? 30_000;
208
- while (!options.signal?.aborted) {
209
- const result = await drumbeatTick(root, relauncher, options);
210
- await options.onTick?.(result);
211
- if (options.signal?.aborted)
212
- break;
213
- await delay(intervalMs, options.signal);
214
- }
215
- }
216
- //# sourceMappingURL=watch.js.map