@ouro.bot/cli 0.1.0-alpha.6 → 0.1.0-alpha.600
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 +229 -183
- package/RepairGuide.ouro/agent.json +5 -0
- package/RepairGuide.ouro/psyche/IDENTITY.md +19 -0
- package/RepairGuide.ouro/psyche/SOUL.md +55 -0
- package/RepairGuide.ouro/skills/diagnose-broken-remote.md +63 -0
- package/RepairGuide.ouro/skills/diagnose-stacked-typed-issues.md +35 -0
- package/RepairGuide.ouro/skills/diagnose-sync-blocked.md +54 -0
- package/RepairGuide.ouro/skills/diagnose-vault-expired.md +60 -0
- package/SerpentGuide.ouro/agent.json +83 -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 +4182 -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 +254 -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 +69 -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 +479 -0
- package/dist/heart/awaiting/await-alert.js +146 -0
- package/dist/heart/awaiting/await-expiry.js +108 -0
- package/dist/heart/awaiting/await-loader.js +91 -0
- package/dist/heart/awaiting/await-parser.js +141 -0
- package/dist/heart/awaiting/await-runtime-state.js +97 -0
- package/dist/heart/awaiting/await-scheduler.js +377 -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 +142 -0
- package/dist/heart/config-registry.js +322 -0
- package/dist/heart/config.js +164 -135
- package/dist/heart/core.js +1069 -260
- package/dist/heart/cross-chat-delivery.js +131 -0
- package/dist/heart/daemon/agent-config-check.js +419 -0
- package/dist/heart/daemon/agent-discovery.js +180 -0
- package/dist/heart/daemon/agent-service.js +522 -0
- package/dist/heart/daemon/agentic-repair.js +547 -0
- package/dist/heart/daemon/bluebubbles-health-diagnostics.js +122 -0
- package/dist/heart/daemon/boot-sync-probe.js +197 -0
- package/dist/heart/daemon/cadence.js +70 -0
- package/dist/heart/daemon/cli-defaults.js +776 -0
- package/dist/heart/daemon/cli-exec.js +7571 -0
- package/dist/heart/daemon/cli-help.js +498 -0
- package/dist/heart/daemon/cli-parse.js +1599 -0
- package/dist/heart/daemon/cli-render-doctor.js +57 -0
- package/dist/heart/daemon/cli-render.js +763 -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 -758
- package/dist/heart/daemon/daemon-entry.js +540 -8
- package/dist/heart/daemon/daemon-health.js +176 -0
- package/dist/heart/daemon/daemon-rollup.js +57 -0
- package/dist/heart/daemon/daemon-runtime-sync.js +287 -0
- package/dist/heart/daemon/daemon-tombstone.js +236 -0
- package/dist/heart/daemon/daemon.js +972 -20
- package/dist/heart/daemon/dns-workflow.js +394 -0
- package/dist/heart/daemon/doctor-types.js +8 -0
- package/dist/heart/daemon/doctor.js +873 -0
- package/dist/heart/daemon/health-monitor.js +122 -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 +188 -0
- package/dist/heart/daemon/log-tailer.js +82 -12
- package/dist/heart/daemon/logs-prune.js +110 -0
- package/dist/heart/daemon/mcp-canary.js +297 -0
- package/dist/heart/daemon/message-router.js +17 -8
- package/dist/heart/daemon/os-cron-deps.js +135 -0
- package/dist/heart/daemon/os-cron.js +14 -12
- 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 +381 -26
- 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 +731 -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 +349 -0
- package/dist/heart/daemon/stale-bundle-prune.js +96 -0
- package/dist/heart/daemon/startup-tui.js +330 -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 +34 -136
- package/dist/heart/{daemon → hatch}/hatch-specialist.js +6 -8
- 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 +281 -67
- 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/mailbox/mailbox-http-hooks.js +66 -0
- package/dist/heart/mailbox/mailbox-http-response.js +7 -0
- package/dist/heart/mailbox/mailbox-http-routes.js +246 -0
- package/dist/heart/mailbox/mailbox-http-static.js +103 -0
- package/dist/heart/mailbox/mailbox-http-transport.js +116 -0
- package/dist/heart/mailbox/mailbox-http.js +99 -0
- package/dist/heart/mailbox/mailbox-read.js +31 -0
- package/dist/heart/mailbox/mailbox-types.js +27 -0
- package/dist/heart/mailbox/mailbox-view.js +195 -0
- package/dist/heart/mailbox/readers/agent-machine.js +382 -0
- package/dist/heart/mailbox/readers/continuity-readers.js +338 -0
- package/dist/heart/mailbox/readers/mail.js +367 -0
- package/dist/heart/mailbox/readers/runtime-readers.js +651 -0
- package/dist/heart/mailbox/readers/sessions.js +232 -0
- package/dist/heart/mailbox/readers/shared.js +111 -0
- package/dist/heart/mcp/mcp-server.js +656 -0
- package/dist/heart/migrate-config.js +100 -0
- package/dist/heart/model-capabilities.js +59 -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 +267 -0
- package/dist/heart/provider-credentials.js +425 -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-readiness-cache.js +40 -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 +127 -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 +367 -0
- package/dist/heart/runtime-cwd.js +87 -0
- package/dist/heart/sense-truth.js +70 -0
- package/dist/heart/session-activity.js +190 -0
- package/dist/heart/session-events.js +1149 -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-stats-cli-main.js +5 -0
- package/dist/heart/session-stats.js +182 -0
- package/dist/heart/session-transcript.js +243 -0
- package/dist/heart/start-of-turn-packet.js +345 -0
- package/dist/heart/streaming.js +129 -34
- package/dist/heart/sync-classification.js +176 -0
- package/dist/heart/sync.js +449 -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/timeouts.js +101 -0
- package/dist/heart/tool-activity-callbacks.js +59 -0
- package/dist/heart/tool-description.js +143 -0
- package/dist/heart/tool-friction.js +55 -0
- package/dist/heart/tool-loop.js +200 -0
- package/dist/heart/turn-context.js +421 -0
- package/dist/heart/turn-coordinator.js +28 -0
- package/dist/heart/versioning/ouro-bot-global-installer.js +129 -0
- package/dist/heart/{daemon → versioning}/ouro-bot-wrapper.js +1 -1
- package/dist/heart/versioning/ouro-path-installer.js +426 -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 +116 -0
- package/dist/heart/versioning/update-hooks.js +142 -0
- package/dist/heart/versioning/wrapper-publish-guard.js +86 -0
- package/dist/mailbox-ui/assets/index-B-461hes.js +61 -0
- package/dist/mailbox-ui/assets/index-BPr5vNuM.css +1 -0
- package/dist/mailbox-ui/index.html +15 -0
- package/dist/mailroom/attention.js +167 -0
- package/dist/mailroom/autonomy.js +209 -0
- package/dist/mailroom/blob-store.js +700 -0
- package/dist/mailroom/body-cache.js +61 -0
- package/dist/mailroom/core.js +788 -0
- package/dist/mailroom/entry.js +160 -0
- package/dist/mailroom/file-store.js +457 -0
- package/dist/mailroom/mbox-import.js +393 -0
- package/dist/mailroom/migration.js +164 -0
- package/dist/mailroom/outbound.js +380 -0
- package/dist/mailroom/policy.js +263 -0
- package/dist/mailroom/reader.js +233 -0
- package/dist/mailroom/search-cache.js +268 -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 +174 -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 +74 -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 +1267 -130
- 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 +129 -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/review/cli-main.js +5 -0
- package/dist/nerves/review/cli.js +156 -0
- package/dist/nerves/review/core.js +152 -0
- package/dist/nerves/runtime.js +5 -1
- 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 +997 -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 +178 -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 +295 -0
- package/dist/repertoire/mcp-manager.js +362 -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-awaiting.js +360 -0
- package/dist/repertoire/tools-base.js +56 -707
- package/dist/repertoire/tools-bluebubbles.js +94 -0
- package/dist/repertoire/tools-bridge.js +142 -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 +119 -0
- package/dist/repertoire/tools-github.js +1 -7
- package/dist/repertoire/tools-mail.js +1916 -0
- package/dist/repertoire/tools-notes.js +421 -0
- package/dist/repertoire/tools-obligations.js +142 -0
- package/dist/repertoire/tools-runtime.js +61 -0
- package/dist/repertoire/tools-session.js +809 -0
- package/dist/repertoire/tools-shell.js +120 -0
- package/dist/repertoire/tools-stripe.js +180 -0
- package/dist/repertoire/tools-surface.js +345 -0
- package/dist/repertoire/tools-teams.js +64 -61
- package/dist/repertoire/tools-travel.js +125 -0
- package/dist/repertoire/tools-trip.js +604 -0
- package/dist/repertoire/tools-user-profile.js +144 -0
- package/dist/repertoire/tools-vault.js +40 -0
- package/dist/repertoire/tools-voice.js +144 -0
- package/dist/repertoire/tools.js +154 -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 +594 -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/await-turn-message.js +58 -0
- package/dist/senses/bluebubbles/active-turns.js +216 -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 +77 -0
- package/dist/senses/bluebubbles/inbound-log.js +126 -0
- package/dist/senses/bluebubbles/index.js +2548 -0
- package/dist/senses/bluebubbles/media.js +389 -0
- package/dist/senses/{bluebubbles-model.js → bluebubbles/model.js} +45 -16
- package/dist/senses/{bluebubbles-mutation-log.js → bluebubbles/mutation-log.js} +46 -6
- package/dist/senses/bluebubbles/processed-log.js +133 -0
- package/dist/senses/bluebubbles/replay.js +137 -0
- package/dist/senses/bluebubbles/runtime-state.js +137 -0
- package/dist/senses/bluebubbles/session-cleanup.js +72 -0
- package/dist/senses/bluebubbles-meta-guard.js +40 -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 +607 -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 +85 -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 +777 -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 +209 -16
- package/dist/senses/inner-dialog.js +682 -91
- package/dist/senses/mail-entry.js +66 -0
- package/dist/senses/mail.js +379 -0
- package/dist/senses/pipeline.js +751 -0
- package/dist/senses/proactive-content-guard.js +51 -0
- package/dist/senses/shared-turn.js +392 -0
- package/dist/senses/surface-tool.js +70 -0
- package/dist/senses/teams-entry.js +60 -8
- package/dist/senses/teams.js +925 -195
- package/dist/senses/trust-gate.js +207 -2
- package/dist/senses/voice/audio-playback.js +237 -0
- package/dist/senses/voice/audio-routing.js +119 -0
- package/dist/senses/voice/elevenlabs.js +202 -0
- package/dist/senses/voice/floor-control.js +431 -0
- package/dist/senses/voice/floor-controller.js +115 -0
- package/dist/senses/voice/golden-path.js +116 -0
- package/dist/senses/voice/index.js +29 -0
- package/dist/senses/voice/meeting.js +113 -0
- package/dist/senses/voice/outbound.js +190 -0
- package/dist/senses/voice/phone.js +33 -0
- package/dist/senses/voice/playback.js +139 -0
- package/dist/senses/voice/realtime-eval.js +496 -0
- package/dist/senses/voice/realtime-trace.js +531 -0
- package/dist/senses/voice/transcript.js +70 -0
- package/dist/senses/voice/turn.js +191 -0
- package/dist/senses/voice/twilio-phone-runtime.js +807 -0
- package/dist/senses/voice/twilio-phone.js +5077 -0
- package/dist/senses/voice/types.js +2 -0
- package/dist/senses/voice/whisper.js +161 -0
- package/dist/senses/voice-entry.js +81 -0
- package/dist/senses/voice-realtime-eval-command.js +99 -0
- package/dist/senses/voice-realtime-eval-entry.js +21 -0
- package/dist/senses/voice-twilio-entry.js +87 -0
- package/dist/trips/core.js +138 -0
- package/dist/trips/store.js +265 -0
- package/package.json +52 -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 +99 -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/dist/senses/bluebubbles-client.js +0 -279
- package/dist/senses/bluebubbles-entry.js +0 -11
- package/dist/senses/bluebubbles.js +0 -332
- 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,182 @@
|
|
|
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.addKindToLegacyCard = addKindToLegacyCard;
|
|
37
|
+
exports.applyFixes = applyFixes;
|
|
38
|
+
const fs = __importStar(require("fs"));
|
|
39
|
+
const path = __importStar(require("path"));
|
|
40
|
+
const runtime_1 = require("../../nerves/runtime");
|
|
41
|
+
const scanner_1 = require("./scanner");
|
|
42
|
+
const parser_1 = require("./parser");
|
|
43
|
+
function issueId(issue) {
|
|
44
|
+
return `${issue.code}:${issue.target}`;
|
|
45
|
+
}
|
|
46
|
+
function addKindToLegacyCard(root, issue) {
|
|
47
|
+
(0, runtime_1.emitNervesEvent)({
|
|
48
|
+
event: "repertoire.fix_apply_start",
|
|
49
|
+
component: "repertoire",
|
|
50
|
+
message: "adding kind: task to legacy card",
|
|
51
|
+
meta: { target: issue.target },
|
|
52
|
+
});
|
|
53
|
+
const filePath = path.join(root, issue.target);
|
|
54
|
+
if (!fs.existsSync(filePath))
|
|
55
|
+
return false;
|
|
56
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
57
|
+
const frontmatter = (0, scanner_1.tryExtractFrontmatter)(content);
|
|
58
|
+
if (!frontmatter)
|
|
59
|
+
return false;
|
|
60
|
+
// Add kind: task to frontmatter
|
|
61
|
+
frontmatter.kind = "task";
|
|
62
|
+
// Extract body (everything after the second ---)
|
|
63
|
+
const lines = content.split(/\r?\n/);
|
|
64
|
+
const firstDelim = lines.findIndex((line) => line.trim() === "---");
|
|
65
|
+
const secondDelim = lines.findIndex((line, idx) => idx > firstDelim && line.trim() === "---");
|
|
66
|
+
const body = lines.slice(secondDelim + 1).join("\n").replace(/^\n/, "");
|
|
67
|
+
const rendered = (0, parser_1.renderTaskFile)(frontmatter, body);
|
|
68
|
+
fs.writeFileSync(filePath, rendered, "utf-8");
|
|
69
|
+
return true;
|
|
70
|
+
}
|
|
71
|
+
function applySingleFix(root, issue) {
|
|
72
|
+
switch (issue.code) {
|
|
73
|
+
case "schema-missing-kind":
|
|
74
|
+
return addKindToLegacyCard(root, issue);
|
|
75
|
+
default:
|
|
76
|
+
return false;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
function applyFixes(options, root) {
|
|
80
|
+
(0, runtime_1.emitNervesEvent)({
|
|
81
|
+
event: "repertoire.fix_start",
|
|
82
|
+
component: "repertoire",
|
|
83
|
+
message: `applying fixes in ${options.mode} mode`,
|
|
84
|
+
meta: { mode: options.mode, root },
|
|
85
|
+
});
|
|
86
|
+
(0, scanner_1.clearTaskScanCache)();
|
|
87
|
+
const index = (0, scanner_1.scanTasks)(root);
|
|
88
|
+
const issues = index.issues;
|
|
89
|
+
if (options.mode === "dry-run") {
|
|
90
|
+
(0, runtime_1.emitNervesEvent)({
|
|
91
|
+
event: "repertoire.fix_complete",
|
|
92
|
+
component: "repertoire",
|
|
93
|
+
message: "dry-run complete, no changes made",
|
|
94
|
+
meta: { issueCount: issues.length },
|
|
95
|
+
});
|
|
96
|
+
const health = issues.length === 0 ? "clean" : buildHealthSummary(issues);
|
|
97
|
+
return {
|
|
98
|
+
applied: [],
|
|
99
|
+
remaining: issues,
|
|
100
|
+
skipped: [],
|
|
101
|
+
health,
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
if (options.mode === "single") {
|
|
105
|
+
const targetId = options.issueId ?? "";
|
|
106
|
+
const match = issues.find((i) => issueId(i) === targetId);
|
|
107
|
+
if (!match) {
|
|
108
|
+
(0, runtime_1.emitNervesEvent)({
|
|
109
|
+
event: "repertoire.fix_complete",
|
|
110
|
+
component: "repertoire",
|
|
111
|
+
message: "single fix: issue not found",
|
|
112
|
+
meta: { issueId: targetId },
|
|
113
|
+
});
|
|
114
|
+
const health = issues.length === 0 ? "clean" : buildHealthSummary(issues);
|
|
115
|
+
return {
|
|
116
|
+
applied: [],
|
|
117
|
+
remaining: issues,
|
|
118
|
+
skipped: [],
|
|
119
|
+
health,
|
|
120
|
+
};
|
|
121
|
+
}
|
|
122
|
+
const success = applySingleFix(root, match);
|
|
123
|
+
(0, scanner_1.clearTaskScanCache)();
|
|
124
|
+
const afterIndex = (0, scanner_1.scanTasks)(root);
|
|
125
|
+
const afterIssues = afterIndex.issues;
|
|
126
|
+
const health = afterIssues.length === 0 ? "clean" : buildHealthSummary(afterIssues);
|
|
127
|
+
(0, runtime_1.emitNervesEvent)({
|
|
128
|
+
event: "repertoire.fix_complete",
|
|
129
|
+
component: "repertoire",
|
|
130
|
+
message: `single fix ${success ? "applied" : "failed"}`,
|
|
131
|
+
meta: { issueId: targetId, success },
|
|
132
|
+
});
|
|
133
|
+
return {
|
|
134
|
+
applied: success ? [match] : [],
|
|
135
|
+
remaining: afterIssues,
|
|
136
|
+
skipped: success ? [] : [match],
|
|
137
|
+
health,
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
// safe mode: apply all safe-confidence fixes
|
|
141
|
+
const applied = [];
|
|
142
|
+
const skipped = [];
|
|
143
|
+
for (const issue of issues) {
|
|
144
|
+
if (issue.confidence !== "safe") {
|
|
145
|
+
skipped.push(issue);
|
|
146
|
+
continue;
|
|
147
|
+
}
|
|
148
|
+
const success = applySingleFix(root, issue);
|
|
149
|
+
if (success) {
|
|
150
|
+
applied.push(issue);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
skipped.push(issue);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
(0, scanner_1.clearTaskScanCache)();
|
|
157
|
+
const afterIndex = (0, scanner_1.scanTasks)(root);
|
|
158
|
+
const afterIssues = afterIndex.issues;
|
|
159
|
+
const health = afterIssues.length === 0 ? "clean" : buildHealthSummary(afterIssues);
|
|
160
|
+
(0, runtime_1.emitNervesEvent)({
|
|
161
|
+
event: "repertoire.fix_complete",
|
|
162
|
+
component: "repertoire",
|
|
163
|
+
message: `safe fixes complete: ${applied.length} applied, ${skipped.length} skipped`,
|
|
164
|
+
meta: { applied: applied.length, skipped: skipped.length },
|
|
165
|
+
});
|
|
166
|
+
return {
|
|
167
|
+
applied,
|
|
168
|
+
remaining: afterIssues,
|
|
169
|
+
skipped,
|
|
170
|
+
health,
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function buildHealthSummary(issues) {
|
|
174
|
+
const liveCount = issues.filter((i) => i.category === "live").length;
|
|
175
|
+
const migrationCount = issues.filter((i) => i.category === "migration").length;
|
|
176
|
+
const parts = [];
|
|
177
|
+
if (liveCount > 0)
|
|
178
|
+
parts.push(`${liveCount} live`);
|
|
179
|
+
if (migrationCount > 0)
|
|
180
|
+
parts.push(`${migrationCount} migration`);
|
|
181
|
+
return parts.join(", ");
|
|
182
|
+
}
|
|
@@ -33,12 +33,15 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
33
33
|
};
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
|
+
exports.createTaskModule = createTaskModule;
|
|
36
37
|
exports.getTaskModule = getTaskModule;
|
|
37
38
|
exports.resetTaskModule = resetTaskModule;
|
|
38
39
|
const fs = __importStar(require("fs"));
|
|
39
40
|
const path = __importStar(require("path"));
|
|
41
|
+
const config_1 = require("../../heart/config");
|
|
40
42
|
const runtime_1 = require("../../nerves/runtime");
|
|
41
43
|
const board_1 = require("./board");
|
|
44
|
+
const fix_1 = require("./fix");
|
|
42
45
|
const lifecycle_1 = require("./lifecycle");
|
|
43
46
|
const parser_1 = require("./parser");
|
|
44
47
|
const scanner_1 = require("./scanner");
|
|
@@ -55,14 +58,6 @@ function formatStemTimestamp(now = new Date()) {
|
|
|
55
58
|
const minutes = String(now.getMinutes()).padStart(2, "0");
|
|
56
59
|
return `${year}-${month}-${day}-${hours}${minutes}`;
|
|
57
60
|
}
|
|
58
|
-
function slugify(input) {
|
|
59
|
-
return input
|
|
60
|
-
.toLowerCase()
|
|
61
|
-
.replace(/[^a-z0-9]+/g, "-")
|
|
62
|
-
.replace(/^-+/, "")
|
|
63
|
-
.replace(/-+$/, "")
|
|
64
|
-
.slice(0, 64);
|
|
65
|
-
}
|
|
66
61
|
function findTask(index, nameOrStem) {
|
|
67
62
|
return (index.tasks.find((task) => task.stem === nameOrStem || task.name === nameOrStem) ??
|
|
68
63
|
index.tasks.find((task) => task.stem.endsWith(nameOrStem)) ??
|
|
@@ -73,8 +68,12 @@ function removeRuntimeFrontmatter(frontmatter) {
|
|
|
73
68
|
return clean;
|
|
74
69
|
}
|
|
75
70
|
class FileTaskModule {
|
|
71
|
+
root;
|
|
72
|
+
constructor(root = (0, scanner_1.getTaskRoot)()) {
|
|
73
|
+
this.root = root;
|
|
74
|
+
}
|
|
76
75
|
scan() {
|
|
77
|
-
return (0, scanner_1.scanTasks)(
|
|
76
|
+
return (0, scanner_1.scanTasks)(this.root);
|
|
78
77
|
}
|
|
79
78
|
getBoard() {
|
|
80
79
|
return (0, board_1.buildTaskBoard)(this.scan());
|
|
@@ -98,12 +97,13 @@ class FileTaskModule {
|
|
|
98
97
|
throw new Error(`invalid task status: ${String(input.status)}`);
|
|
99
98
|
}
|
|
100
99
|
const collection = (0, transitions_1.canonicalCollectionForTaskType)(type);
|
|
101
|
-
const stem = `${formatStemTimestamp()}-${slugify(input.title) || "task"}`;
|
|
100
|
+
const stem = `${formatStemTimestamp()}-${(0, config_1.slugify)(input.title).slice(0, 64) || "task"}`;
|
|
102
101
|
const filename = `${stem}.md`;
|
|
103
|
-
const root =
|
|
102
|
+
const root = this.root;
|
|
104
103
|
const filePath = path.join(root, collection, filename);
|
|
105
104
|
const today = formatDate();
|
|
106
105
|
const frontmatter = {
|
|
106
|
+
kind: "task",
|
|
107
107
|
type,
|
|
108
108
|
category: input.category || "infrastructure",
|
|
109
109
|
title: input.title,
|
|
@@ -115,13 +115,18 @@ class FileTaskModule {
|
|
|
115
115
|
lastRun: input.lastRun ?? null,
|
|
116
116
|
created: today,
|
|
117
117
|
updated: today,
|
|
118
|
-
child_tasks: [],
|
|
119
118
|
artifacts: [],
|
|
120
119
|
};
|
|
121
120
|
if (type === "one-shot") {
|
|
122
121
|
frontmatter.parent_task = null;
|
|
123
122
|
frontmatter.depends_on = [];
|
|
124
123
|
}
|
|
124
|
+
if (input.activeBridge && input.activeBridge.trim()) {
|
|
125
|
+
frontmatter.active_bridge = input.activeBridge.trim();
|
|
126
|
+
}
|
|
127
|
+
if (Array.isArray(input.bridgeSessions) && input.bridgeSessions.length > 0) {
|
|
128
|
+
frontmatter.bridge_sessions = input.bridgeSessions.filter((value) => typeof value === "string" && value.trim());
|
|
129
|
+
}
|
|
125
130
|
const content = (0, parser_1.renderTaskFile)(frontmatter, input.body);
|
|
126
131
|
const validation = (0, middleware_1.validateWrite)(filePath, content);
|
|
127
132
|
if (!validation.ok) {
|
|
@@ -132,6 +137,21 @@ class FileTaskModule {
|
|
|
132
137
|
(0, scanner_1.clearTaskScanCache)();
|
|
133
138
|
return filePath;
|
|
134
139
|
}
|
|
140
|
+
bindBridge(name, input) {
|
|
141
|
+
const task = this.getTask(name);
|
|
142
|
+
if (!task) {
|
|
143
|
+
return { ok: false, reason: `task not found: ${name}` };
|
|
144
|
+
}
|
|
145
|
+
const content = fs.readFileSync(task.path, "utf-8");
|
|
146
|
+
const parsed = (0, parser_1.parseTaskFile)(content, task.path);
|
|
147
|
+
const frontmatter = removeRuntimeFrontmatter(parsed.frontmatter);
|
|
148
|
+
frontmatter.active_bridge = input.bridgeId.trim();
|
|
149
|
+
frontmatter.bridge_sessions = input.sessionRefs.filter((value) => value.trim().length > 0);
|
|
150
|
+
frontmatter.updated = formatDate();
|
|
151
|
+
fs.writeFileSync(task.path, (0, parser_1.renderTaskFile)(frontmatter, parsed.body), "utf-8");
|
|
152
|
+
(0, scanner_1.clearTaskScanCache)();
|
|
153
|
+
return { ok: true, path: task.path };
|
|
154
|
+
}
|
|
135
155
|
updateStatus(name, toStatus) {
|
|
136
156
|
const normalized = (0, transitions_1.normalizeTaskStatus)(toStatus);
|
|
137
157
|
if (!normalized) {
|
|
@@ -178,6 +198,9 @@ class FileTaskModule {
|
|
|
178
198
|
}
|
|
179
199
|
return (0, middleware_1.validateSpawn)(task, spawnType);
|
|
180
200
|
}
|
|
201
|
+
fix(options) {
|
|
202
|
+
return (0, fix_1.applyFixes)(options, this.root);
|
|
203
|
+
}
|
|
181
204
|
detectStale(thresholdDays) {
|
|
182
205
|
return (0, lifecycle_1.detectStaleTasks)(this.scan(), thresholdDays);
|
|
183
206
|
}
|
|
@@ -198,9 +221,12 @@ class FileTaskModule {
|
|
|
198
221
|
}
|
|
199
222
|
}
|
|
200
223
|
let taskModule = null;
|
|
224
|
+
function createTaskModule(root = (0, scanner_1.getTaskRoot)()) {
|
|
225
|
+
return new FileTaskModule(root);
|
|
226
|
+
}
|
|
201
227
|
function getTaskModule() {
|
|
202
228
|
if (!taskModule) {
|
|
203
|
-
taskModule =
|
|
229
|
+
taskModule = createTaskModule();
|
|
204
230
|
}
|
|
205
231
|
return taskModule;
|
|
206
232
|
}
|
|
@@ -48,7 +48,7 @@ function archiveCompletedTasks(index) {
|
|
|
48
48
|
const archived = [];
|
|
49
49
|
const failures = [];
|
|
50
50
|
for (const task of index.tasks) {
|
|
51
|
-
if (task.status !== "done")
|
|
51
|
+
if (task.status !== "done" && task.status !== "cancelled")
|
|
52
52
|
continue;
|
|
53
53
|
const archiveDir = path.join(index.root, "archive", task.collection);
|
|
54
54
|
const archiveFile = path.join(archiveDir, task.name);
|
|
@@ -73,7 +73,7 @@ function detectStaleTasks(index, thresholdDays, now = new Date()) {
|
|
|
73
73
|
const updated = Date.parse(task.updated);
|
|
74
74
|
if (Number.isNaN(updated))
|
|
75
75
|
return false;
|
|
76
|
-
if (task.status === "done")
|
|
76
|
+
if (task.status === "done" || task.status === "cancelled")
|
|
77
77
|
return false;
|
|
78
78
|
return updated < staleCutoffMs;
|
|
79
79
|
});
|
|
@@ -96,8 +96,6 @@ function collectionFromPath(taskPath, type) {
|
|
|
96
96
|
return "one-shots";
|
|
97
97
|
if (parts.includes("ongoing"))
|
|
98
98
|
return "ongoing";
|
|
99
|
-
if (parts.includes("habits"))
|
|
100
|
-
return "habits";
|
|
101
99
|
return (0, transitions_1.canonicalCollectionForTaskType)(type);
|
|
102
100
|
}
|
|
103
101
|
function parseTaskFile(content, filePath) {
|
|
@@ -138,6 +136,9 @@ function parseTaskFile(content, filePath) {
|
|
|
138
136
|
_isCanonicalFilename: (0, transitions_1.isCanonicalTaskFilename)(name),
|
|
139
137
|
},
|
|
140
138
|
body: parsed.body,
|
|
139
|
+
hasWorkDir: false,
|
|
140
|
+
workDirFiles: [],
|
|
141
|
+
derivedChildren: [],
|
|
141
142
|
};
|
|
142
143
|
}
|
|
143
144
|
function formatFrontmatterValue(value) {
|
|
@@ -35,6 +35,7 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.getTaskRoot = getTaskRoot;
|
|
37
37
|
exports.ensureTaskLayout = ensureTaskLayout;
|
|
38
|
+
exports.tryExtractFrontmatter = tryExtractFrontmatter;
|
|
38
39
|
exports.clearTaskScanCache = clearTaskScanCache;
|
|
39
40
|
exports.scanTasks = scanTasks;
|
|
40
41
|
const fs = __importStar(require("fs"));
|
|
@@ -59,30 +60,57 @@ function ensureTaskLayout(root = getTaskRoot()) {
|
|
|
59
60
|
fs.mkdirSync(dir, { recursive: true });
|
|
60
61
|
}
|
|
61
62
|
}
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
63
|
+
/**
|
|
64
|
+
* Attempt to extract frontmatter from markdown content.
|
|
65
|
+
* Returns parsed frontmatter dict or null. Never throws.
|
|
66
|
+
*/
|
|
67
|
+
function tryExtractFrontmatter(content) {
|
|
68
|
+
(0, runtime_1.emitNervesEvent)({
|
|
69
|
+
event: "repertoire.frontmatter_extract_start",
|
|
70
|
+
component: "repertoire",
|
|
71
|
+
message: "attempting frontmatter extraction",
|
|
72
|
+
});
|
|
73
|
+
const lines = content.split(/\r?\n/);
|
|
74
|
+
if (lines[0]?.trim() !== "---") {
|
|
75
|
+
return null;
|
|
76
|
+
}
|
|
77
|
+
const closing = lines.findIndex((line, index) => index > 0 && line.trim() === "---");
|
|
78
|
+
if (closing === -1) {
|
|
79
|
+
return null;
|
|
80
|
+
}
|
|
81
|
+
const rawFrontmatter = lines.slice(1, closing).join("\n");
|
|
82
|
+
return (0, parser_1.parseFrontmatter)(rawFrontmatter);
|
|
83
|
+
}
|
|
84
|
+
const LEGACY_TASK_TYPES = ["one-shot", "ongoing", "habit"];
|
|
85
|
+
function buildFingerprint(root) {
|
|
86
|
+
(0, runtime_1.emitNervesEvent)({
|
|
87
|
+
event: "repertoire.fingerprint_build_start",
|
|
88
|
+
component: "repertoire",
|
|
89
|
+
message: "building scan fingerprint",
|
|
90
|
+
meta: { root },
|
|
91
|
+
});
|
|
92
|
+
const segments = [];
|
|
93
|
+
for (const collection of transitions_1.TASK_CANONICAL_COLLECTIONS) {
|
|
94
|
+
const collDir = path.join(root, collection);
|
|
95
|
+
const entries = fs.readdirSync(collDir, { withFileTypes: true });
|
|
96
|
+
for (const entry of entries) {
|
|
97
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
69
98
|
continue;
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
}
|
|
74
|
-
if (entry.name.endsWith(".md")) {
|
|
75
|
-
acc.push(path.join(dir, entry.name));
|
|
99
|
+
const filePath = path.join(collDir, entry.name);
|
|
100
|
+
const stat = fs.statSync(filePath);
|
|
101
|
+
segments.push(`${filePath}:${stat.mtimeMs}:${stat.size}`);
|
|
76
102
|
}
|
|
77
103
|
}
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
const
|
|
81
|
-
.
|
|
104
|
+
// Also include root-level md files for orphan detection fingerprinting
|
|
105
|
+
const rootEntries = fs.readdirSync(root, { withFileTypes: true });
|
|
106
|
+
for (const entry of rootEntries) {
|
|
107
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
108
|
+
continue;
|
|
109
|
+
const filePath = path.join(root, entry.name);
|
|
82
110
|
const stat = fs.statSync(filePath);
|
|
83
|
-
|
|
84
|
-
}
|
|
85
|
-
|
|
111
|
+
segments.push(`${filePath}:${stat.mtimeMs}:${stat.size}`);
|
|
112
|
+
}
|
|
113
|
+
segments.sort();
|
|
86
114
|
return segments.join("|");
|
|
87
115
|
}
|
|
88
116
|
function clearTaskScanCache() {
|
|
@@ -96,35 +124,164 @@ function scanTasks(root = getTaskRoot()) {
|
|
|
96
124
|
meta: { root },
|
|
97
125
|
});
|
|
98
126
|
ensureTaskLayout(root);
|
|
99
|
-
const
|
|
100
|
-
for (const collection of transitions_1.TASK_CANONICAL_COLLECTIONS) {
|
|
101
|
-
walkMarkdownFiles(path.join(root, collection), files);
|
|
102
|
-
}
|
|
103
|
-
const fingerprint = buildFingerprint(files);
|
|
127
|
+
const fingerprint = buildFingerprint(root);
|
|
104
128
|
if (scanCache && scanCache.fingerprint === fingerprint) {
|
|
105
129
|
return scanCache.index;
|
|
106
130
|
}
|
|
107
131
|
const tasks = [];
|
|
108
|
-
const
|
|
109
|
-
|
|
110
|
-
for (const
|
|
111
|
-
const
|
|
112
|
-
|
|
113
|
-
|
|
132
|
+
const issues = [];
|
|
133
|
+
// Scan each collection with flat directory reads (no recursion)
|
|
134
|
+
for (const collection of transitions_1.TASK_CANONICAL_COLLECTIONS) {
|
|
135
|
+
const collDir = path.join(root, collection);
|
|
136
|
+
const entries = fs.readdirSync(collDir, { withFileTypes: true });
|
|
137
|
+
const dirNames = new Set();
|
|
138
|
+
// Collect directory names for work dir detection
|
|
139
|
+
for (const entry of entries) {
|
|
140
|
+
if (entry.isDirectory()) {
|
|
141
|
+
dirNames.add(entry.name);
|
|
142
|
+
}
|
|
114
143
|
}
|
|
115
|
-
|
|
144
|
+
// Process only .md files at collection root (flat, no recursion)
|
|
145
|
+
let supportDocCount = 0;
|
|
146
|
+
for (const entry of entries) {
|
|
147
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
148
|
+
continue;
|
|
149
|
+
const filePath = path.join(collDir, entry.name);
|
|
116
150
|
const content = fs.readFileSync(filePath, "utf-8");
|
|
117
|
-
|
|
151
|
+
// Step 1: Try to extract frontmatter
|
|
152
|
+
const frontmatter = tryExtractFrontmatter(content);
|
|
153
|
+
if (!frontmatter) {
|
|
154
|
+
// No frontmatter — not a task, count as support doc clutter
|
|
155
|
+
supportDocCount += 1;
|
|
156
|
+
continue;
|
|
157
|
+
}
|
|
158
|
+
// Step 2: Check kind: task
|
|
159
|
+
const isKindTask = frontmatter.kind === "task";
|
|
160
|
+
const fmType = typeof frontmatter.type === "string" ? frontmatter.type.trim().toLowerCase() : "";
|
|
161
|
+
const isLegacyTask = !isKindTask && LEGACY_TASK_TYPES.includes(fmType);
|
|
162
|
+
if (!isKindTask && !isLegacyTask) {
|
|
163
|
+
// Has frontmatter but not a task — skip silently
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
// Step 3: Emit migration issue for legacy task
|
|
167
|
+
if (isLegacyTask) {
|
|
168
|
+
const relPath = path.relative(root, filePath);
|
|
169
|
+
issues.push({
|
|
170
|
+
target: relPath,
|
|
171
|
+
code: "schema-missing-kind",
|
|
172
|
+
description: "Task card missing kind: task field",
|
|
173
|
+
fix: "Add kind: task to frontmatter",
|
|
174
|
+
confidence: "safe",
|
|
175
|
+
category: "migration",
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
// Step 4: Parse the task file
|
|
179
|
+
try {
|
|
180
|
+
const task = (0, parser_1.parseTaskFile)(content, filePath);
|
|
181
|
+
// Check filename canonicality
|
|
182
|
+
const base = path.basename(filePath);
|
|
183
|
+
if (!(0, transitions_1.isCanonicalTaskFilename)(base)) {
|
|
184
|
+
const relPath = path.relative(root, filePath);
|
|
185
|
+
issues.push({
|
|
186
|
+
target: relPath,
|
|
187
|
+
code: "filename-not-canonical",
|
|
188
|
+
description: `Non-canonical filename: ${base}`,
|
|
189
|
+
fix: `Rename to canonical format (YYYY-MM-DD-HHMM-slug.md)`,
|
|
190
|
+
confidence: "safe",
|
|
191
|
+
category: "migration",
|
|
192
|
+
});
|
|
193
|
+
}
|
|
194
|
+
// Work dir detection
|
|
195
|
+
const stem = base.replace(/\.md$/i, "");
|
|
196
|
+
if (dirNames.has(stem)) {
|
|
197
|
+
task.hasWorkDir = true;
|
|
198
|
+
const workDirPath = path.join(collDir, stem);
|
|
199
|
+
task.workDirFiles = fs.readdirSync(workDirPath).sort();
|
|
200
|
+
}
|
|
201
|
+
tasks.push(task);
|
|
202
|
+
}
|
|
203
|
+
catch (error) {
|
|
204
|
+
// Parse error on a file we identified as a task — real issue
|
|
205
|
+
const relPath = path.relative(root, filePath);
|
|
206
|
+
issues.push({
|
|
207
|
+
target: relPath,
|
|
208
|
+
code: "schema-invalid",
|
|
209
|
+
description: `Parse error: ${error instanceof Error ? error.message : String(error)}`,
|
|
210
|
+
fix: "Fix the task card schema (ensure required fields: type, status, etc.)",
|
|
211
|
+
confidence: "needs_review",
|
|
212
|
+
category: "live",
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
// Summarize non-task support docs at collection root as one migration issue
|
|
217
|
+
if (supportDocCount > 0) {
|
|
218
|
+
(0, runtime_1.emitNervesEvent)({
|
|
219
|
+
event: "repertoire.support_docs_detected",
|
|
220
|
+
component: "repertoire",
|
|
221
|
+
message: "non-task support documents at collection root",
|
|
222
|
+
meta: { collection, count: supportDocCount },
|
|
223
|
+
});
|
|
224
|
+
issues.push({
|
|
225
|
+
target: collection,
|
|
226
|
+
code: "org-collection-root-clutter",
|
|
227
|
+
description: `${supportDocCount} non-task file${supportDocCount === 1 ? "" : "s"} at ${collection}/ root (doing docs, planning docs, etc.)`,
|
|
228
|
+
fix: "Move support docs into same-stem work directories for their parent tasks",
|
|
229
|
+
confidence: "needs_review",
|
|
230
|
+
category: "migration",
|
|
231
|
+
});
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
// Orphan detection: root-level .md files outside any canonical collection
|
|
235
|
+
const rootEntries = fs.readdirSync(root, { withFileTypes: true });
|
|
236
|
+
const collectionSet = new Set(transitions_1.TASK_CANONICAL_COLLECTIONS);
|
|
237
|
+
for (const entry of rootEntries) {
|
|
238
|
+
if (!entry.isFile() || !entry.name.endsWith(".md"))
|
|
239
|
+
continue;
|
|
240
|
+
const filePath = path.join(root, entry.name);
|
|
241
|
+
const content = fs.readFileSync(filePath, "utf-8");
|
|
242
|
+
const frontmatter = tryExtractFrontmatter(content);
|
|
243
|
+
// Only flag as orphan if it has task-like frontmatter
|
|
244
|
+
if (!frontmatter)
|
|
245
|
+
continue;
|
|
246
|
+
const fmType = typeof frontmatter.type === "string" ? frontmatter.type.trim().toLowerCase() : "";
|
|
247
|
+
const hasTaskLikeContent = frontmatter.kind === "task" ||
|
|
248
|
+
LEGACY_TASK_TYPES.includes(fmType) ||
|
|
249
|
+
(typeof frontmatter.status === "string" && typeof frontmatter.title === "string");
|
|
250
|
+
if (hasTaskLikeContent) {
|
|
251
|
+
(0, runtime_1.emitNervesEvent)({
|
|
252
|
+
event: "repertoire.orphan_detected",
|
|
253
|
+
component: "repertoire",
|
|
254
|
+
message: "root-level orphan document detected",
|
|
255
|
+
meta: { filePath },
|
|
256
|
+
});
|
|
257
|
+
issues.push({
|
|
258
|
+
target: entry.name,
|
|
259
|
+
code: "org-root-level-doc",
|
|
260
|
+
description: `Root-level document outside any collection: ${entry.name}`,
|
|
261
|
+
fix: `Move to appropriate collection directory (${[...collectionSet].join(", ")})`,
|
|
262
|
+
confidence: "needs_review",
|
|
263
|
+
category: "migration",
|
|
264
|
+
});
|
|
118
265
|
}
|
|
119
|
-
|
|
120
|
-
|
|
266
|
+
}
|
|
267
|
+
// Populate derivedChildren from parent_task links
|
|
268
|
+
const stemToTask = new Map();
|
|
269
|
+
for (const task of tasks) {
|
|
270
|
+
stemToTask.set(task.stem, task);
|
|
271
|
+
}
|
|
272
|
+
for (const task of tasks) {
|
|
273
|
+
const parentStem = typeof task.frontmatter.parent_task === "string"
|
|
274
|
+
? task.frontmatter.parent_task.trim()
|
|
275
|
+
: "";
|
|
276
|
+
if (parentStem && stemToTask.has(parentStem)) {
|
|
277
|
+
const parent = stemToTask.get(parentStem);
|
|
278
|
+
parent.derivedChildren.push(task.stem);
|
|
121
279
|
}
|
|
122
280
|
}
|
|
123
281
|
const index = {
|
|
124
282
|
root,
|
|
125
283
|
tasks,
|
|
126
|
-
|
|
127
|
-
parseErrors,
|
|
284
|
+
issues,
|
|
128
285
|
fingerprint,
|
|
129
286
|
};
|
|
130
287
|
scanCache = { fingerprint, index };
|