@ouro.bot/cli 0.1.0-alpha.48 → 0.1.0-alpha.480
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 +132 -19
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/agent.json +3 -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 +3061 -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 +857 -0
- 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 +426 -0
- package/dist/heart/background-operations.js +234 -0
- package/dist/heart/bridges/manager.js +358 -0
- package/dist/heart/bridges/state-machine.js +135 -0
- package/dist/heart/bridges/store.js +123 -0
- package/dist/heart/bundle-state.js +168 -0
- package/dist/heart/commitments.js +111 -0
- package/dist/heart/config-registry.js +304 -0
- package/dist/heart/config.js +110 -128
- package/dist/heart/core.js +745 -227
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +490 -0
- package/dist/heart/daemon/agent-discovery.js +79 -3
- package/dist/heart/daemon/agent-service.js +360 -0
- package/dist/heart/daemon/agentic-repair.js +216 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +640 -0
- package/dist/heart/daemon/cli-exec.js +6933 -0
- package/dist/heart/daemon/cli-help.js +487 -0
- package/dist/heart/daemon/cli-parse.js +1527 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +561 -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 -1616
- package/dist/heart/daemon/daemon-entry.js +345 -3
- package/dist/heart/daemon/daemon-health.js +141 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +190 -12
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +677 -58
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +486 -0
- package/dist/heart/daemon/health-monitor.js +92 -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 +25 -5
- package/dist/heart/daemon/log-tailer.js +82 -12
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/message-router.js +2 -2
- package/dist/heart/daemon/os-cron-deps.js +134 -0
- 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 +214 -0
- 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 +73 -0
- package/dist/heart/daemon/runtime-mode.js +67 -0
- package/dist/heart/daemon/safe-mode.js +161 -0
- package/dist/heart/daemon/sense-manager.js +178 -37
- 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 +109 -4
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +264 -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 +149 -10
- package/dist/heart/daemon/up-progress.js +366 -0
- package/dist/heart/daemon/vault-items.js +56 -0
- package/dist/heart/delegation.js +62 -0
- package/dist/heart/habits/habit-migration.js +189 -0
- package/dist/heart/habits/habit-parser.js +140 -0
- package/dist/heart/habits/habit-runtime-state.js +100 -0
- package/dist/heart/habits/habit-scheduler.js +372 -0
- package/dist/heart/{daemon → hatch}/hatch-flow.js +52 -117
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
- 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 +201 -66
- 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/mcp/mcp-server.js +653 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +59 -0
- package/dist/heart/outlook/outlook-http-hooks.js +66 -0
- package/dist/heart/outlook/outlook-http-response.js +7 -0
- package/dist/heart/outlook/outlook-http-routes.js +244 -0
- package/dist/heart/outlook/outlook-http-static.js +99 -0
- package/dist/heart/outlook/outlook-http-transport.js +116 -0
- package/dist/heart/outlook/outlook-http.js +99 -0
- package/dist/heart/outlook/outlook-read.js +31 -0
- package/dist/heart/outlook/outlook-types.js +27 -0
- package/dist/heart/outlook/outlook-view.js +195 -0
- package/dist/heart/outlook/readers/agent-machine.js +359 -0
- package/dist/heart/outlook/readers/continuity-readers.js +332 -0
- package/dist/heart/outlook/readers/mail.js +362 -0
- package/dist/heart/outlook/readers/runtime-readers.js +644 -0
- package/dist/heart/outlook/readers/sessions.js +232 -0
- package/dist/heart/outlook/readers/shared.js +111 -0
- package/dist/heart/platform.js +81 -0
- package/dist/heart/progress-story.js +42 -0
- package/dist/heart/provider-attempt.js +134 -0
- package/dist/heart/provider-binding-resolver.js +255 -0
- package/dist/heart/provider-credentials.js +424 -0
- package/dist/heart/provider-failover.js +266 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +262 -0
- package/dist/heart/provider-state.js +216 -0
- package/dist/heart/provider-visibility.js +188 -0
- package/dist/heart/providers/anthropic-token.js +131 -0
- package/dist/heart/providers/anthropic.js +193 -55
- package/dist/heart/providers/azure.js +103 -12
- package/dist/heart/providers/error-classification.js +63 -0
- package/dist/heart/providers/github-copilot.js +145 -0
- package/dist/heart/providers/minimax-vlm.js +189 -0
- package/dist/heart/providers/minimax.js +29 -7
- package/dist/heart/providers/openai-codex.js +62 -38
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +260 -0
- package/dist/heart/sense-truth.js +11 -4
- package/dist/heart/session-activity.js +190 -0
- package/dist/heart/session-events.js +855 -0
- package/dist/heart/session-transcript.js +167 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +36 -27
- package/dist/heart/sync.js +332 -0
- package/dist/heart/target-resolution.js +127 -0
- package/dist/heart/tempo.js +93 -0
- package/dist/heart/temporal-view.js +41 -0
- package/dist/heart/tool-activity-callbacks.js +36 -0
- package/dist/heart/tool-description.js +135 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +361 -0
- package/dist/heart/turn-coordinator.js +24 -1
- package/dist/heart/{daemon → versioning}/ouro-bot-global-installer.js +1 -1
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +425 -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 +5 -1
- package/dist/heart/{daemon → versioning}/update-hooks.js +63 -59
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +558 -0
- package/dist/mailroom/core.js +658 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +400 -0
- package/dist/mailroom/mbox-import.js +341 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +197 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +7 -1
- package/dist/mind/context.js +132 -93
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +74 -93
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/friends/channel.js +30 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +38 -1
- package/dist/mind/friends/store-file.js +39 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- 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 +66 -7
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +978 -169
- 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 +84 -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/runtime.js +5 -1
- package/dist/outlook-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/outlook-ui/assets/index-CPfhbn13.js +61 -0
- package/dist/outlook-ui/index.html +15 -0
- 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 +774 -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 +111 -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 +255 -0
- package/dist/repertoire/mcp-manager.js +305 -0
- package/dist/repertoire/mcp-tools.js +63 -0
- package/dist/repertoire/shell-sessions.js +133 -0
- package/dist/repertoire/skills.js +15 -24
- package/dist/repertoire/stripe-client.js +131 -0
- package/dist/repertoire/tasks/board.js +43 -5
- package/dist/repertoire/tasks/fix.js +182 -0
- package/dist/repertoire/tasks/index.js +37 -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 +44 -740
- package/dist/repertoire/tools-bluebubbles.js +1 -0
- package/dist/repertoire/tools-bridge.js +141 -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 +105 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +896 -0
- package/dist/repertoire/tools-notes.js +376 -0
- package/dist/repertoire/tools-session.js +746 -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-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +144 -113
- 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 +561 -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/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 +73 -0
- package/dist/senses/{bluebubbles-inbound-log.js → bluebubbles/inbound-log.js} +7 -3
- package/dist/senses/{bluebubbles.js → bluebubbles/index.js} +705 -116
- 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/replay.js +129 -0
- package/dist/senses/{bluebubbles-runtime-state.js → bluebubbles/runtime-state.js} +2 -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 +605 -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 +83 -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 +516 -211
- package/dist/senses/commands.js +66 -3
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +97 -17
- package/dist/senses/inner-dialog.js +404 -14
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +232 -0
- package/dist/senses/pipeline.js +533 -72
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +205 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +413 -163
- package/dist/senses/trust-gate.js +5 -5
- package/package.json +37 -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/ouro-path-installer.js +0 -178
- package/dist/heart/daemon/subagent-installer.js +0 -166
- package/dist/mind/associative-recall.js +0 -209
- package/dist/senses/bluebubbles-entry.js +0 -13
- package/dist/senses/debug-activity.js +0 -127
- 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
|
@@ -37,6 +37,115 @@ exports.bundleMetaHook = bundleMetaHook;
|
|
|
37
37
|
const fs = __importStar(require("fs"));
|
|
38
38
|
const path = __importStar(require("path"));
|
|
39
39
|
const runtime_1 = require("../../../nerves/runtime");
|
|
40
|
+
/**
|
|
41
|
+
* Migrate bundle from schema 1 to schema 2:
|
|
42
|
+
* - Move state/{episodes,obligations,cares,intentions}/* to arc/{name}/*
|
|
43
|
+
* - Move the old psyche note store to diary/
|
|
44
|
+
* Idempotent: skips missing sources; on collision, newer mtime wins.
|
|
45
|
+
*/
|
|
46
|
+
function migrateToSchema2(agentRoot) {
|
|
47
|
+
(0, runtime_1.emitNervesEvent)({
|
|
48
|
+
component: "daemon",
|
|
49
|
+
event: "daemon.bundle_migration_start",
|
|
50
|
+
message: "migrating bundle to schema 2",
|
|
51
|
+
meta: { agentRoot },
|
|
52
|
+
});
|
|
53
|
+
// Migrate arc entities
|
|
54
|
+
for (const name of ["episodes", "obligations", "cares", "intentions"]) {
|
|
55
|
+
const src = path.join(agentRoot, "state", name);
|
|
56
|
+
const dest = path.join(agentRoot, "arc", name);
|
|
57
|
+
migrateDirectory(src, dest);
|
|
58
|
+
}
|
|
59
|
+
// Migrate diary from the old pre-diary bundle layout.
|
|
60
|
+
const legacyDiarySrc = path.join(agentRoot, "psyche", "mem" + "ory");
|
|
61
|
+
const diaryDest = path.join(agentRoot, "diary");
|
|
62
|
+
migrateDirectory(legacyDiarySrc, diaryDest);
|
|
63
|
+
// Update bundle .gitignore
|
|
64
|
+
updateBundleGitignore(agentRoot);
|
|
65
|
+
(0, runtime_1.emitNervesEvent)({
|
|
66
|
+
component: "daemon",
|
|
67
|
+
event: "daemon.bundle_migration_end",
|
|
68
|
+
message: "bundle migration to schema 2 complete",
|
|
69
|
+
meta: { agentRoot },
|
|
70
|
+
});
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Ensure bundle .gitignore has state/ ignored and does NOT ignore arc/, diary/, journal/.
|
|
74
|
+
*/
|
|
75
|
+
function updateBundleGitignore(agentRoot) {
|
|
76
|
+
const gitignorePath = path.join(agentRoot, ".gitignore");
|
|
77
|
+
let lines = [];
|
|
78
|
+
try {
|
|
79
|
+
if (fs.existsSync(gitignorePath)) {
|
|
80
|
+
lines = fs.readFileSync(gitignorePath, "utf-8").split("\n");
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
catch {
|
|
84
|
+
// If we can't read, start fresh
|
|
85
|
+
}
|
|
86
|
+
// Remove arc/, diary/, journal/ from ignore (they should be tracked)
|
|
87
|
+
const toRemove = new Set(["arc/", "diary/", "journal/"]);
|
|
88
|
+
lines = lines.filter((line) => !toRemove.has(line.trim()));
|
|
89
|
+
// Ensure state/ is in the ignore list
|
|
90
|
+
const hasState = lines.some((line) => line.trim() === "state/");
|
|
91
|
+
if (!hasState) {
|
|
92
|
+
lines.push("state/");
|
|
93
|
+
}
|
|
94
|
+
// Write back, trimming trailing empty lines and ensuring trailing newline
|
|
95
|
+
const content = lines.join("\n").replace(/\n+$/, "") + "\n";
|
|
96
|
+
try {
|
|
97
|
+
fs.writeFileSync(gitignorePath, content, "utf-8");
|
|
98
|
+
}
|
|
99
|
+
catch {
|
|
100
|
+
// Non-blocking: if we can't write .gitignore, migration still succeeds
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Recursively copy files from src to dest.
|
|
105
|
+
* Creates destination directories as needed. Skips if source doesn't exist.
|
|
106
|
+
* When both source and destination exist, compares mtimes: newer file wins.
|
|
107
|
+
* Logs a warning either way when a collision is detected.
|
|
108
|
+
*/
|
|
109
|
+
function migrateDirectory(src, dest) {
|
|
110
|
+
if (!fs.existsSync(src))
|
|
111
|
+
return;
|
|
112
|
+
fs.mkdirSync(dest, { recursive: true });
|
|
113
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
114
|
+
for (const entry of entries) {
|
|
115
|
+
const srcPath = path.join(src, entry.name);
|
|
116
|
+
const destPath = path.join(dest, entry.name);
|
|
117
|
+
if (entry.isDirectory()) {
|
|
118
|
+
migrateDirectory(srcPath, destPath);
|
|
119
|
+
}
|
|
120
|
+
else if (!fs.existsSync(destPath)) {
|
|
121
|
+
fs.copyFileSync(srcPath, destPath);
|
|
122
|
+
}
|
|
123
|
+
else {
|
|
124
|
+
// Collision: both source and destination exist — compare mtimes
|
|
125
|
+
const srcMtime = fs.statSync(srcPath).mtimeMs;
|
|
126
|
+
const destMtime = fs.statSync(destPath).mtimeMs;
|
|
127
|
+
if (srcMtime > destMtime) {
|
|
128
|
+
fs.copyFileSync(srcPath, destPath);
|
|
129
|
+
(0, runtime_1.emitNervesEvent)({
|
|
130
|
+
level: "warn",
|
|
131
|
+
component: "daemon",
|
|
132
|
+
event: "daemon.bundle_migration_collision",
|
|
133
|
+
message: `migration collision: source newer, overwriting destination`,
|
|
134
|
+
meta: { srcPath, destPath, srcMtime, destMtime },
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
else {
|
|
138
|
+
(0, runtime_1.emitNervesEvent)({
|
|
139
|
+
level: "warn",
|
|
140
|
+
component: "daemon",
|
|
141
|
+
event: "daemon.bundle_migration_collision",
|
|
142
|
+
message: `migration collision: destination newer or equal, keeping destination`,
|
|
143
|
+
meta: { srcPath, destPath, srcMtime, destMtime },
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
}
|
|
40
149
|
async function bundleMetaHook(ctx) {
|
|
41
150
|
(0, runtime_1.emitNervesEvent)({
|
|
42
151
|
component: "daemon",
|
|
@@ -56,9 +165,14 @@ async function bundleMetaHook(ctx) {
|
|
|
56
165
|
// Malformed JSON -- treat as missing, will overwrite with fresh
|
|
57
166
|
existing = undefined;
|
|
58
167
|
}
|
|
168
|
+
// Run schema-2 migration if needed
|
|
169
|
+
const currentSchema = existing?.bundleSchemaVersion ?? 1;
|
|
170
|
+
if (currentSchema < 2) {
|
|
171
|
+
migrateToSchema2(ctx.agentRoot);
|
|
172
|
+
}
|
|
59
173
|
const updated = {
|
|
60
174
|
runtimeVersion: ctx.currentVersion,
|
|
61
|
-
bundleSchemaVersion:
|
|
175
|
+
bundleSchemaVersion: currentSchema < 2 ? 2 : currentSchema,
|
|
62
176
|
lastUpdated: new Date().toISOString(),
|
|
63
177
|
};
|
|
64
178
|
// Save old runtimeVersion as previousRuntimeVersion (if there was one)
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
14
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
15
|
+
}) : function(o, v) {
|
|
16
|
+
o["default"] = v;
|
|
17
|
+
});
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
35
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createHttpHealthProbe = createHttpHealthProbe;
|
|
37
|
+
const http = __importStar(require("node:http"));
|
|
38
|
+
function createHttpHealthProbe(name, port, timeoutMs = 5000) {
|
|
39
|
+
return {
|
|
40
|
+
name,
|
|
41
|
+
check: () => new Promise((resolve) => {
|
|
42
|
+
const req = http.get({
|
|
43
|
+
hostname: "127.0.0.1",
|
|
44
|
+
port,
|
|
45
|
+
path: "/health",
|
|
46
|
+
timeout: timeoutMs,
|
|
47
|
+
}, (res) => {
|
|
48
|
+
let body = "";
|
|
49
|
+
res.on("data", (chunk) => {
|
|
50
|
+
body += chunk.toString();
|
|
51
|
+
});
|
|
52
|
+
res.on("end", () => {
|
|
53
|
+
if (res.statusCode !== 200) {
|
|
54
|
+
resolve({ ok: false, detail: `HTTP ${res.statusCode}` });
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
try {
|
|
58
|
+
const parsed = JSON.parse(body);
|
|
59
|
+
if (parsed.status === "ok") {
|
|
60
|
+
resolve({ ok: true });
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
resolve({ ok: false, detail: `unexpected status: ${String(parsed.status)}` });
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
catch {
|
|
67
|
+
resolve({ ok: false, detail: "invalid JSON response" });
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
req.on("timeout", () => {
|
|
72
|
+
req.destroy();
|
|
73
|
+
resolve({ ok: false, detail: "timeout" });
|
|
74
|
+
});
|
|
75
|
+
req.on("error", (err) => {
|
|
76
|
+
resolve({ ok: false, detail: err.message });
|
|
77
|
+
});
|
|
78
|
+
}),
|
|
79
|
+
};
|
|
80
|
+
}
|
|
@@ -0,0 +1,234 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildOuroHomeActions = buildOuroHomeActions;
|
|
4
|
+
exports.resolveOuroHomeAction = resolveOuroHomeAction;
|
|
5
|
+
exports.renderOuroHomeScreen = renderOuroHomeScreen;
|
|
6
|
+
exports.renderAgentPickerScreen = renderAgentPickerScreen;
|
|
7
|
+
exports.resolveNamedAgentSelection = resolveNamedAgentSelection;
|
|
8
|
+
exports.renderHumanReadinessBoard = renderHumanReadinessBoard;
|
|
9
|
+
exports.renderHumanCommandBoard = renderHumanCommandBoard;
|
|
10
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
11
|
+
const terminal_ui_1 = require("./terminal-ui");
|
|
12
|
+
function renderScreenEvent(screen) {
|
|
13
|
+
(0, runtime_1.emitNervesEvent)({
|
|
14
|
+
component: "daemon",
|
|
15
|
+
event: "daemon.human_screen_rendered",
|
|
16
|
+
message: "rendered human command screen",
|
|
17
|
+
meta: { screen },
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
function homeActionSummary(action) {
|
|
21
|
+
switch (action.kind) {
|
|
22
|
+
case "chat":
|
|
23
|
+
return `Open chat with ${action.agent}.`;
|
|
24
|
+
case "up":
|
|
25
|
+
return "Start the local runtime and check what still needs attention.";
|
|
26
|
+
case "connect":
|
|
27
|
+
return "Set up providers, portable tools, and machine-specific attachments.";
|
|
28
|
+
case "repair":
|
|
29
|
+
return "Walk through repairs for anything blocking startup or chat.";
|
|
30
|
+
case "help":
|
|
31
|
+
return "Show the command guide.";
|
|
32
|
+
case "hatch":
|
|
33
|
+
return "Create a new agent on this machine.";
|
|
34
|
+
case "clone":
|
|
35
|
+
return "Bring an existing bundle onto this machine.";
|
|
36
|
+
case "exit":
|
|
37
|
+
return "Leave the prompt.";
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
function actionToWizardItem(action) {
|
|
41
|
+
return {
|
|
42
|
+
key: action.key,
|
|
43
|
+
label: action.label,
|
|
44
|
+
summary: homeActionSummary(action),
|
|
45
|
+
...(action.key === "1" ? { recommended: true } : {}),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function buildOuroHomeActions(agents) {
|
|
49
|
+
if (agents.length === 0) {
|
|
50
|
+
return [
|
|
51
|
+
{ key: "1", label: "Create a new agent", kind: "hatch", command: "ouro hatch" },
|
|
52
|
+
{ key: "2", label: "Clone an existing bundle", kind: "clone", command: "ouro clone <remote>" },
|
|
53
|
+
{ key: "3", label: "Show help", kind: "help", command: "ouro --help" },
|
|
54
|
+
{ key: "4", label: "Exit", kind: "exit", command: "exit" },
|
|
55
|
+
];
|
|
56
|
+
}
|
|
57
|
+
const actions = agents.map((agent, index) => ({
|
|
58
|
+
key: String(index + 1),
|
|
59
|
+
label: `Talk to ${agent}`,
|
|
60
|
+
kind: "chat",
|
|
61
|
+
command: `ouro chat ${agent}`,
|
|
62
|
+
agent,
|
|
63
|
+
}));
|
|
64
|
+
return [
|
|
65
|
+
...actions,
|
|
66
|
+
{ key: String(actions.length + 1), label: "Start or check Ouro", kind: "up", command: "ouro up" },
|
|
67
|
+
{ key: String(actions.length + 2), label: "Set up connections", kind: "connect", command: "ouro connect --agent <agent>" },
|
|
68
|
+
{ key: String(actions.length + 3), label: "Fix setup issues", kind: "repair", command: "ouro repair --agent <agent>" },
|
|
69
|
+
{ key: String(actions.length + 4), label: "Show help", kind: "help", command: "ouro --help" },
|
|
70
|
+
{ key: String(actions.length + 5), label: "Exit", kind: "exit", command: "exit" },
|
|
71
|
+
];
|
|
72
|
+
}
|
|
73
|
+
function resolveOuroHomeAction(answer, actions) {
|
|
74
|
+
const normalized = answer.trim().toLowerCase();
|
|
75
|
+
if (!normalized)
|
|
76
|
+
return undefined;
|
|
77
|
+
const byKey = actions.find((action) => action.key === normalized);
|
|
78
|
+
if (byKey)
|
|
79
|
+
return byKey;
|
|
80
|
+
const byAgent = actions.find((action) => action.agent?.toLowerCase() === normalized);
|
|
81
|
+
if (byAgent)
|
|
82
|
+
return byAgent;
|
|
83
|
+
return actions.find((action) => action.kind === normalized || action.label.toLowerCase() === normalized);
|
|
84
|
+
}
|
|
85
|
+
function renderOuroHomeScreen(options) {
|
|
86
|
+
renderScreenEvent("home");
|
|
87
|
+
const actions = buildOuroHomeActions(options.agents);
|
|
88
|
+
const chatActions = actions.filter((action) => action.kind === "chat");
|
|
89
|
+
const setupActions = actions.filter((action) => action.kind !== "chat");
|
|
90
|
+
const sections = options.agents.length === 0
|
|
91
|
+
? [
|
|
92
|
+
{
|
|
93
|
+
title: "Start here",
|
|
94
|
+
summary: "There are no agents on this machine yet.",
|
|
95
|
+
items: setupActions.map((action) => actionToWizardItem(action)),
|
|
96
|
+
},
|
|
97
|
+
]
|
|
98
|
+
: [
|
|
99
|
+
{
|
|
100
|
+
title: "Agents",
|
|
101
|
+
summary: "Jump straight into conversation or pick a setup path below.",
|
|
102
|
+
items: chatActions.map((action) => actionToWizardItem(action)),
|
|
103
|
+
},
|
|
104
|
+
{
|
|
105
|
+
title: "System",
|
|
106
|
+
items: setupActions.map((action) => actionToWizardItem(action)),
|
|
107
|
+
},
|
|
108
|
+
];
|
|
109
|
+
return (0, terminal_ui_1.renderTerminalWizard)({
|
|
110
|
+
isTTY: options.isTTY,
|
|
111
|
+
columns: options.columns,
|
|
112
|
+
masthead: {
|
|
113
|
+
subtitle: options.agents.length === 0
|
|
114
|
+
? "No agents are set up on this machine yet."
|
|
115
|
+
: "Choose an agent or a setup task.",
|
|
116
|
+
},
|
|
117
|
+
title: "Ouro home",
|
|
118
|
+
summary: options.agents.length === 0
|
|
119
|
+
? "Create a new agent or clone an existing bundle to get started."
|
|
120
|
+
: "Choose an agent or a setup task without memorizing commands.",
|
|
121
|
+
sections,
|
|
122
|
+
nextStep: {
|
|
123
|
+
label: options.agents.length === 0 ? "Start by creating or cloning an agent." : `Start with ${actions[0].label}.`,
|
|
124
|
+
detail: options.agents.length === 0
|
|
125
|
+
? "Once one agent bundle exists here, the rest of the command surface becomes interactive."
|
|
126
|
+
: "You can always type the number or the agent name instead of remembering a command.",
|
|
127
|
+
},
|
|
128
|
+
prompt: `Choose [1-${actions.length}] or type a name: `,
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
function renderAgentPickerScreen(options) {
|
|
132
|
+
renderScreenEvent("agent-picker");
|
|
133
|
+
return (0, terminal_ui_1.renderTerminalWizard)({
|
|
134
|
+
isTTY: options.isTTY,
|
|
135
|
+
columns: options.columns,
|
|
136
|
+
masthead: {
|
|
137
|
+
subtitle: options.subtitle,
|
|
138
|
+
},
|
|
139
|
+
title: options.title,
|
|
140
|
+
summary: "Type the number or name that matches the agent you want.",
|
|
141
|
+
sections: [
|
|
142
|
+
{
|
|
143
|
+
title: "Agents",
|
|
144
|
+
items: options.agents.map((agent, index) => ({
|
|
145
|
+
key: String(index + 1),
|
|
146
|
+
label: agent,
|
|
147
|
+
summary: "Available on this machine.",
|
|
148
|
+
...(index === 0 ? { recommended: true } : {}),
|
|
149
|
+
})),
|
|
150
|
+
},
|
|
151
|
+
],
|
|
152
|
+
prompt: `Choose [1-${options.agents.length}] or type a name: `,
|
|
153
|
+
});
|
|
154
|
+
}
|
|
155
|
+
function resolveNamedAgentSelection(answer, agents) {
|
|
156
|
+
const normalized = answer.trim().toLowerCase();
|
|
157
|
+
if (!normalized)
|
|
158
|
+
return undefined;
|
|
159
|
+
const numbered = Number.parseInt(normalized, 10);
|
|
160
|
+
if (Number.isFinite(numbered))
|
|
161
|
+
return agents[numbered - 1];
|
|
162
|
+
return agents.find((agent) => agent.toLowerCase() === normalized);
|
|
163
|
+
}
|
|
164
|
+
function renderHumanReadinessBoard(options) {
|
|
165
|
+
renderScreenEvent("readiness");
|
|
166
|
+
const issueItems = options.snapshot.items.map((item) => ({
|
|
167
|
+
label: item.title,
|
|
168
|
+
status: item.status,
|
|
169
|
+
summary: item.summary,
|
|
170
|
+
detailLines: item.detailLines,
|
|
171
|
+
}));
|
|
172
|
+
const actionItems = options.snapshot.nextActions.map((action, index) => ({
|
|
173
|
+
key: String(index + 1),
|
|
174
|
+
label: action.label,
|
|
175
|
+
actor: action.actor,
|
|
176
|
+
command: action.command,
|
|
177
|
+
...(action.recommended ? { recommended: true } : {}),
|
|
178
|
+
}));
|
|
179
|
+
if (options.prompt) {
|
|
180
|
+
actionItems.push({
|
|
181
|
+
key: String(actionItems.length + 1),
|
|
182
|
+
label: "Skip for now",
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
return (0, terminal_ui_1.renderTerminalWizard)({
|
|
186
|
+
isTTY: options.isTTY,
|
|
187
|
+
columns: options.columns,
|
|
188
|
+
masthead: {
|
|
189
|
+
subtitle: options.subtitle,
|
|
190
|
+
},
|
|
191
|
+
title: options.title,
|
|
192
|
+
summary: options.snapshot.summary,
|
|
193
|
+
nextStep: options.snapshot.primaryAction
|
|
194
|
+
? {
|
|
195
|
+
label: options.snapshot.primaryAction.label,
|
|
196
|
+
detail: options.snapshot.summary,
|
|
197
|
+
command: options.snapshot.primaryAction.command,
|
|
198
|
+
}
|
|
199
|
+
: options.snapshot.status === "ready" || options.snapshot.status === "attached"
|
|
200
|
+
? {
|
|
201
|
+
label: "Everything needed here is ready.",
|
|
202
|
+
detail: "You can keep going or leave this area alone.",
|
|
203
|
+
}
|
|
204
|
+
: undefined,
|
|
205
|
+
sections: [
|
|
206
|
+
{
|
|
207
|
+
title: "What needs attention",
|
|
208
|
+
items: issueItems,
|
|
209
|
+
},
|
|
210
|
+
...(actionItems.length > 0
|
|
211
|
+
? [{
|
|
212
|
+
title: "Ways forward",
|
|
213
|
+
items: actionItems,
|
|
214
|
+
}]
|
|
215
|
+
: []),
|
|
216
|
+
],
|
|
217
|
+
prompt: options.prompt,
|
|
218
|
+
});
|
|
219
|
+
}
|
|
220
|
+
function renderHumanCommandBoard(options) {
|
|
221
|
+
renderScreenEvent("command-board");
|
|
222
|
+
return (0, terminal_ui_1.renderTerminalGuide)({
|
|
223
|
+
isTTY: options.isTTY,
|
|
224
|
+
columns: options.columns,
|
|
225
|
+
masthead: {
|
|
226
|
+
subtitle: options.subtitle,
|
|
227
|
+
},
|
|
228
|
+
title: options.title,
|
|
229
|
+
summary: options.summary,
|
|
230
|
+
sections: options.sections,
|
|
231
|
+
actions: options.actions,
|
|
232
|
+
prompt: options.prompt,
|
|
233
|
+
});
|
|
234
|
+
}
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.readinessItemFromIssue = readinessItemFromIssue;
|
|
4
|
+
exports.buildHumanReadinessSnapshot = buildHumanReadinessSnapshot;
|
|
5
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
6
|
+
const STATUS_PRIORITY = {
|
|
7
|
+
locked: 0,
|
|
8
|
+
"needs credentials": 1,
|
|
9
|
+
"needs attention": 2,
|
|
10
|
+
"needs setup": 3,
|
|
11
|
+
missing: 4,
|
|
12
|
+
"not attached": 5,
|
|
13
|
+
ready: 6,
|
|
14
|
+
attached: 6,
|
|
15
|
+
};
|
|
16
|
+
function statusFromIssue(issue) {
|
|
17
|
+
switch (issue.kind) {
|
|
18
|
+
case "vault-locked":
|
|
19
|
+
return "locked";
|
|
20
|
+
case "vault-unconfigured":
|
|
21
|
+
return "needs setup";
|
|
22
|
+
case "provider-credentials-missing":
|
|
23
|
+
return "needs credentials";
|
|
24
|
+
case "provider-live-check-failed":
|
|
25
|
+
return issue.actions[0]?.kind === "provider-auth" ? "needs credentials" : "needs attention";
|
|
26
|
+
case "generic":
|
|
27
|
+
return "needs attention";
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function copyActions(actions) {
|
|
31
|
+
return actions.map((action) => ({
|
|
32
|
+
label: action.label,
|
|
33
|
+
command: action.command,
|
|
34
|
+
actor: action.actor,
|
|
35
|
+
...(action.executable === undefined ? {} : { executable: action.executable }),
|
|
36
|
+
}));
|
|
37
|
+
}
|
|
38
|
+
function readinessItemFromIssue(issue, options) {
|
|
39
|
+
return {
|
|
40
|
+
key: options.key,
|
|
41
|
+
title: options.title,
|
|
42
|
+
status: statusFromIssue(issue),
|
|
43
|
+
summary: issue.summary,
|
|
44
|
+
detailLines: issue.detail ? [issue.detail] : [],
|
|
45
|
+
actions: copyActions(issue.actions),
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
function compareStatus(a, b) {
|
|
49
|
+
return STATUS_PRIORITY[a.status] - STATUS_PRIORITY[b.status];
|
|
50
|
+
}
|
|
51
|
+
function uniqueActions(items) {
|
|
52
|
+
const seen = new Set();
|
|
53
|
+
const actions = [];
|
|
54
|
+
for (const item of [...items].sort(compareStatus)) {
|
|
55
|
+
for (const [index, action] of item.actions.entries()) {
|
|
56
|
+
if (seen.has(action.command))
|
|
57
|
+
continue;
|
|
58
|
+
seen.add(action.command);
|
|
59
|
+
actions.push({
|
|
60
|
+
...action,
|
|
61
|
+
...(actions.length === 0 && index === 0 ? { recommended: true } : {}),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return actions;
|
|
66
|
+
}
|
|
67
|
+
function overallStatus(items) {
|
|
68
|
+
if (items.length === 0)
|
|
69
|
+
return "ready";
|
|
70
|
+
return [...items].sort(compareStatus)[0].status;
|
|
71
|
+
}
|
|
72
|
+
function summaryFor(status) {
|
|
73
|
+
if (status === "ready" || status === "attached") {
|
|
74
|
+
return "Everything needed here is ready.";
|
|
75
|
+
}
|
|
76
|
+
if (status === "locked") {
|
|
77
|
+
return "Start by unlocking the vault on this machine, then continue through the remaining steps.";
|
|
78
|
+
}
|
|
79
|
+
if (status === "needs credentials") {
|
|
80
|
+
return "At least one credential is missing, so the next move is to authenticate it.";
|
|
81
|
+
}
|
|
82
|
+
if (status === "needs attention") {
|
|
83
|
+
return "Something is configured but not healthy yet, so verify or refresh it before moving on.";
|
|
84
|
+
}
|
|
85
|
+
if (status === "needs setup") {
|
|
86
|
+
return "This capability needs setup before it can be used.";
|
|
87
|
+
}
|
|
88
|
+
return "This area still needs a little attention.";
|
|
89
|
+
}
|
|
90
|
+
function buildHumanReadinessSnapshot(options) {
|
|
91
|
+
const status = overallStatus(options.items);
|
|
92
|
+
const nextActions = uniqueActions(options.items);
|
|
93
|
+
const primaryAction = nextActions[0];
|
|
94
|
+
(0, runtime_1.emitNervesEvent)({
|
|
95
|
+
component: "daemon",
|
|
96
|
+
event: "daemon.human_readiness_snapshot",
|
|
97
|
+
message: "built human readiness snapshot",
|
|
98
|
+
meta: {
|
|
99
|
+
agent: options.agent,
|
|
100
|
+
title: options.title,
|
|
101
|
+
items: options.items.length,
|
|
102
|
+
status,
|
|
103
|
+
},
|
|
104
|
+
});
|
|
105
|
+
return {
|
|
106
|
+
agent: options.agent,
|
|
107
|
+
title: options.title,
|
|
108
|
+
status,
|
|
109
|
+
summary: summaryFor(status),
|
|
110
|
+
items: [...options.items].sort(compareStatus),
|
|
111
|
+
...(primaryAction ? { primaryAction } : {}),
|
|
112
|
+
nextActions,
|
|
113
|
+
};
|
|
114
|
+
}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.buildInnerStatusOutput = buildInnerStatusOutput;
|
|
4
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
5
|
+
function formatRelativeTime(elapsedMs) {
|
|
6
|
+
const minutes = Math.floor(elapsedMs / (60 * 1000));
|
|
7
|
+
if (minutes < 1)
|
|
8
|
+
return "just now";
|
|
9
|
+
if (minutes === 1)
|
|
10
|
+
return "1 minute ago";
|
|
11
|
+
if (minutes < 60)
|
|
12
|
+
return `${minutes} minutes ago`;
|
|
13
|
+
const hours = Math.floor(minutes / 60);
|
|
14
|
+
if (hours === 1)
|
|
15
|
+
return "1 hour ago";
|
|
16
|
+
return `${hours} hours ago`;
|
|
17
|
+
}
|
|
18
|
+
function formatCadence(cadenceMs) {
|
|
19
|
+
const minutes = Math.round(cadenceMs / (60 * 1000));
|
|
20
|
+
if (minutes >= 60) {
|
|
21
|
+
const hours = Math.round(minutes / 60);
|
|
22
|
+
return `${hours}h`;
|
|
23
|
+
}
|
|
24
|
+
return `${minutes}m`;
|
|
25
|
+
}
|
|
26
|
+
function buildInnerStatusOutput(input) {
|
|
27
|
+
const { agentName, runtimeState, journalFiles, heartbeat, attentionCount, now } = input;
|
|
28
|
+
const lines = [];
|
|
29
|
+
lines.push(`inner dialog status: ${agentName}`);
|
|
30
|
+
// Last turn
|
|
31
|
+
if (runtimeState?.lastCompletedAt) {
|
|
32
|
+
const lastMs = new Date(runtimeState.lastCompletedAt).getTime();
|
|
33
|
+
const elapsed = now - lastMs;
|
|
34
|
+
const relativeTime = formatRelativeTime(elapsed);
|
|
35
|
+
const reasonSuffix = runtimeState.reason ? ` (${runtimeState.reason})` : "";
|
|
36
|
+
lines.push(` last turn: ${relativeTime}${reasonSuffix}`);
|
|
37
|
+
}
|
|
38
|
+
else {
|
|
39
|
+
lines.push(" last turn: unknown");
|
|
40
|
+
}
|
|
41
|
+
// Status
|
|
42
|
+
if (runtimeState) {
|
|
43
|
+
const reasonSuffix = runtimeState.status === "running" && runtimeState.reason ? ` (${runtimeState.reason})` : "";
|
|
44
|
+
lines.push(` status: ${runtimeState.status}${reasonSuffix}`);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
lines.push(" status: unknown");
|
|
48
|
+
}
|
|
49
|
+
// Heartbeat health
|
|
50
|
+
if (heartbeat && heartbeat.lastCompletedAt !== null) {
|
|
51
|
+
const elapsed = now - heartbeat.lastCompletedAt;
|
|
52
|
+
const threshold = heartbeat.cadenceMs * 1.5;
|
|
53
|
+
const health = elapsed < threshold ? "healthy" : "overdue";
|
|
54
|
+
const cadenceStr = formatCadence(heartbeat.cadenceMs);
|
|
55
|
+
const sinceStr = formatRelativeTime(elapsed);
|
|
56
|
+
lines.push(` heartbeat: ${health} (cadence ${cadenceStr}, ${sinceStr})`);
|
|
57
|
+
}
|
|
58
|
+
else {
|
|
59
|
+
lines.push(" heartbeat: unknown");
|
|
60
|
+
}
|
|
61
|
+
// Journal
|
|
62
|
+
if (journalFiles.length === 0) {
|
|
63
|
+
lines.push(" journal: (empty)");
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
lines.push(" journal:");
|
|
67
|
+
const sorted = [...journalFiles].sort((a, b) => b.mtimeMs - a.mtimeMs);
|
|
68
|
+
for (const file of sorted) {
|
|
69
|
+
const elapsed = now - file.mtimeMs;
|
|
70
|
+
const relativeTime = formatRelativeTime(elapsed);
|
|
71
|
+
lines.push(` - ${file.name} (${relativeTime})`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Attention
|
|
75
|
+
const thoughtWord = attentionCount === 1 ? "thought" : "thoughts";
|
|
76
|
+
lines.push(` attention: ${attentionCount} held ${thoughtWord}`);
|
|
77
|
+
(0, runtime_1.emitNervesEvent)({
|
|
78
|
+
component: "daemon",
|
|
79
|
+
event: "daemon.inner_status_read",
|
|
80
|
+
message: "inner dialog status read",
|
|
81
|
+
meta: {
|
|
82
|
+
agentName,
|
|
83
|
+
status: runtimeState?.status ?? "unknown",
|
|
84
|
+
journalCount: journalFiles.length,
|
|
85
|
+
attentionCount,
|
|
86
|
+
},
|
|
87
|
+
});
|
|
88
|
+
return lines.join("\n");
|
|
89
|
+
}
|