@ouro.bot/cli 0.1.0-alpha.56 → 0.1.0-alpha.561

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 (396) hide show
  1. package/README.md +127 -23
  2. package/RepairGuide.ouro/agent.json +5 -0
  3. package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
  4. package/RepairGuide.ouro/psyche/SOUL.md +55 -0
  5. package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
  6. package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
  7. package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
  8. package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
  9. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
  10. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
  11. package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
  12. package/changelog.json +3604 -0
  13. package/dist/arc/attention-types.js +8 -0
  14. package/dist/arc/cares.js +140 -0
  15. package/dist/arc/episodes.js +117 -0
  16. package/dist/arc/intentions.js +133 -0
  17. package/dist/arc/json-store.js +117 -0
  18. package/dist/arc/obligations.js +237 -0
  19. package/dist/arc/packets.js +193 -0
  20. package/dist/arc/presence.js +185 -0
  21. package/dist/arc/task-lifecycle.js +65 -0
  22. package/dist/heart/active-work.js +837 -26
  23. package/dist/heart/agent-entry.js +58 -3
  24. package/dist/heart/attachments/image-normalize.js +194 -0
  25. package/dist/heart/attachments/materialize.js +97 -0
  26. package/dist/heart/attachments/originals.js +88 -0
  27. package/dist/heart/attachments/render.js +29 -0
  28. package/dist/heart/attachments/sources/adapter.js +2 -0
  29. package/dist/heart/attachments/sources/bluebubbles.js +156 -0
  30. package/dist/heart/attachments/sources/cli-local-file.js +78 -0
  31. package/dist/heart/attachments/sources/index.js +16 -0
  32. package/dist/heart/attachments/store.js +103 -0
  33. package/dist/heart/attachments/types.js +93 -0
  34. package/dist/heart/auth/auth-flow.js +479 -0
  35. package/dist/heart/background-operations.js +281 -0
  36. package/dist/heart/bundle-state.js +168 -0
  37. package/dist/heart/commitments.js +111 -0
  38. package/dist/heart/config-registry.js +322 -0
  39. package/dist/heart/config.js +114 -118
  40. package/dist/heart/core.js +913 -246
  41. package/dist/heart/cross-chat-delivery.js +3 -18
  42. package/dist/heart/daemon/agent-config-check.js +419 -0
  43. package/dist/heart/daemon/agent-discovery.js +102 -3
  44. package/dist/heart/daemon/agent-service.js +522 -0
  45. package/dist/heart/daemon/agentic-repair.js +547 -0
  46. package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
  47. package/dist/heart/daemon/boot-sync-probe.js +197 -0
  48. package/dist/heart/daemon/cadence.js +70 -0
  49. package/dist/heart/daemon/cli-defaults.js +776 -0
  50. package/dist/heart/daemon/cli-exec.js +7457 -0
  51. package/dist/heart/daemon/cli-help.js +498 -0
  52. package/dist/heart/daemon/cli-parse.js +1592 -0
  53. package/dist/heart/daemon/cli-render-doctor.js +57 -0
  54. package/dist/heart/daemon/cli-render.js +763 -0
  55. package/dist/heart/daemon/cli-types.js +8 -0
  56. package/dist/heart/daemon/connect-bay.js +323 -0
  57. package/dist/heart/daemon/daemon-cli.js +29 -1698
  58. package/dist/heart/daemon/daemon-entry.js +387 -2
  59. package/dist/heart/daemon/daemon-health.js +176 -0
  60. package/dist/heart/daemon/daemon-rollup.js +57 -0
  61. package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
  62. package/dist/heart/daemon/daemon-tombstone.js +236 -0
  63. package/dist/heart/daemon/daemon.js +796 -71
  64. package/dist/heart/daemon/dns-workflow.js +394 -0
  65. package/dist/heart/daemon/doctor-types.js +8 -0
  66. package/dist/heart/daemon/doctor.js +826 -0
  67. package/dist/heart/daemon/health-monitor.js +122 -1
  68. package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
  69. package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
  70. package/dist/heart/daemon/http-health-probe.js +80 -0
  71. package/dist/heart/daemon/human-command-screens.js +234 -0
  72. package/dist/heart/daemon/human-readiness.js +114 -0
  73. package/dist/heart/daemon/inner-status.js +89 -0
  74. package/dist/heart/daemon/interactive-repair.js +394 -0
  75. package/dist/heart/daemon/launchd.js +37 -8
  76. package/dist/heart/daemon/log-tailer.js +82 -12
  77. package/dist/heart/daemon/logs-prune.js +110 -0
  78. package/dist/heart/daemon/mcp-canary.js +297 -0
  79. package/dist/heart/daemon/message-router.js +2 -2
  80. package/dist/heart/daemon/os-cron-deps.js +135 -0
  81. package/dist/heart/daemon/os-cron.js +14 -12
  82. package/dist/heart/daemon/ouro-bot-entry.js +4 -2
  83. package/dist/heart/daemon/ouro-entry.js +3 -1
  84. package/dist/heart/daemon/process-manager.js +375 -33
  85. package/dist/heart/daemon/provider-discovery.js +137 -0
  86. package/dist/heart/daemon/provider-ping-progress.js +83 -0
  87. package/dist/heart/daemon/pulse.js +475 -0
  88. package/dist/heart/daemon/readiness-repair.js +365 -0
  89. package/dist/heart/daemon/run-hooks.js +2 -0
  90. package/dist/heart/daemon/runtime-logging.js +67 -16
  91. package/dist/heart/daemon/runtime-metadata.js +3 -31
  92. package/dist/heart/daemon/safe-mode.js +161 -0
  93. package/dist/heart/daemon/sense-manager.js +389 -38
  94. package/dist/heart/daemon/session-id-resolver.js +131 -0
  95. package/dist/heart/daemon/skill-management-installer.js +94 -0
  96. package/dist/heart/daemon/socket-client.js +158 -11
  97. package/dist/heart/daemon/stale-bundle-prune.js +96 -0
  98. package/dist/heart/daemon/startup-tui.js +330 -0
  99. package/dist/heart/daemon/task-scheduler.js +3 -25
  100. package/dist/heart/daemon/terminal-ui.js +499 -0
  101. package/dist/heart/daemon/thoughts.js +162 -17
  102. package/dist/heart/daemon/up-progress.js +366 -0
  103. package/dist/heart/daemon/vault-items.js +56 -0
  104. package/dist/heart/delegation.js +1 -1
  105. package/dist/heart/habits/habit-migration.js +189 -0
  106. package/dist/heart/habits/habit-parser.js +140 -0
  107. package/dist/heart/habits/habit-runtime-state.js +100 -0
  108. package/dist/heart/habits/habit-scheduler.js +372 -0
  109. package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
  110. package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
  111. package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
  112. package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
  113. package/dist/heart/identity.js +203 -57
  114. package/dist/heart/kept-notes.js +357 -0
  115. package/dist/heart/kicks.js +1 -1
  116. package/dist/heart/machine-identity.js +161 -0
  117. package/dist/heart/mail-import-discovery.js +353 -0
  118. package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
  119. package/dist/heart/mailbox/mailbox-http-response.js +7 -0
  120. package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
  121. package/dist/heart/mailbox/mailbox-http-static.js +103 -0
  122. package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
  123. package/dist/heart/mailbox/mailbox-http.js +99 -0
  124. package/dist/heart/mailbox/mailbox-read.js +31 -0
  125. package/dist/heart/mailbox/mailbox-types.js +27 -0
  126. package/dist/heart/mailbox/mailbox-view.js +195 -0
  127. package/dist/heart/mailbox/readers/agent-machine.js +382 -0
  128. package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
  129. package/dist/heart/mailbox/readers/mail.js +362 -0
  130. package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
  131. package/dist/heart/mailbox/readers/sessions.js +232 -0
  132. package/dist/heart/mailbox/readers/shared.js +111 -0
  133. package/dist/heart/mcp/mcp-server.js +683 -0
  134. package/dist/heart/migrate-config.js +100 -0
  135. package/dist/heart/model-capabilities.js +19 -0
  136. package/dist/heart/platform.js +81 -0
  137. package/dist/heart/provider-attempt.js +134 -0
  138. package/dist/heart/provider-binding-resolver.js +267 -0
  139. package/dist/heart/provider-credentials.js +425 -0
  140. package/dist/heart/provider-failover.js +301 -0
  141. package/dist/heart/provider-models.js +81 -0
  142. package/dist/heart/provider-ping.js +262 -0
  143. package/dist/heart/provider-readiness-cache.js +40 -0
  144. package/dist/heart/provider-visibility.js +188 -0
  145. package/dist/heart/providers/anthropic-token.js +131 -0
  146. package/dist/heart/providers/anthropic.js +139 -52
  147. package/dist/heart/providers/azure.js +97 -13
  148. package/dist/heart/providers/error-classification.js +127 -0
  149. package/dist/heart/providers/github-copilot.js +145 -0
  150. package/dist/heart/providers/minimax-vlm.js +189 -0
  151. package/dist/heart/providers/minimax.js +26 -8
  152. package/dist/heart/providers/openai-codex.js +55 -40
  153. package/dist/heart/runtime-capability-check.js +170 -0
  154. package/dist/heart/runtime-credentials.js +367 -0
  155. package/dist/heart/runtime-cwd.js +87 -0
  156. package/dist/heart/sense-truth.js +13 -4
  157. package/dist/heart/session-activity.js +43 -22
  158. package/dist/heart/session-events.js +1149 -0
  159. package/dist/heart/session-playback-cli-main.js +5 -0
  160. package/dist/heart/session-playback-cli.js +36 -0
  161. package/dist/heart/session-playback.js +231 -0
  162. package/dist/heart/session-stats-cli-main.js +5 -0
  163. package/dist/heart/session-stats.js +182 -0
  164. package/dist/heart/session-transcript.js +243 -0
  165. package/dist/heart/start-of-turn-packet.js +345 -0
  166. package/dist/heart/streaming.js +44 -27
  167. package/dist/heart/sync-classification.js +176 -0
  168. package/dist/heart/sync.js +449 -0
  169. package/dist/heart/target-resolution.js +9 -5
  170. package/dist/heart/tempo.js +93 -0
  171. package/dist/heart/temporal-view.js +41 -0
  172. package/dist/heart/timeouts.js +101 -0
  173. package/dist/heart/tool-activity-callbacks.js +59 -0
  174. package/dist/heart/tool-description.js +139 -0
  175. package/dist/heart/tool-friction.js +55 -0
  176. package/dist/heart/tool-loop.js +200 -0
  177. package/dist/heart/turn-context.js +389 -0
  178. package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
  179. package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
  180. package/dist/heart/versioning/ouro-path-installer.js +426 -0
  181. package/dist/heart/versioning/ouro-version-manager.js +295 -0
  182. package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
  183. package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
  184. package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
  185. package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
  186. package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
  187. package/dist/mailbox-ui/index.html +15 -0
  188. package/dist/mailroom/attention.js +167 -0
  189. package/dist/mailroom/autonomy.js +209 -0
  190. package/dist/mailroom/blob-store.js +674 -0
  191. package/dist/mailroom/body-cache.js +61 -0
  192. package/dist/mailroom/core.js +720 -0
  193. package/dist/mailroom/entry.js +160 -0
  194. package/dist/mailroom/file-store.js +430 -0
  195. package/dist/mailroom/mbox-import.js +383 -0
  196. package/dist/mailroom/outbound.js +380 -0
  197. package/dist/mailroom/policy.js +263 -0
  198. package/dist/mailroom/reader.js +233 -0
  199. package/dist/mailroom/search-cache.js +256 -0
  200. package/dist/mailroom/search-relevance.js +319 -0
  201. package/dist/mailroom/smtp-ingress.js +176 -0
  202. package/dist/mailroom/source-state.js +176 -0
  203. package/dist/mailroom/thread.js +109 -0
  204. package/dist/mailroom/travel-extract.js +89 -0
  205. package/dist/mind/bundle-manifest.js +7 -1
  206. package/dist/mind/context.js +165 -101
  207. package/dist/mind/diary-integrity.js +60 -0
  208. package/dist/mind/{memory.js → diary.js} +62 -75
  209. package/dist/mind/embedding-provider.js +60 -0
  210. package/dist/mind/file-state.js +179 -0
  211. package/dist/mind/friends/channel.js +39 -0
  212. package/dist/mind/friends/resolver.js +54 -2
  213. package/dist/mind/friends/store-file.js +39 -3
  214. package/dist/mind/friends/types.js +2 -2
  215. package/dist/mind/journal-index.js +161 -0
  216. package/dist/mind/note-search.js +268 -0
  217. package/dist/mind/obligation-steering.js +221 -0
  218. package/dist/mind/pending.js +4 -0
  219. package/dist/mind/prompt-refresh.js +3 -2
  220. package/dist/mind/prompt.js +1011 -123
  221. package/dist/mind/provenance-trust.js +26 -0
  222. package/dist/mind/scrutiny.js +173 -0
  223. package/dist/nerves/cli-logging.js +7 -1
  224. package/dist/nerves/coverage/audit-rules.js +15 -6
  225. package/dist/nerves/coverage/audit.js +28 -2
  226. package/dist/nerves/coverage/cli.js +1 -1
  227. package/dist/nerves/coverage/contract.js +5 -5
  228. package/dist/nerves/coverage/file-completeness.js +129 -5
  229. package/dist/nerves/coverage/run-artifacts.js +1 -1
  230. package/dist/nerves/event-buffer.js +111 -0
  231. package/dist/nerves/index.js +224 -4
  232. package/dist/nerves/observation.js +20 -0
  233. package/dist/nerves/redact.js +79 -0
  234. package/dist/nerves/review/cli-main.js +5 -0
  235. package/dist/nerves/review/cli.js +156 -0
  236. package/dist/nerves/review/core.js +152 -0
  237. package/dist/nerves/runtime.js +5 -1
  238. package/dist/repertoire/ado-client.js +15 -56
  239. package/dist/repertoire/ado-semantic.js +11 -10
  240. package/dist/repertoire/api-client.js +97 -0
  241. package/dist/repertoire/bitwarden-store.js +963 -0
  242. package/dist/repertoire/bundle-templates.js +72 -0
  243. package/dist/repertoire/bw-installer.js +180 -0
  244. package/dist/repertoire/coding/codex-jsonl.js +64 -0
  245. package/dist/repertoire/coding/context-pack.js +330 -0
  246. package/dist/repertoire/coding/feedback.js +197 -30
  247. package/dist/repertoire/coding/manager.js +158 -9
  248. package/dist/repertoire/coding/spawner.js +55 -9
  249. package/dist/repertoire/coding/tools.js +170 -7
  250. package/dist/repertoire/commerce-errors.js +109 -0
  251. package/dist/repertoire/commerce-self-test.js +156 -0
  252. package/dist/repertoire/credential-access.js +178 -0
  253. package/dist/repertoire/duffel-client.js +185 -0
  254. package/dist/repertoire/github-client.js +14 -55
  255. package/dist/repertoire/graph-client.js +11 -52
  256. package/dist/repertoire/guardrails.js +396 -0
  257. package/dist/repertoire/mcp-client.js +295 -0
  258. package/dist/repertoire/mcp-manager.js +362 -0
  259. package/dist/repertoire/mcp-tools.js +63 -0
  260. package/dist/repertoire/shell-sessions.js +133 -0
  261. package/dist/repertoire/skills.js +15 -24
  262. package/dist/repertoire/stripe-client.js +131 -0
  263. package/dist/repertoire/tasks/board.js +31 -5
  264. package/dist/repertoire/tasks/fix.js +182 -0
  265. package/dist/repertoire/tasks/index.js +16 -4
  266. package/dist/repertoire/tasks/lifecycle.js +2 -2
  267. package/dist/repertoire/tasks/parser.js +3 -2
  268. package/dist/repertoire/tasks/scanner.js +194 -37
  269. package/dist/repertoire/tasks/transitions.js +16 -78
  270. package/dist/repertoire/tool-results.js +29 -0
  271. package/dist/repertoire/tools-attachments.js +317 -0
  272. package/dist/repertoire/tools-base.js +47 -1075
  273. package/dist/repertoire/tools-bluebubbles.js +1 -0
  274. package/dist/repertoire/tools-bridge.js +142 -0
  275. package/dist/repertoire/tools-bundle.js +984 -0
  276. package/dist/repertoire/tools-config.js +185 -0
  277. package/dist/repertoire/tools-continuity.js +248 -0
  278. package/dist/repertoire/tools-credential.js +381 -0
  279. package/dist/repertoire/tools-files.js +342 -0
  280. package/dist/repertoire/tools-flight.js +224 -0
  281. package/dist/repertoire/tools-flow.js +119 -0
  282. package/dist/repertoire/tools-github.js +1 -7
  283. package/dist/repertoire/tools-mail.js +1857 -0
  284. package/dist/repertoire/tools-notes.js +421 -0
  285. package/dist/repertoire/tools-session.js +750 -0
  286. package/dist/repertoire/tools-shell.js +120 -0
  287. package/dist/repertoire/tools-stripe.js +180 -0
  288. package/dist/repertoire/tools-surface.js +243 -0
  289. package/dist/repertoire/tools-teams.js +9 -39
  290. package/dist/repertoire/tools-travel.js +125 -0
  291. package/dist/repertoire/tools-trip.js +604 -0
  292. package/dist/repertoire/tools-user-profile.js +144 -0
  293. package/dist/repertoire/tools-vault.js +40 -0
  294. package/dist/repertoire/tools.js +108 -100
  295. package/dist/repertoire/travel-api-client.js +360 -0
  296. package/dist/repertoire/user-profile.js +131 -0
  297. package/dist/repertoire/vault-setup.js +246 -0
  298. package/dist/repertoire/vault-unlock.js +594 -0
  299. package/dist/scripts/claude-code-hook.js +41 -0
  300. package/dist/scripts/claude-code-stop-hook.js +47 -0
  301. package/dist/senses/attention-queue.js +116 -0
  302. package/dist/senses/bluebubbles/active-turns.js +216 -0
  303. package/dist/senses/bluebubbles/attachment-cache.js +53 -0
  304. package/dist/senses/bluebubbles/attachment-download.js +137 -0
  305. package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
  306. package/dist/senses/bluebubbles/entry.js +77 -0
  307. package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
  308. package/dist/senses/bluebubbles/index.js +2305 -0
  309. package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
  310. package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
  311. package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
  312. package/dist/senses/bluebubbles/processed-log.js +133 -0
  313. package/dist/senses/bluebubbles/replay.js +137 -0
  314. package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
  315. package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
  316. package/dist/senses/cli/bracketed-paste.js +82 -0
  317. package/dist/senses/cli/image-paste.js +287 -0
  318. package/dist/senses/cli/image-ref-navigation.js +75 -0
  319. package/dist/senses/cli/ink-app.js +156 -0
  320. package/dist/senses/cli/inline-diff.js +64 -0
  321. package/dist/senses/cli/input-keys.js +174 -0
  322. package/dist/senses/cli/kill-ring.js +86 -0
  323. package/dist/senses/cli/message-list.js +51 -0
  324. package/dist/senses/cli/ouro-tui.js +607 -0
  325. package/dist/senses/cli/spinner-imperative.js +135 -0
  326. package/dist/senses/cli/spinner.js +101 -0
  327. package/dist/senses/cli/status-line.js +60 -0
  328. package/dist/senses/cli/streaming-markdown.js +526 -0
  329. package/dist/senses/cli/tool-display.js +85 -0
  330. package/dist/senses/cli/tool-render.js +85 -0
  331. package/dist/senses/cli/tui-store.js +240 -0
  332. package/dist/senses/cli/virtual-list.js +35 -0
  333. package/dist/senses/cli-entry.js +60 -8
  334. package/dist/senses/cli-layout.js +187 -0
  335. package/dist/senses/cli.js +520 -209
  336. package/dist/senses/commands.js +66 -3
  337. package/dist/senses/habit-turn-message.js +108 -0
  338. package/dist/senses/inner-dialog-worker.js +175 -21
  339. package/dist/senses/inner-dialog.js +330 -27
  340. package/dist/senses/mail-entry.js +66 -0
  341. package/dist/senses/mail.js +379 -0
  342. package/dist/senses/pipeline.js +549 -181
  343. package/dist/senses/proactive-content-guard.js +51 -0
  344. package/dist/senses/shared-turn.js +251 -0
  345. package/dist/senses/surface-tool.js +68 -0
  346. package/dist/senses/teams-entry.js +60 -8
  347. package/dist/senses/teams.js +387 -98
  348. package/dist/senses/trust-gate.js +100 -5
  349. package/dist/senses/voice/audio-routing.js +119 -0
  350. package/dist/senses/voice/elevenlabs.js +178 -0
  351. package/dist/senses/voice/golden-path.js +116 -0
  352. package/dist/senses/voice/index.js +26 -0
  353. package/dist/senses/voice/meeting.js +113 -0
  354. package/dist/senses/voice/playback.js +139 -0
  355. package/dist/senses/voice/transcript.js +70 -0
  356. package/dist/senses/voice/turn.js +85 -0
  357. package/dist/senses/voice/types.js +2 -0
  358. package/dist/senses/voice/whisper.js +161 -0
  359. package/dist/senses/voice-entry.js +80 -0
  360. package/dist/trips/core.js +138 -0
  361. package/dist/trips/store.js +146 -0
  362. package/package.json +38 -7
  363. package/skills/agent-commerce.md +106 -0
  364. package/skills/browser-navigation.md +117 -0
  365. package/skills/commerce-setup-guide.md +116 -0
  366. package/skills/commerce-setup.md +84 -0
  367. package/skills/configure-dev-tools.md +101 -0
  368. package/skills/travel-planning.md +138 -0
  369. package/dist/heart/daemon/auth-flow.js +0 -351
  370. package/dist/heart/daemon/ouro-path-installer.js +0 -178
  371. package/dist/heart/daemon/subagent-installer.js +0 -166
  372. package/dist/heart/session-recall.js +0 -116
  373. package/dist/mind/associative-recall.js +0 -209
  374. package/dist/senses/bluebubbles-entry.js +0 -13
  375. package/dist/senses/bluebubbles.js +0 -1177
  376. package/dist/senses/debug-activity.js +0 -148
  377. package/subagents/README.md +0 -86
  378. package/subagents/work-doer.md +0 -237
  379. package/subagents/work-merger.md +0 -618
  380. package/subagents/work-planner.md +0 -390
  381. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
  382. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
  383. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
  384. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
  385. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
  386. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
  387. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
  388. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
  389. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
  390. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
  391. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
  392. /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
  393. /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
  394. /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
  395. /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
  396. /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
