@ouro.bot/cli 0.1.0-alpha.92 → 0.1.0-alpha.920

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 (716) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +154 -23
  3. package/RepairGuide.ouro/agent.json +5 -0
  4. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  5. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  6. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  7. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  8. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  9. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  12. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  13. package/assets/bluebubbles-host +264 -0
  14. package/assets/sanctuary-host-launcher.sh +16 -0
  15. package/changelog.json +5819 -16
  16. package/deploy/unraid/Dockerfile +58 -0
  17. package/deploy/unraid/README.txt +2997 -0
  18. package/deploy/unraid/audit-container-spec.sh +4 -0
  19. package/deploy/unraid/container-runtime.json +1 -0
  20. package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
  21. package/deploy/unraid/docker-man-template-xml.cjs +105 -0
  22. package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
  23. package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
  24. package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
  25. package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
  26. package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
  27. package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
  28. package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
  29. package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
  30. package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
  31. package/deploy/unraid/sanctuary-authority-installation.json +36 -0
  32. package/deploy/unraid/sanctuary-authority-service.sh +30 -0
  33. package/deploy/unraid/sanctuary-butler-upgrade.mjs +1254 -0
  34. package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
  35. package/deploy/unraid/sanctuary-replay-gate.mjs +1564 -0
  36. package/deploy/unraid/sanctuary-safe-rename.py +24 -0
  37. package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2086 -0
  38. package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
  39. package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
  40. package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
  41. package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
  42. package/deploy/unraid/sanctuary.ouro/awaiting/house-care-sweep.md +17 -0
  43. package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
  44. package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
  45. package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +2231 -0
  46. package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
  47. package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
  48. package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
  49. package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +33 -0
  50. package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +27 -0
  51. package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +22 -0
  52. package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
  53. package/deploy/unraid/sanctuary.ouro/tool-profiles.json +232 -0
  54. package/deploy/unraid/sanctuary.xml +30 -0
  55. package/dist/a2a/card.js +57 -0
  56. package/dist/a2a/client.js +250 -0
  57. package/dist/a2a/config.js +50 -0
  58. package/dist/a2a/delegated-command-grants.js +93 -0
  59. package/dist/a2a/delegated-command.js +197 -0
  60. package/dist/a2a/delegation-stores.js +56 -0
  61. package/dist/a2a/did-resolution.js +93 -0
  62. package/dist/a2a/escalation-grants.js +84 -0
  63. package/dist/a2a/escalation-wiring.js +60 -0
  64. package/dist/a2a/identity.js +258 -0
  65. package/dist/a2a/inbound-share.js +110 -0
  66. package/dist/a2a/mission-result-wire.js +196 -0
  67. package/dist/a2a/onboarding.js +133 -0
  68. package/dist/a2a/operator-trust.js +382 -0
  69. package/dist/a2a/outbox-client.js +57 -0
  70. package/dist/a2a/outbox-store.js +188 -0
  71. package/dist/a2a/outbox-wire.js +95 -0
  72. package/dist/a2a/pin-store.js +132 -0
  73. package/dist/a2a/replay-grant-holders.js +33 -0
  74. package/dist/a2a/replay-harness.js +188 -0
  75. package/dist/a2a/resolution-proof.js +53 -0
  76. package/dist/a2a/sealed-chat.js +113 -0
  77. package/dist/a2a/seen-ledger.js +120 -0
  78. package/dist/a2a/server.js +771 -0
  79. package/dist/a2a/task-store.js +69 -0
  80. package/dist/a2a/transport.js +45 -0
  81. package/dist/a2a/trust-commands.js +203 -0
  82. package/dist/a2a/trusted-files.js +185 -0
  83. package/dist/a2a/types.js +3 -0
  84. package/dist/arc/attention-types.js +8 -0
  85. package/dist/arc/cares.js +360 -0
  86. package/dist/arc/episodes.js +118 -0
  87. package/dist/arc/evolution.js +490 -0
  88. package/dist/arc/flight-recorder.js +1034 -0
  89. package/dist/arc/intentions.js +134 -0
  90. package/dist/arc/json-store.js +117 -0
  91. package/dist/arc/obligations.js +386 -0
  92. package/dist/arc/packets.js +336 -0
  93. package/dist/arc/presence.js +185 -0
  94. package/dist/arc/task-lifecycle.js +57 -0
  95. package/dist/commerce/store.js +755 -0
  96. package/dist/commerce/types.js +3 -0
  97. package/dist/heart/active-work.js +798 -40
  98. package/dist/heart/agent-entry.js +252 -3
  99. package/dist/heart/approval-files.js +113 -0
  100. package/dist/heart/approval-store.js +960 -0
  101. package/dist/heart/attachments/image-normalize.js +194 -0
  102. package/dist/heart/attachments/materialize.js +97 -0
  103. package/dist/heart/attachments/originals.js +88 -0
  104. package/dist/heart/attachments/render.js +29 -0
  105. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  106. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  107. package/dist/heart/attachments/sources/index.js +18 -0
  108. package/dist/heart/attachments/sources/telegram.js +71 -0
  109. package/dist/heart/attachments/store.js +132 -0
  110. package/dist/heart/attachments/types.js +93 -0
  111. package/dist/heart/auth/auth-flow.js +495 -0
  112. package/dist/heart/autonomy-budget.js +478 -0
  113. package/dist/heart/awaiting/a2a-await-delivery.js +109 -0
  114. package/dist/heart/awaiting/await-alert.js +152 -0
  115. package/dist/heart/awaiting/await-expiry.js +143 -0
  116. package/dist/heart/awaiting/await-loader.js +91 -0
  117. package/dist/heart/awaiting/await-parser.js +152 -0
  118. package/dist/heart/awaiting/await-runtime-state.js +111 -0
  119. package/dist/heart/awaiting/await-scheduler.js +391 -0
  120. package/dist/heart/background-operations.js +281 -0
  121. package/dist/heart/bluebubbles-host-account.js +78 -0
  122. package/dist/heart/bridges/manager.js +137 -17
  123. package/dist/heart/bridges/store.js +14 -2
  124. package/dist/heart/bundle-state.js +168 -0
  125. package/dist/heart/commitments.js +44 -18
  126. package/dist/heart/config-registry.js +331 -0
  127. package/dist/heart/config.js +174 -131
  128. package/dist/heart/context-loss-gauntlet.js +387 -0
  129. package/dist/heart/context-loss-sentinel.js +1159 -0
  130. package/dist/heart/core.js +2364 -578
  131. package/dist/heart/cross-chat-delivery.js +9 -22
  132. package/dist/heart/daemon/agent-config-check.js +451 -0
  133. package/dist/heart/daemon/agent-discovery.js +283 -3
  134. package/dist/heart/daemon/agent-home.js +319 -0
  135. package/dist/heart/daemon/agent-service.js +542 -0
  136. package/dist/heart/daemon/agentic-repair.js +547 -0
  137. package/dist/heart/daemon/await-private-wake.js +59 -0
  138. package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
  139. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  140. package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
  141. package/dist/heart/daemon/bluebubbles-host.js +273 -0
  142. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  143. package/dist/heart/daemon/cadence.js +180 -0
  144. package/dist/heart/daemon/cli-arg-redaction.js +26 -0
  145. package/dist/heart/daemon/cli-defaults.js +876 -0
  146. package/dist/heart/daemon/cli-desk.js +322 -0
  147. package/dist/heart/daemon/cli-exec.js +9199 -0
  148. package/dist/heart/daemon/cli-help.js +735 -0
  149. package/dist/heart/daemon/cli-parse.js +3211 -0
  150. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  151. package/dist/heart/daemon/cli-render.js +819 -0
  152. package/dist/heart/daemon/cli-types.js +8 -0
  153. package/dist/heart/daemon/connect-bay.js +323 -0
  154. package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
  155. package/dist/heart/daemon/container-healthcheck.js +112 -0
  156. package/dist/heart/daemon/container-runtime.js +97 -0
  157. package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
  158. package/dist/heart/daemon/container-spec-auditor.js +235 -0
  159. package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
  160. package/dist/heart/daemon/daemon-cli.js +29 -2350
  161. package/dist/heart/daemon/daemon-entry.js +953 -11
  162. package/dist/heart/daemon/daemon-health.js +186 -0
  163. package/dist/heart/daemon/daemon-rollup.js +57 -0
  164. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  165. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  166. package/dist/heart/daemon/daemon.js +2084 -105
  167. package/dist/heart/daemon/dns-workflow.js +394 -0
  168. package/dist/heart/daemon/doctor-types.js +8 -0
  169. package/dist/heart/daemon/doctor.js +1766 -0
  170. package/dist/heart/daemon/freshness.js +345 -0
  171. package/dist/heart/daemon/habit-private-wake.js +61 -0
  172. package/dist/heart/daemon/health-monitor.js +154 -11
  173. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  174. package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
  175. package/dist/heart/daemon/http-health-probe.js +80 -0
  176. package/dist/heart/daemon/human-command-screens.js +234 -0
  177. package/dist/heart/daemon/human-readiness.js +114 -0
  178. package/dist/heart/daemon/inner-status.js +78 -0
  179. package/dist/heart/daemon/interactive-repair.js +394 -0
  180. package/dist/heart/daemon/launchd.js +37 -8
  181. package/dist/heart/daemon/log-tailer.js +79 -10
  182. package/dist/heart/daemon/logs-prune.js +132 -0
  183. package/dist/heart/daemon/mcp-canary.js +524 -0
  184. package/dist/heart/daemon/message-router.js +65 -5
  185. package/dist/heart/daemon/migrate-to-desk.js +848 -0
  186. package/dist/heart/daemon/os-cron-deps.js +135 -0
  187. package/dist/heart/daemon/os-cron.js +22 -14
  188. package/dist/heart/daemon/ouro-bot-entry.js +6 -3
  189. package/dist/heart/daemon/ouro-entry.js +5 -2
  190. package/dist/heart/daemon/plugin-cli.js +432 -0
  191. package/dist/heart/daemon/process-manager.js +760 -61
  192. package/dist/heart/daemon/provider-discovery.js +137 -0
  193. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  194. package/dist/heart/daemon/prunable-bundle.js +144 -0
  195. package/dist/heart/daemon/pulse.js +511 -0
  196. package/dist/heart/daemon/readiness-repair.js +365 -0
  197. package/dist/heart/daemon/run-hooks.js +2 -0
  198. package/dist/heart/daemon/runtime-logging.js +47 -14
  199. package/dist/heart/daemon/runtime-metadata.js +2 -30
  200. package/dist/heart/daemon/runtime-mode.js +13 -2
  201. package/dist/heart/daemon/safe-mode.js +161 -0
  202. package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
  203. package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
  204. package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
  205. package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
  206. package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
  207. package/dist/heart/daemon/sanctuary-authority-epoch.js +281 -0
  208. package/dist/heart/daemon/sanctuary-authority-installation.js +161 -0
  209. package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
  210. package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +1267 -0
  211. package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
  212. package/dist/heart/daemon/sanctuary-bundle-migration.js +730 -0
  213. package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
  214. package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +493 -0
  215. package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
  216. package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
  217. package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
  218. package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
  219. package/dist/heart/daemon/sanctuary-package-management.js +103 -0
  220. package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
  221. package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
  222. package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +475 -0
  223. package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
  224. package/dist/heart/daemon/sanctuary-telegram-authority-service.js +676 -0
  225. package/dist/heart/daemon/sense-manager.js +733 -48
  226. package/dist/heart/daemon/session-id-resolver.js +131 -0
  227. package/dist/heart/daemon/skill-management-installer.js +1 -1
  228. package/dist/heart/daemon/socket-client.js +180 -12
  229. package/dist/heart/daemon/stale-bundle-prune.js +113 -0
  230. package/dist/heart/daemon/startup-tui.js +339 -0
  231. package/dist/heart/daemon/supercronic-supervisor.js +282 -0
  232. package/dist/heart/daemon/task-scheduler.js +117 -39
  233. package/dist/heart/daemon/terminal-ui.js +503 -0
  234. package/dist/heart/daemon/thoughts.js +138 -54
  235. package/dist/heart/daemon/up-progress.js +366 -0
  236. package/dist/heart/daemon/vault-items.js +56 -0
  237. package/dist/heart/delegation.js +1 -4
  238. package/dist/heart/external-events/router.js +1516 -0
  239. package/dist/heart/failure-reports.js +336 -0
  240. package/dist/heart/file-lock.js +109 -0
  241. package/dist/heart/frontend-approval-runtime.js +506 -0
  242. package/dist/heart/frontend-journal.js +215 -0
  243. package/dist/heart/frontend-session-service.js +237 -0
  244. package/dist/heart/frontend-socket-client.js +164 -0
  245. package/dist/heart/frontend-socket.js +400 -0
  246. package/dist/heart/habits/habit-cancel.js +810 -0
  247. package/dist/heart/habits/habit-lifecycle.js +1327 -0
  248. package/dist/heart/habits/habit-migration.js +194 -0
  249. package/dist/heart/habits/habit-parser.js +278 -0
  250. package/dist/heart/habits/habit-runtime-state.js +93 -0
  251. package/dist/heart/habits/habit-scheduler.js +653 -0
  252. package/dist/heart/habits/habit-session-summary.js +318 -0
  253. package/dist/heart/habits/habit-session.js +636 -0
  254. package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
  255. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  256. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  257. package/dist/heart/{daemon → hatch}/specialist-tools.js +53 -18
  258. package/dist/heart/identity.js +230 -59
  259. package/dist/heart/kept-notes.js +289 -0
  260. package/dist/heart/kicks.js +1 -1
  261. package/dist/heart/machine-identity.js +175 -0
  262. package/dist/heart/mail-import-discovery.js +356 -0
  263. package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
  264. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  265. package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
  266. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  267. package/dist/heart/mailbox/mailbox-http-transport.js +272 -0
  268. package/dist/heart/mailbox/mailbox-http.js +99 -0
  269. package/dist/heart/mailbox/mailbox-read.js +39 -0
  270. package/dist/heart/mailbox/mailbox-types.js +27 -0
  271. package/dist/heart/mailbox/mailbox-view.js +197 -0
  272. package/dist/heart/mailbox/readers/agent-machine.js +428 -0
  273. package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
  274. package/dist/heart/mailbox/readers/mail.js +375 -0
  275. package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
  276. package/dist/heart/mailbox/readers/sessions.js +231 -0
  277. package/dist/heart/mailbox/readers/shared.js +111 -0
  278. package/dist/heart/mcp/mcp-server.js +696 -0
  279. package/dist/heart/migrate-config.js +100 -0
  280. package/dist/heart/model-capabilities.js +83 -16
  281. package/dist/heart/orientation-frame.js +345 -0
  282. package/dist/heart/platform.js +81 -0
  283. package/dist/heart/primitives.js +1 -1
  284. package/dist/heart/private-runtime/decision-renderer.js +158 -0
  285. package/dist/heart/private-runtime/index.js +18 -0
  286. package/dist/heart/private-runtime/ledger.js +221 -0
  287. package/dist/heart/private-runtime/policy.js +260 -0
  288. package/dist/heart/private-runtime/types.js +2 -0
  289. package/dist/heart/progress-story.js +1 -1
  290. package/dist/heart/provider-attempt.js +137 -0
  291. package/dist/heart/provider-binding-resolver.js +273 -0
  292. package/dist/heart/provider-credentials.js +449 -0
  293. package/dist/heart/provider-failover.js +311 -0
  294. package/dist/heart/provider-models.js +96 -0
  295. package/dist/heart/provider-ping.js +265 -0
  296. package/dist/heart/provider-readiness-cache.js +119 -0
  297. package/dist/heart/provider-visibility.js +188 -0
  298. package/dist/heart/providers/anthropic-token.js +131 -0
  299. package/dist/heart/providers/anthropic.js +173 -60
  300. package/dist/heart/providers/azure.js +23 -11
  301. package/dist/heart/providers/error-classification.js +127 -0
  302. package/dist/heart/providers/github-copilot.js +38 -39
  303. package/dist/heart/providers/minimax-vlm.js +189 -0
  304. package/dist/heart/providers/minimax.js +26 -8
  305. package/dist/heart/providers/openai-codex-token.js +349 -0
  306. package/dist/heart/providers/openai-codex.js +55 -40
  307. package/dist/heart/providers/openai-compatible.js +177 -0
  308. package/dist/heart/reply-style.js +52 -0
  309. package/dist/heart/run-ledger.js +247 -0
  310. package/dist/heart/runtime-capability-check.js +170 -0
  311. package/dist/heart/runtime-credentials.js +607 -0
  312. package/dist/heart/runtime-cwd.js +87 -0
  313. package/dist/heart/sense-truth.js +24 -4
  314. package/dist/heart/session-activity.js +92 -24
  315. package/dist/heart/session-events.js +1504 -0
  316. package/dist/heart/session-playback-cli-main.js +5 -0
  317. package/dist/heart/session-playback-cli.js +36 -0
  318. package/dist/heart/session-playback.js +231 -0
  319. package/dist/heart/session-redaction-repair-cli-main.js +31 -0
  320. package/dist/heart/session-redaction-repair.js +552 -0
  321. package/dist/heart/session-stats-cli-main.js +5 -0
  322. package/dist/heart/session-stats.js +183 -0
  323. package/dist/heart/session-transcript.js +133 -0
  324. package/dist/heart/shelf-claims.js +78 -0
  325. package/dist/heart/shepherd-config.js +113 -0
  326. package/dist/heart/source-grounding.js +297 -0
  327. package/dist/heart/start-of-turn-packet.js +372 -0
  328. package/dist/heart/steward-policy.js +656 -0
  329. package/dist/heart/streaming.js +609 -207
  330. package/dist/heart/structured-output.js +196 -0
  331. package/dist/heart/sync-classification.js +176 -0
  332. package/dist/heart/sync-health.js +152 -0
  333. package/dist/heart/sync.js +726 -0
  334. package/dist/heart/target-resolution.js +11 -7
  335. package/dist/heart/tempo.js +93 -0
  336. package/dist/heart/temporal-view.js +41 -0
  337. package/dist/heart/timeouts.js +101 -0
  338. package/dist/heart/tool-activity-callbacks.js +59 -0
  339. package/dist/heart/tool-approval.js +382 -0
  340. package/dist/heart/tool-description.js +155 -0
  341. package/dist/heart/tool-friction.js +55 -0
  342. package/dist/heart/tool-loop.js +206 -0
  343. package/dist/heart/turn-context.js +496 -0
  344. package/dist/heart/turn-execution-lease.js +30 -0
  345. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  346. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +3 -2
  347. package/dist/heart/versioning/ouro-path-installer.js +432 -0
  348. package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
  349. package/dist/heart/versioning/ouro-version-manager.js +432 -0
  350. package/dist/heart/versioning/release-sources.js +173 -0
  351. package/dist/heart/versioning/self-update-defaults.js +294 -0
  352. package/dist/heart/versioning/self-update.js +196 -0
  353. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  354. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  355. package/dist/heart/versioning/update-hooks.js +154 -0
  356. package/dist/heart/versioning/update-state.js +126 -0
  357. package/dist/heart/versioning/updater-launchd.js +150 -0
  358. package/dist/heart/versioning/version-intent.js +114 -0
  359. package/dist/heart/work-card.js +380 -0
  360. package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
  361. package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
  362. package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
  363. package/dist/mailbox-ui/index.html +16 -0
  364. package/dist/mailroom/attention.js +167 -0
  365. package/dist/mailroom/autonomy.js +209 -0
  366. package/dist/mailroom/blob-store.js +889 -0
  367. package/dist/mailroom/body-cache.js +61 -0
  368. package/dist/mailroom/cache-sync-cli.js +58 -0
  369. package/dist/mailroom/core.js +803 -0
  370. package/dist/mailroom/entry.js +160 -0
  371. package/dist/mailroom/file-store.js +568 -0
  372. package/dist/mailroom/hosted-cache-sync.js +384 -0
  373. package/dist/mailroom/mbox-import.js +393 -0
  374. package/dist/mailroom/migration.js +164 -0
  375. package/dist/mailroom/outbound.js +380 -0
  376. package/dist/mailroom/policy.js +263 -0
  377. package/dist/mailroom/reader.js +292 -0
  378. package/dist/mailroom/search-cache.js +513 -0
  379. package/dist/mailroom/search-relevance.js +319 -0
  380. package/dist/mailroom/smtp-ingress.js +176 -0
  381. package/dist/mailroom/source-state.js +176 -0
  382. package/dist/mailroom/thread.js +109 -0
  383. package/dist/mailroom/travel-extract.js +89 -0
  384. package/dist/mind/bundle-manifest.js +24 -2
  385. package/dist/mind/context.js +307 -139
  386. package/dist/mind/desk-section.js +362 -0
  387. package/dist/mind/diary-integrity.js +60 -0
  388. package/dist/mind/{memory.js → diary.js} +68 -77
  389. package/dist/mind/embedding-provider.js +60 -0
  390. package/dist/mind/file-state.js +179 -0
  391. package/dist/mind/friend-link-codes.js +209 -0
  392. package/dist/mind/friend-merge.js +330 -0
  393. package/dist/mind/{associative-recall.js → note-search.js} +47 -58
  394. package/dist/mind/obligation-steering.js +199 -3
  395. package/dist/mind/pending.js +36 -10
  396. package/dist/mind/prompt-budget.js +479 -0
  397. package/dist/mind/prompt-refresh.js +3 -2
  398. package/dist/mind/prompt.js +1085 -198
  399. package/dist/mind/provenance-trust.js +26 -0
  400. package/dist/mind/record-paths.js +312 -0
  401. package/dist/mind/scrutiny.js +173 -0
  402. package/dist/mind/session-transaction.js +564 -0
  403. package/dist/nerves/cli-logging.js +7 -1
  404. package/dist/nerves/coverage/audit-rules.js +15 -6
  405. package/dist/nerves/coverage/audit.js +28 -2
  406. package/dist/nerves/coverage/cli.js +1 -1
  407. package/dist/nerves/coverage/contract.js +5 -5
  408. package/dist/nerves/coverage/file-completeness.js +139 -5
  409. package/dist/nerves/coverage/run-artifacts.js +55 -35
  410. package/dist/nerves/coverage/source-scanner.js +4 -4
  411. package/dist/nerves/event-buffer.js +111 -0
  412. package/dist/nerves/index.js +293 -9
  413. package/dist/nerves/observation.js +20 -0
  414. package/dist/nerves/redact.js +79 -0
  415. package/dist/nerves/review/cli-main.js +5 -0
  416. package/dist/nerves/review/cli.js +156 -0
  417. package/dist/nerves/review/core.js +159 -0
  418. package/dist/nerves/runtime.js +17 -1
  419. package/dist/repertoire/ado-client.js +15 -56
  420. package/dist/repertoire/ado-semantic.js +16 -10
  421. package/dist/repertoire/api-client.js +97 -0
  422. package/dist/repertoire/bitwarden-store.js +1201 -0
  423. package/dist/repertoire/bundle-templates.js +71 -0
  424. package/dist/repertoire/bw-installer.js +231 -0
  425. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  426. package/dist/repertoire/coding/context-pack.js +331 -0
  427. package/dist/repertoire/coding/feedback.js +174 -32
  428. package/dist/repertoire/coding/index.js +15 -3
  429. package/dist/repertoire/coding/manager.js +159 -10
  430. package/dist/repertoire/coding/spawner.js +40 -11
  431. package/dist/repertoire/coding/tools.js +182 -18
  432. package/dist/repertoire/coding/workbench-client.js +272 -0
  433. package/dist/repertoire/coding/workbench-manager.js +346 -0
  434. package/dist/repertoire/commerce-errors.js +109 -0
  435. package/dist/repertoire/commerce-self-test.js +156 -0
  436. package/dist/repertoire/credential-access.js +183 -0
  437. package/dist/repertoire/desk/classifier.js +362 -0
  438. package/dist/repertoire/duffel-client.js +185 -0
  439. package/dist/repertoire/github-client.js +14 -55
  440. package/dist/repertoire/graph-client.js +11 -52
  441. package/dist/repertoire/guardrails.js +968 -20
  442. package/dist/repertoire/house-sweep.js +469 -0
  443. package/dist/repertoire/mcp-client.js +58 -5
  444. package/dist/repertoire/mcp-manager.js +427 -139
  445. package/dist/repertoire/mcp-tools.js +132 -0
  446. package/dist/repertoire/mcp-write-guard.js +46 -0
  447. package/dist/repertoire/plugin-mcp.js +175 -0
  448. package/dist/repertoire/plugins.js +253 -0
  449. package/dist/repertoire/relationship-authorization.js +322 -0
  450. package/dist/repertoire/sanctuary-container-policy.js +46 -0
  451. package/dist/repertoire/shell-sessions.js +134 -0
  452. package/dist/repertoire/skills.js +48 -4
  453. package/dist/repertoire/stripe-client.js +131 -0
  454. package/dist/repertoire/tool-arguments.js +182 -0
  455. package/dist/repertoire/tool-results.js +29 -0
  456. package/dist/repertoire/tools-a2a.js +699 -0
  457. package/dist/repertoire/tools-attachments.js +322 -0
  458. package/dist/repertoire/tools-awaiting.js +872 -0
  459. package/dist/repertoire/tools-base.js +83 -1168
  460. package/dist/repertoire/tools-bluebubbles.js +2 -0
  461. package/dist/repertoire/tools-bridge.js +144 -0
  462. package/dist/repertoire/tools-bundle.js +995 -0
  463. package/dist/repertoire/tools-commerce.js +253 -0
  464. package/dist/repertoire/tools-config.js +186 -0
  465. package/dist/repertoire/tools-continuity.js +575 -0
  466. package/dist/repertoire/tools-credential.js +383 -0
  467. package/dist/repertoire/tools-escalation.js +84 -0
  468. package/dist/repertoire/tools-evolution.js +527 -0
  469. package/dist/repertoire/tools-files.js +344 -0
  470. package/dist/repertoire/tools-flight.js +290 -0
  471. package/dist/repertoire/tools-flow.js +119 -0
  472. package/dist/repertoire/tools-friend-link.js +57 -0
  473. package/dist/repertoire/tools-github.js +3 -8
  474. package/dist/repertoire/tools-habits.js +103 -0
  475. package/dist/repertoire/tools-house-care.js +174 -0
  476. package/dist/repertoire/tools-mail.js +1828 -0
  477. package/dist/repertoire/tools-notes.js +496 -0
  478. package/dist/repertoire/tools-obligations.js +182 -0
  479. package/dist/repertoire/tools-orientation.js +31 -0
  480. package/dist/repertoire/tools-record.js +482 -0
  481. package/dist/repertoire/tools-rsvp.js +139 -0
  482. package/dist/repertoire/tools-runtime.js +238 -0
  483. package/dist/repertoire/tools-sanctuary-host.js +202 -0
  484. package/dist/repertoire/tools-session.js +1133 -0
  485. package/dist/repertoire/tools-shell.js +149 -0
  486. package/dist/repertoire/tools-shepherd.js +262 -0
  487. package/dist/repertoire/tools-steward-policy.js +147 -0
  488. package/dist/repertoire/tools-stripe.js +224 -0
  489. package/dist/repertoire/tools-surface.js +369 -0
  490. package/dist/repertoire/tools-teams.js +12 -39
  491. package/dist/repertoire/tools-telegram-contacts.js +37 -0
  492. package/dist/repertoire/tools-travel.js +125 -0
  493. package/dist/repertoire/tools-trip.js +982 -0
  494. package/dist/repertoire/tools-unraid.js +556 -0
  495. package/dist/repertoire/tools-user-profile.js +146 -0
  496. package/dist/repertoire/tools-vault.js +40 -0
  497. package/dist/repertoire/tools-voice-local.js +198 -0
  498. package/dist/repertoire/tools-voice.js +145 -0
  499. package/dist/repertoire/tools.js +514 -156
  500. package/dist/repertoire/travel-api-client.js +360 -0
  501. package/dist/repertoire/unraid-client.js +155 -0
  502. package/dist/repertoire/unraid-restart.js +339 -0
  503. package/dist/repertoire/user-profile.js +131 -0
  504. package/dist/repertoire/vault-setup.js +246 -0
  505. package/dist/repertoire/vault-unlock.js +686 -0
  506. package/dist/rsvp/aisleplanner-client.js +354 -0
  507. package/dist/rsvp/cli.js +936 -0
  508. package/dist/rsvp/config.js +327 -0
  509. package/dist/rsvp/cutover.js +433 -0
  510. package/dist/rsvp/diagnostics.js +232 -0
  511. package/dist/rsvp/diff-renderer.js +176 -0
  512. package/dist/rsvp/habit-policy.js +110 -0
  513. package/dist/rsvp/habit-stage.js +123 -0
  514. package/dist/rsvp/incident-bundle.js +97 -0
  515. package/dist/rsvp/migration.js +204 -0
  516. package/dist/rsvp/native-habit-runner.js +630 -0
  517. package/dist/rsvp/outbound-state.js +628 -0
  518. package/dist/rsvp/query.js +118 -0
  519. package/dist/rsvp/replay.js +233 -0
  520. package/dist/rsvp/snapshot.js +232 -0
  521. package/dist/rsvp/spend-ledger.js +175 -0
  522. package/dist/scripts/claude-code-hook.js +41 -0
  523. package/dist/scripts/claude-code-stop-hook.js +47 -0
  524. package/dist/senses/a2a-entry.js +132 -0
  525. package/dist/senses/acp-server.js +386 -0
  526. package/dist/senses/attention-queue.js +186 -0
  527. package/dist/senses/await-turn-message.js +65 -0
  528. package/dist/senses/bluebubbles/active-turns.js +216 -0
  529. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  530. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  531. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +379 -41
  532. package/dist/senses/bluebubbles/context-packet.js +207 -0
  533. package/dist/senses/bluebubbles/context-smoke.js +144 -0
  534. package/dist/senses/bluebubbles/entry.js +90 -0
  535. package/dist/senses/bluebubbles/host-account-verifier.js +88 -0
  536. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
  537. package/dist/senses/bluebubbles/index.js +3878 -0
  538. package/dist/senses/bluebubbles/latest-turn.js +311 -0
  539. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
  540. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
  541. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
  542. package/dist/senses/bluebubbles/outbound-state.js +308 -0
  543. package/dist/senses/bluebubbles/processed-log.js +133 -0
  544. package/dist/senses/bluebubbles/reaction-policy.js +47 -0
  545. package/dist/senses/bluebubbles/replay.js +284 -0
  546. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  547. package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
  548. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  549. package/dist/senses/bluebubbles/webhook-registration.js +257 -0
  550. package/dist/senses/bluebubbles-meta-guard.js +39 -0
  551. package/dist/senses/cli/bracketed-paste.js +82 -0
  552. package/dist/senses/cli/image-paste.js +287 -0
  553. package/dist/senses/cli/image-ref-navigation.js +75 -0
  554. package/dist/senses/cli/ink-app.js +156 -0
  555. package/dist/senses/cli/inline-diff.js +64 -0
  556. package/dist/senses/cli/input-keys.js +174 -0
  557. package/dist/senses/cli/kill-ring.js +86 -0
  558. package/dist/senses/cli/message-list.js +51 -0
  559. package/dist/senses/cli/ouro-tui.js +607 -0
  560. package/dist/senses/cli/spinner-imperative.js +135 -0
  561. package/dist/senses/cli/spinner.js +101 -0
  562. package/dist/senses/cli/status-line.js +60 -0
  563. package/dist/senses/cli/streaming-markdown.js +526 -0
  564. package/dist/senses/cli/tool-display.js +85 -0
  565. package/dist/senses/cli/tool-render.js +85 -0
  566. package/dist/senses/cli/tui-store.js +241 -0
  567. package/dist/senses/cli/virtual-list.js +35 -0
  568. package/dist/senses/cli-entry.js +60 -8
  569. package/dist/senses/cli.js +601 -304
  570. package/dist/senses/commands.js +66 -3
  571. package/dist/senses/context-packet-ledger.js +371 -0
  572. package/dist/senses/context-packets.js +154 -0
  573. package/dist/senses/habit-lifecycle-guard.js +24 -0
  574. package/dist/senses/habit-turn-message.js +160 -0
  575. package/dist/senses/ingress-evidence.js +2 -0
  576. package/dist/senses/mail-entry.js +66 -0
  577. package/dist/senses/mail.js +524 -0
  578. package/dist/senses/pipeline.js +1158 -204
  579. package/dist/senses/private-runtime-worker.js +859 -0
  580. package/dist/senses/private-runtime.js +1627 -0
  581. package/dist/senses/proactive-content-guard.js +51 -0
  582. package/dist/senses/root-host-approval-port.js +345 -0
  583. package/dist/senses/root-host-approval-runtime.js +393 -0
  584. package/dist/senses/sanctuary-authority-resident.js +102 -0
  585. package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
  586. package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
  587. package/dist/senses/sanctuary-grounding.js +118 -0
  588. package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
  589. package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
  590. package/dist/senses/sanctuary-health-runner.js +104 -0
  591. package/dist/senses/sanctuary-health.js +422 -0
  592. package/dist/senses/sanctuary-install-state-contract.js +169 -0
  593. package/dist/senses/sanctuary-interactive-control.js +410 -0
  594. package/dist/senses/sanctuary-media-catalog-contract.js +259 -0
  595. package/dist/senses/sanctuary-media-optimization.js +514 -0
  596. package/dist/senses/sanctuary-runtime.js +369 -0
  597. package/dist/senses/sanctuary-sab.js +85 -0
  598. package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
  599. package/dist/senses/shared-turn.js +793 -0
  600. package/dist/senses/shepherd/client.js +196 -0
  601. package/dist/senses/shepherd/cmux.js +344 -0
  602. package/dist/senses/shepherd/herdr.js +315 -0
  603. package/dist/senses/shepherd/host.js +14 -0
  604. package/dist/senses/shepherd/judge.js +137 -0
  605. package/dist/senses/shepherd/owner-notice.js +245 -0
  606. package/dist/senses/shepherd/redact.js +66 -0
  607. package/dist/senses/shepherd/returns.js +79 -0
  608. package/dist/senses/shepherd/sense.js +309 -0
  609. package/dist/senses/shepherd-entry.js +78 -0
  610. package/dist/senses/surface-tool.js +109 -0
  611. package/dist/senses/teams-entry.js +68 -8
  612. package/dist/senses/teams.js +598 -233
  613. package/dist/senses/telegram-admission.js +718 -0
  614. package/dist/senses/telegram-approval-runtime.js +793 -0
  615. package/dist/senses/telegram-attachments.js +186 -0
  616. package/dist/senses/telegram-audit-ledger.js +220 -0
  617. package/dist/senses/telegram-authority-transport.js +231 -0
  618. package/dist/senses/telegram-client.js +1749 -0
  619. package/dist/senses/telegram-effect-adapter.js +900 -0
  620. package/dist/senses/telegram-entry.js +83 -0
  621. package/dist/senses/telegram-handoff.js +80 -0
  622. package/dist/senses/telegram.js +2405 -0
  623. package/dist/senses/trust-gate.js +104 -9
  624. package/dist/senses/voice/audio-playback.js +237 -0
  625. package/dist/senses/voice/audio-routing.js +119 -0
  626. package/dist/senses/voice/call-auth.js +250 -0
  627. package/dist/senses/voice/elevenlabs.js +202 -0
  628. package/dist/senses/voice/floor-control.js +431 -0
  629. package/dist/senses/voice/floor-controller.js +115 -0
  630. package/dist/senses/voice/golden-path.js +116 -0
  631. package/dist/senses/voice/index.js +29 -0
  632. package/dist/senses/voice/local-audio-control.js +344 -0
  633. package/dist/senses/voice/local-audio-devices.js +516 -0
  634. package/dist/senses/voice/local-audio-disclosure.js +174 -0
  635. package/dist/senses/voice/local-audio-identity.js +103 -0
  636. package/dist/senses/voice/local-audio-join.js +325 -0
  637. package/dist/senses/voice/local-audio-mute.js +199 -0
  638. package/dist/senses/voice/local-audio-notify.js +121 -0
  639. package/dist/senses/voice/local-audio-prompts.js +116 -0
  640. package/dist/senses/voice/local-audio-transport.js +427 -0
  641. package/dist/senses/voice/local-audio.js +281 -0
  642. package/dist/senses/voice/local-media-stream.js +145 -0
  643. package/dist/senses/voice/meeting.js +113 -0
  644. package/dist/senses/voice/outbound.js +190 -0
  645. package/dist/senses/voice/phone.js +33 -0
  646. package/dist/senses/voice/playback.js +139 -0
  647. package/dist/senses/voice/process-guards.js +51 -0
  648. package/dist/senses/voice/realtime-eval.js +496 -0
  649. package/dist/senses/voice/realtime-tool-schema.js +195 -0
  650. package/dist/senses/voice/realtime-trace.js +531 -0
  651. package/dist/senses/voice/transcript.js +70 -0
  652. package/dist/senses/voice/turn.js +191 -0
  653. package/dist/senses/voice/twilio-phone-runtime.js +836 -0
  654. package/dist/senses/voice/twilio-phone.js +5454 -0
  655. package/dist/senses/voice/types.js +2 -0
  656. package/dist/senses/voice/whisper.js +161 -0
  657. package/dist/senses/voice-entry.js +83 -0
  658. package/dist/senses/voice-realtime-eval-command.js +99 -0
  659. package/dist/senses/voice-realtime-eval-entry.js +21 -0
  660. package/dist/senses/voice-twilio-entry.js +87 -0
  661. package/dist/trips/core.js +138 -0
  662. package/dist/trips/store.js +265 -0
  663. package/dist/util/frontmatter.js +69 -0
  664. package/npm-shrinkwrap.json +8100 -0
  665. package/package.json +74 -13
  666. package/skills/agent-commerce.md +113 -0
  667. package/skills/browser-navigation.md +117 -0
  668. package/skills/commerce-setup-guide.md +116 -0
  669. package/skills/commerce-setup.md +84 -0
  670. package/skills/configure-dev-tools.md +99 -0
  671. package/skills/travel-planning.md +138 -0
  672. package/dist/heart/daemon/auth-flow.js +0 -430
  673. package/dist/heart/daemon/ouro-path-installer.js +0 -260
  674. package/dist/heart/daemon/ouro-version-manager.js +0 -171
  675. package/dist/heart/daemon/update-hooks.js +0 -138
  676. package/dist/heart/obligations.js +0 -191
  677. package/dist/heart/safe-workspace.js +0 -362
  678. package/dist/heart/session-recall.js +0 -116
  679. package/dist/mind/friends/channel.js +0 -84
  680. package/dist/mind/friends/group-context.js +0 -144
  681. package/dist/mind/friends/resolver.js +0 -84
  682. package/dist/mind/friends/store-file.js +0 -190
  683. package/dist/mind/friends/store.js +0 -4
  684. package/dist/mind/friends/tokens.js +0 -26
  685. package/dist/mind/friends/trust-explanation.js +0 -74
  686. package/dist/mind/friends/types.js +0 -29
  687. package/dist/repertoire/tasks/board.js +0 -134
  688. package/dist/repertoire/tasks/index.js +0 -224
  689. package/dist/repertoire/tasks/lifecycle.js +0 -80
  690. package/dist/repertoire/tasks/middleware.js +0 -65
  691. package/dist/repertoire/tasks/parser.js +0 -173
  692. package/dist/repertoire/tasks/scanner.js +0 -132
  693. package/dist/repertoire/tasks/transitions.js +0 -144
  694. package/dist/senses/bluebubbles-entry.js +0 -13
  695. package/dist/senses/bluebubbles.js +0 -1181
  696. package/dist/senses/debug-activity.js +0 -154
  697. package/dist/senses/inner-dialog-worker.js +0 -90
  698. package/dist/senses/inner-dialog.js +0 -525
  699. package/subagents/README.md +0 -7
  700. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  701. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  702. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  703. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  704. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  705. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  706. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  707. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  708. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  709. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  710. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  711. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  712. /package/dist/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +0 -0
  713. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  714. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  715. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  716. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,726 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.STALE_INDEX_LOCK_MS = exports.SYNC_GIT_TIMEOUT_MS = exports.SYNC_GIT_MAX_BUFFER_BYTES = exports.SYNC_FILE_SIZE_LIMIT_BYTES = void 0;
