mixdog 1.3.5 → 1.4.0
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/NOTICE.md +2 -2
- package/README.md +2 -2
- package/package.json +2 -11
- package/scripts/daemon-stub.mjs +1 -1
- package/scripts/gate-local.mjs +4 -2
- package/scripts/native-release-status.mjs +2 -2
- package/scripts/recall-history-cases.json +1 -1
- package/scripts/suite-health.mjs +10 -1
- package/scripts/test.mjs +7 -11
- package/src/agents/reviewer/AGENT.md +7 -11
- package/src/agents/reviewer/agent.json +1 -1
- package/src/defaults/shipped-history.json +17 -1
- package/src/defaults/skills/browser-use/SKILL.md +59 -11
- package/src/defaults/skills/code-tidy/SKILL.md +142 -270
- package/src/defaults/skills/code-tidy/references/agent-cleanup.md +4 -4
- package/src/defaults/skills/code-tidy/references/cleanup-report.md +31 -76
- package/src/defaults/skills/code-tidy/references/dead-code.md +6 -12
- package/src/defaults/skills/computer-use/SKILL.md +33 -9
- package/src/defaults/skills/setup/SKILL.md +22 -0
- package/src/defaults/skills/setup/references/actions.md +39 -5
- package/src/defaults/skills/setup/references/surfaces.md +11 -2
- package/src/defaults/skills/visualize/SKILL.md +2 -1
- package/src/lib/rules-builder.cjs +10 -8
- package/src/rules/agent/AGENT.md +6 -6
- package/src/rules/lead/LEAD.md +18 -20
- package/src/rules/shared/05-tool-calls.md +5 -6
- package/src/rules/shared/10-tool-workflow.md +2 -0
- package/src/rules/shared/60-verification.md +7 -5
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +2 -3
- package/src/runtime/agent/orchestrator/agent-runtime/title-completion.mjs +3 -1
- package/src/runtime/agent/orchestrator/agent-trace-format.mjs +3 -1
- package/src/runtime/agent/orchestrator/config.mjs +17 -1
- package/src/runtime/agent/orchestrator/context/collect.mjs +3 -0
- package/src/runtime/agent/orchestrator/context/deferred-tools.mjs +72 -67
- package/src/runtime/agent/orchestrator/context/skill-catalog.mjs +54 -1
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +3 -3
- package/src/runtime/agent/orchestrator/mcp/client-transport.mjs +176 -72
- package/src/runtime/agent/orchestrator/mcp/client.mjs +19 -0
- package/src/runtime/agent/orchestrator/providers/account-pool.mjs +181 -133
- package/src/runtime/agent/orchestrator/providers/admission-scheduler.mjs +42 -6
- package/src/runtime/agent/orchestrator/providers/anthropic-cache-warm.mjs +165 -0
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-credentials.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-request/gzip-post.mjs +14 -14
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +145 -66
- package/src/runtime/agent/orchestrator/providers/anthropic-overload-fallback.mjs +25 -3
- package/src/runtime/agent/orchestrator/providers/anthropic-sse.mjs +64 -33
- package/src/runtime/agent/orchestrator/providers/anthropic.mjs +135 -87
- package/src/runtime/agent/orchestrator/providers/antigravity-transport.mjs +123 -102
- package/src/runtime/agent/orchestrator/providers/cache-warm-admission.mjs +90 -0
- package/src/runtime/agent/orchestrator/providers/cursor-wire-transport.mjs +25 -9
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +22 -13
- package/src/runtime/agent/orchestrator/providers/lib/oauth-token-utils.mjs +17 -3
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +52 -10
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.d.mts +8 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-channel.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/npm-cli-version.mjs +11 -3
- package/src/runtime/agent/orchestrator/providers/oauth-credential-probes.mjs +2 -1
- package/src/runtime/agent/orchestrator/providers/openai-oauth-tokens.mjs +10 -9
- package/src/runtime/agent/orchestrator/providers/openai-ws-send/send-context.mjs +22 -3
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/attempt-context.mjs +43 -5
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/handshake-failure.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws-send-attempts/stream-failure.mjs +6 -3
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +65 -1
- package/src/runtime/agent/orchestrator/providers/quota-reading.mjs +38 -12
- package/src/runtime/agent/orchestrator/providers/registry.mjs +26 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +39 -7
- package/src/runtime/agent/orchestrator/providers/statusline-route-meta.mjs +6 -0
- package/src/runtime/agent/orchestrator/runtime-core/ask-user-tool-defs.mjs +12 -7
- package/src/runtime/agent/orchestrator/runtime-core/compaction-config-keys.mjs +62 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +37 -16
- package/src/runtime/agent/orchestrator/runtime-core/deferred-tool-delta.mjs +100 -23
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -0
- package/src/runtime/agent/orchestrator/runtime-core/tool-bridge.mjs +19 -4
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +125 -30
- package/src/runtime/agent/orchestrator/session/cache-warm.mjs +792 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +133 -22
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +475 -58
- package/src/runtime/agent/orchestrator/session/compaction-archive.mjs +42 -17
- package/src/runtime/agent/orchestrator/session/eager-dispatch.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +0 -2
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +36 -4
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +18 -22
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +32 -3
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/loop/no-tool-turn.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +17 -3
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/after-hook.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +3 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +16 -2
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +16 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +10 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +3 -10
- package/src/runtime/agent/orchestrator/session/loop/tool-phase.mjs +12 -3
- package/src/runtime/agent/orchestrator/session/manager/ask-queue.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-session.mjs +19 -1
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +133 -90
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-state.mjs +31 -4
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +30 -18
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +23 -13
- package/src/runtime/agent/orchestrator/session/manager/pending-message-entry.mjs +11 -2
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +13 -0
- package/src/runtime/agent/orchestrator/session/manager/route-fallback-chain.mjs +129 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +20 -2
- package/src/runtime/agent/orchestrator/session/manager/session-close.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +8 -0
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/tool-resolution.mjs +7 -2
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +102 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +18 -5
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +19 -8
- package/src/runtime/agent/orchestrator/session/prompt-cache-idle-gaps.mjs +113 -0
- package/src/runtime/agent/orchestrator/session/prompt-cache-touch-store.mjs +127 -0
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +36 -9
- package/src/runtime/agent/orchestrator/session/sensitive-projection.mjs +100 -0
- package/src/runtime/agent/orchestrator/session/sensitive-values.mjs +257 -0
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +20 -7
- package/src/runtime/agent/orchestrator/session/side-question.mjs +18 -0
- package/src/runtime/agent/orchestrator/session/skill-update-notice.mjs +60 -0
- package/src/runtime/agent/orchestrator/session/store/live-state.mjs +6 -3
- package/src/runtime/agent/orchestrator/session/store/save-delta.mjs +9 -5
- package/src/runtime/agent/orchestrator/session/store/serialize.mjs +9 -8
- package/src/runtime/agent/orchestrator/session/store/session-persistence-events.mjs +29 -0
- package/src/runtime/agent/orchestrator/session/store-agent-worker-rows.mjs +8 -6
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +12 -2
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +44 -14
- package/src/runtime/agent/orchestrator/session/store-summary-reader.mjs +84 -3
- package/src/runtime/agent/orchestrator/session/stored-attachment-history.mjs +32 -0
- package/src/runtime/agent/orchestrator/session/thinking-binding.mjs +108 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/pre-dispatch.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/tool-batch/record-outcome.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +18 -1
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-status.mjs +9 -7
- package/src/runtime/agent/orchestrator/session/transcript-restore/tool-result-text.mjs +2 -2
- package/src/runtime/agent/orchestrator/session/turn-failure.mjs +5 -1
- package/src/runtime/agent/orchestrator/tools/builtin/arg-guard.mjs +5 -2
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +12 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/misuse-guard.mjs +240 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/result-format.mjs +1 -1
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/shell-cwd.mjs +38 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +65 -7
- package/src/runtime/agent/orchestrator/tools/builtin/shell-runtime.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +36 -13
- package/src/runtime/browser-bridge/action-schema.mjs +13 -2
- package/src/runtime/browser-bridge/client.mjs +73 -8
- package/src/runtime/browser-bridge/input-fields.mjs +8 -9
- package/src/runtime/browser-bridge/mail-links.mjs +107 -0
- package/src/runtime/browser-bridge/tool-defs.mjs +1 -1
- package/src/runtime/channels/lib/config.mjs +6 -61
- package/src/runtime/channels/lib/crash-log.mjs +1 -1
- package/src/runtime/channels/lib/event-pipeline.mjs +4 -19
- package/src/runtime/channels/lib/event-queue.mjs +3 -18
- package/src/runtime/channels/lib/owned-runtime/automation-services.mjs +2 -2
- package/src/runtime/channels/lib/owned-runtime/automation-start.mjs +3 -4
- package/src/runtime/channels/lib/owned-runtime/config-reload.mjs +4 -59
- package/src/runtime/channels/lib/owned-runtime/owned-start.mjs +33 -115
- package/src/runtime/channels/lib/owned-runtime/owned-stop.mjs +5 -22
- package/src/runtime/channels/lib/owned-runtime/state.mjs +2 -8
- package/src/runtime/channels/lib/owned-runtime.mjs +6 -23
- package/src/runtime/channels/lib/parent-bridge.mjs +2 -2
- package/src/runtime/channels/lib/runtime-paths.mjs +4 -43
- package/src/runtime/channels/lib/scheduler.mjs +33 -147
- package/src/runtime/channels/lib/schedules-db.mjs +34 -11
- package/src/runtime/channels/lib/status-snapshot.mjs +1 -1
- package/src/runtime/channels/lib/tool-dispatch.mjs +1 -2
- package/src/runtime/channels/lib/webhooks-db.mjs +5 -9
- package/src/runtime/channels/lib/worker-bootstrap.mjs +0 -1
- package/src/runtime/channels/lib/worker-ipc.mjs +0 -1
- package/src/runtime/channels/lib/worker-main.mjs +10 -34
- package/src/runtime/computer-bridge/action-schema.mjs +42 -1
- package/src/runtime/computer-bridge/actions.mjs +9 -1
- package/src/runtime/computer-bridge/client.mjs +180 -8
- package/src/runtime/computer-bridge/core-actions.mjs +2 -2
- package/src/runtime/computer-bridge/error-recovery.mjs +27 -2
- package/src/runtime/computer-bridge/linux-readiness.mjs +65 -23
- package/src/runtime/computer-bridge/pending-continuation.mjs +1 -1
- package/src/runtime/connectors/connector-accounts-mcp.mjs +230 -0
- package/src/runtime/connectors/gmail-app-password.mjs +172 -39
- package/src/runtime/connectors/google-mcp.mjs +10 -12
- package/src/runtime/memory/lib/pg/adapter.mjs +77 -70
- package/src/runtime/memory/lib/pg/supervisor.mjs +24 -12
- package/src/runtime/memory/lib/runtime-fetcher.mjs +23 -5
- package/src/runtime/session-search/session-search-db.mjs +73 -9
- package/src/runtime/session-search/session-search-ingest.mjs +110 -20
- package/src/runtime/shared/abort-race.mjs +89 -0
- package/src/runtime/shared/agent-avatar.d.mts +0 -1
- package/src/runtime/shared/agent-kind.mjs +4 -3
- package/src/runtime/shared/bounded-download.mjs +8 -3
- package/src/runtime/shared/config.mjs +2 -13
- package/src/runtime/shared/connector-accounts.mjs +20 -10
- package/src/runtime/shared/connector-catalog.d.mts +29 -0
- package/src/runtime/shared/connector-catalog.mjs +150 -0
- package/src/runtime/shared/connector-triggers.mjs +22 -19
- package/src/runtime/shared/defaults-separation.mjs +2 -14
- package/src/runtime/shared/delegated-approval-host.mjs +103 -11
- package/src/runtime/shared/err-text.mjs +24 -15
- package/src/runtime/shared/file-permissions.d.mts +0 -8
- package/src/runtime/shared/file-permissions.mjs +0 -11
- package/src/runtime/shared/git-direct.test-support.mjs +19 -0
- package/src/runtime/shared/heartbeat-interval.d.mts +4 -0
- package/src/runtime/shared/heartbeat-interval.mjs +19 -0
- package/src/runtime/shared/idle-auto-clear-gate.mjs +104 -0
- package/src/runtime/shared/llm/usage-rollup.mjs +1 -1
- package/src/runtime/shared/mixy-presence.mjs +22 -0
- package/src/runtime/shared/orchestration.d.mts +2 -0
- package/src/runtime/shared/pg-schema-db.mjs +27 -16
- package/src/runtime/shared/profile-config.cjs +1 -1
- package/src/runtime/shared/prompt-origin.d.mts +4 -0
- package/src/runtime/shared/prompt-origin.mjs +21 -0
- package/src/runtime/shared/provider-accounts.mjs +7 -1
- package/src/runtime/shared/provider-display-name.mjs +29 -0
- package/src/runtime/shared/provider-timeout-phase.mjs +2 -0
- package/src/runtime/shared/routine-trigger.d.mts +2 -0
- package/src/runtime/shared/routine-trigger.mjs +10 -0
- package/src/runtime/shared/sensitive-path-rules.d.mts +2 -10
- package/src/runtime/shared/sensitive-path-rules.mjs +19 -41
- package/src/runtime/shared/session-activity-signal.mjs +34 -1
- package/src/runtime/shared/session-sidebar-host.d.mts +1 -1
- package/src/runtime/shared/session-sidebar-host.mjs +7 -3
- package/src/runtime/shared/session-turn-prelude.mjs +18 -0
- package/src/runtime/shared/tool-result-summary.mjs +1 -14
- package/src/runtime/shared/worktrees/test-support.mjs +9 -4
- package/src/runtime/terminal-bridge/client.mjs +10 -1
- package/src/runtime/visualize-bridge/client.mjs +27 -8
- package/src/runtime/visualize-bridge/tool-defs.mjs +22 -8
- package/src/runtime/visualize-bridge/tool-meta.d.mts +5 -0
- package/src/runtime/visualize-bridge/tool-meta.mjs +22 -0
- package/src/runtime/web-search/lib/fetch-pipeline.mjs +2 -2
- package/src/session-runtime/agent-home-delivery.mjs +448 -185
- package/src/session-runtime/agent-task-sessions.mjs +329 -180
- package/src/session-runtime/boot/apis.mjs +9 -0
- package/src/session-runtime/boot/infrastructure.mjs +4 -0
- package/src/session-runtime/boot/providers.mjs +3 -0
- package/src/session-runtime/boot/tools.mjs +6 -1
- package/src/session-runtime/config-lifecycle.mjs +6 -0
- package/src/session-runtime/connector-merge-migration.mjs +305 -0
- package/src/session-runtime/internal-tool-executor/ask-user-tool.mjs +132 -28
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +2 -0
- package/src/session-runtime/lifecycle/inheritance.mjs +16 -3
- package/src/session-runtime/lifecycle/session-catalog.mjs +3 -1
- package/src/session-runtime/lifecycle/teardown/runtime-stops.mjs +50 -4
- package/src/session-runtime/lifecycle/teardown.mjs +23 -5
- package/src/session-runtime/mcp-glue/server-catalog.mjs +55 -3
- package/src/session-runtime/mcp-oauth-login.mjs +5 -3
- package/src/session-runtime/mixy-heartbeat.mjs +153 -33
- package/src/session-runtime/notification-bus.mjs +31 -117
- package/src/session-runtime/notification-completion-queue.mjs +54 -0
- package/src/session-runtime/notification-listeners.mjs +76 -0
- package/src/session-runtime/owned-automation-run.mjs +2 -1
- package/src/session-runtime/prewarm/channel-start.mjs +3 -7
- package/src/session-runtime/resource-mcp-api.mjs +143 -224
- package/src/session-runtime/resource-mcp-connector-accounts.mjs +163 -0
- package/src/session-runtime/resource-mcp-oauth-api.mjs +217 -0
- package/src/session-runtime/resource-mcp-secrets.mjs +82 -0
- package/src/session-runtime/resource-mcp-servers.mjs +78 -0
- package/src/session-runtime/resource-mcp-store.mjs +49 -0
- package/src/session-runtime/routine-owner.mjs +40 -9
- package/src/session-runtime/services/agent-tool/close-flow.mjs +3 -0
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +7 -2
- package/src/session-runtime/services/agent-tool/tag-registry.mjs +1 -0
- package/src/session-runtime/services/agent-tool/worker-index/awaiting-user-sync.mjs +51 -0
- package/src/session-runtime/services/agent-tool/worker-index/disposal.mjs +55 -0
- package/src/session-runtime/services/agent-tool/worker-index/released-store.mjs +123 -0
- package/src/session-runtime/services/agent-tool/worker-index/restart-settlement.mjs +112 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-reads.mjs +36 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-shape.mjs +2 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-store.mjs +17 -4
- package/src/session-runtime/services/agent-tool/worker-index/row-writes.mjs +58 -0
- package/src/session-runtime/services/agent-tool/worker-index.mjs +41 -241
- package/src/session-runtime/services/agent-tool/worker-rows.mjs +3 -0
- package/src/session-runtime/services/channel-admin.mjs +7 -13
- package/src/session-runtime/services/channel-session-router.mjs +4 -2
- package/src/session-runtime/services/seeds.mjs +0 -28
- package/src/session-runtime/session-compaction-sync.mjs +27 -0
- package/src/session-runtime/session-create/session-options.mjs +1 -0
- package/src/session-runtime/settings-builtin-tools-api.mjs +11 -0
- package/src/session-runtime/settings-compaction-api.mjs +2 -40
- package/src/session-runtime/settings-system-api.mjs +13 -1
- package/src/session-runtime/setup-tool/agent-settings-actions.mjs +65 -0
- package/src/session-runtime/setup-tool/executor.mjs +145 -22
- package/src/session-runtime/setup-tool/extended-actions.mjs +8 -3
- package/src/session-runtime/setup-tool/session-route-actions.mjs +152 -0
- package/src/session-runtime/setup-tool/settings-contract.mjs +4 -3
- package/src/session-runtime/setup-tool/tool-defs.mjs +64 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +17 -13
- package/src/session-runtime/tool-policy/policy-stage.mjs +16 -2
- package/src/session-runtime/turn/turn-run/ask-callbacks.mjs +1 -0
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +4 -0
- package/src/standalone/channel-transport/client-registry/client-records.mjs +65 -0
- package/src/standalone/channel-transport/client-registry/client-registration.mjs +118 -0
- package/src/standalone/channel-transport/client-registry.mjs +24 -163
- package/src/standalone/channel-transport.mjs +1 -1
- package/src/standalone/daemon-channels-loader.mjs +10 -8
- package/src/standalone/daemon-session-control/list-page.mjs +72 -0
- package/src/standalone/daemon-session-control/request.mjs +51 -0
- package/src/standalone/daemon-session-control/room-host.mjs +57 -0
- package/src/standalone/daemon-session-control/route-control.mjs +48 -0
- package/src/standalone/daemon-session-control/send-turn.mjs +60 -0
- package/src/standalone/daemon-session-control/worktree-control.mjs +40 -0
- package/src/standalone/daemon-session-control.mjs +124 -188
- package/src/standalone/daemon.mjs +26 -3
- package/src/standalone/session-client.mjs +7 -3
- package/src/standalone/session-protocol.mjs +5 -0
- package/src/standalone/session-service/agent-tree/agent-child.mjs +1 -0
- package/src/standalone/session-service/quota-resume.mjs +3 -0
- package/src/standalone/session-service/retention/busy.mjs +65 -1
- package/src/standalone/session-service/session-calls/session-action.mjs +23 -2
- package/src/standalone/session-service/session-calls/session-views.mjs +8 -0
- package/src/standalone/session-tool-output.mjs +15 -7
- package/src/tui/app/model-options.mjs +3 -28
- package/src/tui/dist/index.mjs +58 -64
- package/src/tui/session/agent-job-feed/model-notification.mjs +3 -0
- package/src/tui/session/initial-state.mjs +3 -0
- package/src/tui/session/notice-surface.mjs +7 -1
- package/src/tui/session/queue-helpers.mjs +3 -42
- package/src/tui/session/session-api/routes-agent-definitions.mjs +14 -2
- package/src/tui/session/session-api/routes-write.mjs +5 -1
- package/src/tui/session/session-api/routes.mjs +1 -0
- package/src/tui/session/session-api/settings.mjs +17 -1
- package/src/tui/session/session-flow/auto-clear.mjs +4 -33
- package/src/tui/session/session-flow/drain-closed-queue.mjs +38 -0
- package/src/tui/session/session-flow/drain-enqueue.mjs +86 -0
- package/src/tui/session/session-flow/drain-retry.mjs +35 -0
- package/src/tui/session/session-flow/drain.mjs +118 -149
- package/src/tui/session/session-flow/queue/entry-shape.mjs +5 -0
- package/src/tui/session/session-flow/queue/take-entries.mjs +5 -2
- package/src/tui/session/tool-approval-delegation.mjs +64 -0
- package/src/tui/session/tool-approval-request.mjs +39 -0
- package/src/tui/session/tool-approval-settle.mjs +62 -0
- package/src/tui/session/tool-approval.mjs +69 -115
- package/src/tui/session/tui-steering-persist.mjs +8 -1
- package/src/tui/session/turn-stream.mjs +19 -2
- package/src/tui/session/turn.mjs +1 -0
- package/src/vendor/statusline/bin/statusline-route.mjs +1 -219
- package/src/vendor/statusline/src/gateway/route-meta.mjs +35 -13
- package/scripts/code-graph-description-contract.mjs +0 -188
- package/src/runtime/channels/lib/owned-runtime/ownership-refresh.mjs +0 -36
|
@@ -41,6 +41,10 @@ import {
|
|
|
41
41
|
removeRetiredAgentFields,
|
|
42
42
|
} from './config-storage.mjs';
|
|
43
43
|
import { oauthCredentialProbeState, isOAuthProviderAvailable } from './providers/oauth-credential-probes.mjs';
|
|
44
|
+
import {
|
|
45
|
+
DEFAULT_HEARTBEAT_INTERVAL_MINUTES,
|
|
46
|
+
normalizeHeartbeatIntervalMinutes,
|
|
47
|
+
} from '../../shared/heartbeat-interval.mjs';
|
|
44
48
|
import { normalizeDeveloperConfig } from '../../shared/developer-options.mjs';
|
|
45
49
|
import { normalizeWorktreeSettings } from '../../shared/worktrees/settings.mjs';
|
|
46
50
|
import { normalizePluginMcpIntents } from './runtime-core/plugin-mcp.mjs';
|
|
@@ -295,8 +299,13 @@ export function loadConfig(options = {}) {
|
|
|
295
299
|
recap: recapConfig,
|
|
296
300
|
// The model may title the session (session tool, action=rename); default on.
|
|
297
301
|
aiSessionTitles: raw.aiSessionTitles !== false,
|
|
298
|
-
// Mixy's
|
|
302
|
+
// Mixy's heartbeat check (session-runtime/mixy-heartbeat.mjs); default on.
|
|
299
303
|
heartbeat: raw.heartbeat !== false,
|
|
304
|
+
// Minutes between its checks, one of a fixed set (shared/heartbeat-interval.mjs);
|
|
305
|
+
// anything else reads as the default.
|
|
306
|
+
heartbeatIntervalMinutes: normalizeHeartbeatIntervalMinutes(raw.heartbeatIntervalMinutes),
|
|
307
|
+
// Prompt-cache warming (session/cache-warm.mjs); default on.
|
|
308
|
+
promptCacheWarming: raw?.promptCacheWarming !== false,
|
|
300
309
|
// Bots may leave an emoji reaction on the user's message (react tool); default on.
|
|
301
310
|
reactions: raw.reactions !== false,
|
|
302
311
|
// Bots page layout (order, hidden groups, pins, retention) and the shared
|
|
@@ -351,6 +360,7 @@ export function loadConfig(options = {}) {
|
|
|
351
360
|
shell: {},
|
|
352
361
|
update: {},
|
|
353
362
|
recap: { enabled: true },
|
|
363
|
+
promptCacheWarming: true,
|
|
354
364
|
worktree: normalizeWorktreeSettings(null),
|
|
355
365
|
developer: {},
|
|
356
366
|
modules: {},
|
|
@@ -482,8 +492,14 @@ function buildAgentSaveBuilder(config) {
|
|
|
482
492
|
else delete next.aiSessionTitles;
|
|
483
493
|
if (config.heartbeat === false) next.heartbeat = false;
|
|
484
494
|
else delete next.heartbeat;
|
|
495
|
+
// Only a non-default choice is stored.
|
|
496
|
+
const heartbeatMinutes = normalizeHeartbeatIntervalMinutes(config.heartbeatIntervalMinutes);
|
|
497
|
+
if (heartbeatMinutes !== DEFAULT_HEARTBEAT_INTERVAL_MINUTES) next.heartbeatIntervalMinutes = heartbeatMinutes;
|
|
498
|
+
else delete next.heartbeatIntervalMinutes;
|
|
485
499
|
if (config.reactions === false) next.reactions = false;
|
|
486
500
|
else delete next.reactions;
|
|
501
|
+
if (config.promptCacheWarming === false) next.promptCacheWarming = false;
|
|
502
|
+
else delete next.promptCacheWarming;
|
|
487
503
|
if (Array.isArray(config.botOrder) && config.botOrder.length) next.botOrder = [...config.botOrder];
|
|
488
504
|
else delete next.botOrder;
|
|
489
505
|
if (config.leadAvatar && typeof config.leadAvatar === 'object') next.leadAvatar = { ...config.leadAvatar };
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
export {
|
|
2
2
|
applyInitialDeferredToolManifestToBp2,
|
|
3
3
|
buildDeferredToolManifest,
|
|
4
|
+
resetBp2StableContext,
|
|
4
5
|
stripDeferredToolManifestBlock,
|
|
5
6
|
} from './deferred-tools.mjs';
|
|
6
7
|
export {
|
|
@@ -11,11 +12,13 @@ export {
|
|
|
11
12
|
collectPromptSkillsCached,
|
|
12
13
|
collectSkills,
|
|
13
14
|
collectSkillsCached,
|
|
15
|
+
currentSkillDelivery,
|
|
14
16
|
filterSkillsExcludingDisabled,
|
|
15
17
|
invalidateSkillsCache,
|
|
16
18
|
isSkillDisabled,
|
|
17
19
|
loadSkillResource,
|
|
18
20
|
skillBodyPresentInSession,
|
|
21
|
+
skillLoadRefusal,
|
|
19
22
|
skillMissingFeature,
|
|
20
23
|
skillOutsideScope,
|
|
21
24
|
skillEnabledFlags,
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
-
// Deferred-pool
|
|
2
|
-
|
|
1
|
+
// Deferred-pool manifest injected into BP2. MCP server instruction bodies are
|
|
2
|
+
// not injected: a server's one-line entry is its when-to-use trigger (accounts
|
|
3
|
+
// one line per server), and its instructions arrive with its tools
|
|
4
|
+
// on load_tool. The <mcp-instructions> block is still recognized so older
|
|
5
|
+
// prompts can shed it.
|
|
3
6
|
import { connectorTrigger } from '../../../shared/connector-triggers.mjs';
|
|
4
7
|
import { parseMcpToolName, titleCaseMcpServer } from '../../../shared/tool-primitives.mjs';
|
|
8
|
+
import { SKILL_TRIGGER_LISTING_MAX } from '../../../shared/skill-document.mjs';
|
|
5
9
|
import { isToolBridgeEnabled, TOOL_BRIDGE_GUIDANCE } from '../runtime-core/tool-exposure.mjs';
|
|
6
10
|
|
|
7
11
|
export function compactPromptManifestText(value, max = 250) {
|
|
@@ -24,13 +28,24 @@ const MCP_INSTRUCTIONS_BLOCK_RE = /(\n\n---\n*)?<mcp-instructions>[\s\S]*?<\/mcp
|
|
|
24
28
|
// Tool and MCP server names enter the manifests only as plain identifiers
|
|
25
29
|
// (no markup can be smuggled into the prompt through a name).
|
|
26
30
|
const MANIFEST_NAME_SAFE_RE = /^[A-Za-z0-9_.:-]+$/;
|
|
27
|
-
const MCP_INSTRUCTION_MAX_CHARS = 600;
|
|
28
31
|
|
|
29
32
|
function sanitizeManifestName(name) {
|
|
30
33
|
const text = String(name || '').trim();
|
|
31
34
|
return MANIFEST_NAME_SAFE_RE.test(text) ? text : '';
|
|
32
35
|
}
|
|
33
36
|
|
|
37
|
+
const MCP_INSTRUCTION_MAX_CHARS = 600;
|
|
38
|
+
|
|
39
|
+
/** A server's instruction text without markup, capped at MCP_INSTRUCTION_MAX_CHARS. */
|
|
40
|
+
export function sanitizeMcpInstructionText(text, max = MCP_INSTRUCTION_MAX_CHARS) {
|
|
41
|
+
const stripped = String(text || '')
|
|
42
|
+
.replace(/[<>]/g, '')
|
|
43
|
+
.trim();
|
|
44
|
+
if (!stripped) return '';
|
|
45
|
+
const cap = Math.max(1, Number(max) || MCP_INSTRUCTION_MAX_CHARS);
|
|
46
|
+
return stripped.length > cap ? `${stripped.slice(0, Math.max(1, cap - 3))}...` : stripped;
|
|
47
|
+
}
|
|
48
|
+
|
|
34
49
|
function skillRoutedToolNames(messages) {
|
|
35
50
|
const names = new Set();
|
|
36
51
|
for (const message of Array.isArray(messages) ? messages : []) {
|
|
@@ -63,7 +78,8 @@ function hasDeferredToolManifestBlock(text) {
|
|
|
63
78
|
* wire tools). Each entry is either a bare name string or `{ name, description }`;
|
|
64
79
|
* output lines are `- name: description` (description omitted when absent),
|
|
65
80
|
* mirroring the available-skills manifest so the model calls deferred tools
|
|
66
|
-
* directly. Descriptions are compacted
|
|
81
|
+
* directly. Descriptions are compacted to the skill listing's trigger cap
|
|
82
|
+
* (skill-document.mjs SKILL_TRIGGER_LISTING_MAX) and stripped of `<`/`>`.
|
|
67
83
|
* Empty pool → '' (caller omits the block).
|
|
68
84
|
*/
|
|
69
85
|
export function buildDeferredToolManifest(entries) {
|
|
@@ -77,7 +93,7 @@ export function buildDeferredToolManifest(entries) {
|
|
|
77
93
|
const description =
|
|
78
94
|
typeof entry === 'string'
|
|
79
95
|
? ''
|
|
80
|
-
: compactPromptManifestText(String(entry?.description || '').replace(/[<>]/g, ''),
|
|
96
|
+
: compactPromptManifestText(String(entry?.description || '').replace(/[<>]/g, ''), SKILL_TRIGGER_LISTING_MAX);
|
|
81
97
|
list.push({ name, description });
|
|
82
98
|
}
|
|
83
99
|
if (!list.length) return '';
|
|
@@ -90,49 +106,6 @@ export function buildDeferredToolManifest(entries) {
|
|
|
90
106
|
].join('\n');
|
|
91
107
|
}
|
|
92
108
|
|
|
93
|
-
function sanitizeMcpInstructionText(text, max = MCP_INSTRUCTION_MAX_CHARS) {
|
|
94
|
-
const stripped = String(text || '')
|
|
95
|
-
.replace(/[<>]/g, '')
|
|
96
|
-
.trim();
|
|
97
|
-
if (!stripped) return '';
|
|
98
|
-
const cap = Math.max(1, Number(max) || MCP_INSTRUCTION_MAX_CHARS);
|
|
99
|
-
return stripped.length > cap ? `${stripped.slice(0, Math.max(1, cap - 3))}...` : stripped;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
/**
|
|
103
|
-
* Per-server MCP initialize instructions for deferred-pool tools only.
|
|
104
|
-
* Empty when no instructions or no matching deferred MCP tools → omit block.
|
|
105
|
-
* Emits ONLY the server heading + instruction body: tool names are never
|
|
106
|
-
* listed — <available-deferred-tools> names each server once (mcp__<server>).
|
|
107
|
-
*/
|
|
108
|
-
function buildMcpInstructionsManifest(mcpServerInstructions, poolNames, catalog = []) {
|
|
109
|
-
const map = mcpServerInstructions && typeof mcpServerInstructions === 'object' ? mcpServerInstructions : {};
|
|
110
|
-
const pool = [
|
|
111
|
-
...new Set((Array.isArray(poolNames) ? poolNames : []).map((name) => sanitizeManifestName(name)).filter(Boolean)),
|
|
112
|
-
];
|
|
113
|
-
// Tool definitions carry their server (shortened names cannot be parsed).
|
|
114
|
-
const byName = new Map();
|
|
115
|
-
for (const tool of Array.isArray(catalog) ? catalog : []) {
|
|
116
|
-
const name = String(tool?.name || '').trim();
|
|
117
|
-
if (name && !byName.has(name)) byName.set(name, tool);
|
|
118
|
-
}
|
|
119
|
-
const deferredServers = new Set();
|
|
120
|
-
for (const name of pool) {
|
|
121
|
-
const server = parseMcpToolName(byName.get(name) || name)?.server;
|
|
122
|
-
if (server) deferredServers.add(server);
|
|
123
|
-
}
|
|
124
|
-
const servers = [...deferredServers]
|
|
125
|
-
.filter((server) => sanitizeManifestName(server) && sanitizeMcpInstructionText(map[server]))
|
|
126
|
-
.sort((a, b) => a.localeCompare(b));
|
|
127
|
-
if (!servers.length) return '';
|
|
128
|
-
const lines = ['<mcp-instructions>'];
|
|
129
|
-
for (const server of servers) {
|
|
130
|
-
lines.push(`## ${sanitizeManifestName(server)}`, sanitizeMcpInstructionText(map[server]));
|
|
131
|
-
}
|
|
132
|
-
lines.push('</mcp-instructions>');
|
|
133
|
-
return lines.join('\n');
|
|
134
|
-
}
|
|
135
|
-
|
|
136
109
|
export function stripDeferredToolManifestBlock(text) {
|
|
137
110
|
return String(text || '')
|
|
138
111
|
.replace(DEFERRED_TOOLS_BLOCK_RE, '')
|
|
@@ -144,9 +117,8 @@ export function stripDeferredToolManifestBlock(text) {
|
|
|
144
117
|
// Rebuild path: replace the FIRST previously-injected <available-deferred-tools>
|
|
145
118
|
// block (with its leading `---` separator) with the fresh manifest IN PLACE, so
|
|
146
119
|
// the block keeps its original position and no sibling BP2 block (skills
|
|
147
|
-
// manifest, agent rules, …) is reordered or dropped.
|
|
148
|
-
//
|
|
149
|
-
// removed first to avoid duplication.
|
|
120
|
+
// manifest, agent rules, …) is reordered or dropped. A legacy <mcp-instructions>
|
|
121
|
+
// block left by older sessions is removed first.
|
|
150
122
|
function rebuildDeferredToolManifestBlock(text, manifest) {
|
|
151
123
|
let out = String(text || '').replace(MCP_INSTRUCTIONS_BLOCK_RE, '');
|
|
152
124
|
let replaced = false;
|
|
@@ -183,24 +155,50 @@ const firstSentence = (text) => {
|
|
|
183
155
|
return (flat.split(/(?<=[.!?])\s/, 1)[0] || flat).replace(/[.!?]+$/, '');
|
|
184
156
|
};
|
|
185
157
|
|
|
186
|
-
// A catalog connector's curated trigger; else the
|
|
187
|
-
// else its tools' leading descriptions (name
|
|
188
|
-
//
|
|
158
|
+
// A catalog connector's curated when-to-use trigger; else the first sentence
|
|
159
|
+
// of the server's MCP instructions; else its tools' leading descriptions (name
|
|
160
|
+
// order); else its name. Never the account: that is part of the instruction
|
|
161
|
+
// text delivered when the server's tools are loaded. Derived lines are
|
|
162
|
+
// compacted to at most 98 characters, ellipsis included.
|
|
189
163
|
function mcpServerTrigger(server, tools, instructions) {
|
|
190
|
-
// A multi-account connector's server names its account (connector-accounts.mjs).
|
|
191
|
-
const account = accountOfInstructions(instructions?.[server]);
|
|
192
164
|
const curated = connectorTrigger(server);
|
|
193
|
-
if (curated) return
|
|
194
|
-
|
|
165
|
+
if (curated) return curated;
|
|
166
|
+
// The account sentence ("Account: <address>. …", connector-accounts.mjs) is
|
|
167
|
+
// not a use line; it reaches the model with the loaded server's instructions.
|
|
168
|
+
const instruction = String(instructions?.[server] || '')
|
|
169
|
+
.replace(/[<>]/g, '')
|
|
170
|
+
.replace(/^\s*Account: \S+?\.\s+/, '');
|
|
195
171
|
const described = [...tools]
|
|
196
172
|
.sort((a, b) => String(a?.name || '').localeCompare(String(b?.name || '')))
|
|
197
173
|
.map((tool) => firstSentence(String(tool?.description || '').replace(/[<>]/g, '')))
|
|
198
174
|
.filter(Boolean)
|
|
199
175
|
.join('; ');
|
|
200
|
-
const derived = instruction
|
|
176
|
+
const derived = firstSentence(instruction) || described;
|
|
201
177
|
return derived ? compactPromptManifestText(derived, 98) : `${titleCaseMcpServer(server)} MCP server tools.`;
|
|
202
178
|
}
|
|
203
179
|
|
|
180
|
+
// `mcp__<server>` as the manifest names it, or '' for an unsafe server name.
|
|
181
|
+
export const mcpServerManifestLabel = (server) => sanitizeManifestName(mcpServerLineName(server));
|
|
182
|
+
|
|
183
|
+
/**
|
|
184
|
+
* One `{ label: 'mcp__<server>', trigger }` line per server of `servers` (Map
|
|
185
|
+
* server → its tools). The BP2 manifest and the deferred-tool delta both
|
|
186
|
+
* render these; a server with an unsafe name gets none.
|
|
187
|
+
*/
|
|
188
|
+
export function mcpServerLines(servers, instructions) {
|
|
189
|
+
const lines = [];
|
|
190
|
+
for (const [server, tools] of servers) {
|
|
191
|
+
const label = mcpServerManifestLabel(server);
|
|
192
|
+
if (!label) continue;
|
|
193
|
+
const trigger = compactPromptManifestText(
|
|
194
|
+
String(mcpServerTrigger(server, tools, instructions)).replace(/[<>]/g, ''),
|
|
195
|
+
SKILL_TRIGGER_LISTING_MAX
|
|
196
|
+
);
|
|
197
|
+
lines.push({ label, trigger });
|
|
198
|
+
}
|
|
199
|
+
return lines;
|
|
200
|
+
}
|
|
201
|
+
|
|
204
202
|
function deferredManifestEntries(session, pool) {
|
|
205
203
|
const byName = catalogByName(session);
|
|
206
204
|
const skillRoutedNames = skillRoutedToolNames(session.messages);
|
|
@@ -221,11 +219,8 @@ function deferredManifestEntries(session, pool) {
|
|
|
221
219
|
description: skillRoutedNames.has(key) ? '' : String(tool?.trigger || tool?.description || ''),
|
|
222
220
|
});
|
|
223
221
|
}
|
|
224
|
-
for (const
|
|
225
|
-
entries.push({
|
|
226
|
-
name: mcpServerLineName(server),
|
|
227
|
-
description: mcpServerTrigger(server, tools, session.mcpServerInstructions),
|
|
228
|
-
});
|
|
222
|
+
for (const line of mcpServerLines(servers, session.mcpServerInstructions)) {
|
|
223
|
+
entries.push({ name: line.label, description: line.trigger });
|
|
229
224
|
}
|
|
230
225
|
return entries;
|
|
231
226
|
}
|
|
@@ -241,7 +236,7 @@ export function listedDeferredToolNames(session, poolNames, rendered) {
|
|
|
241
236
|
}
|
|
242
237
|
|
|
243
238
|
function composeDeferredBp2Manifest(session, pool) {
|
|
244
|
-
// Bridge exposure gets the native roster
|
|
239
|
+
// Bridge exposure gets the native roster (the pool is
|
|
245
240
|
// already limited to what the session's policy lets it run), followed by
|
|
246
241
|
// the static bridge guidance. A tool-free bridge session gets nothing.
|
|
247
242
|
const bridge = isToolBridgeEnabled(session);
|
|
@@ -249,8 +244,6 @@ function composeDeferredBp2Manifest(session, pool) {
|
|
|
249
244
|
const parts = [];
|
|
250
245
|
const deferredManifest = buildDeferredToolManifest(deferredManifestEntries(session, pool));
|
|
251
246
|
if (deferredManifest) parts.push(deferredManifest);
|
|
252
|
-
const mcpManifest = buildMcpInstructionsManifest(session.mcpServerInstructions, pool, session.deferredToolCatalog);
|
|
253
|
-
if (mcpManifest) parts.push(mcpManifest);
|
|
254
247
|
if (bridge) parts.push(TOOL_BRIDGE_GUIDANCE);
|
|
255
248
|
return parts.join('\n\n');
|
|
256
249
|
}
|
|
@@ -292,6 +285,18 @@ function resolveDeferredBp2Index(session) {
|
|
|
292
285
|
return idx;
|
|
293
286
|
}
|
|
294
287
|
|
|
288
|
+
/**
|
|
289
|
+
* Give BP2 `stableContext` (profile meta + skill manifest) and no deferred
|
|
290
|
+
* manifest. The caller re-applies that manifest
|
|
291
|
+
* (applyInitialDeferredToolManifestToBp2 with `rebuild`), which appends it
|
|
292
|
+
* after the stable part exactly as session creation laid it out.
|
|
293
|
+
*/
|
|
294
|
+
export function resetBp2StableContext(session, stableContext) {
|
|
295
|
+
if (!Array.isArray(session?.messages)) return;
|
|
296
|
+
const idx = resolveDeferredBp2Index(session);
|
|
297
|
+
if (idx >= 0) setSystemContent(session, idx, String(stableContext || ''));
|
|
298
|
+
}
|
|
299
|
+
|
|
295
300
|
function writeDeferredManifestAt(session, idx, manifest, rebuild) {
|
|
296
301
|
for (let i = 0; i < session.messages.length; i++) {
|
|
297
302
|
if (i === idx || session.messages[i]?.role !== 'system' || typeof session.messages[i].content !== 'string')
|
|
@@ -304,6 +304,31 @@ export function skillOutsideScopeError(name) {
|
|
|
304
304
|
return `Error: skill "${name}" is not available in this project (its project scope excludes the current folder)`;
|
|
305
305
|
}
|
|
306
306
|
|
|
307
|
+
/** Why the Skill tool refuses `name` at `cwd` now (missing feature, switched
|
|
308
|
+
* off, outside the project scope), or null when nothing refuses it. `config`
|
|
309
|
+
* and `skills` let a batch of checks share one config read and one scan. */
|
|
310
|
+
export function skillLoadRefusal(name, cwd, config = null, skills = null) {
|
|
311
|
+
const missing = skillMissingFeature(name, config, skills);
|
|
312
|
+
if (missing) {
|
|
313
|
+
return `Error: skill "${name}" needs the ${missing} built-in feature, which is not installed or is switched off in Extensions → Plugin → Built-in`;
|
|
314
|
+
}
|
|
315
|
+
if (isSkillDisabled(name, config, skills)) return `Error: skill "${name}" is disabled`;
|
|
316
|
+
if (skillOutsideScope(name, cwd, config, skills)) return skillOutsideScopeError(name);
|
|
317
|
+
return null;
|
|
318
|
+
}
|
|
319
|
+
|
|
320
|
+
/**
|
|
321
|
+
* What the Skill tool would deliver for `name` at `cwd` now: the injected
|
|
322
|
+
* `<skill>` body and the resource it came from, or null when the skill no
|
|
323
|
+
* longer loads there (refused by skillLoadRefusal, or removed).
|
|
324
|
+
*/
|
|
325
|
+
export function currentSkillDelivery(name, cwd, config = null, skills = null) {
|
|
326
|
+
if (skillLoadRefusal(name, cwd, config, skills)) return null;
|
|
327
|
+
const resource = loadSkillResource(name, cwd);
|
|
328
|
+
if (!resource) return null;
|
|
329
|
+
return { body: buildSkillResultEnvelope(name, resource.content, resource.dir), resource };
|
|
330
|
+
}
|
|
331
|
+
|
|
307
332
|
/**
|
|
308
333
|
* Skills a session may see: not switched off, feature available, and — when
|
|
309
334
|
* `cwd` is given — inside the skill's (or its plugin's) project scope. Without
|
|
@@ -348,11 +373,16 @@ const _skillsCache = new Map();
|
|
|
348
373
|
// every plain-file gate path are stat'ed on every call as before.
|
|
349
374
|
const _ROOT_WATCH_LIMIT = 64;
|
|
350
375
|
const _rootWatches = new Map(); // root -> { watcher, dirty, text, settled }
|
|
376
|
+
// Bumped by every closed root watch; part of each cached SKILL.md text stamp.
|
|
377
|
+
let _skillTextGeneration = 0;
|
|
351
378
|
|
|
352
379
|
function _closeRootWatch(root) {
|
|
353
380
|
const watch = _rootWatches.get(root);
|
|
354
381
|
if (!watch) return;
|
|
355
382
|
_rootWatches.delete(root);
|
|
383
|
+
// Any change under a skill root (or a lost watcher, or an invalidation)
|
|
384
|
+
// makes the next load re-read SKILL.md text, whatever the file stamps say.
|
|
385
|
+
_skillTextGeneration += 1;
|
|
356
386
|
try {
|
|
357
387
|
watch.watcher.close();
|
|
358
388
|
} catch {
|
|
@@ -452,6 +482,26 @@ export function skillExecutionDir(dir, source) {
|
|
|
452
482
|
return String(dir).replace(/([\\/])runtime\.asar(?=[\\/]|$)/, '$1runtime.asar.unpacked');
|
|
453
483
|
}
|
|
454
484
|
|
|
485
|
+
// SKILL.md text per catalog entry, with the stamp it was read at: the
|
|
486
|
+
// file's own mtime and size (any depth) plus the skills watcher generation
|
|
487
|
+
// (an edit that keeps both, e.g. inside one timestamp tick).
|
|
488
|
+
const _skillFileText = new WeakMap();
|
|
489
|
+
|
|
490
|
+
function skillFileText(skill) {
|
|
491
|
+
let stamp;
|
|
492
|
+
try {
|
|
493
|
+
const stat = statSync(skill.filePath);
|
|
494
|
+
stamp = `${_skillTextGeneration}:${stat.mtimeMs}:${stat.size}`;
|
|
495
|
+
} catch {
|
|
496
|
+
return null;
|
|
497
|
+
}
|
|
498
|
+
const cached = _skillFileText.get(skill);
|
|
499
|
+
if (cached?.stamp === stamp) return cached.text;
|
|
500
|
+
const text = readSafe(skill.filePath);
|
|
501
|
+
_skillFileText.set(skill, { stamp, text });
|
|
502
|
+
return text;
|
|
503
|
+
}
|
|
504
|
+
|
|
455
505
|
/**
|
|
456
506
|
* Load full skill content plus its on-disk directory (for base-dir + ${MIXDOG_SKILL_DIR};
|
|
457
507
|
* ${MIXDOG_SKILL_NODE} is resolved at render time in buildSkillResultEnvelope).
|
|
@@ -462,7 +512,10 @@ export function loadSkillResource(name, cwd) {
|
|
|
462
512
|
const skills = collectSkillsCached(cwd);
|
|
463
513
|
const skill = skills.find((s) => s.name === skillName);
|
|
464
514
|
if (!skill) return null;
|
|
465
|
-
|
|
515
|
+
// The catalog's freshness signature does not see every nested SKILL.md, so
|
|
516
|
+
// the text follows the file itself: one stat per load, re-read only when
|
|
517
|
+
// that file's own mtime or size moved.
|
|
518
|
+
const content = skillFileText(skill);
|
|
466
519
|
if (content == null) return null;
|
|
467
520
|
try {
|
|
468
521
|
return {
|
|
@@ -203,7 +203,7 @@ export function readProjectConnectorsFile(path) {
|
|
|
203
203
|
});
|
|
204
204
|
}
|
|
205
205
|
|
|
206
|
-
|
|
206
|
+
function projectConnectorPolicies(dataDir = resolvePluginData()) {
|
|
207
207
|
return cachedRead(join(dataDir, PROJECT_CONNECTORS_FILE), readProjectConnectorsFile);
|
|
208
208
|
}
|
|
209
209
|
|
|
@@ -219,7 +219,7 @@ export function connectorToolPermission(policy, toolOrName) {
|
|
|
219
219
|
return policy?.tools?.[mcp.server]?.[mcp.tool] || connectorToolDefault(serverConnector(mcp.server), mcp.tool);
|
|
220
220
|
}
|
|
221
221
|
|
|
222
|
-
const PERMISSION_RANK = Object.freeze({ disabled: 0, needs_approval: 1, auto: 2 });
|
|
222
|
+
export const PERMISSION_RANK = Object.freeze({ disabled: 0, needs_approval: 1, auto: 2 });
|
|
223
223
|
export const NO_WIDEN_MESSAGE = 'This change would widen what the bot may do without asking; make it on the desktop.';
|
|
224
224
|
|
|
225
225
|
/** Whether replacing the stored policy `before` (a stored value, a parsed
|
|
@@ -229,7 +229,7 @@ export const NO_WIDEN_MESSAGE = 'This change would widen what the bot may do wit
|
|
|
229
229
|
* default, which is `needs_approval` for a catalog connector's high-risk
|
|
230
230
|
* tools and `auto` otherwise). A legacy allow list or an unreadable policy is
|
|
231
231
|
* not compared: it counts as widening. */
|
|
232
|
-
|
|
232
|
+
function connectorPolicyWidens(before, after) {
|
|
233
233
|
let old;
|
|
234
234
|
try {
|
|
235
235
|
old = before == null ? { off: [], tools: {} } : parseConnectorPolicy(before);
|