@@ -0,0 +1,85 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ToolBadge = ToolBadge;
4
+ exports.ToolParams = ToolParams;
5
+ exports.ToolProgress = ToolProgress;
6
+ exports.ToolResultCard = ToolResultCard;
7
+ exports.ToolExecutionBlock = ToolExecutionBlock;
8
+ const jsx_runtime_1 = require("react/jsx-runtime");
9
+ const ink_1 = require("ink");
10
+ const inline_diff_1 = require("./inline-diff");
11
+ /**
12
+ * Tool execution display components for the CLI TUI.
13
+ *
14
+ * Provides: ToolBadge, ToolParams, ToolProgress, ToolResultCard, ToolExecutionBlock.
15
+ *
16
+ * Design: Ouroboros-themed. Inline diffs use green/red with +/- markers and line numbers.
17
+ * No padding -- visual separation via color/bold/dim only.
18
+ *
19
+ * Files >50KB get a summary instead of inline diff (scrutiny finding 17).
20
+ */
21
+ // Ouroboros brand palette
22
+ const OURO_GREEN = "#2ecc40";
23
+ const OURO_RED = "#e74c3c";
24
+ const OURO_TEAL = "#4ec9b0";
25
+ // 50KB threshold for inline diff vs summary
26
+ const LARGE_FILE_THRESHOLD = 50 * 1024;
27
+ // Tool name -> primary parameter key mapping
28
+ const PRIMARY_PARAM = {
29
+ edit_file: "path",
30
+ write_file: "path",
31
+ read_file: "path",
32
+ glob: "pattern",
33
+ grep: "pattern",
34
+ shell: "command",
35
+ coding_spawn: "task",
36
+ coding_status: "session_id",
37
+ coding_tail: "session_id",
38
+ };
39
+ function truncate(s, max) {
40
+ return s.length > max ? s.slice(0, max - 3) + "..." : s;
41
+ }
42
+ function ToolBadge({ name }) {
43
+ return (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_TEAL, bold: true, children: name });
44
+ }
45
+ function ToolParams({ name, args, }) {
46
+ // Find primary parameter to show inline
47
+ const primaryKey = PRIMARY_PARAM[name];
48
+ let display = "";
49
+ if (primaryKey && typeof args[primaryKey] === "string") {
50
+ display = truncate(args[primaryKey], 80);
51
+ }
52
+ else {
53
+ // Fallback: show first string value
54
+ for (const val of Object.values(args)) {
55
+ if (typeof val === "string") {
56
+ display = truncate(val, 80);
57
+ break;
58
+ }
59
+ }
60
+ }
61
+ if (!display)
62
+ return (0, jsx_runtime_1.jsx)(ink_1.Text, { children: "" });
63
+ return (0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: [" ", display] });
64
+ }
65
+ function ToolProgress({ name }) {
66
+ return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_GREEN, children: "\u25CF " }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: [name, " running..."] })] }));
67
+ }
68
+ function ToolResultCard({ name, result, success, expanded, }) {
69
+ const icon = success ? "\u2713" : "\u2717";
70
+ const color = success ? OURO_GREEN : OURO_RED;
71
+ if (expanded) {
72
+ return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: color, children: [icon, " "] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_TEAL, bold: true, children: name })] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { children: result })] }));
73
+ }
74
+ // Collapsed: one-line summary
75
+ const summary = truncate(result.replace(/\n/g, " "), 100);
76
+ return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsxs)(ink_1.Text, { color: color, children: [icon, " "] }), (0, jsx_runtime_1.jsx)(ink_1.Text, { color: OURO_TEAL, bold: true, children: name }), (0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: [" ", summary] })] }));
77
+ }
78
+ function ToolExecutionBlock({ name, args, result, success, fileBefore, fileAfter, }) {
79
+ const filePath = typeof args.path === "string" ? args.path : undefined;
80
+ const showDiff = name === "edit_file" && fileBefore !== undefined && fileAfter !== undefined;
81
+ // Check file size threshold
82
+ const tooLarge = showDiff && ((fileBefore?.length ?? 0) > LARGE_FILE_THRESHOLD ||
83
+ (fileAfter?.length ?? 0) > LARGE_FILE_THRESHOLD);
84
+ return ((0, jsx_runtime_1.jsxs)(ink_1.Box, { flexDirection: "column", children: [(0, jsx_runtime_1.jsxs)(ink_1.Box, { children: [(0, jsx_runtime_1.jsx)(ToolBadge, { name: name }), (0, jsx_runtime_1.jsx)(ToolParams, { name: name, args: args })] }), showDiff && !tooLarge ? ((0, jsx_runtime_1.jsx)(inline_diff_1.InlineDiff, { before: fileBefore, after: fileAfter, filePath: filePath ?? "unknown" })) : /* v8 ignore next -- tooLarge branch not exercised in render tests @preserve */ showDiff && tooLarge ? ((0, jsx_runtime_1.jsxs)(ink_1.Text, { dimColor: true, children: ["large file changed (", Math.round((fileAfter?.length ?? 0) / 1024), "KB)"] })) : ((0, jsx_runtime_1.jsx)(ToolResultCard, { name: name, result: result, success: success }))] }));
85
+ }
@@ -0,0 +1,240 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.TuiStore = void 0;
4
+ exports.createTuiCallbacks = createTuiCallbacks;
5
+ /**
6
+ * TUI Store — mutable external state for the OuroTui component.
7
+ *
8
+ * Tracks two buckets:
9
+ * 1. completedMessages — fed to Ink's <Static>, rendered once
10
+ * 2. live — current turn state, re-renders on change
11
+ *
12
+ * ZERO business logic. Just state + notify.
13
+ */
14
+ const phrases_1 = require("../../mind/phrases");
15
+ const format_1 = require("../../mind/format");
16
+ const runtime_1 = require("../../nerves/runtime");
17
+ class TuiStore {
18
+ _completed = [];
19
+ _live = {
20
+ streamingText: "",
21
+ loading: false,
22
+ spinnerPhrase: "",
23
+ spinnerPhrasePool: [],
24
+ activeTool: null,
25
+ errorMessage: null,
26
+ kickMessage: null,
27
+ inputSuppressed: false,
28
+ };
29
+ _spinnerStart = 0;
30
+ _hadTool = false;
31
+ _turnId = 0;
32
+ _listeners = new Set();
33
+ _headerShown = false;
34
+ _inputHistory = [];
35
+ _queuedInputs = [];
36
+ get completedMessages() { return this._completed; }
37
+ get live() { return this._live; }
38
+ get headerShown() { return this._headerShown; }
39
+ get inputHistory() { return this._inputHistory; }
40
+ get queuedInputs() { return this._queuedInputs; }
41
+ /** Elapsed seconds since spinner started — computed on demand, not stored */
42
+ getElapsed() {
43
+ if (this._live.loading && this._spinnerStart > 0) {
44
+ return Math.floor((Date.now() - this._spinnerStart) / 1000);
45
+ }
46
+ return 0;
47
+ }
48
+ subscribe(fn) {
49
+ this._listeners.add(fn);
50
+ return () => { this._listeners.delete(fn); };
51
+ }
52
+ notify() {
53
+ for (const fn of this._listeners)
54
+ fn();
55
+ }
56
+ // ─── Called by business logic (via callbacks) ───
57
+ modelStart() {
58
+ const phrases = (0, phrases_1.getPhrases)();
59
+ const pool = this._hadTool ? phrases.followup : phrases.thinking;
60
+ this._live = {
61
+ ...this._live,
62
+ loading: true,
63
+ spinnerPhrase: (0, phrases_1.pickPhrase)(pool),
64
+ spinnerPhrasePool: pool,
65
+ streamingText: "",
66
+ activeTool: null,
67
+ errorMessage: null,
68
+ kickMessage: null,
69
+ };
70
+ this._spinnerStart = Date.now();
71
+ this._turnId++;
72
+ this.notify();
73
+ }
74
+ appendText(text) {
75
+ this._live = {
76
+ ...this._live,
77
+ loading: false,
78
+ streamingText: this._live.streamingText + text,
79
+ };
80
+ this.notify();
81
+ }
82
+ clearText() {
83
+ this._live = { ...this._live, streamingText: "" };
84
+ this.notify();
85
+ }
86
+ toolStart(name, args) {
87
+ this._hadTool = true;
88
+ // Before showing tool in-progress, commit any buffered streaming text
89
+ // so it doesn't disappear when the live area switches to tool display
90
+ if (this._live.streamingText.trim()) {
91
+ this._completed = [...this._completed, {
92
+ id: `asst-${this._turnId}-${Date.now()}`,
93
+ role: "assistant",
94
+ content: this._live.streamingText.trim(),
95
+ }];
96
+ }
97
+ this._live = {
98
+ ...this._live,
99
+ loading: true,
100
+ streamingText: "",
101
+ activeTool: { name, args },
102
+ spinnerPhrase: (0, phrases_1.pickPhrase)((0, phrases_1.getPhrases)().tool),
103
+ spinnerPhrasePool: (0, phrases_1.getPhrases)().tool,
104
+ };
105
+ this._spinnerStart = Date.now();
106
+ this.notify();
107
+ }
108
+ toolEnd(name, argSummary, success) {
109
+ // Move tool result to completed messages (so it renders via Static)
110
+ this._completed = [...this._completed, {
111
+ id: `tool-${this._turnId}-${Date.now()}`,
112
+ role: "tool",
113
+ content: "",
114
+ toolCalls: [{ name, argSummary, success }],
115
+ }];
116
+ this._live = {
117
+ ...this._live,
118
+ loading: false,
119
+ activeTool: null,
120
+ };
121
+ this.notify();
122
+ }
123
+ setError(msg) {
124
+ this._live = { ...this._live, loading: false, errorMessage: msg };
125
+ this.notify();
126
+ }
127
+ setKick() {
128
+ this._live = { ...this._live, loading: false, kickMessage: (0, format_1.formatKick)() };
129
+ this.notify();
130
+ }
131
+ suppressInput() {
132
+ this._live = { ...this._live, inputSuppressed: true };
133
+ this.notify();
134
+ }
135
+ restoreInput() {
136
+ this._live = { ...this._live, inputSuppressed: false };
137
+ this.notify();
138
+ }
139
+ /** Commit current streaming text as a completed assistant message */
140
+ commitAssistantMessage() {
141
+ if (this._live.streamingText.trim()) {
142
+ this._completed = [...this._completed, {
143
+ id: `asst-${this._turnId}-${Date.now()}`,
144
+ role: "assistant",
145
+ content: this._live.streamingText.trim(),
146
+ }];
147
+ }
148
+ // Clear streaming text immediately — prevents double display
149
+ this._live = {
150
+ ...this._live,
151
+ loading: false,
152
+ streamingText: "",
153
+ activeTool: null,
154
+ errorMessage: null,
155
+ kickMessage: null,
156
+ };
157
+ this.notify();
158
+ }
159
+ /** Add a user message to completed (for display) AND input history */
160
+ addUserMessage(text) {
161
+ if (this._completed.length === 0) {
162
+ this._headerShown = false;
163
+ }
164
+ this._completed = [...this._completed, {
165
+ id: `user-${Date.now()}`,
166
+ role: "user",
167
+ content: text,
168
+ }];
169
+ this._inputHistory.push(text);
170
+ this.notify();
171
+ }
172
+ /** Add text to input history only (no completed message, no notify). Used by ESC-to-clear. */
173
+ addToHistoryOnly(text) {
174
+ this._inputHistory.push(text);
175
+ }
176
+ /** Seed input history from previous session messages (display only, no rendering) */
177
+ seedHistory(texts) {
178
+ this._inputHistory.push(...texts);
179
+ }
180
+ /** Push previous session exchanges as normal user/assistant messages (for resume display) */
181
+ addResumeMessages(exchanges) {
182
+ if (exchanges.length === 0) {
183
+ this.notify();
184
+ return;
185
+ }
186
+ const msgs = exchanges.map((ex, i) => ({
187
+ id: `resume-${i}`,
188
+ role: ex.role,
189
+ content: ex.content,
190
+ }));
191
+ this._completed = [...msgs, ...this._completed];
192
+ this.notify();
193
+ }
194
+ // ─── Queued input display ────────────────────────────────────────
195
+ enqueueInput(text) {
196
+ this._queuedInputs.push(text);
197
+ this.notify();
198
+ }
199
+ dequeueInput(text) {
200
+ const idx = this._queuedInputs.indexOf(text);
201
+ if (idx !== -1) {
202
+ this._queuedInputs.splice(idx, 1);
203
+ }
204
+ this.notify();
205
+ }
206
+ popAllQueuedForEditing() {
207
+ const copy = [...this._queuedInputs];
208
+ this._queuedInputs = [];
209
+ this.notify();
210
+ return copy;
211
+ }
212
+ clearQueue() {
213
+ this._queuedInputs = [];
214
+ this.notify();
215
+ }
216
+ }
217
+ exports.TuiStore = TuiStore;
218
+ // ─── Callbacks factory ──────────────────────────────────────────────
219
+ function createTuiCallbacks(store) {
220
+ (0, runtime_1.emitNervesEvent)({
221
+ component: "senses",
222
+ event: "senses.tui_callbacks_created",
223
+ message: "TUI callbacks created",
224
+ meta: {},
225
+ });
226
+ return {
227
+ onModelStart: () => { store.modelStart(); },
228
+ onModelStreamStart: () => { },
229
+ onClearText: () => { store.clearText(); },
230
+ onTextChunk: (text) => { store.appendText(text); },
231
+ onReasoningChunk: () => { },
232
+ onToolStart: (name, args) => { store.toolStart(name, args); },
233
+ onToolEnd: (name, argSummary, success) => { store.toolEnd(name, argSummary, success); },
234
+ onError: (error, severity) => {
235
+ store.setError(severity === "terminal" ? (0, format_1.formatError)(error) : error.message);
236
+ },
237
+ onKick: () => { store.setKick(); },
238
+ flushMarkdown: () => { store.commitAssistantMessage(); },
239
+ };
240
+ }
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.VirtualList = VirtualList;
4
+ const jsx_runtime_1 = require("react/jsx-runtime");
5
+ const react_1 = require("react");
6
+ const ink_1 = require("ink");
7
+ function VirtualList({ items, viewportHeight, scrollOffset, renderItem, }) {
8
+ const { startIndex, visibleItems } = (0, react_1.useMemo)(() => {
9
+ if (items.length === 0) {
10
+ return { startIndex: 0, visibleItems: [] };
11
+ }
12
+ // Determine the start index for the visible window
13
+ let start;
14
+ if (scrollOffset !== undefined) {
15
+ // Scroll-locked: show items starting at the given offset
16
+ start = Math.max(0, Math.min(scrollOffset, items.length - 1));
17
+ }
18
+ else {
19
+ // Auto-scroll: pin to bottom, show last viewportHeight items
20
+ start = Math.max(0, items.length - viewportHeight);
21
+ }
22
+ const end = Math.min(start + viewportHeight, items.length);
23
+ return {
24
+ startIndex: start,
25
+ visibleItems: items.slice(start, end),
26
+ };
27
+ }, [items, viewportHeight, scrollOffset]);
28
+ if (visibleItems.length === 0) {
29
+ return (0, jsx_runtime_1.jsx)(ink_1.Box, { children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: "" }) });
30
+ }
31
+ return ((0, jsx_runtime_1.jsx)(ink_1.Box, { flexDirection: "column", children: visibleItems.map((item, i) => {
32
+ const globalIndex = startIndex + i;
33
+ return ((0, jsx_runtime_1.jsx)(ink_1.Box, { children: (0, jsx_runtime_1.jsx)(ink_1.Text, { children: renderItem(item, globalIndex) }) }, globalIndex));
34
+ }) }));
35
+ }
@@ -1,15 +1,67 @@
1
1
  "use strict";
