@ouro.bot/cli 0.1.0-alpha.50 → 0.1.0-alpha.500

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 (366) hide show
  1. package/README.md +133 -19
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  4. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  5. package/changelog.json +3176 -0
  6. package/dist/arc/attention-types.js +8 -0
  7. package/dist/arc/cares.js +140 -0
  8. package/dist/arc/episodes.js +117 -0
  9. package/dist/arc/intentions.js +133 -0
  10. package/dist/arc/json-store.js +117 -0
  11. package/dist/arc/obligations.js +237 -0
  12. package/dist/arc/packets.js +193 -0
  13. package/dist/arc/presence.js +185 -0
  14. package/dist/arc/task-lifecycle.js +65 -0
  15. package/dist/heart/active-work.js +867 -35
  16. package/dist/heart/agent-entry.js +58 -3
  17. package/dist/heart/attachments/image-normalize.js +194 -0
  18. package/dist/heart/attachments/materialize.js +97 -0
  19. package/dist/heart/attachments/originals.js +88 -0
  20. package/dist/heart/attachments/render.js +29 -0
  21. package/dist/heart/attachments/sources/adapter.js +2 -0
  22. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  23. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  24. package/dist/heart/attachments/sources/index.js +16 -0
  25. package/dist/heart/attachments/store.js +103 -0
  26. package/dist/heart/attachments/types.js +93 -0
  27. package/dist/heart/auth/auth-flow.js +426 -0
  28. package/dist/heart/background-operations.js +281 -0
  29. package/dist/heart/bundle-state.js +168 -0
  30. package/dist/heart/commitments.js +111 -0
  31. package/dist/heart/config-registry.js +304 -0
  32. package/dist/heart/config.js +119 -129
  33. package/dist/heart/core.js +898 -244
  34. package/dist/heart/cross-chat-delivery.js +131 -0
  35. package/dist/heart/daemon/agent-config-check.js +490 -0
  36. package/dist/heart/daemon/agent-discovery.js +79 -3
  37. package/dist/heart/daemon/agent-service.js +360 -0
  38. package/dist/heart/daemon/agentic-repair.js +216 -0
  39. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  40. package/dist/heart/daemon/cadence.js +70 -0
  41. package/dist/heart/daemon/cli-defaults.js +640 -0
  42. package/dist/heart/daemon/cli-exec.js +7239 -0
  43. package/dist/heart/daemon/cli-help.js +493 -0
  44. package/dist/heart/daemon/cli-parse.js +1533 -0
  45. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  46. package/dist/heart/daemon/cli-render.js +561 -0
  47. package/dist/heart/daemon/cli-types.js +8 -0
  48. package/dist/heart/daemon/connect-bay.js +323 -0
  49. package/dist/heart/daemon/daemon-cli.js +29 -1631
  50. package/dist/heart/daemon/daemon-entry.js +345 -3
  51. package/dist/heart/daemon/daemon-health.js +141 -0
  52. package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
  53. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  54. package/dist/heart/daemon/daemon.js +677 -58
  55. package/dist/heart/daemon/dns-workflow.js +394 -0
  56. package/dist/heart/daemon/doctor-types.js +8 -0
  57. package/dist/heart/daemon/doctor.js +615 -0
  58. package/dist/heart/daemon/health-monitor.js +92 -1
  59. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  60. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  61. package/dist/heart/daemon/http-health-probe.js +80 -0
  62. package/dist/heart/daemon/human-command-screens.js +234 -0
  63. package/dist/heart/daemon/human-readiness.js +114 -0
  64. package/dist/heart/daemon/inner-status.js +89 -0
  65. package/dist/heart/daemon/interactive-repair.js +394 -0
  66. package/dist/heart/daemon/launchd.js +25 -5
  67. package/dist/heart/daemon/log-tailer.js +82 -12
  68. package/dist/heart/daemon/logs-prune.js +110 -0
  69. package/dist/heart/daemon/message-router.js +2 -2
  70. package/dist/heart/daemon/os-cron-deps.js +134 -0
  71. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  72. package/dist/heart/daemon/ouro-entry.js +3 -1
  73. package/dist/heart/daemon/process-manager.js +214 -0
  74. package/dist/heart/daemon/provider-discovery.js +137 -0
  75. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  76. package/dist/heart/daemon/pulse.js +475 -0
  77. package/dist/heart/daemon/readiness-repair.js +365 -0
  78. package/dist/heart/daemon/run-hooks.js +2 -0
  79. package/dist/heart/daemon/runtime-logging.js +67 -16
  80. package/dist/heart/daemon/runtime-metadata.js +73 -0
  81. package/dist/heart/daemon/runtime-mode.js +67 -0
  82. package/dist/heart/daemon/safe-mode.js +161 -0
  83. package/dist/heart/daemon/sense-manager.js +178 -37
  84. package/dist/heart/daemon/session-id-resolver.js +131 -0
  85. package/dist/heart/daemon/skill-management-installer.js +94 -0
  86. package/dist/heart/daemon/socket-client.js +109 -4
  87. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  88. package/dist/heart/daemon/startup-tui.js +264 -0
  89. package/dist/heart/daemon/task-scheduler.js +3 -25
  90. package/dist/heart/daemon/terminal-ui.js +499 -0
  91. package/dist/heart/daemon/thoughts.js +162 -17
  92. package/dist/heart/daemon/up-progress.js +366 -0
  93. package/dist/heart/daemon/vault-items.js +56 -0
  94. package/dist/heart/delegation.js +1 -1
  95. package/dist/heart/habits/habit-migration.js +189 -0
  96. package/dist/heart/habits/habit-parser.js +140 -0
  97. package/dist/heart/habits/habit-runtime-state.js +100 -0
  98. package/dist/heart/habits/habit-scheduler.js +372 -0
  99. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
  100. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  101. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  102. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  103. package/dist/heart/identity.js +201 -66
  104. package/dist/heart/kept-notes.js +357 -0
  105. package/dist/heart/kicks.js +1 -1
  106. package/dist/heart/machine-identity.js +161 -0
  107. package/dist/heart/mail-import-discovery.js +353 -0
  108. package/dist/heart/mcp/mcp-server.js +653 -0
  109. package/dist/heart/migrate-config.js +100 -0
  110. package/dist/heart/model-capabilities.js +59 -0
  111. package/dist/heart/outlook/outlook-http-hooks.js +66 -0
  112. package/dist/heart/outlook/outlook-http-response.js +7 -0
  113. package/dist/heart/outlook/outlook-http-routes.js +244 -0
  114. package/dist/heart/outlook/outlook-http-static.js +103 -0
  115. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  116. package/dist/heart/outlook/outlook-http.js +99 -0
  117. package/dist/heart/outlook/outlook-read.js +31 -0
  118. package/dist/heart/outlook/outlook-types.js +27 -0
  119. package/dist/heart/outlook/outlook-view.js +195 -0
  120. package/dist/heart/outlook/readers/agent-machine.js +382 -0
  121. package/dist/heart/outlook/readers/continuity-readers.js +336 -0
  122. package/dist/heart/outlook/readers/mail.js +362 -0
  123. package/dist/heart/outlook/readers/runtime-readers.js +644 -0
  124. package/dist/heart/outlook/readers/sessions.js +232 -0
  125. package/dist/heart/outlook/readers/shared.js +111 -0
  126. package/dist/heart/platform.js +81 -0
  127. package/dist/heart/provider-attempt.js +134 -0
  128. package/dist/heart/provider-binding-resolver.js +255 -0
  129. package/dist/heart/provider-credentials.js +424 -0
  130. package/dist/heart/provider-failover.js +301 -0
  131. package/dist/heart/provider-models.js +81 -0
  132. package/dist/heart/provider-ping.js +262 -0
  133. package/dist/heart/provider-state.js +216 -0
  134. package/dist/heart/provider-visibility.js +188 -0
  135. package/dist/heart/providers/anthropic-token.js +131 -0
  136. package/dist/heart/providers/anthropic.js +193 -55
  137. package/dist/heart/providers/azure.js +104 -13
  138. package/dist/heart/providers/error-classification.js +63 -0
  139. package/dist/heart/providers/github-copilot.js +145 -0
  140. package/dist/heart/providers/minimax-vlm.js +189 -0
  141. package/dist/heart/providers/minimax.js +29 -7
  142. package/dist/heart/providers/openai-codex.js +63 -39
  143. package/dist/heart/runtime-capability-check.js +170 -0
  144. package/dist/heart/runtime-credentials.js +260 -0
  145. package/dist/heart/sense-truth.js +11 -4
  146. package/dist/heart/session-activity.js +43 -22
  147. package/dist/heart/session-events.js +1089 -0
  148. package/dist/heart/session-playback-cli-main.js +5 -0
  149. package/dist/heart/session-playback-cli.js +36 -0
  150. package/dist/heart/session-playback.js +231 -0
  151. package/dist/heart/session-transcript.js +167 -0
  152. package/dist/heart/start-of-turn-packet.js +345 -0
  153. package/dist/heart/streaming.js +48 -28
  154. package/dist/heart/sync.js +332 -0
  155. package/dist/heart/target-resolution.js +127 -0
  156. package/dist/heart/tempo.js +93 -0
  157. package/dist/heart/temporal-view.js +41 -0
  158. package/dist/heart/tool-activity-callbacks.js +36 -0
  159. package/dist/heart/tool-description.js +135 -0
  160. package/dist/heart/tool-friction.js +55 -0
  161. package/dist/heart/tool-loop.js +200 -0
  162. package/dist/heart/turn-context.js +372 -0
  163. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  164. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  165. package/dist/heart/versioning/ouro-path-installer.js +425 -0
  166. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  167. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  168. package/dist/heart/{daemon → versioning}/update-checker.js +5 -1
  169. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  170. package/dist/mailroom/attention.js +167 -0
  171. package/dist/mailroom/autonomy.js +209 -0
  172. package/dist/mailroom/blob-store.js +606 -0
  173. package/dist/mailroom/core.js +672 -0
  174. package/dist/mailroom/entry.js +160 -0
  175. package/dist/mailroom/file-store.js +426 -0
  176. package/dist/mailroom/mbox-import.js +382 -0
  177. package/dist/mailroom/outbound.js +380 -0
  178. package/dist/mailroom/policy.js +263 -0
  179. package/dist/mailroom/reader.js +219 -0
  180. package/dist/mailroom/search-cache.js +182 -0
  181. package/dist/mailroom/search-relevance.js +319 -0
  182. package/dist/mailroom/smtp-ingress.js +176 -0
  183. package/dist/mailroom/source-state.js +176 -0
  184. package/dist/mailroom/thread.js +109 -0
  185. package/dist/mailroom/travel-extract.js +89 -0
  186. package/dist/mind/bundle-manifest.js +7 -1
  187. package/dist/mind/context.js +164 -101
  188. package/dist/mind/diary-integrity.js +60 -0
  189. package/dist/mind/{memory.js → diary.js} +74 -93
  190. package/dist/mind/embedding-provider.js +60 -0
  191. package/dist/mind/file-state.js +179 -0
  192. package/dist/mind/friends/channel.js +30 -0
  193. package/dist/mind/friends/group-context.js +144 -0
  194. package/dist/mind/friends/resolver.js +54 -2
  195. package/dist/mind/friends/store-file.js +39 -3
  196. package/dist/mind/friends/trust-explanation.js +74 -0
  197. package/dist/mind/friends/types.js +2 -2
  198. package/dist/mind/journal-index.js +161 -0
  199. package/dist/mind/note-search.js +268 -0
  200. package/dist/mind/obligation-steering.js +221 -0
  201. package/dist/mind/pending.js +4 -0
  202. package/dist/mind/prompt-refresh.js +3 -2
  203. package/dist/mind/prompt.js +948 -110
  204. package/dist/mind/provenance-trust.js +26 -0
  205. package/dist/mind/scrutiny.js +173 -0
  206. package/dist/nerves/cli-logging.js +7 -1
  207. package/dist/nerves/coverage/audit-rules.js +15 -6
  208. package/dist/nerves/coverage/audit.js +28 -2
  209. package/dist/nerves/coverage/cli.js +1 -1
  210. package/dist/nerves/coverage/contract.js +5 -5
  211. package/dist/nerves/coverage/file-completeness.js +101 -5
  212. package/dist/nerves/coverage/run-artifacts.js +1 -1
  213. package/dist/nerves/event-buffer.js +111 -0
  214. package/dist/nerves/index.js +224 -4
  215. package/dist/nerves/observation.js +20 -0
  216. package/dist/nerves/redact.js +79 -0
  217. package/dist/nerves/runtime.js +5 -1
  218. package/dist/outlook-ui/assets/index-BPr5vNuM.css +1 -0
  219. package/dist/outlook-ui/assets/index-Cm51CY9W.js +61 -0
  220. package/dist/outlook-ui/index.html +15 -0
  221. package/dist/repertoire/ado-client.js +15 -56
  222. package/dist/repertoire/ado-semantic.js +11 -10
  223. package/dist/repertoire/api-client.js +97 -0
  224. package/dist/repertoire/bitwarden-store.js +774 -0
  225. package/dist/repertoire/bundle-templates.js +72 -0
  226. package/dist/repertoire/bw-installer.js +180 -0
  227. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  228. package/dist/repertoire/coding/context-pack.js +330 -0
  229. package/dist/repertoire/coding/feedback.js +197 -30
  230. package/dist/repertoire/coding/manager.js +158 -9
  231. package/dist/repertoire/coding/spawner.js +55 -9
  232. package/dist/repertoire/coding/tools.js +170 -7
  233. package/dist/repertoire/commerce-errors.js +109 -0
  234. package/dist/repertoire/commerce-self-test.js +156 -0
  235. package/dist/repertoire/credential-access.js +111 -0
  236. package/dist/repertoire/duffel-client.js +185 -0
  237. package/dist/repertoire/github-client.js +14 -55
  238. package/dist/repertoire/graph-client.js +11 -52
  239. package/dist/repertoire/guardrails.js +396 -0
  240. package/dist/repertoire/mcp-client.js +255 -0
  241. package/dist/repertoire/mcp-manager.js +305 -0
  242. package/dist/repertoire/mcp-tools.js +63 -0
  243. package/dist/repertoire/shell-sessions.js +133 -0
  244. package/dist/repertoire/skills.js +15 -24
  245. package/dist/repertoire/stripe-client.js +131 -0
  246. package/dist/repertoire/tasks/board.js +31 -5
  247. package/dist/repertoire/tasks/fix.js +182 -0
  248. package/dist/repertoire/tasks/index.js +16 -4
  249. package/dist/repertoire/tasks/lifecycle.js +2 -2
  250. package/dist/repertoire/tasks/parser.js +3 -2
  251. package/dist/repertoire/tasks/scanner.js +194 -37
  252. package/dist/repertoire/tasks/transitions.js +16 -78
  253. package/dist/repertoire/tool-results.js +29 -0
  254. package/dist/repertoire/tools-attachments.js +317 -0
  255. package/dist/repertoire/tools-base.js +46 -921
  256. package/dist/repertoire/tools-bluebubbles.js +1 -0
  257. package/dist/repertoire/tools-bridge.js +141 -0
  258. package/dist/repertoire/tools-bundle.js +984 -0
  259. package/dist/repertoire/tools-config.js +185 -0
  260. package/dist/repertoire/tools-continuity.js +248 -0
  261. package/dist/repertoire/tools-credential.js +381 -0
  262. package/dist/repertoire/tools-files.js +342 -0
  263. package/dist/repertoire/tools-flight.js +224 -0
  264. package/dist/repertoire/tools-flow.js +105 -0
  265. package/dist/repertoire/tools-github.js +1 -7
  266. package/dist/repertoire/tools-mail.js +1377 -0
  267. package/dist/repertoire/tools-notes.js +376 -0
  268. package/dist/repertoire/tools-session.js +749 -0
  269. package/dist/repertoire/tools-shell.js +120 -0
  270. package/dist/repertoire/tools-stripe.js +180 -0
  271. package/dist/repertoire/tools-surface.js +243 -0
  272. package/dist/repertoire/tools-teams.js +9 -39
  273. package/dist/repertoire/tools-travel.js +125 -0
  274. package/dist/repertoire/tools-trip.js +356 -0
  275. package/dist/repertoire/tools-user-profile.js +144 -0
  276. package/dist/repertoire/tools-vault.js +40 -0
  277. package/dist/repertoire/tools.js +144 -115
  278. package/dist/repertoire/travel-api-client.js +360 -0
  279. package/dist/repertoire/user-profile.js +131 -0
  280. package/dist/repertoire/vault-setup.js +246 -0
  281. package/dist/repertoire/vault-unlock.js +561 -0
  282. package/dist/scripts/claude-code-hook.js +41 -0
  283. package/dist/scripts/claude-code-stop-hook.js +47 -0
  284. package/dist/senses/attention-queue.js +116 -0
  285. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  286. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  287. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  288. package/dist/senses/bluebubbles/entry.js +73 -0
  289. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  290. package/dist/senses/bluebubbles/index.js +1881 -0
  291. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  292. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  293. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  294. package/dist/senses/bluebubbles/processed-log.js +111 -0
  295. package/dist/senses/bluebubbles/replay.js +129 -0
  296. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +2 -2
  297. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  298. package/dist/senses/cli/bracketed-paste.js +82 -0
  299. package/dist/senses/cli/image-paste.js +287 -0
  300. package/dist/senses/cli/image-ref-navigation.js +75 -0
  301. package/dist/senses/cli/ink-app.js +156 -0
  302. package/dist/senses/cli/inline-diff.js +64 -0
  303. package/dist/senses/cli/input-keys.js +174 -0
  304. package/dist/senses/cli/kill-ring.js +86 -0
  305. package/dist/senses/cli/message-list.js +51 -0
  306. package/dist/senses/cli/ouro-tui.js +605 -0
  307. package/dist/senses/cli/spinner-imperative.js +135 -0
  308. package/dist/senses/cli/spinner.js +101 -0
  309. package/dist/senses/cli/status-line.js +60 -0
  310. package/dist/senses/cli/streaming-markdown.js +526 -0
  311. package/dist/senses/cli/tool-display.js +83 -0
  312. package/dist/senses/cli/tool-render.js +85 -0
  313. package/dist/senses/cli/tui-store.js +240 -0
  314. package/dist/senses/cli/virtual-list.js +35 -0
  315. package/dist/senses/cli-entry.js +60 -8
  316. package/dist/senses/cli-layout.js +187 -0
  317. package/dist/senses/cli.js +511 -209
  318. package/dist/senses/commands.js +66 -3
  319. package/dist/senses/habit-turn-message.js +108 -0
  320. package/dist/senses/inner-dialog-worker.js +175 -21
  321. package/dist/senses/inner-dialog.js +330 -27
  322. package/dist/senses/mail-entry.js +66 -0
  323. package/dist/senses/mail.js +379 -0
  324. package/dist/senses/pipeline.js +573 -164
  325. package/dist/senses/proactive-content-guard.js +51 -0
  326. package/dist/senses/shared-turn.js +248 -0
  327. package/dist/senses/surface-tool.js +68 -0
  328. package/dist/senses/teams-entry.js +60 -8
  329. package/dist/senses/teams.js +405 -170
  330. package/dist/senses/trust-gate.js +100 -5
  331. package/dist/trips/core.js +138 -0
  332. package/dist/trips/store.js +146 -0
  333. package/package.json +37 -7
  334. package/skills/agent-commerce.md +106 -0
  335. package/skills/browser-navigation.md +117 -0
  336. package/skills/commerce-setup-guide.md +116 -0
  337. package/skills/commerce-setup.md +84 -0
  338. package/skills/configure-dev-tools.md +101 -0
  339. package/skills/travel-planning.md +138 -0
  340. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  341. package/dist/heart/daemon/subagent-installer.js +0 -166
  342. package/dist/heart/session-recall.js +0 -116
  343. package/dist/mind/associative-recall.js +0 -209
  344. package/dist/senses/bluebubbles-entry.js +0 -13
  345. package/dist/senses/bluebubbles.js +0 -1142
  346. package/dist/senses/debug-activity.js +0 -148
  347. package/subagents/README.md +0 -86
  348. package/subagents/work-doer.md +0 -237
  349. package/subagents/work-merger.md +0 -618
  350. package/subagents/work-planner.md +0 -390
  351. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  352. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  353. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  354. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  355. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  356. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  357. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  358. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  359. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  360. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  361. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  362. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  363. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  364. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  365. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  366. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,232 @@
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.readSessionInventory = readSessionInventory;
37
+ exports.readSessionTranscript = readSessionTranscript;
38
+ const path = __importStar(require("path"));
39
+ const runtime_1 = require("../../../nerves/runtime");
40
+ const identity_1 = require("../../identity");
41
+ const session_events_1 = require("../../session-events");
42
+ const shared_1 = require("./shared");
43
+ /* v8 ignore start — session envelope parsing utilities */
44
+ function parseSessionUsage(raw) {
45
+ if (!raw || typeof raw !== "object")
46
+ return null;
47
+ const record = raw;
48
+ const inputTokens = typeof record.input_tokens === "number" ? record.input_tokens : 0;
49
+ const outputTokens = typeof record.output_tokens === "number" ? record.output_tokens : 0;
50
+ const reasoningTokens = typeof record.reasoning_tokens === "number" ? record.reasoning_tokens : 0;
51
+ const totalTokens = typeof record.total_tokens === "number" ? record.total_tokens : 0;
52
+ if (inputTokens === 0 && outputTokens === 0 && totalTokens === 0)
53
+ return null;
54
+ return { input_tokens: inputTokens, output_tokens: outputTokens, reasoning_tokens: reasoningTokens, total_tokens: totalTokens };
55
+ }
56
+ function parseSessionContinuity(raw) {
57
+ if (!raw)
58
+ return null;
59
+ if (typeof raw !== "object")
60
+ return null;
61
+ const record = raw;
62
+ const continuity = {
63
+ mustResolveBeforeHandoff: record.mustResolveBeforeHandoff === true,
64
+ lastFriendActivityAt: typeof record.lastFriendActivityAt === "string" ? record.lastFriendActivityAt : null,
65
+ };
66
+ if (!continuity.mustResolveBeforeHandoff && continuity.lastFriendActivityAt === null)
67
+ return null;
68
+ return continuity;
69
+ }
70
+ function extractContent(event) {
71
+ if (!event)
72
+ return null;
73
+ const text = (0, session_events_1.extractEventText)(event);
74
+ return text.length > 0 ? text : null;
75
+ }
76
+ function extractToolCallNames(event) {
77
+ if (!event)
78
+ return [];
79
+ return event.toolCalls
80
+ .map((call) => call.function.name)
81
+ .filter((name) => typeof name === "string" && name.length > 0);
82
+ }
83
+ /* v8 ignore stop */
84
+ function estimateTokenCount(messages) {
85
+ let charCount = 0;
86
+ for (const msg of messages) {
87
+ const content = extractContent(msg);
88
+ if (content)
89
+ charCount += content.length;
90
+ if (msg.toolCalls.length > 0)
91
+ charCount += JSON.stringify(msg.toolCalls).length;
92
+ }
93
+ return Math.ceil(charCount / 4);
94
+ }
95
+ /* v8 ignore start — filesystem traversal with defensive isDirectory checks */
96
+ function resolveAllSessionPaths(sessionsDir) {
97
+ const results = [];
98
+ if (!(0, shared_1.safeIsDirectory)(sessionsDir))
99
+ return results;
100
+ for (const friendId of (0, shared_1.safeReaddir)(sessionsDir)) {
101
+ const friendDir = path.join(sessionsDir, friendId);
102
+ if (!(0, shared_1.safeIsDirectory)(friendDir))
103
+ continue;
104
+ for (const channel of (0, shared_1.safeReaddir)(friendDir)) {
105
+ const channelDir = path.join(friendDir, channel);
106
+ if (!(0, shared_1.safeIsDirectory)(channelDir))
107
+ continue;
108
+ for (const file of (0, shared_1.safeReaddir)(channelDir)) {
109
+ if (!file.endsWith(".json"))
110
+ continue;
111
+ const key = file.slice(0, -5);
112
+ results.push({
113
+ friendId,
114
+ channel,
115
+ key,
116
+ sessionPath: path.join(channelDir, file),
117
+ });
118
+ }
119
+ }
120
+ }
121
+ return results;
122
+ }
123
+ /* v8 ignore stop */
124
+ /* v8 ignore start — defensive parsing */
125
+ function readSessionInventory(agentName, options = {}) {
126
+ const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
127
+ const now = options.now?.() ?? new Date();
128
+ const agentRoot = path.join(bundlesRoot, `${agentName}.ouro`);
129
+ const sessionsDir = path.join(agentRoot, "state", "sessions");
130
+ const friendsDir = path.join(agentRoot, "friends");
131
+ const allSessions = resolveAllSessionPaths(sessionsDir);
132
+ const items = [];
133
+ for (const { friendId, channel, key, sessionPath } of allSessions) {
134
+ if (friendId === "self" && channel === "inner")
135
+ continue;
136
+ const envelope = (0, shared_1.readSessionEnvelope)(sessionPath);
137
+ const events = envelope?.events ?? [];
138
+ const chronology = (0, session_events_1.deriveSessionChronology)(events);
139
+ const lastUsage = parseSessionUsage(envelope?.lastUsage);
140
+ const continuity = parseSessionContinuity(envelope?.state);
141
+ const hasObservedEventTiming = events.some((event) => event.time.authoredAt !== null || event.time.observedAt !== null);
142
+ const lastActivityAt = hasObservedEventTiming
143
+ ? (chronology.lastActivityAt ?? continuity?.lastFriendActivityAt ?? (0, shared_1.safeFileMtime)(sessionPath) ?? now.toISOString())
144
+ : (continuity?.lastFriendActivityAt ?? (0, shared_1.safeFileMtime)(sessionPath) ?? now.toISOString());
145
+ const activitySource = hasObservedEventTiming && chronology.lastActivityAt
146
+ ? "event-timeline"
147
+ : continuity?.lastFriendActivityAt
148
+ ? "friend-facing"
149
+ : "mtime-fallback";
150
+ const userMessages = events.filter((m) => m.role === "user");
151
+ const assistantMessages = events.filter((m) => m.role === "assistant");
152
+ const lastUser = userMessages.length > 0 ? userMessages[userMessages.length - 1] : null;
153
+ const lastAssistant = assistantMessages.length > 0 ? assistantMessages[assistantMessages.length - 1] : null;
154
+ const latestToolCallNames = [];
155
+ for (let i = events.length - 1; i >= 0; i--) {
156
+ const names = extractToolCallNames(events[i]);
157
+ if (names.length > 0) {
158
+ latestToolCallNames.push(...names);
159
+ break;
160
+ }
161
+ }
162
+ const friendName = (0, shared_1.resolveFriendName)(friendsDir, friendId);
163
+ const lastMsg = events.length > 0 ? events[events.length - 1] : null;
164
+ const mustResolve = continuity?.mustResolveBeforeHandoff === true;
165
+ let replyState = "idle";
166
+ if (mustResolve) {
167
+ replyState = "on-hold";
168
+ }
169
+ else if (lastMsg?.role === "user") {
170
+ replyState = "needs-reply";
171
+ }
172
+ else if (events.length > 0) {
173
+ replyState = "monitoring";
174
+ }
175
+ items.push({
176
+ friendId,
177
+ friendName,
178
+ channel,
179
+ key,
180
+ sessionPath,
181
+ lastActivityAt,
182
+ activitySource,
183
+ replyState,
184
+ messageCount: events.length,
185
+ lastUsage,
186
+ continuity,
187
+ latestUserExcerpt: (0, shared_1.truncateExcerpt)(extractContent(lastUser)),
188
+ latestAssistantExcerpt: (0, shared_1.truncateExcerpt)(extractContent(lastAssistant)),
189
+ latestToolCallNames,
190
+ estimatedTokens: events.length > 0 ? estimateTokenCount(events) : null,
191
+ });
192
+ }
193
+ items.sort((a, b) => b.lastActivityAt.localeCompare(a.lastActivityAt));
194
+ const ageThreshold = now.getTime() - shared_1.STALE_THRESHOLD_MS;
195
+ const activeCount = items.filter((item) => Date.parse(item.lastActivityAt) >= ageThreshold).length;
196
+ (0, runtime_1.emitNervesEvent)({
197
+ component: "heart",
198
+ event: "heart.outlook_sessions_read",
199
+ message: "reading outlook session inventory",
200
+ meta: { agentName, totalCount: items.length, activeCount },
201
+ });
202
+ return {
203
+ totalCount: items.length,
204
+ activeCount,
205
+ staleCount: items.length - activeCount,
206
+ items,
207
+ };
208
+ }
209
+ function readSessionTranscript(agentName, friendId, channel, key, options = {}) {
210
+ const bundlesRoot = options.bundlesRoot ?? (0, identity_1.getAgentBundlesRoot)();
211
+ const agentRoot = path.join(bundlesRoot, `${agentName}.ouro`);
212
+ const sessionPath = path.join(agentRoot, "state", "sessions", friendId, channel, `${key}.json`);
213
+ const envelope = (0, shared_1.readSessionEnvelope)(sessionPath);
214
+ if (!envelope)
215
+ return null;
216
+ // Use full event history (envelope + archive) for complete transcript
217
+ const rawMessages = (0, session_events_1.loadFullEventHistory)(sessionPath);
218
+ const friendsDir = path.join(agentRoot, "friends");
219
+ const friendName = (0, shared_1.resolveFriendName)(friendsDir, friendId);
220
+ const messages = rawMessages;
221
+ return {
222
+ friendId,
223
+ friendName,
224
+ channel,
225
+ key,
226
+ sessionPath,
227
+ messageCount: messages.length,
228
+ lastUsage: parseSessionUsage(envelope.lastUsage),
229
+ continuity: parseSessionContinuity(envelope.state),
230
+ messages,
231
+ };
232
+ }
@@ -0,0 +1,111 @@
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_THRESHOLD_MS = exports.BLOCKED_CODING_STATUSES = exports.ACTIVE_CODING_STATUSES = void 0;
37
+ exports.issue = issue;
38
+ exports.safeReaddir = safeReaddir;
39
+ exports.safeIsDirectory = safeIsDirectory;
40
+ exports.resolveFriendName = resolveFriendName;
41
+ exports.safeFileMtime = safeFileMtime;
42
+ exports.truncateExcerpt = truncateExcerpt;
43
+ exports.readSessionEnvelope = readSessionEnvelope;
44
+ const fs = __importStar(require("fs"));
45
+ const path = __importStar(require("path"));
46
+ const runtime_1 = require("../../../nerves/runtime");
47
+ const session_events_1 = require("../../session-events");
48
+ exports.ACTIVE_CODING_STATUSES = new Set(["spawning", "running", "waiting_input", "stalled"]);
49
+ exports.BLOCKED_CODING_STATUSES = new Set(["waiting_input", "stalled"]);
50
+ exports.STALE_THRESHOLD_MS = 24 * 60 * 60 * 1000;
51
+ function issue(code, detail) {
52
+ return { code, detail };
53
+ }
54
+ function safeReaddir(dir) {
55
+ try {
56
+ return fs.readdirSync(dir);
57
+ }
58
+ catch {
59
+ return [];
60
+ }
61
+ }
62
+ function safeIsDirectory(filePath) {
63
+ try {
64
+ return fs.statSync(filePath).isDirectory();
65
+ /* v8 ignore start */
66
+ }
67
+ catch {
68
+ return false;
69
+ }
70
+ /* v8 ignore stop */
71
+ }
72
+ /* v8 ignore start — defensive friend name resolution */
73
+ function resolveFriendName(friendsDir, friendId) {
74
+ try {
75
+ const raw = fs.readFileSync(path.join(friendsDir, `${friendId}.json`), "utf-8");
76
+ const parsed = JSON.parse(raw);
77
+ return typeof parsed.name === "string" ? parsed.name : friendId;
78
+ }
79
+ catch {
80
+ return friendId;
81
+ }
82
+ }
83
+ /* v8 ignore stop */
84
+ /* v8 ignore start — utility helpers with defensive branches */
85
+ function safeFileMtime(filePath) {
86
+ try {
87
+ return fs.statSync(filePath).mtime.toISOString();
88
+ }
89
+ catch {
90
+ return null;
91
+ }
92
+ }
93
+ function truncateExcerpt(content, maxLength = 200) {
94
+ if (!content)
95
+ return null;
96
+ if (content.length <= maxLength)
97
+ return content;
98
+ const truncated = content.slice(0, maxLength);
99
+ const lastSpace = truncated.lastIndexOf(" ");
100
+ return (lastSpace > maxLength * 0.6 ? truncated.slice(0, lastSpace) : truncated) + "…";
101
+ }
102
+ /* v8 ignore stop */
103
+ function readSessionEnvelope(sessionPath) {
104
+ (0, runtime_1.emitNervesEvent)({
105
+ component: "heart",
106
+ event: "heart.outlook_session_envelope_read",
107
+ message: "reading outlook session envelope",
108
+ meta: { sessionPath },
109
+ });
110
+ return (0, session_events_1.loadSessionEnvelopeFile)(sessionPath);
111
+ }
@@ -0,0 +1,81 @@
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.detectPlatform = detectPlatform;
37
+ const fs = __importStar(require("fs"));
38
+ const runtime_1 = require("../nerves/runtime");
39
+ function detectPlatform(deps = {}) {
40
+ const platform = deps.platform ?? process.platform;
41
+ const env = deps.env ?? process.env;
42
+ const readFile = deps.readFileSync ?? ((p) => fs.readFileSync(p, "utf-8"));
43
+ let result;
44
+ if (platform === "darwin") {
45
+ result = "macos";
46
+ }
47
+ else if (platform === "win32") {
48
+ result = "windows-native";
49
+ }
50
+ else if (platform === "linux") {
51
+ result = detectLinuxOrWsl(env, readFile);
52
+ }
53
+ else {
54
+ // Unknown platform — treat as linux
55
+ result = "linux";
56
+ }
57
+ (0, runtime_1.emitNervesEvent)({
58
+ component: "daemon",
59
+ event: "daemon.platform_detected",
60
+ message: "detected platform",
61
+ meta: { platform, result },
62
+ });
63
+ return result;
64
+ }
65
+ function detectLinuxOrWsl(env, readFile) {
66
+ // Primary: WSL_DISTRO_NAME env var
67
+ if (env.WSL_DISTRO_NAME && env.WSL_DISTRO_NAME.length > 0) {
68
+ return "wsl";
69
+ }
70
+ // Fallback: /proc/version containing "microsoft" (case-insensitive)
71
+ try {
72
+ const procVersion = readFile("/proc/version");
73
+ if (/microsoft/i.test(procVersion)) {
74
+ return "wsl";
75
+ }
76
+ }
77
+ catch {
78
+ // /proc/version not readable — not WSL
79
+ }
80
+ return "linux";
81
+ }
@@ -0,0 +1,134 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DEFAULT_PROVIDER_ATTEMPT_POLICY = exports.ProviderAttemptAbortError = void 0;
4
+ exports.runProviderAttempt = runProviderAttempt;
5
+ const runtime_1 = require("../nerves/runtime");
6
+ class ProviderAttemptAbortError extends Error {
7
+ constructor(message = "provider attempt aborted") {
8
+ super(message);
9
+ this.name = "ProviderAttemptAbortError";
10
+ }
11
+ }
12
+ exports.ProviderAttemptAbortError = ProviderAttemptAbortError;
13
+ exports.DEFAULT_PROVIDER_ATTEMPT_POLICY = {
14
+ maxAttempts: 3,
15
+ baseDelayMs: 2_000,
16
+ backoffMultiplier: 2,
17
+ };
18
+ function sleep(delayMs) {
19
+ return new Promise((resolve) => setTimeout(resolve, delayMs));
20
+ }
21
+ function normalizePolicy(policy) {
22
+ return {
23
+ ...exports.DEFAULT_PROVIDER_ATTEMPT_POLICY,
24
+ ...policy,
25
+ };
26
+ }
27
+ function toError(error) {
28
+ return error instanceof Error ? error : new Error(String(error));
29
+ }
30
+ function classify(error, classifyError) {
31
+ if (!(error instanceof Error))
32
+ return "unknown";
33
+ try {
34
+ return classifyError(error);
35
+ }
36
+ catch {
37
+ return "unknown";
38
+ }
39
+ }
40
+ function httpStatus(error) {
41
+ const status = error.status;
42
+ return typeof status === "number" ? status : null;
43
+ }
44
+ function delayForAttempt(policy, attempt) {
45
+ return policy.baseDelayMs * Math.pow(policy.backoffMultiplier, attempt - 1);
46
+ }
47
+ async function runProviderAttempt(input) {
48
+ const policy = normalizePolicy(input.policy);
49
+ const maxAttempts = Math.max(1, Math.floor(policy.maxAttempts));
50
+ const wait = input.sleep ?? sleep;
51
+ const attempts = [];
52
+ for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
53
+ try {
54
+ await input.onAttemptStart?.(attempt, maxAttempts);
55
+ const value = await input.run();
56
+ attempts.push({
57
+ attempt,
58
+ provider: input.provider,
59
+ model: input.model,
60
+ operation: input.operation,
61
+ ok: true,
62
+ willRetry: false,
63
+ });
64
+ (0, runtime_1.emitNervesEvent)({
65
+ component: "engine",
66
+ event: "engine.provider_attempt_succeeded",
67
+ message: "provider attempt succeeded",
68
+ meta: { provider: input.provider, model: input.model, operation: input.operation, attempt, maxAttempts },
69
+ });
70
+ return { ok: true, value, attempts };
71
+ }
72
+ catch (caught) {
73
+ if (caught instanceof ProviderAttemptAbortError)
74
+ throw caught;
75
+ const error = toError(caught);
76
+ const classification = classify(caught, input.classifyError);
77
+ const willRetry = attempt < maxAttempts;
78
+ const delayMs = willRetry ? delayForAttempt(policy, attempt) : undefined;
79
+ const record = {
80
+ attempt,
81
+ provider: input.provider,
82
+ model: input.model,
83
+ operation: input.operation,
84
+ ok: false,
85
+ classification,
86
+ errorMessage: error.message,
87
+ httpStatus: httpStatus(error),
88
+ willRetry,
89
+ ...(delayMs !== undefined ? { delayMs } : {}),
90
+ };
91
+ attempts.push(record);
92
+ if (!willRetry) {
93
+ (0, runtime_1.emitNervesEvent)({
94
+ level: "warn",
95
+ component: "engine",
96
+ event: "engine.provider_attempt_failed",
97
+ message: "provider attempt failed",
98
+ meta: {
99
+ provider: input.provider,
100
+ model: input.model,
101
+ operation: input.operation,
102
+ attempt,
103
+ maxAttempts,
104
+ classification,
105
+ errorMessage: error.message.slice(0, 200),
106
+ httpStatus: httpStatus(error),
107
+ },
108
+ });
109
+ return { ok: false, error, classification, attempts };
110
+ }
111
+ const retryDelayMs = delayMs;
112
+ (0, runtime_1.emitNervesEvent)({
113
+ component: "engine",
114
+ event: "engine.provider_attempt_retry",
115
+ message: "provider attempt failed; retrying",
116
+ meta: {
117
+ provider: input.provider,
118
+ model: input.model,
119
+ operation: input.operation,
120
+ attempt,
121
+ maxAttempts,
122
+ classification,
123
+ errorMessage: error.message.slice(0, 200),
124
+ httpStatus: httpStatus(error),
125
+ delayMs: retryDelayMs,
126
+ },
127
+ });
128
+ await input.onRetry?.(record, maxAttempts);
129
+ await wait(retryDelayMs);
130
+ }
131
+ }
132
+ /* v8 ignore next 2 -- defensive: loop always returns on success or final failure @preserve */
133
+ return { ok: false, error: new Error("provider attempt loop ended unexpectedly"), classification: "unknown", attempts };
134
+ }