@ouro.bot/cli 0.1.0-alpha.60 → 0.1.0-alpha.600
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.
- package/README.md +127 -23
- package/RepairGuide.ouro/agent.json +5 -0
- package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
- package/RepairGuide.ouro/psyche/SOUL.md +55 -0
- package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
- package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
- package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
- package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +4 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/SOUL.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/changelog.json +3857 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +254 -0
- package/dist/arc/packets.js +193 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +65 -0
- package/dist/heart/active-work.js +837 -26
- package/dist/heart/agent-entry.js +69 -3
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/adapter.js +2 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +16 -0
- package/dist/heart/attachments/store.js +103 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +479 -0
- package/dist/heart/awaiting/await-alert.js +146 -0
- package/dist/heart/awaiting/await-expiry.js +108 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +141 -0
- package/dist/heart/awaiting/await-runtime-state.js +97 -0
- package/dist/heart/awaiting/await-scheduler.js +377 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +142 -0
- package/dist/heart/config-registry.js +322 -0
- package/dist/heart/config.js +114 -119
- package/dist/heart/core.js +909 -246
- package/dist/heart/cross-chat-delivery.js +3 -18
- package/dist/heart/daemon/agent-config-check.js +419 -0
- package/dist/heart/daemon/agent-discovery.js +102 -3
- package/dist/heart/daemon/agent-service.js +522 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +776 -0
- package/dist/heart/daemon/cli-exec.js +7571 -0
- package/dist/heart/daemon/cli-help.js +498 -0
- package/dist/heart/daemon/cli-parse.js +1599 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +763 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/daemon-cli.js +29 -1703
- package/dist/heart/daemon/daemon-entry.js +485 -2
- package/dist/heart/daemon/daemon-health.js +176 -0
- package/dist/heart/daemon/daemon-rollup.js +57 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +88 -13
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +842 -69
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +873 -0
- package/dist/heart/daemon/health-monitor.js +122 -1
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +37 -8
- package/dist/heart/daemon/log-tailer.js +78 -9
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +14 -12
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/process-manager.js +375 -33
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/pulse.js +475 -0
- package/dist/heart/daemon/readiness-repair.js +365 -0
- package/dist/heart/daemon/run-hooks.js +2 -0
- package/dist/heart/daemon/runtime-logging.js +10 -2
- package/dist/heart/daemon/runtime-metadata.js +2 -30
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +462 -38
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +158 -11
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +330 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +162 -17
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +1 -1
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
- package/dist/heart/{daemon → hatch}/specialist-tools.js +35 -12
- package/dist/heart/identity.js +166 -55
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +31 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +195 -0
- package/dist/heart/mailbox/readers/agent-machine.js +382 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
- package/dist/heart/mailbox/readers/mail.js +367 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
- package/dist/heart/mailbox/readers/sessions.js +232 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +656 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +19 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +267 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +139 -52
- package/dist/heart/providers/azure.js +23 -11
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +367 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +13 -4
- package/dist/heart/session-activity.js +43 -22
- package/dist/heart/session-events.js +1149 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +182 -0
- package/dist/heart/session-transcript.js +243 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +44 -27
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -0
- package/dist/heart/target-resolution.js +9 -5
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/timeouts.js +101 -0
- package/dist/heart/tool-activity-callbacks.js +59 -0
- package/dist/heart/tool-description.js +143 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +421 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +426 -0
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
- package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/mailbox-ui/index.html +15 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +700 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/core.js +788 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +457 -0
- package/dist/mailroom/mbox-import.js +393 -0
- package/dist/mailroom/migration.js +164 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +233 -0
- package/dist/mailroom/search-cache.js +268 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/thread.js +109 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +7 -1
- package/dist/mind/context.js +165 -101
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +62 -75
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +39 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +39 -3
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/note-search.js +268 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +4 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1050 -135
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/nerves/cli-logging.js +7 -1
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +129 -5
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +224 -4
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/redact.js +79 -0
- package/dist/nerves/review/cli-main.js +5 -0
- package/dist/nerves/review/cli.js +156 -0
- package/dist/nerves/review/core.js +152 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +997 -0
- package/dist/repertoire/bundle-templates.js +72 -0
- package/dist/repertoire/bw-installer.js +180 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +158 -9
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -7
- package/dist/repertoire/commerce-errors.js +109 -0
- package/dist/repertoire/commerce-self-test.js +156 -0
- package/dist/repertoire/credential-access.js +178 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +396 -0
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +362 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +31 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +16 -4
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +16 -78
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-awaiting.js +360 -0
- package/dist/repertoire/tools-base.js +53 -1082
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +142 -0
- package/dist/repertoire/tools-bundle.js +984 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +381 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1916 -0
- package/dist/repertoire/tools-notes.js +421 -0
- package/dist/repertoire/tools-obligations.js +142 -0
- package/dist/repertoire/tools-runtime.js +61 -0
- package/dist/repertoire/tools-session.js +809 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +345 -0
- package/dist/repertoire/tools-teams.js +9 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +604 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice.js +144 -0
- package/dist/repertoire/tools.js +115 -103
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +594 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +116 -0
- package/dist/senses/await-turn-message.js +58 -0
- package/dist/senses/bluebubbles/active-turns.js +216 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/bluebubbles/attachment-download.js +137 -0
- package/dist/senses/{bluebubbles-client.js → bluebubbles/client.js} +219 -18
- package/dist/senses/bluebubbles/entry.js +77 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +20 -3
- package/dist/senses/bluebubbles/index.js +2548 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +33 -12
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +3 -3
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/replay.js +137 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/bluebubbles-meta-guard.js +40 -0
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +607 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +85 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +240 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli-layout.js +100 -0
- package/dist/senses/cli.js +516 -204
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +185 -21
- package/dist/senses/inner-dialog.js +372 -27
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +654 -181
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +392 -0
- package/dist/senses/surface-tool.js +70 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +387 -98
- package/dist/senses/trust-gate.js +100 -5
- package/dist/senses/voice/audio-playback.js +237 -0
- package/dist/senses/voice/audio-routing.js +119 -0
- package/dist/senses/voice/elevenlabs.js +202 -0
- package/dist/senses/voice/floor-control.js +431 -0
- package/dist/senses/voice/floor-controller.js +115 -0
- package/dist/senses/voice/golden-path.js +116 -0
- package/dist/senses/voice/index.js +29 -0
- package/dist/senses/voice/meeting.js +113 -0
- package/dist/senses/voice/outbound.js +190 -0
- package/dist/senses/voice/phone.js +33 -0
- package/dist/senses/voice/playback.js +139 -0
- package/dist/senses/voice/realtime-eval.js +496 -0
- package/dist/senses/voice/realtime-trace.js +531 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +191 -0
- package/dist/senses/voice/twilio-phone-runtime.js +807 -0
- package/dist/senses/voice/twilio-phone.js +5077 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +81 -0
- package/dist/senses/voice-realtime-eval-command.js +99 -0
- package/dist/senses/voice-realtime-eval-entry.js +21 -0
- package/dist/senses/voice-twilio-entry.js +87 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +265 -0
- package/package.json +41 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +99 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -351
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/associative-recall.js +0 -209
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/bluebubbles.js +0 -1177
- package/dist/senses/debug-activity.js +0 -148
- package/subagents/README.md +0 -86
- package/subagents/work-doer.md +0 -237
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -390
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/basilisk.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jafar.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/jormungandr.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/kaa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/medusa.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/nagini.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/ouroboros.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/python.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/quetzalcoatl.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/sir-hiss.md +0 -0
- /package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-snake.md +0 -0
- /package/dist/heart/{daemon → hatch}/hatch-animation.js +0 -0
- /package/dist/heart/{daemon → hatch}/specialist-orchestrator.js +0 -0
- /package/dist/heart/{daemon → versioning}/ouro-uti.js +0 -0
- /package/dist/heart/{daemon → versioning}/wrapper-publish-guard.js +0 -0
|
@@ -0,0 +1,393 @@
|
|
|
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.splitMboxMessages = splitMboxMessages;
|
|
37
|
+
exports.importMboxToStore = importMboxToStore;
|
|
38
|
+
exports.importMboxFileToStore = importMboxFileToStore;
|
|
39
|
+
exports.cacheMatchingMailSearchDocumentsFromMboxFile = cacheMatchingMailSearchDocumentsFromMboxFile;
|
|
40
|
+
const fs = __importStar(require("node:fs"));
|
|
41
|
+
const runtime_1 = require("../nerves/runtime");
|
|
42
|
+
const core_1 = require("./core");
|
|
43
|
+
const search_cache_1 = require("./search-cache");
|
|
44
|
+
const search_relevance_1 = require("./search-relevance");
|
|
45
|
+
function splitMboxMessages(rawMbox) {
|
|
46
|
+
const text = rawMbox.toString("utf-8");
|
|
47
|
+
const separators = [...text.matchAll(/^From [^\r\n]*(?:\r?\n)/gm)];
|
|
48
|
+
if (separators.length === 0) {
|
|
49
|
+
const trimmed = text.trim();
|
|
50
|
+
return trimmed ? [Buffer.from(text, "utf-8")] : [];
|
|
51
|
+
}
|
|
52
|
+
const messages = separators
|
|
53
|
+
.map((match, index) => {
|
|
54
|
+
const start = match.index + match[0].length;
|
|
55
|
+
const end = index + 1 < separators.length ? separators[index + 1].index : text.length;
|
|
56
|
+
return text.slice(start, end).replace(/\r?\n$/, "");
|
|
57
|
+
})
|
|
58
|
+
.filter((message) => message.trim().length > 0)
|
|
59
|
+
.map((message) => Buffer.from(message, "utf-8"));
|
|
60
|
+
(0, runtime_1.emitNervesEvent)({
|
|
61
|
+
component: "senses",
|
|
62
|
+
event: "senses.mail_mbox_split",
|
|
63
|
+
message: "mbox payload split into messages",
|
|
64
|
+
meta: { messages: messages.length },
|
|
65
|
+
});
|
|
66
|
+
return messages;
|
|
67
|
+
}
|
|
68
|
+
function trimTrailingLineEnding(message) {
|
|
69
|
+
if (message.length >= 2 && message[message.length - 2] === 0x0d && message[message.length - 1] === 0x0a) {
|
|
70
|
+
return message.subarray(0, -2);
|
|
71
|
+
}
|
|
72
|
+
if (message.length >= 1 && message[message.length - 1] === 0x0a) {
|
|
73
|
+
return message.subarray(0, -1);
|
|
74
|
+
}
|
|
75
|
+
return message;
|
|
76
|
+
}
|
|
77
|
+
function isSeparatorLine(line) {
|
|
78
|
+
return line.length >= 5 &&
|
|
79
|
+
line[0] === 0x46 &&
|
|
80
|
+
line[1] === 0x72 &&
|
|
81
|
+
line[2] === 0x6f &&
|
|
82
|
+
line[3] === 0x6d &&
|
|
83
|
+
line[4] === 0x20;
|
|
84
|
+
}
|
|
85
|
+
async function* streamMboxMessagesFromFile(filePath) {
|
|
86
|
+
const stream = fs.createReadStream(filePath);
|
|
87
|
+
let pending = Buffer.alloc(0);
|
|
88
|
+
let currentParts = [];
|
|
89
|
+
const flushCurrent = () => {
|
|
90
|
+
if (currentParts.length === 0)
|
|
91
|
+
return null;
|
|
92
|
+
const message = trimTrailingLineEnding(Buffer.concat(currentParts));
|
|
93
|
+
currentParts = [];
|
|
94
|
+
return message;
|
|
95
|
+
};
|
|
96
|
+
for await (const chunk of stream) {
|
|
97
|
+
pending = pending.length > 0 ? Buffer.concat([pending, chunk]) : Buffer.from(chunk);
|
|
98
|
+
let newlineIndex = pending.indexOf(0x0a);
|
|
99
|
+
while (newlineIndex >= 0) {
|
|
100
|
+
const line = pending.subarray(0, newlineIndex + 1);
|
|
101
|
+
pending = pending.subarray(newlineIndex + 1);
|
|
102
|
+
if (isSeparatorLine(line)) {
|
|
103
|
+
const message = flushCurrent();
|
|
104
|
+
if (message && message.length > 0)
|
|
105
|
+
yield message;
|
|
106
|
+
}
|
|
107
|
+
else {
|
|
108
|
+
currentParts.push(Buffer.from(line));
|
|
109
|
+
}
|
|
110
|
+
newlineIndex = pending.indexOf(0x0a);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (pending.length > 0) {
|
|
114
|
+
if (isSeparatorLine(pending)) {
|
|
115
|
+
const message = flushCurrent();
|
|
116
|
+
if (message && message.length > 0)
|
|
117
|
+
yield message;
|
|
118
|
+
}
|
|
119
|
+
else {
|
|
120
|
+
currentParts.push(Buffer.from(pending));
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
const finalMessage = flushCurrent();
|
|
124
|
+
if (finalMessage && finalMessage.length > 0)
|
|
125
|
+
yield finalMessage;
|
|
126
|
+
}
|
|
127
|
+
function findSourceGrant(input) {
|
|
128
|
+
const ownerEmail = input.ownerEmail ? (0, core_1.normalizeMailAddress)(input.ownerEmail) : undefined;
|
|
129
|
+
const source = input.source?.trim().toLowerCase();
|
|
130
|
+
const grants = input.registry.sourceGrants.filter((grant) => {
|
|
131
|
+
if (!grant.enabled || grant.agentId !== input.agentId)
|
|
132
|
+
return false;
|
|
133
|
+
if (ownerEmail && (0, core_1.normalizeMailAddress)(grant.ownerEmail) !== ownerEmail)
|
|
134
|
+
return false;
|
|
135
|
+
if (source && grant.source.toLowerCase() !== source)
|
|
136
|
+
return false;
|
|
137
|
+
return true;
|
|
138
|
+
});
|
|
139
|
+
if (grants.length === 0) {
|
|
140
|
+
throw new Error(`No enabled Mailroom source grant found for ${input.agentId}${ownerEmail ? ` owner ${ownerEmail}` : ""}${source ? ` source ${source}` : ""}`);
|
|
141
|
+
}
|
|
142
|
+
if (grants.length > 1 && !ownerEmail && !source) {
|
|
143
|
+
throw new Error(`Multiple source grants found for ${input.agentId}; pass --owner-email or --source to choose one`);
|
|
144
|
+
}
|
|
145
|
+
return grants[0];
|
|
146
|
+
}
|
|
147
|
+
function parseMboxMessage(rawMessage, grant) {
|
|
148
|
+
const mailFrom = extractHeaderAddress(rawMessage, "from");
|
|
149
|
+
const messageDate = extractHeaderDate(rawMessage, "date");
|
|
150
|
+
return {
|
|
151
|
+
rawMessage,
|
|
152
|
+
envelope: {
|
|
153
|
+
mailFrom: mailFrom ? (0, core_1.normalizeMailAddress)(mailFrom) : "",
|
|
154
|
+
rcptTo: [(0, core_1.normalizeMailAddress)(grant.aliasAddress)],
|
|
155
|
+
remoteAddress: "mbox-import",
|
|
156
|
+
},
|
|
157
|
+
...(messageDate ? { messageDate } : {}),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
function latestMessageDate(messages) {
|
|
161
|
+
const timestamps = messages
|
|
162
|
+
.map((message) => message.messageDate?.getTime())
|
|
163
|
+
.filter((timestamp) => typeof timestamp === "number" && Number.isFinite(timestamp));
|
|
164
|
+
if (timestamps.length === 0)
|
|
165
|
+
return null;
|
|
166
|
+
return new Date(Math.max(...timestamps)).toISOString();
|
|
167
|
+
}
|
|
168
|
+
function readHeaderBlock(rawMessage) {
|
|
169
|
+
const crlfBoundary = rawMessage.indexOf("\r\n\r\n");
|
|
170
|
+
if (crlfBoundary >= 0) {
|
|
171
|
+
return rawMessage.subarray(0, crlfBoundary).toString("utf-8");
|
|
172
|
+
}
|
|
173
|
+
const lfBoundary = rawMessage.indexOf("\n\n");
|
|
174
|
+
if (lfBoundary >= 0) {
|
|
175
|
+
return rawMessage.subarray(0, lfBoundary).toString("utf-8");
|
|
176
|
+
}
|
|
177
|
+
return rawMessage.toString("utf-8");
|
|
178
|
+
}
|
|
179
|
+
function extractHeaderValue(rawMessage, headerName) {
|
|
180
|
+
const target = `${headerName.toLowerCase()}:`;
|
|
181
|
+
let currentHeader = "";
|
|
182
|
+
const unfoldedHeaders = [];
|
|
183
|
+
for (const line of readHeaderBlock(rawMessage).split(/\r?\n/)) {
|
|
184
|
+
if (/^[ \t]/.test(line) && currentHeader) {
|
|
185
|
+
currentHeader += ` ${line.trim()}`;
|
|
186
|
+
continue;
|
|
187
|
+
}
|
|
188
|
+
if (currentHeader)
|
|
189
|
+
unfoldedHeaders.push(currentHeader);
|
|
190
|
+
currentHeader = line;
|
|
191
|
+
}
|
|
192
|
+
if (currentHeader)
|
|
193
|
+
unfoldedHeaders.push(currentHeader);
|
|
194
|
+
const match = unfoldedHeaders.find((line) => line.toLowerCase().startsWith(target));
|
|
195
|
+
return match ? match.slice(target.length).trim() : "";
|
|
196
|
+
}
|
|
197
|
+
function extractHeaderAddress(rawMessage, headerName) {
|
|
198
|
+
const value = extractHeaderValue(rawMessage, headerName);
|
|
199
|
+
if (!value)
|
|
200
|
+
return "";
|
|
201
|
+
const bracketed = value.match(/<([^>]+)>/);
|
|
202
|
+
if (bracketed?.[1])
|
|
203
|
+
return bracketed[1];
|
|
204
|
+
const plain = value.match(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i);
|
|
205
|
+
return plain?.[0] ?? "";
|
|
206
|
+
}
|
|
207
|
+
function extractHeaderDate(rawMessage, headerName) {
|
|
208
|
+
const value = extractHeaderValue(rawMessage, headerName);
|
|
209
|
+
if (!value)
|
|
210
|
+
return undefined;
|
|
211
|
+
const parsed = new Date(value);
|
|
212
|
+
return Number.isFinite(parsed.getTime()) ? parsed : undefined;
|
|
213
|
+
}
|
|
214
|
+
function normalizeSearchTerms(queryTerms) {
|
|
215
|
+
return queryTerms
|
|
216
|
+
.map((term) => term.trim().toLowerCase())
|
|
217
|
+
.filter((term) => term.length > 0);
|
|
218
|
+
}
|
|
219
|
+
function historicalImportClassification(resolvedPlacement, sourceGrant) {
|
|
220
|
+
return {
|
|
221
|
+
placement: resolvedPlacement,
|
|
222
|
+
candidate: false,
|
|
223
|
+
trustReason: `delegated source grant ${sourceGrant.source} historical mbox import`,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
async function importParsedMessagesToStore(input) {
|
|
227
|
+
let imported = 0;
|
|
228
|
+
let duplicates = 0;
|
|
229
|
+
const messages = [];
|
|
230
|
+
let scanned = 0;
|
|
231
|
+
const importedAt = (input.importedAt ?? new Date()).toISOString();
|
|
232
|
+
const sourceFreshThrough = input.sourceFreshThrough ?? null;
|
|
233
|
+
const maxConcurrency = Math.max(1, input.maxConcurrency ?? 1);
|
|
234
|
+
const inFlight = new Set();
|
|
235
|
+
const enqueue = (parsedMessage) => {
|
|
236
|
+
const task = (async () => {
|
|
237
|
+
const result = await input.store.putRawMessage({
|
|
238
|
+
resolved: input.resolved,
|
|
239
|
+
envelope: parsedMessage.envelope,
|
|
240
|
+
rawMime: parsedMessage.rawMessage,
|
|
241
|
+
receivedAt: parsedMessage.messageDate ?? input.importedAt,
|
|
242
|
+
ingest: {
|
|
243
|
+
schemaVersion: 1,
|
|
244
|
+
kind: "mbox-import",
|
|
245
|
+
importedAt,
|
|
246
|
+
sourceFreshThrough,
|
|
247
|
+
attentionSuppressed: true,
|
|
248
|
+
},
|
|
249
|
+
classification: historicalImportClassification(input.resolved.defaultPlacement, input.sourceGrant),
|
|
250
|
+
});
|
|
251
|
+
if (input.collectMessages !== false)
|
|
252
|
+
messages.push(result.message);
|
|
253
|
+
if (result.created)
|
|
254
|
+
imported += 1;
|
|
255
|
+
else
|
|
256
|
+
duplicates += 1;
|
|
257
|
+
input.onProgress?.({ scanned, imported, duplicates });
|
|
258
|
+
})().finally(() => {
|
|
259
|
+
inFlight.delete(task);
|
|
260
|
+
});
|
|
261
|
+
inFlight.add(task);
|
|
262
|
+
return task;
|
|
263
|
+
};
|
|
264
|
+
for await (const parsedMessage of input.parsedMessages) {
|
|
265
|
+
scanned += 1;
|
|
266
|
+
input.onProgress?.({ scanned, imported, duplicates });
|
|
267
|
+
enqueue(parsedMessage);
|
|
268
|
+
if (inFlight.size >= maxConcurrency) {
|
|
269
|
+
await Promise.race(inFlight);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
await Promise.all(inFlight);
|
|
273
|
+
(0, runtime_1.emitNervesEvent)({
|
|
274
|
+
component: "senses",
|
|
275
|
+
event: "senses.mail_mbox_imported",
|
|
276
|
+
message: "mbox mail imported",
|
|
277
|
+
meta: { agentId: input.sourceGrant.agentId.toLowerCase(), scanned, imported, duplicates, grantId: input.sourceGrant.grantId },
|
|
278
|
+
});
|
|
279
|
+
return {
|
|
280
|
+
agentId: input.sourceGrant.agentId.toLowerCase(),
|
|
281
|
+
sourceGrant: input.sourceGrant,
|
|
282
|
+
scanned,
|
|
283
|
+
imported,
|
|
284
|
+
duplicates,
|
|
285
|
+
sourceFreshThrough,
|
|
286
|
+
messages,
|
|
287
|
+
};
|
|
288
|
+
}
|
|
289
|
+
async function scanMboxFileFreshness(filePath, sourceGrant) {
|
|
290
|
+
let latestTimestamp = Number.NEGATIVE_INFINITY;
|
|
291
|
+
for await (const rawMessage of streamMboxMessagesFromFile(filePath)) {
|
|
292
|
+
const parsedMessage = parseMboxMessage(rawMessage, sourceGrant);
|
|
293
|
+
if (parsedMessage.messageDate) {
|
|
294
|
+
latestTimestamp = Math.max(latestTimestamp, parsedMessage.messageDate.getTime());
|
|
295
|
+
}
|
|
296
|
+
}
|
|
297
|
+
return Number.isFinite(latestTimestamp) ? new Date(latestTimestamp).toISOString() : null;
|
|
298
|
+
}
|
|
299
|
+
function resolveImportTarget(input) {
|
|
300
|
+
const agentId = input.agentId.toLowerCase();
|
|
301
|
+
const sourceGrant = findSourceGrant({
|
|
302
|
+
registry: input.registry,
|
|
303
|
+
agentId,
|
|
304
|
+
ownerEmail: input.ownerEmail,
|
|
305
|
+
source: input.source,
|
|
306
|
+
});
|
|
307
|
+
const resolved = (0, core_1.resolveMailAddress)(input.registry, sourceGrant.aliasAddress);
|
|
308
|
+
/* v8 ignore start -- findSourceGrant and resolveMailAddress share the same registry; this is a corruption guard. @preserve */
|
|
309
|
+
if (!resolved) {
|
|
310
|
+
throw new Error(`Source grant alias ${sourceGrant.aliasAddress} is not resolvable`);
|
|
311
|
+
}
|
|
312
|
+
/* v8 ignore stop */
|
|
313
|
+
return { agentId, sourceGrant, resolved };
|
|
314
|
+
}
|
|
315
|
+
async function importMboxToStore(input) {
|
|
316
|
+
const target = resolveImportTarget(input);
|
|
317
|
+
const rawMessages = splitMboxMessages(input.rawMbox);
|
|
318
|
+
const parsedMessages = rawMessages.map((rawMessage) => parseMboxMessage(rawMessage, target.sourceGrant));
|
|
319
|
+
const sourceFreshThrough = latestMessageDate(parsedMessages);
|
|
320
|
+
return importParsedMessagesToStore({
|
|
321
|
+
sourceGrant: target.sourceGrant,
|
|
322
|
+
resolved: target.resolved,
|
|
323
|
+
store: input.store,
|
|
324
|
+
parsedMessages,
|
|
325
|
+
importedAt: input.importedAt,
|
|
326
|
+
collectMessages: true,
|
|
327
|
+
sourceFreshThrough,
|
|
328
|
+
});
|
|
329
|
+
}
|
|
330
|
+
async function importMboxFileToStore(input) {
|
|
331
|
+
const target = resolveImportTarget(input);
|
|
332
|
+
const sourceFreshThrough = await scanMboxFileFreshness(input.filePath, target.sourceGrant);
|
|
333
|
+
async function* parsedMessages() {
|
|
334
|
+
for await (const rawMessage of streamMboxMessagesFromFile(input.filePath)) {
|
|
335
|
+
yield parseMboxMessage(rawMessage, target.sourceGrant);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
return importParsedMessagesToStore({
|
|
339
|
+
sourceGrant: target.sourceGrant,
|
|
340
|
+
resolved: target.resolved,
|
|
341
|
+
store: input.store,
|
|
342
|
+
parsedMessages: parsedMessages(),
|
|
343
|
+
importedAt: input.importedAt,
|
|
344
|
+
collectMessages: false,
|
|
345
|
+
sourceFreshThrough,
|
|
346
|
+
maxConcurrency: 8,
|
|
347
|
+
onProgress: input.onProgress,
|
|
348
|
+
});
|
|
349
|
+
}
|
|
350
|
+
async function cacheMatchingMailSearchDocumentsFromMboxFile(input) {
|
|
351
|
+
const target = resolveImportTarget(input);
|
|
352
|
+
const queryTerms = normalizeSearchTerms(input.queryTerms);
|
|
353
|
+
if (queryTerms.length === 0 || input.limit <= 0)
|
|
354
|
+
return [];
|
|
355
|
+
const matches = [];
|
|
356
|
+
for await (const rawMessage of streamMboxMessagesFromFile(input.filePath)) {
|
|
357
|
+
const parsedMessage = parseMboxMessage(rawMessage, target.sourceGrant);
|
|
358
|
+
const { privateEnvelope, metadata } = await (0, core_1.buildStoredMailMessageMetadata)({
|
|
359
|
+
resolved: target.resolved,
|
|
360
|
+
envelope: parsedMessage.envelope,
|
|
361
|
+
rawMime: parsedMessage.rawMessage,
|
|
362
|
+
receivedAt: parsedMessage.messageDate,
|
|
363
|
+
ingest: {
|
|
364
|
+
schemaVersion: 1,
|
|
365
|
+
kind: "mbox-import",
|
|
366
|
+
attentionSuppressed: true,
|
|
367
|
+
},
|
|
368
|
+
classification: historicalImportClassification(target.resolved.defaultPlacement, target.sourceGrant),
|
|
369
|
+
});
|
|
370
|
+
// Projection-only: we need a `StoredMailMessage` shape for buildMailSearchCacheDocument
|
|
371
|
+
// but never persist this view; the live import (via store.putRawMessage) is
|
|
372
|
+
// what writes the durable record.
|
|
373
|
+
const { rawObjectStem, ...rest } = metadata;
|
|
374
|
+
const message = {
|
|
375
|
+
...rest,
|
|
376
|
+
rawObject: `${rawObjectStem}.eml`,
|
|
377
|
+
bodyForm: "plaintext",
|
|
378
|
+
private: privateEnvelope,
|
|
379
|
+
};
|
|
380
|
+
const document = (0, search_cache_1.buildMailSearchCacheDocument)(message, privateEnvelope);
|
|
381
|
+
if (!queryTerms.some((term) => document.searchText.includes(term)))
|
|
382
|
+
continue;
|
|
383
|
+
(0, search_cache_1.upsertMailSearchCacheDocument)(message, privateEnvelope);
|
|
384
|
+
matches.push(document);
|
|
385
|
+
matches.sort((left, right) => (0, search_relevance_1.compareByRelevanceThenRecency)({ document: left, relevance: (0, search_relevance_1.scoreMailSearchDocument)(left, queryTerms) }, { document: right, relevance: (0, search_relevance_1.scoreMailSearchDocument)(right, queryTerms) }));
|
|
386
|
+
if (matches.length > input.limit)
|
|
387
|
+
matches.length = input.limit;
|
|
388
|
+
}
|
|
389
|
+
return matches
|
|
390
|
+
.map((document) => ({ document, relevance: (0, search_relevance_1.scoreMailSearchDocument)(document, queryTerms) }))
|
|
391
|
+
.sort(search_relevance_1.compareByRelevanceThenRecency)
|
|
392
|
+
.map((entry) => entry.document);
|
|
393
|
+
}
|
|
@@ -0,0 +1,164 @@
|
|
|
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.migrateLocalMailroomToPlaintext = migrateLocalMailroomToPlaintext;
|
|
37
|
+
const fs = __importStar(require("node:fs"));
|
|
38
|
+
const path = __importStar(require("node:path"));
|
|
39
|
+
const runtime_1 = require("../nerves/runtime");
|
|
40
|
+
function readJson(filePath) {
|
|
41
|
+
try {
|
|
42
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
43
|
+
}
|
|
44
|
+
catch {
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
function listJsonEntries(dir) {
|
|
49
|
+
if (!fs.existsSync(dir))
|
|
50
|
+
return [];
|
|
51
|
+
return fs.readdirSync(dir).filter((name) => name.endsWith(".json"));
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* One-time, idempotent cleanup of pre-plaintext residue.
|
|
55
|
+
*
|
|
56
|
+
* Wipes:
|
|
57
|
+
* - `messages/*.json` for this agent that are not already in the new plaintext
|
|
58
|
+
* shape (no `bodyForm: "plaintext"` AND no `private` field). Unparseable JSON
|
|
59
|
+
* also goes — we cannot safely keep ambiguous bytes.
|
|
60
|
+
* - `raw/*.json` files that look like an `EncryptedPayload` JSON wrapper (the
|
|
61
|
+
* pre-change raw-storage shape). Plaintext `.eml` files are preserved.
|
|
62
|
+
* Non-EncryptedPayload JSON in `raw/` is left alone.
|
|
63
|
+
* - Coverage records in `searchCacheRoot/coverage/` whose `storeKind` is no
|
|
64
|
+
* longer reachable (`azure-blob` from a previous hosted attachment) or whose
|
|
65
|
+
* JSON is unreadable. `file` coverage records are preserved.
|
|
66
|
+
* - Orphan search-cache docs in `searchCacheRoot/*.json` that belong to this
|
|
67
|
+
* agent but reference a `messageId` no longer present in `messages/`.
|
|
68
|
+
*
|
|
69
|
+
* Idempotent: a second run finds nothing to wipe and returns zeroed counts.
|
|
70
|
+
*/
|
|
71
|
+
function migrateLocalMailroomToPlaintext(input) {
|
|
72
|
+
const messagesDir = path.join(input.mailroomRoot, "messages");
|
|
73
|
+
const rawDir = path.join(input.mailroomRoot, "raw");
|
|
74
|
+
const coverageDir = path.join(input.searchCacheRoot, "coverage");
|
|
75
|
+
let wipedEnvelopes = 0;
|
|
76
|
+
let wipedRaw = 0;
|
|
77
|
+
let wipedCoverageRecords = 0;
|
|
78
|
+
let wipedOrphanSearchDocs = 0;
|
|
79
|
+
// 1. Messages: drop pre-plaintext or malformed shapes for this agent.
|
|
80
|
+
const surviving = new Set();
|
|
81
|
+
for (const entry of listJsonEntries(messagesDir)) {
|
|
82
|
+
const filePath = path.join(messagesDir, entry);
|
|
83
|
+
const value = readJson(filePath);
|
|
84
|
+
if (value === null) {
|
|
85
|
+
// Unparseable JSON — we cannot tell whose it is or what shape, but the
|
|
86
|
+
// pre-change codebase wrote message JSON here; treat as wipeable.
|
|
87
|
+
fs.unlinkSync(filePath);
|
|
88
|
+
wipedEnvelopes += 1;
|
|
89
|
+
continue;
|
|
90
|
+
}
|
|
91
|
+
const isCurrentShape = value.bodyForm === "plaintext" && value.private !== undefined && value.private !== null;
|
|
92
|
+
if (isCurrentShape) {
|
|
93
|
+
const stem = entry.slice(0, -".json".length);
|
|
94
|
+
surviving.add(stem);
|
|
95
|
+
continue;
|
|
96
|
+
}
|
|
97
|
+
// We don't restrict to a specific agentId here because the file store is
|
|
98
|
+
// single-agent: the bundle owns this directory and the migration is
|
|
99
|
+
// initiated from inside that bundle.
|
|
100
|
+
fs.unlinkSync(filePath);
|
|
101
|
+
wipedEnvelopes += 1;
|
|
102
|
+
}
|
|
103
|
+
// 2. Raw artifacts: drop pre-change encrypted JSON wrappers.
|
|
104
|
+
if (fs.existsSync(rawDir)) {
|
|
105
|
+
for (const entry of fs.readdirSync(rawDir)) {
|
|
106
|
+
if (!entry.endsWith(".json"))
|
|
107
|
+
continue;
|
|
108
|
+
const filePath = path.join(rawDir, entry);
|
|
109
|
+
const value = readJson(filePath);
|
|
110
|
+
const isEncryptedPayload = value !== null
|
|
111
|
+
&& typeof value.algorithm === "string"
|
|
112
|
+
&& value.algorithm.startsWith("RSA-OAEP")
|
|
113
|
+
&& typeof value.ciphertext === "string";
|
|
114
|
+
if (!isEncryptedPayload)
|
|
115
|
+
continue;
|
|
116
|
+
fs.unlinkSync(filePath);
|
|
117
|
+
wipedRaw += 1;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// 3. Coverage records: drop azure-blob (no longer reachable) and malformed.
|
|
121
|
+
for (const entry of listJsonEntries(coverageDir)) {
|
|
122
|
+
const filePath = path.join(coverageDir, entry);
|
|
123
|
+
const value = readJson(filePath);
|
|
124
|
+
if (value === null) {
|
|
125
|
+
fs.unlinkSync(filePath);
|
|
126
|
+
wipedCoverageRecords += 1;
|
|
127
|
+
continue;
|
|
128
|
+
}
|
|
129
|
+
if (value.agentId !== input.agentId)
|
|
130
|
+
continue;
|
|
131
|
+
if (value.storeKind === "file")
|
|
132
|
+
continue;
|
|
133
|
+
fs.unlinkSync(filePath);
|
|
134
|
+
wipedCoverageRecords += 1;
|
|
135
|
+
}
|
|
136
|
+
// 4. Orphan search-cache docs.
|
|
137
|
+
for (const entry of listJsonEntries(input.searchCacheRoot)) {
|
|
138
|
+
const filePath = path.join(input.searchCacheRoot, entry);
|
|
139
|
+
const value = readJson(filePath);
|
|
140
|
+
if (value === null)
|
|
141
|
+
continue;
|
|
142
|
+
if (value.agentId !== input.agentId)
|
|
143
|
+
continue;
|
|
144
|
+
if (typeof value.messageId !== "string")
|
|
145
|
+
continue;
|
|
146
|
+
if (surviving.has(value.messageId))
|
|
147
|
+
continue;
|
|
148
|
+
fs.unlinkSync(filePath);
|
|
149
|
+
wipedOrphanSearchDocs += 1;
|
|
150
|
+
}
|
|
151
|
+
(0, runtime_1.emitNervesEvent)({
|
|
152
|
+
component: "senses",
|
|
153
|
+
event: "senses.mail_local_migration_executed",
|
|
154
|
+
message: "local mailroom plaintext migration executed",
|
|
155
|
+
meta: {
|
|
156
|
+
agentId: input.agentId,
|
|
157
|
+
wipedEnvelopes,
|
|
158
|
+
wipedRaw,
|
|
159
|
+
wipedCoverageRecords,
|
|
160
|
+
wipedOrphanSearchDocs,
|
|
161
|
+
},
|
|
162
|
+
});
|
|
163
|
+
return { wipedEnvelopes, wipedRaw, wipedCoverageRecords, wipedOrphanSearchDocs };
|
|
164
|
+
}
|