@ouro.bot/cli 0.1.0-alpha.48 → 0.1.0-alpha.481
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 +3069 -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 +573 -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,12 +37,14 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
37
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
38
38
|
exports.formatSurfacedValue = formatSurfacedValue;
|
|
39
39
|
exports.deriveInnerDialogStatus = deriveInnerDialogStatus;
|
|
40
|
+
exports.deriveInnerJob = deriveInnerJob;
|
|
40
41
|
exports.formatInnerDialogStatus = formatInnerDialogStatus;
|
|
41
42
|
exports.extractThoughtResponseFromMessages = extractThoughtResponseFromMessages;
|
|
42
43
|
exports.parseInnerDialogSession = parseInnerDialogSession;
|
|
43
44
|
exports.formatThoughtTurns = formatThoughtTurns;
|
|
44
45
|
exports.getInnerDialogSessionPath = getInnerDialogSessionPath;
|
|
45
46
|
exports.readInnerDialogStatus = readInnerDialogStatus;
|
|
47
|
+
exports.readInnerDialogRawData = readInnerDialogRawData;
|
|
46
48
|
exports.followThoughts = followThoughts;
|
|
47
49
|
const fs = __importStar(require("fs"));
|
|
48
50
|
const path = __importStar(require("path"));
|
|
@@ -91,7 +93,7 @@ function extractToolNames(messages) {
|
|
|
91
93
|
if (msg.role === "assistant" && Array.isArray(msg.tool_calls)) {
|
|
92
94
|
for (const tc of msg.tool_calls) {
|
|
93
95
|
const toolFunction = extractToolFunction(tc);
|
|
94
|
-
if (toolFunction?.name && toolFunction.name !== "
|
|
96
|
+
if (toolFunction?.name && toolFunction.name !== "settle")
|
|
95
97
|
names.push(toolFunction.name);
|
|
96
98
|
}
|
|
97
99
|
}
|
|
@@ -149,10 +151,34 @@ function formatSurfacedValue(text, maxLength = 120) {
|
|
|
149
151
|
return `"${firstLine}"`;
|
|
150
152
|
return `"${firstLine.slice(0, maxLength - 3)}..."`;
|
|
151
153
|
}
|
|
154
|
+
function extractEnrichedFields(pendingMessages) {
|
|
155
|
+
const delegated = pendingMessages.find((msg) => msg.delegatedFrom);
|
|
156
|
+
if (!delegated?.delegatedFrom)
|
|
157
|
+
return {};
|
|
158
|
+
const snippet = delegated.content.length > 80 ? delegated.content.slice(0, 77) + "..." : delegated.content;
|
|
159
|
+
return {
|
|
160
|
+
origin: {
|
|
161
|
+
friendId: delegated.delegatedFrom.friendId,
|
|
162
|
+
channel: delegated.delegatedFrom.channel,
|
|
163
|
+
key: delegated.delegatedFrom.key,
|
|
164
|
+
},
|
|
165
|
+
contentSnippet: snippet,
|
|
166
|
+
...(delegated.obligationStatus === "pending" ? { obligationPending: true } : {}),
|
|
167
|
+
};
|
|
168
|
+
}
|
|
152
169
|
function deriveInnerDialogStatus(pendingMessages, turns, runtimeState) {
|
|
153
170
|
if (runtimeState?.status === "running") {
|
|
171
|
+
if (pendingMessages.length > 0) {
|
|
172
|
+
return {
|
|
173
|
+
queue: "queued to inner/dialog",
|
|
174
|
+
wake: "queued behind active turn",
|
|
175
|
+
processing: "pending",
|
|
176
|
+
surfaced: "nothing yet",
|
|
177
|
+
...extractEnrichedFields(pendingMessages),
|
|
178
|
+
};
|
|
179
|
+
}
|
|
154
180
|
return {
|
|
155
|
-
queue:
|
|
181
|
+
queue: "clear",
|
|
156
182
|
wake: "in progress",
|
|
157
183
|
processing: "started",
|
|
158
184
|
surfaced: "nothing yet",
|
|
@@ -164,6 +190,7 @@ function deriveInnerDialogStatus(pendingMessages, turns, runtimeState) {
|
|
|
164
190
|
wake: "awaiting inner session",
|
|
165
191
|
processing: "pending",
|
|
166
192
|
surfaced: "nothing yet",
|
|
193
|
+
...extractEnrichedFields(pendingMessages),
|
|
167
194
|
};
|
|
168
195
|
}
|
|
169
196
|
const latestProcessedPendingTurn = [...turns]
|
|
@@ -184,23 +211,125 @@ function deriveInnerDialogStatus(pendingMessages, turns, runtimeState) {
|
|
|
184
211
|
surfaced: formatSurfacedValue(latestProcessedPendingTurn.response),
|
|
185
212
|
};
|
|
186
213
|
}
|
|
214
|
+
function deriveInnerJob(pendingMessages, turns, runtimeState) {
|
|
215
|
+
const isRunning = runtimeState?.status === "running";
|
|
216
|
+
const delegated = pendingMessages.find((msg) => msg.delegatedFrom);
|
|
217
|
+
const enriched = extractEnrichedFields(pendingMessages);
|
|
218
|
+
const pendingMode = delegated && "mode" in delegated && delegated.mode ? delegated.mode : "reflect";
|
|
219
|
+
const origin = enriched.origin ?? null;
|
|
220
|
+
const content = delegated?.content ?? null;
|
|
221
|
+
const obligationStatus = delegated?.obligationStatus ?? null;
|
|
222
|
+
const queuedAt = delegated?.timestamp ?? null;
|
|
223
|
+
if (isRunning) {
|
|
224
|
+
(0, runtime_1.emitNervesEvent)({
|
|
225
|
+
component: "engine",
|
|
226
|
+
event: "engine.inner_job_derive",
|
|
227
|
+
message: "derived inner job state",
|
|
228
|
+
meta: { status: "running", mode: pendingMode, hasOrigin: origin !== null, hasObligation: obligationStatus !== null },
|
|
229
|
+
});
|
|
230
|
+
return {
|
|
231
|
+
status: "running",
|
|
232
|
+
content,
|
|
233
|
+
origin,
|
|
234
|
+
mode: pendingMode,
|
|
235
|
+
obligationStatus,
|
|
236
|
+
surfacedResult: null,
|
|
237
|
+
queuedAt,
|
|
238
|
+
startedAt: runtimeState?.startedAt ?? null,
|
|
239
|
+
surfacedAt: null,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
if (pendingMessages.length > 0) {
|
|
243
|
+
(0, runtime_1.emitNervesEvent)({
|
|
244
|
+
component: "engine",
|
|
245
|
+
event: "engine.inner_job_derive",
|
|
246
|
+
message: "derived inner job state",
|
|
247
|
+
meta: { status: "queued", mode: pendingMode, hasOrigin: origin !== null, hasObligation: obligationStatus !== null },
|
|
248
|
+
});
|
|
249
|
+
return {
|
|
250
|
+
status: "queued",
|
|
251
|
+
content,
|
|
252
|
+
origin,
|
|
253
|
+
mode: pendingMode,
|
|
254
|
+
obligationStatus,
|
|
255
|
+
surfacedResult: null,
|
|
256
|
+
queuedAt,
|
|
257
|
+
startedAt: null,
|
|
258
|
+
surfacedAt: null,
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
// No pending, not running -- check for surfaced result
|
|
262
|
+
const latestProcessedPendingTurn = [...turns]
|
|
263
|
+
.reverse()
|
|
264
|
+
.find((turn) => extractPendingPromptMessages(turn.prompt).length > 0);
|
|
265
|
+
if (latestProcessedPendingTurn) {
|
|
266
|
+
const surfacedResult = extractThoughtResponseFromMessages([
|
|
267
|
+
{ role: "assistant", content: latestProcessedPendingTurn.response },
|
|
268
|
+
]);
|
|
269
|
+
(0, runtime_1.emitNervesEvent)({
|
|
270
|
+
component: "engine",
|
|
271
|
+
event: "engine.inner_job_derive",
|
|
272
|
+
message: "derived inner job state",
|
|
273
|
+
meta: { status: "surfaced", mode: "reflect", hasOrigin: false, hasObligation: false },
|
|
274
|
+
});
|
|
275
|
+
return {
|
|
276
|
+
status: "surfaced",
|
|
277
|
+
content: null,
|
|
278
|
+
origin: null,
|
|
279
|
+
mode: "reflect",
|
|
280
|
+
obligationStatus: null,
|
|
281
|
+
/* v8 ignore next -- defensive: surfacedResult fallback @preserve */
|
|
282
|
+
surfacedResult: surfacedResult || null,
|
|
283
|
+
queuedAt: null,
|
|
284
|
+
startedAt: null,
|
|
285
|
+
surfacedAt: null,
|
|
286
|
+
};
|
|
287
|
+
}
|
|
288
|
+
(0, runtime_1.emitNervesEvent)({
|
|
289
|
+
component: "engine",
|
|
290
|
+
event: "engine.inner_job_derive",
|
|
291
|
+
message: "derived inner job state",
|
|
292
|
+
meta: { status: "idle", mode: "reflect", hasOrigin: false, hasObligation: false },
|
|
293
|
+
});
|
|
294
|
+
return {
|
|
295
|
+
status: "idle",
|
|
296
|
+
content: null,
|
|
297
|
+
origin: null,
|
|
298
|
+
mode: "reflect",
|
|
299
|
+
obligationStatus: null,
|
|
300
|
+
surfacedResult: null,
|
|
301
|
+
queuedAt: null,
|
|
302
|
+
startedAt: null,
|
|
303
|
+
surfacedAt: null,
|
|
304
|
+
};
|
|
305
|
+
}
|
|
187
306
|
function formatInnerDialogStatus(status) {
|
|
188
|
-
|
|
307
|
+
const lines = [
|
|
189
308
|
`queue: ${status.queue}`,
|
|
190
309
|
`wake: ${status.wake}`,
|
|
191
310
|
`processing: ${status.processing}`,
|
|
192
311
|
`surfaced: ${status.surfaced}`,
|
|
193
|
-
]
|
|
312
|
+
];
|
|
313
|
+
if (status.origin) {
|
|
314
|
+
lines.push(`origin: ${status.origin.friendId}/${status.origin.channel}/${status.origin.key}`);
|
|
315
|
+
}
|
|
316
|
+
if (status.contentSnippet) {
|
|
317
|
+
lines.push(`asked: ${status.contentSnippet}`);
|
|
318
|
+
}
|
|
319
|
+
if (status.obligationPending) {
|
|
320
|
+
lines.push("obligation: pending");
|
|
321
|
+
}
|
|
322
|
+
return lines.join("\n");
|
|
194
323
|
}
|
|
195
|
-
/** Extract text from a
|
|
196
|
-
function
|
|
324
|
+
/** Extract text from a settle tool call's arguments. */
|
|
325
|
+
function extractSettleAnswer(messages) {
|
|
197
326
|
for (let k = messages.length - 1; k >= 0; k--) {
|
|
198
327
|
const msg = messages[k];
|
|
199
328
|
if (msg.role !== "assistant" || !Array.isArray(msg.tool_calls))
|
|
200
329
|
continue;
|
|
201
330
|
for (const tc of msg.tool_calls) {
|
|
202
331
|
const toolFunction = extractToolFunction(tc);
|
|
203
|
-
if (toolFunction?.name !== "
|
|
332
|
+
if (toolFunction?.name !== "settle")
|
|
204
333
|
continue;
|
|
205
334
|
try {
|
|
206
335
|
const parsed = JSON.parse(toolFunction.arguments ?? "{}");
|
|
@@ -219,7 +348,7 @@ function extractThoughtResponseFromMessages(messages) {
|
|
|
219
348
|
const lastAssistant = assistantMsgs.reverse().find((message) => contentToText(message.content).trim().length > 0);
|
|
220
349
|
return lastAssistant
|
|
221
350
|
? contentToText(lastAssistant.content).trim()
|
|
222
|
-
:
|
|
351
|
+
: extractSettleAnswer(messages);
|
|
223
352
|
}
|
|
224
353
|
function parseInnerDialogSession(sessionPath) {
|
|
225
354
|
(0, runtime_1.emitNervesEvent)({
|
|
@@ -268,7 +397,7 @@ function parseInnerDialogSession(sessionPath) {
|
|
|
268
397
|
j++;
|
|
269
398
|
}
|
|
270
399
|
// Find the last assistant text response in this turn.
|
|
271
|
-
// With tool_choice="required", the response may be inside a
|
|
400
|
+
// With tool_choice="required", the response may be inside a settle tool call.
|
|
272
401
|
const response = extractThoughtResponseFromMessages(turnMessages);
|
|
273
402
|
const tools = extractToolNames(turnMessages);
|
|
274
403
|
turns.push({
|
|
@@ -339,6 +468,13 @@ function readInnerDialogStatus(sessionPath, pendingDir, runtimePath = getInnerDi
|
|
|
339
468
|
const runtimeState = readInnerDialogRuntimeState(runtimePath);
|
|
340
469
|
return deriveInnerDialogStatus(pendingMessages, turns, runtimeState);
|
|
341
470
|
}
|
|
471
|
+
function readInnerDialogRawData(sessionPath, pendingDir) {
|
|
472
|
+
const runtimePath = getInnerDialogRuntimeStatePath(sessionPath);
|
|
473
|
+
const pendingMessages = readPendingMessagesForStatus(pendingDir);
|
|
474
|
+
const turns = parseInnerDialogSession(sessionPath);
|
|
475
|
+
const runtimeState = readInnerDialogRuntimeState(runtimePath);
|
|
476
|
+
return { pendingMessages, turns, runtimeState };
|
|
477
|
+
}
|
|
342
478
|
/**
|
|
343
479
|
* Watch a session file and emit new turns as they appear.
|
|
344
480
|
* Returns a cleanup function that stops the watcher.
|
|
@@ -361,9 +497,12 @@ function followThoughts(sessionPath, onNewTurns, pollIntervalMs = 1000) {
|
|
|
361
497
|
});
|
|
362
498
|
return () => {
|
|
363
499
|
fs.unwatchFile(sessionPath);
|
|
500
|
+
// Must be named `_end` (not `_stop`) to satisfy the nerves audit's
|
|
501
|
+
// start/end pairing rule — see src/nerves/coverage/audit-rules.ts which
|
|
502
|
+
// pairs `<prefix>_start` with `<prefix>_end` or `<prefix>_error`.
|
|
364
503
|
(0, runtime_1.emitNervesEvent)({
|
|
365
504
|
component: "daemon",
|
|
366
|
-
event: "daemon.
|
|
505
|
+
event: "daemon.thoughts_follow_end",
|
|
367
506
|
message: "stopped following inner dialog session",
|
|
368
507
|
meta: { sessionPath, totalTurns: displayedCount },
|
|
369
508
|
});
|
|
@@ -0,0 +1,366 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* UpProgress — accumulated-checklist progress renderer.
|
|
4
|
+
*
|
|
5
|
+
* Displays completed phases with checkmarks, the current phase with a
|
|
6
|
+
* spinner and elapsed time, and pending phases as plain text. Uses ANSI
|
|
7
|
+
* cursor control for in-place overwriting in TTY mode, and falls back to
|
|
8
|
+
* static line-per-phase output in non-TTY mode.
|
|
9
|
+
*
|
|
10
|
+
* The caller can drive animation by calling `render(now)`. In production CLI
|
|
11
|
+
* use, `autoRender` starts a short-lived timer while a TTY phase is active so
|
|
12
|
+
* long operations never leave a dead-looking cursor.
|
|
13
|
+
*/
|
|
14
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
15
|
+
exports.CommandProgress = exports.UpProgress = void 0;
|
|
16
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
17
|
+
const terminal_ui_1 = require("./terminal-ui");
|
|
18
|
+
// ── ANSI constants (shared with startup-tui.ts pattern) ──
|
|
19
|
+
const SPINNER_FRAMES = "\u280B\u2819\u2839\u2838\u283C\u2834\u2826\u2827\u2807\u280F";
|
|
20
|
+
const RESET = "\x1b[0m";
|
|
21
|
+
const BOLD = "\x1b[1m";
|
|
22
|
+
const DIM = "\x1b[2m";
|
|
23
|
+
const GREEN = "\x1b[38;2;46;204;64m";
|
|
24
|
+
const RED = "\x1b[38;2;255;106;106m";
|
|
25
|
+
const BASE_UP_PHASE_PLAN = [
|
|
26
|
+
"update check",
|
|
27
|
+
"system setup",
|
|
28
|
+
"provider checks",
|
|
29
|
+
"starting daemon",
|
|
30
|
+
"final daemon check",
|
|
31
|
+
];
|
|
32
|
+
const FRIENDLY_UP_PHASE_LABELS = {
|
|
33
|
+
"update check": "Check for updates",
|
|
34
|
+
"system setup": "Prepare this machine",
|
|
35
|
+
"agent updates": "Update installed agents",
|
|
36
|
+
"bundle cleanup": "Clean up stale bundles",
|
|
37
|
+
"provider checks": "Check the providers your agents use right now",
|
|
38
|
+
"starting daemon": "Start the background service",
|
|
39
|
+
"final daemon check": "Confirm the background service stayed up",
|
|
40
|
+
};
|
|
41
|
+
function splitDetailLines(detail) {
|
|
42
|
+
if (!detail)
|
|
43
|
+
return [];
|
|
44
|
+
return detail
|
|
45
|
+
.split(/\r?\n/)
|
|
46
|
+
.map((line) => line.trimEnd())
|
|
47
|
+
.filter((line) => line.length > 0);
|
|
48
|
+
}
|
|
49
|
+
// ── UpProgress class ──
|
|
50
|
+
class UpProgress {
|
|
51
|
+
write;
|
|
52
|
+
isTTY;
|
|
53
|
+
columns;
|
|
54
|
+
now;
|
|
55
|
+
autoRender;
|
|
56
|
+
renderIntervalMs;
|
|
57
|
+
setTimer;
|
|
58
|
+
clearTimer;
|
|
59
|
+
eventScope;
|
|
60
|
+
commandName;
|
|
61
|
+
completed = [];
|
|
62
|
+
currentPhase = null;
|
|
63
|
+
currentDetail = null;
|
|
64
|
+
upPhasePlan = BASE_UP_PHASE_PLAN;
|
|
65
|
+
prevLineCount = 0;
|
|
66
|
+
ended = false;
|
|
67
|
+
renderTimer = null;
|
|
68
|
+
constructor(options) {
|
|
69
|
+
/* v8 ignore next -- thin wrapper: raw process.stdout.write for ANSI cursor control @preserve */
|
|
70
|
+
this.write = options?.write ?? ((text) => process.stdout.write(text));
|
|
71
|
+
/* v8 ignore next -- thin wrapper: real isTTY check injected for testability @preserve */
|
|
72
|
+
this.isTTY = options?.isTTY ?? (process.stdout.isTTY === true);
|
|
73
|
+
this.columns = options?.columns;
|
|
74
|
+
/* v8 ignore next -- thin wrapper: real Date.now injected for testability @preserve */
|
|
75
|
+
this.now = options?.now ?? (() => Date.now());
|
|
76
|
+
this.autoRender = options?.autoRender ?? false;
|
|
77
|
+
this.renderIntervalMs = options?.renderIntervalMs ?? 80;
|
|
78
|
+
/* v8 ignore start -- real timers are injected in tests when needed @preserve */
|
|
79
|
+
this.setTimer = options?.setInterval ?? ((callback, ms) => setInterval(callback, ms));
|
|
80
|
+
this.clearTimer = options?.clearInterval ?? ((handle) => clearInterval(handle));
|
|
81
|
+
/* v8 ignore stop */
|
|
82
|
+
this.eventScope = options?.eventScope ?? "up";
|
|
83
|
+
this.commandName = options?.commandName ?? null;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Begin a new phase with spinner. If a phase is already active, it is
|
|
87
|
+
* auto-completed (no detail text).
|
|
88
|
+
*/
|
|
89
|
+
startPhase(label) {
|
|
90
|
+
if (this.currentPhase) {
|
|
91
|
+
this.completePhase(this.currentPhase.label);
|
|
92
|
+
}
|
|
93
|
+
this.currentPhase = { label, startedAt: this.now() };
|
|
94
|
+
this.currentDetail = null;
|
|
95
|
+
if (this.isTTY) {
|
|
96
|
+
this.ensureAutoRender();
|
|
97
|
+
this.flushRender();
|
|
98
|
+
}
|
|
99
|
+
else {
|
|
100
|
+
this.write(` ... ${label}\n`);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* Emit a one-line status breadcrumb in non-TTY mode without affecting the
|
|
105
|
+
* accumulated checklist state. Used for daemon startup sub-steps.
|
|
106
|
+
*/
|
|
107
|
+
announceStep(label) {
|
|
108
|
+
if (this.currentPhase) {
|
|
109
|
+
this.updateDetail(label);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
if (this.isTTY)
|
|
113
|
+
return;
|
|
114
|
+
this.write(` ${label}\n`);
|
|
115
|
+
}
|
|
116
|
+
setPhasePlan(labels) {
|
|
117
|
+
const nextPlan = [...new Set(labels.map((label) => label.trim()).filter((label) => label.length > 0))];
|
|
118
|
+
this.upPhasePlan = nextPlan.length > 0 ? nextPlan : BASE_UP_PHASE_PLAN;
|
|
119
|
+
if (this.isTTY && this.eventScope === "up") {
|
|
120
|
+
this.flushRender();
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Update the sub-step detail on the current spinner phase. Rendered as
|
|
125
|
+
* "label (Xs) -- detail" in TTY mode. In non-TTY mode, writes changed
|
|
126
|
+
* detail lines so long operations remain visible in logs and captured output.
|
|
127
|
+
*/
|
|
128
|
+
updateDetail(detail) {
|
|
129
|
+
if (!this.currentPhase || detail === this.currentDetail)
|
|
130
|
+
return;
|
|
131
|
+
this.currentDetail = detail;
|
|
132
|
+
this.currentPhase.detail = detail;
|
|
133
|
+
if (this.isTTY) {
|
|
134
|
+
this.flushRender();
|
|
135
|
+
return;
|
|
136
|
+
}
|
|
137
|
+
for (const line of splitDetailLines(detail)) {
|
|
138
|
+
this.write(` ${line}\n`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
/**
|
|
142
|
+
* Mark the current phase as done. In non-TTY mode, immediately writes
|
|
143
|
+
* a static line. Emits a nerves event for observability.
|
|
144
|
+
*/
|
|
145
|
+
completePhase(label, detail) {
|
|
146
|
+
if (!this.currentPhase) {
|
|
147
|
+
return;
|
|
148
|
+
}
|
|
149
|
+
const elapsedMs = this.now() - this.currentPhase.startedAt;
|
|
150
|
+
this.completed.push({ status: "success", label, detail });
|
|
151
|
+
this.currentPhase = null;
|
|
152
|
+
this.currentDetail = null;
|
|
153
|
+
this.stopAutoRender();
|
|
154
|
+
if (this.eventScope === "command") {
|
|
155
|
+
(0, runtime_1.emitNervesEvent)({
|
|
156
|
+
component: "daemon",
|
|
157
|
+
event: "daemon.cli_progress_phase_complete",
|
|
158
|
+
message: `phase complete: ${label}`,
|
|
159
|
+
meta: { command: this.commandName, phase: label, detail: detail ?? null, elapsedMs },
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
(0, runtime_1.emitNervesEvent)({
|
|
164
|
+
component: "daemon",
|
|
165
|
+
event: "daemon.up_phase_complete",
|
|
166
|
+
message: `phase complete: ${label}`,
|
|
167
|
+
meta: { phase: label, detail: detail ?? null, elapsedMs },
|
|
168
|
+
});
|
|
169
|
+
}
|
|
170
|
+
if (this.isTTY) {
|
|
171
|
+
this.flushRender();
|
|
172
|
+
}
|
|
173
|
+
else {
|
|
174
|
+
const detailStr = detail ? ` \u2014 ${detail}` : "";
|
|
175
|
+
this.write(` \u2713 ${label}${detailStr}\n`);
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
failPhase(label, detail) {
|
|
179
|
+
if (!this.currentPhase) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
const elapsedMs = this.now() - this.currentPhase.startedAt;
|
|
183
|
+
this.completed.push({ status: "failure", label, detail });
|
|
184
|
+
this.currentPhase = null;
|
|
185
|
+
this.currentDetail = null;
|
|
186
|
+
this.stopAutoRender();
|
|
187
|
+
if (this.eventScope === "command") {
|
|
188
|
+
(0, runtime_1.emitNervesEvent)({
|
|
189
|
+
level: "warn",
|
|
190
|
+
component: "daemon",
|
|
191
|
+
event: "daemon.cli_progress_phase_failed",
|
|
192
|
+
message: `phase failed: ${label}`,
|
|
193
|
+
meta: { command: this.commandName, phase: label, detail: detail ?? null, elapsedMs },
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
else {
|
|
197
|
+
(0, runtime_1.emitNervesEvent)({
|
|
198
|
+
level: "warn",
|
|
199
|
+
component: "daemon",
|
|
200
|
+
event: "daemon.up_phase_failed",
|
|
201
|
+
message: `phase failed: ${label}`,
|
|
202
|
+
meta: { phase: label, detail: detail ?? null, elapsedMs },
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
if (this.isTTY) {
|
|
206
|
+
this.flushRender();
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
const detailStr = detail ? ` \u2014 ${detail}` : "";
|
|
210
|
+
this.write(` \u2717 ${label}${detailStr}\n`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
/**
|
|
214
|
+
* Build an ANSI string for in-place terminal display. Returns empty
|
|
215
|
+
* string in non-TTY mode (output is written eagerly in completePhase).
|
|
216
|
+
*/
|
|
217
|
+
render(now) {
|
|
218
|
+
if (!this.isTTY) {
|
|
219
|
+
return "";
|
|
220
|
+
}
|
|
221
|
+
const lines = this.renderLines(now);
|
|
222
|
+
const output = (0, terminal_ui_1.renderOverwriteFrame)(lines, this.prevLineCount, true);
|
|
223
|
+
this.prevLineCount = lines.length;
|
|
224
|
+
return output;
|
|
225
|
+
}
|
|
226
|
+
/**
|
|
227
|
+
* Finalize the progress display. Clears the current phase (if any) and
|
|
228
|
+
* writes the final checklist state. Idempotent.
|
|
229
|
+
*/
|
|
230
|
+
end() {
|
|
231
|
+
if (this.ended) {
|
|
232
|
+
return;
|
|
233
|
+
}
|
|
234
|
+
this.ended = true;
|
|
235
|
+
if (this.currentPhase) {
|
|
236
|
+
this.currentPhase = null;
|
|
237
|
+
this.currentDetail = null;
|
|
238
|
+
}
|
|
239
|
+
this.stopAutoRender();
|
|
240
|
+
if (this.isTTY) {
|
|
241
|
+
this.flushRender();
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
ensureAutoRender() {
|
|
245
|
+
if (!this.autoRender || !this.isTTY || this.renderTimer !== null) {
|
|
246
|
+
return;
|
|
247
|
+
}
|
|
248
|
+
this.renderTimer = this.setTimer(() => this.flushRender(), this.renderIntervalMs);
|
|
249
|
+
}
|
|
250
|
+
stopAutoRender() {
|
|
251
|
+
if (this.renderTimer === null) {
|
|
252
|
+
return;
|
|
253
|
+
}
|
|
254
|
+
this.clearTimer(this.renderTimer);
|
|
255
|
+
this.renderTimer = null;
|
|
256
|
+
}
|
|
257
|
+
flushRender() {
|
|
258
|
+
const output = this.render(this.now());
|
|
259
|
+
this.write(output);
|
|
260
|
+
}
|
|
261
|
+
renderLines(now) {
|
|
262
|
+
if (this.eventScope === "up") {
|
|
263
|
+
return this.renderUpScreen(now);
|
|
264
|
+
}
|
|
265
|
+
const lines = [];
|
|
266
|
+
for (const phase of this.completed) {
|
|
267
|
+
const detailStr = phase.detail ? ` ${DIM}\u2014 ${phase.detail}${RESET}` : "";
|
|
268
|
+
if (phase.status === "failure") {
|
|
269
|
+
lines.push(` ${RED}\u2717${RESET} ${phase.label}${detailStr}`);
|
|
270
|
+
}
|
|
271
|
+
else {
|
|
272
|
+
lines.push(` ${GREEN}\u2713${RESET} ${phase.label}${detailStr}`);
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
if (this.currentPhase) {
|
|
276
|
+
const elapsed = now - this.currentPhase.startedAt;
|
|
277
|
+
const elapsedSec = (elapsed / 1000).toFixed(1);
|
|
278
|
+
const frameIndex = Math.floor(elapsed / 80) % SPINNER_FRAMES.length;
|
|
279
|
+
const spinner = SPINNER_FRAMES[frameIndex];
|
|
280
|
+
lines.push(` ${BOLD}${spinner}${RESET} ${this.currentPhase.label} ${DIM}(${elapsedSec}s)${RESET}`);
|
|
281
|
+
for (const detailLine of splitDetailLines(this.currentPhase.detail)) {
|
|
282
|
+
lines.push(` ${DIM}${detailLine}${RESET}`);
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
return lines;
|
|
286
|
+
}
|
|
287
|
+
renderUpStepLabel(label) {
|
|
288
|
+
return FRIENDLY_UP_PHASE_LABELS[label] ?? label;
|
|
289
|
+
}
|
|
290
|
+
renderUpScreen(now) {
|
|
291
|
+
const seenLabels = new Set();
|
|
292
|
+
const completedByLabel = new Map(this.completed.map((phase) => [phase.label, phase]));
|
|
293
|
+
const steps = [];
|
|
294
|
+
let currentStepLabel = this.completed.some((phase) => phase.status === "failure")
|
|
295
|
+
? "Boot paused."
|
|
296
|
+
: this.completed.length > 0
|
|
297
|
+
? "Boot checklist complete."
|
|
298
|
+
: "Waiting to begin.";
|
|
299
|
+
let currentStepDetails = [];
|
|
300
|
+
if (this.currentPhase) {
|
|
301
|
+
const elapsed = now - this.currentPhase.startedAt;
|
|
302
|
+
const elapsedSec = (elapsed / 1000).toFixed(1);
|
|
303
|
+
const frameIndex = Math.floor(elapsed / 80) % SPINNER_FRAMES.length;
|
|
304
|
+
const spinner = SPINNER_FRAMES[frameIndex];
|
|
305
|
+
currentStepLabel = `${spinner} ${this.renderUpStepLabel(this.currentPhase.label)} (${elapsedSec}s)`;
|
|
306
|
+
currentStepDetails = splitDetailLines(this.currentPhase.detail);
|
|
307
|
+
}
|
|
308
|
+
for (const label of this.upPhasePlan) {
|
|
309
|
+
seenLabels.add(label);
|
|
310
|
+
const completedPhase = completedByLabel.get(label);
|
|
311
|
+
if (completedPhase) {
|
|
312
|
+
steps.push({
|
|
313
|
+
label: this.renderUpStepLabel(label),
|
|
314
|
+
status: completedPhase.status === "failure" ? "failed" : "done",
|
|
315
|
+
detail: completedPhase.detail,
|
|
316
|
+
});
|
|
317
|
+
continue;
|
|
318
|
+
}
|
|
319
|
+
if (this.currentPhase?.label === label) {
|
|
320
|
+
steps.push({
|
|
321
|
+
label: this.renderUpStepLabel(label),
|
|
322
|
+
status: "active",
|
|
323
|
+
});
|
|
324
|
+
continue;
|
|
325
|
+
}
|
|
326
|
+
steps.push({
|
|
327
|
+
label: this.renderUpStepLabel(label),
|
|
328
|
+
status: "pending",
|
|
329
|
+
});
|
|
330
|
+
}
|
|
331
|
+
for (const phase of this.completed) {
|
|
332
|
+
if (!seenLabels.has(phase.label)) {
|
|
333
|
+
steps.push({
|
|
334
|
+
label: this.renderUpStepLabel(phase.label),
|
|
335
|
+
status: phase.status === "failure" ? "failed" : "done",
|
|
336
|
+
detail: phase.detail,
|
|
337
|
+
});
|
|
338
|
+
}
|
|
339
|
+
}
|
|
340
|
+
if (this.currentPhase && !seenLabels.has(this.currentPhase.label)) {
|
|
341
|
+
steps.push({
|
|
342
|
+
label: this.renderUpStepLabel(this.currentPhase.label),
|
|
343
|
+
status: "active",
|
|
344
|
+
});
|
|
345
|
+
}
|
|
346
|
+
return (0, terminal_ui_1.renderTerminalOperation)({
|
|
347
|
+
isTTY: true,
|
|
348
|
+
columns: this.columns,
|
|
349
|
+
masthead: {
|
|
350
|
+
subtitle: "Booting the local agent runtime.",
|
|
351
|
+
},
|
|
352
|
+
title: "Starting Ouro",
|
|
353
|
+
summary: "Ouro is bringing the local agent runtime online and will stop here if anything needs attention.",
|
|
354
|
+
currentStep: {
|
|
355
|
+
label: currentStepLabel,
|
|
356
|
+
detailLines: currentStepDetails,
|
|
357
|
+
},
|
|
358
|
+
steps,
|
|
359
|
+
currentTitle: "Doing now",
|
|
360
|
+
stepsTitle: "Boot checklist",
|
|
361
|
+
suppressEvent: true,
|
|
362
|
+
}).trimEnd().split("\n");
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
exports.UpProgress = UpProgress;
|
|
366
|
+
exports.CommandProgress = UpProgress;
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PORKBUN_OPS_COMPATIBILITY_ALIAS = exports.PORKBUN_OPS_CREDENTIAL_PREFIX = void 0;
|
|
4
|
+
exports.isVaultItemTemplate = isVaultItemTemplate;
|
|
5
|
+
exports.normalizeVaultItemName = normalizeVaultItemName;
|
|
6
|
+
exports.normalizeVaultItemFieldName = normalizeVaultItemFieldName;
|
|
7
|
+
exports.vaultItemTemplateSecretFields = vaultItemTemplateSecretFields;
|
|
8
|
+
exports.normalizePorkbunOpsAccount = normalizePorkbunOpsAccount;
|
|
9
|
+
exports.porkbunOpsCredentialItemName = porkbunOpsCredentialItemName;
|
|
10
|
+
exports.porkbunOpsAccountFromItemName = porkbunOpsAccountFromItemName;
|
|
11
|
+
exports.requireVaultItemSecret = requireVaultItemSecret;
|
|
12
|
+
exports.PORKBUN_OPS_CREDENTIAL_PREFIX = "ops/registrars/porkbun/accounts";
|
|
13
|
+
exports.PORKBUN_OPS_COMPATIBILITY_ALIAS = "vault ops porkbun";
|
|
14
|
+
const VAULT_ITEM_NAME_FORBIDDEN = /[\r\n\t]/;
|
|
15
|
+
const VAULT_ITEM_FIELD_FORBIDDEN = /[\r\n\t=]/;
|
|
16
|
+
const PORKBUN_OPS_ACCOUNT_FORBIDDEN = /[\/\r\n\t]/;
|
|
17
|
+
function isVaultItemTemplate(value) {
|
|
18
|
+
return value === "porkbun-api";
|
|
19
|
+
}
|
|
20
|
+
function normalizeVaultItemName(item) {
|
|
21
|
+
const normalized = item?.trim() ?? "";
|
|
22
|
+
if (!normalized || VAULT_ITEM_NAME_FORBIDDEN.test(normalized) || normalized.startsWith("/") || normalized.endsWith("/")) {
|
|
23
|
+
throw new Error("Vault item name/path must be non-empty, relative, and free of control characters.");
|
|
24
|
+
}
|
|
25
|
+
return normalized;
|
|
26
|
+
}
|
|
27
|
+
function normalizeVaultItemFieldName(field) {
|
|
28
|
+
const normalized = field?.trim() ?? "";
|
|
29
|
+
if (!normalized || VAULT_ITEM_FIELD_FORBIDDEN.test(normalized)) {
|
|
30
|
+
throw new Error("Vault item field names must be non-empty and free of control characters or '='.");
|
|
31
|
+
}
|
|
32
|
+
return normalized;
|
|
33
|
+
}
|
|
34
|
+
function vaultItemTemplateSecretFields(_template) {
|
|
35
|
+
return ["apiKey", "secretApiKey"];
|
|
36
|
+
}
|
|
37
|
+
function normalizePorkbunOpsAccount(account) {
|
|
38
|
+
const normalized = account?.trim() ?? "";
|
|
39
|
+
if (!normalized || PORKBUN_OPS_ACCOUNT_FORBIDDEN.test(normalized)) {
|
|
40
|
+
throw new Error("Porkbun account must be a non-empty account label without slashes or control characters.");
|
|
41
|
+
}
|
|
42
|
+
return normalized;
|
|
43
|
+
}
|
|
44
|
+
function porkbunOpsCredentialItemName(account) {
|
|
45
|
+
return `${exports.PORKBUN_OPS_CREDENTIAL_PREFIX}/${normalizePorkbunOpsAccount(account)}`;
|
|
46
|
+
}
|
|
47
|
+
function porkbunOpsAccountFromItemName(itemName) {
|
|
48
|
+
const prefix = `${exports.PORKBUN_OPS_CREDENTIAL_PREFIX}/`;
|
|
49
|
+
return itemName.startsWith(prefix) ? itemName.slice(prefix.length) : undefined;
|
|
50
|
+
}
|
|
51
|
+
function requireVaultItemSecret(value, label) {
|
|
52
|
+
const trimmed = value.trim();
|
|
53
|
+
if (!trimmed)
|
|
54
|
+
throw new Error(`${label} cannot be blank`);
|
|
55
|
+
return trimmed;
|
|
56
|
+
}
|