@ouro.bot/cli 0.1.0-alpha.5 → 0.1.0-alpha.500
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 +226 -183
- package/SerpentGuide.ouro/agent.json +82 -0
- package/SerpentGuide.ouro/psyche/SOUL.md +25 -0
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/monty.md +2 -2
- package/{AdoptionSpecialist.ouro → SerpentGuide.ouro}/psyche/identities/the-serpent.md +1 -1
- package/assets/ouroboros.png +0 -0
- package/changelog.json +3418 -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 +989 -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 +281 -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 +193 -130
- package/dist/heart/core.js +1010 -261
- 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 +157 -0
- 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 +7239 -0
- package/dist/heart/daemon/cli-help.js +493 -0
- package/dist/heart/daemon/cli-parse.js +1533 -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 +30 -697
- package/dist/heart/daemon/daemon-entry.js +359 -8
- package/dist/heart/daemon/daemon-health.js +141 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +268 -0
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +813 -19
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +615 -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 +206 -0
- 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 +171 -0
- 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 +17 -8
- 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 +215 -1
- 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 +39 -0
- package/dist/heart/daemon/runtime-logging.js +67 -16
- package/dist/heart/daemon/runtime-metadata.js +191 -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 +431 -0
- 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 +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 +524 -0
- 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-animation.js +10 -3
- package/dist/heart/{daemon → hatch}/hatch-flow.js +54 -136
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +3 -3
- package/dist/heart/hatch/specialist-orchestrator.js +129 -0
- package/dist/heart/hatch/specialist-prompt.js +102 -0
- package/dist/heart/hatch/specialist-tools.js +306 -0
- package/dist/heart/identity.js +274 -61
- package/dist/heart/kept-notes.js +357 -0
- package/dist/heart/kicks.js +2 -20
- package/dist/heart/machine-identity.js +161 -0
- package/dist/heart/mail-import-discovery.js +353 -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 +103 -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 +382 -0
- package/dist/heart/outlook/readers/continuity-readers.js +336 -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 +301 -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 +202 -50
- package/dist/heart/providers/azure.js +104 -13
- 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 +63 -39
- package/dist/heart/runtime-capability-check.js +170 -0
- package/dist/heart/runtime-credentials.js +260 -0
- package/dist/heart/sense-truth.js +68 -0
- package/dist/heart/session-activity.js +190 -0
- package/dist/heart/session-events.js +1089 -0
- package/dist/heart/session-playback-cli-main.js +5 -0
- package/dist/heart/session-playback-cli.js +36 -0
- package/dist/heart/session-playback.js +231 -0
- package/dist/heart/session-transcript.js +167 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +129 -34
- 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 +372 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/heart/versioning/ouro-bot-global-installer.js +128 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +425 -0
- package/dist/heart/{daemon → versioning}/ouro-uti.js +11 -2
- package/dist/heart/versioning/ouro-version-manager.js +295 -0
- package/dist/heart/versioning/staged-restart.js +146 -0
- package/dist/heart/versioning/update-checker.js +115 -0
- package/dist/heart/versioning/update-hooks.js +142 -0
- package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +606 -0
- package/dist/mailroom/core.js +672 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +426 -0
- package/dist/mailroom/mbox-import.js +382 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +219 -0
- package/dist/mailroom/search-cache.js +182 -0
- package/dist/mailroom/search-relevance.js +319 -0
- package/dist/mailroom/smtp-ingress.js +176 -0
- package/dist/mailroom/source-state.js +176 -0
- package/dist/mailroom/thread.js +109 -0
- package/dist/mailroom/travel-extract.js +89 -0
- package/dist/mind/bundle-manifest.js +77 -1
- package/dist/mind/context.js +173 -94
- package/dist/mind/diary-integrity.js +60 -0
- package/dist/mind/{memory.js → diary.js} +84 -96
- package/dist/mind/embedding-provider.js +60 -0
- package/dist/mind/file-state.js +179 -0
- package/dist/mind/first-impressions.js +16 -2
- package/dist/mind/friends/channel.js +73 -0
- package/dist/mind/friends/group-context.js +144 -0
- package/dist/mind/friends/resolver.js +54 -2
- package/dist/mind/friends/store-file.js +58 -3
- package/dist/mind/friends/trust-explanation.js +74 -0
- package/dist/mind/friends/types.js +10 -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 +76 -9
- package/dist/mind/phrases.js +1 -0
- package/dist/mind/prompt-refresh.js +3 -2
- package/dist/mind/prompt.js +1144 -117
- package/dist/mind/provenance-trust.js +26 -0
- package/dist/mind/scrutiny.js +173 -0
- package/dist/mind/token-estimate.js +8 -12
- package/dist/nerves/cli-logging.js +22 -3
- 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 +101 -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-Cm51CY9W.js +61 -0
- package/dist/outlook-ui/index.html +15 -0
- package/dist/repertoire/ado-client.js +17 -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 +301 -0
- package/dist/repertoire/coding/index.js +4 -1
- package/dist/repertoire/coding/manager.js +220 -13
- package/dist/repertoire/coding/spawner.js +58 -12
- package/dist/repertoire/coding/tools.js +209 -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/data/ado-endpoints.json +188 -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 +39 -13
- 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 -79
- package/dist/repertoire/tool-results.js +29 -0
- package/dist/repertoire/tools-attachments.js +317 -0
- package/dist/repertoire/tools-base.js +49 -707
- package/dist/repertoire/tools-bluebubbles.js +94 -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 +1377 -0
- package/dist/repertoire/tools-notes.js +376 -0
- package/dist/repertoire/tools-session.js +749 -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 +64 -61
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +356 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools.js +149 -98
- 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 +685 -0
- package/dist/senses/bluebubbles/entry.js +73 -0
- package/dist/senses/bluebubbles/inbound-log.js +126 -0
- package/dist/senses/bluebubbles/index.js +1881 -0
- package/dist/senses/bluebubbles/media.js +389 -0
- package/dist/senses/bluebubbles/model.js +282 -0
- package/dist/senses/bluebubbles/mutation-log.js +116 -0
- package/dist/senses/bluebubbles/processed-log.js +111 -0
- package/dist/senses/bluebubbles/replay.js +129 -0
- package/dist/senses/bluebubbles/runtime-state.js +109 -0
- package/dist/senses/bluebubbles/session-cleanup.js +72 -0
- package/dist/senses/cli/bracketed-paste.js +82 -0
- package/dist/senses/cli/image-paste.js +287 -0
- package/dist/senses/cli/image-ref-navigation.js +75 -0
- package/dist/senses/cli/ink-app.js +156 -0
- package/dist/senses/cli/inline-diff.js +64 -0
- package/dist/senses/cli/input-keys.js +174 -0
- package/dist/senses/cli/kill-ring.js +86 -0
- package/dist/senses/cli/message-list.js +51 -0
- package/dist/senses/cli/ouro-tui.js +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 +768 -264
- package/dist/senses/commands.js +66 -3
- package/dist/senses/continuity.js +94 -0
- package/dist/senses/habit-turn-message.js +108 -0
- package/dist/senses/inner-dialog-worker.js +199 -16
- package/dist/senses/inner-dialog.js +640 -91
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +665 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +248 -0
- package/dist/senses/surface-tool.js +68 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +844 -197
- package/dist/senses/trust-gate.js +207 -2
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +146 -0
- package/package.json +47 -6
- 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/AdoptionSpecialist.ouro/agent.json +0 -20
- package/AdoptionSpecialist.ouro/psyche/SOUL.md +0 -22
- package/dist/heart/daemon/specialist-orchestrator.js +0 -160
- package/dist/heart/daemon/specialist-prompt.js +0 -40
- package/dist/heart/daemon/specialist-session.js +0 -142
- package/dist/heart/daemon/specialist-tools.js +0 -128
- package/dist/heart/daemon/subagent-installer.js +0 -125
- package/dist/inner-worker-entry.js +0 -4
- package/dist/mind/associative-recall.js +0 -197
- package/subagents/README.md +0 -73
- package/subagents/work-doer.md +0 -233
- package/subagents/work-merger.md +0 -624
- package/subagents/work-planner.md +0 -373
- /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/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
|
@@ -0,0 +1,357 @@
|
|
|
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.gatherKeptNotesCandidates = gatherKeptNotesCandidates;
|
|
37
|
+
exports.renderKeptNotesOutcome = renderKeptNotesOutcome;
|
|
38
|
+
exports.injectKeptNotes = injectKeptNotes;
|
|
39
|
+
exports.createKeptNotesJudge = createKeptNotesJudge;
|
|
40
|
+
const fs = __importStar(require("fs"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const diary_1 = require("../mind/diary");
|
|
43
|
+
const runtime_1 = require("../nerves/runtime");
|
|
44
|
+
const DEFAULT_TIMEOUT_MS = 2500;
|
|
45
|
+
const MAX_CANDIDATES = 8;
|
|
46
|
+
const NOOP_CALLBACKS = {
|
|
47
|
+
onModelStart() { },
|
|
48
|
+
onModelStreamStart() { },
|
|
49
|
+
onTextChunk() { },
|
|
50
|
+
onReasoningChunk() { },
|
|
51
|
+
onToolStart() { },
|
|
52
|
+
onToolEnd() { },
|
|
53
|
+
onError() { },
|
|
54
|
+
};
|
|
55
|
+
function elapsedSince(startedAt) {
|
|
56
|
+
return Math.max(0, Date.now() - startedAt);
|
|
57
|
+
}
|
|
58
|
+
function latestUserText(messages) {
|
|
59
|
+
for (let i = messages.length - 1; i >= 0; i--) {
|
|
60
|
+
const message = messages[i];
|
|
61
|
+
if (message.role !== "user" || typeof message.content !== "string")
|
|
62
|
+
continue;
|
|
63
|
+
const text = message.content.trim();
|
|
64
|
+
if (text)
|
|
65
|
+
return text;
|
|
66
|
+
}
|
|
67
|
+
return "";
|
|
68
|
+
}
|
|
69
|
+
function tokenize(text) {
|
|
70
|
+
return new Set(text
|
|
71
|
+
.toLowerCase()
|
|
72
|
+
.split(/[^a-z0-9]+/g)
|
|
73
|
+
.map((token) => token.trim())
|
|
74
|
+
.filter((token) => token.length > 2));
|
|
75
|
+
}
|
|
76
|
+
function scoreText(queryTerms, text) {
|
|
77
|
+
const textTerms = tokenize(text);
|
|
78
|
+
let matches = 0;
|
|
79
|
+
for (const term of queryTerms) {
|
|
80
|
+
if (textTerms.has(term))
|
|
81
|
+
matches += 1;
|
|
82
|
+
}
|
|
83
|
+
return matches / queryTerms.size;
|
|
84
|
+
}
|
|
85
|
+
function readJournalIndex(journalDir) {
|
|
86
|
+
try {
|
|
87
|
+
const parsed = JSON.parse(fs.readFileSync(path.join(journalDir, ".index.json"), "utf8"));
|
|
88
|
+
if (!Array.isArray(parsed))
|
|
89
|
+
return [];
|
|
90
|
+
return parsed
|
|
91
|
+
.filter((entry) => (typeof entry === "object" &&
|
|
92
|
+
entry !== null &&
|
|
93
|
+
typeof entry.filename === "string" &&
|
|
94
|
+
typeof entry.preview === "string"));
|
|
95
|
+
}
|
|
96
|
+
catch {
|
|
97
|
+
return [];
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
function journalDirForDiaryRoot(diaryRoot, explicitJournalDir) {
|
|
101
|
+
if (explicitJournalDir)
|
|
102
|
+
return explicitJournalDir;
|
|
103
|
+
return path.join(path.dirname(diaryRoot), "journal");
|
|
104
|
+
}
|
|
105
|
+
function diaryCandidate(fact) {
|
|
106
|
+
return {
|
|
107
|
+
text: fact.text,
|
|
108
|
+
source: { kind: "diary", label: "diary", ref: fact.id },
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
function friendNoteCandidates(friend, queryTerms) {
|
|
112
|
+
if (!friend)
|
|
113
|
+
return [];
|
|
114
|
+
return Object.entries(friend.notes ?? {})
|
|
115
|
+
.map(([key, note]) => {
|
|
116
|
+
const text = `${friend.name} / ${key}: ${note.value}`;
|
|
117
|
+
return {
|
|
118
|
+
candidate: {
|
|
119
|
+
text,
|
|
120
|
+
source: { kind: "friend-note", label: `friend note: ${friend.name}`, ref: key },
|
|
121
|
+
},
|
|
122
|
+
score: scoreText(queryTerms, `${key} ${note.value}`),
|
|
123
|
+
};
|
|
124
|
+
})
|
|
125
|
+
.filter((entry) => entry.score > 0);
|
|
126
|
+
}
|
|
127
|
+
function gatherKeptNotesCandidates(query, options = {}) {
|
|
128
|
+
const queryTerms = tokenize(query);
|
|
129
|
+
if (queryTerms.size === 0)
|
|
130
|
+
return [];
|
|
131
|
+
const diaryRoot = (0, diary_1.resolveDiaryRoot)(options.diaryRoot);
|
|
132
|
+
const diaryEntries = (0, diary_1.readDiaryEntries)(diaryRoot);
|
|
133
|
+
const diaryCandidates = diaryEntries
|
|
134
|
+
.map((fact) => ({ candidate: diaryCandidate(fact), score: scoreText(queryTerms, fact.text) }))
|
|
135
|
+
.filter((entry) => entry.score > 0);
|
|
136
|
+
const journalDir = journalDirForDiaryRoot(diaryRoot, options.journalDir);
|
|
137
|
+
const journalCandidates = readJournalIndex(journalDir)
|
|
138
|
+
.map((entry) => ({
|
|
139
|
+
candidate: {
|
|
140
|
+
text: `${entry.filename}: ${entry.preview}`,
|
|
141
|
+
source: { kind: "journal", label: "journal", ref: entry.filename },
|
|
142
|
+
},
|
|
143
|
+
score: scoreText(queryTerms, `${entry.filename} ${entry.preview}`),
|
|
144
|
+
}))
|
|
145
|
+
.filter((entry) => entry.score > 0);
|
|
146
|
+
return [...diaryCandidates, ...journalCandidates, ...friendNoteCandidates(options.friend, queryTerms)]
|
|
147
|
+
.sort((left, right) => right.score - left.score)
|
|
148
|
+
.slice(0, MAX_CANDIDATES)
|
|
149
|
+
.map((entry) => entry.candidate);
|
|
150
|
+
}
|
|
151
|
+
function selectedSources(candidates, indexes) {
|
|
152
|
+
if (!indexes || indexes.length === 0)
|
|
153
|
+
return [];
|
|
154
|
+
const sources = [];
|
|
155
|
+
for (const index of indexes) {
|
|
156
|
+
if (!Number.isInteger(index))
|
|
157
|
+
continue;
|
|
158
|
+
const candidate = candidates[index];
|
|
159
|
+
if (candidate)
|
|
160
|
+
sources.push(candidate.source);
|
|
161
|
+
}
|
|
162
|
+
return sources;
|
|
163
|
+
}
|
|
164
|
+
function isFirstPerson(text) {
|
|
165
|
+
return /^(i|i'm|i’ve|i've|my|me)\b/i.test(text.trim());
|
|
166
|
+
}
|
|
167
|
+
function foundLine(text) {
|
|
168
|
+
const trimmed = text.trim();
|
|
169
|
+
if (isFirstPerson(trimmed))
|
|
170
|
+
return trimmed;
|
|
171
|
+
return `I kept this: ${trimmed}`;
|
|
172
|
+
}
|
|
173
|
+
function fuzzyLine(text) {
|
|
174
|
+
const trimmed = text.trim();
|
|
175
|
+
if (isFirstPerson(trimmed))
|
|
176
|
+
return trimmed;
|
|
177
|
+
return `I may have kept something related: ${trimmed}`;
|
|
178
|
+
}
|
|
179
|
+
const SOURCE_KIND_ORDER = ["diary", "journal", "friend-note"];
|
|
180
|
+
const SOURCE_KIND_LABELS = {
|
|
181
|
+
diary: "my diary",
|
|
182
|
+
journal: "my journal",
|
|
183
|
+
"friend-note": "my friend notes",
|
|
184
|
+
};
|
|
185
|
+
function joinLabels(labels) {
|
|
186
|
+
if (labels.length === 1)
|
|
187
|
+
return labels[0];
|
|
188
|
+
if (labels.length === 2)
|
|
189
|
+
return `${labels[0]} and ${labels[1]}`;
|
|
190
|
+
return `${labels.slice(0, -1).join(", ")}, and ${labels[labels.length - 1]}`;
|
|
191
|
+
}
|
|
192
|
+
function sourceHeading(sources) {
|
|
193
|
+
const sourceKinds = new Set(sources.map((source) => source.kind));
|
|
194
|
+
const labels = SOURCE_KIND_ORDER
|
|
195
|
+
.filter((kind) => sourceKinds.has(kind))
|
|
196
|
+
.map((kind) => SOURCE_KIND_LABELS[kind]);
|
|
197
|
+
if (labels.length === 0)
|
|
198
|
+
return "## from notes i chose to keep";
|
|
199
|
+
return `## from ${joinLabels(labels)}`;
|
|
200
|
+
}
|
|
201
|
+
function renderKeptNotesOutcome(outcome) {
|
|
202
|
+
if (outcome.status === "found") {
|
|
203
|
+
return `${sourceHeading(outcome.sources)}\nThis may matter now:\n${foundLine(outcome.note)}`;
|
|
204
|
+
}
|
|
205
|
+
if (outcome.status === "fuzzy") {
|
|
206
|
+
return `${sourceHeading(outcome.sources)}\nThis is only a possible match; I should verify it before relying on it:\n${fuzzyLine(outcome.hint)}`;
|
|
207
|
+
}
|
|
208
|
+
return null;
|
|
209
|
+
}
|
|
210
|
+
function finish(outcome, traceId) {
|
|
211
|
+
(0, runtime_1.emitNervesEvent)({
|
|
212
|
+
component: "mind",
|
|
213
|
+
event: "mind.kept_notes_end",
|
|
214
|
+
trace_id: traceId,
|
|
215
|
+
message: "kept notes completed",
|
|
216
|
+
meta: { status: outcome.status, elapsedMs: outcome.elapsedMs },
|
|
217
|
+
});
|
|
218
|
+
return outcome;
|
|
219
|
+
}
|
|
220
|
+
async function withTimeout(promise, timeoutMs) {
|
|
221
|
+
return await new Promise((resolve, reject) => {
|
|
222
|
+
const timeout = setTimeout(() => resolve("timeout"), timeoutMs);
|
|
223
|
+
promise
|
|
224
|
+
.then((value) => {
|
|
225
|
+
clearTimeout(timeout);
|
|
226
|
+
resolve(value);
|
|
227
|
+
})
|
|
228
|
+
.catch((error) => {
|
|
229
|
+
clearTimeout(timeout);
|
|
230
|
+
reject(error);
|
|
231
|
+
});
|
|
232
|
+
});
|
|
233
|
+
}
|
|
234
|
+
async function injectKeptNotes(messages, options = {}) {
|
|
235
|
+
const startedAt = Date.now();
|
|
236
|
+
const systemMessage = messages[0];
|
|
237
|
+
const query = latestUserText(messages);
|
|
238
|
+
if (systemMessage?.role !== "system" || typeof systemMessage.content !== "string" || !query) {
|
|
239
|
+
return { status: "none", elapsedMs: elapsedSince(startedAt), pressure: [] };
|
|
240
|
+
}
|
|
241
|
+
(0, runtime_1.emitNervesEvent)({
|
|
242
|
+
component: "mind",
|
|
243
|
+
event: "mind.kept_notes_start",
|
|
244
|
+
trace_id: options.traceId,
|
|
245
|
+
message: "kept notes started",
|
|
246
|
+
meta: { channel: options.channel ?? "unknown" },
|
|
247
|
+
});
|
|
248
|
+
try {
|
|
249
|
+
const candidates = gatherKeptNotesCandidates(query, options);
|
|
250
|
+
if (candidates.length === 0 || !options.judge) {
|
|
251
|
+
return finish({ status: "none", elapsedMs: elapsedSince(startedAt), pressure: [] }, options.traceId);
|
|
252
|
+
}
|
|
253
|
+
const judged = await withTimeout(options.judge({ query, candidates }), options.timeoutMs ?? DEFAULT_TIMEOUT_MS);
|
|
254
|
+
if (judged === "timeout") {
|
|
255
|
+
return finish({ status: "timeout", elapsedMs: elapsedSince(startedAt) }, options.traceId);
|
|
256
|
+
}
|
|
257
|
+
const elapsedMs = elapsedSince(startedAt);
|
|
258
|
+
const outcome = judged.status === "found"
|
|
259
|
+
? { status: "found", note: judged.note, sources: selectedSources(candidates, judged.sourceIndexes), elapsedMs }
|
|
260
|
+
: judged.status === "fuzzy"
|
|
261
|
+
? { status: "fuzzy", hint: judged.hint, sources: selectedSources(candidates, judged.sourceIndexes), elapsedMs }
|
|
262
|
+
: { status: "none", pressure: judged.pressure, elapsedMs };
|
|
263
|
+
if (outcome.status === "found" || outcome.status === "fuzzy") {
|
|
264
|
+
const rendered = renderKeptNotesOutcome(outcome);
|
|
265
|
+
messages[0] = { role: "system", content: `${systemMessage.content}\n\n${rendered}` };
|
|
266
|
+
(0, runtime_1.emitNervesEvent)({
|
|
267
|
+
component: "mind",
|
|
268
|
+
event: "mind.kept_notes_injected",
|
|
269
|
+
trace_id: options.traceId,
|
|
270
|
+
message: "kept notes injected",
|
|
271
|
+
meta: { status: outcome.status, sourceCount: outcome.sources.length },
|
|
272
|
+
});
|
|
273
|
+
}
|
|
274
|
+
return finish(outcome, options.traceId);
|
|
275
|
+
}
|
|
276
|
+
catch (error) {
|
|
277
|
+
const reason = error instanceof Error ? error.message : String(error);
|
|
278
|
+
const outcome = { status: "error", reason, elapsedMs: elapsedSince(startedAt) };
|
|
279
|
+
(0, runtime_1.emitNervesEvent)({
|
|
280
|
+
level: "warn",
|
|
281
|
+
component: "mind",
|
|
282
|
+
event: "mind.kept_notes_error",
|
|
283
|
+
trace_id: options.traceId,
|
|
284
|
+
message: "kept notes failed",
|
|
285
|
+
meta: { reason },
|
|
286
|
+
});
|
|
287
|
+
return finish(outcome, options.traceId);
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
function parseJudgeResult(content) {
|
|
291
|
+
try {
|
|
292
|
+
const parsed = JSON.parse(content);
|
|
293
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
294
|
+
return { status: "none", pressure: ["invalid kept notes judge output"] };
|
|
295
|
+
}
|
|
296
|
+
const record = parsed;
|
|
297
|
+
if (record.status === "found" && typeof record.note === "string" && record.note.trim()) {
|
|
298
|
+
return {
|
|
299
|
+
status: "found",
|
|
300
|
+
note: record.note.trim(),
|
|
301
|
+
sourceIndexes: Array.isArray(record.sourceIndexes) ? record.sourceIndexes.filter((index) => typeof index === "number") : undefined,
|
|
302
|
+
};
|
|
303
|
+
}
|
|
304
|
+
if (record.status === "fuzzy" && typeof record.hint === "string" && record.hint.trim()) {
|
|
305
|
+
return {
|
|
306
|
+
status: "fuzzy",
|
|
307
|
+
hint: record.hint.trim(),
|
|
308
|
+
sourceIndexes: Array.isArray(record.sourceIndexes) ? record.sourceIndexes.filter((index) => typeof index === "number") : undefined,
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
if (record.status === "none") {
|
|
312
|
+
return {
|
|
313
|
+
status: "none",
|
|
314
|
+
pressure: Array.isArray(record.pressure) ? record.pressure.filter((value) => typeof value === "string") : [],
|
|
315
|
+
};
|
|
316
|
+
}
|
|
317
|
+
return { status: "none", pressure: ["invalid kept notes judge output"] };
|
|
318
|
+
}
|
|
319
|
+
catch {
|
|
320
|
+
return { status: "none", pressure: ["invalid kept notes judge output"] };
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
function createJudgePrompt(input) {
|
|
324
|
+
const candidates = input.candidates
|
|
325
|
+
.map((candidate, index) => `${index}. [${candidate.source.kind}] ${candidate.text}`)
|
|
326
|
+
.join("\n");
|
|
327
|
+
return [
|
|
328
|
+
{
|
|
329
|
+
role: "system",
|
|
330
|
+
content: [
|
|
331
|
+
"Decide whether these intentionally kept notes matter to the user's current turn.",
|
|
332
|
+
"Return only JSON.",
|
|
333
|
+
"Use found when a note clearly helps, fuzzy when a note is close but uncertain, and none when nothing should be surfaced.",
|
|
334
|
+
"Shapes: {\"status\":\"found\",\"note\":\"...\",\"sourceIndexes\":[0]}, {\"status\":\"fuzzy\",\"hint\":\"...\",\"sourceIndexes\":[0]}, or {\"status\":\"none\",\"pressure\":[]}.",
|
|
335
|
+
].join("\n"),
|
|
336
|
+
},
|
|
337
|
+
{
|
|
338
|
+
role: "user",
|
|
339
|
+
content: `Current turn:\n${input.query}\n\nCandidates:\n${candidates}`,
|
|
340
|
+
},
|
|
341
|
+
];
|
|
342
|
+
}
|
|
343
|
+
function createKeptNotesJudge(runtime, signal) {
|
|
344
|
+
return async (input) => {
|
|
345
|
+
const messages = createJudgePrompt(input);
|
|
346
|
+
runtime.resetTurnState?.(messages);
|
|
347
|
+
const result = await runtime.streamTurn({
|
|
348
|
+
messages,
|
|
349
|
+
activeTools: [],
|
|
350
|
+
callbacks: NOOP_CALLBACKS,
|
|
351
|
+
signal,
|
|
352
|
+
toolChoiceRequired: false,
|
|
353
|
+
reasoningEffort: "low",
|
|
354
|
+
});
|
|
355
|
+
return parseJudgeResult(result.content ?? "");
|
|
356
|
+
};
|
|
357
|
+
}
|
package/dist/heart/kicks.js
CHANGED
|
@@ -1,28 +1,11 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
// TODO: Kicks enforce "any action" but not "meaningful action". After a narration
|
|
3
|
-
// kick, the model can satisfy the constraint by calling a no-op tool like
|
|
4
|
-
// get_current_time({}). We need to detect trivial compliance and either re-kick
|
|
5
|
-
// or discount the tool call. Ideally, the kick message would suggest a specific
|
|
6
|
-
// tool call based on conversation context (what the user asked, what tools are
|
|
7
|
-
// relevant) rather than just saying "call a tool". That's a bigger piece of work —
|
|
8
|
-
// it requires the kick system to be context-aware.
|
|
9
|
-
// See ouroboros' observation: "i'm not chickening out. i'm satisfying a crude
|
|
10
|
-
// constraint. poorly."
|
|
11
|
-
//
|
|
12
|
-
// A kick is a self-correction. When the harness detects a malformed response,
|
|
13
|
-
// it injects an assistant-role message as if the model caught its own mistake.
|
|
14
|
-
//
|
|
15
|
-
// Kicks are:
|
|
16
|
-
// - assistant role (self-correction, not external rebuke)
|
|
17
|
-
// - first person ("I" not "you")
|
|
18
|
-
// - forward-looking (what I'm doing next, not what I did wrong)
|
|
19
|
-
// - short (one sentence)
|
|
20
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
21
3
|
exports.hasToolIntent = hasToolIntent;
|
|
22
4
|
exports.detectKick = detectKick;
|
|
5
|
+
const runtime_1 = require("../nerves/runtime");
|
|
23
6
|
const KICK_MESSAGES = {
|
|
24
7
|
empty: "I sent an empty message by accident — let me try again.",
|
|
25
|
-
narration: "I narrated instead of acting. Using the tool now -- if done, calling
|
|
8
|
+
narration: "I narrated instead of acting. Using the tool now -- if done, calling settle.",
|
|
26
9
|
tool_required: "tool-required is on — I need to call a tool. use /tool-required to turn it off.",
|
|
27
10
|
};
|
|
28
11
|
const TOOL_INTENT_PATTERNS = [
|
|
@@ -141,4 +124,3 @@ function detectKick(content, options) {
|
|
|
141
124
|
}
|
|
142
125
|
return null;
|
|
143
126
|
}
|
|
144
|
-
const runtime_1 = require("../nerves/runtime");
|
|
@@ -0,0 +1,161 @@
|
|
|
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.getMachineIdentityPath = getMachineIdentityPath;
|
|
37
|
+
exports.loadOrCreateMachineIdentity = loadOrCreateMachineIdentity;
|
|
38
|
+
const crypto = __importStar(require("crypto"));
|
|
39
|
+
const fs = __importStar(require("fs"));
|
|
40
|
+
const os = __importStar(require("os"));
|
|
41
|
+
const path = __importStar(require("path"));
|
|
42
|
+
const runtime_1 = require("../nerves/runtime");
|
|
43
|
+
function nowIso(deps) {
|
|
44
|
+
return (deps.now?.() ?? new Date()).toISOString();
|
|
45
|
+
}
|
|
46
|
+
function currentHostname(deps) {
|
|
47
|
+
return (deps.hostname?.() ?? os.hostname()).trim();
|
|
48
|
+
}
|
|
49
|
+
function defaultRandomId() {
|
|
50
|
+
return `machine_${crypto.randomUUID()}`;
|
|
51
|
+
}
|
|
52
|
+
function normalizeAliases(value) {
|
|
53
|
+
if (!Array.isArray(value))
|
|
54
|
+
return [];
|
|
55
|
+
const aliases = [];
|
|
56
|
+
for (const alias of value) {
|
|
57
|
+
if (typeof alias !== "string")
|
|
58
|
+
continue;
|
|
59
|
+
const trimmed = alias.trim();
|
|
60
|
+
if (trimmed && !aliases.includes(trimmed))
|
|
61
|
+
aliases.push(trimmed);
|
|
62
|
+
}
|
|
63
|
+
return aliases;
|
|
64
|
+
}
|
|
65
|
+
function parseMachineIdentity(value) {
|
|
66
|
+
if (!value || typeof value !== "object" || Array.isArray(value))
|
|
67
|
+
return null;
|
|
68
|
+
const record = value;
|
|
69
|
+
const aliases = normalizeAliases(record.hostnameAliases);
|
|
70
|
+
if (record.schemaVersion !== 1 ||
|
|
71
|
+
typeof record.machineId !== "string" ||
|
|
72
|
+
record.machineId.trim().length === 0 ||
|
|
73
|
+
typeof record.createdAt !== "string" ||
|
|
74
|
+
record.createdAt.trim().length === 0 ||
|
|
75
|
+
typeof record.updatedAt !== "string" ||
|
|
76
|
+
record.updatedAt.trim().length === 0) {
|
|
77
|
+
return null;
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
schemaVersion: 1,
|
|
81
|
+
machineId: record.machineId,
|
|
82
|
+
createdAt: record.createdAt,
|
|
83
|
+
updatedAt: record.updatedAt,
|
|
84
|
+
hostnameAliases: aliases,
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
function writeMachineIdentity(machinePath, identity) {
|
|
88
|
+
fs.mkdirSync(path.dirname(machinePath), { recursive: true, mode: 0o700 });
|
|
89
|
+
fs.writeFileSync(machinePath, `${JSON.stringify(identity, null, 2)}\n`, { encoding: "utf-8", mode: 0o600 });
|
|
90
|
+
}
|
|
91
|
+
function getMachineIdentityPath(homeDir = os.homedir()) {
|
|
92
|
+
return path.join(homeDir, ".ouro-cli", "machine.json");
|
|
93
|
+
}
|
|
94
|
+
function loadOrCreateMachineIdentity(deps = {}) {
|
|
95
|
+
const homeDir = deps.homeDir ?? os.homedir();
|
|
96
|
+
const machinePath = getMachineIdentityPath(homeDir);
|
|
97
|
+
const hostname = currentHostname(deps);
|
|
98
|
+
let existing = null;
|
|
99
|
+
let hadInvalidFile = false;
|
|
100
|
+
try {
|
|
101
|
+
existing = parseMachineIdentity(JSON.parse(fs.readFileSync(machinePath, "utf-8")));
|
|
102
|
+
if (!existing)
|
|
103
|
+
hadInvalidFile = true;
|
|
104
|
+
}
|
|
105
|
+
catch (error) {
|
|
106
|
+
const code = error && typeof error === "object" && "code" in error
|
|
107
|
+
? error.code
|
|
108
|
+
: undefined;
|
|
109
|
+
if (code !== "ENOENT")
|
|
110
|
+
hadInvalidFile = true;
|
|
111
|
+
}
|
|
112
|
+
if (hadInvalidFile) {
|
|
113
|
+
(0, runtime_1.emitNervesEvent)({
|
|
114
|
+
level: "warn",
|
|
115
|
+
component: "config/identity",
|
|
116
|
+
event: "config.machine_identity_invalid",
|
|
117
|
+
message: "machine identity file is invalid; replacing it",
|
|
118
|
+
meta: { path: machinePath },
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
if (existing) {
|
|
122
|
+
if (hostname && !existing.hostnameAliases.includes(hostname)) {
|
|
123
|
+
const updated = {
|
|
124
|
+
...existing,
|
|
125
|
+
updatedAt: nowIso(deps),
|
|
126
|
+
hostnameAliases: [...existing.hostnameAliases, hostname],
|
|
127
|
+
};
|
|
128
|
+
writeMachineIdentity(machinePath, updated);
|
|
129
|
+
(0, runtime_1.emitNervesEvent)({
|
|
130
|
+
component: "config/identity",
|
|
131
|
+
event: "config.machine_identity_alias_added",
|
|
132
|
+
message: "recorded hostname alias for stable machine identity",
|
|
133
|
+
meta: { machineId: updated.machineId, hostname },
|
|
134
|
+
});
|
|
135
|
+
return updated;
|
|
136
|
+
}
|
|
137
|
+
(0, runtime_1.emitNervesEvent)({
|
|
138
|
+
component: "config/identity",
|
|
139
|
+
event: "config.machine_identity_loaded",
|
|
140
|
+
message: "loaded stable machine identity",
|
|
141
|
+
meta: { machineId: existing.machineId },
|
|
142
|
+
});
|
|
143
|
+
return existing;
|
|
144
|
+
}
|
|
145
|
+
const timestamp = nowIso(deps);
|
|
146
|
+
const identity = {
|
|
147
|
+
schemaVersion: 1,
|
|
148
|
+
machineId: (deps.randomId?.() ?? defaultRandomId()).trim() || defaultRandomId(),
|
|
149
|
+
createdAt: timestamp,
|
|
150
|
+
updatedAt: timestamp,
|
|
151
|
+
hostnameAliases: hostname ? [hostname] : [],
|
|
152
|
+
};
|
|
153
|
+
writeMachineIdentity(machinePath, identity);
|
|
154
|
+
(0, runtime_1.emitNervesEvent)({
|
|
155
|
+
component: "config/identity",
|
|
156
|
+
event: "config.machine_identity_created",
|
|
157
|
+
message: "created stable machine identity",
|
|
158
|
+
meta: { machineId: identity.machineId },
|
|
159
|
+
});
|
|
160
|
+
return identity;
|
|
161
|
+
}
|