@ouro.bot/cli 0.1.0-alpha.35 → 0.1.0-alpha.351

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 (325) hide show
  1. package/README.md +188 -187
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
  4. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  5. package/changelog.json +2098 -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 +832 -0
  16. package/dist/heart/agent-entry.js +37 -2
  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 +463 -0
  28. package/dist/heart/bridges/manager.js +358 -0
  29. package/dist/heart/bridges/state-machine.js +135 -0
  30. package/dist/heart/bridges/store.js +123 -0
  31. package/dist/heart/bundle-state.js +168 -0
  32. package/dist/heart/commitments.js +111 -0
  33. package/dist/heart/config-registry.js +304 -0
  34. package/dist/heart/config.js +53 -21
  35. package/dist/heart/core.js +744 -252
  36. package/dist/heart/cross-chat-delivery.js +131 -0
  37. package/dist/heart/daemon/agent-config-check.js +561 -0
  38. package/dist/heart/daemon/agent-discovery.js +79 -3
  39. package/dist/heart/daemon/agent-service.js +360 -0
  40. package/dist/heart/daemon/agentic-repair.js +170 -0
  41. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  42. package/dist/heart/daemon/cadence.js +70 -0
  43. package/dist/heart/daemon/cli-defaults.js +591 -0
  44. package/dist/heart/daemon/cli-exec.js +2633 -0
  45. package/dist/heart/daemon/cli-help.js +306 -0
  46. package/dist/heart/daemon/cli-parse.js +913 -0
  47. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  48. package/dist/heart/daemon/cli-render.js +512 -0
  49. package/dist/heart/daemon/cli-types.js +8 -0
  50. package/dist/heart/daemon/daemon-cli.js +30 -1171
  51. package/dist/heart/daemon/daemon-entry.js +358 -3
  52. package/dist/heart/daemon/daemon-health.js +141 -0
  53. package/dist/heart/daemon/daemon-runtime-sync.js +157 -12
  54. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  55. package/dist/heart/daemon/daemon.js +751 -58
  56. package/dist/heart/daemon/doctor-types.js +8 -0
  57. package/dist/heart/daemon/doctor.js +465 -0
  58. package/dist/heart/daemon/health-monitor.js +79 -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/inner-status.js +89 -0
  63. package/dist/heart/daemon/interactive-repair.js +91 -0
  64. package/dist/heart/daemon/launchd.js +46 -9
  65. package/dist/heart/daemon/log-tailer.js +82 -12
  66. package/dist/heart/daemon/logs-prune.js +105 -0
  67. package/dist/heart/daemon/message-router.js +17 -8
  68. package/dist/heart/daemon/os-cron-deps.js +134 -0
  69. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  70. package/dist/heart/daemon/process-manager.js +201 -0
  71. package/dist/heart/daemon/provider-discovery.js +105 -0
  72. package/dist/heart/daemon/pulse.js +463 -0
  73. package/dist/heart/daemon/run-hooks.js +2 -0
  74. package/dist/heart/daemon/runtime-logging.js +67 -16
  75. package/dist/heart/daemon/runtime-metadata.js +101 -0
  76. package/dist/heart/daemon/runtime-mode.js +67 -0
  77. package/dist/heart/daemon/safe-mode.js +161 -0
  78. package/dist/heart/daemon/sense-manager.js +72 -3
  79. package/dist/heart/daemon/session-id-resolver.js +131 -0
  80. package/dist/heart/daemon/skill-management-installer.js +94 -0
  81. package/dist/heart/daemon/socket-client.js +307 -0
  82. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  83. package/dist/heart/daemon/startup-tui.js +237 -0
  84. package/dist/heart/daemon/task-scheduler.js +3 -25
  85. package/dist/heart/daemon/thoughts.js +510 -0
  86. package/dist/heart/daemon/up-progress.js +135 -0
  87. package/dist/heart/delegation.js +62 -0
  88. package/dist/heart/habits/habit-migration.js +181 -0
  89. package/dist/heart/habits/habit-parser.js +140 -0
  90. package/dist/heart/habits/habit-scheduler.js +371 -0
  91. package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -120
  92. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  93. package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
  94. package/dist/heart/{daemon → hatch}/specialist-tools.js +56 -10
  95. package/dist/heart/identity.js +154 -59
  96. package/dist/heart/kept-notes.js +357 -0
  97. package/dist/heart/kicks.js +2 -20
  98. package/dist/heart/machine-identity.js +161 -0
  99. package/dist/heart/mcp/mcp-server.js +653 -0
  100. package/dist/heart/migrate-config.js +127 -0
  101. package/dist/heart/model-capabilities.js +59 -0
  102. package/dist/heart/outlook/outlook-http-hooks.js +64 -0
  103. package/dist/heart/outlook/outlook-http-response.js +7 -0
  104. package/dist/heart/outlook/outlook-http-routes.js +232 -0
  105. package/dist/heart/outlook/outlook-http-static.js +99 -0
  106. package/dist/heart/outlook/outlook-http-transport.js +116 -0
  107. package/dist/heart/outlook/outlook-http.js +99 -0
  108. package/dist/heart/outlook/outlook-read.js +28 -0
  109. package/dist/heart/outlook/outlook-types.js +27 -0
  110. package/dist/heart/outlook/outlook-view.js +194 -0
  111. package/dist/heart/outlook/readers/agent-machine.js +355 -0
  112. package/dist/heart/outlook/readers/continuity-readers.js +332 -0
  113. package/dist/heart/outlook/readers/runtime-readers.js +660 -0
  114. package/dist/heart/outlook/readers/sessions.js +231 -0
  115. package/dist/heart/outlook/readers/shared.js +111 -0
  116. package/dist/heart/progress-story.js +42 -0
  117. package/dist/heart/provider-attempt.js +133 -0
  118. package/dist/heart/provider-binding-resolver.js +240 -0
  119. package/dist/heart/provider-credential-pool.js +395 -0
  120. package/dist/heart/provider-failover.js +135 -0
  121. package/dist/heart/provider-models.js +81 -0
  122. package/dist/heart/provider-ping.js +258 -0
  123. package/dist/heart/provider-state.js +208 -0
  124. package/dist/heart/providers/anthropic-token.js +163 -0
  125. package/dist/heart/providers/anthropic.js +171 -50
  126. package/dist/heart/providers/azure.js +97 -11
  127. package/dist/heart/providers/error-classification.js +63 -0
  128. package/dist/heart/providers/github-copilot.js +135 -0
  129. package/dist/heart/providers/minimax-vlm.js +189 -0
  130. package/dist/heart/providers/minimax.js +23 -6
  131. package/dist/heart/providers/openai-codex.js +33 -23
  132. package/dist/heart/session-activity.js +190 -0
  133. package/dist/heart/session-events.js +727 -0
  134. package/dist/heart/session-transcript.js +162 -0
  135. package/dist/heart/start-of-turn-packet.js +341 -0
  136. package/dist/heart/streaming.js +36 -27
  137. package/dist/heart/sync.js +332 -0
  138. package/dist/heart/target-resolution.js +127 -0
  139. package/dist/heart/tempo.js +93 -0
  140. package/dist/heart/temporal-view.js +41 -0
  141. package/dist/heart/tool-activity-callbacks.js +36 -0
  142. package/dist/heart/tool-description.js +135 -0
  143. package/dist/heart/tool-friction.js +55 -0
  144. package/dist/heart/tool-loop.js +200 -0
  145. package/dist/heart/turn-context.js +358 -0
  146. package/dist/heart/turn-coordinator.js +28 -0
  147. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  148. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  149. package/dist/heart/versioning/ouro-path-installer.js +296 -0
  150. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  151. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  152. package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
  153. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  154. package/dist/mind/bundle-manifest.js +7 -1
  155. package/dist/mind/context.js +140 -94
  156. package/dist/mind/diary-integrity.js +60 -0
  157. package/dist/mind/{memory.js → diary.js} +84 -96
  158. package/dist/mind/embedding-provider.js +60 -0
  159. package/dist/mind/file-state.js +179 -0
  160. package/dist/mind/first-impressions.js +14 -1
  161. package/dist/mind/friends/channel.js +56 -0
  162. package/dist/mind/friends/group-context.js +144 -0
  163. package/dist/mind/friends/resolver.js +38 -1
  164. package/dist/mind/friends/store-file.js +58 -3
  165. package/dist/mind/friends/trust-explanation.js +74 -0
  166. package/dist/mind/friends/types.js +9 -1
  167. package/dist/mind/journal-index.js +161 -0
  168. package/dist/mind/note-search.js +268 -0
  169. package/dist/mind/obligation-steering.js +221 -0
  170. package/dist/mind/pending.js +74 -7
  171. package/dist/mind/prompt.js +1001 -112
  172. package/dist/mind/provenance-trust.js +26 -0
  173. package/dist/mind/scrutiny.js +173 -0
  174. package/dist/mind/token-estimate.js +8 -12
  175. package/dist/nerves/cli-logging.js +7 -1
  176. package/dist/nerves/coverage/audit-rules.js +15 -6
  177. package/dist/nerves/coverage/audit.js +28 -2
  178. package/dist/nerves/coverage/cli.js +1 -1
  179. package/dist/nerves/coverage/file-completeness.js +83 -5
  180. package/dist/nerves/coverage/run-artifacts.js +1 -1
  181. package/dist/nerves/event-buffer.js +111 -0
  182. package/dist/nerves/index.js +224 -4
  183. package/dist/nerves/observation.js +20 -0
  184. package/dist/nerves/redact.js +79 -0
  185. package/dist/nerves/runtime.js +5 -1
  186. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  187. package/dist/outlook-ui/assets/index-xTdv64BV.js +61 -0
  188. package/dist/outlook-ui/index.html +15 -0
  189. package/dist/repertoire/ado-client.js +15 -56
  190. package/dist/repertoire/ado-semantic.js +11 -10
  191. package/dist/repertoire/api-client.js +97 -0
  192. package/dist/repertoire/bitwarden-store.js +319 -0
  193. package/dist/repertoire/bundle-templates.js +72 -0
  194. package/dist/repertoire/bw-installer.js +79 -0
  195. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  196. package/dist/repertoire/coding/context-pack.js +330 -0
  197. package/dist/repertoire/coding/feedback.js +197 -30
  198. package/dist/repertoire/coding/manager.js +158 -9
  199. package/dist/repertoire/coding/spawner.js +55 -9
  200. package/dist/repertoire/coding/tools.js +170 -7
  201. package/dist/repertoire/commerce-errors.js +109 -0
  202. package/dist/repertoire/commerce-self-test.js +156 -0
  203. package/dist/repertoire/credential-access.js +527 -0
  204. package/dist/repertoire/duffel-client.js +185 -0
  205. package/dist/repertoire/github-client.js +14 -55
  206. package/dist/repertoire/graph-client.js +11 -52
  207. package/dist/repertoire/guardrails.js +375 -0
  208. package/dist/repertoire/mcp-client.js +255 -0
  209. package/dist/repertoire/mcp-manager.js +305 -0
  210. package/dist/repertoire/mcp-tools.js +63 -0
  211. package/dist/repertoire/shell-sessions.js +133 -0
  212. package/dist/repertoire/skills.js +15 -24
  213. package/dist/repertoire/stripe-client.js +131 -0
  214. package/dist/repertoire/tasks/board.js +43 -5
  215. package/dist/repertoire/tasks/fix.js +182 -0
  216. package/dist/repertoire/tasks/index.js +28 -10
  217. package/dist/repertoire/tasks/lifecycle.js +2 -2
  218. package/dist/repertoire/tasks/parser.js +3 -2
  219. package/dist/repertoire/tasks/scanner.js +194 -37
  220. package/dist/repertoire/tasks/transitions.js +16 -79
  221. package/dist/repertoire/tool-results.js +29 -0
  222. package/dist/repertoire/tools-attachments.js +316 -0
  223. package/dist/repertoire/tools-base.js +45 -771
  224. package/dist/repertoire/tools-bluebubbles.js +1 -0
  225. package/dist/repertoire/tools-bridge.js +141 -0
  226. package/dist/repertoire/tools-bundle.js +984 -0
  227. package/dist/repertoire/tools-config.js +185 -0
  228. package/dist/repertoire/tools-continuity.js +248 -0
  229. package/dist/repertoire/tools-credential.js +182 -0
  230. package/dist/repertoire/tools-files.js +342 -0
  231. package/dist/repertoire/tools-flight.js +224 -0
  232. package/dist/repertoire/tools-flow.js +105 -0
  233. package/dist/repertoire/tools-github.js +1 -7
  234. package/dist/repertoire/tools-notes.js +376 -0
  235. package/dist/repertoire/tools-session.js +739 -0
  236. package/dist/repertoire/tools-shell.js +120 -0
  237. package/dist/repertoire/tools-stripe.js +180 -0
  238. package/dist/repertoire/tools-surface.js +243 -0
  239. package/dist/repertoire/tools-teams.js +12 -62
  240. package/dist/repertoire/tools-travel.js +125 -0
  241. package/dist/repertoire/tools-user-profile.js +144 -0
  242. package/dist/repertoire/tools-vault.js +110 -0
  243. package/dist/repertoire/tools.js +144 -138
  244. package/dist/repertoire/travel-api-client.js +360 -0
  245. package/dist/repertoire/user-profile.js +118 -0
  246. package/dist/repertoire/vault-setup.js +241 -0
  247. package/dist/scripts/claude-code-hook.js +41 -0
  248. package/dist/scripts/claude-code-stop-hook.js +47 -0
  249. package/dist/senses/attention-queue.js +116 -0
  250. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  251. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  252. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +225 -9
  253. package/dist/senses/bluebubbles/entry.js +13 -0
  254. package/dist/senses/bluebubbles/inbound-log.js +113 -0
  255. package/dist/senses/bluebubbles/index.js +1616 -0
  256. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  257. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +43 -12
  258. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
  259. package/dist/senses/bluebubbles/replay.js +129 -0
  260. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  261. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  262. package/dist/senses/cli/bracketed-paste.js +82 -0
  263. package/dist/senses/cli/image-paste.js +287 -0
  264. package/dist/senses/cli/image-ref-navigation.js +75 -0
  265. package/dist/senses/cli/ink-app.js +156 -0
  266. package/dist/senses/cli/inline-diff.js +64 -0
  267. package/dist/senses/cli/input-keys.js +174 -0
  268. package/dist/senses/cli/kill-ring.js +86 -0
  269. package/dist/senses/cli/message-list.js +51 -0
  270. package/dist/senses/cli/ouro-tui.js +605 -0
  271. package/dist/senses/cli/spinner-imperative.js +135 -0
  272. package/dist/senses/cli/spinner.js +101 -0
  273. package/dist/senses/cli/status-line.js +60 -0
  274. package/dist/senses/cli/streaming-markdown.js +526 -0
  275. package/dist/senses/cli/tool-display.js +83 -0
  276. package/dist/senses/cli/tool-render.js +85 -0
  277. package/dist/senses/cli/tui-store.js +240 -0
  278. package/dist/senses/cli/virtual-list.js +35 -0
  279. package/dist/senses/cli-entry.js +1 -1
  280. package/dist/senses/cli-layout.js +187 -0
  281. package/dist/senses/cli.js +603 -246
  282. package/dist/senses/commands.js +65 -1
  283. package/dist/senses/continuity.js +94 -0
  284. package/dist/senses/habit-turn-message.js +108 -0
  285. package/dist/senses/inner-dialog-worker.js +112 -19
  286. package/dist/senses/inner-dialog.js +633 -86
  287. package/dist/senses/pipeline.js +567 -0
  288. package/dist/senses/proactive-content-guard.js +51 -0
  289. package/dist/senses/shared-turn.js +199 -0
  290. package/dist/senses/surface-tool.js +68 -0
  291. package/dist/senses/teams.js +690 -160
  292. package/dist/senses/trust-gate.js +112 -2
  293. package/package.json +29 -7
  294. package/skills/agent-commerce.md +106 -0
  295. package/skills/browser-navigation.md +110 -0
  296. package/skills/commerce-setup-guide.md +116 -0
  297. package/skills/commerce-setup.md +84 -0
  298. package/skills/configure-dev-tools.md +81 -0
  299. package/skills/travel-planning.md +138 -0
  300. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  301. package/dist/heart/daemon/subagent-installer.js +0 -134
  302. package/dist/mind/associative-recall.js +0 -197
  303. package/dist/senses/bluebubbles-entry.js +0 -11
  304. package/dist/senses/bluebubbles.js +0 -548
  305. package/dist/senses/debug-activity.js +0 -127
  306. package/subagents/README.md +0 -73
  307. package/subagents/work-doer.md +0 -235
  308. package/subagents/work-merger.md +0 -618
  309. package/subagents/work-planner.md +0 -382
  310. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  311. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  312. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  313. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  314. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  315. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  316. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  317. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  318. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  319. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  320. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  321. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  322. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  323. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  324. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  325. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -2,11 +2,14 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createBlueBubblesClient = createBlueBubblesClient;
