@ouro.bot/cli 0.1.0-alpha.62 → 0.1.0-alpha.637
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 +4087 -13
- 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/intentions.js +134 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +270 -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/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 +322 -0
- package/dist/heart/config.js +114 -119
- package/dist/heart/core.js +1028 -248
- package/dist/heart/cross-chat-delivery.js +3 -18
- package/dist/heart/daemon/agent-config-check.js +419 -0
- package/dist/heart/daemon/agent-discovery.js +102 -3
- package/dist/heart/daemon/agent-service.js +522 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +776 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +7468 -0
- package/dist/heart/daemon/cli-help.js +505 -0
- package/dist/heart/daemon/cli-parse.js +1554 -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 -1700
- 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 +906 -71
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +873 -0
- package/dist/heart/daemon/health-monitor.js +122 -1
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +115 -1
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +89 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +37 -8
- package/dist/heart/daemon/log-tailer.js +79 -10
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- 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 +501 -35
- 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 +11 -3
- 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 +493 -38
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +22 -9
- 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 +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +32 -56
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- package/dist/heart/{daemon → hatch}/specialist-prompt.js +12 -9
- package/dist/heart/{daemon → hatch}/specialist-tools.js +37 -14
- package/dist/heart/identity.js +168 -57
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +66 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +31 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +197 -0
- package/dist/heart/mailbox/readers/agent-machine.js +418 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +319 -0
- package/dist/heart/mailbox/readers/mail.js +375 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +756 -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 +692 -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 +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +139 -52
- package/dist/heart/providers/azure.js +23 -11
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +367 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +13 -4
- package/dist/heart/session-activity.js +48 -24
- package/dist/heart/session-events.js +1163 -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 +345 -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 +143 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +389 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +6 -5
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +426 -0
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailbox-ui/assets/index-9-AxCxuB.js +61 -0
- package/dist/mailbox-ui/assets/index-CWzt267f.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 +14 -1
- package/dist/mind/context.js +251 -101
- package/dist/mind/desk-section.js +310 -0
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +68 -76
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +39 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +48 -4
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/journal-index.js +162 -0
- package/dist/mind/note-search.js +268 -0
- 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 +1075 -146
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/nerves/cli-logging.js +7 -1
- package/dist/nerves/coverage/audit-rules.js +15 -6
- package/dist/nerves/coverage/audit.js +28 -2
- package/dist/nerves/coverage/cli.js +1 -1
- package/dist/nerves/coverage/contract.js +5 -5
- package/dist/nerves/coverage/file-completeness.js +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 +1040 -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 +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 +385 -0
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +403 -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-attachments.js +317 -0
- package/dist/repertoire/tools-awaiting.js +372 -0
- package/dist/repertoire/tools-base.js +59 -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-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 +227 -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 +438 -0
- package/dist/repertoire/tools-obligations.js +143 -0
- package/dist/repertoire/tools-orientation.js +31 -0
- package/dist/repertoire/tools-record.js +464 -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 +182 -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 +215 -103
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +594 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +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 +108 -0
- package/dist/senses/inner-dialog-worker.js +254 -22
- package/dist/senses/inner-dialog.js +505 -40
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +666 -181
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +393 -0
- package/dist/senses/surface-tool.js +108 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +388 -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 +53 -0
- package/package.json +48 -8
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +99 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -351
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/associative-recall.js +0 -209
- 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
|
@@ -0,0 +1,135 @@
|
|
|
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.createRealOsCronDeps = createRealOsCronDeps;
|
|
37
|
+
exports.createRealCrontabDeps = createRealCrontabDeps;
|
|
38
|
+
exports.resolveOuroBinaryPath = resolveOuroBinaryPath;
|
|
39
|
+
const child_process_1 = require("child_process");
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const os = __importStar(require("os"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
44
|
+
function createRealOsCronDeps() {
|
|
45
|
+
(0, runtime_1.emitNervesEvent)({
|
|
46
|
+
component: "daemon",
|
|
47
|
+
event: "daemon.os_cron_deps_created",
|
|
48
|
+
message: "created real OS cron deps",
|
|
49
|
+
meta: { platform: process.platform },
|
|
50
|
+
});
|
|
51
|
+
return {
|
|
52
|
+
exec: (cmd) => {
|
|
53
|
+
try {
|
|
54
|
+
(0, child_process_1.execSync)(cmd, { stdio: "ignore" });
|
|
55
|
+
}
|
|
56
|
+
catch {
|
|
57
|
+
/* best effort */
|
|
58
|
+
}
|
|
59
|
+
},
|
|
60
|
+
writeFile: (p, c) => fs.writeFileSync(p, c, "utf-8"),
|
|
61
|
+
removeFile: (p) => {
|
|
62
|
+
try {
|
|
63
|
+
fs.unlinkSync(p);
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
/* best effort — file may already be gone */
|
|
67
|
+
}
|
|
68
|
+
},
|
|
69
|
+
existsFile: (p) => fs.existsSync(p),
|
|
70
|
+
listDir: (dir) => {
|
|
71
|
+
try {
|
|
72
|
+
return fs.readdirSync(dir);
|
|
73
|
+
}
|
|
74
|
+
catch {
|
|
75
|
+
return [];
|
|
76
|
+
}
|
|
77
|
+
},
|
|
78
|
+
mkdirp: (dir) => fs.mkdirSync(dir, { recursive: true }),
|
|
79
|
+
homeDir: os.homedir(),
|
|
80
|
+
envPath: process.env.PATH ?? "",
|
|
81
|
+
};
|
|
82
|
+
}
|
|
83
|
+
function createRealCrontabDeps() {
|
|
84
|
+
(0, runtime_1.emitNervesEvent)({
|
|
85
|
+
component: "daemon",
|
|
86
|
+
event: "daemon.crontab_deps_created",
|
|
87
|
+
message: "created real crontab deps",
|
|
88
|
+
meta: {},
|
|
89
|
+
});
|
|
90
|
+
/* v8 ignore start -- crontab exec closures: calling these in tests would modify the real system crontab @preserve */
|
|
91
|
+
return {
|
|
92
|
+
execOutput: (cmd) => (0, child_process_1.execSync)(cmd, { encoding: "utf-8" }),
|
|
93
|
+
execWrite: (cmd, stdin) => {
|
|
94
|
+
(0, child_process_1.execSync)(cmd, { input: stdin, stdio: ["pipe", "ignore", "ignore"] });
|
|
95
|
+
},
|
|
96
|
+
};
|
|
97
|
+
/* v8 ignore stop */
|
|
98
|
+
}
|
|
99
|
+
/* v8 ignore start -- ouro path resolution: probes process.argv, filesystem layout, and PATH; branches depend on install method and runtime environment @preserve */
|
|
100
|
+
function resolveOuroBinaryPath() {
|
|
101
|
+
// Try to resolve from process.argv[1] — the script being run
|
|
102
|
+
const scriptPath = process.argv[1];
|
|
103
|
+
if (scriptPath) {
|
|
104
|
+
// If running via node dist/heart/daemon/daemon-entry.js, resolve the ouro wrapper
|
|
105
|
+
// The ouro binary is typically at the package root's bin
|
|
106
|
+
const distDir = path.resolve(path.dirname(scriptPath));
|
|
107
|
+
const packageBin = path.resolve(distDir, "..", "..", "..", "node_modules", ".bin", "ouro");
|
|
108
|
+
if (fs.existsSync(packageBin)) {
|
|
109
|
+
return packageBin;
|
|
110
|
+
}
|
|
111
|
+
// Try the repo-local scripts/ouro.sh
|
|
112
|
+
const repoOuro = path.resolve(distDir, "..", "..", "..", "scripts", "ouro.sh");
|
|
113
|
+
if (fs.existsSync(repoOuro)) {
|
|
114
|
+
return repoOuro;
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
// Try which ouro
|
|
118
|
+
try {
|
|
119
|
+
const result = (0, child_process_1.execSync)("which ouro", { encoding: "utf-8" }).trim();
|
|
120
|
+
if (result.length > 0)
|
|
121
|
+
return result;
|
|
122
|
+
}
|
|
123
|
+
catch {
|
|
124
|
+
/* not on PATH */
|
|
125
|
+
}
|
|
126
|
+
// Fallback: use "ouro" and rely on PATH
|
|
127
|
+
(0, runtime_1.emitNervesEvent)({
|
|
128
|
+
component: "daemon",
|
|
129
|
+
event: "daemon.ouro_path_fallback",
|
|
130
|
+
message: "could not resolve full ouro binary path, falling back to 'ouro'",
|
|
131
|
+
meta: {},
|
|
132
|
+
});
|
|
133
|
+
return "ouro";
|
|
134
|
+
}
|
|
135
|
+
/* v8 ignore stop */
|
|
@@ -43,6 +43,7 @@ exports.crontabLine = crontabLine;
|
|
|
43
43
|
const os = __importStar(require("os"));
|
|
44
44
|
const runtime_1 = require("../../nerves/runtime");
|
|
45
45
|
const PLIST_PREFIX = "bot.ouro.";
|
|
46
|
+
const DAEMON_PLIST_FILENAME = "bot.ouro.daemon.plist";
|
|
46
47
|
function plistLabel(job) {
|
|
47
48
|
return `${PLIST_PREFIX}${job.agent}.${job.taskId}`;
|
|
48
49
|
}
|
|
@@ -80,7 +81,7 @@ function scheduleToCalendarInterval(schedule) {
|
|
|
80
81
|
result.Month = parseInt(month, 10);
|
|
81
82
|
return Object.keys(result).length > 0 ? result : null;
|
|
82
83
|
}
|
|
83
|
-
function generatePlistXml(job) {
|
|
84
|
+
function generatePlistXml(job, envPath) {
|
|
84
85
|
const label = plistLabel(job);
|
|
85
86
|
const seconds = cadenceToSeconds(job.schedule);
|
|
86
87
|
const calendar = seconds === null ? scheduleToCalendarInterval(job.schedule) : null;
|
|
@@ -97,7 +98,7 @@ function generatePlistXml(job) {
|
|
|
97
98
|
else {
|
|
98
99
|
triggerXml = ` <key>StartInterval</key>\n <integer>1800</integer>`;
|
|
99
100
|
}
|
|
100
|
-
|
|
101
|
+
const lines = [
|
|
101
102
|
`<?xml version="1.0" encoding="UTF-8"?>`,
|
|
102
103
|
`<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">`,
|
|
103
104
|
`<plist version="1.0">`,
|
|
@@ -110,14 +111,12 @@ function generatePlistXml(job) {
|
|
|
110
111
|
...job.command.split(" ").slice(1).map((arg) => ` <string>${arg}</string>`),
|
|
111
112
|
` </array>`,
|
|
112
113
|
triggerXml,
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
` <key>
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
``,
|
|
120
|
-
].join("\n");
|
|
114
|
+
];
|
|
115
|
+
if (envPath) {
|
|
116
|
+
lines.push(` <key>EnvironmentVariables</key>`, ` <dict>`, ` <key>PATH</key>`, ` <string>${envPath}</string>`, ` </dict>`);
|
|
117
|
+
}
|
|
118
|
+
lines.push(` <key>StandardOutPath</key>`, ` <string>/tmp/${label}.stdout.log</string>`, ` <key>StandardErrorPath</key>`, ` <string>/tmp/${label}.stderr.log</string>`, `</dict>`, `</plist>`, ``);
|
|
119
|
+
return lines.join("\n");
|
|
121
120
|
}
|
|
122
121
|
class LaunchdCronManager {
|
|
123
122
|
deps;
|
|
@@ -148,7 +147,7 @@ class LaunchdCronManager {
|
|
|
148
147
|
const label = plistLabel(job);
|
|
149
148
|
const filename = `${label}.plist`;
|
|
150
149
|
const fullPath = `${this.launchAgentsDir}/${filename}`;
|
|
151
|
-
const xml = generatePlistXml(job);
|
|
150
|
+
const xml = generatePlistXml(job, this.deps.envPath);
|
|
152
151
|
try {
|
|
153
152
|
this.deps.exec(`launchctl unload "${fullPath}"`);
|
|
154
153
|
}
|
|
@@ -178,7 +177,9 @@ class LaunchdCronManager {
|
|
|
178
177
|
listPlistFiles() {
|
|
179
178
|
if (!this.deps.existsFile(this.launchAgentsDir))
|
|
180
179
|
return [];
|
|
181
|
-
return this.deps.listDir(this.launchAgentsDir).filter((f) => f.startsWith(PLIST_PREFIX) &&
|
|
180
|
+
return this.deps.listDir(this.launchAgentsDir).filter((f) => f.startsWith(PLIST_PREFIX) &&
|
|
181
|
+
f.endsWith(".plist") &&
|
|
182
|
+
f !== DAEMON_PLIST_FILENAME);
|
|
182
183
|
}
|
|
183
184
|
}
|
|
184
185
|
exports.LaunchdCronManager = LaunchdCronManager;
|
|
@@ -248,6 +249,7 @@ function createOsCronManager(options = {}) {
|
|
|
248
249
|
listDir: () => [],
|
|
249
250
|
mkdirp: () => { },
|
|
250
251
|
homeDir: os.homedir(),
|
|
252
|
+
envPath: process.env.PATH ?? "",
|
|
251
253
|
};
|
|
252
254
|
/* v8 ignore stop */
|
|
253
255
|
return new LaunchdCronManager(deps);
|
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
4
4
|
const runtime_1 = require("../../nerves/runtime");
|
|
5
5
|
const runtime_logging_1 = require("./runtime-logging");
|
|
6
|
-
const ouro_bot_wrapper_1 = require("
|
|
6
|
+
const ouro_bot_wrapper_1 = require("../versioning/ouro-bot-wrapper");
|
|
7
7
|
(0, runtime_logging_1.configureDaemonRuntimeLogger)("ouro-bot");
|
|
8
8
|
(0, runtime_1.emitNervesEvent)({
|
|
9
9
|
component: "daemon",
|
|
@@ -12,12 +12,14 @@ const ouro_bot_wrapper_1 = require("./ouro-bot-wrapper");
|
|
|
12
12
|
meta: { args: process.argv.slice(2) },
|
|
13
13
|
});
|
|
14
14
|
void (0, ouro_bot_wrapper_1.runOuroBotWrapper)(process.argv.slice(2)).catch((error) => {
|
|
15
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16
|
+
process.stderr.write(`${message}\n`);
|
|
15
17
|
(0, runtime_1.emitNervesEvent)({
|
|
16
18
|
level: "error",
|
|
17
19
|
component: "daemon",
|
|
18
20
|
event: "daemon.ouro_bot_entry_error",
|
|
19
21
|
message: "ouro.bot wrapper entrypoint failed",
|
|
20
|
-
meta: { error:
|
|
22
|
+
meta: { error: message },
|
|
21
23
|
});
|
|
22
24
|
process.exit(1);
|
|
23
25
|
});
|
|
@@ -12,12 +12,14 @@ const runtime_logging_1 = require("./runtime-logging");
|
|
|
12
12
|
meta: { args: process.argv.slice(2) },
|
|
13
13
|
});
|
|
14
14
|
void (0, daemon_cli_1.runOuroCli)(process.argv.slice(2)).catch((error) => {
|
|
15
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
16
|
+
process.stderr.write(`${message}\n`);
|
|
15
17
|
(0, runtime_1.emitNervesEvent)({
|
|
16
18
|
level: "error",
|
|
17
19
|
component: "daemon",
|
|
18
20
|
event: "daemon.cli_entry_error",
|
|
19
21
|
message: "ouro CLI entrypoint failed",
|
|
20
|
-
meta: { error:
|
|
22
|
+
meta: { error: message },
|
|
21
23
|
});
|
|
22
24
|
process.exit(1);
|
|
23
25
|
});
|
|
@@ -0,0 +1,432 @@
|
|
|
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.derivePluginIdFromSource = derivePluginIdFromSource;
|
|
37
|
+
exports.executePluginInstall = executePluginInstall;
|
|
38
|
+
exports.executePluginList = executePluginList;
|
|
39
|
+
exports.executePluginRemove = executePluginRemove;
|
|
40
|
+
const child_process_1 = require("child_process");
|
|
41
|
+
const fs = __importStar(require("fs"));
|
|
42
|
+
const path = __importStar(require("path"));
|
|
43
|
+
const identity_1 = require("../identity");
|
|
44
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
45
|
+
const ouro_version_manager_1 = require("../versioning/ouro-version-manager");
|
|
46
|
+
function getPluginsRootDir() {
|
|
47
|
+
return path.join((0, ouro_version_manager_1.getOuroCliHome)(), "plugins");
|
|
48
|
+
}
|
|
49
|
+
// ── agent.json plugin-list helpers ───────────────────────────────────────────
|
|
50
|
+
//
|
|
51
|
+
// Each agent's bundle (~/AgentBundles/<name>.ouro/agent.json) declares a
|
|
52
|
+
// `plugins[]` array of PluginConfig entries. `--agent <name>` flags on
|
|
53
|
+
// `ouro plugin install / list / remove` operate on that array. This is the
|
|
54
|
+
// ouro-side per-agent enable mechanism; it lives in the consuming agent's
|
|
55
|
+
// bundle, NOT in the plugin's manifest, which stays portable across the
|
|
56
|
+
// universal Claude Code / Copilot CLI spec.
|
|
57
|
+
//
|
|
58
|
+
// Atomic-write note: codebase pattern is plain `fs.writeFileSync(file, JSON
|
|
59
|
+
// + "\n")`. Daemon writes to agent.json are already racy with other handlers,
|
|
60
|
+
// so we match the existing pattern. A future `writeAgentConfig` atomic helper
|
|
61
|
+
// would benefit ~3 callsites; deferred.
|
|
62
|
+
function getAgentJsonPath(agentName) {
|
|
63
|
+
return path.join((0, identity_1.getAgentRoot)(agentName), "agent.json");
|
|
64
|
+
}
|
|
65
|
+
function readAgentJsonOrThrow(agentName) {
|
|
66
|
+
const jsonPath = getAgentJsonPath(agentName);
|
|
67
|
+
if (!fs.existsSync(jsonPath)) {
|
|
68
|
+
throw new Error(`Agent '${agentName}' bundle not found at ${path.dirname(jsonPath)}. Bundle must exist before installing a plugin for it.`);
|
|
69
|
+
}
|
|
70
|
+
const raw = JSON.parse(fs.readFileSync(jsonPath, "utf-8"));
|
|
71
|
+
return { raw, path: jsonPath };
|
|
72
|
+
}
|
|
73
|
+
function writeAgentJson(jsonPath, raw) {
|
|
74
|
+
fs.writeFileSync(jsonPath, JSON.stringify(raw, null, 2) + "\n", "utf-8");
|
|
75
|
+
}
|
|
76
|
+
function readAgentPluginsList(agentName) {
|
|
77
|
+
try {
|
|
78
|
+
const { raw } = readAgentJsonOrThrow(agentName);
|
|
79
|
+
return Array.isArray(raw.plugins) ? raw.plugins : [];
|
|
80
|
+
}
|
|
81
|
+
catch {
|
|
82
|
+
return [];
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
function addPluginToAgent(agentName, entry) {
|
|
86
|
+
const { raw, path: jsonPath } = readAgentJsonOrThrow(agentName);
|
|
87
|
+
const existing = Array.isArray(raw.plugins) ? raw.plugins : [];
|
|
88
|
+
if (existing.some((p) => p.id === entry.id)) {
|
|
89
|
+
return { added: false, agentJsonPath: jsonPath };
|
|
90
|
+
}
|
|
91
|
+
raw.plugins = [...existing, entry];
|
|
92
|
+
writeAgentJson(jsonPath, raw);
|
|
93
|
+
return { added: true, agentJsonPath: jsonPath };
|
|
94
|
+
}
|
|
95
|
+
function removePluginFromAgent(agentName, pluginId) {
|
|
96
|
+
const { raw, path: jsonPath } = readAgentJsonOrThrow(agentName);
|
|
97
|
+
const existing = Array.isArray(raw.plugins) ? raw.plugins : [];
|
|
98
|
+
const next = existing.filter((p) => p.id !== pluginId);
|
|
99
|
+
if (next.length === existing.length) {
|
|
100
|
+
return { removed: false, agentJsonPath: jsonPath };
|
|
101
|
+
}
|
|
102
|
+
raw.plugins = next;
|
|
103
|
+
writeAgentJson(jsonPath, raw);
|
|
104
|
+
return { removed: true, agentJsonPath: jsonPath };
|
|
105
|
+
}
|
|
106
|
+
function listAgentsReferencingPlugin(pluginId) {
|
|
107
|
+
const bundlesRoot = (0, identity_1.getAgentBundlesRoot)();
|
|
108
|
+
if (!fs.existsSync(bundlesRoot))
|
|
109
|
+
return [];
|
|
110
|
+
const agents = [];
|
|
111
|
+
for (const entry of fs.readdirSync(bundlesRoot)) {
|
|
112
|
+
if (!entry.endsWith(".ouro"))
|
|
113
|
+
continue;
|
|
114
|
+
const agentName = entry.slice(0, -".ouro".length);
|
|
115
|
+
if (readAgentPluginsList(agentName).some((p) => p.id === pluginId)) {
|
|
116
|
+
agents.push(agentName);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
return agents.sort();
|
|
120
|
+
}
|
|
121
|
+
function derivePluginIdFromSource(source) {
|
|
122
|
+
// Accepts:
|
|
123
|
+
// github:org/repo:plugins/<id>
|
|
124
|
+
// github:org/repo:path/to/<id>
|
|
125
|
+
// https://github.com/org/repo[.git]
|
|
126
|
+
// local:/abs/path/to/<id>
|
|
127
|
+
// /abs/path/to/<id>
|
|
128
|
+
// Returns the trailing path segment as the plugin id.
|
|
129
|
+
const cleaned = source
|
|
130
|
+
.replace(/^github:[^:]+:/, "")
|
|
131
|
+
.replace(/^https?:\/\/[^/]+\//, "")
|
|
132
|
+
.replace(/^local:/, "")
|
|
133
|
+
.replace(/\.git$/, "")
|
|
134
|
+
.replace(/\/$/, "");
|
|
135
|
+
const segments = cleaned.split("/").filter(Boolean);
|
|
136
|
+
const last = segments[segments.length - 1];
|
|
137
|
+
if (!last) {
|
|
138
|
+
throw new Error(`Could not derive plugin id from source: ${source}`);
|
|
139
|
+
}
|
|
140
|
+
if (!/^[a-z0-9][a-z0-9-]*$/i.test(last)) {
|
|
141
|
+
throw new Error(`Derived plugin id '${last}' is not a valid name (alphanumeric + dashes only)`);
|
|
142
|
+
}
|
|
143
|
+
return last;
|
|
144
|
+
}
|
|
145
|
+
function buildPluginCloneUrl(source) {
|
|
146
|
+
if (source.startsWith("github:")) {
|
|
147
|
+
const match = source.match(/^github:([^/]+)\/([^:]+)(?::(.*))?$/);
|
|
148
|
+
if (!match) {
|
|
149
|
+
throw new Error(`Invalid github: source: ${source}`);
|
|
150
|
+
}
|
|
151
|
+
const [, org, repo] = match;
|
|
152
|
+
return `https://github.com/${org}/${repo}.git`;
|
|
153
|
+
}
|
|
154
|
+
if (source.startsWith("local:")) {
|
|
155
|
+
return source.replace(/^local:/, "");
|
|
156
|
+
}
|
|
157
|
+
return source;
|
|
158
|
+
}
|
|
159
|
+
function buildPluginSubpath(source) {
|
|
160
|
+
const match = source.match(/^github:[^/]+\/[^:]+:(.+)$/);
|
|
161
|
+
if (match)
|
|
162
|
+
return match[1];
|
|
163
|
+
return null;
|
|
164
|
+
}
|
|
165
|
+
async function executePluginInstall(command, deps) {
|
|
166
|
+
const { source } = command;
|
|
167
|
+
const pluginsRoot = getPluginsRootDir();
|
|
168
|
+
const pluginId = derivePluginIdFromSource(source);
|
|
169
|
+
const installDir = path.join(pluginsRoot, pluginId);
|
|
170
|
+
(0, runtime_1.emitNervesEvent)({
|
|
171
|
+
component: "daemon",
|
|
172
|
+
event: "daemon.plugin_install_start",
|
|
173
|
+
message: "installing plugin",
|
|
174
|
+
meta: { source, pluginId, installDir },
|
|
175
|
+
});
|
|
176
|
+
if (fs.existsSync(installDir)) {
|
|
177
|
+
const message = `Plugin '${pluginId}' is already installed at ${installDir}. Run 'ouro plugin remove ${pluginId}' first to reinstall.`;
|
|
178
|
+
deps.writeStdout(message);
|
|
179
|
+
(0, runtime_1.emitNervesEvent)({
|
|
180
|
+
level: "error",
|
|
181
|
+
component: "daemon",
|
|
182
|
+
event: "daemon.plugin_install_error",
|
|
183
|
+
message: "plugin already installed",
|
|
184
|
+
meta: { source, pluginId, installDir },
|
|
185
|
+
});
|
|
186
|
+
return message;
|
|
187
|
+
}
|
|
188
|
+
fs.mkdirSync(pluginsRoot, { recursive: true });
|
|
189
|
+
const cloneUrl = buildPluginCloneUrl(source);
|
|
190
|
+
const subpath = buildPluginSubpath(source);
|
|
191
|
+
try {
|
|
192
|
+
if (subpath) {
|
|
193
|
+
const tmpClone = path.join(pluginsRoot, `.${pluginId}.clone-${Date.now()}`);
|
|
194
|
+
(0, child_process_1.execFileSync)("git", ["clone", "--depth", "1", cloneUrl, tmpClone], { stdio: "pipe" });
|
|
195
|
+
const subpathInClone = path.join(tmpClone, subpath);
|
|
196
|
+
if (!fs.existsSync(subpathInClone)) {
|
|
197
|
+
fs.rmSync(tmpClone, { recursive: true, force: true });
|
|
198
|
+
throw new Error(`Subpath '${subpath}' not found in cloned repo`);
|
|
199
|
+
}
|
|
200
|
+
fs.renameSync(subpathInClone, installDir);
|
|
201
|
+
fs.rmSync(tmpClone, { recursive: true, force: true });
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
(0, child_process_1.execFileSync)("git", ["clone", "--depth", "1", cloneUrl, installDir], { stdio: "pipe" });
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
catch (e) {
|
|
208
|
+
const errMessage = e instanceof Error ? e.message : String(e);
|
|
209
|
+
(0, runtime_1.emitNervesEvent)({
|
|
210
|
+
level: "error",
|
|
211
|
+
component: "daemon",
|
|
212
|
+
event: "daemon.plugin_install_error",
|
|
213
|
+
message: "plugin clone failed",
|
|
214
|
+
meta: { source, pluginId, error: errMessage },
|
|
215
|
+
});
|
|
216
|
+
if (fs.existsSync(installDir)) {
|
|
217
|
+
fs.rmSync(installDir, { recursive: true, force: true });
|
|
218
|
+
}
|
|
219
|
+
const message = `Plugin install failed: ${errMessage}`;
|
|
220
|
+
deps.writeStdout(message);
|
|
221
|
+
return message;
|
|
222
|
+
}
|
|
223
|
+
const pluginJson = path.join(installDir, ".claude-plugin", "plugin.json");
|
|
224
|
+
if (!fs.existsSync(pluginJson)) {
|
|
225
|
+
fs.rmSync(installDir, { recursive: true, force: true });
|
|
226
|
+
const message = `Plugin install failed: .claude-plugin/plugin.json missing in ${installDir}. Rolled back.`;
|
|
227
|
+
deps.writeStdout(message);
|
|
228
|
+
(0, runtime_1.emitNervesEvent)({
|
|
229
|
+
level: "error",
|
|
230
|
+
component: "daemon",
|
|
231
|
+
event: "daemon.plugin_install_error",
|
|
232
|
+
message: "plugin manifest missing",
|
|
233
|
+
meta: { source, pluginId, expectedManifest: pluginJson },
|
|
234
|
+
});
|
|
235
|
+
return message;
|
|
236
|
+
}
|
|
237
|
+
// Wire the plugin entry into the agent's agent.json plugins[] when
|
|
238
|
+
// --agent was passed.
|
|
239
|
+
let agentEnableMessage = null;
|
|
240
|
+
if (command.agent) {
|
|
241
|
+
try {
|
|
242
|
+
const entry = {
|
|
243
|
+
id: pluginId,
|
|
244
|
+
enabled: true,
|
|
245
|
+
/* v8 ignore next -- command.source is a required field; falsy branch unreachable */
|
|
246
|
+
...(command.source ? { source: command.source } : {}),
|
|
247
|
+
...(command.version ? { version: command.version } : {}),
|
|
248
|
+
};
|
|
249
|
+
const result = addPluginToAgent(command.agent, entry);
|
|
250
|
+
agentEnableMessage = result.added
|
|
251
|
+
? `Enabled plugin '${pluginId}' for agent '${command.agent}' (updated ${result.agentJsonPath}).`
|
|
252
|
+
: `Plugin '${pluginId}' was already enabled for agent '${command.agent}'.`;
|
|
253
|
+
(0, runtime_1.emitNervesEvent)({
|
|
254
|
+
component: "daemon",
|
|
255
|
+
event: result.added
|
|
256
|
+
? "daemon.plugin_agent_enable_end"
|
|
257
|
+
: "daemon.plugin_agent_enable_noop",
|
|
258
|
+
message: result.added
|
|
259
|
+
? "plugin enabled for agent"
|
|
260
|
+
: "plugin already enabled for agent",
|
|
261
|
+
meta: { pluginId, agent: command.agent, agentJsonPath: result.agentJsonPath },
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
catch (e) {
|
|
265
|
+
/* v8 ignore start -- defensive: readAgentJsonOrThrow only throws Error */
|
|
266
|
+
const errMessage = e instanceof Error ? e.message : String(e);
|
|
267
|
+
/* v8 ignore stop */
|
|
268
|
+
agentEnableMessage = `Plugin installed on disk, but enabling for agent '${command.agent}' failed: ${errMessage}`;
|
|
269
|
+
(0, runtime_1.emitNervesEvent)({
|
|
270
|
+
level: "error",
|
|
271
|
+
component: "daemon",
|
|
272
|
+
event: "daemon.plugin_agent_enable_error",
|
|
273
|
+
message: "agent enable failed; plugin still installed on disk",
|
|
274
|
+
meta: { pluginId, agent: command.agent, error: errMessage },
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
(0, runtime_1.emitNervesEvent)({
|
|
279
|
+
component: "daemon",
|
|
280
|
+
event: "daemon.plugin_install_end",
|
|
281
|
+
message: "plugin installed",
|
|
282
|
+
meta: { source, pluginId, installDir, agent: command.agent },
|
|
283
|
+
});
|
|
284
|
+
const baseMessage = `Plugin '${pluginId}' installed at ${installDir}. Run 'ouro up' to activate.`;
|
|
285
|
+
const message = agentEnableMessage ? `${baseMessage}\n${agentEnableMessage}` : baseMessage;
|
|
286
|
+
deps.writeStdout(message);
|
|
287
|
+
return message;
|
|
288
|
+
}
|
|
289
|
+
async function executePluginList(command, deps) {
|
|
290
|
+
const pluginsRoot = getPluginsRootDir();
|
|
291
|
+
(0, runtime_1.emitNervesEvent)({
|
|
292
|
+
component: "daemon",
|
|
293
|
+
event: "daemon.plugin_list_start",
|
|
294
|
+
message: "listing plugins",
|
|
295
|
+
meta: { pluginsRoot, agent: command.agent },
|
|
296
|
+
});
|
|
297
|
+
if (!fs.existsSync(pluginsRoot)) {
|
|
298
|
+
const message = "No plugins installed.";
|
|
299
|
+
deps.writeStdout(message);
|
|
300
|
+
(0, runtime_1.emitNervesEvent)({
|
|
301
|
+
component: "daemon",
|
|
302
|
+
event: "daemon.plugin_list_end",
|
|
303
|
+
message: "no plugins root",
|
|
304
|
+
meta: { count: 0 },
|
|
305
|
+
});
|
|
306
|
+
return message;
|
|
307
|
+
}
|
|
308
|
+
let entries = fs
|
|
309
|
+
.readdirSync(pluginsRoot)
|
|
310
|
+
.filter((name) => {
|
|
311
|
+
try {
|
|
312
|
+
return (fs.statSync(path.join(pluginsRoot, name)).isDirectory() &&
|
|
313
|
+
!name.startsWith("."));
|
|
314
|
+
}
|
|
315
|
+
catch {
|
|
316
|
+
return false;
|
|
317
|
+
}
|
|
318
|
+
})
|
|
319
|
+
.sort();
|
|
320
|
+
// With --agent X, filter to plugins enabled for X (intersect installed-on-disk
|
|
321
|
+
// with X's agent.json plugins[]). Without --agent, list all installed.
|
|
322
|
+
if (command.agent) {
|
|
323
|
+
const agentPlugins = readAgentPluginsList(command.agent);
|
|
324
|
+
const enabledIds = new Set(agentPlugins.filter((p) => p.enabled).map((p) => p.id));
|
|
325
|
+
entries = entries.filter((id) => enabledIds.has(id));
|
|
326
|
+
if (entries.length === 0) {
|
|
327
|
+
const message = `No plugins enabled for agent '${command.agent}'.`;
|
|
328
|
+
deps.writeStdout(message);
|
|
329
|
+
return message;
|
|
330
|
+
}
|
|
331
|
+
const message = `Plugins enabled for agent '${command.agent}' (${entries.length}):\n` +
|
|
332
|
+
entries.map((id) => ` - ${id}`).join("\n");
|
|
333
|
+
deps.writeStdout(message);
|
|
334
|
+
return message;
|
|
335
|
+
}
|
|
336
|
+
if (entries.length === 0) {
|
|
337
|
+
const message = "No plugins installed.";
|
|
338
|
+
deps.writeStdout(message);
|
|
339
|
+
return message;
|
|
340
|
+
}
|
|
341
|
+
const message = `Installed plugins (${entries.length}):\n` +
|
|
342
|
+
entries.map((id) => ` - ${id}`).join("\n");
|
|
343
|
+
deps.writeStdout(message);
|
|
344
|
+
(0, runtime_1.emitNervesEvent)({
|
|
345
|
+
component: "daemon",
|
|
346
|
+
event: "daemon.plugin_list_end",
|
|
347
|
+
message: "listed plugins",
|
|
348
|
+
meta: { count: entries.length },
|
|
349
|
+
});
|
|
350
|
+
return message;
|
|
351
|
+
}
|
|
352
|
+
async function executePluginRemove(command, deps) {
|
|
353
|
+
const { pluginId, agent } = command;
|
|
354
|
+
const installDir = path.join(getPluginsRootDir(), pluginId);
|
|
355
|
+
(0, runtime_1.emitNervesEvent)({
|
|
356
|
+
component: "daemon",
|
|
357
|
+
event: "daemon.plugin_remove_start",
|
|
358
|
+
message: "removing plugin",
|
|
359
|
+
meta: { pluginId, installDir, agent },
|
|
360
|
+
});
|
|
361
|
+
// With --agent X: scoped to that agent's plugins[] only; never touches disk.
|
|
362
|
+
if (agent) {
|
|
363
|
+
try {
|
|
364
|
+
const { removed, agentJsonPath } = removePluginFromAgent(agent, pluginId);
|
|
365
|
+
const message = removed
|
|
366
|
+
? `Plugin '${pluginId}' disabled for agent '${agent}' (updated ${agentJsonPath}). Run 'ouro up' to apply.`
|
|
367
|
+
: `Plugin '${pluginId}' was not enabled for agent '${agent}'.`;
|
|
368
|
+
deps.writeStdout(message);
|
|
369
|
+
(0, runtime_1.emitNervesEvent)({
|
|
370
|
+
component: "daemon",
|
|
371
|
+
event: "daemon.plugin_remove_end",
|
|
372
|
+
message: removed ? "plugin disabled for agent" : "plugin was not enabled for agent",
|
|
373
|
+
meta: { pluginId, agent, agentJsonPath, removed },
|
|
374
|
+
});
|
|
375
|
+
return message;
|
|
376
|
+
}
|
|
377
|
+
catch (e) {
|
|
378
|
+
/* v8 ignore start -- defensive: removePluginFromAgent only throws Error */
|
|
379
|
+
const errMessage = e instanceof Error ? e.message : String(e);
|
|
380
|
+
/* v8 ignore stop */
|
|
381
|
+
const message = `Plugin remove failed for agent '${agent}': ${errMessage}`;
|
|
382
|
+
deps.writeStdout(message);
|
|
383
|
+
(0, runtime_1.emitNervesEvent)({
|
|
384
|
+
level: "error",
|
|
385
|
+
component: "daemon",
|
|
386
|
+
event: "daemon.plugin_remove_error",
|
|
387
|
+
message: "agent remove failed",
|
|
388
|
+
meta: { pluginId, agent, error: errMessage },
|
|
389
|
+
});
|
|
390
|
+
return message;
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
// Without --agent: machine-wide remove. Refuse if any agent's plugins[]
|
|
394
|
+
// still references this plugin (silent removal would break those agents
|
|
395
|
+
// on next `ouro up`).
|
|
396
|
+
const refs = listAgentsReferencingPlugin(pluginId);
|
|
397
|
+
if (refs.length > 0) {
|
|
398
|
+
const message = `Cannot remove plugin '${pluginId}': still enabled for: ${refs.join(", ")}.\n` +
|
|
399
|
+
`Disable per-agent first with 'ouro plugin remove ${pluginId} --agent <name>', then re-run.`;
|
|
400
|
+
deps.writeStdout(message);
|
|
401
|
+
(0, runtime_1.emitNervesEvent)({
|
|
402
|
+
level: "error",
|
|
403
|
+
component: "daemon",
|
|
404
|
+
event: "daemon.plugin_remove_error",
|
|
405
|
+
message: "plugin still referenced by agents",
|
|
406
|
+
meta: { pluginId, refs },
|
|
407
|
+
});
|
|
408
|
+
return message;
|
|
409
|
+
}
|
|
410
|
+
if (!fs.existsSync(installDir)) {
|
|
411
|
+
const message = `Plugin '${pluginId}' is not installed at ${installDir}.`;
|
|
412
|
+
deps.writeStdout(message);
|
|
413
|
+
(0, runtime_1.emitNervesEvent)({
|
|
414
|
+
level: "error",
|
|
415
|
+
component: "daemon",
|
|
416
|
+
event: "daemon.plugin_remove_error",
|
|
417
|
+
message: "plugin not installed",
|
|
418
|
+
meta: { pluginId, installDir },
|
|
419
|
+
});
|
|
420
|
+
return message;
|
|
421
|
+
}
|
|
422
|
+
fs.rmSync(installDir, { recursive: true, force: true });
|
|
423
|
+
(0, runtime_1.emitNervesEvent)({
|
|
424
|
+
component: "daemon",
|
|
425
|
+
event: "daemon.plugin_remove_end",
|
|
426
|
+
message: "plugin removed",
|
|
427
|
+
meta: { pluginId, installDir },
|
|
428
|
+
});
|
|
429
|
+
const message = `Plugin '${pluginId}' removed from ${installDir}. Run 'ouro up' to deactivate.`;
|
|
430
|
+
deps.writeStdout(message);
|
|
431
|
+
return message;
|
|
432
|
+
}
|