@ouro.bot/cli 0.1.0-alpha.83 → 0.1.0-alpha.831
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/LICENSE +21 -0
- package/README.md +154 -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/assets/bluebubbles-host +264 -0
- package/assets/sanctuary-host-launcher.sh +16 -0
- package/changelog.json +5308 -16
- package/deploy/unraid/Dockerfile +54 -0
- package/deploy/unraid/README.txt +2983 -0
- package/deploy/unraid/audit-container-spec.sh +4 -0
- package/deploy/unraid/container-runtime.json +1 -0
- package/deploy/unraid/docker-man-template-transaction.mjs +711 -0
- package/deploy/unraid/docker-man-template-xml.cjs +105 -0
- package/deploy/unraid/migrate-sanctuary-bundle.mjs +60 -0
- package/deploy/unraid/ouro-events/bootstrap-spool.sh +92 -0
- package/deploy/unraid/ouro-events/emit-event.mjs +310 -0
- package/deploy/unraid/ouro-events/emit-usenet-event.sh +54 -0
- package/deploy/unraid/ouro-events/install-usenet-guard.sh +435 -0
- package/deploy/unraid/ouro-events/usenet-health.sh +176 -0
- package/deploy/unraid/sanctuary-acceptance-adapter.sh +43 -0
- package/deploy/unraid/sanctuary-acceptance-contract.json +198 -0
- package/deploy/unraid/sanctuary-acceptance-harness.sh +23 -0
- package/deploy/unraid/sanctuary-authority-installation.json +36 -0
- package/deploy/unraid/sanctuary-authority-service.sh +30 -0
- package/deploy/unraid/sanctuary-deployment-target.mjs +710 -0
- package/deploy/unraid/sanctuary-safe-rename.py +24 -0
- package/deploy/unraid/sanctuary-unit16-host-broker.mjs +2084 -0
- package/deploy/unraid/sanctuary-unit16-run.sh +560 -0
- package/deploy/unraid/sanctuary-unit18-target-audit.sh +27 -0
- package/deploy/unraid/sanctuary.ouro/agent.json +66 -0
- package/deploy/unraid/sanctuary.ouro/arc/README.md +3 -0
- package/deploy/unraid/sanctuary.ouro/bundle-meta.json +5 -0
- package/deploy/unraid/sanctuary.ouro/habits/sanctuary-health.md +8 -0
- package/deploy/unraid/sanctuary.ouro/mcp/media-mcp.mjs +795 -0
- package/deploy/unraid/sanctuary.ouro/provider-readiness.json +11 -0
- package/deploy/unraid/sanctuary.ouro/psyche/ASPIRATIONS.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/IDENTITY.md +5 -0
- package/deploy/unraid/sanctuary.ouro/psyche/LORE.md +15 -0
- package/deploy/unraid/sanctuary.ouro/psyche/SOUL.md +25 -0
- package/deploy/unraid/sanctuary.ouro/psyche/TACIT.md +15 -0
- package/deploy/unraid/sanctuary.ouro/state/policy/steward.json +7 -0
- package/deploy/unraid/sanctuary.ouro/tool-profiles.json +135 -0
- package/deploy/unraid/sanctuary.xml +28 -0
- package/dist/a2a/card.js +57 -0
- package/dist/a2a/client.js +180 -0
- package/dist/a2a/config.js +50 -0
- package/dist/a2a/delegation-stores.js +56 -0
- package/dist/a2a/did-resolution.js +93 -0
- package/dist/a2a/identity.js +170 -0
- package/dist/a2a/inbound-share.js +107 -0
- package/dist/a2a/mission-result-wire.js +196 -0
- package/dist/a2a/onboarding.js +115 -0
- package/dist/a2a/pin-store.js +132 -0
- package/dist/a2a/seen-ledger.js +120 -0
- package/dist/a2a/server.js +604 -0
- package/dist/a2a/task-store.js +69 -0
- package/dist/a2a/transport.js +45 -0
- package/dist/a2a/types.js +3 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +360 -0
- package/dist/arc/episodes.js +118 -0
- package/dist/arc/evolution.js +490 -0
- package/dist/arc/flight-recorder.js +1034 -0
- package/dist/arc/intentions.js +134 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +386 -0
- package/dist/arc/packets.js +336 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +57 -0
- package/dist/commerce/store.js +755 -0
- package/dist/commerce/types.js +3 -0
- package/dist/heart/active-work.js +798 -40
- package/dist/heart/agent-entry.js +252 -3
- package/dist/heart/approval-files.js +113 -0
- package/dist/heart/approval-store.js +960 -0
- 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 +18 -0
- package/dist/heart/attachments/sources/telegram.js +71 -0
- package/dist/heart/attachments/store.js +132 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +495 -0
- package/dist/heart/autonomy-budget.js +478 -0
- package/dist/heart/awaiting/await-alert.js +148 -0
- package/dist/heart/awaiting/await-expiry.js +143 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +149 -0
- package/dist/heart/awaiting/await-runtime-state.js +111 -0
- package/dist/heart/awaiting/await-scheduler.js +382 -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 +44 -18
- package/dist/heart/config-registry.js +331 -0
- package/dist/heart/config.js +174 -131
- package/dist/heart/context-loss-gauntlet.js +387 -0
- package/dist/heart/context-loss-sentinel.js +1157 -0
- package/dist/heart/core.js +2169 -581
- package/dist/heart/cross-chat-delivery.js +9 -22
- package/dist/heart/daemon/agent-config-check.js +451 -0
- package/dist/heart/daemon/agent-discovery.js +185 -3
- package/dist/heart/daemon/agent-service.js +542 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/await-private-wake.js +59 -0
- package/dist/heart/daemon/bluebubbles-cli-integration.js +71 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/bluebubbles-host-protocol.js +433 -0
- package/dist/heart/daemon/bluebubbles-host.js +273 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +180 -0
- package/dist/heart/daemon/cli-defaults.js +854 -0
- package/dist/heart/daemon/cli-desk.js +322 -0
- package/dist/heart/daemon/cli-exec.js +8822 -0
- package/dist/heart/daemon/cli-help.js +716 -0
- package/dist/heart/daemon/cli-parse.js +2771 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +777 -0
- package/dist/heart/daemon/cli-types.js +8 -0
- package/dist/heart/daemon/connect-bay.js +323 -0
- package/dist/heart/daemon/container-credential-bootstrap.js +273 -0
- package/dist/heart/daemon/container-healthcheck.js +112 -0
- package/dist/heart/daemon/container-runtime.js +97 -0
- package/dist/heart/daemon/container-spec-auditor-main.js +171 -0
- package/dist/heart/daemon/container-spec-auditor.js +229 -0
- package/dist/heart/daemon/daemon-bootstrap-startup.js +115 -0
- package/dist/heart/daemon/daemon-cli.js +29 -2349
- package/dist/heart/daemon/daemon-entry.js +930 -11
- package/dist/heart/daemon/daemon-health.js +186 -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 +2084 -105
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +1755 -0
- package/dist/heart/daemon/freshness.js +345 -0
- package/dist/heart/daemon/habit-private-wake.js +61 -0
- package/dist/heart/daemon/health-monitor.js +142 -11
- package/dist/heart/daemon/hooks/agent-config-v2.js +33 -0
- package/dist/heart/daemon/hooks/bundle-meta.js +135 -1
- package/dist/heart/daemon/http-health-probe.js +80 -0
- package/dist/heart/daemon/human-command-screens.js +234 -0
- package/dist/heart/daemon/human-readiness.js +114 -0
- package/dist/heart/daemon/inner-status.js +78 -0
- package/dist/heart/daemon/interactive-repair.js +394 -0
- package/dist/heart/daemon/launchd.js +37 -8
- package/dist/heart/daemon/log-tailer.js +79 -10
- package/dist/heart/daemon/logs-prune.js +132 -0
- package/dist/heart/daemon/mcp-canary.js +524 -0
- package/dist/heart/daemon/message-router.js +65 -5
- 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 +22 -14
- 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 +733 -61
- package/dist/heart/daemon/provider-discovery.js +137 -0
- package/dist/heart/daemon/provider-ping-progress.js +83 -0
- package/dist/heart/daemon/prunable-bundle.js +144 -0
- package/dist/heart/daemon/pulse.js +511 -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 +47 -14
- package/dist/heart/daemon/runtime-metadata.js +2 -30
- package/dist/heart/daemon/runtime-mode.js +13 -2
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sanctuary-acceptance-adapter.js +2654 -0
- package/dist/heart/daemon/sanctuary-acceptance-harness.js +1830 -0
- package/dist/heart/daemon/sanctuary-acceptance-marker.js +267 -0
- package/dist/heart/daemon/sanctuary-acceptance-scenarios.js +955 -0
- package/dist/heart/daemon/sanctuary-authority-codec.js +86 -0
- package/dist/heart/daemon/sanctuary-authority-epoch.js +256 -0
- package/dist/heart/daemon/sanctuary-authority-installation.js +140 -0
- package/dist/heart/daemon/sanctuary-authority-ledger.js +241 -0
- package/dist/heart/daemon/sanctuary-authority-root-lifecycle.js +819 -0
- package/dist/heart/daemon/sanctuary-authority-vault-migration.js +79 -0
- package/dist/heart/daemon/sanctuary-bundle-migration.js +729 -0
- package/dist/heart/daemon/sanctuary-host-authority.js +1008 -0
- package/dist/heart/daemon/sanctuary-host-detached-supervisor.js +494 -0
- package/dist/heart/daemon/sanctuary-host-executor.js +670 -0
- package/dist/heart/daemon/sanctuary-host-linux-kernel.js +334 -0
- package/dist/heart/daemon/sanctuary-host-supervisor-entry.js +207 -0
- package/dist/heart/daemon/sanctuary-host-supervisor.js +95 -0
- package/dist/heart/daemon/sanctuary-package-management.js +103 -0
- package/dist/heart/daemon/sanctuary-scheduler-liveness.js +227 -0
- package/dist/heart/daemon/sanctuary-scheduler-origin.js +132 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-entry.js +445 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-gateway.js +585 -0
- package/dist/heart/daemon/sanctuary-telegram-authority-service.js +630 -0
- package/dist/heart/daemon/sense-manager.js +699 -48
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +1 -1
- package/dist/heart/daemon/socket-client.js +180 -12
- package/dist/heart/daemon/stale-bundle-prune.js +113 -0
- package/dist/heart/daemon/startup-tui.js +339 -0
- package/dist/heart/daemon/supercronic-supervisor.js +282 -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 +138 -54
- 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/external-events/router.js +1430 -0
- package/dist/heart/frontend-approval-runtime.js +506 -0
- package/dist/heart/frontend-journal.js +215 -0
- package/dist/heart/frontend-session-service.js +237 -0
- package/dist/heart/frontend-socket-client.js +164 -0
- package/dist/heart/frontend-socket.js +400 -0
- package/dist/heart/habits/habit-cancel.js +810 -0
- package/dist/heart/habits/habit-lifecycle.js +1327 -0
- package/dist/heart/habits/habit-migration.js +194 -0
- package/dist/heart/habits/habit-parser.js +278 -0
- package/dist/heart/habits/habit-runtime-state.js +93 -0
- package/dist/heart/habits/habit-scheduler.js +653 -0
- package/dist/heart/habits/habit-session-summary.js +318 -0
- package/dist/heart/habits/habit-session.js +636 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +55 -62
- 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 +53 -18
- package/dist/heart/identity.js +196 -59
- package/dist/heart/kept-notes.js +289 -0
- package/dist/heart/kicks.js +1 -1
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +356 -0
- package/dist/heart/mailbox/mailbox-http-hooks.js +98 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +398 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +129 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +39 -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 +428 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +329 -0
- package/dist/heart/mailbox/readers/mail.js +375 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +823 -0
- package/dist/heart/mailbox/readers/sessions.js +231 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +696 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +11 -0
- package/dist/heart/orientation-frame.js +345 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/primitives.js +1 -1
- package/dist/heart/private-runtime/decision-renderer.js +158 -0
- package/dist/heart/private-runtime/index.js +18 -0
- package/dist/heart/private-runtime/ledger.js +221 -0
- package/dist/heart/private-runtime/policy.js +252 -0
- package/dist/heart/private-runtime/types.js +2 -0
- package/dist/heart/progress-story.js +1 -1
- package/dist/heart/provider-attempt.js +137 -0
- package/dist/heart/provider-binding-resolver.js +273 -0
- package/dist/heart/provider-credentials.js +449 -0
- package/dist/heart/provider-failover.js +311 -0
- package/dist/heart/provider-models.js +96 -0
- package/dist/heart/provider-ping.js +265 -0
- package/dist/heart/provider-readiness-cache.js +119 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +173 -60
- package/dist/heart/providers/azure.js +23 -11
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +34 -38
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +26 -8
- package/dist/heart/providers/openai-codex-token.js +349 -0
- package/dist/heart/providers/openai-codex.js +55 -40
- package/dist/heart/providers/openai-compatible.js +177 -0
- package/dist/heart/run-ledger.js +247 -0
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +607 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +22 -4
- package/dist/heart/session-activity.js +92 -24
- package/dist/heart/session-events.js +1504 -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-redaction-repair-cli-main.js +31 -0
- package/dist/heart/session-redaction-repair.js +552 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +183 -0
- package/dist/heart/session-transcript.js +133 -0
- package/dist/heart/start-of-turn-packet.js +372 -0
- package/dist/heart/steward-policy.js +618 -0
- package/dist/heart/streaming.js +604 -207
- 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 +11 -7
- 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-approval.js +382 -0
- package/dist/heart/tool-description.js +155 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +482 -0
- package/dist/heart/turn-execution-lease.js +30 -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 +432 -0
- package/dist/heart/versioning/ouro-recovery-launcher.js +76 -0
- package/dist/heart/versioning/ouro-version-manager.js +409 -0
- package/dist/heart/{daemon → versioning}/staged-restart.js +40 -8
- package/dist/heart/{daemon → versioning}/update-checker.js +6 -1
- package/dist/heart/versioning/update-hooks.js +154 -0
- package/dist/heart/versioning/version-intent.js +114 -0
- package/dist/heart/work-card.js +380 -0
- package/dist/mailbox-ui/assets/index-Cyv4mw3Y.js +1 -0
- package/dist/mailbox-ui/assets/index-Du_9G9WO.css +1 -0
- package/dist/mailbox-ui/assets/vendor-CcN1XpQ9.js +61 -0
- package/dist/mailbox-ui/index.html +16 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +889 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/cache-sync-cli.js +58 -0
- package/dist/mailroom/core.js +803 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +568 -0
- package/dist/mailroom/hosted-cache-sync.js +384 -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 +292 -0
- package/dist/mailroom/search-cache.js +513 -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 +24 -2
- package/dist/mind/context.js +309 -111
- package/dist/mind/desk-section.js +362 -0
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +68 -77
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/{associative-recall.js → note-search.js} +47 -58
- package/dist/mind/obligation-steering.js +199 -3
- package/dist/mind/pending.js +36 -10
- package/dist/mind/prompt-budget.js +479 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1050 -189
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/record-paths.js +312 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/session-transaction.js +564 -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/coverage/run-artifacts.js +55 -35
- package/dist/nerves/coverage/source-scanner.js +4 -4
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +293 -9
- 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 +159 -0
- package/dist/nerves/runtime.js +17 -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 +1045 -0
- package/dist/repertoire/bundle-templates.js +71 -0
- package/dist/repertoire/bw-installer.js +180 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +331 -0
- package/dist/repertoire/coding/feedback.js +174 -32
- package/dist/repertoire/coding/index.js +15 -3
- package/dist/repertoire/coding/manager.js +159 -10
- package/dist/repertoire/coding/spawner.js +58 -11
- package/dist/repertoire/coding/tools.js +221 -15
- package/dist/repertoire/coding/workbench-client.js +272 -0
- package/dist/repertoire/coding/workbench-manager.js +346 -0
- 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 +811 -18
- package/dist/repertoire/mcp-client.js +44 -3
- package/dist/repertoire/mcp-manager.js +427 -139
- package/dist/repertoire/mcp-tools.js +124 -0
- package/dist/repertoire/plugin-mcp.js +175 -0
- package/dist/repertoire/plugins.js +253 -0
- package/dist/repertoire/relationship-authorization.js +322 -0
- package/dist/repertoire/shell-sessions.js +134 -0
- package/dist/repertoire/skills.js +48 -4
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tool-arguments.js +170 -0
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-a2a.js +699 -0
- package/dist/repertoire/tools-attachments.js +322 -0
- package/dist/repertoire/tools-awaiting.js +575 -0
- package/dist/repertoire/tools-base.js +77 -1138
- package/dist/repertoire/tools-bluebubbles.js +2 -0
- package/dist/repertoire/tools-bridge.js +144 -0
- package/dist/repertoire/tools-bundle.js +993 -0
- package/dist/repertoire/tools-commerce.js +253 -0
- package/dist/repertoire/tools-config.js +186 -0
- package/dist/repertoire/tools-continuity.js +575 -0
- package/dist/repertoire/tools-credential.js +383 -0
- package/dist/repertoire/tools-evolution.js +527 -0
- package/dist/repertoire/tools-files.js +344 -0
- package/dist/repertoire/tools-flight.js +290 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +3 -8
- package/dist/repertoire/tools-habits.js +103 -0
- package/dist/repertoire/tools-mail.js +1828 -0
- package/dist/repertoire/tools-notes.js +485 -0
- package/dist/repertoire/tools-obligations.js +182 -0
- package/dist/repertoire/tools-orientation.js +31 -0
- package/dist/repertoire/tools-record.js +482 -0
- package/dist/repertoire/tools-rsvp.js +139 -0
- package/dist/repertoire/tools-runtime.js +150 -0
- package/dist/repertoire/tools-sanctuary-host.js +202 -0
- package/dist/repertoire/tools-session.js +1133 -0
- package/dist/repertoire/tools-shell.js +149 -0
- package/dist/repertoire/tools-steward-policy.js +119 -0
- package/dist/repertoire/tools-stripe.js +224 -0
- package/dist/repertoire/tools-surface.js +369 -0
- package/dist/repertoire/tools-teams.js +12 -39
- package/dist/repertoire/tools-telegram-contacts.js +37 -0
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +982 -0
- package/dist/repertoire/tools-unraid.js +531 -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 +494 -148
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/unraid-client.js +155 -0
- package/dist/repertoire/unraid-restart.js +339 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +628 -0
- package/dist/rsvp/aisleplanner-client.js +354 -0
- package/dist/rsvp/cli.js +926 -0
- package/dist/rsvp/config.js +327 -0
- package/dist/rsvp/cutover.js +433 -0
- package/dist/rsvp/diagnostics.js +232 -0
- package/dist/rsvp/diff-renderer.js +176 -0
- package/dist/rsvp/habit-policy.js +110 -0
- package/dist/rsvp/habit-stage.js +123 -0
- package/dist/rsvp/incident-bundle.js +97 -0
- package/dist/rsvp/migration.js +204 -0
- package/dist/rsvp/native-habit-runner.js +630 -0
- package/dist/rsvp/outbound-state.js +628 -0
- package/dist/rsvp/query.js +118 -0
- package/dist/rsvp/replay.js +233 -0
- package/dist/rsvp/snapshot.js +232 -0
- package/dist/rsvp/spend-ledger.js +175 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/a2a-entry.js +115 -0
- package/dist/senses/acp-server.js +386 -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} +355 -40
- package/dist/senses/bluebubbles/context-packet.js +207 -0
- package/dist/senses/bluebubbles/context-smoke.js +144 -0
- package/dist/senses/bluebubbles/entry.js +90 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +21 -3
- package/dist/senses/bluebubbles/index.js +3841 -0
- package/dist/senses/bluebubbles/latest-turn.js +311 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -71
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +159 -28
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +24 -13
- package/dist/senses/bluebubbles/outbound-state.js +308 -0
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/reaction-policy.js +47 -0
- package/dist/senses/bluebubbles/replay.js +284 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +30 -2
- package/dist/senses/bluebubbles/semantic-receipts.js +1986 -0
- package/dist/senses/{bluebubbles-session-cleanup.js → bluebubbles/session-cleanup.js} +1 -1
- package/dist/senses/bluebubbles/webhook-registration.js +228 -0
- package/dist/senses/bluebubbles-meta-guard.js +39 -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 +241 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli.js +604 -320
- package/dist/senses/commands.js +66 -3
- package/dist/senses/context-packet-ledger.js +371 -0
- package/dist/senses/context-packets.js +154 -0
- package/dist/senses/habit-lifecycle-guard.js +24 -0
- package/dist/senses/habit-turn-message.js +160 -0
- package/dist/senses/ingress-evidence.js +2 -0
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +524 -0
- package/dist/senses/pipeline.js +1115 -204
- package/dist/senses/private-runtime-worker.js +859 -0
- package/dist/senses/private-runtime.js +1517 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/root-host-approval-port.js +345 -0
- package/dist/senses/root-host-approval-runtime.js +393 -0
- package/dist/senses/sanctuary-authority-resident.js +102 -0
- package/dist/senses/sanctuary-download-credit-presentation.js +31 -0
- package/dist/senses/sanctuary-full-visibility-contract.js +302 -0
- package/dist/senses/sanctuary-grounding.js +118 -0
- package/dist/senses/sanctuary-health-acceptance-probe-entry.js +12 -0
- package/dist/senses/sanctuary-health-acceptance-probe.js +774 -0
- package/dist/senses/sanctuary-health-runner.js +100 -0
- package/dist/senses/sanctuary-health.js +408 -0
- package/dist/senses/sanctuary-install-state-contract.js +126 -0
- package/dist/senses/sanctuary-interactive-control.js +410 -0
- package/dist/senses/sanctuary-media-catalog-contract.js +297 -0
- package/dist/senses/sanctuary-media-optimization.js +514 -0
- package/dist/senses/sanctuary-runtime.js +340 -0
- package/dist/senses/sanctuary-sab.js +85 -0
- package/dist/senses/sanctuary-storage-optimization-contract.js +32 -0
- package/dist/senses/shared-turn.js +772 -0
- package/dist/senses/surface-tool.js +109 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +519 -218
- package/dist/senses/telegram-admission.js +718 -0
- package/dist/senses/telegram-approval-runtime.js +793 -0
- package/dist/senses/telegram-attachments.js +186 -0
- package/dist/senses/telegram-audit-ledger.js +220 -0
- package/dist/senses/telegram-authority-transport.js +231 -0
- package/dist/senses/telegram-client.js +1749 -0
- package/dist/senses/telegram-effect-adapter.js +896 -0
- package/dist/senses/telegram-entry.js +83 -0
- package/dist/senses/telegram.js +2324 -0
- package/dist/senses/trust-gate.js +104 -9
- 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 +5031 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +81 -0
- package/dist/senses/voice-realtime-eval-command.js +99 -0
- package/dist/senses/voice-realtime-eval-entry.js +21 -0
- package/dist/senses/voice-twilio-entry.js +87 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +265 -0
- package/dist/util/frontmatter.js +69 -0
- package/npm-shrinkwrap.json +8138 -0
- package/package.json +72 -13
- package/skills/agent-commerce.md +113 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +99 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -430
- package/dist/heart/daemon/ouro-path-installer.js +0 -260
- package/dist/heart/daemon/ouro-version-manager.js +0 -171
- package/dist/heart/daemon/update-hooks.js +0 -138
- package/dist/heart/obligations.js +0 -191
- package/dist/heart/safe-workspace.js +0 -228
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/friends/channel.js +0 -84
- package/dist/mind/friends/group-context.js +0 -144
- package/dist/mind/friends/resolver.js +0 -84
- package/dist/mind/friends/store-file.js +0 -190
- package/dist/mind/friends/store.js +0 -4
- package/dist/mind/friends/tokens.js +0 -26
- package/dist/mind/friends/trust-explanation.js +0 -74
- package/dist/mind/friends/types.js +0 -29
- 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 -1181
- package/dist/senses/debug-activity.js +0 -154
- package/dist/senses/inner-dialog-worker.js +0 -90
- package/dist/senses/inner-dialog.js +0 -525
- 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,273 @@
|
|
|
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
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
36
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
37
|
+
};
|
|
38
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
39
|
+
exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL = exports.BLUEBUBBLES_EXECUTABLE_PATH = exports.BLUEBUBBLES_APP_PATH = void 0;
|
|
40
|
+
exports.blueBubblesLaunchAgentPlist = blueBubblesLaunchAgentPlist;
|
|
41
|
+
exports.blueBubblesLaunchAgentPath = blueBubblesLaunchAgentPath;
|
|
42
|
+
exports.inspectBlueBubblesHost = inspectBlueBubblesHost;
|
|
43
|
+
exports.runBlueBubblesHostAction = runBlueBubblesHostAction;
|
|
44
|
+
exports.createDefaultBlueBubblesHostDeps = createDefaultBlueBubblesHostDeps;
|
|
45
|
+
const child_process_1 = require("child_process");
|
|
46
|
+
const fs = __importStar(require("fs"));
|
|
47
|
+
const os = __importStar(require("os"));
|
|
48
|
+
const path = __importStar(require("path"));
|
|
49
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
50
|
+
exports.BLUEBUBBLES_APP_PATH = "/Applications/BlueBubbles.app";
|
|
51
|
+
exports.BLUEBUBBLES_EXECUTABLE_PATH = `${exports.BLUEBUBBLES_APP_PATH}/Contents/MacOS/BlueBubbles`;
|
|
52
|
+
exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL = "com.bluebubbles.server";
|
|
53
|
+
function blueBubblesLaunchAgentPlist(appExecutablePath = exports.BLUEBUBBLES_EXECUTABLE_PATH) {
|
|
54
|
+
return `<?xml version="1.0" encoding="UTF-8"?>
|
|
55
|
+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
56
|
+
<plist version="1.0">
|
|
57
|
+
<dict>
|
|
58
|
+
<key>AssociatedBundleIdentifiers</key>
|
|
59
|
+
<array>
|
|
60
|
+
<string>com.BlueBubbles.BlueBubbles-Server</string>
|
|
61
|
+
</array>
|
|
62
|
+
<key>Label</key>
|
|
63
|
+
<string>com.bluebubbles.server</string>
|
|
64
|
+
<key>Program</key>
|
|
65
|
+
<string>${appExecutablePath}</string>
|
|
66
|
+
<key>RunAtLoad</key>
|
|
67
|
+
<true/>
|
|
68
|
+
<key>KeepAlive</key>
|
|
69
|
+
<dict>
|
|
70
|
+
<key>SuccessfulExit</key>
|
|
71
|
+
<false/>
|
|
72
|
+
<key>Crashed</key>
|
|
73
|
+
<true/>
|
|
74
|
+
</dict>
|
|
75
|
+
</dict>
|
|
76
|
+
</plist>`;
|
|
77
|
+
}
|
|
78
|
+
function blueBubblesLaunchAgentPath(homeDir) {
|
|
79
|
+
return path.join(homeDir, "Library", "LaunchAgents", `${exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL}.plist`);
|
|
80
|
+
}
|
|
81
|
+
function requireMacOS(deps) {
|
|
82
|
+
if (deps.platform !== "darwin")
|
|
83
|
+
throw new Error("BlueBubbles host lifecycle requires macOS");
|
|
84
|
+
}
|
|
85
|
+
function launchdDomain(deps) {
|
|
86
|
+
return `gui/${deps.uid}`;
|
|
87
|
+
}
|
|
88
|
+
function serviceTarget(deps) {
|
|
89
|
+
return `${launchdDomain(deps)}/${exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL}`;
|
|
90
|
+
}
|
|
91
|
+
function requireLaunchctl(result, operation) {
|
|
92
|
+
if (!result.ok)
|
|
93
|
+
throw new Error(`launchctl ${operation} failed: ${result.detail}`);
|
|
94
|
+
}
|
|
95
|
+
async function inspectBlueBubblesHost(deps) {
|
|
96
|
+
requireMacOS(deps);
|
|
97
|
+
const plistPath = blueBubblesLaunchAgentPath(deps.homeDir);
|
|
98
|
+
const expectedPlist = blueBubblesLaunchAgentPlist();
|
|
99
|
+
let plist = "missing";
|
|
100
|
+
if (deps.existsSync(plistPath)) {
|
|
101
|
+
try {
|
|
102
|
+
plist = deps.readFileSync(plistPath) === expectedPlist ? "current" : "drifted";
|
|
103
|
+
}
|
|
104
|
+
catch {
|
|
105
|
+
plist = "drifted";
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
const launchd = deps.launchctl(["print", serviceTarget(deps)]);
|
|
109
|
+
const http = deps.probeHttp
|
|
110
|
+
? await deps.probeHttp()
|
|
111
|
+
: { ok: null, detail: "HTTP health was not configured for this host inspection" };
|
|
112
|
+
const state = {
|
|
113
|
+
app: deps.existsSync(exports.BLUEBUBBLES_APP_PATH) ? "present" : "missing",
|
|
114
|
+
plist,
|
|
115
|
+
service: launchd.ok ? "loaded" : "not-loaded",
|
|
116
|
+
serviceDetail: launchd.detail,
|
|
117
|
+
process: deps.isProcessRunning() ? "running" : "not-running",
|
|
118
|
+
http,
|
|
119
|
+
plistPath,
|
|
120
|
+
launchdDomain: launchdDomain(deps),
|
|
121
|
+
launchAgentLabel: exports.BLUEBUBBLES_LAUNCH_AGENT_LABEL,
|
|
122
|
+
};
|
|
123
|
+
(0, runtime_1.emitNervesEvent)({
|
|
124
|
+
component: "daemon",
|
|
125
|
+
event: "daemon.bluebubbles_host_inspected",
|
|
126
|
+
message: "inspected native BlueBubbles host lifecycle",
|
|
127
|
+
meta: {
|
|
128
|
+
app: state.app,
|
|
129
|
+
plist: state.plist,
|
|
130
|
+
service: state.service,
|
|
131
|
+
process: state.process,
|
|
132
|
+
httpOk: state.http.ok,
|
|
133
|
+
launchdDomain: state.launchdDomain,
|
|
134
|
+
},
|
|
135
|
+
});
|
|
136
|
+
return state;
|
|
137
|
+
}
|
|
138
|
+
function writeNativePlist(deps, plistPath) {
|
|
139
|
+
deps.mkdirSync(path.dirname(plistPath), { recursive: true });
|
|
140
|
+
deps.writeFileSync(plistPath, blueBubblesLaunchAgentPlist(), { mode: 0o644 });
|
|
141
|
+
}
|
|
142
|
+
function reloadNativeService(deps, plistPath, wasLoaded) {
|
|
143
|
+
const target = serviceTarget(deps);
|
|
144
|
+
const domain = launchdDomain(deps);
|
|
145
|
+
if (wasLoaded)
|
|
146
|
+
requireLaunchctl(deps.launchctl(["bootout", target]), "bootout");
|
|
147
|
+
requireLaunchctl(deps.launchctl(["disable", target]), "disable");
|
|
148
|
+
requireLaunchctl(deps.launchctl(["enable", target]), "enable");
|
|
149
|
+
requireLaunchctl(deps.launchctl(["bootstrap", domain, plistPath]), "bootstrap");
|
|
150
|
+
}
|
|
151
|
+
async function runBlueBubblesHostAction(action, deps) {
|
|
152
|
+
requireMacOS(deps);
|
|
153
|
+
(0, runtime_1.emitNervesEvent)({
|
|
154
|
+
component: "daemon",
|
|
155
|
+
event: "daemon.bluebubbles_host_action_start",
|
|
156
|
+
message: "starting native BlueBubbles host lifecycle action",
|
|
157
|
+
meta: { action, uid: deps.uid },
|
|
158
|
+
});
|
|
159
|
+
try {
|
|
160
|
+
const before = await inspectBlueBubblesHost(deps);
|
|
161
|
+
let changed = false;
|
|
162
|
+
if (action === "status") {
|
|
163
|
+
(0, runtime_1.emitNervesEvent)({
|
|
164
|
+
component: "daemon",
|
|
165
|
+
event: "daemon.bluebubbles_host_action_end",
|
|
166
|
+
message: "completed native BlueBubbles host lifecycle action",
|
|
167
|
+
meta: { action, changed: false, service: before.service },
|
|
168
|
+
});
|
|
169
|
+
return { action, changed: false, state: before };
|
|
170
|
+
}
|
|
171
|
+
if (action === "remove") {
|
|
172
|
+
if (before.service === "loaded") {
|
|
173
|
+
requireLaunchctl(deps.launchctl(["disable", serviceTarget(deps)]), "disable");
|
|
174
|
+
requireLaunchctl(deps.launchctl(["bootout", serviceTarget(deps)]), "bootout");
|
|
175
|
+
changed = true;
|
|
176
|
+
}
|
|
177
|
+
if (before.plist !== "missing") {
|
|
178
|
+
deps.unlinkSync(before.plistPath);
|
|
179
|
+
changed = true;
|
|
180
|
+
}
|
|
181
|
+
const state = changed ? await inspectBlueBubblesHost(deps) : before;
|
|
182
|
+
(0, runtime_1.emitNervesEvent)({
|
|
183
|
+
component: "daemon",
|
|
184
|
+
event: "daemon.bluebubbles_host_action_end",
|
|
185
|
+
message: "completed native BlueBubbles host lifecycle action",
|
|
186
|
+
meta: { action, changed, service: state.service },
|
|
187
|
+
});
|
|
188
|
+
return { action, changed, state };
|
|
189
|
+
}
|
|
190
|
+
if (before.app === "missing") {
|
|
191
|
+
throw new Error(`BlueBubbles app is missing at ${exports.BLUEBUBBLES_APP_PATH}`);
|
|
192
|
+
}
|
|
193
|
+
const needsPlist = before.plist !== "current";
|
|
194
|
+
if (needsPlist) {
|
|
195
|
+
writeNativePlist(deps, before.plistPath);
|
|
196
|
+
changed = true;
|
|
197
|
+
}
|
|
198
|
+
if (needsPlist || before.service !== "loaded") {
|
|
199
|
+
reloadNativeService(deps, before.plistPath, before.service === "loaded");
|
|
200
|
+
changed = true;
|
|
201
|
+
}
|
|
202
|
+
const state = changed ? await inspectBlueBubblesHost(deps) : before;
|
|
203
|
+
if (state.plist !== "current" || state.service !== "loaded") {
|
|
204
|
+
throw new Error(`BlueBubbles host postcondition failed: plist=${state.plist}, service=${state.service}`);
|
|
205
|
+
}
|
|
206
|
+
(0, runtime_1.emitNervesEvent)({
|
|
207
|
+
component: "daemon",
|
|
208
|
+
event: "daemon.bluebubbles_host_action_end",
|
|
209
|
+
message: "completed native BlueBubbles host lifecycle action",
|
|
210
|
+
meta: { action, changed, service: state.service },
|
|
211
|
+
});
|
|
212
|
+
return { action, changed, state };
|
|
213
|
+
}
|
|
214
|
+
catch (error) {
|
|
215
|
+
(0, runtime_1.emitNervesEvent)({
|
|
216
|
+
component: "daemon",
|
|
217
|
+
event: "daemon.bluebubbles_host_action_error",
|
|
218
|
+
level: "error",
|
|
219
|
+
message: "native BlueBubbles host lifecycle action failed",
|
|
220
|
+
meta: { action, uid: deps.uid, error: error instanceof Error ? error.message : String(error) },
|
|
221
|
+
});
|
|
222
|
+
throw error;
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
function createDefaultBlueBubblesHostDeps(input = {}) {
|
|
226
|
+
const serverUrl = input.serverUrl ?? "http://127.0.0.1:1234/";
|
|
227
|
+
const requestTimeoutMs = input.requestTimeoutMs ?? 30_000;
|
|
228
|
+
/* v8 ignore next -- production uses global fetch; unit tests inject the adapter @preserve */
|
|
229
|
+
const fetchImpl = input.fetchImpl ?? fetch;
|
|
230
|
+
const probeHttp = input.probeHttp ?? (async () => {
|
|
231
|
+
try {
|
|
232
|
+
const response = await fetchImpl(serverUrl, {
|
|
233
|
+
method: "GET",
|
|
234
|
+
signal: AbortSignal.timeout(requestTimeoutMs),
|
|
235
|
+
});
|
|
236
|
+
return { ok: true, detail: `HTTP server responded with ${response.status}` };
|
|
237
|
+
}
|
|
238
|
+
catch (error) {
|
|
239
|
+
return { ok: false, detail: error instanceof Error ? error.message : String(error) };
|
|
240
|
+
}
|
|
241
|
+
});
|
|
242
|
+
return {
|
|
243
|
+
platform: process.platform,
|
|
244
|
+
homeDir: os.homedir(),
|
|
245
|
+
uid: process.getuid?.() ?? 0,
|
|
246
|
+
existsSync: fs.existsSync,
|
|
247
|
+
readFileSync: (filePath) => fs.readFileSync(filePath, "utf8"),
|
|
248
|
+
mkdirSync: fs.mkdirSync,
|
|
249
|
+
writeFileSync: (filePath, content, options) => fs.writeFileSync(filePath, content, options),
|
|
250
|
+
unlinkSync: fs.unlinkSync,
|
|
251
|
+
launchctl: (args) => {
|
|
252
|
+
try {
|
|
253
|
+
const stdout = (0, child_process_1.execFileSync)("launchctl", args, { encoding: "utf8", stdio: ["ignore", "pipe", "pipe"] });
|
|
254
|
+
return { ok: true, detail: stdout.trim() || "ok" };
|
|
255
|
+
}
|
|
256
|
+
catch (error) {
|
|
257
|
+
const detail = error instanceof Error ? error.message : String(error);
|
|
258
|
+
return { ok: false, detail };
|
|
259
|
+
}
|
|
260
|
+
},
|
|
261
|
+
isProcessRunning: () => {
|
|
262
|
+
try {
|
|
263
|
+
(0, child_process_1.execFileSync)("pgrep", ["-f", exports.BLUEBUBBLES_EXECUTABLE_PATH], { stdio: "ignore" });
|
|
264
|
+
return true;
|
|
265
|
+
}
|
|
266
|
+
catch {
|
|
267
|
+
return false;
|
|
268
|
+
}
|
|
269
|
+
},
|
|
270
|
+
probeHttp,
|
|
271
|
+
};
|
|
272
|
+
}
|
|
273
|
+
__exportStar(require("./bluebubbles-host-protocol"), exports);
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Boot sync probe — Layer 2 orchestrator for `ouro up`.
|
|
4
|
+
*
|
|
5
|
+
* For each sync-enabled bundle, runs `preTurnPullAsync` wrapped in
|
|
6
|
+
* `runWithTimeouts`, classifies failures via `classifySyncFailure`, and
|
|
7
|
+
* returns aggregated findings. Findings surface in the boot stdout
|
|
8
|
+
* summary written by `cli-exec.ts` after the probe phase.
|
|
9
|
+
*
|
|
10
|
+
* Layer 2 is intentionally a **boot-time preflight surface only** — it
|
|
11
|
+
* does NOT feed into the running daemon's rollup state. `computeDaemonRollup`
|
|
12
|
+
* is unaware of these findings; nothing is persisted to daemon health for
|
|
13
|
+
* the running daemon to consume. Layer 3 RepairGuide is the planned consumer
|
|
14
|
+
* (it reads the in-memory `BootSyncProbeFinding[]` at boot time and
|
|
15
|
+
* dispatches the right diagnostic skill).
|
|
16
|
+
*
|
|
17
|
+
* The probe NEVER:
|
|
18
|
+
* - Writes to `state/` (verified by Unit 7's grep gate).
|
|
19
|
+
* - Throws — every failure becomes a finding.
|
|
20
|
+
* - Hangs — `AbortSignal` from `runWithTimeouts` cuts hung remotes
|
|
21
|
+
* within `hardMs`.
|
|
22
|
+
*
|
|
23
|
+
* Advisory vs blocking classifications (consumed by layer 3, not by the
|
|
24
|
+
* layer 1 rollup — see comment above):
|
|
25
|
+
*
|
|
26
|
+
* | classification | advisory? | rationale |
|
|
27
|
+
* | ---------------------- | --------- | ------------------------------------------- |
|
|
28
|
+
* | auth-failed | no | agent can't sync; needs human intervention |
|
|
29
|
+
* | not-found-404 | no | remote is gone; needs human intervention |
|
|
30
|
+
* | network-down | no | agent can't reach the remote at all |
|
|
31
|
+
* | timeout-hard | no | abort cut the op; remote is hung |
|
|
32
|
+
* | dirty-working-tree | yes | local edits prevent merge; agent still runs |
|
|
33
|
+
* | non-fast-forward | yes | local commits ahead; agent still runs |
|
|
34
|
+
* | merge-conflict | yes | rebase failed; needs cleanup |
|
|
35
|
+
* | timeout-soft | yes | warning surfaced, op completed |
|
|
36
|
+
* | unknown | yes | unrecognised; surface for diagnosis |
|
|
37
|
+
*
|
|
38
|
+
* `advisory: true` is a hint for layer 3 ("warn-and-continue, agent likely
|
|
39
|
+
* still works") vs `advisory: false` ("blocking, agent can't sync until
|
|
40
|
+
* fixed"). Layer 3 will route the right diagnostic skill on this signal.
|
|
41
|
+
*/
|
|
42
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
43
|
+
if (k2 === undefined) k2 = k;
|
|
44
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
45
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
46
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
47
|
+
}
|
|
48
|
+
Object.defineProperty(o, k2, desc);
|
|
49
|
+
}) : (function(o, m, k, k2) {
|
|
50
|
+
if (k2 === undefined) k2 = k;
|
|
51
|
+
o[k2] = m[k];
|
|
52
|
+
}));
|
|
53
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
54
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
55
|
+
}) : function(o, v) {
|
|
56
|
+
o["default"] = v;
|
|
57
|
+
});
|
|
58
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
59
|
+
var ownKeys = function(o) {
|
|
60
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
61
|
+
var ar = [];
|
|
62
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
63
|
+
return ar;
|
|
64
|
+
};
|
|
65
|
+
return ownKeys(o);
|
|
66
|
+
};
|
|
67
|
+
return function (mod) {
|
|
68
|
+
if (mod && mod.__esModule) return mod;
|
|
69
|
+
var result = {};
|
|
70
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
71
|
+
__setModuleDefault(result, mod);
|
|
72
|
+
return result;
|
|
73
|
+
};
|
|
74
|
+
})();
|
|
75
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
76
|
+
exports.runBootSyncProbe = runBootSyncProbe;
|
|
77
|
+
const path = __importStar(require("path"));
|
|
78
|
+
const sync_1 = require("../sync");
|
|
79
|
+
const sync_classification_1 = require("../sync-classification");
|
|
80
|
+
const timeouts_1 = require("../timeouts");
|
|
81
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
82
|
+
/** Default soft / hard timeout windows for the boot git op. Matches Layer 2 O1 lock. */
|
|
83
|
+
const DEFAULT_SOFT_MS = 8000;
|
|
84
|
+
const DEFAULT_HARD_MS = 15000;
|
|
85
|
+
const BLOCKING_CLASSIFICATIONS = new Set([
|
|
86
|
+
"auth-failed",
|
|
87
|
+
"not-found-404",
|
|
88
|
+
"network-down",
|
|
89
|
+
"timeout-hard",
|
|
90
|
+
]);
|
|
91
|
+
function isAdvisory(classification) {
|
|
92
|
+
return !BLOCKING_CLASSIFICATIONS.has(classification);
|
|
93
|
+
}
|
|
94
|
+
/**
|
|
95
|
+
* Probe sync state for every enabled, git-initialised bundle. Returns
|
|
96
|
+
* findings for every non-clean result. Probes run sequentially (not in
|
|
97
|
+
* parallel) so the boot path's progress reporter has a stable per-agent
|
|
98
|
+
* narrative; the per-probe hard cap means worst-case total wait is
|
|
99
|
+
* `bundles.length * hardMs`, which is acceptable for typical 1-3 agent
|
|
100
|
+
* deployments.
|
|
101
|
+
*/
|
|
102
|
+
async function runBootSyncProbe(bundles, options) {
|
|
103
|
+
const startedAt = Date.now();
|
|
104
|
+
const softMs = options.softMs ?? DEFAULT_SOFT_MS;
|
|
105
|
+
const hardMs = options.hardMs ?? DEFAULT_HARD_MS;
|
|
106
|
+
(0, runtime_1.emitNervesEvent)({
|
|
107
|
+
component: "daemon",
|
|
108
|
+
event: "daemon.boot_sync_probe_start",
|
|
109
|
+
message: "boot sync probe starting",
|
|
110
|
+
meta: { bundleCount: bundles.length, softMs, hardMs },
|
|
111
|
+
});
|
|
112
|
+
const findings = [];
|
|
113
|
+
for (const bundle of bundles) {
|
|
114
|
+
if (!bundle.enabled)
|
|
115
|
+
continue;
|
|
116
|
+
const agentRoot = path.join(options.bundlesRoot, `${bundle.agent}.ouro`);
|
|
117
|
+
// gitInitialized=false: bundle is enabled for sync but never had `git init`.
|
|
118
|
+
// Surface as advisory finding without invoking git.
|
|
119
|
+
if (bundle.gitInitialized === false) {
|
|
120
|
+
findings.push({
|
|
121
|
+
agent: bundle.agent,
|
|
122
|
+
classification: "unknown",
|
|
123
|
+
error: `bundle is not a git repo; run \`git init\` inside ${agentRoot} to enable sync (or disable sync in agent.json)`,
|
|
124
|
+
conflictFiles: [],
|
|
125
|
+
warnings: [],
|
|
126
|
+
advisory: true,
|
|
127
|
+
});
|
|
128
|
+
continue;
|
|
129
|
+
}
|
|
130
|
+
const syncConfig = { enabled: bundle.enabled, remote: bundle.remote };
|
|
131
|
+
const outcome = await (0, timeouts_1.runWithTimeouts)((signal) => (0, sync_1.preTurnPullAsync)(agentRoot, syncConfig, { signal }), { softMs, hardMs, label: `boot-sync-probe ${bundle.agent}`, envKey: "GIT" });
|
|
132
|
+
// Hard timeout — the probe was aborted. Synthesise a finding from the
|
|
133
|
+
// outcome's classification (the underlying `preTurnPullAsync` may also
|
|
134
|
+
// have rejected with an AbortError, but the wrapper already swallowed
|
|
135
|
+
// it).
|
|
136
|
+
if (outcome.classification === "timeout-hard") {
|
|
137
|
+
findings.push({
|
|
138
|
+
agent: bundle.agent,
|
|
139
|
+
classification: "timeout-hard",
|
|
140
|
+
error: `boot sync probe for ${bundle.agent} aborted after ${hardMs}ms hard timeout`,
|
|
141
|
+
conflictFiles: [],
|
|
142
|
+
warnings: outcome.warnings,
|
|
143
|
+
advisory: isAdvisory("timeout-hard"),
|
|
144
|
+
});
|
|
145
|
+
continue;
|
|
146
|
+
}
|
|
147
|
+
const result = outcome.result;
|
|
148
|
+
/* v8 ignore start -- defensive: exclusive state from runWithTimeouts contract — either result or classification, never both undefined @preserve */
|
|
149
|
+
if (!result) {
|
|
150
|
+
findings.push({
|
|
151
|
+
agent: bundle.agent,
|
|
152
|
+
classification: "unknown",
|
|
153
|
+
error: "boot sync probe returned without result or classification",
|
|
154
|
+
conflictFiles: [],
|
|
155
|
+
warnings: outcome.warnings,
|
|
156
|
+
advisory: true,
|
|
157
|
+
});
|
|
158
|
+
continue;
|
|
159
|
+
}
|
|
160
|
+
/* v8 ignore stop */
|
|
161
|
+
if (!result.ok) {
|
|
162
|
+
const classification = (0, sync_classification_1.classifySyncFailure)(new Error(result.error ?? "unknown sync error"), { agentRoot });
|
|
163
|
+
findings.push({
|
|
164
|
+
agent: bundle.agent,
|
|
165
|
+
classification: classification.classification,
|
|
166
|
+
error: classification.error,
|
|
167
|
+
conflictFiles: classification.conflictFiles,
|
|
168
|
+
warnings: outcome.warnings,
|
|
169
|
+
advisory: isAdvisory(classification.classification),
|
|
170
|
+
});
|
|
171
|
+
continue;
|
|
172
|
+
}
|
|
173
|
+
// Probe succeeded. If the soft warning fired, surface it as an advisory
|
|
174
|
+
// finding so the operator sees the slow-pull warning even on success.
|
|
175
|
+
if (outcome.warnings.length > 0) {
|
|
176
|
+
findings.push({
|
|
177
|
+
agent: bundle.agent,
|
|
178
|
+
classification: "timeout-soft",
|
|
179
|
+
error: outcome.warnings.join("; "),
|
|
180
|
+
conflictFiles: [],
|
|
181
|
+
warnings: outcome.warnings,
|
|
182
|
+
advisory: true,
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
// Stable order — sort by agent name so renderers and tests see the same
|
|
187
|
+
// sequence.
|
|
188
|
+
findings.sort((a, b) => a.agent.localeCompare(b.agent));
|
|
189
|
+
const durationMs = Date.now() - startedAt;
|
|
190
|
+
(0, runtime_1.emitNervesEvent)({
|
|
191
|
+
component: "daemon",
|
|
192
|
+
event: "daemon.boot_sync_probe_end",
|
|
193
|
+
message: "boot sync probe complete",
|
|
194
|
+
meta: { findingCount: findings.length, durationMs },
|
|
195
|
+
});
|
|
196
|
+
return { findings, durationMs };
|
|
197
|
+
}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.DEFAULT_CADENCE_MS = void 0;
|
|
4
|
+
exports.parseCadenceToCron = parseCadenceToCron;
|
|
5
|
+
exports.parseCadenceToMs = parseCadenceToMs;
|
|
6
|
+
exports.nextCadenceRunAt = nextCadenceRunAt;
|
|
7
|
+
exports.cadenceFallbackDelayMs = cadenceFallbackDelayMs;
|
|
8
|
+
exports.evaluateCadenceDue = evaluateCadenceDue;
|
|
9
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
10
|
+
exports.DEFAULT_CADENCE_MS = 30 * 60 * 1000; // 30 minutes
|
|
11
|
+
function parseFixedDailyCron(raw) {
|
|
12
|
+
if (typeof raw !== "string")
|
|
13
|
+
return null;
|
|
14
|
+
const parts = raw.trim().split(/\s+/);
|
|
15
|
+
if (parts.length !== 5)
|
|
16
|
+
return null;
|
|
17
|
+
const minuteRaw = parts[0];
|
|
18
|
+
const hourRaw = parts[1];
|
|
19
|
+
const day = parts[2];
|
|
20
|
+
const month = parts[3];
|
|
21
|
+
const weekday = parts[4];
|
|
22
|
+
if (day !== "*" || month !== "*" || weekday !== "*")
|
|
23
|
+
return null;
|
|
24
|
+
if (!/^\d+$/.test(minuteRaw) || !/^\d+$/.test(hourRaw))
|
|
25
|
+
return null;
|
|
26
|
+
const minute = Number.parseInt(minuteRaw, 10);
|
|
27
|
+
const hour = Number.parseInt(hourRaw, 10);
|
|
28
|
+
if (minute < 0 || minute > 59 || hour < 0 || hour > 23)
|
|
29
|
+
return null;
|
|
30
|
+
return { minute, hour };
|
|
31
|
+
}
|
|
32
|
+
function coerceTimeMs(value) {
|
|
33
|
+
const time = value instanceof Date ? value.getTime() : typeof value === "number" ? value : Date.parse(value);
|
|
34
|
+
return Number.isFinite(time) ? time : null;
|
|
35
|
+
}
|
|
36
|
+
function localOccurrenceForDay(referenceMs, fixed) {
|
|
37
|
+
const occurrence = new Date(referenceMs);
|
|
38
|
+
occurrence.setHours(fixed.hour, fixed.minute, 0, 0);
|
|
39
|
+
return occurrence;
|
|
40
|
+
}
|
|
41
|
+
function previousFixedDailyOccurrence(fixed, nowMs) {
|
|
42
|
+
const occurrence = localOccurrenceForDay(nowMs, fixed);
|
|
43
|
+
if (occurrence.getTime() > nowMs) {
|
|
44
|
+
occurrence.setDate(occurrence.getDate() - 1);
|
|
45
|
+
}
|
|
46
|
+
return occurrence;
|
|
47
|
+
}
|
|
48
|
+
function nextFixedDailyOccurrence(fixed, fromMs) {
|
|
49
|
+
const occurrence = localOccurrenceForDay(fromMs, fixed);
|
|
50
|
+
if (occurrence.getTime() <= fromMs) {
|
|
51
|
+
occurrence.setDate(occurrence.getDate() + 1);
|
|
52
|
+
}
|
|
53
|
+
return occurrence;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Parse a cadence shorthand (e.g. "30m", "2h", "1d") into a cron string.
|
|
57
|
+
* Also accepts raw cron strings (5 space-separated fields) and passes them through.
|
|
58
|
+
* Returns null for invalid input.
|
|
59
|
+
*/
|
|
60
|
+
function parseCadenceToCron(raw) {
|
|
61
|
+
if (typeof raw !== "string")
|
|
62
|
+
return null;
|
|
63
|
+
const value = raw.trim();
|
|
64
|
+
if (!value)
|
|
65
|
+
return null;
|
|
66
|
+
// Cron format (minute hour day month weekday)
|
|
67
|
+
if (/^\S+\s+\S+\s+\S+\s+\S+\s+\S+$/.test(value)) {
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
const cadenceMatch = /^(\d+)(m|h|d)$/.exec(value);
|
|
71
|
+
if (!cadenceMatch)
|
|
72
|
+
return null;
|
|
73
|
+
const interval = Number.parseInt(cadenceMatch[1], 10);
|
|
74
|
+
if (!Number.isFinite(interval) || interval <= 0)
|
|
75
|
+
return null;
|
|
76
|
+
(0, runtime_1.emitNervesEvent)({
|
|
77
|
+
event: "daemon.cadence_parsed",
|
|
78
|
+
component: "daemon",
|
|
79
|
+
message: "parsed cadence shorthand to cron",
|
|
80
|
+
meta: { raw: value, interval, unit: cadenceMatch[2] },
|
|
81
|
+
});
|
|
82
|
+
const unit = cadenceMatch[2];
|
|
83
|
+
if (unit === "m")
|
|
84
|
+
return `*/${interval} * * * *`;
|
|
85
|
+
if (unit === "h")
|
|
86
|
+
return `0 */${interval} * * *`;
|
|
87
|
+
return `0 0 */${interval} * *`;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Parse a cadence shorthand (e.g. "30m", "2h", "1d") into milliseconds.
|
|
91
|
+
* Returns null for invalid input.
|
|
92
|
+
*/
|
|
93
|
+
function parseCadenceToMs(raw) {
|
|
94
|
+
if (typeof raw !== "string")
|
|
95
|
+
return null;
|
|
96
|
+
const value = raw.trim();
|
|
97
|
+
if (!value)
|
|
98
|
+
return null;
|
|
99
|
+
const match = /^(\d+)(m|h|d)$/.exec(value);
|
|
100
|
+
if (!match)
|
|
101
|
+
return null;
|
|
102
|
+
const interval = Number.parseInt(match[1], 10);
|
|
103
|
+
if (!Number.isFinite(interval) || interval <= 0)
|
|
104
|
+
return null;
|
|
105
|
+
(0, runtime_1.emitNervesEvent)({
|
|
106
|
+
event: "daemon.cadence_parsed_ms",
|
|
107
|
+
component: "daemon",
|
|
108
|
+
message: "parsed cadence shorthand to milliseconds",
|
|
109
|
+
meta: { raw: value, interval, unit: match[2] },
|
|
110
|
+
});
|
|
111
|
+
const unit = match[2];
|
|
112
|
+
if (unit === "m")
|
|
113
|
+
return interval * 60 * 1000;
|
|
114
|
+
if (unit === "h")
|
|
115
|
+
return interval * 60 * 60 * 1000;
|
|
116
|
+
return interval * 24 * 60 * 60 * 1000;
|
|
117
|
+
}
|
|
118
|
+
function nextCadenceRunAt(raw, from) {
|
|
119
|
+
const fromMs = coerceTimeMs(from);
|
|
120
|
+
if (fromMs === null)
|
|
121
|
+
return null;
|
|
122
|
+
const intervalMs = parseCadenceToMs(raw);
|
|
123
|
+
if (intervalMs !== null) {
|
|
124
|
+
return new Date(fromMs + intervalMs).toISOString();
|
|
125
|
+
}
|
|
126
|
+
const fixed = parseFixedDailyCron(raw);
|
|
127
|
+
if (!fixed)
|
|
128
|
+
return null;
|
|
129
|
+
const next = nextFixedDailyOccurrence(fixed, fromMs);
|
|
130
|
+
(0, runtime_1.emitNervesEvent)({
|
|
131
|
+
event: "daemon.fixed_cadence_next_run_computed",
|
|
132
|
+
component: "daemon",
|
|
133
|
+
message: "computed fixed daily cadence next run",
|
|
134
|
+
meta: { raw, nextRunAt: next.toISOString() },
|
|
135
|
+
});
|
|
136
|
+
return next.toISOString();
|
|
137
|
+
}
|
|
138
|
+
function cadenceFallbackDelayMs(raw, nowMs) {
|
|
139
|
+
const intervalMs = parseCadenceToMs(raw);
|
|
140
|
+
if (intervalMs !== null)
|
|
141
|
+
return intervalMs;
|
|
142
|
+
const nextRunAt = nextCadenceRunAt(raw, nowMs);
|
|
143
|
+
if (!nextRunAt)
|
|
144
|
+
return null;
|
|
145
|
+
const delay = Date.parse(nextRunAt) - nowMs;
|
|
146
|
+
return delay;
|
|
147
|
+
}
|
|
148
|
+
function evaluateCadenceDue(raw, lastRun, nowMs) {
|
|
149
|
+
const intervalMs = parseCadenceToMs(raw);
|
|
150
|
+
if (intervalMs !== null) {
|
|
151
|
+
if (lastRun === null) {
|
|
152
|
+
return { due: true, elapsedMs: Infinity, occurrenceId: `overdue:first-run:${String(raw).trim()}` };
|
|
153
|
+
}
|
|
154
|
+
const lastRunMs = Date.parse(lastRun);
|
|
155
|
+
if (!Number.isFinite(lastRunMs))
|
|
156
|
+
return { due: false, elapsedMs: 0, occurrenceId: null };
|
|
157
|
+
const elapsedMs = nowMs - lastRunMs;
|
|
158
|
+
return {
|
|
159
|
+
due: elapsedMs >= intervalMs,
|
|
160
|
+
elapsedMs,
|
|
161
|
+
occurrenceId: elapsedMs >= intervalMs ? `overdue:last-run:${lastRun}:cadence:${String(raw).trim()}` : null,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const fixed = parseFixedDailyCron(raw);
|
|
165
|
+
if (!fixed)
|
|
166
|
+
return null;
|
|
167
|
+
const occurrence = previousFixedDailyOccurrence(fixed, nowMs);
|
|
168
|
+
const elapsedMs = lastRun === null ? Infinity : nowMs - occurrence.getTime();
|
|
169
|
+
const todayOccurrence = localOccurrenceForDay(nowMs, fixed);
|
|
170
|
+
const hasReachedTodayOccurrence = todayOccurrence.getTime() <= nowMs;
|
|
171
|
+
const lastRunMs = lastRun === null ? null : Date.parse(lastRun);
|
|
172
|
+
const due = lastRunMs === null
|
|
173
|
+
? hasReachedTodayOccurrence
|
|
174
|
+
: Number.isFinite(lastRunMs) && lastRunMs < occurrence.getTime();
|
|
175
|
+
return {
|
|
176
|
+
due,
|
|
177
|
+
elapsedMs,
|
|
178
|
+
occurrenceId: due ? `fixed-daily:${occurrence.toISOString()}:cadence:${String(raw).trim()}` : null,
|
|
179
|
+
};
|
|
180
|
+
}
|