@ouro.bot/cli 0.1.0-alpha.66 → 0.1.0-alpha.661
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 +4216 -13
- package/dist/a2a/card.js +56 -0
- package/dist/a2a/client.js +143 -0
- package/dist/a2a/config.js +50 -0
- package/dist/a2a/onboarding.js +111 -0
- package/dist/a2a/server.js +498 -0
- package/dist/a2a/task-store.js +69 -0
- package/dist/a2a/types.js +3 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +144 -0
- package/dist/arc/episodes.js +118 -0
- package/dist/arc/evolution.js +487 -0
- package/dist/arc/flight-recorder.js +369 -0
- package/dist/arc/intentions.js +134 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +292 -0
- package/dist/arc/packets.js +288 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +57 -0
- package/dist/commerce/store.js +755 -0
- package/dist/commerce/types.js +3 -0
- package/dist/heart/active-work.js +860 -43
- 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/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 +100 -0
- package/dist/heart/awaiting/await-scheduler.js +377 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bridges/manager.js +137 -17
- package/dist/heart/bridges/store.js +14 -2
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +135 -0
- package/dist/heart/config-registry.js +331 -0
- package/dist/heart/config.js +118 -119
- package/dist/heart/context-loss-gauntlet.js +354 -0
- package/dist/heart/core.js +1123 -247
- 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 +523 -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 +780 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +7767 -0
- package/dist/heart/daemon/cli-help.js +558 -0
- package/dist/heart/daemon/cli-parse.js +1688 -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 -1750
- 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 +937 -74
- 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 +135 -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 +78 -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 +79 -10
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/message-router.js +6 -2
- package/dist/heart/daemon/migrate-to-desk.js +848 -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/plugin-cli.js +432 -0
- package/dist/heart/daemon/process-manager.js +511 -40
- 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 +35 -14
- 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 +564 -38
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +1 -1
- 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 +117 -39
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +229 -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 -4
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +203 -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 +40 -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 +45 -18
- package/dist/heart/identity.js +174 -57
- package/dist/heart/kept-notes.js +289 -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 +67 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +250 -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 +32 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +197 -0
- package/dist/heart/mailbox/readers/agent-machine.js +418 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +324 -0
- package/dist/heart/mailbox/readers/mail.js +375 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +728 -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 +696 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +19 -0
- package/dist/heart/orientation-frame.js +217 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +272 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +311 -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-token.js +349 -0
- 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 +17 -4
- package/dist/heart/session-activity.js +48 -24
- package/dist/heart/session-events.js +1133 -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 +133 -0
- package/dist/heart/start-of-turn-packet.js +351 -0
- package/dist/heart/streaming.js +44 -27
- package/dist/heart/structured-output.js +196 -0
- 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 +155 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +430 -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 +409 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/versioning/update-hooks.js +154 -0
- package/dist/heart/work-card.js +386 -0
- package/dist/mailbox-ui/assets/index-B-V9vRQ0.js +61 -0
- package/dist/mailbox-ui/assets/index-BOZbGbkL.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 +715 -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 +568 -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 +334 -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 +21 -2
- package/dist/mind/context.js +250 -101
- package/dist/mind/desk-section.js +362 -0
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +68 -77
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +48 -0
- package/dist/mind/friends/resolver.js +107 -4
- package/dist/mind/friends/store-file.js +61 -4
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/{associative-recall.js → note-search.js} +47 -58
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +6 -1
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1015 -140
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/record-paths.js +312 -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 +139 -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 +16 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +1041 -0
- package/dist/repertoire/bundle-templates.js +71 -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 +331 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +166 -10
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +219 -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/desk/classifier.js +362 -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 +159 -25
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +434 -0
- package/dist/repertoire/mcp-tools.js +83 -0
- package/dist/repertoire/plugin-mcp.js +175 -0
- package/dist/repertoire/plugins.js +253 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +48 -4
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-a2a.js +283 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-awaiting.js +372 -0
- package/dist/repertoire/tools-base.js +63 -1082
- package/dist/repertoire/tools-bluebubbles.js +2 -0
- package/dist/repertoire/tools-bridge.js +144 -0
- package/dist/repertoire/tools-bundle.js +993 -0
- package/dist/repertoire/tools-commerce.js +253 -0
- package/dist/repertoire/tools-config.js +186 -0
- package/dist/repertoire/tools-continuity.js +252 -0
- package/dist/repertoire/tools-credential.js +383 -0
- package/dist/repertoire/tools-evolution.js +527 -0
- package/dist/repertoire/tools-files.js +344 -0
- package/dist/repertoire/tools-flight.js +290 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +3 -8
- package/dist/repertoire/tools-mail.js +1975 -0
- package/dist/repertoire/tools-notes.js +418 -0
- package/dist/repertoire/tools-obligations.js +143 -0
- package/dist/repertoire/tools-orientation.js +31 -0
- package/dist/repertoire/tools-record.js +469 -0
- package/dist/repertoire/tools-runtime.js +150 -0
- package/dist/repertoire/tools-session.js +766 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +224 -0
- package/dist/repertoire/tools-surface.js +344 -0
- package/dist/repertoire/tools-teams.js +12 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +982 -0
- package/dist/repertoire/tools-user-profile.js +146 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice.js +145 -0
- package/dist/repertoire/tools.js +243 -79
- 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/a2a-entry.js +78 -0
- package/dist/senses/attention-queue.js +186 -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 +2737 -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 +517 -204
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +122 -0
- package/dist/senses/inner-dialog-worker.js +303 -22
- package/dist/senses/inner-dialog.js +525 -41
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +857 -180
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +419 -0
- package/dist/senses/surface-tool.js +108 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +390 -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 +5079 -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/dist/util/frontmatter.js +69 -0
- package/package.json +55 -12
- package/skills/agent-commerce.md +113 -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/update-hooks.js +0 -138
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- package/dist/repertoire/tasks/board.js +0 -134
- package/dist/repertoire/tasks/index.js +0 -224
- package/dist/repertoire/tasks/lifecycle.js +0 -80
- package/dist/repertoire/tasks/middleware.js +0 -65
- package/dist/repertoire/tasks/parser.js +0 -173
- package/dist/repertoire/tasks/scanner.js +0 -132
- package/dist/repertoire/tasks/transitions.js +0 -144
- 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 -7
- /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/{repertoire/tasks/types.js → heart/attachments/sources/adapter.js} +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
|
@@ -33,53 +33,26 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
-
exports.
|
|
37
|
-
exports.
|
|
38
|
-
exports.
|
|
39
|
-
exports.
|
|
36
|
+
exports.ensureDiaryStorePaths = ensureDiaryStorePaths;
|
|
37
|
+
exports.appendEntriesWithDedup = appendEntriesWithDedup;
|
|
38
|
+
exports.resolveDiaryRoot = resolveDiaryRoot;
|
|
39
|
+
exports.readDiaryEntries = readDiaryEntries;
|
|
40
|
+
exports.saveDiaryEntry = saveDiaryEntry;
|
|
40
41
|
exports.backfillEmbeddings = backfillEmbeddings;
|
|
41
|
-
exports.
|
|
42
|
+
exports.searchDiaryEntries = searchDiaryEntries;
|
|
42
43
|
const fs = __importStar(require("fs"));
|
|
43
44
|
const path = __importStar(require("path"));
|
|
44
45
|
const crypto_1 = require("crypto");
|
|
45
|
-
const
|
|
46
|
-
const identity_1 = require("../heart/identity");
|
|
46
|
+
const session_events_1 = require("../heart/session-events");
|
|
47
47
|
const runtime_1 = require("../nerves/runtime");
|
|
48
|
-
const
|
|
48
|
+
const note_search_1 = require("./note-search");
|
|
49
|
+
const diary_integrity_1 = require("./diary-integrity");
|
|
50
|
+
const embedding_provider_1 = require("./embedding-provider");
|
|
51
|
+
const record_paths_1 = require("./record-paths");
|
|
49
52
|
const DEDUP_THRESHOLD = 0.6;
|
|
50
53
|
const SEMANTIC_DEDUP_THRESHOLD = 0.95;
|
|
51
54
|
const ENTITY_TOKEN = /[a-z0-9]+/g;
|
|
52
|
-
|
|
53
|
-
class OpenAIEmbeddingProvider {
|
|
54
|
-
apiKey;
|
|
55
|
-
model;
|
|
56
|
-
constructor(apiKey, model = DEFAULT_EMBEDDING_MODEL) {
|
|
57
|
-
this.apiKey = apiKey;
|
|
58
|
-
this.model = model;
|
|
59
|
-
}
|
|
60
|
-
async embed(texts) {
|
|
61
|
-
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
62
|
-
method: "POST",
|
|
63
|
-
headers: {
|
|
64
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
65
|
-
"Content-Type": "application/json",
|
|
66
|
-
},
|
|
67
|
-
body: JSON.stringify({
|
|
68
|
-
model: this.model,
|
|
69
|
-
input: texts,
|
|
70
|
-
}),
|
|
71
|
-
});
|
|
72
|
-
if (!response.ok) {
|
|
73
|
-
throw new Error(`embedding request failed: ${response.status} ${response.statusText}`);
|
|
74
|
-
}
|
|
75
|
-
const payload = (await response.json());
|
|
76
|
-
if (!payload.data || payload.data.length !== texts.length) {
|
|
77
|
-
throw new Error("embedding response missing expected vectors");
|
|
78
|
-
}
|
|
79
|
-
return payload.data.map((entry) => entry.embedding);
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
function ensureMemoryStorePaths(rootDir) {
|
|
55
|
+
function ensureDiaryStorePaths(rootDir) {
|
|
83
56
|
const factsPath = path.join(rootDir, "facts.jsonl");
|
|
84
57
|
const entitiesPath = path.join(rootDir, "entities.json");
|
|
85
58
|
const dailyDir = path.join(rootDir, "daily");
|
|
@@ -91,8 +64,8 @@ function ensureMemoryStorePaths(rootDir) {
|
|
|
91
64
|
fs.writeFileSync(entitiesPath, "{}\n", "utf8");
|
|
92
65
|
(0, runtime_1.emitNervesEvent)({
|
|
93
66
|
component: "mind",
|
|
94
|
-
event: "mind.
|
|
95
|
-
message: "
|
|
67
|
+
event: "mind.diary_paths_ready",
|
|
68
|
+
message: "diary store paths ready",
|
|
96
69
|
meta: { rootDir },
|
|
97
70
|
});
|
|
98
71
|
return { rootDir, factsPath, entitiesPath, dailyDir };
|
|
@@ -115,7 +88,7 @@ function overlapScore(left, right) {
|
|
|
115
88
|
}
|
|
116
89
|
return common / Math.min(leftWords.size, rightWords.size);
|
|
117
90
|
}
|
|
118
|
-
function
|
|
91
|
+
function readExistingEntries(factsPath) {
|
|
119
92
|
if (!fs.existsSync(factsPath))
|
|
120
93
|
return [];
|
|
121
94
|
const raw = fs.readFileSync(factsPath, "utf8").trim();
|
|
@@ -178,13 +151,17 @@ function appendDailyFact(dailyDir, fact) {
|
|
|
178
151
|
const dayPath = path.join(dailyDir, `${day}.jsonl`);
|
|
179
152
|
fs.appendFileSync(dayPath, `${JSON.stringify(fact)}\n`, "utf8");
|
|
180
153
|
}
|
|
181
|
-
function
|
|
182
|
-
const existing =
|
|
154
|
+
function appendEntriesWithDedup(stores, incoming, options) {
|
|
155
|
+
const existing = readExistingEntries(stores.factsPath);
|
|
156
|
+
const cappedIncoming = incoming.map((fact) => ({
|
|
157
|
+
...fact,
|
|
158
|
+
text: (0, session_events_1.capStructuredRecordString)(fact.text),
|
|
159
|
+
}));
|
|
183
160
|
const all = [...existing];
|
|
184
161
|
let added = 0;
|
|
185
162
|
let skipped = 0;
|
|
186
163
|
const semanticThreshold = options?.semanticThreshold;
|
|
187
|
-
for (const fact of
|
|
164
|
+
for (const fact of cappedIncoming) {
|
|
188
165
|
const duplicate = all.some((prior) => {
|
|
189
166
|
if (overlapScore(prior.text, fact.text) > DEDUP_THRESHOLD)
|
|
190
167
|
return true;
|
|
@@ -192,7 +169,7 @@ function appendFactsWithDedup(stores, incoming, options) {
|
|
|
192
169
|
Array.isArray(fact.embedding) && fact.embedding.length > 0 &&
|
|
193
170
|
Array.isArray(prior.embedding) && prior.embedding.length > 0 &&
|
|
194
171
|
fact.embedding.length === prior.embedding.length) {
|
|
195
|
-
return (0,
|
|
172
|
+
return (0, note_search_1.cosineSimilarity)(fact.embedding, prior.embedding) > semanticThreshold;
|
|
196
173
|
}
|
|
197
174
|
return false;
|
|
198
175
|
});
|
|
@@ -208,26 +185,20 @@ function appendFactsWithDedup(stores, incoming, options) {
|
|
|
208
185
|
}
|
|
209
186
|
(0, runtime_1.emitNervesEvent)({
|
|
210
187
|
component: "mind",
|
|
211
|
-
event: "mind.
|
|
212
|
-
message: "
|
|
188
|
+
event: "mind.diary_write",
|
|
189
|
+
message: "diary write completed",
|
|
213
190
|
meta: { added, skipped },
|
|
214
191
|
});
|
|
215
192
|
return { added, skipped };
|
|
216
193
|
}
|
|
217
|
-
function createDefaultEmbeddingProvider() {
|
|
218
|
-
const apiKey = (0, config_1.getOpenAIEmbeddingsApiKey)().trim();
|
|
219
|
-
if (!apiKey)
|
|
220
|
-
return null;
|
|
221
|
-
return new OpenAIEmbeddingProvider(apiKey);
|
|
222
|
-
}
|
|
223
194
|
async function buildEmbedding(text, embeddingProvider) {
|
|
224
|
-
const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
|
|
195
|
+
const provider = embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
|
|
225
196
|
if (!provider) {
|
|
226
197
|
(0, runtime_1.emitNervesEvent)({
|
|
227
198
|
level: "warn",
|
|
228
199
|
component: "mind",
|
|
229
|
-
event: "mind.
|
|
230
|
-
message: "embedding provider unavailable for
|
|
200
|
+
event: "mind.diary_embedding_unavailable",
|
|
201
|
+
message: "embedding provider unavailable for diary write",
|
|
231
202
|
meta: { reason: "missing_openai_embeddings_key" },
|
|
232
203
|
});
|
|
233
204
|
return [];
|
|
@@ -240,8 +211,8 @@ async function buildEmbedding(text, embeddingProvider) {
|
|
|
240
211
|
(0, runtime_1.emitNervesEvent)({
|
|
241
212
|
level: "warn",
|
|
242
213
|
component: "mind",
|
|
243
|
-
event: "mind.
|
|
244
|
-
message: "embedding provider unavailable for
|
|
214
|
+
event: "mind.diary_embedding_unavailable",
|
|
215
|
+
message: "embedding provider unavailable for diary write",
|
|
245
216
|
meta: {
|
|
246
217
|
reason: error instanceof Error ? error.message : String(error),
|
|
247
218
|
},
|
|
@@ -249,13 +220,18 @@ async function buildEmbedding(text, embeddingProvider) {
|
|
|
249
220
|
return [];
|
|
250
221
|
}
|
|
251
222
|
}
|
|
252
|
-
function
|
|
253
|
-
|
|
223
|
+
function resolveDiaryRoot(explicitRoot) {
|
|
224
|
+
if (explicitRoot)
|
|
225
|
+
return explicitRoot;
|
|
226
|
+
return (0, record_paths_1.resolveRecordDiaryRoot)();
|
|
254
227
|
}
|
|
255
|
-
|
|
228
|
+
function readDiaryEntries(diaryRoot) {
|
|
229
|
+
return readExistingEntries(path.join(resolveDiaryRoot(diaryRoot), "facts.jsonl"));
|
|
230
|
+
}
|
|
231
|
+
async function saveDiaryEntry(options) {
|
|
256
232
|
const text = options.text.trim();
|
|
257
|
-
const
|
|
258
|
-
const stores =
|
|
233
|
+
const diaryRoot = resolveDiaryRoot(options.diaryRoot);
|
|
234
|
+
const stores = ensureDiaryStorePaths(diaryRoot);
|
|
259
235
|
const embedding = await buildEmbedding(text, options.embeddingProvider);
|
|
260
236
|
const fact = {
|
|
261
237
|
id: options.idFactory ? options.idFactory() : (0, crypto_1.randomUUID)(),
|
|
@@ -264,24 +240,39 @@ async function saveMemoryFact(options) {
|
|
|
264
240
|
about: options.about?.trim() || undefined,
|
|
265
241
|
createdAt: (options.now ?? (() => new Date()))().toISOString(),
|
|
266
242
|
embedding,
|
|
243
|
+
...(options.provenance ? { provenance: options.provenance } : {}),
|
|
267
244
|
};
|
|
268
|
-
|
|
245
|
+
const integrity = (0, diary_integrity_1.detectSuspiciousContent)(text);
|
|
246
|
+
if (integrity.suspicious) {
|
|
247
|
+
(0, runtime_1.emitNervesEvent)({
|
|
248
|
+
level: "warn",
|
|
249
|
+
component: "mind",
|
|
250
|
+
event: "mind.diary_integrity_warning",
|
|
251
|
+
message: "suspicious content detected in diary entry",
|
|
252
|
+
meta: {
|
|
253
|
+
patterns: integrity.patterns,
|
|
254
|
+
textPreview: text.slice(0, 200),
|
|
255
|
+
entryId: fact.id,
|
|
256
|
+
},
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
return appendEntriesWithDedup(stores, [fact], { semanticThreshold: SEMANTIC_DEDUP_THRESHOLD });
|
|
269
260
|
}
|
|
270
261
|
async function backfillEmbeddings(options) {
|
|
271
|
-
const
|
|
272
|
-
const factsPath = path.join(
|
|
262
|
+
const diaryRoot = resolveDiaryRoot(options?.diaryRoot);
|
|
263
|
+
const factsPath = path.join(diaryRoot, "facts.jsonl");
|
|
273
264
|
if (!fs.existsSync(factsPath))
|
|
274
265
|
return { total: 0, backfilled: 0, failed: 0 };
|
|
275
|
-
const facts =
|
|
266
|
+
const facts = readExistingEntries(factsPath);
|
|
276
267
|
const needsEmbedding = facts.filter((f) => !Array.isArray(f.embedding) || f.embedding.length === 0);
|
|
277
268
|
if (needsEmbedding.length === 0)
|
|
278
269
|
return { total: facts.length, backfilled: 0, failed: 0 };
|
|
279
|
-
const provider = options?.embeddingProvider ?? createDefaultEmbeddingProvider();
|
|
270
|
+
const provider = options?.embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
|
|
280
271
|
if (!provider) {
|
|
281
272
|
(0, runtime_1.emitNervesEvent)({
|
|
282
273
|
level: "warn",
|
|
283
274
|
component: "mind",
|
|
284
|
-
event: "mind.
|
|
275
|
+
event: "mind.diary_backfill_skipped",
|
|
285
276
|
message: "embedding provider unavailable for backfill",
|
|
286
277
|
meta: { needsEmbedding: needsEmbedding.length },
|
|
287
278
|
});
|
|
@@ -307,7 +298,7 @@ async function backfillEmbeddings(options) {
|
|
|
307
298
|
(0, runtime_1.emitNervesEvent)({
|
|
308
299
|
level: "warn",
|
|
309
300
|
component: "mind",
|
|
310
|
-
event: "mind.
|
|
301
|
+
event: "mind.diary_backfill_batch_error",
|
|
311
302
|
message: "embedding backfill batch failed",
|
|
312
303
|
meta: {
|
|
313
304
|
batchStart: i,
|
|
@@ -322,7 +313,7 @@ async function backfillEmbeddings(options) {
|
|
|
322
313
|
fs.writeFileSync(factsPath, lines, "utf8");
|
|
323
314
|
(0, runtime_1.emitNervesEvent)({
|
|
324
315
|
component: "mind",
|
|
325
|
-
event: "mind.
|
|
316
|
+
event: "mind.diary_backfill_complete",
|
|
326
317
|
message: "embedding backfill completed",
|
|
327
318
|
meta: { total: facts.length, backfilled, failed },
|
|
328
319
|
});
|
|
@@ -342,7 +333,7 @@ function uniqueFacts(facts) {
|
|
|
342
333
|
}
|
|
343
334
|
return unique;
|
|
344
335
|
}
|
|
345
|
-
async function
|
|
336
|
+
async function searchDiaryEntries(query, facts, embeddingProvider) {
|
|
346
337
|
const trimmed = query.trim();
|
|
347
338
|
if (!trimmed)
|
|
348
339
|
return [];
|
|
@@ -352,7 +343,7 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
|
|
|
352
343
|
if (embeddedFacts.length === 0) {
|
|
353
344
|
return substringFallback();
|
|
354
345
|
}
|
|
355
|
-
const provider = embeddingProvider ?? createDefaultEmbeddingProvider();
|
|
346
|
+
const provider = embeddingProvider ?? (0, embedding_provider_1.createDefaultEmbeddingProvider)();
|
|
356
347
|
if (!provider) {
|
|
357
348
|
return substringFallback();
|
|
358
349
|
}
|
|
@@ -366,7 +357,7 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
|
|
|
366
357
|
.filter((fact) => fact.embedding.length === queryEmbedding.length)
|
|
367
358
|
.map((fact) => ({
|
|
368
359
|
fact,
|
|
369
|
-
score: (0,
|
|
360
|
+
score: (0, note_search_1.cosineSimilarity)(queryEmbedding, fact.embedding),
|
|
370
361
|
}))
|
|
371
362
|
.filter((entry) => entry.score > 0)
|
|
372
363
|
.sort((left, right) => right.score - left.score)
|
|
@@ -378,8 +369,8 @@ async function searchMemoryFacts(query, facts, embeddingProvider) {
|
|
|
378
369
|
(0, runtime_1.emitNervesEvent)({
|
|
379
370
|
level: "warn",
|
|
380
371
|
component: "mind",
|
|
381
|
-
event: "mind.
|
|
382
|
-
message: "embedding provider unavailable for
|
|
372
|
+
event: "mind.diary_embedding_unavailable",
|
|
373
|
+
message: "embedding provider unavailable for diary search",
|
|
383
374
|
meta: {
|
|
384
375
|
reason: error instanceof Error ? error.message : String(error),
|
|
385
376
|
},
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Shared OpenAI embedding provider.
|
|
4
|
+
*
|
|
5
|
+
* Both diary.ts and note-search.ts need to call the OpenAI embeddings
|
|
6
|
+
* API. This module provides the shared implementation so neither duplicates
|
|
7
|
+
* the fetch logic.
|
|
8
|
+
*/
|
|
9
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
10
|
+
exports.OpenAIEmbeddingProvider = void 0;
|
|
11
|
+
exports.createDefaultEmbeddingProvider = createDefaultEmbeddingProvider;
|
|
12
|
+
const config_1 = require("../heart/config");
|
|
13
|
+
const runtime_1 = require("../nerves/runtime");
|
|
14
|
+
const DEFAULT_EMBEDDING_MODEL = "text-embedding-3-small";
|
|
15
|
+
class OpenAIEmbeddingProvider {
|
|
16
|
+
apiKey;
|
|
17
|
+
model;
|
|
18
|
+
constructor(apiKey, model = DEFAULT_EMBEDDING_MODEL) {
|
|
19
|
+
this.apiKey = apiKey;
|
|
20
|
+
this.model = model;
|
|
21
|
+
}
|
|
22
|
+
async embed(texts) {
|
|
23
|
+
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
24
|
+
method: "POST",
|
|
25
|
+
headers: {
|
|
26
|
+
Authorization: `Bearer ${this.apiKey}`,
|
|
27
|
+
"Content-Type": "application/json",
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify({
|
|
30
|
+
model: this.model,
|
|
31
|
+
input: texts,
|
|
32
|
+
}),
|
|
33
|
+
});
|
|
34
|
+
if (!response.ok) {
|
|
35
|
+
throw new Error(`embedding request failed: ${response.status} ${response.statusText}`);
|
|
36
|
+
}
|
|
37
|
+
const payload = (await response.json());
|
|
38
|
+
if (!payload.data || payload.data.length !== texts.length) {
|
|
39
|
+
throw new Error("embedding response missing expected vectors");
|
|
40
|
+
}
|
|
41
|
+
return payload.data.map((entry) => entry.embedding);
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.OpenAIEmbeddingProvider = OpenAIEmbeddingProvider;
|
|
45
|
+
/**
|
|
46
|
+
* Create a default embedding provider from the configured API key.
|
|
47
|
+
* Returns null if no key is configured.
|
|
48
|
+
*/
|
|
49
|
+
function createDefaultEmbeddingProvider() {
|
|
50
|
+
const apiKey = (0, config_1.getOpenAIEmbeddingsApiKey)().trim();
|
|
51
|
+
if (!apiKey)
|
|
52
|
+
return null;
|
|
53
|
+
(0, runtime_1.emitNervesEvent)({
|
|
54
|
+
component: "mind",
|
|
55
|
+
event: "mind.embedding_provider_created",
|
|
56
|
+
message: "default embedding provider created",
|
|
57
|
+
meta: { model: DEFAULT_EMBEDDING_MODEL },
|
|
58
|
+
});
|
|
59
|
+
return new OpenAIEmbeddingProvider(apiKey);
|
|
60
|
+
}
|
|
@@ -0,0 +1,179 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.fileStateCache = exports.FileStateCache = void 0;
|
|
4
|
+
exports.contentHash = contentHash;
|
|
5
|
+
const crypto_1 = require("crypto");
|
|
6
|
+
const fs_1 = require("fs");
|
|
7
|
+
const runtime_1 = require("../nerves/runtime");
|
|
8
|
+
/** Compute sha256 hex hash of content */
|
|
9
|
+
function contentHash(content) {
|
|
10
|
+
return (0, crypto_1.createHash)("sha256").update(content).digest("hex");
|
|
11
|
+
}
|
|
12
|
+
/**
|
|
13
|
+
* Session-scoped LRU cache tracking file reads.
|
|
14
|
+
* Stores content hashes (not full content) to limit stored content.
|
|
15
|
+
* Keyed by absolute file path.
|
|
16
|
+
*
|
|
17
|
+
* Also maintains a separate snapshot list for future rewind support.
|
|
18
|
+
* Snapshots are indexed by content hash and linked to conversation messages.
|
|
19
|
+
*/
|
|
20
|
+
class FileStateCache {
|
|
21
|
+
entries;
|
|
22
|
+
maxSize;
|
|
23
|
+
snapshots = [];
|
|
24
|
+
maxSnapshots = 100;
|
|
25
|
+
constructor(maxSize = 50) {
|
|
26
|
+
this.entries = new Map();
|
|
27
|
+
this.maxSize = maxSize;
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Record a file read. Computes content hash and stores metadata.
|
|
31
|
+
*/
|
|
32
|
+
record(filePath, content, mtime, offset, limit, messageId) {
|
|
33
|
+
// If key already exists, delete it so re-insertion moves it to end (most recent)
|
|
34
|
+
if (this.entries.has(filePath)) {
|
|
35
|
+
this.entries.delete(filePath);
|
|
36
|
+
}
|
|
37
|
+
const hash = contentHash(content);
|
|
38
|
+
const fullRead = offset === undefined && limit === undefined;
|
|
39
|
+
this.entries.set(filePath, {
|
|
40
|
+
hash,
|
|
41
|
+
mtime,
|
|
42
|
+
offset: fullRead ? undefined : offset,
|
|
43
|
+
limit: fullRead ? undefined : limit,
|
|
44
|
+
fullRead,
|
|
45
|
+
recordedAt: Date.now(),
|
|
46
|
+
messageId,
|
|
47
|
+
});
|
|
48
|
+
(0, runtime_1.emitNervesEvent)({
|
|
49
|
+
component: "mind",
|
|
50
|
+
event: "mind.file_state.record",
|
|
51
|
+
message: "recorded file state",
|
|
52
|
+
meta: { path: filePath, hash, fullRead },
|
|
53
|
+
});
|
|
54
|
+
// Evict LRU (first entry in Map iteration order) if over capacity
|
|
55
|
+
if (this.entries.size > this.maxSize) {
|
|
56
|
+
const firstKey = this.entries.keys().next().value;
|
|
57
|
+
this.entries.delete(firstKey);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Get the cached state for a file path. Also promotes it in LRU order.
|
|
62
|
+
*/
|
|
63
|
+
get(filePath) {
|
|
64
|
+
const entry = this.entries.get(filePath);
|
|
65
|
+
if (entry === undefined)
|
|
66
|
+
return undefined;
|
|
67
|
+
// Promote to most-recently-used by re-inserting
|
|
68
|
+
this.entries.delete(filePath);
|
|
69
|
+
this.entries.set(filePath, entry);
|
|
70
|
+
(0, runtime_1.emitNervesEvent)({
|
|
71
|
+
component: "mind",
|
|
72
|
+
event: "mind.file_state.get",
|
|
73
|
+
message: "retrieved file state",
|
|
74
|
+
meta: { path: filePath, hash: entry.hash },
|
|
75
|
+
});
|
|
76
|
+
return entry;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Check if a file has been modified since the last recorded read.
|
|
80
|
+
* Uses mtime as primary signal, content hash as fallback for cloud sync / touch scenarios.
|
|
81
|
+
* Returns { stale: false } if the path is not in cache or the file cannot be stat'd.
|
|
82
|
+
*/
|
|
83
|
+
isStale(filePath) {
|
|
84
|
+
const entry = this.entries.get(filePath);
|
|
85
|
+
if (entry === undefined)
|
|
86
|
+
return { stale: false };
|
|
87
|
+
let currentMtime;
|
|
88
|
+
try {
|
|
89
|
+
currentMtime = (0, fs_1.statSync)(filePath).mtimeMs;
|
|
90
|
+
}
|
|
91
|
+
catch {
|
|
92
|
+
// File doesn't exist or can't be stat'd -- no basis for staleness
|
|
93
|
+
return { stale: false };
|
|
94
|
+
}
|
|
95
|
+
// Fast path: mtime unchanged means not stale
|
|
96
|
+
if (currentMtime === entry.mtime)
|
|
97
|
+
return { stale: false };
|
|
98
|
+
// mtime differs -- check content hash as fallback (handles touch / cloud sync)
|
|
99
|
+
try {
|
|
100
|
+
const currentContent = (0, fs_1.readFileSync)(filePath, "utf-8");
|
|
101
|
+
const currentHash = contentHash(currentContent);
|
|
102
|
+
if (currentHash === entry.hash)
|
|
103
|
+
return { stale: false };
|
|
104
|
+
(0, runtime_1.emitNervesEvent)({
|
|
105
|
+
component: "mind",
|
|
106
|
+
event: "mind.file_state.stale_detected",
|
|
107
|
+
message: "file staleness detected",
|
|
108
|
+
meta: { path: filePath, previousHash: entry.hash, currentHash },
|
|
109
|
+
});
|
|
110
|
+
return { stale: true, reason: `file modified since last read (mtime and content differ)` };
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Can't read file -- treat as not stale (file may have been deleted)
|
|
114
|
+
return { stale: false };
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
/**
|
|
118
|
+
* Create a pre-edit snapshot of the current cache state for a file.
|
|
119
|
+
* Snapshots are stored separately from the LRU cache for future rewind support.
|
|
120
|
+
* Returns undefined if the path is not in cache.
|
|
121
|
+
*/
|
|
122
|
+
snapshot(filePath) {
|
|
123
|
+
const entry = this.entries.get(filePath);
|
|
124
|
+
if (entry === undefined)
|
|
125
|
+
return undefined;
|
|
126
|
+
const snap = {
|
|
127
|
+
filePath,
|
|
128
|
+
hash: entry.hash,
|
|
129
|
+
mtime: entry.mtime,
|
|
130
|
+
messageId: entry.messageId,
|
|
131
|
+
createdAt: Date.now(),
|
|
132
|
+
};
|
|
133
|
+
this.snapshots.push(snap);
|
|
134
|
+
(0, runtime_1.emitNervesEvent)({
|
|
135
|
+
component: "mind",
|
|
136
|
+
event: "mind.file_state.snapshot_created",
|
|
137
|
+
message: "created file state snapshot",
|
|
138
|
+
meta: { path: filePath, hash: snap.hash },
|
|
139
|
+
});
|
|
140
|
+
// Evict oldest snapshots if over capacity
|
|
141
|
+
if (this.snapshots.length > this.maxSnapshots) {
|
|
142
|
+
this.snapshots = this.snapshots.slice(this.snapshots.length - this.maxSnapshots);
|
|
143
|
+
}
|
|
144
|
+
return snap;
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Get all snapshots in creation order.
|
|
148
|
+
*/
|
|
149
|
+
getSnapshots() {
|
|
150
|
+
return this.snapshots;
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Look up a snapshot by content hash. Returns the first match.
|
|
154
|
+
*/
|
|
155
|
+
lookupSnapshotByHash(hash) {
|
|
156
|
+
return this.snapshots.find(s => s.hash === hash);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Clear all snapshots.
|
|
160
|
+
*/
|
|
161
|
+
clearSnapshots() {
|
|
162
|
+
this.snapshots = [];
|
|
163
|
+
}
|
|
164
|
+
/**
|
|
165
|
+
* Clear all cached entries (does not clear snapshots).
|
|
166
|
+
*/
|
|
167
|
+
clear() {
|
|
168
|
+
(0, runtime_1.emitNervesEvent)({
|
|
169
|
+
component: "mind",
|
|
170
|
+
event: "mind.file_state.clear",
|
|
171
|
+
message: "cleared file state cache",
|
|
172
|
+
meta: { entryCount: this.entries.size },
|
|
173
|
+
});
|
|
174
|
+
this.entries.clear();
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
exports.FileStateCache = FileStateCache;
|
|
178
|
+
/** Session-scoped singleton instance used by tool handlers */
|
|
179
|
+
exports.fileStateCache = new FileStateCache();
|
|
@@ -2,10 +2,22 @@
|
|
|
2
2
|
// Channel capabilities -- hardcoded const map keyed by channel identifier.
|
|
3
3
|
// Pure lookup, no I/O, cannot fail. Unknown channel gets minimal defaults.
|
|
4
4
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
5
|
+
exports.channelToFacing = channelToFacing;
|
|
5
6
|
exports.getChannelCapabilities = getChannelCapabilities;
|
|
6
7
|
exports.isRemoteChannel = isRemoteChannel;
|
|
7
8
|
exports.getAlwaysOnSenseNames = getAlwaysOnSenseNames;
|
|
8
9
|
const runtime_1 = require("../../nerves/runtime");
|
|
10
|
+
const AGENT_FACING_CHANNELS = new Set(["inner", "mcp", "a2a"]);
|
|
11
|
+
function channelToFacing(channel) {
|
|
12
|
+
const facing = channel && AGENT_FACING_CHANNELS.has(channel) ? "agent" : "human";
|
|
13
|
+
(0, runtime_1.emitNervesEvent)({
|
|
14
|
+
component: "channels",
|
|
15
|
+
event: "channel.facing_lookup",
|
|
16
|
+
message: "channel facing lookup",
|
|
17
|
+
meta: { channel: channel ?? "undefined", facing },
|
|
18
|
+
});
|
|
19
|
+
return facing;
|
|
20
|
+
}
|
|
9
21
|
const CHANNEL_CAPABILITIES = {
|
|
10
22
|
cli: {
|
|
11
23
|
channel: "cli",
|
|
@@ -34,6 +46,33 @@ const CHANNEL_CAPABILITIES = {
|
|
|
34
46
|
supportsRichCards: false,
|
|
35
47
|
maxMessageLength: Infinity,
|
|
36
48
|
},
|
|
49
|
+
mail: {
|
|
50
|
+
channel: "mail",
|
|
51
|
+
senseType: "open",
|
|
52
|
+
availableIntegrations: [],
|
|
53
|
+
supportsMarkdown: false,
|
|
54
|
+
supportsStreaming: false,
|
|
55
|
+
supportsRichCards: false,
|
|
56
|
+
maxMessageLength: Infinity,
|
|
57
|
+
},
|
|
58
|
+
voice: {
|
|
59
|
+
channel: "voice",
|
|
60
|
+
senseType: "local",
|
|
61
|
+
availableIntegrations: [],
|
|
62
|
+
supportsMarkdown: false,
|
|
63
|
+
supportsStreaming: true,
|
|
64
|
+
supportsRichCards: false,
|
|
65
|
+
maxMessageLength: Infinity,
|
|
66
|
+
},
|
|
67
|
+
a2a: {
|
|
68
|
+
channel: "a2a",
|
|
69
|
+
senseType: "open",
|
|
70
|
+
availableIntegrations: [],
|
|
71
|
+
supportsMarkdown: true,
|
|
72
|
+
supportsStreaming: false,
|
|
73
|
+
supportsRichCards: false,
|
|
74
|
+
maxMessageLength: Infinity,
|
|
75
|
+
},
|
|
37
76
|
inner: {
|
|
38
77
|
channel: "inner",
|
|
39
78
|
senseType: "internal",
|
|
@@ -43,6 +82,15 @@ const CHANNEL_CAPABILITIES = {
|
|
|
43
82
|
supportsRichCards: false,
|
|
44
83
|
maxMessageLength: Infinity,
|
|
45
84
|
},
|
|
85
|
+
mcp: {
|
|
86
|
+
channel: "mcp",
|
|
87
|
+
senseType: "local",
|
|
88
|
+
availableIntegrations: [],
|
|
89
|
+
supportsMarkdown: true,
|
|
90
|
+
supportsStreaming: false,
|
|
91
|
+
supportsRichCards: false,
|
|
92
|
+
maxMessageLength: Infinity,
|
|
93
|
+
},
|
|
46
94
|
};
|
|
47
95
|
const DEFAULT_CAPABILITIES = {
|
|
48
96
|
channel: "cli",
|