37
+ exports.pendingSyncPath = pendingSyncPath;
38
+ exports.skippedSyncFilesPath = skippedSyncFilesPath;
39
+ exports.clearPendingSync = clearPendingSync;
40
+ exports.preTurnPull = preTurnPull;
41
+ exports.postTurnPush = postTurnPush;
42
+ exports.preTurnPullAsync = preTurnPullAsync;
43
+ const child_process_1 = require("child_process");
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const runtime_1 = require("../nerves/runtime");
47
+ const sync_health_1 = require("./sync-health");
48
+ /**
49
+ * Sync never commits a file larger than this. GitHub rejects any push that
50
+ * contains a file over 100 MiB and warns above 50 MiB; one such file in an
51
+ * unpushed commit blocks every later push from the bundle. The guard leaves
52
+ * the file in the working tree, uncommitted, and records it.
53
+ */
54
+ exports.SYNC_FILE_SIZE_LIMIT_BYTES = 50 * 1024 * 1024;
55
+ /**
56
+ * Output buffer for git commands whose output grows with the number of
57
+ * changed files. Node's 1 MiB default made `git status` fail with ENOBUFS
58
+ * once a bundle held about 30,000 changed files, which stopped sync.
59
+ */
60
+ exports.SYNC_GIT_MAX_BUFFER_BYTES = 256 * 1024 * 1024;
61
+ /**
62
+ * Timeout for sync's add, commit, push and pull. `git add -A` took 17 s on a
63
+ * bundle with 30,000 changed files, past the old 10 s limit.
64
+ */
65
+ exports.SYNC_GIT_TIMEOUT_MS = 120_000;
66
+ function pendingSyncPath(agentRoot) {
67
+ return path.join(agentRoot, "state", "pending-sync.json");
68
+ }
69
+ function skippedSyncFilesPath(agentRoot) {
70
+ return path.join(agentRoot, "state", "sync-skipped-files.json");
71
+ }
72
+ function readPreviousFailure(agentRoot) {
73
+ try {
74
+ return (0, sync_health_1.parseBundleSyncFailure)(JSON.parse(fs.readFileSync(pendingSyncPath(agentRoot), "utf-8")));
75
+ }
76
+ catch {
77
+ return null;
78
+ }
79
+ }
80
+ function writePendingSync(agentRoot, error, classification, conflictFiles) {
81
+ const previous = readPreviousFailure(agentRoot);
82
+ const failedAt = new Date().toISOString();
83
+ const previousFirst = previous && previous.firstFailedAt !== "unknown" ? previous.firstFailedAt : null;
84
+ fs.mkdirSync(path.join(agentRoot, "state"), { recursive: true });
85
+ const record = {
86
+ error,
87
+ failedAt,
88
+ classification,
89
+ conflictFiles,
90
+ firstFailedAt: previousFirst ?? failedAt,
91
+ consecutiveFailures: (previous?.consecutiveFailures ?? 0) + 1,
92
+ };
93
+ fs.writeFileSync(pendingSyncPath(agentRoot), JSON.stringify(record, null, 2), "utf-8");
94
+ }
95
+ function recordPendingSync(agentRoot, error, classification, conflictFiles) {
96
+ try {
97
+ writePendingSync(agentRoot, error, classification, conflictFiles);
98
+ }
99
+ catch {
100
+ // Best effort: the caller's nerves event still records the failure.
101
+ }
102
+ }
103
+ /**
104
+ * Remove `state/pending-sync.json` after a sync that reached the remote (or
105
+ * committed, for a local-only bundle). The record otherwise stays, so the
106
+ * start-of-turn packet, `ouro status` and the daemon health check keep
107
+ * reporting the failure until it is fixed.
108
+ */
109
+ function clearPendingSync(agentRoot) {
110
+ try {
111
+ fs.rmSync(pendingSyncPath(agentRoot), { force: true });
112
+ }
113
+ catch {
114
+ // Best effort: a stale record is reported again and cleared next time.
115
+ }
116
+ }
117
+ function writeSkippedSyncFiles(agentRoot, files) {
118
+ try {
119
+ if (files.length === 0) {
120
+ fs.rmSync(skippedSyncFilesPath(agentRoot), { force: true });
121
+ return;
122
+ }
123
+ fs.mkdirSync(path.join(agentRoot, "state"), { recursive: true });
124
+ const record = {
125
+ updatedAt: new Date().toISOString(),
126
+ limitBytes: exports.SYNC_FILE_SIZE_LIMIT_BYTES,
127
+ files,
128
+ };
129
+ fs.writeFileSync(skippedSyncFilesPath(agentRoot), JSON.stringify(record, null, 2), "utf-8");
130
+ }
131
+ catch {
132
+ // Best effort: the nerves event emitted by the caller names the files.
133
+ }
134
+ }
135
+ /** Parse `git diff --cached --name-status -z` output. */
136
+ function parseStagedChanges(output) {
137
+ const tokens = output.split("\0").filter((entry) => entry.length > 0);
138
+ const changes = [];
139
+ for (let index = 0; index < tokens.length;) {
140
+ const status = tokens[index];
141
+ if (status.startsWith("R") || status.startsWith("C")) {
142
+ changes.push({ status, fromPath: tokens[index + 1], path: tokens[index + 2] });
143
+ index += 3;
144
+ }
145
+ else {
146
+ changes.push({ status, path: tokens[index + 1] });
147
+ index += 2;
148
+ }
149
+ }
150
+ return changes;
151
+ }
152
+ /**
153
+ * Unstage every staged file larger than `SYNC_FILE_SIZE_LIMIT_BYTES`. The
154
+ * file stays in the working tree and the previous committed version, if any,
155
+ * stays in the index, so nothing is deleted on other machines. For a rename,
156
+ * the deletion of the old path is unstaged too; otherwise the remote would
157
+ * lose the old path while never receiving the new one.
158
+ */
159
+ function unstageOversizedFiles(agentRoot) {
160
+ const changes = parseStagedChanges((0, child_process_1.execFileSync)("git", ["diff", "--cached", "--name-status", "-M", "-z"], {
161
+ cwd: agentRoot,
162
+ stdio: "pipe",
163
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
164
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
165
+ }).toString());
166
+ const oversized = [];
167
+ const unstage = [];
168
+ for (const change of changes) {
169
+ if (change.status.startsWith("D"))
170
+ continue;
171
+ let bytes;
172
+ try {
173
+ bytes = fs.lstatSync(path.join(agentRoot, change.path)).size;
174
+ }
175
+ catch {
176
+ continue;
177
+ }
178
+ if (bytes <= exports.SYNC_FILE_SIZE_LIMIT_BYTES)
179
+ continue;
180
+ oversized.push({ path: change.path, bytes });
181
+ unstage.push(change.path);
182
+ if (change.status.startsWith("R") && change.fromPath)
183
+ unstage.push(change.fromPath);
184
+ }
185
+ if (oversized.length === 0)
186
+ return oversized;
187
+ (0, child_process_1.execFileSync)("git", ["--literal-pathspecs", "reset", "-q", "--", ...unstage], {
188
+ cwd: agentRoot,
189
+ stdio: "pipe",
190
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
191
+ });
192
+ (0, runtime_1.emitNervesEvent)({
193
+ level: "warn",
194
+ component: "heart",
195
+ event: "heart.sync_oversized_files_skipped",
196
+ message: "post-turn push: left files over the sync size limit uncommitted",
197
+ meta: { agentRoot, limitBytes: exports.SYNC_FILE_SIZE_LIMIT_BYTES, files: oversized },
198
+ });
199
+ return oversized;
200
+ }
201
+ function hasStagedChanges(agentRoot) {
202
+ try {
203
+ (0, child_process_1.execFileSync)("git", ["diff", "--cached", "--quiet"], {
204
+ cwd: agentRoot,
205
+ stdio: "pipe",
206
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
207
+ });
208
+ return false;
209
+ }
210
+ catch {
211
+ return true;
212
+ }
213
+ }
214
+ function collectRebaseConflictFiles(agentRoot) {
215
+ try {
216
+ const output = (0, child_process_1.execFileSync)("git", ["status", "--porcelain=v1"], {
217
+ cwd: agentRoot,
218
+ stdio: "pipe",
219
+ timeout: 5000,
220
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
221
+ }).toString();
222
+ const files = [];
223
+ for (const line of output.split("\n")) {
224
+ // Unmerged paths in porcelain v1 are prefixed with UU/AA/DD/AU/UA/DU/UD
225
+ if (/^(UU|AA|DD|AU|UA|DU|UD) /.test(line)) {
226
+ files.push(line.slice(3).trim());
227
+ }
228
+ }
229
+ return files;
230
+ }
231
+ catch {
232
+ /* v8 ignore next -- git status --porcelain failure inside a repo would require a corrupt repo @preserve */
233
+ return [];
234
+ }
235
+ }
236
+ /**
237
+ * Check whether the bundle is initialized as a git repo.
238
+ * Used by both pre-turn pull and post-turn push to surface a clear,
239
+ * actionable error when sync is enabled but the user never ran `git init`
240
+ * inside their bundle. This error is propagated all the way into the
241
+ * agent's start-of-turn packet as a Sync warning, so the agent can
242
+ * either ask the user or run `git init` itself.
243
+ */
244
+ function ensureGitRepo(agentRoot) {
245
+ if (fs.existsSync(path.join(agentRoot, ".git"))) {
246
+ return { ok: true };
247
+ }
248
+ const error = `bundle is not a git repo; run \`git init\` inside ${agentRoot} to enable sync (or disable sync in agent.json)`;
249
+ return { ok: false, error };
250
+ }
251
+ /**
252
+ * Git holds `.git/index.lock` for milliseconds to seconds, and every git call
253
+ * in this module has a timeout of 30s or less. A lock older than this was left
254
+ * behind by a git process that died mid-write; while it exists every `git add`
255
+ * fails, which silently stopped one bundle's sync for three months.
256
+ */
257
+ exports.STALE_INDEX_LOCK_MS = 10 * 60 * 1000;
258
+ // Only an empty lock is removed: git writes the new index into the lock right
259
+ // after creating it, while a live `git commit` waiting in an editor holds a
260
+ // full, unchanging lock that can be older than the threshold. When `.git` is a
261
+ // gitdir file (worktree), statSync fails and the lock is left alone.
262
+ function clearStaleIndexLock(agentRoot) {
263
+ const lockPath = path.join(agentRoot, ".git", "index.lock");
264
+ let ageMs;
265
+ try {
266
+ const stat = fs.statSync(lockPath);
267
+ if (stat.size !== 0)
268
+ return;
269
+ ageMs = Date.now() - stat.mtimeMs;
270
+ }
271
+ catch {
272
+ return;
273
+ }
274
+ if (ageMs < exports.STALE_INDEX_LOCK_MS)
275
+ return;
276
+ try {
277
+ fs.rmSync(lockPath, { force: true });
278
+ }
279
+ catch (err) {
280
+ (0, runtime_1.emitNervesEvent)({
281
+ level: "warn",
282
+ component: "heart",
283
+ event: "heart.sync_stale_lock_clear_failed",
284
+ message: "post-turn push: could not remove stale git index.lock",
285
+ meta: { agentRoot, lockPath, error: err instanceof Error ? err.message : /* v8 ignore next -- defensive non-Error catch @preserve */ String(err) },
286
+ });
287
+ return;
288
+ }
289
+ (0, runtime_1.emitNervesEvent)({
290
+ level: "warn",
291
+ component: "heart",
292
+ event: "heart.sync_stale_lock_cleared",
293
+ message: "post-turn push: removed stale git index.lock",
294
+ meta: { agentRoot, lockPath, ageMs },
295
+ });
296
+ }
297
+ /**
298
+ * Pre-turn pull: sync the agent bundle from remote before assembling the start-of-turn packet.
299
+ *
300
+ * If the bundle has no git remote configured, the pull is skipped and the function
301
+ * returns ok — matching the no-remote behavior of postTurnPush. This supports the
302
+ * "local-only sync" mode where the bundle accumulates a commit log without ever
303
+ * pushing or pulling from a remote.
304
+ */
305
+ function preTurnPull(agentRoot, config) {
306
+ (0, runtime_1.emitNervesEvent)({
307
+ component: "heart",
308
+ event: "heart.sync_pull_start",
309
+ message: "pre-turn pull starting",
310
+ meta: { agentRoot, remote: config.remote },
311
+ });
312
+ // Check that the bundle is actually a git repo before touching git at all.
313
+ // Surfaces a clear, actionable error via syncFailure → start-of-turn packet
314
+ // so the agent can propose running `git init` (or just do it).
315
+ const repoCheck = ensureGitRepo(agentRoot);
316
+ if (!repoCheck.ok) {
317
+ (0, runtime_1.emitNervesEvent)({
318
+ level: "warn",
319
+ component: "heart",
320
+ event: "heart.sync_not_a_repo",
321
+ message: "pre-turn pull failed: bundle is not a git repo",
322
+ meta: { agentRoot },
323
+ });
324
+ return repoCheck;
325
+ }
326
+ // Check if any remote is configured. If not, skip the pull (local-only mode).
327
+ try {
328
+ const remoteOutput = (0, child_process_1.execFileSync)("git", ["remote"], {
329
+ cwd: agentRoot,
330
+ stdio: "pipe",
331
+ timeout: 5000,
332
+ }).toString().trim();
333
+ if (remoteOutput.length === 0) {
334
+ (0, runtime_1.emitNervesEvent)({
335
+ component: "heart",
336
+ event: "heart.sync_pull_end",
337
+ message: "pre-turn pull skipped: no remote configured",
338
+ meta: { agentRoot },
339
+ });
340
+ return { ok: true };
341
+ }
342
+ }
343
+ catch (err) {
344
+ const error = err instanceof Error ? err.message : String(err);
345
+ (0, runtime_1.emitNervesEvent)({
346
+ component: "heart",
347
+ event: "heart.sync_pull_error",
348
+ message: "pre-turn pull failed: git remote check failed",
349
+ meta: { agentRoot, error },
350
+ });
351
+ return { ok: false, error };
352
+ }
353
+ try {
354
+ (0, child_process_1.execFileSync)("git", ["pull", config.remote], {
355
+ cwd: agentRoot,
356
+ stdio: "pipe",
357
+ timeout: 30000,
358
+ });
359
+ (0, runtime_1.emitNervesEvent)({
360
+ component: "heart",
361
+ event: "heart.sync_pull_end",
362
+ message: "pre-turn pull complete",
363
+ meta: { agentRoot },
364
+ });
365
+ return { ok: true };
366
+ }
367
+ catch (err) {
368
+ const error = err instanceof Error ? err.message : String(err);
369
+ (0, runtime_1.emitNervesEvent)({
370
+ component: "heart",
371
+ event: "heart.sync_pull_error",
372
+ message: "pre-turn pull failed",
373
+ meta: { agentRoot, error },
374
+ });
375
+ return { ok: false, error };
376
+ }
377
+ }
378
+ /**
379
+ * Post-turn push: discover dirty files via `git status`, commit, and push.
380
+ * Uses git-status-based discovery instead of explicit path tracking, ensuring
381
+ * all file writers are captured regardless of whether they call a tracking API.
382
+ */
383
+ function postTurnPush(agentRoot, config) {
384
+ (0, runtime_1.emitNervesEvent)({
385
+ component: "heart",
386
+ event: "heart.sync_push_start",
387
+ message: "post-turn push starting",
388
+ meta: { agentRoot, remote: config.remote },
389
+ });
390
+ // Same git-repo check as preTurnPull. This is the more common failure path
391
+ // since postTurnPush runs after every turn while preTurnPull only runs on
392
+ // user-initiated turns. Prior to this guard, an un-init'd bundle would fail
393
+ // the git-status invocation below with a generic "not a git repository"
394
+ // error; now we catch it explicitly with an actionable message.
395
+ const repoCheck = ensureGitRepo(agentRoot);
396
+ if (!repoCheck.ok) {
397
+ (0, runtime_1.emitNervesEvent)({
398
+ level: "warn",
399
+ component: "heart",
400
+ event: "heart.sync_not_a_repo",
401
+ message: "post-turn push failed: bundle is not a git repo",
402
+ meta: { agentRoot },
403
+ });
404
+ return repoCheck;
405
+ }
406
+ let statusOutput;
407
+ try {
408
+ statusOutput = (0, child_process_1.execFileSync)("git", ["status", "--porcelain"], {
409
+ cwd: agentRoot,
410
+ stdio: "pipe",
411
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
412
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
413
+ }).toString().trim();
414
+ }
415
+ catch (err) {
416
+ const error = err instanceof Error ? err.message : String(err);
417
+ recordPendingSync(agentRoot, error, "unknown", []);
418
+ (0, runtime_1.emitNervesEvent)({
419
+ component: "heart",
420
+ event: "heart.sync_push_error",
421
+ message: "post-turn push: git status failed",
422
+ meta: { agentRoot, error },
423
+ });
424
+ return { ok: false, error };
425
+ }
426
+ if (statusOutput.length === 0) {
427
+ // Nothing to commit, so nothing is skipped for size any more.
428
+ writeSkippedSyncFiles(agentRoot, []);
429
+ return syncCleanTree(agentRoot, config);
430
+ }
431
+ const changedCount = statusOutput.split("\n").length;
432
+ clearStaleIndexLock(agentRoot);
433
+ try {
434
+ (0, child_process_1.execFileSync)("git", ["add", "-A"], {
435
+ cwd: agentRoot,
436
+ stdio: "pipe",
437
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
438
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
439
+ });
440
+ const skippedFiles = unstageOversizedFiles(agentRoot);
441
+ writeSkippedSyncFiles(agentRoot, skippedFiles);
442
+ if (skippedFiles.length > 0 && !hasStagedChanges(agentRoot)) {
443
+ (0, runtime_1.emitNervesEvent)({
444
+ component: "heart",
445
+ event: "heart.sync_push_end",
446
+ message: "post-turn push: only oversized files changed, nothing committed",
447
+ meta: { agentRoot, changedCount, skippedCount: skippedFiles.length },
448
+ });
449
+ return syncCleanTree(agentRoot, config);
450
+ }
451
+ // -q: without it git prints a create/delete line per file, which overran
452
+ // the output buffer on a 30,000-file commit after the commit had landed.
453
+ (0, child_process_1.execFileSync)("git", ["commit", "-q", "-m", "sync: post-turn update"], {
454
+ cwd: agentRoot,
455
+ stdio: "pipe",
456
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
457
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
458
+ });
459
+ if (!hasRemote(agentRoot)) {
460
+ (0, runtime_1.emitNervesEvent)({
461
+ component: "heart",
462
+ event: "heart.sync_push_end",
463
+ message: "post-turn push: committed locally, no remote configured",
464
+ meta: { agentRoot, changedCount },
465
+ });
466
+ clearPendingSync(agentRoot);
467
+ return { ok: true };
468
+ }
469
+ return pushWithRebaseRetry(agentRoot, config, changedCount);
470
+ }
471
+ catch (err) {
472
+ const error = err instanceof Error ? err.message : String(err);
473
+ // Record it so the start-of-turn packet surfaces the failure; otherwise a
474
+ // failing local commit is visible only in nerves logs.
475
+ recordPendingSync(agentRoot, error, "unknown", []);
476
+ (0, runtime_1.emitNervesEvent)({
477
+ component: "heart",
478
+ event: "heart.sync_push_error",
479
+ message: "post-turn push failed",
480
+ meta: { agentRoot, error },
481
+ });
482
+ return { ok: false, error };
483
+ }
484
+ }
485
+ function hasRemote(agentRoot) {
486
+ return (0, child_process_1.execFileSync)("git", ["remote"], {
487
+ cwd: agentRoot,
488
+ stdio: "pipe",
489
+ timeout: 5000,
490
+ }).toString().trim().length > 0;
491
+ }
492
+ /**
493
+ * Nothing new to commit. A failure record must not outlive the problem, and
494
+ * commits left behind by an earlier failed push still need to reach the
495
+ * remote: with no remote, or nothing ahead of the upstream, the record is
496
+ * cleared; with unpushed commits, the push is retried.
497
+ */
498
+ function syncCleanTree(agentRoot, config) {
499
+ try {
500
+ if (!hasRemote(agentRoot)) {
501
+ clearPendingSync(agentRoot);
502
+ }
503
+ else {
504
+ const ahead = Number.parseInt((0, child_process_1.execFileSync)("git", ["rev-list", "--count", "@{upstream}..HEAD"], {
505
+ cwd: agentRoot,
506
+ stdio: "pipe",
507
+ timeout: 5000,
508
+ }).toString().trim(), 10);
509
+ if (ahead > 0)
510
+ return pushWithRebaseRetry(agentRoot, config, 0);
511
+ if (ahead === 0)
512
+ clearPendingSync(agentRoot);
513
+ }
514
+ }
515
+ catch (err) {
516
+ // No upstream tracked (or git failed): nothing to compare against, so
517
+ // leave any failure record as it is rather than guess.
518
+ (0, runtime_1.emitNervesEvent)({
519
+ component: "heart",
520
+ event: "heart.sync_upstream_unknown",
521
+ message: "post-turn push: could not compare with upstream",
522
+ meta: { agentRoot, error: err instanceof Error ? err.message : /* v8 ignore next -- defensive non-Error catch @preserve */ String(err) },
523
+ });
524
+ }
525
+ (0, runtime_1.emitNervesEvent)({
526
+ component: "heart",
527
+ event: "heart.sync_push_end",
528
+ message: "post-turn push: no changes to sync",
529
+ meta: { agentRoot },
530
+ });
531
+ return { ok: true };
532
+ }
533
+ function pushWithRebaseRetry(agentRoot, config, changedCount) {
534
+ try {
535
+ (0, child_process_1.execFileSync)("git", ["push", config.remote], {
536
+ cwd: agentRoot,
537
+ stdio: "pipe",
538
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
539
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
540
+ });
541
+ }
542
+ catch {
543
+ // Push rejected -- try pull-rebase-push. --autostash: an oversized file
544
+ // the size guard left uncommitted is an unstaged change, and a plain
545
+ // rebase refuses to start while one exists.
546
+ let rebaseError = null;
547
+ try {
548
+ (0, child_process_1.execFileSync)("git", ["pull", "--rebase", "--autostash", config.remote], {
549
+ cwd: agentRoot,
550
+ stdio: "pipe",
551
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
552
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
553
+ });
554
+ }
555
+ catch (err) {
556
+ rebaseError = err instanceof Error ? err.message : String(err);
557
+ }
558
+ if (rebaseError === null) {
559
+ try {
560
+ (0, child_process_1.execFileSync)("git", ["push", config.remote], {
561
+ cwd: agentRoot,
562
+ stdio: "pipe",
563
+ timeout: exports.SYNC_GIT_TIMEOUT_MS,
564
+ maxBuffer: exports.SYNC_GIT_MAX_BUFFER_BYTES,
565
+ });
566
+ // rebase + retry push both succeeded — fall through to success
567
+ (0, runtime_1.emitNervesEvent)({
568
+ component: "heart",
569
+ event: "heart.sync_push_end",
570
+ message: "post-turn push complete after rebase retry",
571
+ meta: { agentRoot, changedCount },
572
+ });
573
+ clearPendingSync(agentRoot);
574
+ return { ok: true };
575
+ }
576
+ catch (retryErr) {
577
+ // Second push rejected — remote advanced again during rebase
578
+ const retryError = retryErr instanceof Error ? retryErr.message : /* v8 ignore next -- defensive non-Error catch @preserve */ String(retryErr);
579
+ recordPendingSync(agentRoot, retryError, "push_rejected", []);
580
+ (0, runtime_1.emitNervesEvent)({
581
+ component: "heart",
582
+ event: "heart.sync_push_error",
583
+ message: "post-turn push failed after retry: push_rejected",
584
+ meta: { agentRoot, error: retryError, classification: "push_rejected" },
585
+ });
586
+ return { ok: false, error: retryError };
587
+ }
588
+ }
589
+ // Rebase failed — detect conflict files via git status. Preserve
590
+ // the original rebase error message so callers see the real cause.
591
+ const conflictFiles = collectRebaseConflictFiles(agentRoot);
592
+ const classification = conflictFiles.length > 0 ? "pull_rebase_conflict" : "unknown";
593
+ recordPendingSync(agentRoot, rebaseError, classification, conflictFiles);
594
+ (0, runtime_1.emitNervesEvent)({
595
+ component: "heart",
596
+ event: "heart.sync_push_error",
597
+ message: `post-turn push failed: ${classification}`,
598
+ meta: { agentRoot, error: rebaseError, classification, conflictFiles },
599
+ });
600
+ return { ok: false, error: rebaseError };
601
+ }
602
+ (0, runtime_1.emitNervesEvent)({
603
+ component: "heart",
604
+ event: "heart.sync_push_end",
605
+ message: "post-turn push complete",
606
+ meta: { agentRoot, changedCount },
607
+ });
608
+ clearPendingSync(agentRoot);
609
+ return { ok: true };
610
+ }
611
+ /**
612
+ * Layer 2 — async, signal-aware sibling of `preTurnPull`.
613
+ *
614
+ * Used by `runBootSyncProbe` (the `ouro up` boot orchestrator) to perform
615
+ * the pre-flight pull with end-to-end `AbortSignal` propagation. The
616
+ * underlying `child_process.execFile` accepts the signal and kills the git
617
+ * child process when it aborts, so a hung remote (DNS hole, slow server)
618
+ * can be cut by the boot timeout wrapper rather than hanging the whole
619
+ * boot.
620
+ *
621
+ * The legacy sync `preTurnPull` is preserved unchanged for the per-turn
622
+ * pipeline at `src/senses/pipeline.ts:522`. The two functions share the
623
+ * same `.git` and remote-availability gates — the only difference is the
624
+ * pull itself: `execFileSync` (no signal) vs `execFile` + `{ signal }`.
625
+ *
626
+ * Honour-the-signal contract:
627
+ * - If `options.signal` is already aborted at call time, the pull is
628
+ * skipped and the result is `{ ok: false, error: "aborted" }`.
629
+ * - If `options.signal` aborts mid-fetch, the child receives `SIGTERM`
630
+ * via Node's built-in AbortSignal handling, and the result is
631
+ * `{ ok: false, error: <abort message> }`.
632
+ * - With no signal supplied, behaviour matches the sync version (subject
633
+ * to the small differences listed above — same git-repo / no-remote
634
+ * gates and same nerves events).
635
+ */
636
+ function preTurnPullAsync(agentRoot, config, options = {}) {
637
+ (0, runtime_1.emitNervesEvent)({
638
+ component: "heart",
639
+ event: "heart.sync_pull_start",
640
+ message: "pre-turn pull starting (async)",
641
+ meta: { agentRoot, remote: config.remote },
642
+ });
643
+ // Bail early when the caller has already aborted — saves a git invocation
644
+ // and signals failure consistently.
645
+ if (options.signal?.aborted) {
646
+ (0, runtime_1.emitNervesEvent)({
647
+ level: "warn",
648
+ component: "heart",
649
+ event: "heart.sync_pull_aborted",
650
+ message: "pre-turn pull skipped: signal already aborted",
651
+ meta: { agentRoot },
652
+ });
653
+ return Promise.resolve({ ok: false, error: "aborted before pull started" });
654
+ }
655
+ // Same .git presence check as the sync version.
656
+ const repoCheck = ensureGitRepo(agentRoot);
657
+ if (!repoCheck.ok) {
658
+ (0, runtime_1.emitNervesEvent)({
659
+ level: "warn",
660
+ component: "heart",
661
+ event: "heart.sync_not_a_repo",
662
+ message: "pre-turn pull failed: bundle is not a git repo (async)",
663
+ meta: { agentRoot },
664
+ });
665
+ return Promise.resolve(repoCheck);
666
+ }
667
+ // Remote-presence check stays sync — it's a fast local op and doesn't
668
+ // need cancellation. The hangable op is the actual pull.
669
+ try {
670
+ const remoteOutput = (0, child_process_1.execFileSync)("git", ["remote"], {
671
+ cwd: agentRoot,
672
+ stdio: "pipe",
673
+ timeout: 5000,
674
+ }).toString().trim();
675
+ if (remoteOutput.length === 0) {
676
+ (0, runtime_1.emitNervesEvent)({
677
+ component: "heart",
678
+ event: "heart.sync_pull_end",
679
+ message: "pre-turn pull skipped: no remote configured (async)",
680
+ meta: { agentRoot },
681
+ });
682
+ return Promise.resolve({ ok: true });
683
+ }
684
+ }
685
+ catch (err) {
686
+ const error = err instanceof Error ? err.message : String(err);
687
+ (0, runtime_1.emitNervesEvent)({
688
+ component: "heart",
689
+ event: "heart.sync_pull_error",
690
+ message: "pre-turn pull failed: git remote check failed (async)",
691
+ meta: { agentRoot, error },
692
+ });
693
+ return Promise.resolve({ ok: false, error });
694
+ }
695
+ // The hangable op. `execFile` accepts `{ signal }` and kills the child
696
+ // when the signal aborts — that's the whole point of the async path.
697
+ const execOptions = {
698
+ cwd: agentRoot,
699
+ timeout: 30000,
700
+ };
701
+ if (options.signal) {
702
+ execOptions.signal = options.signal;
703
+ }
704
+ return new Promise((resolve) => {
705
+ (0, child_process_1.execFile)("git", ["pull", config.remote], execOptions, (err) => {
706
+ if (err) {
707
+ const error = err instanceof Error ? err.message : String(err);
708
+ (0, runtime_1.emitNervesEvent)({
709
+ component: "heart",
710
+ event: "heart.sync_pull_error",
711
+ message: "pre-turn pull failed (async)",
712
+ meta: { agentRoot, error },
713
+ });
714
+ resolve({ ok: false, error });
715
+ return;
716
+ }
717
+ (0, runtime_1.emitNervesEvent)({
718
+ component: "heart",
719
+ event: "heart.sync_pull_end",
720
+ message: "pre-turn pull complete (async)",
721
+ meta: { agentRoot },
722
+ });
723
+ resolve({ ok: true });
724
+ });
725
+ });
726
+ }