@ouro.bot/cli 0.1.0-alpha.56 → 0.1.0-alpha.560
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 +3596 -0
- package/dist/arc/attention-types.js +8 -0
- package/dist/arc/cares.js +140 -0
- package/dist/arc/episodes.js +117 -0
- package/dist/arc/intentions.js +133 -0
- package/dist/arc/json-store.js +117 -0
- package/dist/arc/obligations.js +237 -0
- package/dist/arc/packets.js +193 -0
- package/dist/arc/presence.js +185 -0
- package/dist/arc/task-lifecycle.js +65 -0
- package/dist/heart/active-work.js +837 -26
- package/dist/heart/agent-entry.js +58 -3
- package/dist/heart/attachments/image-normalize.js +194 -0
- package/dist/heart/attachments/materialize.js +97 -0
- package/dist/heart/attachments/originals.js +88 -0
- package/dist/heart/attachments/render.js +29 -0
- package/dist/heart/attachments/sources/adapter.js +2 -0
- package/dist/heart/attachments/sources/bluebubbles.js +156 -0
- package/dist/heart/attachments/sources/cli-local-file.js +78 -0
- package/dist/heart/attachments/sources/index.js +16 -0
- package/dist/heart/attachments/store.js +103 -0
- package/dist/heart/attachments/types.js +93 -0
- package/dist/heart/auth/auth-flow.js +479 -0
- package/dist/heart/background-operations.js +281 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +322 -0
- package/dist/heart/config.js +114 -118
- package/dist/heart/core.js +913 -246
- 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-exec.js +7457 -0
- package/dist/heart/daemon/cli-help.js +498 -0
- package/dist/heart/daemon/cli-parse.js +1592 -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 -1698
- package/dist/heart/daemon/daemon-entry.js +387 -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 +796 -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 +826 -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 +82 -12
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/message-router.js +2 -2
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +14 -12
- package/dist/heart/daemon/ouro-bot-entry.js +4 -2
- package/dist/heart/daemon/ouro-entry.js +3 -1
- package/dist/heart/daemon/process-manager.js +375 -33
- 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 +67 -16
- package/dist/heart/daemon/runtime-metadata.js +3 -31
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +389 -38
- package/dist/heart/daemon/session-id-resolver.js +131 -0
- package/dist/heart/daemon/skill-management-installer.js +94 -0
- package/dist/heart/daemon/socket-client.js +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 +3 -25
- package/dist/heart/daemon/terminal-ui.js +499 -0
- package/dist/heart/daemon/thoughts.js +162 -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 -1
- 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 +35 -12
- package/dist/heart/identity.js +203 -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 +195 -0
- package/dist/heart/mailbox/readers/agent-machine.js +382 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
- package/dist/heart/mailbox/readers/mail.js +362 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
- package/dist/heart/mailbox/readers/sessions.js +232 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +683 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +19 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +267 -0
- package/dist/heart/provider-credentials.js +425 -0
- package/dist/heart/provider-failover.js +301 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-readiness-cache.js +40 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +139 -52
- package/dist/heart/providers/azure.js +97 -13
- package/dist/heart/providers/error-classification.js +127 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +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 +43 -22
- package/dist/heart/session-events.js +1149 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +182 -0
- package/dist/heart/session-transcript.js +243 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +44 -27
- 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 +139 -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-B-461hes.js +61 -0
- package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/mailbox-ui/index.html +15 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +674 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/core.js +720 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +430 -0
- package/dist/mailroom/mbox-import.js +383 -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 +256 -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 +7 -1
- package/dist/mind/context.js +165 -101
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +62 -75
- 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 +39 -3
- package/dist/mind/friends/types.js +2 -2
- package/dist/mind/journal-index.js +161 -0
- package/dist/mind/note-search.js +268 -0
- package/dist/mind/obligation-steering.js +221 -0
- package/dist/mind/pending.js +4 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1011 -123
- 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 +129 -5
- package/dist/nerves/coverage/run-artifacts.js +1 -1
- package/dist/nerves/event-buffer.js +111 -0
- package/dist/nerves/index.js +224 -4
- package/dist/nerves/observation.js +20 -0
- package/dist/nerves/redact.js +79 -0
- package/dist/nerves/review/cli-main.js +5 -0
- package/dist/nerves/review/cli.js +156 -0
- package/dist/nerves/review/core.js +152 -0
- package/dist/nerves/runtime.js +5 -1
- package/dist/repertoire/ado-client.js +15 -56
- package/dist/repertoire/ado-semantic.js +11 -10
- package/dist/repertoire/api-client.js +97 -0
- package/dist/repertoire/bitwarden-store.js +963 -0
- package/dist/repertoire/bundle-templates.js +72 -0
- package/dist/repertoire/bw-installer.js +180 -0
- package/dist/repertoire/coding/codex-jsonl.js +64 -0
- package/dist/repertoire/coding/context-pack.js +330 -0
- package/dist/repertoire/coding/feedback.js +197 -30
- package/dist/repertoire/coding/manager.js +158 -9
- package/dist/repertoire/coding/spawner.js +55 -9
- package/dist/repertoire/coding/tools.js +170 -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/duffel-client.js +185 -0
- package/dist/repertoire/github-client.js +14 -55
- package/dist/repertoire/graph-client.js +11 -52
- package/dist/repertoire/guardrails.js +396 -0
- package/dist/repertoire/mcp-client.js +295 -0
- package/dist/repertoire/mcp-manager.js +362 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +31 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +16 -4
- package/dist/repertoire/tasks/lifecycle.js +2 -2
- package/dist/repertoire/tasks/parser.js +3 -2
- package/dist/repertoire/tasks/scanner.js +194 -37
- package/dist/repertoire/tasks/transitions.js +16 -78
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-base.js +47 -1075
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +142 -0
- package/dist/repertoire/tools-bundle.js +984 -0
- package/dist/repertoire/tools-config.js +185 -0
- package/dist/repertoire/tools-continuity.js +248 -0
- package/dist/repertoire/tools-credential.js +381 -0
- package/dist/repertoire/tools-files.js +342 -0
- package/dist/repertoire/tools-flight.js +224 -0
- package/dist/repertoire/tools-flow.js +119 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1857 -0
- package/dist/repertoire/tools-notes.js +421 -0
- package/dist/repertoire/tools-session.js +750 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +243 -0
- package/dist/repertoire/tools-teams.js +9 -39
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +604 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +108 -100
- package/dist/repertoire/travel-api-client.js +360 -0
- package/dist/repertoire/user-profile.js +131 -0
- package/dist/repertoire/vault-setup.js +246 -0
- package/dist/repertoire/vault-unlock.js +594 -0
- package/dist/scripts/claude-code-hook.js +41 -0
- package/dist/scripts/claude-code-stop-hook.js +47 -0
- package/dist/senses/attention-queue.js +116 -0
- package/dist/senses/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 +2305 -0
- package/dist/senses/{bluebubbles-media.js → bluebubbles/media.js} +121 -70
- 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/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +607 -0
- package/dist/senses/cli/spinner-imperative.js +135 -0
- package/dist/senses/cli/spinner.js +101 -0
- package/dist/senses/cli/status-line.js +60 -0
- package/dist/senses/cli/streaming-markdown.js +526 -0
- package/dist/senses/cli/tool-display.js +85 -0
- package/dist/senses/cli/tool-render.js +85 -0
- package/dist/senses/cli/tui-store.js +240 -0
- package/dist/senses/cli/virtual-list.js +35 -0
- package/dist/senses/cli-entry.js +60 -8
- package/dist/senses/cli-layout.js +187 -0
- package/dist/senses/cli.js +520 -209
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +175 -21
- package/dist/senses/inner-dialog.js +330 -27
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +549 -181
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +248 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +387 -98
- package/dist/senses/trust-gate.js +100 -5
- package/dist/senses/voice/elevenlabs.js +125 -0
- package/dist/senses/voice/index.js +22 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +85 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +133 -0
- package/dist/senses/voice-entry.js +80 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +146 -0
- package/package.json +38 -7
- package/skills/agent-commerce.md +106 -0
- package/skills/browser-navigation.md +117 -0
- package/skills/commerce-setup-guide.md +116 -0
- package/skills/commerce-setup.md +84 -0
- package/skills/configure-dev-tools.md +101 -0
- package/skills/travel-planning.md +138 -0
- package/dist/heart/daemon/auth-flow.js +0 -351
- package/dist/heart/daemon/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- package/dist/heart/session-recall.js +0 -116
- package/dist/mind/associative-recall.js +0 -209
- 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 -86
- package/subagents/work-doer.md +0 -237
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -390
- /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/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
|
@@ -2,8 +2,20 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.formatCodingTail = formatCodingTail;
|
|
4
4
|
exports.attachCodingSessionFeedback = attachCodingSessionFeedback;
|
|
5
|
+
const identity_1 = require("../../heart/identity");
|
|
6
|
+
const socket_client_1 = require("../../heart/daemon/socket-client");
|
|
7
|
+
const obligations_1 = require("../../arc/obligations");
|
|
5
8
|
const runtime_1 = require("../../nerves/runtime");
|
|
6
9
|
const TERMINAL_UPDATE_KINDS = new Set(["completed", "failed", "killed"]);
|
|
10
|
+
const OBLIGATION_WAKE_UPDATE_KINDS = new Set([
|
|
11
|
+
"waiting_input",
|
|
12
|
+
"stalled",
|
|
13
|
+
"completed",
|
|
14
|
+
"failed",
|
|
15
|
+
"killed",
|
|
16
|
+
]);
|
|
17
|
+
const PULL_REQUEST_NUMBER_PATTERN = /\bPR\s*#(\d+)\b/i;
|
|
18
|
+
const PULL_REQUEST_URL_PATTERN = /\/pull\/(\d+)(?:\b|\/)?/i;
|
|
7
19
|
function clip(text, maxLength = 280) {
|
|
8
20
|
const trimmed = text.trim();
|
|
9
21
|
if (trimmed.length <= maxLength)
|
|
@@ -42,25 +54,114 @@ function lastMeaningfulLine(text) {
|
|
|
42
54
|
return clip(lines.at(-1));
|
|
43
55
|
}
|
|
44
56
|
function formatSessionLabel(session) {
|
|
45
|
-
|
|
57
|
+
const origin = session.originSession
|
|
58
|
+
? ` for ${session.originSession.channel}/${session.originSession.key}`
|
|
59
|
+
: "";
|
|
60
|
+
return `${session.runner} ${session.id}${origin}`;
|
|
61
|
+
}
|
|
62
|
+
function extractPullRequestLabel(snippet) {
|
|
63
|
+
if (!snippet)
|
|
64
|
+
return null;
|
|
65
|
+
const numberMatch = snippet.match(PULL_REQUEST_NUMBER_PATTERN);
|
|
66
|
+
if (numberMatch)
|
|
67
|
+
return `PR #${numberMatch[1]}`;
|
|
68
|
+
const urlMatch = snippet.match(PULL_REQUEST_URL_PATTERN);
|
|
69
|
+
if (urlMatch)
|
|
70
|
+
return `PR #${urlMatch[1]}`;
|
|
71
|
+
return null;
|
|
72
|
+
}
|
|
73
|
+
function isMergedPullRequestSnippet(snippet) {
|
|
74
|
+
return /\bmerged\b/i.test(snippet) || /\blanded\b/i.test(snippet);
|
|
75
|
+
}
|
|
76
|
+
function deriveObligationMilestone(update) {
|
|
77
|
+
const snippet = pickUpdateSnippet(update);
|
|
78
|
+
const pullRequest = extractPullRequestLabel(snippet);
|
|
79
|
+
if (update.kind === "completed" && snippet && pullRequest && isMergedPullRequestSnippet(snippet)) {
|
|
80
|
+
return {
|
|
81
|
+
status: "updating_runtime",
|
|
82
|
+
currentSurface: { kind: "runtime", label: "ouro up" },
|
|
83
|
+
currentArtifact: pullRequest,
|
|
84
|
+
nextAction: "update runtime, verify version/changelog, then re-observe",
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
if (update.kind === "completed" && pullRequest) {
|
|
88
|
+
return {
|
|
89
|
+
status: "waiting_for_merge",
|
|
90
|
+
currentSurface: { kind: "merge", label: pullRequest },
|
|
91
|
+
currentArtifact: pullRequest,
|
|
92
|
+
nextAction: `wait for checks, merge ${pullRequest}, then update runtime`,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
if (update.kind === "waiting_input") {
|
|
96
|
+
return {
|
|
97
|
+
status: "investigating",
|
|
98
|
+
currentSurface: { kind: "coding", label: `${update.session.runner} ${update.session.id}` },
|
|
99
|
+
nextAction: `answer ${update.session.runner} ${update.session.id} and continue`,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
if (update.kind === "stalled") {
|
|
103
|
+
return {
|
|
104
|
+
status: "investigating",
|
|
105
|
+
currentSurface: { kind: "coding", label: `${update.session.runner} ${update.session.id}` },
|
|
106
|
+
nextAction: `unstick ${update.session.runner} ${update.session.id} and continue`,
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
if (update.kind === "progress" || update.kind === "spawned" || update.kind === "failed" || update.kind === "killed" || update.kind === "completed") {
|
|
110
|
+
return {
|
|
111
|
+
status: "investigating",
|
|
112
|
+
currentSurface: { kind: "coding", label: `${update.session.runner} ${update.session.id}` },
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
return null;
|
|
46
116
|
}
|
|
47
117
|
function isSafeProgressSnippet(snippet) {
|
|
118
|
+
const normalized = snippet.trim();
|
|
48
119
|
const wordCount = snippet.split(/\s+/).filter(Boolean).length;
|
|
49
|
-
return (
|
|
120
|
+
return (normalized.length <= 80
|
|
121
|
+
&& wordCount >= 2
|
|
50
122
|
&& wordCount <= 8
|
|
51
|
-
&&
|
|
52
|
-
&& !
|
|
53
|
-
&&
|
|
54
|
-
&&
|
|
55
|
-
&& !/^
|
|
56
|
-
&& !/^
|
|
57
|
-
&& !/^
|
|
123
|
+
&& /[A-Za-z]{3,}/.test(normalized)
|
|
124
|
+
&& !normalized.includes(":")
|
|
125
|
+
&& !/[{}\[\]();]/.test(normalized)
|
|
126
|
+
&& !normalized.startsWith("**")
|
|
127
|
+
&& !/^Respond with\b/i.test(normalized)
|
|
128
|
+
&& !/^Coding session metadata\b/i.test(normalized)
|
|
129
|
+
&& !/^sessionId\b/i.test(normalized)
|
|
130
|
+
&& !/^taskRef\b/i.test(normalized)
|
|
131
|
+
&& !/^parentAgent\b/i.test(normalized));
|
|
58
132
|
}
|
|
59
133
|
function pickUpdateSnippet(update) {
|
|
60
|
-
|
|
134
|
+
const checkpoint = update.session.checkpoint?.trim() || null;
|
|
135
|
+
return (checkpoint
|
|
136
|
+
?? lastMeaningfulLine(update.text)
|
|
61
137
|
?? lastMeaningfulLine(update.session.stderrTail)
|
|
62
138
|
?? lastMeaningfulLine(update.session.stdoutTail));
|
|
63
139
|
}
|
|
140
|
+
function renderValue(text) {
|
|
141
|
+
const trimmed = text?.trim();
|
|
142
|
+
return trimmed && trimmed.length > 0 ? trimmed : "(empty)";
|
|
143
|
+
}
|
|
144
|
+
function renderPath(text) {
|
|
145
|
+
return text && text.trim().length > 0 ? text : "(none)";
|
|
146
|
+
}
|
|
147
|
+
function formatCodingTail(session) {
|
|
148
|
+
const stdout = renderValue(session.stdoutTail);
|
|
149
|
+
const stderr = renderValue(session.stderrTail);
|
|
150
|
+
return [
|
|
151
|
+
`sessionId: ${session.id}`,
|
|
152
|
+
`runner: ${session.runner}`,
|
|
153
|
+
`status: ${session.status}`,
|
|
154
|
+
`checkpoint: ${renderValue(session.checkpoint ?? undefined)}`,
|
|
155
|
+
`artifactPath: ${renderPath(session.artifactPath)}`,
|
|
156
|
+
`workdir: ${session.workdir}`,
|
|
157
|
+
"",
|
|
158
|
+
"[stdout]",
|
|
159
|
+
stdout,
|
|
160
|
+
"",
|
|
161
|
+
"[stderr]",
|
|
162
|
+
stderr,
|
|
163
|
+
].join("\n");
|
|
164
|
+
}
|
|
64
165
|
function formatUpdateMessage(update) {
|
|
65
166
|
const label = formatSessionLabel(update.session);
|
|
66
167
|
const snippet = pickUpdateSnippet(update);
|
|
@@ -81,26 +182,88 @@ function formatUpdateMessage(update) {
|
|
|
81
182
|
return `${label} started`;
|
|
82
183
|
}
|
|
83
184
|
}
|
|
84
|
-
function
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
185
|
+
function formatReportBackMessage(update, baseMessage) {
|
|
186
|
+
if (!baseMessage)
|
|
187
|
+
return null;
|
|
188
|
+
if (!update.session.obligationId || !update.session.originSession) {
|
|
189
|
+
return baseMessage;
|
|
190
|
+
}
|
|
191
|
+
const milestone = deriveObligationMilestone(update);
|
|
192
|
+
const extraLines = [];
|
|
193
|
+
if (milestone?.currentArtifact) {
|
|
194
|
+
extraLines.push(`current artifact: ${milestone.currentArtifact}`);
|
|
195
|
+
}
|
|
196
|
+
if (milestone?.nextAction) {
|
|
197
|
+
extraLines.push(`next: ${milestone.nextAction}`);
|
|
198
|
+
}
|
|
199
|
+
return extraLines.length > 0 ? `${baseMessage}\n${extraLines.join("\n")}` : baseMessage;
|
|
200
|
+
}
|
|
201
|
+
function obligationNoteFromUpdate(update) {
|
|
202
|
+
const snippet = pickUpdateSnippet(update);
|
|
203
|
+
switch (update.kind) {
|
|
204
|
+
case "spawned":
|
|
205
|
+
return update.session.originSession
|
|
206
|
+
? `coding session started for ${update.session.originSession.channel}/${update.session.originSession.key}`
|
|
207
|
+
: "coding session started";
|
|
208
|
+
case "progress":
|
|
209
|
+
return snippet ? `coding session progress: ${snippet}` : null;
|
|
210
|
+
case "waiting_input":
|
|
211
|
+
return snippet ? `coding session waiting: ${snippet}` : "coding session waiting for input";
|
|
212
|
+
case "stalled":
|
|
213
|
+
return snippet ? `coding session stalled: ${snippet}` : "coding session stalled";
|
|
214
|
+
case "completed":
|
|
215
|
+
return snippet
|
|
216
|
+
? `coding session completed: ${snippet}; merge/update still pending`
|
|
217
|
+
: "coding session completed; merge/update still pending";
|
|
218
|
+
case "failed":
|
|
219
|
+
return snippet ? `coding session failed: ${snippet}` : "coding session failed";
|
|
220
|
+
case "killed":
|
|
221
|
+
return "coding session killed";
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
function syncObligationFromUpdate(update) {
|
|
225
|
+
const obligationId = update.session.obligationId;
|
|
226
|
+
if (!obligationId)
|
|
227
|
+
return;
|
|
228
|
+
const milestone = deriveObligationMilestone(update);
|
|
229
|
+
try {
|
|
230
|
+
(0, obligations_1.advanceObligation)((0, identity_1.getAgentRoot)(), obligationId, {
|
|
231
|
+
status: milestone?.status ?? "investigating",
|
|
232
|
+
currentSurface: milestone?.currentSurface ?? { kind: "coding", label: `${update.session.runner} ${update.session.id}` },
|
|
233
|
+
currentArtifact: milestone?.currentArtifact,
|
|
234
|
+
nextAction: milestone?.nextAction,
|
|
235
|
+
latestNote: obligationNoteFromUpdate(update) ?? undefined,
|
|
236
|
+
});
|
|
237
|
+
}
|
|
238
|
+
catch {
|
|
239
|
+
// Detached feedback should still reach the human even if obligation sync is unavailable.
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
async function wakeInnerDialogForObligation(update) {
|
|
243
|
+
if (!update.session.obligationId || !OBLIGATION_WAKE_UPDATE_KINDS.has(update.kind)) {
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
try {
|
|
247
|
+
await (0, socket_client_1.requestInnerWake)((0, identity_1.getAgentName)());
|
|
248
|
+
}
|
|
249
|
+
catch (error) {
|
|
250
|
+
(0, runtime_1.emitNervesEvent)({
|
|
251
|
+
level: "warn",
|
|
252
|
+
component: "repertoire",
|
|
253
|
+
event: "repertoire.coding_feedback_wake_error",
|
|
254
|
+
message: "coding feedback wake request failed",
|
|
255
|
+
meta: {
|
|
256
|
+
sessionId: update.session.id,
|
|
257
|
+
kind: update.kind,
|
|
258
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
259
|
+
},
|
|
260
|
+
});
|
|
261
|
+
}
|
|
99
262
|
}
|
|
100
263
|
function attachCodingSessionFeedback(manager, session, target) {
|
|
101
264
|
let lastMessage = "";
|
|
102
265
|
let closed = false;
|
|
103
|
-
let unsubscribe =
|
|
266
|
+
let unsubscribe = null;
|
|
104
267
|
const sendMessage = (message) => {
|
|
105
268
|
if (closed || !message || message === lastMessage) {
|
|
106
269
|
return;
|
|
@@ -119,16 +282,20 @@ function attachCodingSessionFeedback(manager, session, target) {
|
|
|
119
282
|
});
|
|
120
283
|
});
|
|
121
284
|
};
|
|
122
|
-
|
|
285
|
+
const spawnedUpdate = { kind: "spawned", session };
|
|
286
|
+
syncObligationFromUpdate(spawnedUpdate);
|
|
287
|
+
sendMessage(formatReportBackMessage(spawnedUpdate, formatUpdateMessage(spawnedUpdate)));
|
|
123
288
|
unsubscribe = manager.subscribe(session.id, async (update) => {
|
|
124
|
-
|
|
289
|
+
syncObligationFromUpdate(update);
|
|
290
|
+
sendMessage(formatReportBackMessage(update, formatUpdateMessage(update)));
|
|
291
|
+
await wakeInnerDialogForObligation(update);
|
|
125
292
|
if (TERMINAL_UPDATE_KINDS.has(update.kind)) {
|
|
126
293
|
closed = true;
|
|
127
|
-
unsubscribe();
|
|
294
|
+
unsubscribe?.();
|
|
128
295
|
}
|
|
129
296
|
});
|
|
130
297
|
return () => {
|
|
131
298
|
closed = true;
|
|
132
|
-
unsubscribe();
|
|
299
|
+
unsubscribe?.();
|
|
133
300
|
};
|
|
134
301
|
}
|
|
@@ -39,17 +39,12 @@ const path = __importStar(require("path"));
|
|
|
39
39
|
const identity_1 = require("../../heart/identity");
|
|
40
40
|
const runtime_1 = require("../../nerves/runtime");
|
|
41
41
|
const spawner_1 = require("./spawner");
|
|
42
|
-
function safeAgentName() {
|
|
43
|
-
try {
|
|
44
|
-
return (0, identity_1.getAgentName)();
|
|
45
|
-
}
|
|
46
|
-
catch {
|
|
47
|
-
return "default";
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
42
|
function defaultStateFilePath(agentName) {
|
|
51
43
|
return path.join((0, identity_1.getAgentRoot)(agentName), "state", "coding", "sessions.json");
|
|
52
44
|
}
|
|
45
|
+
function defaultArtifactDirPath(agentName) {
|
|
46
|
+
return path.join((0, identity_1.getAgentRoot)(agentName), "state", "coding", "sessions");
|
|
47
|
+
}
|
|
53
48
|
function isPidAlive(pid) {
|
|
54
49
|
try {
|
|
55
50
|
process.kill(pid, 0);
|
|
@@ -62,6 +57,9 @@ function isPidAlive(pid) {
|
|
|
62
57
|
function cloneSession(session) {
|
|
63
58
|
return {
|
|
64
59
|
...session,
|
|
60
|
+
originSession: session.originSession ? { ...session.originSession } : undefined,
|
|
61
|
+
checkpoint: session.checkpoint ?? null,
|
|
62
|
+
artifactPath: session.artifactPath,
|
|
65
63
|
stdoutTail: session.stdoutTail,
|
|
66
64
|
stderrTail: session.stderrTail,
|
|
67
65
|
failure: session.failure
|
|
@@ -85,6 +83,46 @@ function appendTail(existing, nextChunk, maxLength = 2000) {
|
|
|
85
83
|
const combined = `${existing}${nextChunk}`;
|
|
86
84
|
return combined.length <= maxLength ? combined : combined.slice(combined.length - maxLength);
|
|
87
85
|
}
|
|
86
|
+
function compactText(text) {
|
|
87
|
+
return text.replace(/\s+/g, " ").trim();
|
|
88
|
+
}
|
|
89
|
+
function clipText(text, maxLength = 240) {
|
|
90
|
+
return text.length <= maxLength ? text : `${text.slice(0, maxLength - 3)}...`;
|
|
91
|
+
}
|
|
92
|
+
function latestMeaningfulLine(text) {
|
|
93
|
+
const lines = text
|
|
94
|
+
.split(/\r?\n/)
|
|
95
|
+
.map((line) => compactText(line))
|
|
96
|
+
.filter(Boolean);
|
|
97
|
+
if (lines.length === 0)
|
|
98
|
+
return null;
|
|
99
|
+
return clipText(lines.at(-1));
|
|
100
|
+
}
|
|
101
|
+
function fallbackCheckpoint(status, code, signal) {
|
|
102
|
+
switch (status) {
|
|
103
|
+
case "waiting_input":
|
|
104
|
+
return "needs input";
|
|
105
|
+
case "stalled":
|
|
106
|
+
return "no recent output";
|
|
107
|
+
case "completed":
|
|
108
|
+
return "completed";
|
|
109
|
+
case "failed":
|
|
110
|
+
if (code !== null)
|
|
111
|
+
return `exit code ${code}`;
|
|
112
|
+
if (signal)
|
|
113
|
+
return `terminated by ${signal}`;
|
|
114
|
+
return "failed";
|
|
115
|
+
case "killed":
|
|
116
|
+
return "terminated by parent agent";
|
|
117
|
+
default:
|
|
118
|
+
return null;
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function deriveCheckpoint(session) {
|
|
122
|
+
return (latestMeaningfulLine(session.stderrTail)
|
|
123
|
+
?? latestMeaningfulLine(session.stdoutTail)
|
|
124
|
+
?? fallbackCheckpoint(session.status, session.lastExitCode, session.lastSignal));
|
|
125
|
+
}
|
|
88
126
|
function isSpawnCodingResult(value) {
|
|
89
127
|
return typeof value === "object" && value !== null && "process" in value;
|
|
90
128
|
}
|
|
@@ -122,6 +160,7 @@ class CodingSessionManager {
|
|
|
122
160
|
maxRestarts;
|
|
123
161
|
defaultStallThresholdMs;
|
|
124
162
|
stateFilePath;
|
|
163
|
+
artifactDirPath;
|
|
125
164
|
existsSync;
|
|
126
165
|
readFileSync;
|
|
127
166
|
writeFileSync;
|
|
@@ -139,8 +178,19 @@ class CodingSessionManager {
|
|
|
139
178
|
this.writeFileSync = options.writeFileSync ?? fs.writeFileSync;
|
|
140
179
|
this.mkdirSync = options.mkdirSync ?? fs.mkdirSync;
|
|
141
180
|
this.pidAlive = options.pidAlive ?? isPidAlive;
|
|
142
|
-
|
|
181
|
+
// No silent fallback to "default" — if there's no agentName and no
|
|
182
|
+
// explicit option, getAgentName() throws. The previous `safeAgentName`
|
|
183
|
+
// helper fell back to "default" and ended up writing coding session
|
|
184
|
+
// state to `~/AgentBundles/default.ouro/state/coding/sessions.json` on
|
|
185
|
+
// every vitest run because the coding manager singleton constructs with
|
|
186
|
+
// `{}`. That leaked real-fs state into the developer's home directory
|
|
187
|
+
// on every coverage run. Production callers always pass via argv (see
|
|
188
|
+
// getAgentName); test callers must either pass `agentName` explicitly
|
|
189
|
+
// or mock `../../heart/identity`.
|
|
190
|
+
this.agentName = options.agentName ?? (0, identity_1.getAgentName)();
|
|
143
191
|
this.stateFilePath = options.stateFilePath ?? defaultStateFilePath(this.agentName);
|
|
192
|
+
this.artifactDirPath = options.artifactDirPath
|
|
193
|
+
?? (options.stateFilePath ? path.dirname(options.stateFilePath) : defaultArtifactDirPath(this.agentName));
|
|
144
194
|
this.loadPersistedState();
|
|
145
195
|
}
|
|
146
196
|
async spawnSession(request) {
|
|
@@ -157,8 +207,12 @@ class CodingSessionManager {
|
|
|
157
207
|
runner: normalizedRequest.runner,
|
|
158
208
|
workdir: normalizedRequest.workdir,
|
|
159
209
|
taskRef: normalizedRequest.taskRef,
|
|
210
|
+
originSession: normalizedRequest.originSession ? { ...normalizedRequest.originSession } : undefined,
|
|
211
|
+
obligationId: normalizedRequest.obligationId,
|
|
160
212
|
scopeFile: normalizedRequest.scopeFile,
|
|
161
213
|
stateFile: normalizedRequest.stateFile,
|
|
214
|
+
checkpoint: null,
|
|
215
|
+
artifactPath: this.artifactPathFor(id),
|
|
162
216
|
status: "spawning",
|
|
163
217
|
stdoutTail: "",
|
|
164
218
|
stderrTail: "",
|
|
@@ -245,6 +299,7 @@ class CodingSessionManager {
|
|
|
245
299
|
record.process.kill("SIGTERM");
|
|
246
300
|
record.process = null;
|
|
247
301
|
record.session.status = "killed";
|
|
302
|
+
record.session.checkpoint = "terminated by parent agent";
|
|
248
303
|
record.session.endedAt = this.nowIso();
|
|
249
304
|
(0, runtime_1.emitNervesEvent)({
|
|
250
305
|
component: "repertoire",
|
|
@@ -267,6 +322,7 @@ class CodingSessionManager {
|
|
|
267
322
|
continue;
|
|
268
323
|
stalled += 1;
|
|
269
324
|
record.session.status = "stalled";
|
|
325
|
+
record.session.checkpoint = deriveCheckpoint(record.session);
|
|
270
326
|
(0, runtime_1.emitNervesEvent)({
|
|
271
327
|
level: "warn",
|
|
272
328
|
component: "repertoire",
|
|
@@ -292,6 +348,7 @@ class CodingSessionManager {
|
|
|
292
348
|
record.process = null;
|
|
293
349
|
if (record.session.status === "running" || record.session.status === "spawning") {
|
|
294
350
|
record.session.status = "killed";
|
|
351
|
+
record.session.checkpoint = "terminated during manager shutdown";
|
|
295
352
|
record.session.endedAt = this.nowIso();
|
|
296
353
|
}
|
|
297
354
|
}
|
|
@@ -336,6 +393,13 @@ class CodingSessionManager {
|
|
|
336
393
|
record.session.endedAt = this.nowIso();
|
|
337
394
|
updateKind = "completed";
|
|
338
395
|
}
|
|
396
|
+
const checkpoint = latestMeaningfulLine(text);
|
|
397
|
+
if (checkpoint) {
|
|
398
|
+
record.session.checkpoint = checkpoint;
|
|
399
|
+
}
|
|
400
|
+
else if (!record.session.checkpoint) {
|
|
401
|
+
record.session.checkpoint = deriveCheckpoint(record.session);
|
|
402
|
+
}
|
|
339
403
|
(0, runtime_1.emitNervesEvent)({
|
|
340
404
|
component: "repertoire",
|
|
341
405
|
event: "repertoire.coding_session_output",
|
|
@@ -359,12 +423,14 @@ class CodingSessionManager {
|
|
|
359
423
|
record.session.lastSignal = signal;
|
|
360
424
|
if (record.session.status === "killed" || record.session.status === "completed") {
|
|
361
425
|
record.session.endedAt = this.nowIso();
|
|
426
|
+
record.session.checkpoint = deriveCheckpoint(record.session);
|
|
362
427
|
this.persistState();
|
|
363
428
|
return;
|
|
364
429
|
}
|
|
365
430
|
if (code === 0) {
|
|
366
431
|
record.session.status = "completed";
|
|
367
432
|
record.session.endedAt = this.nowIso();
|
|
433
|
+
record.session.checkpoint = deriveCheckpoint(record.session);
|
|
368
434
|
this.persistState();
|
|
369
435
|
this.notifyListeners(record.session.id, { kind: "completed", session: cloneSession(record.session) });
|
|
370
436
|
return;
|
|
@@ -376,6 +442,7 @@ class CodingSessionManager {
|
|
|
376
442
|
record.session.status = "failed";
|
|
377
443
|
record.session.endedAt = this.nowIso();
|
|
378
444
|
record.session.failure = defaultFailureDiagnostics(code, signal, record.command, record.args, record.stdoutTail, record.stderrTail);
|
|
445
|
+
record.session.checkpoint = deriveCheckpoint(record.session);
|
|
379
446
|
(0, runtime_1.emitNervesEvent)({
|
|
380
447
|
level: "error",
|
|
381
448
|
component: "repertoire",
|
|
@@ -401,6 +468,7 @@ class CodingSessionManager {
|
|
|
401
468
|
record.session.lastActivityAt = this.nowIso();
|
|
402
469
|
record.session.endedAt = null;
|
|
403
470
|
record.session.failure = null;
|
|
471
|
+
record.session.checkpoint = `restarted after ${reason}`;
|
|
404
472
|
this.attachProcessListeners(record);
|
|
405
473
|
(0, runtime_1.emitNervesEvent)({
|
|
406
474
|
level: "warn",
|
|
@@ -482,15 +550,21 @@ class CodingSessionManager {
|
|
|
482
550
|
}
|
|
483
551
|
const normalizedRequest = {
|
|
484
552
|
...request,
|
|
553
|
+
originSession: request.originSession ? { ...request.originSession } : undefined,
|
|
485
554
|
sessionId: request.sessionId ?? session.id,
|
|
555
|
+
obligationId: request.obligationId,
|
|
486
556
|
parentAgent: request.parentAgent ?? this.agentName,
|
|
487
557
|
};
|
|
488
558
|
const normalizedSession = {
|
|
489
559
|
...session,
|
|
490
560
|
taskRef: session.taskRef ?? normalizedRequest.taskRef,
|
|
561
|
+
originSession: session.originSession ?? normalizedRequest.originSession,
|
|
562
|
+
obligationId: session.obligationId ?? normalizedRequest.obligationId,
|
|
491
563
|
failure: session.failure ?? null,
|
|
492
564
|
stdoutTail: session.stdoutTail ?? session.failure?.stdoutTail ?? "",
|
|
493
565
|
stderrTail: session.stderrTail ?? session.failure?.stderrTail ?? "",
|
|
566
|
+
checkpoint: typeof session.checkpoint === "string" ? session.checkpoint : null,
|
|
567
|
+
artifactPath: typeof session.artifactPath === "string" ? session.artifactPath : this.artifactPathFor(session.id),
|
|
494
568
|
};
|
|
495
569
|
if (typeof normalizedSession.pid === "number") {
|
|
496
570
|
const alive = this.pidAlive(normalizedSession.pid);
|
|
@@ -503,6 +577,7 @@ class CodingSessionManager {
|
|
|
503
577
|
normalizedSession.pid = null;
|
|
504
578
|
}
|
|
505
579
|
}
|
|
580
|
+
normalizedSession.checkpoint = normalizedSession.checkpoint ?? deriveCheckpoint(normalizedSession);
|
|
506
581
|
this.records.set(normalizedSession.id, {
|
|
507
582
|
request: normalizedRequest,
|
|
508
583
|
session: normalizedSession,
|
|
@@ -542,6 +617,80 @@ class CodingSessionManager {
|
|
|
542
617
|
meta: { path: this.stateFilePath, reason: error instanceof Error ? error.message : String(error) },
|
|
543
618
|
});
|
|
544
619
|
}
|
|
620
|
+
this.persistArtifacts();
|
|
621
|
+
}
|
|
622
|
+
artifactPathFor(sessionId) {
|
|
623
|
+
return path.join(this.artifactDirPath, `${sessionId}.md`);
|
|
624
|
+
}
|
|
625
|
+
renderArtifact(record) {
|
|
626
|
+
const { request, session } = record;
|
|
627
|
+
const stdout = session.stdoutTail.trim() || "(empty)";
|
|
628
|
+
const stderr = session.stderrTail.trim() || "(empty)";
|
|
629
|
+
const lines = [
|
|
630
|
+
"# Coding Session Artifact",
|
|
631
|
+
"",
|
|
632
|
+
"## Session",
|
|
633
|
+
`id: ${session.id}`,
|
|
634
|
+
`runner: ${session.runner}`,
|
|
635
|
+
`status: ${session.status}`,
|
|
636
|
+
`taskRef: ${session.taskRef ?? "unassigned"}`,
|
|
637
|
+
`workdir: ${session.workdir}`,
|
|
638
|
+
`startedAt: ${session.startedAt}`,
|
|
639
|
+
`lastActivityAt: ${session.lastActivityAt}`,
|
|
640
|
+
`endedAt: ${session.endedAt ?? "active"}`,
|
|
641
|
+
`pid: ${session.pid ?? "none"}`,
|
|
642
|
+
`restarts: ${session.restartCount}`,
|
|
643
|
+
`checkpoint: ${session.checkpoint ?? "none"}`,
|
|
644
|
+
`scopeFile: ${session.scopeFile ?? "none"}`,
|
|
645
|
+
`stateFile: ${session.stateFile ?? "none"}`,
|
|
646
|
+
"",
|
|
647
|
+
"## Request",
|
|
648
|
+
request.prompt,
|
|
649
|
+
"",
|
|
650
|
+
"## Stdout Tail",
|
|
651
|
+
stdout,
|
|
652
|
+
"",
|
|
653
|
+
"## Stderr Tail",
|
|
654
|
+
stderr,
|
|
655
|
+
];
|
|
656
|
+
if (session.failure) {
|
|
657
|
+
lines.push("", "## Failure", `command: ${session.failure.command}`, `args: ${session.failure.args.join(" ") || "(none)"}`, `code: ${session.failure.code ?? "null"}`, `signal: ${session.failure.signal ?? "null"}`);
|
|
658
|
+
}
|
|
659
|
+
return `${lines.join("\n")}\n`;
|
|
660
|
+
}
|
|
661
|
+
persistArtifacts() {
|
|
662
|
+
try {
|
|
663
|
+
this.mkdirSync(this.artifactDirPath, { recursive: true });
|
|
664
|
+
}
|
|
665
|
+
catch (error) {
|
|
666
|
+
(0, runtime_1.emitNervesEvent)({
|
|
667
|
+
level: "warn",
|
|
668
|
+
component: "repertoire",
|
|
669
|
+
event: "repertoire.coding_artifact_persist_error",
|
|
670
|
+
message: "failed preparing coding artifact directory",
|
|
671
|
+
meta: { path: this.artifactDirPath, reason: error instanceof Error ? error.message : String(error) },
|
|
672
|
+
});
|
|
673
|
+
return;
|
|
674
|
+
}
|
|
675
|
+
for (const record of this.records.values()) {
|
|
676
|
+
try {
|
|
677
|
+
record.session.artifactPath = record.session.artifactPath ?? this.artifactPathFor(record.session.id);
|
|
678
|
+
this.writeFileSync(record.session.artifactPath, this.renderArtifact(record), "utf-8");
|
|
679
|
+
}
|
|
680
|
+
catch (error) {
|
|
681
|
+
(0, runtime_1.emitNervesEvent)({
|
|
682
|
+
level: "warn",
|
|
683
|
+
component: "repertoire",
|
|
684
|
+
event: "repertoire.coding_artifact_persist_error",
|
|
685
|
+
message: "failed writing coding session artifact",
|
|
686
|
+
meta: {
|
|
687
|
+
id: record.session.id,
|
|
688
|
+
path: record.session.artifactPath ?? this.artifactPathFor(record.session.id),
|
|
689
|
+
reason: error instanceof Error ? error.message : String(error),
|
|
690
|
+
},
|
|
691
|
+
});
|
|
692
|
+
}
|
|
693
|
+
}
|
|
545
694
|
}
|
|
546
695
|
}
|
|
547
696
|
exports.CodingSessionManager = CodingSessionManager;
|
|
@@ -36,8 +36,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
36
36
|
exports.spawnCodingProcess = spawnCodingProcess;
|
|
37
37
|
const child_process_1 = require("child_process");
|
|
38
38
|
const fs = __importStar(require("fs"));
|
|
39
|
+
const os = __importStar(require("os"));
|
|
40
|
+
const path = __importStar(require("path"));
|
|
39
41
|
const runtime_1 = require("../../nerves/runtime");
|
|
40
|
-
function buildCommandArgs(runner, workdir) {
|
|
42
|
+
function buildCommandArgs(runner, workdir, parentAgent) {
|
|
41
43
|
if (runner === "claude") {
|
|
42
44
|
return {
|
|
43
45
|
command: "claude",
|
|
@@ -53,25 +55,65 @@ function buildCommandArgs(runner, workdir) {
|
|
|
53
55
|
],
|
|
54
56
|
};
|
|
55
57
|
}
|
|
58
|
+
const agent = parentAgent ?? "unknown";
|
|
59
|
+
// Use absolute path to ouro-entry.js so MCP works in both dev and installed mode
|
|
60
|
+
// __dirname at runtime is dist/repertoire/coding/ — go up 2 levels to dist/
|
|
61
|
+
const distRoot = path.resolve(__dirname, "..", "..");
|
|
62
|
+
const ouroEntryPath = path.join(distRoot, "heart", "daemon", "ouro-entry.js");
|
|
56
63
|
return {
|
|
57
64
|
command: "codex",
|
|
58
|
-
args: [
|
|
65
|
+
args: [
|
|
66
|
+
"exec",
|
|
67
|
+
"--skip-git-repo-check",
|
|
68
|
+
"--cd",
|
|
69
|
+
workdir,
|
|
70
|
+
"--ephemeral",
|
|
71
|
+
"--json",
|
|
72
|
+
"-c",
|
|
73
|
+
`mcp_servers.ouro.command=node`,
|
|
74
|
+
"-c",
|
|
75
|
+
`mcp_servers.ouro.args=["${ouroEntryPath}","mcp-serve","--agent","${agent}"]`,
|
|
76
|
+
],
|
|
59
77
|
};
|
|
60
78
|
}
|
|
79
|
+
function buildSpawnEnv(baseEnv, homeDir) {
|
|
80
|
+
const binDir = path.join(homeDir, ".ouro-cli", "bin");
|
|
81
|
+
const existingPath = baseEnv.PATH ?? "";
|
|
82
|
+
const pathEntries = existingPath.split(path.delimiter).filter((entry) => entry.length > 0);
|
|
83
|
+
if (!pathEntries.includes(binDir)) {
|
|
84
|
+
pathEntries.unshift(binDir);
|
|
85
|
+
}
|
|
86
|
+
return {
|
|
87
|
+
...baseEnv,
|
|
88
|
+
PATH: pathEntries.join(path.delimiter),
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
function appendFileSection(sections, label, filePath, deps) {
|
|
92
|
+
if (!filePath || !deps.existsSync(filePath))
|
|
93
|
+
return;
|
|
94
|
+
const content = deps.readFileSync(filePath, "utf-8").trim();
|
|
95
|
+
if (content.length === 0)
|
|
96
|
+
return;
|
|
97
|
+
sections.push(`${label} (${filePath}):\n${content}`);
|
|
98
|
+
}
|
|
61
99
|
function buildPrompt(request, deps) {
|
|
62
100
|
const sections = [];
|
|
101
|
+
sections.push([
|
|
102
|
+
"Execution contract:",
|
|
103
|
+
"- You are a subordinate coding session launched by a parent Ouro agent.",
|
|
104
|
+
"- Execute the concrete request in the supplied workdir directly.",
|
|
105
|
+
"- Do not switch into planning/doing workflows, approval gates, or repo-management rituals unless the request explicitly asks for them.",
|
|
106
|
+
"- Treat the request, scope file, and state file as the authoritative briefing for this session.",
|
|
107
|
+
"- Prefer direct execution and verification over narration.",
|
|
108
|
+
].join("\n"));
|
|
63
109
|
sections.push([
|
|
64
110
|
"Coding session metadata:",
|
|
65
111
|
`sessionId: ${request.sessionId ?? "pending"}`,
|
|
66
112
|
`parentAgent: ${request.parentAgent ?? "unknown"}`,
|
|
67
113
|
`taskRef: ${request.taskRef ?? "unassigned"}`,
|
|
68
114
|
].join("\n"));
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
if (stateContent.length > 0) {
|
|
72
|
-
sections.push(`State file (${request.stateFile}):\n${stateContent}`);
|
|
73
|
-
}
|
|
74
|
-
}
|
|
115
|
+
appendFileSection(sections, "Scope file", request.scopeFile, deps);
|
|
116
|
+
appendFileSection(sections, "State file", request.stateFile, deps);
|
|
75
117
|
sections.push(request.prompt);
|
|
76
118
|
return sections.join("\n\n---\n\n");
|
|
77
119
|
}
|
|
@@ -79,8 +121,11 @@ function spawnCodingProcess(request, deps = {}) {
|
|
|
79
121
|
const spawnFn = deps.spawnFn ?? ((command, args, options) => (0, child_process_1.spawn)(command, args, options));
|
|
80
122
|
const existsSync = deps.existsSync ?? fs.existsSync;
|
|
81
123
|
const readFileSync = deps.readFileSync ?? fs.readFileSync;
|
|
124
|
+
const homeDir = deps.homeDir ?? os.homedir();
|
|
125
|
+
const baseEnv = deps.baseEnv ?? process.env;
|
|
82
126
|
const prompt = buildPrompt(request, { existsSync, readFileSync });
|
|
83
|
-
const { command, args } = buildCommandArgs(request.runner, request.workdir);
|
|
127
|
+
const { command, args } = buildCommandArgs(request.runner, request.workdir, request.parentAgent);
|
|
128
|
+
const env = buildSpawnEnv(baseEnv, homeDir);
|
|
84
129
|
(0, runtime_1.emitNervesEvent)({
|
|
85
130
|
component: "repertoire",
|
|
86
131
|
event: "repertoire.coding_spawn_start",
|
|
@@ -89,6 +134,7 @@ function spawnCodingProcess(request, deps = {}) {
|
|
|
89
134
|
});
|
|
90
135
|
const proc = spawnFn(command, args, {
|
|
91
136
|
cwd: request.workdir,
|
|
137
|
+
env,
|
|
92
138
|
stdio: ["pipe", "pipe", "pipe"],
|
|
93
139
|
});
|
|
94
140
|
proc.stdin.end(`${prompt}\n`);
|