@ouro.bot/cli 0.1.0-alpha.6 → 0.1.0-alpha.600
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +229 -183
- 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/SerpentGuide.ouro/agent.json +83 -0
- package/SerpentGuide.ouro/psyche/SOUL.md +25 -0
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/assets/ouroboros.png +0 -0
- package/changelog.json +4182 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +254 -0
- package/dist/arc/packets.js +193 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +65 -0
- package/dist/heart/active-work.js +989 -0
- package/dist/heart/agent-entry.js +69 -3
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/adapter.js +2 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +16 -0
- package/dist/heart/attachments/store.js +103 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +479 -0
- package/dist/heart/awaiting/await-alert.js +146 -0
- package/dist/heart/awaiting/await-expiry.js +108 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +141 -0
- package/dist/heart/awaiting/await-runtime-state.js +97 -0
- package/dist/heart/awaiting/await-scheduler.js +377 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bridges/manager.js +358 -0
- package/dist/heart/bridges/state-machine.js +135 -0
- package/dist/heart/bridges/store.js +123 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +142 -0
- package/dist/heart/config-registry.js +322 -0
- package/dist/heart/config.js +164 -135
- package/dist/heart/core.js +1069 -260
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +419 -0
- package/dist/heart/daemon/agent-discovery.js +180 -0
- package/dist/heart/daemon/agent-service.js +522 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +776 -0
- package/dist/heart/daemon/cli-exec.js +7571 -0
- package/dist/heart/daemon/cli-help.js +498 -0
- package/dist/heart/daemon/cli-parse.js +1599 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +763 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/daemon-cli.js +30 -758
- package/dist/heart/daemon/daemon-entry.js +540 -8
- 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 +287 -0
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +972 -20
- 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 +206 -0
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +188 -0
- package/dist/heart/daemon/log-tailer.js +82 -12
- 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 +17 -8
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +14 -12
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/process-manager.js +381 -26
- 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 +39 -0
- package/dist/heart/daemon/runtime-logging.js +67 -16
- package/dist/heart/daemon/runtime-metadata.js +191 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +731 -0
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +349 -0
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +330 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +524 -0
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-animation.js +10 -3
- package/dist/heart/{daemon → hatch}/hatch-flow.js +34 -136
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- package/dist/heart/hatch/specialist-orchestrator.js +129 -0
- package/dist/heart/hatch/specialist-prompt.js +102 -0
- package/dist/heart/hatch/specialist-tools.js +306 -0
- package/dist/heart/identity.js +281 -67
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +2 -20
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +31 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +195 -0
- package/dist/heart/mailbox/readers/agent-machine.js +382 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
- package/dist/heart/mailbox/readers/mail.js +367 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
- package/dist/heart/mailbox/readers/sessions.js +232 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +656 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +59 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +267 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +202 -50
- package/dist/heart/providers/azure.js +104 -13
- 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 +29 -7
- package/dist/heart/providers/openai-codex.js +63 -39
- 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 +70 -0
- package/dist/heart/session-activity.js +190 -0
- package/dist/heart/session-events.js +1149 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +182 -0
- package/dist/heart/session-transcript.js +243 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +129 -34
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -0
- package/dist/heart/target-resolution.js +127 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/timeouts.js +101 -0
- package/dist/heart/tool-activity-callbacks.js +59 -0
- package/dist/heart/tool-description.js +143 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +421 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/heart/versioning/ouro-bot-global-installer.js +129 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +426 -0
- package/dist/heart/{daemon → versioning}/ouro-uti.js +11 -2
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/versioning/staged-restart.js +146 -0
- package/dist/heart/versioning/update-checker.js +116 -0
- package/dist/heart/versioning/update-hooks.js +142 -0
- package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
- package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
- package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/mailbox-ui/index.html +15 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +700 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/core.js +788 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +457 -0
- package/dist/mailroom/mbox-import.js +393 -0
- package/dist/mailroom/migration.js +164 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +233 -0
- package/dist/mailroom/search-cache.js +268 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/thread.js +109 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +77 -1
- package/dist/mind/context.js +174 -94
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +84 -96
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/first-impressions.js +16 -2
- package/dist/mind/friends/channel.js +74 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +58 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- package/dist/mind/friends/types.js +10 -2
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/note-search.js +268 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +76 -9
- package/dist/mind/phrases.js +1 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1267 -130
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/token-estimate.js +8 -12
- package/dist/nerves/cli-logging.js +22 -3
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +129 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- 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 +17 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +997 -0
- package/dist/repertoire/bundle-templates.js +72 -0
- package/dist/repertoire/bw-installer.js +180 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +330 -0
- package/dist/repertoire/coding/feedback.js +301 -0
- package/dist/repertoire/coding/index.js +4 -1
- package/dist/repertoire/coding/manager.js +220 -13
- package/dist/repertoire/coding/spawner.js +58 -12
- package/dist/repertoire/coding/tools.js +209 -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/data/ado-endpoints.json +188 -0
- package/dist/repertoire/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +396 -0
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +362 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +43 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +39 -13
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +16 -79
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-awaiting.js +360 -0
- package/dist/repertoire/tools-base.js +56 -707
- package/dist/repertoire/tools-bluebubbles.js +94 -0
- package/dist/repertoire/tools-bridge.js +142 -0
- package/dist/repertoire/tools-bundle.js +984 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +381 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1916 -0
- package/dist/repertoire/tools-notes.js +421 -0
- package/dist/repertoire/tools-obligations.js +142 -0
- package/dist/repertoire/tools-runtime.js +61 -0
- package/dist/repertoire/tools-session.js +809 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +345 -0
- package/dist/repertoire/tools-teams.js +64 -61
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +604 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice.js +144 -0
- package/dist/repertoire/tools.js +154 -98
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +594 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +116 -0
- package/dist/senses/await-turn-message.js +58 -0
- package/dist/senses/bluebubbles/active-turns.js +216 -0
- package/dist/senses/bluebubbles/attachment-cache.js +53 -0
- package/dist/senses/bluebubbles/attachment-download.js +137 -0
- package/dist/senses/bluebubbles/client.js +685 -0
- package/dist/senses/bluebubbles/entry.js +77 -0
- package/dist/senses/bluebubbles/inbound-log.js +126 -0
- package/dist/senses/bluebubbles/index.js +2548 -0
- package/dist/senses/bluebubbles/media.js +389 -0
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +45 -16
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/replay.js +137 -0
- package/dist/senses/bluebubbles/runtime-state.js +137 -0
- package/dist/senses/bluebubbles/session-cleanup.js +72 -0
- 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 +187 -0
- package/dist/senses/cli.js +777 -264
- package/dist/senses/commands.js +66 -3
- package/dist/senses/continuity.js +94 -0
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +209 -16
- package/dist/senses/inner-dialog.js +682 -91
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +751 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +392 -0
- package/dist/senses/surface-tool.js +70 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +925 -195
- package/dist/senses/trust-gate.js +207 -2
- package/dist/senses/voice/audio-playback.js +237 -0
- package/dist/senses/voice/audio-routing.js +119 -0
- package/dist/senses/voice/elevenlabs.js +202 -0
- package/dist/senses/voice/floor-control.js +431 -0
- package/dist/senses/voice/floor-controller.js +115 -0
- package/dist/senses/voice/golden-path.js +116 -0
- package/dist/senses/voice/index.js +29 -0
- package/dist/senses/voice/meeting.js +113 -0
- package/dist/senses/voice/outbound.js +190 -0
- package/dist/senses/voice/phone.js +33 -0
- package/dist/senses/voice/playback.js +139 -0
- package/dist/senses/voice/realtime-eval.js +496 -0
- package/dist/senses/voice/realtime-trace.js +531 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +191 -0
- package/dist/senses/voice/twilio-phone-runtime.js +807 -0
- package/dist/senses/voice/twilio-phone.js +5077 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +81 -0
- package/dist/senses/voice-realtime-eval-command.js +99 -0
- package/dist/senses/voice-realtime-eval-entry.js +21 -0
- package/dist/senses/voice-twilio-entry.js +87 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +265 -0
- package/package.json +52 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +99 -0
- package/skills/travel-planning.md +138 -0
- package/AdoptionSpecialist.ouro/agent.json +0 -20
- package/AdoptionSpecialist.ouro/psyche/SOUL.md +0 -22
- package/dist/heart/daemon/specialist-orchestrator.js +0 -160
- package/dist/heart/daemon/specialist-prompt.js +0 -40
- package/dist/heart/daemon/specialist-session.js +0 -142
- package/dist/heart/daemon/specialist-tools.js +0 -128
- package/dist/heart/daemon/subagent-installer.js +0 -125
- package/dist/inner-worker-entry.js +0 -4
- package/dist/mind/associative-recall.js +0 -197
- package/dist/senses/bluebubbles-client.js +0 -279
- package/dist/senses/bluebubbles-entry.js +0 -11
- package/dist/senses/bluebubbles.js +0 -332
- package/subagents/README.md +0 -73
- package/subagents/work-doer.md +0 -233
- package/subagents/work-merger.md +0 -624
- package/subagents/work-planner.md +0 -373
- /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/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
|
@@ -0,0 +1,394 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Interactive repair flow for degraded agents detected during `ouro up`.
|
|
4
|
+
*
|
|
5
|
+
* Examines each degraded agent's errorReason and fixHint to detect common
|
|
6
|
+
* issue patterns and prompt the user for repair actions.
|
|
7
|
+
*/
|
|
8
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
9
|
+
exports.hasRunnableInteractiveRepair = hasRunnableInteractiveRepair;
|
|
10
|
+
exports.isAffirmativeAnswer = isAffirmativeAnswer;
|
|
11
|
+
exports.runInteractiveRepair = runInteractiveRepair;
|
|
12
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
13
|
+
const identity_1 = require("../identity");
|
|
14
|
+
const terminal_ui_1 = require("./terminal-ui");
|
|
15
|
+
function isCredentialIssue(degraded) {
|
|
16
|
+
const reason = degraded.errorReason.toLowerCase();
|
|
17
|
+
const hint = degraded.fixHint.toLowerCase();
|
|
18
|
+
return reason.includes("credentials") || hint.includes("ouro auth");
|
|
19
|
+
}
|
|
20
|
+
function isVaultUnlockIssue(degraded) {
|
|
21
|
+
const text = `${degraded.errorReason}\n${degraded.fixHint}`.toLowerCase();
|
|
22
|
+
return /ouro vault unlock|credential vault is locked|vault(?: is)? locked/.test(text);
|
|
23
|
+
}
|
|
24
|
+
function isConfigError(degraded) {
|
|
25
|
+
return degraded.fixHint.length > 0 && !isVaultUnlockIssue(degraded) && !isCredentialIssue(degraded);
|
|
26
|
+
}
|
|
27
|
+
function hasRunnableInteractiveRepair(degraded) {
|
|
28
|
+
if (degraded.issue?.actions.some((action) => typedActionToRunnable(degraded, action) !== undefined)) {
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
return isVaultUnlockIssue(degraded) || isCredentialIssue(degraded);
|
|
32
|
+
}
|
|
33
|
+
function isAgentProvider(value) {
|
|
34
|
+
return Object.prototype.hasOwnProperty.call(identity_1.PROVIDER_CREDENTIALS, value);
|
|
35
|
+
}
|
|
36
|
+
function extractProviderFromFixHint(fixHint) {
|
|
37
|
+
const provider = fixHint.match(/--provider\s+([a-z0-9-]+)/)?.[1]
|
|
38
|
+
?? fixHint.match(/providers\.([a-z0-9-]+)/)?.[1];
|
|
39
|
+
if (!provider || !isAgentProvider(provider))
|
|
40
|
+
return undefined;
|
|
41
|
+
return provider;
|
|
42
|
+
}
|
|
43
|
+
function escapeRegExp(value) {
|
|
44
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
|
|
45
|
+
}
|
|
46
|
+
function cleanExtractedCommand(command) {
|
|
47
|
+
const cleaned = command?.trim().replace(/[`'",;:.)]+$/g, "").trim();
|
|
48
|
+
return cleaned && cleaned.length > 0 ? cleaned : undefined;
|
|
49
|
+
}
|
|
50
|
+
function extractRepairCommand(fixHint, commandPrefix) {
|
|
51
|
+
const escapedPrefix = escapeRegExp(commandPrefix);
|
|
52
|
+
const commandBody = `${escapedPrefix}(?=\\s|$)[^\`'"]*`;
|
|
53
|
+
const quoted = fixHint.match(new RegExp(`[\`'"](${commandBody})[\`'"]`, "i"))?.[1];
|
|
54
|
+
const unquoted = fixHint.match(new RegExp(`(${escapedPrefix}(?=\\s|$)[^\\n,;.]+)`, "i"))?.[1];
|
|
55
|
+
return cleanExtractedCommand(quoted) ?? cleanExtractedCommand(unquoted);
|
|
56
|
+
}
|
|
57
|
+
function authCommandFor(degraded) {
|
|
58
|
+
const command = extractRepairCommand(degraded.fixHint, "ouro auth");
|
|
59
|
+
return command && command.length > 0 ? command : `ouro auth --agent ${degraded.agent}`;
|
|
60
|
+
}
|
|
61
|
+
function vaultUnlockCommandFor(degraded) {
|
|
62
|
+
const command = extractRepairCommand(degraded.fixHint, "ouro vault unlock");
|
|
63
|
+
return command && command.length > 0 ? command : `ouro vault unlock --agent ${degraded.agent}`;
|
|
64
|
+
}
|
|
65
|
+
function isAffirmativeAnswer(answer) {
|
|
66
|
+
return /^(y|yes)$/i.test(answer.trim());
|
|
67
|
+
}
|
|
68
|
+
function uniqueCommands(commands) {
|
|
69
|
+
const seen = new Set();
|
|
70
|
+
const unique = [];
|
|
71
|
+
commands.forEach((command) => {
|
|
72
|
+
if (!command)
|
|
73
|
+
return;
|
|
74
|
+
if (seen.has(command))
|
|
75
|
+
return;
|
|
76
|
+
seen.add(command);
|
|
77
|
+
unique.push(command);
|
|
78
|
+
});
|
|
79
|
+
return unique;
|
|
80
|
+
}
|
|
81
|
+
function fallbackCommandsFor(degraded, primaryCommand) {
|
|
82
|
+
const issueCommands = degraded.issue?.actions.map((action) => action.command) ?? [];
|
|
83
|
+
return uniqueCommands([
|
|
84
|
+
primaryCommand,
|
|
85
|
+
...issueCommands,
|
|
86
|
+
extractRepairCommand(degraded.fixHint, "ouro vault replace"),
|
|
87
|
+
extractRepairCommand(degraded.fixHint, "ouro vault recover"),
|
|
88
|
+
extractRepairCommand(degraded.fixHint, "ouro use"),
|
|
89
|
+
]);
|
|
90
|
+
}
|
|
91
|
+
function renderRepairChoices(prefix, commands) {
|
|
92
|
+
return commands.map((command, index) => ` ${index === 0 ? prefix : "or"}: ${command}`);
|
|
93
|
+
}
|
|
94
|
+
function repairStatusFor(action) {
|
|
95
|
+
return action.kind === "vault-unlock" ? "locked" : "needs credentials";
|
|
96
|
+
}
|
|
97
|
+
function renderRepairQueueSummaryLines(degraded) {
|
|
98
|
+
const repairable = degraded
|
|
99
|
+
.map((entry) => ({ entry, action: runnableRepairActionFor(entry) }))
|
|
100
|
+
.filter((item) => item.action !== undefined);
|
|
101
|
+
if (repairable.length < 2)
|
|
102
|
+
return [];
|
|
103
|
+
const lines = [
|
|
104
|
+
"Repair queue",
|
|
105
|
+
`${repairable.length} agents need attention before startup can finish.`,
|
|
106
|
+
"",
|
|
107
|
+
];
|
|
108
|
+
repairable.forEach(({ entry, action }, index) => {
|
|
109
|
+
lines.push(`${entry.agent} - ${action.label}`);
|
|
110
|
+
lines.push(` ${action.command}`);
|
|
111
|
+
if (index < repairable.length - 1)
|
|
112
|
+
lines.push("");
|
|
113
|
+
});
|
|
114
|
+
return lines;
|
|
115
|
+
}
|
|
116
|
+
function renderRepairQueueSummary(degraded, deps) {
|
|
117
|
+
const repairable = degraded
|
|
118
|
+
.map((entry) => ({ entry, action: runnableRepairActionFor(entry) }))
|
|
119
|
+
.filter((item) => item.action !== undefined);
|
|
120
|
+
if (!deps.isTTY) {
|
|
121
|
+
return renderRepairQueueSummaryLines(degraded).join("\n");
|
|
122
|
+
}
|
|
123
|
+
return (0, terminal_ui_1.renderTerminalWizard)({
|
|
124
|
+
isTTY: true,
|
|
125
|
+
columns: deps.stdoutColumns,
|
|
126
|
+
masthead: {
|
|
127
|
+
subtitle: "Repair paths ready.",
|
|
128
|
+
},
|
|
129
|
+
title: "Needs attention before startup can finish",
|
|
130
|
+
summary: "Ouro found repair steps it can open right now. It will walk through them one at a time.",
|
|
131
|
+
sections: [{
|
|
132
|
+
title: "Repair queue",
|
|
133
|
+
items: repairable.map(({ entry, action }) => ({
|
|
134
|
+
label: entry.agent,
|
|
135
|
+
status: repairStatusFor(action),
|
|
136
|
+
summary: action.label,
|
|
137
|
+
detailLines: [entry.errorReason],
|
|
138
|
+
command: action.command,
|
|
139
|
+
})),
|
|
140
|
+
}],
|
|
141
|
+
suppressEvent: true,
|
|
142
|
+
}).trimEnd();
|
|
143
|
+
}
|
|
144
|
+
function renderActionPromptLines(agent, action) {
|
|
145
|
+
const lines = [
|
|
146
|
+
`${agent}`,
|
|
147
|
+
` needs: ${action.label}`,
|
|
148
|
+
` run: ${action.command}`,
|
|
149
|
+
];
|
|
150
|
+
if (action.kind === "vault-unlock") {
|
|
151
|
+
lines.push(" note: use the saved vault unlock secret");
|
|
152
|
+
}
|
|
153
|
+
return lines;
|
|
154
|
+
}
|
|
155
|
+
function renderActionPrompt(entry, action, deps) {
|
|
156
|
+
if (!deps.isTTY)
|
|
157
|
+
return renderActionPromptLines(entry.agent, action).join("\n");
|
|
158
|
+
const footer = action.kind === "vault-unlock"
|
|
159
|
+
? "Only say yes if you have the saved vault unlock secret."
|
|
160
|
+
: "Say yes if you want Ouro to open the auth flow now.";
|
|
161
|
+
return (0, terminal_ui_1.renderTerminalWizard)({
|
|
162
|
+
isTTY: true,
|
|
163
|
+
columns: deps.stdoutColumns,
|
|
164
|
+
masthead: {
|
|
165
|
+
subtitle: "One repair step at a time.",
|
|
166
|
+
},
|
|
167
|
+
title: `Repair ${entry.agent}`,
|
|
168
|
+
summary: "Ouro found one clear next move for this agent.",
|
|
169
|
+
nextStep: {
|
|
170
|
+
label: action.kind === "vault-unlock"
|
|
171
|
+
? "Unlock the credential vault on this machine."
|
|
172
|
+
: "Refresh provider authentication.",
|
|
173
|
+
detail: action.kind === "vault-unlock"
|
|
174
|
+
? "Use the saved unlock secret if you have it. If not, leave this for later and choose a replacement or recovery path."
|
|
175
|
+
: "This opens the provider login or refresh flow for the selected provider.",
|
|
176
|
+
command: action.command,
|
|
177
|
+
},
|
|
178
|
+
sections: [{
|
|
179
|
+
title: "Why startup paused",
|
|
180
|
+
items: [{
|
|
181
|
+
label: entry.agent,
|
|
182
|
+
status: repairStatusFor(action),
|
|
183
|
+
summary: entry.errorReason,
|
|
184
|
+
}],
|
|
185
|
+
}],
|
|
186
|
+
footerLines: [footer],
|
|
187
|
+
suppressEvent: true,
|
|
188
|
+
}).trimEnd();
|
|
189
|
+
}
|
|
190
|
+
function renderDeferredRepair(agent, commands, deps) {
|
|
191
|
+
if (!deps.isTTY) {
|
|
192
|
+
return [
|
|
193
|
+
`Leaving ${agent} for later.`,
|
|
194
|
+
...renderRepairChoices("next", commands),
|
|
195
|
+
].join("\n");
|
|
196
|
+
}
|
|
197
|
+
return (0, terminal_ui_1.renderTerminalWizard)({
|
|
198
|
+
isTTY: true,
|
|
199
|
+
columns: deps.stdoutColumns,
|
|
200
|
+
masthead: {
|
|
201
|
+
subtitle: "Nothing changed yet.",
|
|
202
|
+
},
|
|
203
|
+
title: `Leaving ${agent} for later`,
|
|
204
|
+
summary: "Ouro did not open this repair flow right now.",
|
|
205
|
+
sections: [{
|
|
206
|
+
title: "Next time",
|
|
207
|
+
items: commands.map((command, index) => ({
|
|
208
|
+
key: String(index + 1),
|
|
209
|
+
label: index === 0 ? "Start here" : "Or try this",
|
|
210
|
+
command,
|
|
211
|
+
})),
|
|
212
|
+
}],
|
|
213
|
+
suppressEvent: true,
|
|
214
|
+
}).trimEnd();
|
|
215
|
+
}
|
|
216
|
+
function renderManualRepairHint(agent, fixHint) {
|
|
217
|
+
return [
|
|
218
|
+
`${agent}`,
|
|
219
|
+
" needs manual attention",
|
|
220
|
+
` next: ${fixHint}`,
|
|
221
|
+
].join("\n");
|
|
222
|
+
}
|
|
223
|
+
function renderUnknownRepair(agent, errorReason) {
|
|
224
|
+
return [
|
|
225
|
+
`${agent}`,
|
|
226
|
+
` ${errorReason}`,
|
|
227
|
+
].join("\n");
|
|
228
|
+
}
|
|
229
|
+
function writeDeclinedRepair(degraded, command, deps) {
|
|
230
|
+
deps.writeStdout(renderDeferredRepair(degraded.agent, fallbackCommandsFor(degraded, command), deps));
|
|
231
|
+
}
|
|
232
|
+
function runnableRepairActionFor(degraded) {
|
|
233
|
+
const typedAction = degraded.issue?.actions
|
|
234
|
+
.map((action) => typedActionToRunnable(degraded, action))
|
|
235
|
+
.find((action) => action !== undefined);
|
|
236
|
+
if (typedAction)
|
|
237
|
+
return typedAction;
|
|
238
|
+
if (isVaultUnlockIssue(degraded)) {
|
|
239
|
+
return { kind: "vault-unlock", label: "vault unlock", command: vaultUnlockCommandFor(degraded) };
|
|
240
|
+
}
|
|
241
|
+
if (isCredentialIssue(degraded)) {
|
|
242
|
+
return {
|
|
243
|
+
kind: "provider-auth",
|
|
244
|
+
label: "provider auth",
|
|
245
|
+
command: authCommandFor(degraded),
|
|
246
|
+
provider: extractProviderFromFixHint(degraded.fixHint),
|
|
247
|
+
};
|
|
248
|
+
}
|
|
249
|
+
return undefined;
|
|
250
|
+
}
|
|
251
|
+
function typedActionToRunnable(degraded, action) {
|
|
252
|
+
if (action.executable === false || action.command.includes("<"))
|
|
253
|
+
return undefined;
|
|
254
|
+
if (action.kind === "vault-unlock") {
|
|
255
|
+
return { kind: "vault-unlock", label: "vault unlock", command: action.command };
|
|
256
|
+
}
|
|
257
|
+
if (action.kind === "provider-auth") {
|
|
258
|
+
return {
|
|
259
|
+
kind: "provider-auth",
|
|
260
|
+
label: "provider auth",
|
|
261
|
+
command: action.command || `ouro auth --agent ${degraded.agent}`,
|
|
262
|
+
provider: action.provider,
|
|
263
|
+
};
|
|
264
|
+
}
|
|
265
|
+
return undefined;
|
|
266
|
+
}
|
|
267
|
+
function writeRepairQueueSummary(degraded, deps) {
|
|
268
|
+
const lines = renderRepairQueueSummaryLines(degraded);
|
|
269
|
+
if (lines.length > 0)
|
|
270
|
+
deps.writeStdout(renderRepairQueueSummary(degraded, deps));
|
|
271
|
+
}
|
|
272
|
+
async function attemptVaultUnlock(entry, action, deps) {
|
|
273
|
+
deps.writeStdout(renderActionPrompt(entry, action, deps));
|
|
274
|
+
const answer = await deps.promptInput(`Unlock ${entry.agent}'s vault now? [y/N] `);
|
|
275
|
+
if (!isAffirmativeAnswer(answer)) {
|
|
276
|
+
writeDeclinedRepair(entry, action.command, deps);
|
|
277
|
+
return { succeeded: false, attempted: false };
|
|
278
|
+
}
|
|
279
|
+
try {
|
|
280
|
+
if (!deps.runVaultUnlock) {
|
|
281
|
+
deps.writeStdout(renderManualRepairHint(entry.agent, entry.fixHint));
|
|
282
|
+
return { succeeded: false, attempted: false };
|
|
283
|
+
}
|
|
284
|
+
await deps.runVaultUnlock(entry.agent);
|
|
285
|
+
return { succeeded: true, attempted: true };
|
|
286
|
+
}
|
|
287
|
+
catch (error) {
|
|
288
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
289
|
+
deps.writeStdout(`Vault unlock did not finish for ${entry.agent}.\n ${msg}`);
|
|
290
|
+
(0, runtime_1.emitNervesEvent)({
|
|
291
|
+
level: "error",
|
|
292
|
+
component: "daemon",
|
|
293
|
+
event: "daemon.interactive_repair_vault_unlock_error",
|
|
294
|
+
message: `vault unlock failed for ${entry.agent}`,
|
|
295
|
+
meta: { agent: entry.agent, error: msg },
|
|
296
|
+
});
|
|
297
|
+
return { succeeded: false, attempted: true };
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
async function attemptProviderAuth(entry, action, deps) {
|
|
301
|
+
deps.writeStdout(renderActionPrompt(entry, action, deps));
|
|
302
|
+
const answer = await deps.promptInput(`Open the auth flow for ${entry.agent} now? [y/N] `);
|
|
303
|
+
if (!isAffirmativeAnswer(answer)) {
|
|
304
|
+
writeDeclinedRepair(entry, action.command, deps);
|
|
305
|
+
return { succeeded: false, attempted: false };
|
|
306
|
+
}
|
|
307
|
+
try {
|
|
308
|
+
if (action.provider) {
|
|
309
|
+
await deps.runAuthFlow(entry.agent, action.provider);
|
|
310
|
+
}
|
|
311
|
+
else {
|
|
312
|
+
await deps.runAuthFlow(entry.agent);
|
|
313
|
+
}
|
|
314
|
+
return { succeeded: true, attempted: true };
|
|
315
|
+
}
|
|
316
|
+
catch (error) {
|
|
317
|
+
const msg = error instanceof Error ? error.message : String(error);
|
|
318
|
+
deps.writeStdout(`Auth did not finish for ${entry.agent}.\n ${msg}`);
|
|
319
|
+
(0, runtime_1.emitNervesEvent)({
|
|
320
|
+
level: "error",
|
|
321
|
+
component: "daemon",
|
|
322
|
+
event: "daemon.interactive_repair_auth_error",
|
|
323
|
+
message: `auth flow failed for ${entry.agent}`,
|
|
324
|
+
meta: { agent: entry.agent, error: msg },
|
|
325
|
+
});
|
|
326
|
+
return { succeeded: false, attempted: true };
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
async function processEntry(entry, deps) {
|
|
330
|
+
let current = entry;
|
|
331
|
+
while (current) {
|
|
332
|
+
const action = runnableRepairActionFor(current);
|
|
333
|
+
let outcome;
|
|
334
|
+
if (action?.kind === "vault-unlock") {
|
|
335
|
+
outcome = await attemptVaultUnlock(current, action, deps);
|
|
336
|
+
}
|
|
337
|
+
else if (action?.kind === "provider-auth") {
|
|
338
|
+
outcome = await attemptProviderAuth(current, action, deps);
|
|
339
|
+
}
|
|
340
|
+
else if (isConfigError(current)) {
|
|
341
|
+
deps.writeStdout(renderManualRepairHint(current.agent, current.fixHint));
|
|
342
|
+
return { attempted: false };
|
|
343
|
+
}
|
|
344
|
+
else {
|
|
345
|
+
deps.writeStdout(renderUnknownRepair(current.agent, current.errorReason));
|
|
346
|
+
return { attempted: false };
|
|
347
|
+
}
|
|
348
|
+
if (!outcome.succeeded || !deps.recheckAgent) {
|
|
349
|
+
return { attempted: outcome.attempted };
|
|
350
|
+
}
|
|
351
|
+
// Re-evaluate the agent after successful repair
|
|
352
|
+
const recheckResult = await deps.recheckAgent(current.agent);
|
|
353
|
+
if (recheckResult === null) {
|
|
354
|
+
deps.writeStdout(`${current.agent} recovered.`);
|
|
355
|
+
return { attempted: true };
|
|
356
|
+
}
|
|
357
|
+
// Agent still degraded with a new error -- loop to present the new action
|
|
358
|
+
current = recheckResult;
|
|
359
|
+
}
|
|
360
|
+
/* v8 ignore next -- unreachable: loop always returns from within @preserve */
|
|
361
|
+
return { attempted: false };
|
|
362
|
+
}
|
|
363
|
+
async function runInteractiveRepair(degraded, deps) {
|
|
364
|
+
(0, runtime_1.emitNervesEvent)({
|
|
365
|
+
level: "info",
|
|
366
|
+
component: "daemon",
|
|
367
|
+
event: "daemon.interactive_repair_start",
|
|
368
|
+
message: "interactive repair flow started",
|
|
369
|
+
meta: { degradedCount: degraded.length },
|
|
370
|
+
});
|
|
371
|
+
if (degraded.length === 0) {
|
|
372
|
+
return { repairsAttempted: false };
|
|
373
|
+
}
|
|
374
|
+
let repairsAttempted = false;
|
|
375
|
+
if (!deps.skipQueueSummary) {
|
|
376
|
+
writeRepairQueueSummary(degraded, deps);
|
|
377
|
+
}
|
|
378
|
+
for (const entry of degraded) {
|
|
379
|
+
const result = await processEntry(entry, deps);
|
|
380
|
+
if (result.attempted)
|
|
381
|
+
repairsAttempted = true;
|
|
382
|
+
}
|
|
383
|
+
if (repairsAttempted) {
|
|
384
|
+
deps.writeStdout("Repair flow complete.");
|
|
385
|
+
}
|
|
386
|
+
(0, runtime_1.emitNervesEvent)({
|
|
387
|
+
level: "info",
|
|
388
|
+
component: "daemon",
|
|
389
|
+
event: "daemon.interactive_repair_end",
|
|
390
|
+
message: "interactive repair flow completed",
|
|
391
|
+
meta: { repairsAttempted },
|
|
392
|
+
});
|
|
393
|
+
return { repairsAttempted };
|
|
394
|
+
}
|
|
@@ -0,0 +1,188 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.DAEMON_PLIST_LABEL = void 0;
|
|
37
|
+
exports.bootoutLaunchAgentByLabel = bootoutLaunchAgentByLabel;
|
|
38
|
+
exports.generateDaemonPlist = generateDaemonPlist;
|
|
39
|
+
exports.writeLaunchAgentPlist = writeLaunchAgentPlist;
|
|
40
|
+
exports.installLaunchAgent = installLaunchAgent;
|
|
41
|
+
exports.uninstallLaunchAgent = uninstallLaunchAgent;
|
|
42
|
+
exports.isDaemonInstalled = isDaemonInstalled;
|
|
43
|
+
const path = __importStar(require("path"));
|
|
44
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
45
|
+
exports.DAEMON_PLIST_LABEL = "bot.ouro.daemon";
|
|
46
|
+
function plistFilePath(homeDir) {
|
|
47
|
+
return path.join(homeDir, "Library", "LaunchAgents", `${exports.DAEMON_PLIST_LABEL}.plist`);
|
|
48
|
+
}
|
|
49
|
+
function userLaunchDomain(userUid) {
|
|
50
|
+
return `gui/${userUid}`;
|
|
51
|
+
}
|
|
52
|
+
function bootoutLaunchAgentByLabel(deps) {
|
|
53
|
+
const domain = userLaunchDomain(deps.userUid);
|
|
54
|
+
try {
|
|
55
|
+
deps.exec(`launchctl bootout ${domain}/${exports.DAEMON_PLIST_LABEL}`);
|
|
56
|
+
(0, runtime_1.emitNervesEvent)({
|
|
57
|
+
component: "daemon",
|
|
58
|
+
event: "daemon.launchd_label_bootout",
|
|
59
|
+
message: "booted out daemon launch agent by label",
|
|
60
|
+
meta: { label: exports.DAEMON_PLIST_LABEL, domain },
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
catch (error) {
|
|
64
|
+
(0, runtime_1.emitNervesEvent)({
|
|
65
|
+
component: "daemon",
|
|
66
|
+
event: "daemon.launchd_label_bootout_skipped",
|
|
67
|
+
message: "daemon launch agent label bootout skipped",
|
|
68
|
+
meta: { label: exports.DAEMON_PLIST_LABEL, domain, reason: error instanceof Error ? error.message : String(error) },
|
|
69
|
+
});
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
function generateDaemonPlist(options) {
|
|
73
|
+
(0, runtime_1.emitNervesEvent)({
|
|
74
|
+
component: "daemon",
|
|
75
|
+
event: "daemon.launchd_generate_plist",
|
|
76
|
+
message: "generating daemon plist",
|
|
77
|
+
meta: { entryPath: options.entryPath, socketPath: options.socketPath },
|
|
78
|
+
});
|
|
79
|
+
const lines = [
|
|
80
|
+
`<?xml version="1.0" encoding="UTF-8"?>`,
|
|
81
|
+
`<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">`,
|
|
82
|
+
`<plist version="1.0">`,
|
|
83
|
+
`<dict>`,
|
|
84
|
+
` <key>Label</key>`,
|
|
85
|
+
` <string>${exports.DAEMON_PLIST_LABEL}</string>`,
|
|
86
|
+
` <key>ProgramArguments</key>`,
|
|
87
|
+
` <array>`,
|
|
88
|
+
` <string>${options.nodePath}</string>`,
|
|
89
|
+
` <string>${options.entryPath}</string>`,
|
|
90
|
+
` <string>--socket</string>`,
|
|
91
|
+
` <string>${options.socketPath}</string>`,
|
|
92
|
+
` </array>`,
|
|
93
|
+
` <key>RunAtLoad</key>`,
|
|
94
|
+
` <true/>`,
|
|
95
|
+
` <key>KeepAlive</key>`,
|
|
96
|
+
` <true/>`,
|
|
97
|
+
];
|
|
98
|
+
if (options.envPath) {
|
|
99
|
+
lines.push(` <key>EnvironmentVariables</key>`, ` <dict>`, ` <key>PATH</key>`, ` <string>${options.envPath}</string>`, ` </dict>`);
|
|
100
|
+
}
|
|
101
|
+
if (options.logDir) {
|
|
102
|
+
// PR 1 decision: we no longer emit `StandardErrorPath` for the daemon.
|
|
103
|
+
// The daemon's structured nerves ndjson pipeline (rotated + gzipped via
|
|
104
|
+
// createNdjsonFileSink) is the source of truth for diagnostics. Writing
|
|
105
|
+
// raw process stderr to an unrotated file grew to 366 MB in the wild;
|
|
106
|
+
// dropping the key lets launchd forward stray stderr to the system log
|
|
107
|
+
// where it gets rotated by the OS.
|
|
108
|
+
lines.push(` <key>StandardOutPath</key>`, ` <string>${path.join(options.logDir, "ouro-daemon-stdout.log")}</string>`);
|
|
109
|
+
}
|
|
110
|
+
lines.push(`</dict>`, `</plist>`, ``);
|
|
111
|
+
return lines.join("\n");
|
|
112
|
+
}
|
|
113
|
+
function writeLaunchAgentPlist(deps, options) {
|
|
114
|
+
const launchAgentsDir = path.join(deps.homeDir, "Library", "LaunchAgents");
|
|
115
|
+
deps.mkdirp(launchAgentsDir);
|
|
116
|
+
if (options.logDir) {
|
|
117
|
+
deps.mkdirp(options.logDir);
|
|
118
|
+
}
|
|
119
|
+
const fullPath = plistFilePath(deps.homeDir);
|
|
120
|
+
const xml = generateDaemonPlist(options);
|
|
121
|
+
deps.writeFile(fullPath, xml);
|
|
122
|
+
(0, runtime_1.emitNervesEvent)({
|
|
123
|
+
component: "daemon",
|
|
124
|
+
event: "daemon.launchd_plist_written",
|
|
125
|
+
message: "daemon launch agent plist written",
|
|
126
|
+
meta: { plistPath: fullPath, entryPath: options.entryPath, socketPath: options.socketPath },
|
|
127
|
+
});
|
|
128
|
+
return fullPath;
|
|
129
|
+
}
|
|
130
|
+
function installLaunchAgent(deps, options) {
|
|
131
|
+
(0, runtime_1.emitNervesEvent)({
|
|
132
|
+
component: "daemon",
|
|
133
|
+
event: "daemon.launchd_install",
|
|
134
|
+
message: "installing launch agent",
|
|
135
|
+
meta: { entryPath: options.entryPath, socketPath: options.socketPath },
|
|
136
|
+
});
|
|
137
|
+
const fullPath = plistFilePath(deps.homeDir);
|
|
138
|
+
const domain = userLaunchDomain(deps.userUid);
|
|
139
|
+
// Unload existing (best effort) for idempotent re-install
|
|
140
|
+
if (deps.existsFile(fullPath)) {
|
|
141
|
+
try {
|
|
142
|
+
deps.exec(`launchctl bootout ${domain} "${fullPath}"`);
|
|
143
|
+
}
|
|
144
|
+
catch { /* best effort */ }
|
|
145
|
+
}
|
|
146
|
+
writeLaunchAgentPlist(deps, options);
|
|
147
|
+
// Bootstrap the plist so launchd manages crash recovery via KeepAlive.
|
|
148
|
+
// This is safe because ouro up calls this AFTER the daemon is already running,
|
|
149
|
+
// so launchd sees the existing process and just registers for KeepAlive.
|
|
150
|
+
try {
|
|
151
|
+
deps.exec(`launchctl bootstrap ${domain} "${fullPath}"`);
|
|
152
|
+
}
|
|
153
|
+
catch { /* already loaded */ }
|
|
154
|
+
(0, runtime_1.emitNervesEvent)({
|
|
155
|
+
component: "daemon",
|
|
156
|
+
event: "daemon.launchd_installed",
|
|
157
|
+
message: "launch agent installed with KeepAlive",
|
|
158
|
+
meta: { plistPath: fullPath },
|
|
159
|
+
});
|
|
160
|
+
}
|
|
161
|
+
function uninstallLaunchAgent(deps) {
|
|
162
|
+
(0, runtime_1.emitNervesEvent)({
|
|
163
|
+
component: "daemon",
|
|
164
|
+
event: "daemon.launchd_uninstall",
|
|
165
|
+
message: "uninstalling launch agent",
|
|
166
|
+
meta: {},
|
|
167
|
+
});
|
|
168
|
+
const fullPath = plistFilePath(deps.homeDir);
|
|
169
|
+
bootoutLaunchAgentByLabel(deps);
|
|
170
|
+
if (deps.existsFile(fullPath)) {
|
|
171
|
+
deps.removeFile(fullPath);
|
|
172
|
+
}
|
|
173
|
+
(0, runtime_1.emitNervesEvent)({
|
|
174
|
+
component: "daemon",
|
|
175
|
+
event: "daemon.launchd_uninstalled",
|
|
176
|
+
message: "launch agent uninstalled",
|
|
177
|
+
meta: { plistPath: fullPath },
|
|
178
|
+
});
|
|
179
|
+
}
|
|
180
|
+
function isDaemonInstalled(deps) {
|
|
181
|
+
(0, runtime_1.emitNervesEvent)({
|
|
182
|
+
component: "daemon",
|
|
183
|
+
event: "daemon.launchd_check_installed",
|
|
184
|
+
message: "checking if daemon is installed",
|
|
185
|
+
meta: {},
|
|
186
|
+
});
|
|
187
|
+
return deps.existsFile(plistFilePath(deps.homeDir));
|
|
188
|
+
}
|