@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
|
@@ -10,24 +10,158 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
10
10
|
exports.isTypeOnlyFile = isTypeOnlyFile;
|
|
11
11
|
exports.checkFileCompleteness = checkFileCompleteness;
|
|
12
12
|
/**
|
|
13
|
-
* Determines if a source file is type-only
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
*
|
|
13
|
+
* Determines if a source file is type-only or a pure assembly/re-export file.
|
|
14
|
+
* Exempt files contain no runtime behavior requiring independent observability.
|
|
15
|
+
*
|
|
16
|
+
* Exempt patterns:
|
|
17
|
+
* - Files with only type/interface/enum declarations
|
|
18
|
+
* - `const ... as const` declarations (frozen compile-time values)
|
|
19
|
+
* - Files whose only executable code is const array spreads (assembly/composition)
|
|
20
|
+
* - Files whose only executable code is re-exports
|
|
17
21
|
*/
|
|
18
22
|
function isTypeOnlyFile(source) {
|
|
19
23
|
const lines = source.split("\n");
|
|
20
24
|
for (const line of lines) {
|
|
21
25
|
const trimmed = line.trim();
|
|
26
|
+
/* v8 ignore start -- regex branches: functionally tested in file-completeness.test.ts @preserve */
|
|
22
27
|
// Skip lines that are const+as-const (type-equivalent frozen values)
|
|
23
28
|
if (/\bconst\s/.test(trimmed) && /\bas\s+const\b/.test(trimmed))
|
|
24
29
|
continue;
|
|
30
|
+
// Skip const declarations that are pure data (arrays, objects, maps, sets)
|
|
31
|
+
if (/\bconst\s+\w+[\s:][^=]*=\s*[\[{]/.test(trimmed))
|
|
32
|
+
continue;
|
|
33
|
+
if (/\bconst\s+\w+[\s:][^=]*=\s*\w+\.map\(/.test(trimmed))
|
|
34
|
+
continue;
|
|
35
|
+
if (/^export\s+const\s+\w+[\s:][^=]*=\s*[\[{]/.test(trimmed))
|
|
36
|
+
continue;
|
|
37
|
+
if (/^export\s+const\s+\w+[\s:][^=]*=\s*\w+\.map\(/.test(trimmed))
|
|
38
|
+
continue;
|
|
39
|
+
if (/\bconst\s+\w+[\s:][^=]*=\s*new\s+(Set|Map)\b/.test(trimmed))
|
|
40
|
+
continue;
|
|
25
41
|
// Check for executable code markers
|
|
26
42
|
if (/\b(function|class|const|let|var)\s/.test(trimmed))
|
|
27
43
|
return false;
|
|
44
|
+
/* v8 ignore stop */
|
|
28
45
|
}
|
|
29
46
|
return true;
|
|
30
47
|
}
|
|
48
|
+
// Sub-modules dispatched through a centralized pattern where the router
|
|
49
|
+
// handles all observability events. These files don't need independent
|
|
50
|
+
// emitNervesEvent calls.
|
|
51
|
+
const DISPATCH_EXEMPT_PATTERNS = [
|
|
52
|
+
"repertoire/tools-files",
|
|
53
|
+
"repertoire/tools-shell",
|
|
54
|
+
"repertoire/tools-notes",
|
|
55
|
+
"repertoire/tools-bridge",
|
|
56
|
+
"repertoire/tools-session",
|
|
57
|
+
"repertoire/tools-continuity",
|
|
58
|
+
"repertoire/tools-surface",
|
|
59
|
+
"repertoire/tools-config",
|
|
60
|
+
"repertoire/tools-base",
|
|
61
|
+
// CLI sub-modules: cli-exec.ts is the router with emitNervesEvent calls;
|
|
62
|
+
// cli-parse, cli-render, cli-help, and their small helpers are pure functions/data with no side effects.
|
|
63
|
+
"daemon/cli-parse",
|
|
64
|
+
"daemon/cli-render",
|
|
65
|
+
"daemon/cli-help",
|
|
66
|
+
"daemon/vault-items",
|
|
67
|
+
// Shared utility modules: pure helpers consumed by modules that own observability.
|
|
68
|
+
"arc/json-store",
|
|
69
|
+
"heart/mail-import-discovery",
|
|
70
|
+
"repertoire/api-client",
|
|
71
|
+
"repertoire/github-client",
|
|
72
|
+
"mind/embedding-provider",
|
|
73
|
+
// Commerce utility module: error classes and pure helpers (no independent side effects).
|
|
74
|
+
"repertoire/commerce-errors",
|
|
75
|
+
// Diary integrity: pure detection utility (pattern matching only). The caller
|
|
76
|
+
// (diary.ts saveDiaryEntry) owns observability via mind.diary_integrity_warning.
|
|
77
|
+
"mind/diary-integrity",
|
|
78
|
+
// Provenance trust: pure classification function (no side effects). Callers
|
|
79
|
+
// (note-search.ts, tools-notes.ts) own observability for note search results.
|
|
80
|
+
"mind/provenance-trust",
|
|
81
|
+
// Log redaction: pure utility consumed by the NDJSON sink (no independent side effects).
|
|
82
|
+
"nerves/redact",
|
|
83
|
+
// Bundle templates: pure constants (gitignore template string, PII
|
|
84
|
+
// directory list). No runtime behavior — consumed by tools-bundle.ts
|
|
85
|
+
// which owns the observability for bundle operations.
|
|
86
|
+
"repertoire/bundle-templates",
|
|
87
|
+
// HTTP health probe: pure HTTP utility factory. The HealthMonitor caller
|
|
88
|
+
// owns observability via daemon.health_result events.
|
|
89
|
+
"daemon/http-health-probe",
|
|
90
|
+
// Rollup decision function: pure decision tree mapping per-agent
|
|
91
|
+
// snapshots + bootstrap-degraded entries + safe-mode flag to a
|
|
92
|
+
// RollupStatus. No side effects. The caller (daemon-entry.ts
|
|
93
|
+
// buildDaemonHealthState → DaemonHealthWriter) owns observability via
|
|
94
|
+
// daemon.health_written when the rolled-up state is persisted.
|
|
95
|
+
"daemon/daemon-rollup",
|
|
96
|
+
// Attachment helper modules: generic file-path/extension utilities and the
|
|
97
|
+
// source registry are pure support seams. The orchestrator/adapters that
|
|
98
|
+
// call them own the observability.
|
|
99
|
+
"heart/attachments/originals",
|
|
100
|
+
"heart/attachments/sources/index",
|
|
101
|
+
"heart/attachments/sources/cli-local-file",
|
|
102
|
+
// Browser-safe Mailbox contract helpers: shared types/formatting helpers
|
|
103
|
+
// consumed by server readers and the UI. Mailbox read/render modules own
|
|
104
|
+
// the observability for these projections.
|
|
105
|
+
"heart/mailbox/mailbox-types",
|
|
106
|
+
// Mail search relevance scorer: pure heuristic function (regex + counter
|
|
107
|
+
// arithmetic). The caller (search-cache.ts searchMailSearchCache) owns
|
|
108
|
+
// observability via senses.mail_search_cache_upserted and friends.
|
|
109
|
+
"mailroom/search-relevance",
|
|
110
|
+
// Mail thread reconstruction: pure graph-walk over decrypted message
|
|
111
|
+
// metadata. Consumers (tools-mail.ts mail_thread handler) own observability.
|
|
112
|
+
"mailroom/thread",
|
|
113
|
+
// Trip ledger crypto helpers: pure RSA/AES envelope construction + slug
|
|
114
|
+
// hashing. The caller (trips/store.ts) owns observability via
|
|
115
|
+
// trips.ledger_created and trips.evidence_attached.
|
|
116
|
+
"trips/core",
|
|
117
|
+
// Mailbox HTTP helper modules: route/static/transport/hook seams are
|
|
118
|
+
// dispatched by mailbox-http.ts, whose server lifecycle owns observability.
|
|
119
|
+
"heart/mailbox/mailbox-http-transport",
|
|
120
|
+
"heart/mailbox/mailbox-http-static",
|
|
121
|
+
"heart/mailbox/mailbox-http-hooks",
|
|
122
|
+
"heart/mailbox/mailbox-http-routes",
|
|
123
|
+
"heart/mailbox/mailbox-http-response",
|
|
124
|
+
// Session playback: read-only debugging CLI for sanitize-pipeline replay.
|
|
125
|
+
// No side effects on the runtime; output is human-readable diagnostics only.
|
|
126
|
+
"heart/session-playback-cli-main",
|
|
127
|
+
"heart/session-playback-cli",
|
|
128
|
+
"heart/session-playback",
|
|
129
|
+
// Nerves review: read-only NDJSON tail/filter CLI for debugging.
|
|
130
|
+
// Diagnostics-only utility; the running daemon owns observability.
|
|
131
|
+
"nerves/review/cli-main",
|
|
132
|
+
"nerves/review/cli",
|
|
133
|
+
"nerves/review/core",
|
|
134
|
+
// Mail body cache: in-process LRU helper. Cache hit/miss observability
|
|
135
|
+
// lives at the caller (tools-mail.ts mail_body handler) which fires
|
|
136
|
+
// repertoire.mail_body_cache_hit on cache reuse.
|
|
137
|
+
"mailroom/body-cache",
|
|
138
|
+
// Session stats: read-only session.json analyzer CLI for debugging.
|
|
139
|
+
// Diagnostics-only utility; output is human-readable summary.
|
|
140
|
+
"heart/session-stats-cli-main",
|
|
141
|
+
"heart/session-stats",
|
|
142
|
+
// Layer 2 sync classifier: pure pattern-matcher mapping (error, context)
|
|
143
|
+
// to a SyncClassification. The orchestrator (boot-sync-probe.ts) owns
|
|
144
|
+
// observability via daemon.boot_sync_probe_start/end events; the
|
|
145
|
+
// post-turn push path (sync.ts) emits its own classification events.
|
|
146
|
+
"heart/sync-classification",
|
|
147
|
+
// Layer 2 timeout wrapper: pure soft/hard timeout abstraction over
|
|
148
|
+
// AbortController + setTimeout. Callers (boot-sync-probe.ts and any
|
|
149
|
+
// future consumer) own observability; the wrapper itself is mechanical.
|
|
150
|
+
"heart/timeouts",
|
|
151
|
+
// Shared frontmatter parser: pure YAML-ish parser used by habit-parser,
|
|
152
|
+
// habit-migration, await-parser, and any other small markdown reader.
|
|
153
|
+
// No side effects of its own; callers emit nerves events around their
|
|
154
|
+
// parse calls (e.g. daemon.habit_parse, daemon.await_parse).
|
|
155
|
+
"util/frontmatter",
|
|
156
|
+
// Legacy-tasks-to-desk migration classifier: pure-data per-file bucketing function.
|
|
157
|
+
// The caller (migrate-to-desk.ts) owns observability via
|
|
158
|
+
// daemon.migrate_to_desk_* events around the runMigrateToDesk() entry
|
|
159
|
+
// points.
|
|
160
|
+
"repertoire/desk/classifier",
|
|
161
|
+
];
|
|
162
|
+
function isDispatchExempt(filePath) {
|
|
163
|
+
return DISPATCH_EXEMPT_PATTERNS.some((pattern) => filePath.includes(pattern));
|
|
164
|
+
}
|
|
31
165
|
/**
|
|
32
166
|
* Check that all production files have at least one emitNervesEvent call.
|
|
33
167
|
*
|
|
@@ -41,7 +175,7 @@ function checkFileCompleteness(filesWithKeys, fileContents) {
|
|
|
41
175
|
const hasKeys = filesWithKeys.has(filePath) && filesWithKeys.get(filePath).length > 0;
|
|
42
176
|
if (hasKeys)
|
|
43
177
|
continue;
|
|
44
|
-
if (isTypeOnlyFile(source)) {
|
|
178
|
+
if (isTypeOnlyFile(source) || isDispatchExempt(filePath)) {
|
|
45
179
|
exempt.push(filePath);
|
|
46
180
|
}
|
|
47
181
|
else {
|
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createBufferedSink = createBufferedSink;
|
|
4
|
+
const runtime_1 = require("./runtime");
|
|
5
|
+
const DEFAULT_MAX_SIZE = 1000;
|
|
6
|
+
const DEFAULT_TTL_MS = 5 * 60 * 1000; // 5 minutes
|
|
7
|
+
function createBufferedSink(inner, options = {}) {
|
|
8
|
+
const maxSize = options.maxSize ?? DEFAULT_MAX_SIZE;
|
|
9
|
+
const ttlMs = options.ttlMs ?? DEFAULT_TTL_MS;
|
|
10
|
+
const nowMs = options.nowMs ?? (() => Date.now());
|
|
11
|
+
const buffer = [];
|
|
12
|
+
let dropped = 0;
|
|
13
|
+
let sinkHealthy = true;
|
|
14
|
+
let unhealthySince = null;
|
|
15
|
+
function tryInner(event) {
|
|
16
|
+
try {
|
|
17
|
+
inner(event);
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return false;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function markUnhealthy() {
|
|
25
|
+
sinkHealthy = false;
|
|
26
|
+
unhealthySince = unhealthySince ?? nowMs();
|
|
27
|
+
}
|
|
28
|
+
function markHealthy() {
|
|
29
|
+
sinkHealthy = true;
|
|
30
|
+
unhealthySince = null;
|
|
31
|
+
}
|
|
32
|
+
function discardBuffer() {
|
|
33
|
+
const count = buffer.length;
|
|
34
|
+
dropped += count;
|
|
35
|
+
buffer.length = 0;
|
|
36
|
+
(0, runtime_1.emitNervesEvent)({
|
|
37
|
+
component: "nerves",
|
|
38
|
+
event: "nerves.buffer_ttl_discard",
|
|
39
|
+
message: `discarded ${count} buffered events after TTL`,
|
|
40
|
+
meta: { discarded: count, ttlMs },
|
|
41
|
+
});
|
|
42
|
+
}
|
|
43
|
+
function checkTtl() {
|
|
44
|
+
if (unhealthySince !== null && nowMs() - unhealthySince > ttlMs) {
|
|
45
|
+
discardBuffer();
|
|
46
|
+
// Reset unhealthySince to now so TTL starts fresh for newly buffered events
|
|
47
|
+
unhealthySince = nowMs();
|
|
48
|
+
return true;
|
|
49
|
+
}
|
|
50
|
+
return false;
|
|
51
|
+
}
|
|
52
|
+
function addToBuffer(event) {
|
|
53
|
+
if (buffer.length >= maxSize) {
|
|
54
|
+
buffer.shift();
|
|
55
|
+
dropped++;
|
|
56
|
+
}
|
|
57
|
+
buffer.push(event);
|
|
58
|
+
}
|
|
59
|
+
function flushBuffer() {
|
|
60
|
+
while (buffer.length > 0) {
|
|
61
|
+
const event = buffer[0];
|
|
62
|
+
if (tryInner(event)) {
|
|
63
|
+
buffer.shift();
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
markUnhealthy();
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
function sink(event) {
|
|
72
|
+
if (!sinkHealthy) {
|
|
73
|
+
checkTtl();
|
|
74
|
+
// Try sending the new event to see if inner has recovered
|
|
75
|
+
if (tryInner(event)) {
|
|
76
|
+
markHealthy();
|
|
77
|
+
flushBuffer();
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
addToBuffer(event);
|
|
81
|
+
}
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (tryInner(event)) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
// Inner failed
|
|
88
|
+
markUnhealthy();
|
|
89
|
+
addToBuffer(event);
|
|
90
|
+
}
|
|
91
|
+
function flush() {
|
|
92
|
+
if (buffer.length === 0)
|
|
93
|
+
return;
|
|
94
|
+
// Test if inner is recovered by trying the first buffered event
|
|
95
|
+
const first = buffer[0];
|
|
96
|
+
if (tryInner(first)) {
|
|
97
|
+
buffer.shift();
|
|
98
|
+
markHealthy();
|
|
99
|
+
flushBuffer();
|
|
100
|
+
}
|
|
101
|
+
// If still broken, leave buffer intact
|
|
102
|
+
}
|
|
103
|
+
function state() {
|
|
104
|
+
return {
|
|
105
|
+
buffered: buffer.length,
|
|
106
|
+
dropped,
|
|
107
|
+
sinkHealthy,
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
return { sink, flush, state };
|
|
111
|
+
}
|
package/dist/nerves/index.js
CHANGED
|
@@ -1,17 +1,60 @@
|
|
|
1
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
|
+
})();
|
|
2
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DEFAULT_MAX_GENERATIONS = exports.DEFAULT_MAX_LOG_SIZE_BYTES = void 0;
|
|
3
37
|
exports.createTraceId = createTraceId;
|
|
4
38
|
exports.ensureTraceId = ensureTraceId;
|
|
5
39
|
exports.createFanoutSink = createFanoutSink;
|
|
6
40
|
exports.formatTerminalEntry = formatTerminalEntry;
|
|
41
|
+
exports.registerSpinnerHooks = registerSpinnerHooks;
|
|
7
42
|
exports.createTerminalSink = createTerminalSink;
|
|
8
43
|
exports.createStderrSink = createStderrSink;
|
|
44
|
+
exports.rotateIfNeeded = rotateIfNeeded;
|
|
9
45
|
exports.createNdjsonFileSink = createNdjsonFileSink;
|
|
10
46
|
exports.registerGlobalLogSink = registerGlobalLogSink;
|
|
11
47
|
exports.createLogger = createLogger;
|
|
12
48
|
const fs_1 = require("fs");
|
|
13
49
|
const path_1 = require("path");
|
|
14
50
|
const crypto_1 = require("crypto");
|
|
51
|
+
const zlib = __importStar(require("zlib"));
|
|
52
|
+
// NOTE: runtime.ts imports `createLogger` and `ensureTraceId` from this file.
|
|
53
|
+
// The cycle is safe in CommonJS because runtime.ts only uses those values
|
|
54
|
+
// lazily inside `getRuntimeLogger()`, and we only call `emitNervesEvent` from
|
|
55
|
+
// inside `rotateIfNeeded` — never at module top level.
|
|
56
|
+
const runtime_1 = require("./runtime");
|
|
57
|
+
const redact_1 = require("./redact");
|
|
15
58
|
const LEVEL_PRIORITY = {
|
|
16
59
|
debug: 10,
|
|
17
60
|
info: 20,
|
|
@@ -73,36 +116,213 @@ function formatTerminalEntry(entry) {
|
|
|
73
116
|
const level = entry.level.toUpperCase();
|
|
74
117
|
return `${formatTerminalTime(entry.ts)} ${level} [${entry.component}] ${entry.message}${formatTerminalMeta(entry.meta)}`;
|
|
75
118
|
}
|
|
76
|
-
|
|
119
|
+
// Spinner coordination: the CLI sense registers these so log output
|
|
120
|
+
// doesn't interleave with the active spinner animation.
|
|
121
|
+
let _pauseSpinner = null;
|
|
122
|
+
let _resumeSpinner = null;
|
|
123
|
+
function registerSpinnerHooks(pause, resume) {
|
|
124
|
+
_pauseSpinner = pause;
|
|
125
|
+
_resumeSpinner = resume;
|
|
126
|
+
}
|
|
127
|
+
function createTerminalSink(write = (chunk) => { try {
|
|
128
|
+
process.stderr.write(chunk);
|
|
129
|
+
}
|
|
130
|
+
catch { /* EPIPE: daemon detached, no terminal */ } }, colorize = true) {
|
|
77
131
|
return (entry) => {
|
|
132
|
+
_pauseSpinner?.();
|
|
78
133
|
const line = formatTerminalEntry(entry);
|
|
79
134
|
if (!colorize) {
|
|
80
135
|
write(`${line}\n`);
|
|
136
|
+
_resumeSpinner?.();
|
|
81
137
|
return;
|
|
82
138
|
}
|
|
83
139
|
const prefix = LEVEL_COLORS[entry.level];
|
|
84
140
|
write(`${prefix}${line}\x1b[0m\n`);
|
|
141
|
+
_resumeSpinner?.();
|
|
85
142
|
};
|
|
86
143
|
}
|
|
87
|
-
function createStderrSink(write
|
|
144
|
+
function createStderrSink(write) {
|
|
88
145
|
return createTerminalSink(write);
|
|
89
146
|
}
|
|
90
|
-
|
|
147
|
+
exports.DEFAULT_MAX_LOG_SIZE_BYTES = 25 * 1024 * 1024; // 25 MB per active stream
|
|
148
|
+
exports.DEFAULT_MAX_GENERATIONS = 5; // keep 5 gzipped historical generations
|
|
149
|
+
const DEFAULT_ROTATION_CHECK_INTERVAL_BYTES = 1024 * 1024; // ~1MB between stat checks
|
|
150
|
+
/** Internal: compute the gzipped generation path for a given ndjson file. */
|
|
151
|
+
function generationGzPath(base, ext, n) {
|
|
152
|
+
return ext === ".ndjson" ? `${base}.${n}.ndjson.gz` : `${base}.${n}.gz`;
|
|
153
|
+
}
|
|
154
|
+
/** Internal: compute the legacy uncompressed generation path for a given file. */
|
|
155
|
+
function generationPlainPath(base, ext, n) {
|
|
156
|
+
return ext === ".ndjson" ? `${base}.${n}.ndjson` : `${base}.${n}`;
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Rotate a log file in place.
|
|
160
|
+
*
|
|
161
|
+
* Scheme (25 MB × 5 gzipped generations by default):
|
|
162
|
+
* active : foo.ndjson
|
|
163
|
+
* newest gen : foo.1.ndjson.gz
|
|
164
|
+
* oldest gen : foo.5.ndjson.gz (dropped on next rotation)
|
|
165
|
+
*
|
|
166
|
+
* Legacy tolerance: uncompressed `foo.1.ndjson` / `foo.2.ndjson` files from the
|
|
167
|
+
* old scheme are treated as the corresponding generation and gzipped on first
|
|
168
|
+
* rotation.
|
|
169
|
+
*
|
|
170
|
+
* Concurrent-writer safety: the active file is renamed (inode stays alive for
|
|
171
|
+
* any open writer fd) then gzipped at the renamed path. An active writer
|
|
172
|
+
* continues writing to its original fd; on the next write cycle it sees the
|
|
173
|
+
* old path is missing and creates a fresh file.
|
|
174
|
+
*
|
|
175
|
+
* Backwards-compatible signature: passing a `number` as the second argument
|
|
176
|
+
* (the old API) is still accepted and interpreted as `maxSizeBytes`.
|
|
177
|
+
*/
|
|
178
|
+
function rotateIfNeeded(filePath, optionsOrMaxSize) {
|
|
179
|
+
const options = typeof optionsOrMaxSize === "number"
|
|
180
|
+
? { maxSizeBytes: optionsOrMaxSize }
|
|
181
|
+
: optionsOrMaxSize ?? {};
|
|
182
|
+
const maxSizeBytes = options.maxSizeBytes ?? exports.DEFAULT_MAX_LOG_SIZE_BYTES;
|
|
183
|
+
const maxGenerations = options.maxGenerations ?? exports.DEFAULT_MAX_GENERATIONS;
|
|
184
|
+
const compress = options.compress ?? true;
|
|
185
|
+
let size;
|
|
186
|
+
try {
|
|
187
|
+
size = (0, fs_1.statSync)(filePath).size;
|
|
188
|
+
}
|
|
189
|
+
catch {
|
|
190
|
+
return false;
|
|
191
|
+
}
|
|
192
|
+
if (size < maxSizeBytes)
|
|
193
|
+
return false;
|
|
194
|
+
const ext = filePath.endsWith(".ndjson") ? ".ndjson" : "";
|
|
195
|
+
const base = ext ? filePath.slice(0, -ext.length) : filePath;
|
|
196
|
+
const traceId = (0, crypto_1.randomUUID)();
|
|
197
|
+
(0, runtime_1.emitNervesEvent)({
|
|
198
|
+
component: "nerves",
|
|
199
|
+
event: "nerves.rotation_start",
|
|
200
|
+
trace_id: traceId,
|
|
201
|
+
message: "rotating log file",
|
|
202
|
+
meta: { path: filePath, currentSize: size, threshold: maxSizeBytes, generation: 1 },
|
|
203
|
+
});
|
|
204
|
+
let completed = false;
|
|
205
|
+
try {
|
|
206
|
+
// Step 1: drop / shift existing generations starting from the oldest.
|
|
207
|
+
// For each slot N (maxGenerations..2), find whatever occupies slot (N-1)
|
|
208
|
+
// (as .gz or legacy uncompressed) and move it to slot N. Slot N occupants
|
|
209
|
+
// get overwritten (oldest is dropped). Non-existent slots are skipped.
|
|
210
|
+
for (let n = maxGenerations; n >= 2; n--) {
|
|
211
|
+
const destGz = generationGzPath(base, ext, n);
|
|
212
|
+
const srcGz = generationGzPath(base, ext, n - 1);
|
|
213
|
+
const srcPlain = generationPlainPath(base, ext, n - 1);
|
|
214
|
+
// Drop whatever currently occupies the destination slot (oldest generation).
|
|
215
|
+
if ((0, fs_1.existsSync)(destGz)) {
|
|
216
|
+
(0, fs_1.unlinkSync)(destGz);
|
|
217
|
+
}
|
|
218
|
+
const destPlain = generationPlainPath(base, ext, n);
|
|
219
|
+
if ((0, fs_1.existsSync)(destPlain)) {
|
|
220
|
+
(0, fs_1.unlinkSync)(destPlain);
|
|
221
|
+
}
|
|
222
|
+
// Prefer moving .gz → .gz (cheap rename).
|
|
223
|
+
if ((0, fs_1.existsSync)(srcGz)) {
|
|
224
|
+
(0, fs_1.renameSync)(srcGz, destGz);
|
|
225
|
+
continue;
|
|
226
|
+
}
|
|
227
|
+
// Legacy migration: if a plain .ndjson generation file exists from the
|
|
228
|
+
// old scheme, read it, gzip it into the destination slot, and delete
|
|
229
|
+
// the plain source.
|
|
230
|
+
if ((0, fs_1.existsSync)(srcPlain)) {
|
|
231
|
+
if (compress) {
|
|
232
|
+
const buf = (0, fs_1.readFileSync)(srcPlain);
|
|
233
|
+
const compressed = zlib.gzipSync(buf);
|
|
234
|
+
(0, fs_1.writeFileSync)(destGz, compressed);
|
|
235
|
+
(0, fs_1.unlinkSync)(srcPlain);
|
|
236
|
+
}
|
|
237
|
+
else {
|
|
238
|
+
// compress=false: just rename
|
|
239
|
+
(0, fs_1.renameSync)(srcPlain, destPlain);
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Step 2: rename the active file to the generation-1 plain path. The
|
|
244
|
+
// active writer keeps its open fd; the file path now points elsewhere.
|
|
245
|
+
const plain1 = generationPlainPath(base, ext, 1);
|
|
246
|
+
// If a stale .1 plain path exists (e.g. a previous compress=false run),
|
|
247
|
+
// remove it so the rename can claim the slot cleanly.
|
|
248
|
+
if ((0, fs_1.existsSync)(plain1)) {
|
|
249
|
+
(0, fs_1.unlinkSync)(plain1);
|
|
250
|
+
}
|
|
251
|
+
(0, fs_1.renameSync)(filePath, plain1);
|
|
252
|
+
// Step 3: gzip (or keep plain) the renamed file into the .1 generation.
|
|
253
|
+
if (compress) {
|
|
254
|
+
const gz1 = generationGzPath(base, ext, 1);
|
|
255
|
+
// Remove any lingering .1.ndjson.gz to avoid "file exists" on write.
|
|
256
|
+
if ((0, fs_1.existsSync)(gz1)) {
|
|
257
|
+
(0, fs_1.unlinkSync)(gz1);
|
|
258
|
+
}
|
|
259
|
+
const buf = (0, fs_1.readFileSync)(plain1);
|
|
260
|
+
const compressed = zlib.gzipSync(buf);
|
|
261
|
+
(0, fs_1.writeFileSync)(gz1, compressed);
|
|
262
|
+
(0, fs_1.unlinkSync)(plain1);
|
|
263
|
+
}
|
|
264
|
+
completed = true;
|
|
265
|
+
(0, runtime_1.emitNervesEvent)({
|
|
266
|
+
component: "nerves",
|
|
267
|
+
event: "nerves.rotation_end",
|
|
268
|
+
trace_id: traceId,
|
|
269
|
+
message: "log rotation complete",
|
|
270
|
+
meta: { path: filePath, compressedPath: compress ? generationGzPath(base, ext, 1) : plain1, bytesFreed: size },
|
|
271
|
+
});
|
|
272
|
+
return true;
|
|
273
|
+
}
|
|
274
|
+
catch (err) {
|
|
275
|
+
/* v8 ignore next -- defensive: completed=true only reached after the try block's return @preserve */
|
|
276
|
+
if (!completed) {
|
|
277
|
+
/* v8 ignore next -- defensive: fs ops throw real Errors @preserve */
|
|
278
|
+
const reason = err instanceof Error ? err.message : String(err);
|
|
279
|
+
(0, runtime_1.emitNervesEvent)({
|
|
280
|
+
component: "nerves",
|
|
281
|
+
event: "nerves.rotation_error",
|
|
282
|
+
trace_id: traceId,
|
|
283
|
+
level: "error",
|
|
284
|
+
message: "log rotation failed",
|
|
285
|
+
meta: { path: filePath, error: reason },
|
|
286
|
+
});
|
|
287
|
+
}
|
|
288
|
+
throw err;
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
function createNdjsonFileSink(filePath, optionsOrMaxSize) {
|
|
91
292
|
(0, fs_1.mkdirSync)((0, path_1.dirname)(filePath), { recursive: true });
|
|
293
|
+
const options = typeof optionsOrMaxSize === "number"
|
|
294
|
+
? { maxSizeBytes: optionsOrMaxSize }
|
|
295
|
+
: optionsOrMaxSize ?? {};
|
|
296
|
+
const rotationCheckInterval = options.rotationCheckIntervalBytes ?? DEFAULT_ROTATION_CHECK_INTERVAL_BYTES;
|
|
297
|
+
const verbose = process.env.OURO_LOG_VERBOSE === "1";
|
|
92
298
|
const queue = [];
|
|
93
299
|
let flushing = false;
|
|
300
|
+
let bytesSinceCheck = 0;
|
|
94
301
|
function flush() {
|
|
95
302
|
if (flushing || queue.length === 0)
|
|
96
303
|
return;
|
|
97
304
|
flushing = true;
|
|
98
305
|
const line = queue.shift();
|
|
306
|
+
if (bytesSinceCheck >= rotationCheckInterval) {
|
|
307
|
+
bytesSinceCheck = 0;
|
|
308
|
+
try {
|
|
309
|
+
rotateIfNeeded(filePath, options);
|
|
310
|
+
}
|
|
311
|
+
catch {
|
|
312
|
+
// Rotation errors are surfaced via nerves events; never block writes.
|
|
313
|
+
}
|
|
314
|
+
}
|
|
99
315
|
(0, fs_1.appendFile)(filePath, line, "utf8", () => {
|
|
100
316
|
flushing = false;
|
|
101
317
|
flush();
|
|
102
318
|
});
|
|
103
319
|
}
|
|
104
320
|
return (entry) => {
|
|
105
|
-
|
|
321
|
+
const line = verbose
|
|
322
|
+
? `${JSON.stringify(entry)}\n`
|
|
323
|
+
: `${(0, redact_1.redactString)(JSON.stringify((0, redact_1.redactLogEntry)(entry)))}\n`;
|
|
324
|
+
bytesSinceCheck += line.length;
|
|
325
|
+
queue.push(line);
|
|
106
326
|
flush();
|
|
107
327
|
};
|
|
108
328
|
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Nerves observation layer — shared typed readers for runtime state.
|
|
4
|
+
*
|
|
5
|
+
* This module re-exports domain types that multiple consumers need
|
|
6
|
+
* (Mailbox, CLI, agent tools) so they don't maintain parallel type universes.
|
|
7
|
+
*
|
|
8
|
+
* The Mailbox UI consumes these through the HTTP API, but the same
|
|
9
|
+
* observation functions back CLI commands and future native clients.
|
|
10
|
+
*/
|
|
11
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
12
|
+
/* v8 ignore start — module-level observability event */
|
|
13
|
+
const runtime_1 = require("./runtime");
|
|
14
|
+
(0, runtime_1.emitNervesEvent)({
|
|
15
|
+
component: "nerves",
|
|
16
|
+
event: "nerves.observation_loaded",
|
|
17
|
+
message: "observation layer loaded",
|
|
18
|
+
meta: {},
|
|
19
|
+
});
|
|
20
|
+
/* v8 ignore stop */
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SENSITIVE_PATTERNS = exports.SENSITIVE_KEYS = void 0;
|
|
4
|
+
exports.redactMeta = redactMeta;
|
|
5
|
+
exports.redactString = redactString;
|
|
6
|
+
exports.redactLogEntry = redactLogEntry;
|
|
7
|
+
/**
|
|
8
|
+
* Lowercase key names that trigger structured redaction.
|
|
9
|
+
* Matched case-insensitively against meta object keys.
|
|
10
|
+
*/
|
|
11
|
+
exports.SENSITIVE_KEYS = new Set([
|
|
12
|
+
"password",
|
|
13
|
+
"secret",
|
|
14
|
+
"token",
|
|
15
|
+
"accesstoken",
|
|
16
|
+
"refreshtoken",
|
|
17
|
+
"clientsecret",
|
|
18
|
+
"apikey",
|
|
19
|
+
"oauthaccesstoken",
|
|
20
|
+
"authorization",
|
|
21
|
+
"cookie",
|
|
22
|
+
"set-cookie",
|
|
23
|
+
]);
|
|
24
|
+
/**
|
|
25
|
+
* Regex patterns for string-level fallback redaction.
|
|
26
|
+
* Applied in order; each match is replaced with `[REDACTED:name]`.
|
|
27
|
+
*/
|
|
28
|
+
exports.SENSITIVE_PATTERNS = [
|
|
29
|
+
{ name: "anthropic_key", pattern: /sk-ant-[A-Za-z0-9_-]+/g },
|
|
30
|
+
{ name: "openai_key", pattern: /sk-proj-[A-Za-z0-9_-]+/g },
|
|
31
|
+
{ name: "bearer_token", pattern: /Bearer [A-Za-z0-9\-_.]+/g },
|
|
32
|
+
{ name: "api_key_assignment", pattern: /api[_-]?key[=:]\s*["']?[A-Za-z0-9\-_.]+/g },
|
|
33
|
+
{ name: "url_token", pattern: /[?&](?:token|key|api_key|access_token)=[A-Za-z0-9\-_.%]+/g },
|
|
34
|
+
];
|
|
35
|
+
/**
|
|
36
|
+
* Deep-clone meta and replace values at sensitive keys with `[REDACTED:key_name]`.
|
|
37
|
+
* Recurses into nested objects. Case-insensitive key matching.
|
|
38
|
+
*/
|
|
39
|
+
function redactMeta(meta) {
|
|
40
|
+
const result = {};
|
|
41
|
+
for (const key of Object.keys(meta)) {
|
|
42
|
+
const value = meta[key];
|
|
43
|
+
if (exports.SENSITIVE_KEYS.has(key.toLowerCase())) {
|
|
44
|
+
result[key] = `[REDACTED:${key}]`;
|
|
45
|
+
}
|
|
46
|
+
else if (value !== null && typeof value === "object" && !Array.isArray(value)) {
|
|
47
|
+
result[key] = redactMeta(value);
|
|
48
|
+
}
|
|
49
|
+
else {
|
|
50
|
+
result[key] = value;
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Apply all regex patterns to a string, replacing matches with `[REDACTED:pattern_name]`.
|
|
57
|
+
*/
|
|
58
|
+
function redactString(text) {
|
|
59
|
+
let result = text;
|
|
60
|
+
for (const { name, pattern } of exports.SENSITIVE_PATTERNS) {
|
|
61
|
+
// Reset lastIndex for global regexes reused across calls
|
|
62
|
+
pattern.lastIndex = 0;
|
|
63
|
+
result = result.replace(pattern, `[REDACTED:${name}]`);
|
|
64
|
+
}
|
|
65
|
+
return result;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Full redaction pipeline: redact meta (structured keys), then redact message (regex patterns).
|
|
69
|
+
* Returns a new LogEvent -- never mutates the input.
|
|
70
|
+
*/
|
|
71
|
+
function redactLogEntry(entry) {
|
|
72
|
+
const redactedMeta = redactMeta(entry.meta);
|
|
73
|
+
const redactedMessage = redactString(entry.message);
|
|
74
|
+
return {
|
|
75
|
+
...entry,
|
|
76
|
+
meta: redactedMeta,
|
|
77
|
+
message: redactedMessage,
|
|
78
|
+
};
|
|
79
|
+
}
|