4
4
  const node_crypto_1 = require("node:crypto");
5
- const config_1 = require("../heart/config");
6
- const identity_1 = require("../heart/identity");
7
- const runtime_1 = require("../nerves/runtime");
8
- const bluebubbles_model_1 = require("./bluebubbles-model");
9
- const bluebubbles_media_1 = require("./bluebubbles-media");
5
+ const config_1 = require("../../heart/config");
6
+ const identity_1 = require("../../heart/identity");
7
+ const bluebubbles_health_diagnostics_1 = require("../../heart/daemon/bluebubbles-health-diagnostics");
8
+ const runtime_1 = require("../../nerves/runtime");
9
+ const minimax_1 = require("../../heart/providers/minimax");
10
+ const minimax_vlm_1 = require("../../heart/providers/minimax-vlm");
11
+ const model_1 = require("./model");
12
+ const media_1 = require("./media");
10
13
  function buildBlueBubblesApiUrl(baseUrl, endpoint, password) {
11
14
  const root = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
12
15
  const url = new URL(endpoint.replace(/^\//, ""), root);
@@ -55,6 +58,9 @@ async function parseJsonBody(response) {
55
58
  return null;
56
59
  }
57
60
  }
61
+ function describeCaughtValue(error) {
62
+ return error instanceof Error ? error.message : String(error);
63
+ }
58
64
  function buildRepairUrl(baseUrl, messageGuid, password) {
59
65
  const url = buildBlueBubblesApiUrl(baseUrl, `/api/v1/message/${encodeURIComponent(messageGuid)}`, password);
60
66
  const parsed = new URL(url);
@@ -99,6 +105,17 @@ function extractChatQueryRows(payload) {
99
105
  }
100
106
  return data.map((entry) => asRecord(entry)).filter((entry) => entry !== null);
101
107
  }
108
+ function extractMessageQueryRows(payload) {
109
+ const record = asRecord(payload);
110
+ const data = asRecord(record?.data);
111
+ const rows = Array.isArray(record?.data) ? record.data
112
+ : Array.isArray(data?.messages) ? data.messages
113
+ : Array.isArray(data?.results) ? data.results
114
+ : Array.isArray(record?.messages) ? record.messages
115
+ : Array.isArray(payload) ? payload
116
+ : [];
117
+ return rows.map((entry) => asRecord(entry)).filter((entry) => entry !== null);
118
+ }
102
119
  async function resolveChatGuidForIdentifier(config, channelConfig, chatIdentifier) {
103
120
  const trimmedIdentifier = chatIdentifier.trim();
104
121
  if (!trimmedIdentifier)
@@ -170,6 +187,12 @@ function applyRepairNotice(event, notice) {
170
187
  repairNotice: notice,
171
188
  };
172
189
  }
190
+ function hasRecoverableMessageContent(event) {
191
+ return event.kind === "message"
192
+ && (event.textForAgent.trim().length > 0
193
+ || event.attachments.length > 0
194
+ || event.hasPayloadData);
195
+ }
173
196
  function hydrateTextForAgent(event, rawData) {
174
197
  if (event.kind !== "message") {
175
198
  return { ...event, requiresRepair: false };
@@ -323,6 +346,107 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
323
346
  throw new Error(`BlueBubbles read failed (${response.status}): ${errorText || "unknown"}`);
324
347
  }
325
348
  },
349
+ async checkHealth() {
350
+ (0, runtime_1.emitNervesEvent)({
351
+ component: "senses",
352
+ event: "senses.bluebubbles_healthcheck_start",
353
+ message: "probing bluebubbles upstream health",
354
+ meta: { serverUrl: config.serverUrl },
355
+ });
356
+ const result = await (0, bluebubbles_health_diagnostics_1.probeBlueBubblesHealth)({
357
+ serverUrl: config.serverUrl,
358
+ password: config.password,
359
+ requestTimeoutMs: channelConfig.requestTimeoutMs,
360
+ fetchImpl: fetch,
361
+ });
362
+ if (!result.ok) {
363
+ (0, runtime_1.emitNervesEvent)({
364
+ level: "warn",
365
+ component: "senses",
366
+ event: "senses.bluebubbles_healthcheck_error",
367
+ message: "bluebubbles upstream health probe failed",
368
+ meta: {
369
+ serverUrl: config.serverUrl,
370
+ status: result.status,
371
+ reason: result.reason,
372
+ classification: result.classification,
373
+ detail: (0, bluebubbles_health_diagnostics_1.redactBlueBubblesHealthDetailForNerves)(result.detail),
374
+ },
375
+ });
376
+ throw new Error(result.detail);
377
+ }
378
+ (0, runtime_1.emitNervesEvent)({
379
+ component: "senses",
380
+ event: "senses.bluebubbles_healthcheck_end",
381
+ message: "bluebubbles upstream health probe succeeded",
382
+ meta: { serverUrl: config.serverUrl },
383
+ });
384
+ },
385
+ async listRecentMessages(params = {}) {
386
+ const limit = Math.max(1, Math.min(100, Math.floor(params.limit ?? 50)));
387
+ const offset = Math.max(0, Math.floor(params.offset ?? 0));
388
+ const url = buildBlueBubblesApiUrl(config.serverUrl, "/api/v1/message/query", config.password);
389
+ (0, runtime_1.emitNervesEvent)({
390
+ component: "senses",
391
+ event: "senses.bluebubbles_query_recent_start",
392
+ message: "querying recent bluebubbles messages",
393
+ meta: { limit, offset },
394
+ });
395
+ const response = await fetch(url, {
396
+ method: "POST",
397
+ headers: { "Content-Type": "application/json" },
398
+ body: JSON.stringify({
399
+ limit,
400
+ offset,
401
+ sort: "DESC",
402
+ with: ["chats", "attachments", "payloadData", "messageSummaryInfo"],
403
+ }),
404
+ signal: AbortSignal.timeout(channelConfig.requestTimeoutMs),
405
+ });
406
+ if (!response.ok) {
407
+ const errorText = await response.text().catch(() => "");
408
+ (0, runtime_1.emitNervesEvent)({
409
+ level: "warn",
410
+ component: "senses",
411
+ event: "senses.bluebubbles_query_recent_error",
412
+ message: "bluebubbles recent message query failed",
413
+ meta: {
414
+ status: response.status,
415
+ reason: errorText || "unknown",
416
+ },
417
+ });
418
+ throw new Error(`BlueBubbles recent message query failed (${response.status}): ${errorText || "unknown"}`);
419
+ }
420
+ const payload = await parseJsonBody(response);
421
+ const rows = extractMessageQueryRows(payload);
422
+ const messages = [];
423
+ for (const row of rows) {
424
+ try {
425
+ messages.push((0, model_1.normalizeBlueBubblesEvent)({ type: "new-message", data: row }));
426
+ }
427
+ catch (error) {
428
+ (0, runtime_1.emitNervesEvent)({
429
+ level: "warn",
430
+ component: "senses",
431
+ event: "senses.bluebubbles_query_recent_skip",
432
+ message: "skipped unusable bluebubbles recent message row",
433
+ meta: {
434
+ reason: describeCaughtValue(error),
435
+ },
436
+ });
437
+ }
438
+ }
439
+ (0, runtime_1.emitNervesEvent)({
440
+ component: "senses",
441
+ event: "senses.bluebubbles_query_recent_end",
442
+ message: "queried recent bluebubbles messages",
443
+ meta: {
444
+ rows: rows.length,
445
+ normalized: messages.length,
446
+ },
447
+ });
448
+ return messages;
449
+ },
326
450
  async repairEvent(event) {
327
451
  if (!event.requiresRepair) {
328
452
  (0, runtime_1.emitNervesEvent)({
@@ -337,6 +461,7 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
337
461
  return event;
338
462
  }
339
463
  (0, runtime_1.emitNervesEvent)({
464
+ level: "warn",
340
465
  component: "senses",
341
466
  event: "senses.bluebubbles_repair_start",
342
467
  message: "repairing bluebubbles event by guid",
@@ -383,16 +508,57 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
383
508
  });
384
509
  return repaired;
385
510
  }
386
- const normalized = (0, bluebubbles_model_1.normalizeBlueBubblesEvent)({
511
+ const normalized = (0, model_1.normalizeBlueBubblesEvent)({
387
512
  type: event.eventType,
388
513
  data,
389
514
  });
390
- let hydrated = hydrateTextForAgent(normalized, data);
515
+ const recoveredMessage = event.kind === "mutation"
516
+ && !event.shouldNotifyAgent
517
+ ? (0, model_1.normalizeBlueBubblesEvent)({
518
+ type: "new-message",
519
+ data,
520
+ })
521
+ : null;
522
+ let hydrated = recoveredMessage && hasRecoverableMessageContent(recoveredMessage)
523
+ ? hydrateTextForAgent(recoveredMessage, data)
524
+ : hydrateTextForAgent(normalized, data);
391
525
  if (hydrated.kind === "message" &&
392
526
  hydrated.balloonBundleId !== "com.apple.messages.URLBalloonProvider" &&
393
527
  hydrated.attachments.length > 0) {
394
- const media = await (0, bluebubbles_media_1.hydrateBlueBubblesAttachments)(hydrated.attachments, config, channelConfig, {
395
- preferAudioInput: providerSupportsAudioInput((0, identity_1.loadAgentConfig)().provider),
528
+ const agentConfig = (0, identity_1.loadAgentConfig)();
529
+ const chatModel = agentConfig.humanFacing.model;
530
+ const chatProvider = agentConfig.humanFacing.provider;
531
+ const vlmDescribe = async (params) => {
532
+ if (chatProvider !== "minimax") {
533
+ throw new Error("VLM fallback requires a minimax credential for this agent — " +
534
+ "configure one or switch to a vision-capable chat model");
535
+ }
536
+ const { apiKey } = (0, config_1.getMinimaxConfig)();
537
+ if (!apiKey) {
538
+ throw new Error("VLM fallback: minimax API key not found in secrets.json — " +
539
+ "re-run credential setup or ask the user to add a minimax key");
540
+ }
541
+ return (0, minimax_vlm_1.minimaxVlmDescribe)({
542
+ apiKey,
543
+ prompt: params.prompt,
544
+ imageDataUrl: params.imageDataUrl,
545
+ baseURL: minimax_1.MINIMAX_PROVIDER_BASE_URL,
546
+ attachmentGuid: params.attachmentGuid,
547
+ mimeType: params.mimeType,
548
+ chatModel: params.chatModel,
549
+ });
550
+ };
551
+ // VLM prompt context wants the user's raw inbound text — NOT
552
+ // the agent-facing rendering, which now carries the attachment
553
+ // marker after the B2 fix. Pull it from the source payload.
554
+ const rawUserText = typeof data.text === "string"
555
+ ? (data.text).trim()
556
+ : "";
557
+ const media = await (0, media_1.hydrateBlueBubblesAttachments)(hydrated.attachments, config, channelConfig, {
558
+ preferAudioInput: providerSupportsAudioInput(chatProvider),
559
+ chatModel,
560
+ vlmDescribe,
561
+ userText: rawUserText,
396
562
  });
397
563
  const transcriptSuffix = media.transcriptAdditions.map((entry) => `[${entry}]`).join("\n");
398
564
  const noticeSuffix = media.notices.map((entry) => `[${entry}]`).join("\n");
@@ -404,6 +570,7 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
404
570
  };
405
571
  }
406
572
  (0, runtime_1.emitNervesEvent)({
573
+ level: "warn",
407
574
  component: "senses",
408
575
  event: "senses.bluebubbles_repair_end",
409
576
  message: "bluebubbles event repaired",
@@ -411,6 +578,7 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
411
578
  kind: hydrated.kind,
412
579
  messageGuid: hydrated.messageGuid,
413
580
  repairedFrom: event.kind,
581
+ promotedFromMutation: event.kind === "mutation" && hydrated.kind === "message",
414
582
  },
415
583
  });
416
584
  return hydrated;
@@ -430,5 +598,53 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
430
598
  return applyRepairNotice(event, `BlueBubbles repair failed: ${reason}`);
431
599
  }
432
600
  },
601
+ async getMessageText(messageGuid) {
602
+ const url = buildRepairUrl(config.serverUrl, messageGuid, config.password);
603
+ try {
604
+ const response = await fetch(url, {
605
+ method: "GET",
606
+ signal: AbortSignal.timeout(channelConfig.requestTimeoutMs),
607
+ });
608
+ if (!response.ok) {
609
+ (0, runtime_1.emitNervesEvent)({
610
+ level: "warn",
611
+ component: "senses",
612
+ event: "senses.bluebubbles_get_message_text_error",
613
+ message: "failed to fetch message text",
614
+ meta: { messageGuid, status: response.status },
615
+ });
616
+ return null;
617
+ }
618
+ const payload = await parseJsonBody(response);
619
+ const data = extractRepairData(payload);
620
+ if (!data || typeof data.text !== "string") {
621
+ (0, runtime_1.emitNervesEvent)({
622
+ level: "warn",
623
+ component: "senses",
624
+ event: "senses.bluebubbles_get_message_text_error",
625
+ message: "message payload missing text field",
626
+ meta: { messageGuid, hasData: !!data, textType: data ? typeof data.text : "n/a" },
627
+ });
628
+ return null;
629
+ }
630
+ (0, runtime_1.emitNervesEvent)({
631
+ component: "senses",
632
+ event: "senses.bluebubbles_get_message_text",
633
+ message: "fetched message text by guid",
634
+ meta: { messageGuid },
635
+ });
636
+ return data.text.trim() || null;
637
+ }
638
+ catch (error) {
639
+ (0, runtime_1.emitNervesEvent)({
640
+ level: "warn",
641
+ component: "senses",
642
+ event: "senses.bluebubbles_get_message_text_error",
643
+ message: "exception fetching message text",
644
+ meta: { messageGuid, reason: error instanceof Error ? error.message : String(error) },
645
+ });
646
+ return null;
647
+ }
648
+ },
433
649
  };
434
650
  }
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ // Thin entrypoint for `npm run bluebubbles` / `node dist/senses/bluebubbles/entry.js --agent <name>`.
3
+ // Separated from index.ts so the BlueBubbles adapter stays testable.
4
+ Object.defineProperty(exports, "__esModule", { value: true });
5
+ if (!process.argv.includes("--agent")) {
6
+ // eslint-disable-next-line no-console -- pre-boot guard: --agent check before imports
7
+ console.error("Missing required --agent <name> argument.\nUsage: node dist/senses/bluebubbles/entry.js --agent ouroboros");
8
+ process.exit(1);
9
+ }
10
+ const index_1 = require("./index");
11
+ const runtime_logging_1 = require("../../heart/daemon/runtime-logging");
12
+ (0, runtime_logging_1.configureDaemonRuntimeLogger)("bluebubbles");
13
+ (0, index_1.startBlueBubblesApp)();
@@ -0,0 +1,113 @@
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.getBlueBubblesInboundLogPath = getBlueBubblesInboundLogPath;
37
+ exports.hasRecordedBlueBubblesInbound = hasRecordedBlueBubblesInbound;
38
+ exports.recordBlueBubblesInbound = recordBlueBubblesInbound;
39
+ const fs = __importStar(require("node:fs"));
40
+ const path = __importStar(require("node:path"));
41
+ const config_1 = require("../../heart/config");
42
+ const identity_1 = require("../../heart/identity");
43
+ const runtime_1 = require("../../nerves/runtime");
44
+ function getBlueBubblesInboundLogPath(agentName, sessionKey) {
45
+ return path.join((0, identity_1.getAgentRoot)(agentName), "state", "senses", "bluebubbles", "inbound", `${(0, config_1.sanitizeKey)(sessionKey)}.ndjson`);
46
+ }
47
+ function readEntries(filePath) {
48
+ try {
49
+ const raw = fs.readFileSync(filePath, "utf-8");
50
+ return raw
51
+ .split("\n")
52
+ .map((line) => line.trim())
53
+ .filter(Boolean)
54
+ .map((line) => JSON.parse(line))
55
+ .filter((entry) => typeof entry.messageGuid === "string" && typeof entry.sessionKey === "string");
56
+ }
57
+ catch {
58
+ return [];
59
+ }
60
+ }
61
+ function hasRecordedBlueBubblesInbound(agentName, sessionKey, messageGuid) {
62
+ if (!messageGuid.trim())
63
+ return false;
64
+ const filePath = getBlueBubblesInboundLogPath(agentName, sessionKey);
65
+ return readEntries(filePath).some((entry) => entry.messageGuid === messageGuid);
66
+ }
67
+ function recordBlueBubblesInbound(agentName, event, source) {
68
+ const filePath = getBlueBubblesInboundLogPath(agentName, event.chat.sessionKey);
69
+ try {
70
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
71
+ if (event.messageGuid.trim() && readEntries(filePath).some((entry) => entry.messageGuid === event.messageGuid)) {
72
+ return filePath;
73
+ }
74
+ fs.appendFileSync(filePath, JSON.stringify({
75
+ recordedAt: new Date(event.timestamp).toISOString(),
76
+ messageGuid: event.messageGuid,
77
+ chatGuid: event.chat.chatGuid ?? null,
78
+ chatIdentifier: event.chat.chatIdentifier ?? null,
79
+ sessionKey: event.chat.sessionKey,
80
+ textForAgent: event.textForAgent,
81
+ source,
82
+ }) + "\n", "utf-8");
83
+ }
84
+ catch (error) {
85
+ (0, runtime_1.emitNervesEvent)({
86
+ level: "warn",
87
+ component: "senses",
88
+ event: "senses.bluebubbles_inbound_log_error",
89
+ message: "failed to record bluebubbles inbound sidecar log",
90
+ meta: {
91
+ agentName,
92
+ messageGuid: event.messageGuid,
93
+ sessionKey: event.chat.sessionKey,
94
+ reason: error instanceof Error ? error.message : String(error),
95
+ },
96
+ });
97
+ return filePath;
98
+ }
99
+ (0, runtime_1.emitNervesEvent)({
100
+ level: "warn",
101
+ component: "senses",
102
+ event: "senses.bluebubbles_inbound_logged",
103
+ message: "recorded bluebubbles inbound message to sidecar log",
104
+ meta: {
105
+ agentName,
106
+ messageGuid: event.messageGuid,
107
+ sessionKey: event.chat.sessionKey,
108
+ source,
109
+ path: filePath,
110
+ },
111
+ });
112
+ return filePath;
113
+ }