@ouro.bot/cli 0.1.0-alpha.44 → 0.1.0-alpha.441
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 -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 +2789 -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 +832 -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/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 +439 -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 +214 -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 +626 -0
- package/dist/heart/daemon/cli-exec.js +5646 -0
- package/dist/heart/daemon/cli-help.js +428 -0
- package/dist/heart/daemon/cli-parse.js +1156 -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 +457 -0
- package/dist/heart/daemon/daemon-cli.js +28 -1582
- package/dist/heart/daemon/daemon-entry.js +356 -3
- package/dist/heart/daemon/daemon-health.js +141 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +175 -12
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +684 -58
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +427 -0
- package/dist/heart/daemon/health-monitor.js +79 -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 +236 -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 +307 -0
- package/dist/heart/daemon/launchd.js +46 -9
- package/dist/heart/daemon/log-tailer.js +82 -12
- package/dist/heart/daemon/logs-prune.js +105 -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 +76 -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 +145 -32
- 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 +307 -0
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +272 -0
- package/dist/heart/daemon/task-scheduler.js +3 -25
- package/dist/heart/daemon/terminal-ui.js +224 -0
- package/dist/heart/daemon/thoughts.js +510 -0
- package/dist/heart/daemon/up-progress.js +313 -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 +197 -65
- 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 +64 -0
- package/dist/heart/outlook/outlook-http-response.js +7 -0
- package/dist/heart/outlook/outlook-http-routes.js +232 -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 +28 -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/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 +239 -0
- package/dist/heart/provider-credentials.js +400 -0
- package/dist/heart/provider-failover.js +266 -0
- package/dist/heart/provider-models.js +81 -0
- package/dist/heart/provider-ping.js +239 -0
- package/dist/heart/provider-state.js +216 -0
- package/dist/heart/provider-visibility.js +186 -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 +3 -0
- 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 +351 -0
- package/dist/heart/turn-coordinator.js +28 -0
- 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/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 +21 -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 +1 -1
- 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 +947 -165
- 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 +83 -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-BAcU08c-.css +1 -0
- package/dist/outlook-ui/assets/index-D7l3l4vY.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 +733 -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 +371 -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 +42 -690
- 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 +361 -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-notes.js +376 -0
- package/dist/repertoire/tools-session.js +739 -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} +260 -9
- package/dist/senses/bluebubbles/entry.js +73 -0
- package/dist/senses/bluebubbles/inbound-log.js +113 -0
- package/dist/senses/bluebubbles/index.js +1620 -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} +45 -3
- package/dist/senses/bluebubbles/replay.js +129 -0
- package/dist/senses/bluebubbles/runtime-state.js +109 -0
- 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 +102 -19
- package/dist/senses/inner-dialog.js +597 -95
- 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 +32 -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 -11
- package/dist/senses/bluebubbles.js +0 -854
- package/dist/senses/debug-activity.js +0 -127
- package/subagents/README.md +0 -86
- package/subagents/work-doer.md +0 -235
- package/subagents/work-merger.md +0 -618
- package/subagents/work-planner.md +0 -382
- /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,236 @@
|
|
|
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
|
+
exports.renderHouseStatusScreen = renderHouseStatusScreen;
|
|
11
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
12
|
+
const terminal_ui_1 = require("./terminal-ui");
|
|
13
|
+
function renderScreenEvent(screen) {
|
|
14
|
+
(0, runtime_1.emitNervesEvent)({
|
|
15
|
+
component: "daemon",
|
|
16
|
+
event: "daemon.human_screen_rendered",
|
|
17
|
+
message: "rendered human command screen",
|
|
18
|
+
meta: { screen },
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function buildOuroHomeActions(agents) {
|
|
22
|
+
if (agents.length === 0) {
|
|
23
|
+
return [
|
|
24
|
+
{ key: "1", label: "Hatch a new agent", kind: "hatch", command: "ouro hatch" },
|
|
25
|
+
{ key: "2", label: "Clone an existing bundle", kind: "clone", command: "ouro clone <remote>" },
|
|
26
|
+
{ key: "3", label: "Show help", kind: "help", command: "ouro --help" },
|
|
27
|
+
{ key: "4", label: "Exit", kind: "exit", command: "exit" },
|
|
28
|
+
];
|
|
29
|
+
}
|
|
30
|
+
const actions = agents.map((agent, index) => ({
|
|
31
|
+
key: String(index + 1),
|
|
32
|
+
label: `Talk to ${agent}`,
|
|
33
|
+
kind: "chat",
|
|
34
|
+
command: `ouro chat ${agent}`,
|
|
35
|
+
agent,
|
|
36
|
+
}));
|
|
37
|
+
return [
|
|
38
|
+
...actions,
|
|
39
|
+
{ key: String(actions.length + 1), label: "Prepare the house", kind: "up", command: "ouro up" },
|
|
40
|
+
{ key: String(actions.length + 2), label: "Connect an agent", kind: "connect", command: "ouro connect --agent <agent>" },
|
|
41
|
+
{ key: String(actions.length + 3), label: "Repair an agent", kind: "repair", command: "ouro repair --agent <agent>" },
|
|
42
|
+
{ key: String(actions.length + 4), label: "Show help", kind: "help", command: "ouro --help" },
|
|
43
|
+
{ key: String(actions.length + 5), label: "Exit", kind: "exit", command: "exit" },
|
|
44
|
+
];
|
|
45
|
+
}
|
|
46
|
+
function resolveOuroHomeAction(answer, actions) {
|
|
47
|
+
const normalized = answer.trim().toLowerCase();
|
|
48
|
+
if (!normalized)
|
|
49
|
+
return undefined;
|
|
50
|
+
const byKey = actions.find((action) => action.key === normalized);
|
|
51
|
+
if (byKey)
|
|
52
|
+
return byKey;
|
|
53
|
+
const byAgent = actions.find((action) => action.agent?.toLowerCase() === normalized);
|
|
54
|
+
if (byAgent)
|
|
55
|
+
return byAgent;
|
|
56
|
+
return actions.find((action) => action.kind === normalized || action.label.toLowerCase() === normalized);
|
|
57
|
+
}
|
|
58
|
+
function renderOuroHomeScreen(options) {
|
|
59
|
+
renderScreenEvent("home");
|
|
60
|
+
const actions = buildOuroHomeActions(options.agents);
|
|
61
|
+
const sections = [
|
|
62
|
+
{
|
|
63
|
+
title: options.agents.length === 0 ? "Start here" : "Around the house",
|
|
64
|
+
lines: options.agents.length === 0
|
|
65
|
+
? ["No agents are home yet. Hatch someone new or bring an existing bundle aboard."]
|
|
66
|
+
: options.agents.map((agent) => `${agent} is home and ready when called.`),
|
|
67
|
+
},
|
|
68
|
+
];
|
|
69
|
+
const actionRows = actions.map((action, index) => ({
|
|
70
|
+
label: action.label,
|
|
71
|
+
actor: "agent-runnable",
|
|
72
|
+
command: action.command,
|
|
73
|
+
...(index === 0 ? { recommended: true } : {}),
|
|
74
|
+
}));
|
|
75
|
+
return (0, terminal_ui_1.renderTerminalBoard)({
|
|
76
|
+
isTTY: options.isTTY,
|
|
77
|
+
columns: options.columns,
|
|
78
|
+
masthead: {
|
|
79
|
+
subtitle: options.agents.length === 0
|
|
80
|
+
? "No agents are home yet."
|
|
81
|
+
: "Welcome home.",
|
|
82
|
+
},
|
|
83
|
+
title: "Ouro home",
|
|
84
|
+
summary: options.agents.length === 0
|
|
85
|
+
? "Hatch someone new or bring an existing bundle aboard."
|
|
86
|
+
: "Choose who to wake or what to prepare without memorizing commands.",
|
|
87
|
+
sections,
|
|
88
|
+
actions: actionRows,
|
|
89
|
+
prompt: `Choose [1-${actions.length}] or type a name: `,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
function renderAgentPickerScreen(options) {
|
|
93
|
+
renderScreenEvent("agent-picker");
|
|
94
|
+
return (0, terminal_ui_1.renderTerminalBoard)({
|
|
95
|
+
isTTY: options.isTTY,
|
|
96
|
+
columns: options.columns,
|
|
97
|
+
masthead: {
|
|
98
|
+
subtitle: options.subtitle,
|
|
99
|
+
},
|
|
100
|
+
title: options.title,
|
|
101
|
+
summary: "Type the number or name that matches the agent you want.",
|
|
102
|
+
sections: [
|
|
103
|
+
{
|
|
104
|
+
title: "Agents",
|
|
105
|
+
lines: options.agents.map((agent, index) => `${index + 1}. ${agent}`),
|
|
106
|
+
},
|
|
107
|
+
],
|
|
108
|
+
prompt: `Choose [1-${options.agents.length}] or type a name: `,
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function resolveNamedAgentSelection(answer, agents) {
|
|
112
|
+
const normalized = answer.trim().toLowerCase();
|
|
113
|
+
if (!normalized)
|
|
114
|
+
return undefined;
|
|
115
|
+
const numbered = Number.parseInt(normalized, 10);
|
|
116
|
+
if (Number.isFinite(numbered))
|
|
117
|
+
return agents[numbered - 1];
|
|
118
|
+
return agents.find((agent) => agent.toLowerCase() === normalized);
|
|
119
|
+
}
|
|
120
|
+
function statusLabel(status) {
|
|
121
|
+
return status.replace(/-/g, " ");
|
|
122
|
+
}
|
|
123
|
+
function renderHumanReadinessBoard(options) {
|
|
124
|
+
renderScreenEvent("readiness");
|
|
125
|
+
const sections = options.snapshot.items.map((item) => ({
|
|
126
|
+
title: item.title,
|
|
127
|
+
lines: [
|
|
128
|
+
`${statusLabel(item.status)} — ${item.summary}`,
|
|
129
|
+
...item.detailLines,
|
|
130
|
+
],
|
|
131
|
+
}));
|
|
132
|
+
return renderHumanCommandBoard({
|
|
133
|
+
title: options.title,
|
|
134
|
+
subtitle: options.subtitle,
|
|
135
|
+
summary: options.snapshot.summary,
|
|
136
|
+
isTTY: options.isTTY,
|
|
137
|
+
columns: options.columns,
|
|
138
|
+
sections,
|
|
139
|
+
actions: options.snapshot.nextActions,
|
|
140
|
+
prompt: options.prompt,
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
function renderHumanCommandBoard(options) {
|
|
144
|
+
renderScreenEvent("command-board");
|
|
145
|
+
return (0, terminal_ui_1.renderTerminalBoard)({
|
|
146
|
+
isTTY: options.isTTY,
|
|
147
|
+
columns: options.columns,
|
|
148
|
+
masthead: {
|
|
149
|
+
subtitle: options.subtitle,
|
|
150
|
+
},
|
|
151
|
+
title: options.title,
|
|
152
|
+
summary: options.summary,
|
|
153
|
+
sections: options.sections,
|
|
154
|
+
actions: options.actions,
|
|
155
|
+
prompt: options.prompt,
|
|
156
|
+
});
|
|
157
|
+
}
|
|
158
|
+
function renderHouseStatusScreen(options) {
|
|
159
|
+
renderScreenEvent("house-status");
|
|
160
|
+
const sections = [
|
|
161
|
+
{
|
|
162
|
+
title: "House pulse",
|
|
163
|
+
lines: [
|
|
164
|
+
`Daemon: ${options.payload.overview.daemon}`,
|
|
165
|
+
`Health: ${options.payload.overview.health}`,
|
|
166
|
+
`Outlook: ${options.payload.overview.outlookUrl}`,
|
|
167
|
+
`Updated: ${options.payload.overview.lastUpdated}`,
|
|
168
|
+
],
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
if (options.payload.agents.length > 0) {
|
|
172
|
+
sections.push({
|
|
173
|
+
title: "Agents",
|
|
174
|
+
lines: options.payload.agents.map((agent) => `${agent.name} — ${agent.enabled ? "enabled" : "disabled"}`),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
if (options.payload.providers.length > 0) {
|
|
178
|
+
sections.push({
|
|
179
|
+
title: "Providers",
|
|
180
|
+
lines: options.payload.providers.map((provider) => {
|
|
181
|
+
const detail = [provider.readiness, provider.detail, provider.source, provider.credential].filter(Boolean).join("; ");
|
|
182
|
+
return `${provider.agent} ${provider.lane} — ${provider.provider} / ${provider.model}${detail ? ` — ${detail}` : ""}`;
|
|
183
|
+
}),
|
|
184
|
+
});
|
|
185
|
+
}
|
|
186
|
+
if (options.payload.senses.length > 0) {
|
|
187
|
+
sections.push({
|
|
188
|
+
title: "Senses",
|
|
189
|
+
lines: options.payload.senses.map((sense) => {
|
|
190
|
+
const status = sense.enabled ? sense.status : "disabled";
|
|
191
|
+
return `${sense.agent} — ${sense.label ?? sense.sense} — ${status}${sense.detail ? ` — ${sense.detail}` : ""}`;
|
|
192
|
+
}),
|
|
193
|
+
});
|
|
194
|
+
}
|
|
195
|
+
if (options.payload.workers.length > 0) {
|
|
196
|
+
sections.push({
|
|
197
|
+
title: "Workers",
|
|
198
|
+
lines: options.payload.workers.map((worker) => {
|
|
199
|
+
const details = [`restarts: ${worker.restartCount}`];
|
|
200
|
+
if (worker.pid !== null)
|
|
201
|
+
details.unshift(`pid ${worker.pid}`);
|
|
202
|
+
if (worker.lastExitCode !== null)
|
|
203
|
+
details.push(`exit=${worker.lastExitCode}`);
|
|
204
|
+
if (worker.lastSignal !== null)
|
|
205
|
+
details.push(`signal=${worker.lastSignal}`);
|
|
206
|
+
if (worker.errorReason)
|
|
207
|
+
details.push(`error: ${worker.errorReason}`);
|
|
208
|
+
if (worker.fixHint)
|
|
209
|
+
details.push(`fix: ${worker.fixHint}`);
|
|
210
|
+
return `${worker.agent} — ${worker.worker} — ${worker.status} — ${details.join("; ")}`;
|
|
211
|
+
}),
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
if (options.payload.sync.length > 0) {
|
|
215
|
+
sections.push({
|
|
216
|
+
title: "Git sync",
|
|
217
|
+
lines: options.payload.sync.map((row) => {
|
|
218
|
+
if (!row.enabled)
|
|
219
|
+
return `${row.agent} — disabled`;
|
|
220
|
+
if (row.gitInitialized === false)
|
|
221
|
+
return `${row.agent} — needs git init`;
|
|
222
|
+
if (row.remoteUrl)
|
|
223
|
+
return `${row.agent} — ${row.remote} -> ${row.remoteUrl}`;
|
|
224
|
+
return `${row.agent} — local only`;
|
|
225
|
+
}),
|
|
226
|
+
});
|
|
227
|
+
}
|
|
228
|
+
return renderHumanCommandBoard({
|
|
229
|
+
title: "House status",
|
|
230
|
+
subtitle: "The house is awake enough to answer clearly.",
|
|
231
|
+
summary: "What is awake, resting, or asking for care.",
|
|
232
|
+
isTTY: options.isTTY,
|
|
233
|
+
columns: options.columns,
|
|
234
|
+
sections,
|
|
235
|
+
});
|
|
236
|
+
}
|
|
@@ -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
|
+
}
|