2
- // Thin entrypoint for `npm run dev` / `node dist/senses/cli-entry.js --agent <name>`.
3
- // Separated from cli.ts so the CLI adapter is pure library code with clean
4
- // 100% test coverage -- entrypoints can't be covered by vitest since
5
- // require.main !== module in the test runner.
6
- // All config comes from the conventional ~/.agentsecrets/<agent>/secrets.json path.
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
+ })();
7
35
  Object.defineProperty(exports, "__esModule", { value: true });
36
+ const runtime_1 = require("../nerves/runtime");
8
37
  // Fail fast if --agent is missing (before any src/ code tries getAgentName())
9
- if (!process.argv.includes("--agent")) {
38
+ const agentArgIndex = process.argv.indexOf("--agent");
39
+ const agentName = agentArgIndex >= 0 ? process.argv[agentArgIndex + 1] : undefined;
40
+ if (!agentName) {
10
41
  // eslint-disable-next-line no-console -- pre-boot guard: --agent check before imports
11
42
  console.error("Missing required --agent <name> argument.\nUsage: node dist/senses/cli-entry.js --agent ouroboros");
12
43
  process.exit(1);
13
44
  }
14
- const cli_1 = require("./cli");
15
- (0, cli_1.main)();
45
+ (0, runtime_1.emitNervesEvent)({
46
+ component: "senses",
47
+ event: "senses.entry_boot",
48
+ message: "booting CLI entrypoint",
49
+ meta: { entry: "cli", agentName },
50
+ });
51
+ Promise.resolve().then(() => __importStar(require("../heart/runtime-credentials"))).then(async ({ refreshRuntimeCredentialConfig }) => {
52
+ void refreshRuntimeCredentialConfig(agentName, { preserveCachedOnFailure: true }).catch(() => undefined);
53
+ const { main } = await Promise.resolve().then(() => __importStar(require("./cli")));
54
+ main();
55
+ })
56
+ .catch((error) => {
57
+ (0, runtime_1.emitNervesEvent)({
58
+ level: "error",
59
+ component: "senses",
60
+ event: "senses.entry_error",
61
+ message: "CLI entrypoint failed",
62
+ meta: { entry: "cli", agentName, error: error instanceof Error ? error.message : String(error) },
63
+ });
64
+ // eslint-disable-next-line no-console -- fatal startup guard for sense process
65
+ console.error(error instanceof Error ? error.message : String(error));
66
+ process.exit(1);
67
+ });
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StreamingWordWrapper = void 0;
4
+ exports.wrapCliText = wrapCliText;
5
+ exports.formatEchoedInputSummary = formatEchoedInputSummary;
6
+ const runtime_1 = require("../nerves/runtime");
7
+ // Strip ANSI escape sequences to measure visible text width.
8
+ const ANSI_RE = /\x1b\[[0-9;]*[A-Za-z]/g;
9
+ function visibleLength(text) {
10
+ return text.replace(ANSI_RE, "").length;
11
+ }
12
+ /**
13
+ * Streaming word wrapper for terminal output.
14
+ *
15
+ * Text arrives in small chunks (sometimes single characters). This class
16
+ * buffers a partial line and emits complete wrapped lines at word boundaries
17
+ * when the visible width approaches the terminal column limit.
18
+ *
19
+ * ANSI escape sequences are treated as zero-width so colours and styles
20
+ * pass through without affecting line-break decisions.
21
+ */
22
+ class StreamingWordWrapper {
23
+ col = 0; // visible columns consumed on the current line
24
+ buf = ""; // buffered text for the current line (not yet emitted)
25
+ width; // terminal column count
26
+ constructor(cols) {
27
+ this.width = Math.max(cols ?? (process.stdout.columns || 80), 1);
28
+ }
29
+ /** Accept a chunk of already-rendered text and return text ready for stdout. */
30
+ push(text) {
31
+ let out = "";
32
+ for (let i = 0; i < text.length; i++) {
33
+ const ch = text[i];
34
+ // Pass through ANSI escape sequences without counting width
35
+ /* v8 ignore start -- ANSI handling: tested via StreamingWordWrapper ANSI test @preserve */
36
+ if (ch === "\x1b") {
37
+ const rest = text.slice(i);
38
+ const m = rest.match(/^\x1b\[[0-9;]*[A-Za-z]/);
39
+ if (m) {
40
+ this.buf += m[0];
41
+ i += m[0].length - 1;
42
+ continue;
43
+ }
44
+ }
45
+ /* v8 ignore stop */
46
+ // Explicit newline: flush current line and reset
47
+ if (ch === "\n") {
48
+ out += this.buf + "\n";
49
+ this.buf = "";
50
+ this.col = 0;
51
+ continue;
52
+ }
53
+ // Space: if the current line is already at or past width, wrap now.
54
+ // Otherwise just append.
55
+ if (ch === " ") {
56
+ /* v8 ignore start -- wrap-at-space: tested via StreamingWordWrapper unit tests @preserve */
57
+ if (this.col >= this.width) {
58
+ out += this.buf + "\n";
59
+ this.buf = "";
60
+ this.col = 0;
61
+ // Drop the space at the wrap point
62
+ continue;
63
+ /* v8 ignore stop */
64
+ }
65
+ this.buf += ch;
66
+ this.col++;
67
+ continue;
68
+ }
69
+ // Non-space character
70
+ this.col++;
71
+ if (this.col > this.width) {
72
+ // We've exceeded the width. Try to break at the last space.
73
+ const lastSpace = this.buf.lastIndexOf(" ");
74
+ if (lastSpace !== -1) {
75
+ out += this.buf.slice(0, lastSpace) + "\n";
76
+ // Keep the remainder (after space) plus current char
77
+ this.buf = this.buf.slice(lastSpace + 1) + ch;
78
+ this.col = visibleLength(this.buf);
79
+ }
80
+ else {
81
+ // No space to break at — hard wrap
82
+ out += this.buf + "\n";
83
+ this.buf = ch;
84
+ this.col = 1;
85
+ }
86
+ continue;
87
+ }
88
+ this.buf += ch;
89
+ }
90
+ return out;
91
+ }
92
+ /** Flush any remaining buffered text (call at end of response). */
93
+ flush() {
94
+ const remainder = this.buf;
95
+ this.buf = "";
96
+ this.col = 0;
97
+ return remainder;
98
+ }
99
+ /** Reset wrapper state (call at start of new model turn). */
100
+ reset() {
101
+ this.buf = "";
102
+ this.col = 0;
103
+ }
104
+ }
105
+ exports.StreamingWordWrapper = StreamingWordWrapper;
106
+ function splitLongWord(word, width) {
107
+ const chunks = [];
108
+ for (let index = 0; index < word.length; index += width) {
109
+ chunks.push(word.slice(index, index + width));
110
+ }
111
+ return chunks;
112
+ }
113
+ function wrapCliText(text, cols) {
114
+ const width = Math.max(cols, 1);
115
+ const wrapped = [];
116
+ for (const rawLine of text.split("\n")) {
117
+ if (rawLine.trim().length === 0) {
118
+ wrapped.push("");
119
+ continue;
120
+ }
121
+ const words = rawLine.trim().split(/\s+/);
122
+ let current = "";
123
+ for (const word of words) {
124
+ if (!current) {
125
+ if (word.length <= width) {
126
+ current = word;
127
+ continue;
128
+ }
129
+ const chunks = splitLongWord(word, width);
130
+ wrapped.push(...chunks.slice(0, -1));
131
+ current = chunks[chunks.length - 1];
132
+ continue;
133
+ }
134
+ const candidate = `${current} ${word}`;
135
+ if (candidate.length <= width) {
136
+ current = candidate;
137
+ continue;
138
+ }
139
+ wrapped.push(current);
140
+ if (word.length <= width) {
141
+ current = word;
142
+ continue;
143
+ }
144
+ const chunks = splitLongWord(word, width);
145
+ wrapped.push(...chunks.slice(0, -1));
146
+ current = chunks[chunks.length - 1];
147
+ }
148
+ wrapped.push(current);
149
+ }
150
+ return wrapped;
151
+ }
152
+ function countEchoedInputRows(input, cols) {
153
+ const width = Math.max(cols, 1);
154
+ return input.split("\n").reduce((sum, line, index) => {
155
+ const promptWidth = index === 0 ? 2 : 0;
156
+ return sum + Math.max(1, Math.ceil((promptWidth + line.length) / width));
157
+ }, 0);
158
+ }
159
+ function formatEchoedInputSummary(input, cols) {
160
+ const inputLines = input.split("\n");
161
+ const summary = `> ${inputLines[0]}${inputLines.length > 1 ? ` (+${inputLines.length - 1} lines)` : ""}`;
162
+ const wrappedSummary = wrapCliText(summary, cols);
163
+ const echoRows = countEchoedInputRows(input, cols);
164
+ (0, runtime_1.emitNervesEvent)({
165
+ component: "senses",
166
+ event: "senses.cli_echo_summary_formatted",
167
+ message: "formatted echoed cli input summary",
168
+ meta: {
169
+ cols,
170
+ echo_rows: echoRows,
171
+ input_line_count: inputLines.length,
172
+ wrapped_line_count: wrappedSummary.length,
173
+ },
174
+ });
175
+ let output = `\x1b[${echoRows}A`;
176
+ for (let i = 0; i < echoRows; i += 1) {
177
+ output += "\r\x1b[K";
178
+ if (i < echoRows - 1) {
179
+ output += "\x1b[1B";
180
+ }
181
+ }
182
+ if (echoRows > 1) {
183
+ output += `\x1b[${echoRows - 1}A`;
184
+ }
185
+ output += `\x1b[1m${wrappedSummary.join("\n")}\x1b[0m\n\n`;
186
+ return output;
187
+ }