@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
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
# Travel Planning Skill
|
|
2
|
+
|
|
3
|
+
Compose all travel infrastructure to plan and book trips effectively.
|
|
4
|
+
|
|
5
|
+
## Research Phase
|
|
6
|
+
|
|
7
|
+
### Destination Research
|
|
8
|
+
1. Use `geocode_search` to find candidate destinations and get coordinates
|
|
9
|
+
2. Use `weather_lookup` to check climate for travel dates
|
|
10
|
+
3. Use `travel_advisory` to check US State Dept safety levels (1-4):
|
|
11
|
+
- Level 1: Exercise Normal Precautions
|
|
12
|
+
- Level 2: Exercise Increased Caution
|
|
13
|
+
- Level 3: Reconsider Travel
|
|
14
|
+
- Level 4: Do Not Travel
|
|
15
|
+
4. Use browser tools (see `browser-navigation` skill) for destination reviews, travel blogs, local tips
|
|
16
|
+
5. Compare multiple destinations on weather, safety, cost, and flight availability
|
|
17
|
+
|
|
18
|
+
### Information Gathering Workflow
|
|
19
|
+
```
|
|
20
|
+
geocode_search -> get coordinates
|
|
21
|
+
weather_lookup -> check weather at coordinates
|
|
22
|
+
travel_advisory -> check safety level
|
|
23
|
+
browser tools -> reviews, local info, pricing
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
## Flight Search
|
|
27
|
+
|
|
28
|
+
### Using Duffel MCP (when available)
|
|
29
|
+
- Search via `duffel_search_flights` tool (first-class MCP tool)
|
|
30
|
+
- Provide: origin, destination, dates, passengers, cabin class
|
|
31
|
+
- Compare options on price, duration, stops, airline
|
|
32
|
+
|
|
33
|
+
### Using Browser (fallback)
|
|
34
|
+
- Use browser-navigation skill patterns for Google Flights, airline sites
|
|
35
|
+
- Add delays between searches to avoid detection
|
|
36
|
+
|
|
37
|
+
### Comparison Criteria
|
|
38
|
+
Present top 3-5 options comparing:
|
|
39
|
+
- Total price (including bags, seat selection)
|
|
40
|
+
- Duration and number of stops
|
|
41
|
+
- Airline and aircraft
|
|
42
|
+
- Departure/arrival times
|
|
43
|
+
- Cancellation/change policy
|
|
44
|
+
|
|
45
|
+
## Accommodation Search
|
|
46
|
+
|
|
47
|
+
### Hotel Search
|
|
48
|
+
- Use Expedia MCP when available (`expedia_search_hotels` tool)
|
|
49
|
+
- Compare: price per night, total stay cost, location, rating, amenities
|
|
50
|
+
- Check cancellation policies (crucial for travel planning)
|
|
51
|
+
|
|
52
|
+
### Vacation Rentals (Browser-based)
|
|
53
|
+
- Use browser-navigation skill for Airbnb/VRBO
|
|
54
|
+
- Search by location, dates, guests, budget
|
|
55
|
+
- Compare: price, location proximity, reviews, amenities, host rating
|
|
56
|
+
- Screenshot listings for user review
|
|
57
|
+
|
|
58
|
+
### Comparison Criteria
|
|
59
|
+
- Price per night and total cost
|
|
60
|
+
- Location (distance to key attractions/activities)
|
|
61
|
+
- Reviews and ratings
|
|
62
|
+
- Amenities (WiFi, kitchen, parking, pool)
|
|
63
|
+
- Cancellation flexibility
|
|
64
|
+
|
|
65
|
+
## Booking Workflow
|
|
66
|
+
|
|
67
|
+
### Critical Safety Gates
|
|
68
|
+
- **ALWAYS confirm with user before any booking action**
|
|
69
|
+
- **ALWAYS confirm before entering payment information**
|
|
70
|
+
- **ALWAYS confirm before agreeing to terms**
|
|
71
|
+
- **Never proceed with a financial commitment without explicit approval**
|
|
72
|
+
|
|
73
|
+
### Credential Handling
|
|
74
|
+
|
|
75
|
+
Credentials are managed through the credential access layer, which stores
|
|
76
|
+
agent-owned secrets in the agent's Bitwarden/Vaultwarden credential vault.
|
|
77
|
+
Stored passwords stay in the vault. A brand-new signup password may enter
|
|
78
|
+
model context briefly when the agent explicitly generates or types it during
|
|
79
|
+
an interactive sign-up flow.
|
|
80
|
+
|
|
81
|
+
- Use `credential_get` to check what credentials exist for a domain (metadata only, never passwords)
|
|
82
|
+
- Use `credential_generate_password` to mint a strong password for a new sign-up
|
|
83
|
+
- Use `credential_store` to save credentials the agent acquired after the site accepts them
|
|
84
|
+
- The credential gateway automatically injects secrets into API requests via `getRawSecret()`
|
|
85
|
+
- Use browser-navigation skill form patterns for entering credentials during interactive sessions
|
|
86
|
+
|
|
87
|
+
**How credentials work:**
|
|
88
|
+
- Agent-owned credentials live in the agent's Bitwarden/Vaultwarden vault
|
|
89
|
+
- Travel credentials such as Duffel and Stripe are ordinary vault credential items
|
|
90
|
+
- The agent can sign up for services and store its own credentials
|
|
91
|
+
- Existing stored passwords are never returned to the model — only metadata (domain, username, notes)
|
|
92
|
+
|
|
93
|
+
### Post-Booking
|
|
94
|
+
- Save confirmation details (confirmation number, dates, hotel name, airline, booking reference)
|
|
95
|
+
- Save to diary/journal for future reference
|
|
96
|
+
- Set reminders for check-in windows
|
|
97
|
+
- Note cancellation deadlines
|
|
98
|
+
|
|
99
|
+
## Preference Management
|
|
100
|
+
|
|
101
|
+
### Storing Preferences
|
|
102
|
+
Track and reference these travel preferences:
|
|
103
|
+
- Preferred airlines and alliance status
|
|
104
|
+
- Preferred hotel chains and loyalty numbers
|
|
105
|
+
- Seat preferences (window/aisle, extra legroom)
|
|
106
|
+
- Dietary needs for in-flight meals
|
|
107
|
+
- Budget ranges (per night for hotels, per flight)
|
|
108
|
+
- Must-have amenities (WiFi, gym, pool)
|
|
109
|
+
|
|
110
|
+
### Using Preferences
|
|
111
|
+
- Reference stored preferences when searching
|
|
112
|
+
- Apply airline preferences to flight comparisons
|
|
113
|
+
- Apply hotel brand preferences to accommodation searches
|
|
114
|
+
- Adjust budget ranges based on destination
|
|
115
|
+
|
|
116
|
+
## Tool Reference
|
|
117
|
+
|
|
118
|
+
### Native Tools (always available)
|
|
119
|
+
- `weather_lookup` - Current weather and daily forecast by city or coordinates (Open-Meteo, zero config)
|
|
120
|
+
- `travel_advisory` - US State Dept advisory by country code
|
|
121
|
+
- `geocode_search` - Location/POI search with coordinates
|
|
122
|
+
- `credential_get` - Check credential metadata for a domain (never returns passwords)
|
|
123
|
+
- `credential_generate_password` - Generate a strong password for a new sign-up (family trust)
|
|
124
|
+
- `credential_store` - Store credentials the agent acquired (family trust)
|
|
125
|
+
- `credential_list` - List stored credential domains
|
|
126
|
+
- `credential_delete` - Delete stored credentials (family trust)
|
|
127
|
+
|
|
128
|
+
### MCP Tools (when configured)
|
|
129
|
+
- Browser tools via `@playwright/mcp` - see `browser-navigation` skill
|
|
130
|
+
- Duffel flight search (when MCP server available)
|
|
131
|
+
- Expedia hotel search (when MCP server available)
|
|
132
|
+
|
|
133
|
+
### Human Confirmation Required For
|
|
134
|
+
- Any booking or payment
|
|
135
|
+
- Entering personal information
|
|
136
|
+
- Agreeing to terms of service
|
|
137
|
+
- Creating financial obligations
|
|
138
|
+
- Sharing credentials with third parties
|
|
@@ -1,178 +0,0 @@
|
|
|
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.installOuroCommand = installOuroCommand;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const os = __importStar(require("os"));
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const runtime_1 = require("../../nerves/runtime");
|
|
41
|
-
const CLI_PACKAGE_SPECIFIER = "@ouro.bot/cli@alpha";
|
|
42
|
-
const WRAPPER_SCRIPT = `#!/bin/sh
|
|
43
|
-
exec npx --yes ${CLI_PACKAGE_SPECIFIER} "$@"
|
|
44
|
-
`;
|
|
45
|
-
function detectShellProfile(homeDir, shell) {
|
|
46
|
-
if (!shell)
|
|
47
|
-
return null;
|
|
48
|
-
const base = path.basename(shell);
|
|
49
|
-
if (base === "zsh")
|
|
50
|
-
return path.join(homeDir, ".zshrc");
|
|
51
|
-
if (base === "bash") {
|
|
52
|
-
// macOS uses .bash_profile, Linux uses .bashrc
|
|
53
|
-
const profilePath = path.join(homeDir, ".bash_profile");
|
|
54
|
-
return profilePath;
|
|
55
|
-
}
|
|
56
|
-
if (base === "fish")
|
|
57
|
-
return path.join(homeDir, ".config", "fish", "config.fish");
|
|
58
|
-
return null;
|
|
59
|
-
}
|
|
60
|
-
function isBinDirInPath(binDir, envPath) {
|
|
61
|
-
return envPath.split(path.delimiter).some((p) => p === binDir);
|
|
62
|
-
}
|
|
63
|
-
function buildPathExportLine(binDir, shell) {
|
|
64
|
-
const base = shell ? path.basename(shell) : /* v8 ignore next -- unreachable: only called when detectShellProfile returns non-null, which requires shell @preserve */ "";
|
|
65
|
-
if (base === "fish") {
|
|
66
|
-
return `\n# Added by ouro\nset -gx PATH ${binDir} $PATH\n`;
|
|
67
|
-
}
|
|
68
|
-
return `\n# Added by ouro\nexport PATH="${binDir}:$PATH"\n`;
|
|
69
|
-
}
|
|
70
|
-
function installOuroCommand(deps = {}) {
|
|
71
|
-
/* v8 ignore start -- dep defaults: only used in real runtime, tests always inject @preserve */
|
|
72
|
-
const platform = deps.platform ?? process.platform;
|
|
73
|
-
const homeDir = deps.homeDir ?? os.homedir();
|
|
74
|
-
const existsSync = deps.existsSync ?? fs.existsSync;
|
|
75
|
-
const mkdirSync = deps.mkdirSync ?? fs.mkdirSync;
|
|
76
|
-
const writeFileSync = deps.writeFileSync ?? fs.writeFileSync;
|
|
77
|
-
const readFileSync = deps.readFileSync ?? ((p, enc) => fs.readFileSync(p, enc));
|
|
78
|
-
const appendFileSync = deps.appendFileSync ?? fs.appendFileSync;
|
|
79
|
-
const chmodSync = deps.chmodSync ?? fs.chmodSync;
|
|
80
|
-
const envPath = deps.envPath ?? process.env.PATH ?? "";
|
|
81
|
-
const shell = deps.shell ?? process.env.SHELL;
|
|
82
|
-
/* v8 ignore stop */
|
|
83
|
-
if (platform === "win32") {
|
|
84
|
-
(0, runtime_1.emitNervesEvent)({
|
|
85
|
-
component: "daemon",
|
|
86
|
-
event: "daemon.ouro_path_install_skip",
|
|
87
|
-
message: "skipped ouro PATH install on Windows",
|
|
88
|
-
meta: { platform },
|
|
89
|
-
});
|
|
90
|
-
return { installed: false, scriptPath: null, pathReady: false, shellProfileUpdated: null, skippedReason: "windows" };
|
|
91
|
-
}
|
|
92
|
-
const binDir = path.join(homeDir, ".local", "bin");
|
|
93
|
-
const scriptPath = path.join(binDir, "ouro");
|
|
94
|
-
(0, runtime_1.emitNervesEvent)({
|
|
95
|
-
component: "daemon",
|
|
96
|
-
event: "daemon.ouro_path_install_start",
|
|
97
|
-
message: "installing ouro command to PATH",
|
|
98
|
-
meta: { scriptPath, binDir },
|
|
99
|
-
});
|
|
100
|
-
// If ouro already exists, check content and repair if stale
|
|
101
|
-
if (existsSync(scriptPath)) {
|
|
102
|
-
let existingContent = "";
|
|
103
|
-
try {
|
|
104
|
-
existingContent = readFileSync(scriptPath, "utf-8");
|
|
105
|
-
}
|
|
106
|
-
catch {
|
|
107
|
-
// Can't read — treat as stale, will overwrite below
|
|
108
|
-
}
|
|
109
|
-
if (existingContent === WRAPPER_SCRIPT) {
|
|
110
|
-
(0, runtime_1.emitNervesEvent)({
|
|
111
|
-
component: "daemon",
|
|
112
|
-
event: "daemon.ouro_path_install_skip",
|
|
113
|
-
message: "ouro command already installed",
|
|
114
|
-
meta: { scriptPath },
|
|
115
|
-
});
|
|
116
|
-
return { installed: false, scriptPath, pathReady: isBinDirInPath(binDir, envPath), shellProfileUpdated: null, skippedReason: "already-installed" };
|
|
117
|
-
}
|
|
118
|
-
// Content is stale — repair by overwriting
|
|
119
|
-
(0, runtime_1.emitNervesEvent)({
|
|
120
|
-
component: "daemon",
|
|
121
|
-
event: "daemon.ouro_path_install_repair",
|
|
122
|
-
message: "repairing stale ouro wrapper script",
|
|
123
|
-
meta: { scriptPath },
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
try {
|
|
127
|
-
mkdirSync(binDir, { recursive: true });
|
|
128
|
-
writeFileSync(scriptPath, WRAPPER_SCRIPT, { mode: 0o755 });
|
|
129
|
-
chmodSync(scriptPath, 0o755);
|
|
130
|
-
}
|
|
131
|
-
catch (error) {
|
|
132
|
-
(0, runtime_1.emitNervesEvent)({
|
|
133
|
-
level: "warn",
|
|
134
|
-
component: "daemon",
|
|
135
|
-
event: "daemon.ouro_path_install_error",
|
|
136
|
-
message: "failed to install ouro command",
|
|
137
|
-
meta: { error: error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error) },
|
|
138
|
-
});
|
|
139
|
-
return { installed: false, scriptPath: null, pathReady: false, shellProfileUpdated: null, skippedReason: error instanceof Error ? error.message : /* v8 ignore next -- defensive @preserve */ String(error) };
|
|
140
|
-
}
|
|
141
|
-
// Check if ~/.local/bin is already in PATH
|
|
142
|
-
let shellProfileUpdated = null;
|
|
143
|
-
const pathReady = isBinDirInPath(binDir, envPath);
|
|
144
|
-
if (!pathReady) {
|
|
145
|
-
const profilePath = detectShellProfile(homeDir, shell);
|
|
146
|
-
if (profilePath) {
|
|
147
|
-
try {
|
|
148
|
-
let existing = "";
|
|
149
|
-
try {
|
|
150
|
-
existing = readFileSync(profilePath, "utf-8");
|
|
151
|
-
}
|
|
152
|
-
catch {
|
|
153
|
-
// Profile doesn't exist yet — that's fine, we'll create it
|
|
154
|
-
}
|
|
155
|
-
if (!existing.includes(binDir)) {
|
|
156
|
-
appendFileSync(profilePath, buildPathExportLine(binDir, shell));
|
|
157
|
-
shellProfileUpdated = profilePath;
|
|
158
|
-
}
|
|
159
|
-
}
|
|
160
|
-
catch (error) {
|
|
161
|
-
(0, runtime_1.emitNervesEvent)({
|
|
162
|
-
level: "warn",
|
|
163
|
-
component: "daemon",
|
|
164
|
-
event: "daemon.ouro_path_profile_error",
|
|
165
|
-
message: "failed to update shell profile for PATH",
|
|
166
|
-
meta: { profilePath, error: error instanceof Error ? error.message : /* v8 ignore next -- defensive: non-Error catch branch @preserve */ String(error) },
|
|
167
|
-
});
|
|
168
|
-
}
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
(0, runtime_1.emitNervesEvent)({
|
|
172
|
-
component: "daemon",
|
|
173
|
-
event: "daemon.ouro_path_install_end",
|
|
174
|
-
message: "ouro command installed",
|
|
175
|
-
meta: { scriptPath, pathReady, shellProfileUpdated },
|
|
176
|
-
});
|
|
177
|
-
return { installed: true, scriptPath, pathReady, shellProfileUpdated };
|
|
178
|
-
}
|
|
@@ -1,166 +0,0 @@
|
|
|
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.installSubagentsForAvailableCli = installSubagentsForAvailableCli;
|
|
37
|
-
const fs = __importStar(require("fs"));
|
|
38
|
-
const os = __importStar(require("os"));
|
|
39
|
-
const path = __importStar(require("path"));
|
|
40
|
-
const child_process_1 = require("child_process");
|
|
41
|
-
const runtime_1 = require("../../nerves/runtime");
|
|
42
|
-
function detectCliBinary(binary) {
|
|
43
|
-
const result = (0, child_process_1.spawnSync)("which", [binary], { encoding: "utf-8" });
|
|
44
|
-
if (result.status !== 0)
|
|
45
|
-
return null;
|
|
46
|
-
const resolved = result.stdout.trim();
|
|
47
|
-
return resolved.length > 0 ? resolved : null;
|
|
48
|
-
}
|
|
49
|
-
function listSubagentSources(subagentsDir) {
|
|
50
|
-
if (!fs.existsSync(subagentsDir))
|
|
51
|
-
return [];
|
|
52
|
-
return fs.readdirSync(subagentsDir)
|
|
53
|
-
.filter((name) => name.endsWith(".md"))
|
|
54
|
-
.filter((name) => name !== "README.md")
|
|
55
|
-
.map((name) => path.join(subagentsDir, name))
|
|
56
|
-
.sort((a, b) => a.localeCompare(b));
|
|
57
|
-
}
|
|
58
|
-
function pathExists(target) {
|
|
59
|
-
try {
|
|
60
|
-
fs.lstatSync(target);
|
|
61
|
-
return true;
|
|
62
|
-
}
|
|
63
|
-
catch {
|
|
64
|
-
return false;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
function isSameFile(source, target) {
|
|
68
|
-
try {
|
|
69
|
-
const sourceStats = fs.statSync(source);
|
|
70
|
-
const targetStats = fs.statSync(target);
|
|
71
|
-
return sourceStats.dev === targetStats.dev && sourceStats.ino === targetStats.ino;
|
|
72
|
-
}
|
|
73
|
-
catch {
|
|
74
|
-
return false;
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
function ensureSymlink(source, target) {
|
|
78
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
79
|
-
if (pathExists(target)) {
|
|
80
|
-
const stats = fs.lstatSync(target);
|
|
81
|
-
if (stats.isSymbolicLink()) {
|
|
82
|
-
const linkedPath = fs.readlinkSync(target);
|
|
83
|
-
if (linkedPath === source)
|
|
84
|
-
return false;
|
|
85
|
-
}
|
|
86
|
-
fs.unlinkSync(target);
|
|
87
|
-
}
|
|
88
|
-
fs.symlinkSync(source, target);
|
|
89
|
-
return true;
|
|
90
|
-
}
|
|
91
|
-
function ensureHardLink(source, target) {
|
|
92
|
-
fs.mkdirSync(path.dirname(target), { recursive: true });
|
|
93
|
-
if (pathExists(target)) {
|
|
94
|
-
const stats = fs.lstatSync(target);
|
|
95
|
-
if (!stats.isSymbolicLink() && isSameFile(source, target)) {
|
|
96
|
-
return false;
|
|
97
|
-
}
|
|
98
|
-
fs.unlinkSync(target);
|
|
99
|
-
}
|
|
100
|
-
fs.linkSync(source, target);
|
|
101
|
-
return true;
|
|
102
|
-
}
|
|
103
|
-
function hasOpenAiSkillHome(homeDir) {
|
|
104
|
-
return pathExists(path.join(homeDir, ".codex")) || pathExists(path.join(homeDir, ".agents"));
|
|
105
|
-
}
|
|
106
|
-
function openAiSkillTargets(homeDir, source) {
|
|
107
|
-
const skillName = path.basename(source, ".md");
|
|
108
|
-
return [path.join(homeDir, ".agents", "skills", skillName, "SKILL.md")];
|
|
109
|
-
}
|
|
110
|
-
async function installSubagentsForAvailableCli(options = {}) {
|
|
111
|
-
const repoRoot = options.repoRoot ?? path.resolve(__dirname, "..", "..", "..");
|
|
112
|
-
const homeDir = options.homeDir ?? os.homedir();
|
|
113
|
-
const which = options.which ?? detectCliBinary;
|
|
114
|
-
const subagentsDir = path.join(repoRoot, "subagents");
|
|
115
|
-
const sources = listSubagentSources(subagentsDir);
|
|
116
|
-
const notes = [];
|
|
117
|
-
(0, runtime_1.emitNervesEvent)({
|
|
118
|
-
component: "daemon",
|
|
119
|
-
event: "daemon.subagent_install_start",
|
|
120
|
-
message: "starting subagent auto-install",
|
|
121
|
-
meta: { sources: sources.length },
|
|
122
|
-
});
|
|
123
|
-
if (sources.length === 0) {
|
|
124
|
-
notes.push(`no subagent files found at ${subagentsDir}`);
|
|
125
|
-
return { claudeInstalled: 0, codexInstalled: 0, notes };
|
|
126
|
-
}
|
|
127
|
-
let claudeInstalled = 0;
|
|
128
|
-
let codexInstalled = 0;
|
|
129
|
-
const claudePath = which("claude");
|
|
130
|
-
if (!claudePath) {
|
|
131
|
-
notes.push("claude CLI not found; skipping subagent install");
|
|
132
|
-
}
|
|
133
|
-
else {
|
|
134
|
-
const claudeAgentsDir = path.join(homeDir, ".claude", "agents");
|
|
135
|
-
for (const source of sources) {
|
|
136
|
-
const target = path.join(claudeAgentsDir, path.basename(source));
|
|
137
|
-
if (ensureSymlink(source, target)) {
|
|
138
|
-
claudeInstalled += 1;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
const codexPath = which("codex");
|
|
143
|
-
if (!codexPath && !hasOpenAiSkillHome(homeDir)) {
|
|
144
|
-
notes.push("codex CLI/config not found; skipping subagent install");
|
|
145
|
-
}
|
|
146
|
-
else {
|
|
147
|
-
for (const source of sources) {
|
|
148
|
-
let installedForSkill = false;
|
|
149
|
-
for (const target of openAiSkillTargets(homeDir, source)) {
|
|
150
|
-
if (ensureHardLink(source, target)) {
|
|
151
|
-
installedForSkill = true;
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
if (installedForSkill) {
|
|
155
|
-
codexInstalled += 1;
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
}
|
|
159
|
-
(0, runtime_1.emitNervesEvent)({
|
|
160
|
-
component: "daemon",
|
|
161
|
-
event: "daemon.subagent_install_end",
|
|
162
|
-
message: "completed subagent auto-install",
|
|
163
|
-
meta: { claudeInstalled, codexInstalled, notes: notes.length },
|
|
164
|
-
});
|
|
165
|
-
return { claudeInstalled, codexInstalled, notes };
|
|
166
|
-
}
|
|
@@ -1,209 +0,0 @@
|
|
|
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.cosineSimilarity = cosineSimilarity;
|
|
37
|
-
exports.recallFactsForQuery = recallFactsForQuery;
|
|
38
|
-
exports.injectAssociativeRecall = injectAssociativeRecall;
|
|
39
|
-
const fs = __importStar(require("fs"));
|
|
40
|
-
const path = __importStar(require("path"));
|
|
41
|
-
const config_1 = require("../heart/config");
|
|
42
|
-
const identity_1 = require("../heart/identity");
|
|
43
|
-
const runtime_1 = require("../nerves/runtime");
|
|
44
|
-
const DEFAULT_EMBEDDING_MODEL = "text-embedding-3-small";
|
|
45
|
-
const DEFAULT_MIN_SCORE = 0.5;
|
|
46
|
-
const DEFAULT_TOP_K = 3;
|
|
47
|
-
class OpenAIEmbeddingProvider {
|
|
48
|
-
apiKey;
|
|
49
|
-
model;
|
|
50
|
-
constructor(apiKey, model = DEFAULT_EMBEDDING_MODEL) {
|
|
51
|
-
this.apiKey = apiKey;
|
|
52
|
-
this.model = model;
|
|
53
|
-
}
|
|
54
|
-
async embed(texts) {
|
|
55
|
-
const response = await fetch("https://api.openai.com/v1/embeddings", {
|
|
56
|
-
method: "POST",
|
|
57
|
-
headers: {
|
|
58
|
-
Authorization: `Bearer ${this.apiKey}`,
|
|
59
|
-
"Content-Type": "application/json",
|
|
60
|
-
},
|
|
61
|
-
body: JSON.stringify({
|
|
62
|
-
model: this.model,
|
|
63
|
-
input: texts,
|
|
64
|
-
}),
|
|
65
|
-
});
|
|
66
|
-
if (!response.ok) {
|
|
67
|
-
throw new Error(`embedding request failed: ${response.status} ${response.statusText}`);
|
|
68
|
-
}
|
|
69
|
-
const payload = (await response.json());
|
|
70
|
-
if (!payload.data || payload.data.length !== texts.length) {
|
|
71
|
-
throw new Error("embedding response missing expected vectors");
|
|
72
|
-
}
|
|
73
|
-
return payload.data.map((entry) => entry.embedding);
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
function createDefaultProvider() {
|
|
77
|
-
const apiKey = (0, config_1.getOpenAIEmbeddingsApiKey)();
|
|
78
|
-
if (!apiKey) {
|
|
79
|
-
throw new Error("openaiEmbeddingsApiKey not configured");
|
|
80
|
-
}
|
|
81
|
-
return new OpenAIEmbeddingProvider(apiKey);
|
|
82
|
-
}
|
|
83
|
-
function readFacts(memoryRoot) {
|
|
84
|
-
const factsPath = path.join(memoryRoot, "facts.jsonl");
|
|
85
|
-
if (!fs.existsSync(factsPath))
|
|
86
|
-
return [];
|
|
87
|
-
const raw = fs.readFileSync(factsPath, "utf8").trim();
|
|
88
|
-
if (!raw)
|
|
89
|
-
return [];
|
|
90
|
-
const facts = [];
|
|
91
|
-
for (const line of raw.split("\n")) {
|
|
92
|
-
const trimmed = line.trim();
|
|
93
|
-
if (!trimmed)
|
|
94
|
-
continue;
|
|
95
|
-
try {
|
|
96
|
-
facts.push(JSON.parse(trimmed));
|
|
97
|
-
}
|
|
98
|
-
catch {
|
|
99
|
-
// Skip corrupt lines (e.g. partial write from a crash).
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
return facts;
|
|
103
|
-
}
|
|
104
|
-
function getLatestUserText(messages) {
|
|
105
|
-
for (let i = messages.length - 1; i >= 0; i--) {
|
|
106
|
-
const message = messages[i];
|
|
107
|
-
if (message.role !== "user")
|
|
108
|
-
continue;
|
|
109
|
-
if (typeof message.content !== "string")
|
|
110
|
-
continue;
|
|
111
|
-
const text = message.content.trim();
|
|
112
|
-
if (text.length > 0)
|
|
113
|
-
return text;
|
|
114
|
-
}
|
|
115
|
-
return "";
|
|
116
|
-
}
|
|
117
|
-
function cosineSimilarity(left, right) {
|
|
118
|
-
if (left.length === 0 || right.length === 0 || left.length !== right.length)
|
|
119
|
-
return 0;
|
|
120
|
-
let dot = 0;
|
|
121
|
-
let leftNorm = 0;
|
|
122
|
-
let rightNorm = 0;
|
|
123
|
-
for (let i = 0; i < left.length; i++) {
|
|
124
|
-
dot += left[i] * right[i];
|
|
125
|
-
leftNorm += left[i] * left[i];
|
|
126
|
-
rightNorm += right[i] * right[i];
|
|
127
|
-
}
|
|
128
|
-
if (leftNorm === 0 || rightNorm === 0)
|
|
129
|
-
return 0;
|
|
130
|
-
return dot / (Math.sqrt(leftNorm) * Math.sqrt(rightNorm));
|
|
131
|
-
}
|
|
132
|
-
async function recallFactsForQuery(query, facts, provider, options) {
|
|
133
|
-
const trimmed = query.trim();
|
|
134
|
-
if (!trimmed)
|
|
135
|
-
return [];
|
|
136
|
-
const minScore = options?.minScore ?? DEFAULT_MIN_SCORE;
|
|
137
|
-
const topK = options?.topK ?? DEFAULT_TOP_K;
|
|
138
|
-
const [queryEmbedding] = await provider.embed([trimmed]);
|
|
139
|
-
return facts
|
|
140
|
-
.map((fact) => ({
|
|
141
|
-
...fact,
|
|
142
|
-
score: cosineSimilarity(queryEmbedding, fact.embedding),
|
|
143
|
-
}))
|
|
144
|
-
.filter((fact) => fact.score >= minScore)
|
|
145
|
-
.sort((left, right) => right.score - left.score)
|
|
146
|
-
.slice(0, topK);
|
|
147
|
-
}
|
|
148
|
-
async function injectAssociativeRecall(messages, options) {
|
|
149
|
-
try {
|
|
150
|
-
if (messages[0]?.role !== "system" || typeof messages[0].content !== "string")
|
|
151
|
-
return;
|
|
152
|
-
const query = getLatestUserText(messages);
|
|
153
|
-
if (!query)
|
|
154
|
-
return;
|
|
155
|
-
const memoryRoot = options?.memoryRoot ?? path.join((0, identity_1.getAgentRoot)(), "psyche", "memory");
|
|
156
|
-
const facts = readFacts(memoryRoot);
|
|
157
|
-
if (facts.length === 0)
|
|
158
|
-
return;
|
|
159
|
-
let recalled;
|
|
160
|
-
try {
|
|
161
|
-
const provider = options?.provider ?? createDefaultProvider();
|
|
162
|
-
recalled = await recallFactsForQuery(query, facts, provider, options);
|
|
163
|
-
}
|
|
164
|
-
catch {
|
|
165
|
-
// Embeddings unavailable — fall back to substring matching
|
|
166
|
-
const lowerQuery = query.toLowerCase();
|
|
167
|
-
const topK = options?.topK ?? DEFAULT_TOP_K;
|
|
168
|
-
recalled = facts
|
|
169
|
-
.filter((fact) => fact.text.toLowerCase().includes(lowerQuery))
|
|
170
|
-
.slice(0, topK)
|
|
171
|
-
.map((fact) => ({ ...fact, score: 1 }));
|
|
172
|
-
if (recalled.length > 0) {
|
|
173
|
-
(0, runtime_1.emitNervesEvent)({
|
|
174
|
-
level: "warn",
|
|
175
|
-
component: "mind",
|
|
176
|
-
event: "mind.associative_recall_fallback",
|
|
177
|
-
message: "embeddings unavailable, used substring fallback",
|
|
178
|
-
meta: { matchCount: recalled.length },
|
|
179
|
-
});
|
|
180
|
-
}
|
|
181
|
-
}
|
|
182
|
-
if (recalled.length === 0)
|
|
183
|
-
return;
|
|
184
|
-
const recallSection = recalled
|
|
185
|
-
.map((fact, index) => `${index + 1}. ${fact.text} [score=${fact.score.toFixed(3)} source=${fact.source}]`)
|
|
186
|
-
.join("\n");
|
|
187
|
-
messages[0] = {
|
|
188
|
-
role: "system",
|
|
189
|
-
content: `${messages[0].content}\n\n## recalled context\n${recallSection}`,
|
|
190
|
-
};
|
|
191
|
-
(0, runtime_1.emitNervesEvent)({
|
|
192
|
-
component: "mind",
|
|
193
|
-
event: "mind.associative_recall",
|
|
194
|
-
message: "associative recall injected",
|
|
195
|
-
meta: { count: recalled.length },
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
catch (error) {
|
|
199
|
-
(0, runtime_1.emitNervesEvent)({
|
|
200
|
-
level: "warn",
|
|
201
|
-
component: "mind",
|
|
202
|
-
event: "mind.associative_recall_error",
|
|
203
|
-
message: "associative recall failed",
|
|
204
|
-
meta: {
|
|
205
|
-
reason: error instanceof Error ? error.message : /* v8 ignore start -- defensive: non-Error catch branch @preserve */ String(error) /* v8 ignore stop */,
|
|
206
|
-
},
|
|
207
|
-
});
|
|
208
|
-
}
|
|
209
|
-
}
|