@ouro.bot/cli 0.1.0-alpha.32 → 0.1.0-alpha.321

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 (308) hide show
  1. package/README.md +188 -190
  2. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -2
  3. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +1 -1
  4. package/changelog.json +1924 -0
  5. package/dist/arc/attention-types.js +8 -0
  6. package/dist/arc/cares.js +140 -0
  7. package/dist/arc/episodes.js +117 -0
  8. package/dist/arc/intentions.js +133 -0
  9. package/dist/arc/json-store.js +117 -0
  10. package/dist/arc/obligations.js +237 -0
  11. package/dist/arc/packets.js +193 -0
  12. package/dist/arc/presence.js +185 -0
  13. package/dist/arc/task-lifecycle.js +65 -0
  14. package/dist/heart/active-work.js +832 -0
  15. package/dist/heart/agent-entry.js +37 -2
  16. package/dist/heart/attachments/image-normalize.js +194 -0
  17. package/dist/heart/attachments/materialize.js +97 -0
  18. package/dist/heart/attachments/originals.js +88 -0
  19. package/dist/heart/attachments/render.js +29 -0
  20. package/dist/heart/attachments/sources/adapter.js +2 -0
  21. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  22. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  23. package/dist/heart/attachments/sources/index.js +16 -0
  24. package/dist/heart/attachments/store.js +103 -0
  25. package/dist/heart/attachments/types.js +93 -0
  26. package/dist/heart/auth/auth-flow.js +456 -0
  27. package/dist/heart/bridges/manager.js +358 -0
  28. package/dist/heart/bridges/state-machine.js +135 -0
  29. package/dist/heart/bridges/store.js +123 -0
  30. package/dist/heart/bundle-state.js +168 -0
  31. package/dist/heart/commitments.js +111 -0
  32. package/dist/heart/config-registry.js +304 -0
  33. package/dist/heart/config.js +63 -30
  34. package/dist/heart/core.js +669 -195
  35. package/dist/heart/cross-chat-delivery.js +131 -0
  36. package/dist/heart/daemon/agent-config-check.js +149 -0
  37. package/dist/heart/daemon/agent-discovery.js +79 -3
  38. package/dist/heart/daemon/agent-service.js +360 -0
  39. package/dist/heart/daemon/agentic-repair.js +170 -0
  40. package/dist/heart/daemon/cadence.js +70 -0
  41. package/dist/heart/daemon/cli-defaults.js +596 -0
  42. package/dist/heart/daemon/cli-exec.js +2238 -0
  43. package/dist/heart/daemon/cli-help.js +306 -0
  44. package/dist/heart/daemon/cli-parse.js +824 -0
  45. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  46. package/dist/heart/daemon/cli-render.js +506 -0
  47. package/dist/heart/daemon/cli-types.js +8 -0
  48. package/dist/heart/daemon/daemon-cli.js +29 -1171
  49. package/dist/heart/daemon/daemon-entry.js +333 -3
  50. package/dist/heart/daemon/daemon-health.js +137 -0
  51. package/dist/heart/daemon/daemon-runtime-sync.js +153 -12
  52. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  53. package/dist/heart/daemon/daemon.js +751 -58
  54. package/dist/heart/daemon/doctor-types.js +8 -0
  55. package/dist/heart/daemon/doctor.js +322 -0
  56. package/dist/heart/daemon/health-monitor.js +66 -0
  57. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  58. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  59. package/dist/heart/daemon/http-health-probe.js +80 -0
  60. package/dist/heart/daemon/inner-status.js +89 -0
  61. package/dist/heart/daemon/interactive-repair.js +69 -0
  62. package/dist/heart/daemon/launchd.js +46 -9
  63. package/dist/heart/daemon/log-tailer.js +82 -12
  64. package/dist/heart/daemon/logs-prune.js +105 -0
  65. package/dist/heart/daemon/message-router.js +17 -8
  66. package/dist/heart/daemon/os-cron-deps.js +134 -0
  67. package/dist/heart/daemon/ouro-bot-entry.js +1 -1
  68. package/dist/heart/daemon/process-manager.js +201 -0
  69. package/dist/heart/daemon/provider-discovery.js +105 -0
  70. package/dist/heart/daemon/pulse.js +463 -0
  71. package/dist/heart/daemon/run-hooks.js +2 -0
  72. package/dist/heart/daemon/runtime-logging.js +67 -16
  73. package/dist/heart/daemon/runtime-metadata.js +101 -0
  74. package/dist/heart/daemon/runtime-mode.js +67 -0
  75. package/dist/heart/daemon/safe-mode.js +161 -0
  76. package/dist/heart/daemon/sense-manager.js +72 -3
  77. package/dist/heart/daemon/session-id-resolver.js +131 -0
  78. package/dist/heart/daemon/skill-management-installer.js +94 -0
  79. package/dist/heart/daemon/socket-client.js +307 -0
  80. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  81. package/dist/heart/daemon/startup-tui.js +227 -0
  82. package/dist/heart/daemon/task-scheduler.js +3 -25
  83. package/dist/heart/daemon/thoughts.js +510 -0
  84. package/dist/heart/daemon/up-progress.js +135 -0
  85. package/dist/heart/delegation.js +62 -0
  86. package/dist/heart/habits/habit-migration.js +181 -0
  87. package/dist/heart/habits/habit-parser.js +140 -0
  88. package/dist/heart/habits/habit-scheduler.js +371 -0
  89. package/dist/heart/{daemon → hatch}/hatch-flow.js +30 -120
  90. package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
  91. package/dist/heart/{daemon → hatch}/specialist-prompt.js +10 -7
  92. package/dist/heart/{daemon → hatch}/specialist-tools.js +49 -3
  93. package/dist/heart/identity.js +163 -60
  94. package/dist/heart/kicks.js +2 -20
  95. package/dist/heart/mcp/mcp-server.js +653 -0
  96. package/dist/heart/migrate-config.js +127 -0
  97. package/dist/heart/model-capabilities.js +59 -0
  98. package/dist/heart/outlook/outlook-http.js +439 -0
  99. package/dist/heart/outlook/outlook-read.js +28 -0
  100. package/dist/heart/outlook/outlook-render.js +1032 -0
  101. package/dist/heart/outlook/outlook-types.js +27 -0
  102. package/dist/heart/outlook/outlook-view.js +194 -0
  103. package/dist/heart/outlook/readers/agent-machine.js +355 -0
  104. package/dist/heart/outlook/readers/continuity-readers.js +332 -0
  105. package/dist/heart/outlook/readers/runtime-readers.js +660 -0
  106. package/dist/heart/outlook/readers/sessions.js +231 -0
  107. package/dist/heart/outlook/readers/shared.js +111 -0
  108. package/dist/heart/progress-story.js +42 -0
  109. package/dist/heart/provider-failover.js +88 -0
  110. package/dist/heart/provider-ping.js +162 -0
  111. package/dist/heart/providers/anthropic-token.js +163 -0
  112. package/dist/heart/providers/anthropic.js +169 -46
  113. package/dist/heart/providers/azure.js +98 -11
  114. package/dist/heart/providers/error-classification.js +63 -0
  115. package/dist/heart/providers/github-copilot.js +136 -0
  116. package/dist/heart/providers/minimax-vlm.js +189 -0
  117. package/dist/heart/providers/minimax.js +23 -5
  118. package/dist/heart/providers/openai-codex.js +33 -22
  119. package/dist/heart/session-activity.js +190 -0
  120. package/dist/heart/session-events.js +726 -0
  121. package/dist/heart/session-recall.js +162 -0
  122. package/dist/heart/start-of-turn-packet.js +341 -0
  123. package/dist/heart/streaming.js +36 -27
  124. package/dist/heart/sync.js +332 -0
  125. package/dist/heart/target-resolution.js +127 -0
  126. package/dist/heart/tempo.js +93 -0
  127. package/dist/heart/temporal-view.js +41 -0
  128. package/dist/heart/tool-activity-callbacks.js +36 -0
  129. package/dist/heart/tool-description.js +135 -0
  130. package/dist/heart/tool-friction.js +55 -0
  131. package/dist/heart/tool-loop.js +200 -0
  132. package/dist/heart/turn-context.js +358 -0
  133. package/dist/heart/turn-coordinator.js +28 -0
  134. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
  135. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  136. package/dist/heart/{daemon → versioning}/ouro-path-installer.js +78 -35
  137. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  138. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  139. package/dist/heart/{daemon → versioning}/update-checker.js +12 -2
  140. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  141. package/dist/mind/associative-recall.js +137 -66
  142. package/dist/mind/bundle-manifest.js +8 -1
  143. package/dist/mind/context.js +89 -93
  144. package/dist/mind/diary-integrity.js +60 -0
  145. package/dist/mind/{memory.js → diary.js} +84 -96
  146. package/dist/mind/embedding-provider.js +60 -0
  147. package/dist/mind/file-state.js +179 -0
  148. package/dist/mind/first-impressions.js +14 -1
  149. package/dist/mind/friends/channel.js +56 -0
  150. package/dist/mind/friends/group-context.js +144 -0
  151. package/dist/mind/friends/resolver.js +37 -0
  152. package/dist/mind/friends/store-file.js +58 -3
  153. package/dist/mind/friends/trust-explanation.js +74 -0
  154. package/dist/mind/friends/types.js +8 -0
  155. package/dist/mind/journal-index.js +161 -0
  156. package/dist/mind/obligation-steering.js +221 -0
  157. package/dist/mind/pending.js +76 -9
  158. package/dist/mind/prompt.js +950 -113
  159. package/dist/mind/provenance-trust.js +26 -0
  160. package/dist/mind/scrutiny.js +173 -0
  161. package/dist/mind/token-estimate.js +8 -12
  162. package/dist/nerves/cli-logging.js +7 -1
  163. package/dist/nerves/coverage/audit.js +1 -1
  164. package/dist/nerves/coverage/file-completeness.js +76 -5
  165. package/dist/nerves/coverage/run-artifacts.js +1 -1
  166. package/dist/nerves/event-buffer.js +111 -0
  167. package/dist/nerves/index.js +224 -4
  168. package/dist/nerves/observation.js +20 -0
  169. package/dist/nerves/redact.js +79 -0
  170. package/dist/nerves/runtime.js +5 -1
  171. package/dist/outlook-ui/assets/index-IuR4F6y6.js +61 -0
  172. package/dist/outlook-ui/assets/index-LwChZTgL.css +1 -0
  173. package/dist/outlook-ui/index.html +15 -0
  174. package/dist/repertoire/ado-client.js +15 -56
  175. package/dist/repertoire/ado-semantic.js +11 -10
  176. package/dist/repertoire/api-client.js +97 -0
  177. package/dist/repertoire/bitwarden-store.js +319 -0
  178. package/dist/repertoire/bundle-templates.js +72 -0
  179. package/dist/repertoire/bw-installer.js +79 -0
  180. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  181. package/dist/repertoire/coding/context-pack.js +330 -0
  182. package/dist/repertoire/coding/feedback.js +197 -30
  183. package/dist/repertoire/coding/manager.js +159 -11
  184. package/dist/repertoire/coding/spawner.js +55 -9
  185. package/dist/repertoire/coding/tools.js +170 -7
  186. package/dist/repertoire/commerce-errors.js +109 -0
  187. package/dist/repertoire/commerce-self-test.js +156 -0
  188. package/dist/repertoire/credential-access.js +527 -0
  189. package/dist/repertoire/duffel-client.js +185 -0
  190. package/dist/repertoire/github-client.js +14 -55
  191. package/dist/repertoire/graph-client.js +11 -52
  192. package/dist/repertoire/guardrails.js +375 -0
  193. package/dist/repertoire/mcp-client.js +255 -0
  194. package/dist/repertoire/mcp-manager.js +305 -0
  195. package/dist/repertoire/mcp-tools.js +63 -0
  196. package/dist/repertoire/shell-sessions.js +133 -0
  197. package/dist/repertoire/skills.js +14 -23
  198. package/dist/repertoire/stripe-client.js +131 -0
  199. package/dist/repertoire/tasks/board.js +43 -5
  200. package/dist/repertoire/tasks/fix.js +182 -0
  201. package/dist/repertoire/tasks/index.js +28 -10
  202. package/dist/repertoire/tasks/lifecycle.js +2 -2
  203. package/dist/repertoire/tasks/parser.js +3 -2
  204. package/dist/repertoire/tasks/scanner.js +194 -37
  205. package/dist/repertoire/tasks/transitions.js +16 -79
  206. package/dist/repertoire/tool-results.js +29 -0
  207. package/dist/repertoire/tools-attachments.js +316 -0
  208. package/dist/repertoire/tools-base.js +45 -771
  209. package/dist/repertoire/tools-bluebubbles.js +1 -0
  210. package/dist/repertoire/tools-bridge.js +141 -0
  211. package/dist/repertoire/tools-bundle.js +984 -0
  212. package/dist/repertoire/tools-config.js +185 -0
  213. package/dist/repertoire/tools-continuity.js +248 -0
  214. package/dist/repertoire/tools-credential.js +182 -0
  215. package/dist/repertoire/tools-files.js +342 -0
  216. package/dist/repertoire/tools-flight.js +224 -0
  217. package/dist/repertoire/tools-flow.js +105 -0
  218. package/dist/repertoire/tools-github.js +1 -7
  219. package/dist/repertoire/tools-memory.js +376 -0
  220. package/dist/repertoire/tools-session.js +739 -0
  221. package/dist/repertoire/tools-shell.js +120 -0
  222. package/dist/repertoire/tools-stripe.js +180 -0
  223. package/dist/repertoire/tools-surface.js +243 -0
  224. package/dist/repertoire/tools-teams.js +12 -62
  225. package/dist/repertoire/tools-travel.js +125 -0
  226. package/dist/repertoire/tools-user-profile.js +144 -0
  227. package/dist/repertoire/tools-vault.js +110 -0
  228. package/dist/repertoire/tools.js +144 -138
  229. package/dist/repertoire/travel-api-client.js +360 -0
  230. package/dist/repertoire/user-profile.js +118 -0
  231. package/dist/repertoire/vault-setup.js +241 -0
  232. package/dist/scripts/claude-code-hook.js +41 -0
  233. package/dist/scripts/claude-code-stop-hook.js +47 -0
  234. package/dist/senses/attention-queue.js +116 -0
  235. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  236. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  237. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +143 -9
  238. package/dist/senses/bluebubbles/entry.js +13 -0
  239. package/dist/senses/bluebubbles/inbound-log.js +113 -0
  240. package/dist/senses/bluebubbles/index.js +1436 -0
  241. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  242. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +43 -12
  243. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
  244. package/dist/senses/bluebubbles/replay.js +129 -0
  245. package/dist/senses/bluebubbles/runtime-state.js +109 -0
  246. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  247. package/dist/senses/cli/bracketed-paste.js +82 -0
  248. package/dist/senses/cli/image-paste.js +287 -0
  249. package/dist/senses/cli/image-ref-navigation.js +75 -0
  250. package/dist/senses/cli/ink-app.js +156 -0
  251. package/dist/senses/cli/inline-diff.js +64 -0
  252. package/dist/senses/cli/input-keys.js +174 -0
  253. package/dist/senses/cli/kill-ring.js +86 -0
  254. package/dist/senses/cli/message-list.js +51 -0
  255. package/dist/senses/cli/ouro-tui.js +605 -0
  256. package/dist/senses/cli/spinner-imperative.js +135 -0
  257. package/dist/senses/cli/spinner.js +101 -0
  258. package/dist/senses/cli/status-line.js +60 -0
  259. package/dist/senses/cli/streaming-markdown.js +526 -0
  260. package/dist/senses/cli/tool-display.js +83 -0
  261. package/dist/senses/cli/tool-render.js +85 -0
  262. package/dist/senses/cli/tui-store.js +240 -0
  263. package/dist/senses/cli/virtual-list.js +35 -0
  264. package/dist/senses/cli-entry.js +1 -1
  265. package/dist/senses/cli-layout.js +187 -0
  266. package/dist/senses/cli.js +595 -246
  267. package/dist/senses/commands.js +65 -1
  268. package/dist/senses/continuity.js +94 -0
  269. package/dist/senses/habit-turn-message.js +108 -0
  270. package/dist/senses/inner-dialog-worker.js +112 -19
  271. package/dist/senses/inner-dialog.js +633 -86
  272. package/dist/senses/pipeline.js +565 -0
  273. package/dist/senses/shared-turn.js +199 -0
  274. package/dist/senses/surface-tool.js +68 -0
  275. package/dist/senses/teams.js +666 -166
  276. package/dist/senses/trust-gate.js +112 -2
  277. package/package.json +27 -7
  278. package/skills/agent-commerce.md +106 -0
  279. package/skills/browser-navigation.md +110 -0
  280. package/skills/commerce-setup-guide.md +116 -0
  281. package/skills/commerce-setup.md +84 -0
  282. package/skills/configure-dev-tools.md +81 -0
  283. package/skills/travel-planning.md +138 -0
  284. package/dist/heart/daemon/subagent-installer.js +0 -134
  285. package/dist/senses/bluebubbles-entry.js +0 -11
  286. package/dist/senses/bluebubbles.js +0 -544
  287. package/dist/senses/debug-activity.js +0 -108
  288. package/subagents/README.md +0 -73
  289. package/subagents/work-doer.md +0 -235
  290. package/subagents/work-merger.md +0 -618
  291. package/subagents/work-planner.md +0 -382
  292. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  293. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  294. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  295. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  296. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  297. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  298. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  299. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  300. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  301. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  302. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  303. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +0 -0
  304. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  305. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  306. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  307. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  308. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -2,11 +2,13 @@
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 runtime_1 = require("../../nerves/runtime");
8
+ const minimax_1 = require("../../heart/providers/minimax");
9
+ const minimax_vlm_1 = require("../../heart/providers/minimax-vlm");
10
+ const model_1 = require("./model");
11
+ const media_1 = require("./media");
10
12
  function buildBlueBubblesApiUrl(baseUrl, endpoint, password) {
11
13
  const root = baseUrl.endsWith("/") ? baseUrl : `${baseUrl}/`;
12
14
  const url = new URL(endpoint.replace(/^\//, ""), root);
@@ -170,6 +172,12 @@ function applyRepairNotice(event, notice) {
170
172
  repairNotice: notice,
171
173
  };
172
174
  }
175
+ function hasRecoverableMessageContent(event) {
176
+ return event.kind === "message"
177
+ && (event.textForAgent.trim().length > 0
178
+ || event.attachments.length > 0
179
+ || event.hasPayloadData);
180
+ }
173
181
  function hydrateTextForAgent(event, rawData) {
174
182
  if (event.kind !== "message") {
175
183
  return { ...event, requiresRepair: false };
@@ -323,6 +331,40 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
323
331
  throw new Error(`BlueBubbles read failed (${response.status}): ${errorText || "unknown"}`);
324
332
  }
325
333
  },
334
+ async checkHealth() {
335
+ const url = buildBlueBubblesApiUrl(config.serverUrl, "/api/v1/message/count", config.password);
336
+ (0, runtime_1.emitNervesEvent)({
337
+ component: "senses",
338
+ event: "senses.bluebubbles_healthcheck_start",
339
+ message: "probing bluebubbles upstream health",
340
+ meta: { serverUrl: config.serverUrl },
341
+ });
342
+ const response = await fetch(url, {
343
+ method: "GET",
344
+ signal: AbortSignal.timeout(channelConfig.requestTimeoutMs),
345
+ });
346
+ if (!response.ok) {
347
+ const errorText = await response.text().catch(() => "");
348
+ (0, runtime_1.emitNervesEvent)({
349
+ level: "warn",
350
+ component: "senses",
351
+ event: "senses.bluebubbles_healthcheck_error",
352
+ message: "bluebubbles upstream health probe failed",
353
+ meta: {
354
+ serverUrl: config.serverUrl,
355
+ status: response.status,
356
+ reason: errorText || "unknown",
357
+ },
358
+ });
359
+ throw new Error(`BlueBubbles upstream health check failed (${response.status}): ${errorText || "unknown"}`);
360
+ }
361
+ (0, runtime_1.emitNervesEvent)({
362
+ component: "senses",
363
+ event: "senses.bluebubbles_healthcheck_end",
364
+ message: "bluebubbles upstream health probe succeeded",
365
+ meta: { serverUrl: config.serverUrl },
366
+ });
367
+ },
326
368
  async repairEvent(event) {
327
369
  if (!event.requiresRepair) {
328
370
  (0, runtime_1.emitNervesEvent)({
@@ -337,6 +379,7 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
337
379
  return event;
338
380
  }
339
381
  (0, runtime_1.emitNervesEvent)({
382
+ level: "warn",
340
383
  component: "senses",
341
384
  event: "senses.bluebubbles_repair_start",
342
385
  message: "repairing bluebubbles event by guid",
@@ -383,16 +426,57 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
383
426
  });
384
427
  return repaired;
385
428
  }
386
- const normalized = (0, bluebubbles_model_1.normalizeBlueBubblesEvent)({
429
+ const normalized = (0, model_1.normalizeBlueBubblesEvent)({
387
430
  type: event.eventType,
388
431
  data,
389
432
  });
390
- let hydrated = hydrateTextForAgent(normalized, data);
433
+ const recoveredMessage = event.kind === "mutation"
434
+ && !event.shouldNotifyAgent
435
+ ? (0, model_1.normalizeBlueBubblesEvent)({
436
+ type: "new-message",
437
+ data,
438
+ })
439
+ : null;
440
+ let hydrated = recoveredMessage && hasRecoverableMessageContent(recoveredMessage)
441
+ ? hydrateTextForAgent(recoveredMessage, data)
442
+ : hydrateTextForAgent(normalized, data);
391
443
  if (hydrated.kind === "message" &&
392
444
  hydrated.balloonBundleId !== "com.apple.messages.URLBalloonProvider" &&
393
445
  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),
446
+ const agentConfig = (0, identity_1.loadAgentConfig)();
447
+ const chatModel = agentConfig.humanFacing.model;
448
+ const chatProvider = agentConfig.humanFacing.provider;
449
+ const vlmDescribe = async (params) => {
450
+ if (chatProvider !== "minimax") {
451
+ throw new Error("VLM fallback requires a minimax credential for this agent — " +
452
+ "configure one or switch to a vision-capable chat model");
453
+ }
454
+ const { apiKey } = (0, config_1.getMinimaxConfig)();
455
+ if (!apiKey) {
456
+ throw new Error("VLM fallback: minimax API key not found in secrets.json — " +
457
+ "re-run credential setup or ask the user to add a minimax key");
458
+ }
459
+ return (0, minimax_vlm_1.minimaxVlmDescribe)({
460
+ apiKey,
461
+ prompt: params.prompt,
462
+ imageDataUrl: params.imageDataUrl,
463
+ baseURL: minimax_1.MINIMAX_PROVIDER_BASE_URL,
464
+ attachmentGuid: params.attachmentGuid,
465
+ mimeType: params.mimeType,
466
+ chatModel: params.chatModel,
467
+ });
468
+ };
469
+ // VLM prompt context wants the user's raw inbound text — NOT
470
+ // the agent-facing rendering, which now carries the attachment
471
+ // marker after the B2 fix. Pull it from the source payload.
472
+ const rawUserText = typeof data.text === "string"
473
+ ? (data.text).trim()
474
+ : "";
475
+ const media = await (0, media_1.hydrateBlueBubblesAttachments)(hydrated.attachments, config, channelConfig, {
476
+ preferAudioInput: providerSupportsAudioInput(chatProvider),
477
+ chatModel,
478
+ vlmDescribe,
479
+ userText: rawUserText,
396
480
  });
397
481
  const transcriptSuffix = media.transcriptAdditions.map((entry) => `[${entry}]`).join("\n");
398
482
  const noticeSuffix = media.notices.map((entry) => `[${entry}]`).join("\n");
@@ -404,6 +488,7 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
404
488
  };
405
489
  }
406
490
  (0, runtime_1.emitNervesEvent)({
491
+ level: "warn",
407
492
  component: "senses",
408
493
  event: "senses.bluebubbles_repair_end",
409
494
  message: "bluebubbles event repaired",
@@ -411,6 +496,7 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
411
496
  kind: hydrated.kind,
412
497
  messageGuid: hydrated.messageGuid,
413
498
  repairedFrom: event.kind,
499
+ promotedFromMutation: event.kind === "mutation" && hydrated.kind === "message",
414
500
  },
415
501
  });
416
502
  return hydrated;
@@ -430,5 +516,53 @@ function createBlueBubblesClient(config = (0, config_1.getBlueBubblesConfig)(),
430
516
  return applyRepairNotice(event, `BlueBubbles repair failed: ${reason}`);
431
517
  }
432
518
  },
519
+ async getMessageText(messageGuid) {
520
+ const url = buildRepairUrl(config.serverUrl, messageGuid, config.password);
521
+ try {
522
+ const response = await fetch(url, {
523
+ method: "GET",
524
+ signal: AbortSignal.timeout(channelConfig.requestTimeoutMs),
525
+ });
526
+ if (!response.ok) {
527
+ (0, runtime_1.emitNervesEvent)({
528
+ level: "warn",
529
+ component: "senses",
530
+ event: "senses.bluebubbles_get_message_text_error",
531
+ message: "failed to fetch message text",
532
+ meta: { messageGuid, status: response.status },
533
+ });
534
+ return null;
535
+ }
536
+ const payload = await parseJsonBody(response);
537
+ const data = extractRepairData(payload);
538
+ if (!data || typeof data.text !== "string") {
539
+ (0, runtime_1.emitNervesEvent)({
540
+ level: "warn",
541
+ component: "senses",
542
+ event: "senses.bluebubbles_get_message_text_error",
543
+ message: "message payload missing text field",
544
+ meta: { messageGuid, hasData: !!data, textType: data ? typeof data.text : "n/a" },
545
+ });
546
+ return null;
547
+ }
548
+ (0, runtime_1.emitNervesEvent)({
549
+ component: "senses",
550
+ event: "senses.bluebubbles_get_message_text",
551
+ message: "fetched message text by guid",
552
+ meta: { messageGuid },
553
+ });
554
+ return data.text.trim() || null;
555
+ }
556
+ catch (error) {
557
+ (0, runtime_1.emitNervesEvent)({
558
+ level: "warn",
559
+ component: "senses",
560
+ event: "senses.bluebubbles_get_message_text_error",
561
+ message: "exception fetching message text",
562
+ meta: { messageGuid, reason: error instanceof Error ? error.message : String(error) },
563
+ });
564
+ return null;
565
+ }
566
+ },
433
567
  };
434
568
  }
@@ -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
+ }