mixdog 1.3.0 → 1.3.2
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 +52 -9
- package/README.md +8 -4
- package/package.json +2 -2
- package/scripts/native-release-status.mjs +238 -0
- package/src/defaults/shipped-history.json +8 -1
- package/src/defaults/skills/pptx/scripts/qc-pages.mjs +3 -2
- package/src/defaults/skills/setup/SKILL.md +23 -1
- package/src/defaults/skills/setup/references/actions.md +54 -4
- package/src/defaults/skills/setup/references/surfaces.md +23 -3
- package/src/defaults/skills/setup-guide/SKILL.md +17 -10
- package/src/defaults/skills/visualize/SKILL.md +9 -6
- package/src/defaults/skills/visualize/references/craft.md +8 -1
- package/src/help.mjs +1 -1
- package/src/lib/keychain-cjs.cjs +4 -1
- package/src/lib/rules-builder.cjs +14 -7
- package/src/output-styles/common.md +13 -8
- package/src/rules/agent-mode/AGENT_MODE.md +9 -6
- package/src/rules/agent-mode/MIXY.md +11 -6
- package/src/rules/lead/LEAD.md +2 -2
- package/src/rules/shared/10-tool-workflow.md +4 -0
- package/src/rules/shared/20-research.md +2 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/preset.mjs +5 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-dispatch/session-prep.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/agent-progress-watchdog.mjs +6 -1
- package/src/runtime/agent/orchestrator/agent-runtime/cache-strategy.mjs +114 -26
- package/src/runtime/agent/orchestrator/agent-runtime/maintenance-route.mjs +8 -0
- package/src/runtime/agent/orchestrator/agent-runtime/room-supervisor-completion.mjs +5 -4
- package/src/runtime/agent/orchestrator/agent-trace.mjs +3 -0
- package/src/runtime/agent/orchestrator/cache-break-trace.mjs +4 -0
- package/src/runtime/agent/orchestrator/config-presets.mjs +2 -0
- package/src/runtime/agent/orchestrator/config-storage.mjs +10 -3
- package/src/runtime/agent/orchestrator/config.mjs +11 -0
- package/src/runtime/agent/orchestrator/context/role-instructions.mjs +81 -16
- package/src/runtime/agent/orchestrator/mcp/agent-connectors.mjs +97 -4
- package/src/runtime/agent/orchestrator/mcp/child-tree.mjs +6 -10
- package/src/runtime/agent/orchestrator/mcp/client.mjs +7 -4
- package/src/runtime/agent/orchestrator/providers/anthropic-api-request.mjs +80 -31
- package/src/runtime/agent/orchestrator/providers/anthropic-model-resolve.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth-client-version.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/anthropic-oauth.mjs +67 -38
- package/src/runtime/agent/orchestrator/providers/anthropic-turn-result.mjs +2 -0
- package/src/runtime/agent/orchestrator/providers/antigravity-oauth-catalog.mjs +7 -2
- package/src/runtime/agent/orchestrator/providers/antigravity-request.mjs +6 -2
- package/src/runtime/agent/orchestrator/providers/auto-effort.mjs +34 -16
- package/src/runtime/agent/orchestrator/providers/cursor-wire.mjs +31 -4
- package/src/runtime/agent/orchestrator/providers/cursor.mjs +4 -1
- package/src/runtime/agent/orchestrator/providers/custom-provider.mjs +11 -8
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-prefix-trace.mjs +76 -0
- package/src/runtime/agent/orchestrator/providers/lib/anthropic-request-utils.mjs +19 -1
- package/src/runtime/agent/orchestrator/providers/lib/tail-reminder-split.mjs +13 -0
- package/src/runtime/agent/orchestrator/providers/lib/tool-call-wire-ids.mjs +65 -0
- package/src/runtime/agent/orchestrator/providers/media-normalization.mjs +16 -1
- package/src/runtime/agent/orchestrator/providers/mixdog-local.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/model-proxy-provider.mjs +1 -0
- package/src/runtime/agent/orchestrator/providers/openai-codex-metadata.mjs +5 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-models.mjs +9 -5
- package/src/runtime/agent/orchestrator/providers/openai-compat-responses.mjs +9 -1
- package/src/runtime/agent/orchestrator/providers/openai-compat-retry-profile.mjs +8 -2
- package/src/runtime/agent/orchestrator/providers/openai-compat-wire.mjs +10 -2
- package/src/runtime/agent/orchestrator/providers/openai-direct-request.mjs +30 -3
- package/src/runtime/agent/orchestrator/providers/openai-model-capabilities.mjs +1 -1
- package/src/runtime/agent/orchestrator/providers/openai-responses-input.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/openai-ws.mjs +3 -1
- package/src/runtime/agent/orchestrator/providers/opencode-go-oauth.mjs +61 -8
- package/src/runtime/agent/orchestrator/providers/provider-error-kind.mjs +14 -2
- package/src/runtime/agent/orchestrator/providers/registry.mjs +9 -0
- package/src/runtime/agent/orchestrator/providers/retry-executor.mjs +17 -0
- package/src/runtime/agent/orchestrator/runtime-core/config-helpers.mjs +90 -24
- package/src/runtime/agent/orchestrator/runtime-core/fs-utils.mjs +8 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-mutations.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/goal-storage.mjs +68 -22
- package/src/runtime/agent/orchestrator/runtime-core/goal-tool-exec.mjs +1 -1
- package/src/runtime/agent/orchestrator/runtime-core/orchestration.mjs +5 -5
- package/src/runtime/agent/orchestrator/runtime-core/route-context-state.mjs +81 -0
- package/src/runtime/agent/orchestrator/runtime-core/session-text.mjs +2 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-catalog.mjs +12 -1
- package/src/runtime/agent/orchestrator/runtime-core/tool-defs.mjs +17 -6
- package/src/runtime/agent/orchestrator/runtime-core/workflow/agents.mjs +41 -10
- package/src/runtime/agent/orchestrator/runtime-core/workflow/context.mjs +6 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow/packs.mjs +8 -4
- package/src/runtime/agent/orchestrator/runtime-core/workflow.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/agent-mode.mjs +0 -6
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.d.mts +1 -1
- package/src/runtime/agent/orchestrator/session/agent-room-supervisor.mjs +22 -4
- package/src/runtime/agent/orchestrator/session/agent-room.d.mts +21 -2
- package/src/runtime/agent/orchestrator/session/agent-room.mjs +149 -45
- package/src/runtime/agent/orchestrator/session/attachment-preflight.mjs +80 -0
- package/src/runtime/agent/orchestrator/session/catalog-db/schema.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/compact/execution-tail.mjs +14 -11
- package/src/runtime/agent/orchestrator/session/compact/forked-summary.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/compact/runner.mjs +68 -18
- package/src/runtime/agent/orchestrator/session/compact/summary-mode.mjs +16 -0
- package/src/runtime/agent/orchestrator/session/compact/summary-route.mjs +87 -0
- package/src/runtime/agent/orchestrator/session/compact/summary.mjs +2 -0
- package/src/runtime/agent/orchestrator/session/compact/text-utils.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/compact/user-message-kind.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/compaction-archive-capture.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/context-utils.mjs +41 -10
- package/src/runtime/agent/orchestrator/session/human-gate/delegation.mjs +230 -0
- package/src/runtime/agent/orchestrator/session/human-gate/gate.mjs +156 -25
- package/src/runtime/agent/orchestrator/session/human-gate/outbound-policy.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/human-gate/requests.mjs +21 -9
- package/src/runtime/agent/orchestrator/session/human-gate/run-policy.mjs +73 -0
- package/src/runtime/agent/orchestrator/session/human-gate/store.mjs +55 -27
- package/src/runtime/agent/orchestrator/session/human-gate/unattended-port.mjs +15 -0
- package/src/runtime/agent/orchestrator/session/loop/compact-policy.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/loop/fresh-context.mjs +189 -105
- package/src/runtime/agent/orchestrator/session/loop/loop-state.mjs +9 -0
- package/src/runtime/agent/orchestrator/session/loop/pre-dispatch-deny.mjs +6 -2
- package/src/runtime/agent/orchestrator/session/loop/route-fallback.mjs +111 -9
- package/src/runtime/agent/orchestrator/session/loop/send-phase.mjs +11 -14
- package/src/runtime/agent/orchestrator/session/loop/steering.mjs +3 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/before-hook.mjs +38 -5
- package/src/runtime/agent/orchestrator/session/loop/tool-exec/dispatch.mjs +21 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-exec.mjs +2 -1
- package/src/runtime/agent/orchestrator/session/loop/tool-exposure-migration.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/loop/tool-helpers.mjs +11 -5
- package/src/runtime/agent/orchestrator/session/loop/usage.mjs +46 -4
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-auto-effort.mjs +13 -2
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-commit.mjs +18 -8
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-execute.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-prepare.mjs +6 -0
- package/src/runtime/agent/orchestrator/session/manager/ask-turn-settle.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/manager/compaction-runner.mjs +44 -18
- package/src/runtime/agent/orchestrator/session/manager/orchestration-mode-switch-notice.mjs +99 -0
- package/src/runtime/agent/orchestrator/session/manager/owner-route-fallbacks.mjs +42 -0
- package/src/runtime/agent/orchestrator/session/manager/pending-messages.mjs +3 -9
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-file.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/pending-spool-shard.mjs +5 -3
- package/src/runtime/agent/orchestrator/session/manager/provider-replay.mjs +50 -0
- package/src/runtime/agent/orchestrator/session/manager/rules-cache.mjs +40 -1
- package/src/runtime/agent/orchestrator/session/manager/runtime-liveness.mjs +12 -0
- package/src/runtime/agent/orchestrator/session/manager/runtime-state.mjs +20 -0
- package/src/runtime/agent/orchestrator/session/manager/session-lifecycle.mjs +62 -47
- package/src/runtime/agent/orchestrator/session/manager/session-prompt-composition.mjs +6 -8
- package/src/runtime/agent/orchestrator/session/manager/session-record.mjs +12 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint-journal.mjs +6 -15
- package/src/runtime/agent/orchestrator/session/manager/turn-checkpoint.mjs +7 -1
- package/src/runtime/agent/orchestrator/session/manager/turn-interruption.mjs +24 -8
- package/src/runtime/agent/orchestrator/session/manager/usage-metrics.mjs +1 -1
- package/src/runtime/agent/orchestrator/session/manager/workflow-switch-notice.mjs +94 -13
- package/src/runtime/agent/orchestrator/session/mixy-name.mjs +5 -2
- package/src/runtime/agent/orchestrator/session/pre-send-compact.mjs +42 -10
- package/src/runtime/agent/orchestrator/session/provider-prefix-guard.mjs +21 -3
- package/src/runtime/agent/orchestrator/session/routine-result.d.mts +35 -4
- package/src/runtime/agent/orchestrator/session/routine-result.mjs +179 -16
- package/src/runtime/agent/orchestrator/session/send-with-recovery.mjs +5 -1
- package/src/runtime/agent/orchestrator/session/side-question-store.mjs +3 -1
- package/src/runtime/agent/orchestrator/session/store/canonical-reader.mjs +41 -7
- package/src/runtime/agent/orchestrator/session/store/lifecycle-barriers.mjs +10 -2
- package/src/runtime/agent/orchestrator/session/store/load-cache.mjs +14 -2
- package/src/runtime/agent/orchestrator/session/store/session-delete.mjs +15 -1
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-record.mjs +8 -3
- package/src/runtime/agent/orchestrator/session/store/sweep/sweep-row.mjs +36 -1
- package/src/runtime/agent/orchestrator/session/store-summary-catalog.mjs +4 -1
- package/src/runtime/agent/orchestrator/session/store-summary-index.mjs +40 -5
- package/src/runtime/agent/orchestrator/session/store-summary-last-message.mjs +47 -2
- package/src/runtime/agent/orchestrator/session/tail-reminder-rules.mjs +125 -0
- package/src/runtime/agent/orchestrator/session/tool-batch/finalize.mjs +4 -0
- package/src/runtime/agent/orchestrator/session/tool-result-offload.mjs +78 -43
- package/src/runtime/agent/orchestrator/session/transcript-restore/restore.mjs +49 -14
- package/src/runtime/agent/orchestrator/session/transcript-restore/user-text.mjs +134 -17
- package/src/runtime/agent/orchestrator/tools/builtin/advisory-lock.mjs +35 -13
- package/src/runtime/agent/orchestrator/tools/builtin/atomic-write.mjs +25 -5
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/backgrounded-result.mjs +4 -3
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/completed-result.mjs +13 -14
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool/transport-artifacts.mjs +9 -0
- package/src/runtime/agent/orchestrator/tools/builtin/bash-tool.mjs +19 -14
- package/src/runtime/agent/orchestrator/tools/builtin/builtin-tools.mjs +7 -1
- package/src/runtime/agent/orchestrator/tools/builtin/lib/shell-job-records.mjs +6 -14
- package/src/runtime/agent/orchestrator/tools/builtin/pdf-test-fixtures.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/builtin/read-image.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-single-media.mjs +47 -2
- package/src/runtime/agent/orchestrator/tools/builtin/read-special-files.mjs +264 -87
- package/src/runtime/agent/orchestrator/tools/builtin/shell-analysis.mjs +10 -4
- package/src/runtime/agent/orchestrator/tools/builtin/shell-jobs.mjs +34 -21
- package/src/runtime/agent/orchestrator/tools/code-graph/constants.mjs +8 -4
- package/src/runtime/agent/orchestrator/tools/lib/shell-descendants.mjs +9 -30
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-settle.mjs +24 -12
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-spawn.mjs +3 -2
- package/src/runtime/agent/orchestrator/tools/lib/shell-run-state.mjs +6 -2
- package/src/runtime/agent/orchestrator/tools/patch/delete-quarantine.mjs +2 -1
- package/src/runtime/agent/orchestrator/tools/patch/replay-capture.mjs +4 -2
- package/src/runtime/agent/orchestrator/tools/patch/rollback-state.mjs +33 -2
- package/src/runtime/agent/orchestrator/tools/patch-manifest.json +13 -13
- package/src/runtime/agent/orchestrator/tools/shell-command.mjs +5 -3
- package/src/runtime/agent/orchestrator/tools/shell-exec-output.mjs +3 -1
- package/src/runtime/attachments/attachment-reference.mjs +155 -0
- package/src/runtime/attachments/limits.mjs +5 -1
- package/src/runtime/attachments/office-extract.mjs +3 -6
- package/src/runtime/attachments/pdf-extract.mjs +84 -10
- package/src/runtime/attachments/store.mjs +55 -30
- package/src/runtime/browser-bridge/client.mjs +73 -20
- package/src/runtime/channels/lib/runtime-paths.mjs +1 -1
- package/src/runtime/channels/lib/scheduler.mjs +14 -7
- package/src/runtime/channels/lib/state-file.mjs +15 -15
- package/src/runtime/channels/lib/voice-runtime-fetcher.mjs +14 -13
- package/src/runtime/channels/lib/webhook/relay-tunnel.mjs +22 -18
- package/src/runtime/channels/lib/webhook/session-dispatch.mjs +14 -36
- package/src/runtime/channels/lib/worker-main.mjs +3 -2
- package/src/runtime/effort-judge/compact-tokenizer.mjs +8 -2
- package/src/runtime/effort-judge/judge-client.mjs +6 -3
- package/src/runtime/effort-judge/model-install.mjs +16 -8
- package/src/runtime/effort-judge/model-manifest.json +7 -7
- package/src/runtime/local-provider/asset-installer.mjs +10 -4
- package/src/runtime/local-provider/catalog.mjs +5 -2
- package/src/runtime/local-provider/registered-models.mjs +64 -27
- package/src/runtime/local-provider/server.mjs +2 -3
- package/src/runtime/media/adapters/image-api.mjs +89 -0
- package/src/runtime/media/auth.mjs +64 -1
- package/src/runtime/media/catalog.mjs +66 -4
- package/src/runtime/media/jobs.mjs +4 -0
- package/src/runtime/media/lanes.mjs +46 -5
- package/src/runtime/media/media-usage.mjs +17 -0
- package/src/runtime/media/renditions.mjs +15 -15
- package/src/runtime/media/store.mjs +36 -35
- package/src/runtime/media/tool.mjs +8 -1
- package/src/runtime/memory/lib/cycle-scheduler/health-ledger.mjs +8 -2
- package/src/runtime/memory/lib/embedding-model-files.mjs +30 -7
- package/src/runtime/memory/lib/ingest/transcript-tail.mjs +16 -7
- package/src/runtime/memory/lib/pg/process.mjs +8 -4
- package/src/runtime/memory/lib/project-id-resolver.mjs +5 -1
- package/src/runtime/memory/lib/runtime-fetcher.mjs +6 -1
- package/src/runtime/office/core/journal.mjs +7 -14
- package/src/runtime/office/design/library/design-library-core.mjs +4 -16
- package/src/runtime/office/pdf/ocr-engine-worker.mjs +37 -0
- package/src/runtime/office/pdf/ocr-engine.mjs +146 -0
- package/src/runtime/office/pdf/pdf-ocr.mjs +51 -21
- package/src/runtime/office/pdf/pdf-render.mjs +30 -18
- package/src/runtime/office/portable/ooxml-validator.mjs +2 -2
- package/src/runtime/office/portable/portable-soffice.mjs +4 -0
- package/src/runtime/shared/agent-kind-migration.mjs +200 -0
- package/src/runtime/shared/agent-kind.mjs +152 -0
- package/src/runtime/shared/agent-message-envelope.d.mts +6 -0
- package/src/runtime/shared/agent-message-envelope.mjs +44 -0
- package/src/runtime/shared/agent-reap-state.d.mts +4 -0
- package/src/runtime/shared/agent-route-config.d.mts +1 -0
- package/src/runtime/shared/agent-route-config.mjs +22 -8
- package/src/runtime/shared/agent-store.mjs +149 -0
- package/src/runtime/shared/agent-task-starts.mjs +27 -0
- package/src/runtime/shared/atomic-file.d.mts +50 -0
- package/src/runtime/shared/atomic-file.mjs +394 -132
- package/src/runtime/shared/background-tasks.mjs +7 -4
- package/src/runtime/shared/bot-hops.mjs +30 -0
- package/src/runtime/shared/bot-split-migration.mjs +457 -0
- package/src/runtime/shared/bounded-download.mjs +4 -2
- package/src/runtime/shared/config-patch.mjs +20 -1
- package/src/runtime/shared/config.mjs +39 -9
- package/src/runtime/shared/connector-catalog.d.mts +1 -2
- package/src/runtime/shared/connector-catalog.mjs +2 -4
- package/src/runtime/shared/connector-triggers.mjs +2 -0
- package/src/runtime/shared/defaults-separation.mjs +6 -2
- package/src/runtime/shared/delegated-approval-host.mjs +74 -0
- package/src/runtime/shared/err-text.mjs +7 -1
- package/src/runtime/shared/error-presentation.mjs +113 -10
- package/src/runtime/shared/file-has-data.mjs +28 -0
- package/src/runtime/shared/handoff-artifacts.d.mts +20 -0
- package/src/runtime/shared/handoff-artifacts.mjs +61 -0
- package/src/runtime/shared/llm/provider-model-identities.mjs +6 -1
- package/src/runtime/shared/llm/usage-accounting.mjs +7 -1
- package/src/runtime/shared/llm/usage-ledger-import.mjs +37 -18
- package/src/runtime/shared/model-route-fallback.mjs +79 -7
- package/src/runtime/shared/pending-agent-work.mjs +54 -0
- package/src/runtime/shared/plain-preview.mjs +22 -17
- package/src/runtime/shared/process-lifecycle.mjs +8 -12
- package/src/runtime/shared/projects.mjs +50 -41
- package/src/runtime/shared/provider-accounts.mjs +17 -12
- package/src/runtime/shared/routine-trigger.d.mts +6 -1
- package/src/runtime/shared/routine-trigger.mjs +14 -6
- package/src/runtime/shared/run-child.d.mts +3 -0
- package/src/runtime/shared/run-child.mjs +24 -3
- package/src/runtime/shared/sensitive-path-rules.d.mts +15 -0
- package/src/runtime/shared/sensitive-path-rules.mjs +256 -0
- package/src/runtime/shared/session-baseline-store.mjs +8 -2
- package/src/runtime/shared/singleton-owner.mjs +7 -6
- package/src/runtime/shared/skill-tool-dependencies.mjs +4 -10
- package/src/runtime/shared/staged-update.mjs +4 -2
- package/src/runtime/shared/statusline/statusline-segments.mjs +4 -15
- package/src/runtime/shared/tool-execution-contract.mjs +6 -0
- package/src/runtime/shared/transcript-metadata.mjs +28 -3
- package/src/runtime/shared/transcript-writer/session-record.mjs +7 -6
- package/src/runtime/shared/turn-snapshot-store.mjs +5 -4
- package/src/runtime/shared/turn-snapshot.mjs +44 -2
- package/src/runtime/shared/usage-readout-totals.mjs +15 -13
- package/src/runtime/shared/user-cwd.mjs +9 -4
- package/src/runtime/shared/user-data-guard.mjs +46 -44
- package/src/runtime/shared/utf8-cut.mjs +10 -0
- package/src/runtime/shared/worktrees/activity-gate.mjs +269 -61
- package/src/runtime/shared/worktrees/registry.mjs +26 -26
- package/src/runtime/tidy/core-install.mjs +26 -4
- package/src/runtime/tidy/install.mjs +91 -23
- package/src/runtime/web-search/lib/config.mjs +4 -16
- package/src/session-runtime/agent-home-delivery.mjs +859 -136
- package/src/session-runtime/agent-room-delivery.mjs +167 -19
- package/src/session-runtime/agent-task-sessions.mjs +831 -69
- package/src/session-runtime/agent-tool-routing.mjs +1 -0
- package/src/session-runtime/boot/apis.mjs +58 -24
- package/src/session-runtime/boot/config.mjs +1 -0
- package/src/session-runtime/boot/facade.mjs +11 -1
- package/src/session-runtime/boot/infrastructure.mjs +14 -2
- package/src/session-runtime/boot/providers.mjs +16 -6
- package/src/session-runtime/boot/shared.mjs +12 -6
- package/src/session-runtime/boot/tools.mjs +2 -2
- package/src/session-runtime/bot-status.mjs +432 -0
- package/src/session-runtime/config-lifecycle/lead-route-sync.mjs +29 -0
- package/src/session-runtime/config-lifecycle.mjs +78 -32
- package/src/session-runtime/cwd-plugins/core-memory-context.mjs +2 -4
- package/src/session-runtime/handoff-attachments.mjs +593 -0
- package/src/session-runtime/held-requests.mjs +36 -33
- package/src/session-runtime/internal-tool-executor/bridge-tools.mjs +10 -1
- package/src/session-runtime/internal-tool-executor/feature-tools.mjs +2 -2
- package/src/session-runtime/internal-tool-executor/workspace-tools.mjs +45 -6
- package/src/session-runtime/lifecycle/session-catalog.mjs +12 -2
- package/src/session-runtime/lifecycle/teardown.mjs +11 -3
- package/src/session-runtime/mcp-glue/connect.mjs +100 -186
- package/src/session-runtime/mcp-glue/initial-connect-gate.mjs +57 -0
- package/src/session-runtime/mcp-glue/server-connection.mjs +71 -0
- package/src/session-runtime/media-api.mjs +5 -2
- package/src/session-runtime/model-route/route-persist.mjs +2 -2
- package/src/session-runtime/model-route/route-tuning.mjs +11 -2
- package/src/session-runtime/model-route/set-route.mjs +82 -2
- package/src/session-runtime/native-web-search.mjs +2 -2
- package/src/session-runtime/new-session-config.mjs +6 -1
- package/src/session-runtime/owned-automation-run.mjs +8 -1
- package/src/session-runtime/room-member-gate.mjs +16 -3
- package/src/session-runtime/route-resolution.mjs +21 -19
- package/src/session-runtime/route-state.mjs +1 -59
- package/src/session-runtime/routine-home-turn.mjs +5 -3
- package/src/session-runtime/runtime-bootstrap.mjs +5 -3
- package/src/session-runtime/runtime-paths.mjs +11 -5
- package/src/session-runtime/runtime-tunables.mjs +6 -0
- package/src/session-runtime/services/agent-tool/close-flow/close-all.mjs +11 -2
- package/src/session-runtime/services/agent-tool/close-flow.mjs +4 -2
- package/src/session-runtime/services/agent-tool/execute-send.mjs +1 -0
- package/src/session-runtime/services/agent-tool/execute-spawn.mjs +1 -0
- package/src/session-runtime/services/agent-tool/helpers.mjs +24 -5
- package/src/session-runtime/services/agent-tool/restart-notify.mjs +10 -0
- package/src/session-runtime/services/agent-tool/send-flow.mjs +36 -24
- package/src/session-runtime/services/agent-tool/spawn-flow/job-start.mjs +4 -0
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-prep.mjs +6 -3
- package/src/session-runtime/services/agent-tool/spawn-flow/spawn-run.mjs +12 -6
- package/src/session-runtime/services/agent-tool/spawn-preset.mjs +5 -8
- package/src/session-runtime/services/agent-tool/tool-def.mjs +7 -0
- package/src/session-runtime/services/agent-tool/worker-index/row-liveness.mjs +22 -2
- package/src/session-runtime/services/agent-tool/worker-index.mjs +4 -6
- package/src/session-runtime/services/agent-tool.mjs +6 -0
- package/src/session-runtime/services/daemon-crash-capture/daemon-exit-record.mjs +1 -1
- package/src/session-runtime/services/daemon-crash-capture/retention.mjs +4 -3
- package/src/session-runtime/services/hook-bus/config-loader.mjs +14 -5
- package/src/session-runtime/services/hook-bus/rule-file.mjs +49 -11
- package/src/session-runtime/services/plugin-admin.mjs +26 -26
- package/src/session-runtime/services/provider-admin.mjs +14 -4
- package/src/session-runtime/services/schedule-access.mjs +33 -4
- package/src/session-runtime/services/seeds.mjs +4 -3
- package/src/session-runtime/services/usage-dashboard.mjs +1 -1
- package/src/session-runtime/services/usage-stats-model.mjs +2 -1
- package/src/session-runtime/session-create/materialize.mjs +2 -3
- package/src/session-runtime/session-create/session-options.mjs +15 -2
- package/src/session-runtime/settings-builtin-tools-api.mjs +63 -1
- package/src/session-runtime/settings-compaction-api.mjs +86 -39
- package/src/session-runtime/setup-tool/executor.mjs +20 -3
- package/src/session-runtime/setup-tool/extended-actions.mjs +19 -7
- package/src/session-runtime/setup-tool/settings-contract.mjs +37 -1
- package/src/session-runtime/setup-tool/tool-defs.mjs +20 -3
- package/src/session-runtime/skills-api.mjs +12 -5
- package/src/session-runtime/tool-policy/agent-profile-fold.mjs +265 -0
- package/src/session-runtime/tool-policy/mode-switch.mjs +54 -0
- package/src/session-runtime/tool-policy/pending-switches.mjs +59 -0
- package/src/session-runtime/tool-policy/policy-stage.mjs +165 -0
- package/src/session-runtime/tool-policy/session-switches.mjs +169 -0
- package/src/session-runtime/tool-policy/surface-helpers.mjs +114 -0
- package/src/session-runtime/tool-policy/workflow-overlay.mjs +145 -0
- package/src/session-runtime/tool-policy-refresh.mjs +47 -358
- package/src/session-runtime/tool-surface.mjs +5 -3
- package/src/session-runtime/turn/turn-run/turn-prepare.mjs +99 -81
- package/src/session-runtime/turn/turn-run/turn-timing.mjs +4 -3
- package/src/session-runtime/turn/turn-run.mjs +2 -1
- package/src/session-runtime/workflow-agents-api/agent-connectors.mjs +54 -7
- package/src/session-runtime/workflow-agents-api/agent-editor.mjs +578 -301
- package/src/session-runtime/workflow-agents-api/agent-route.mjs +113 -53
- package/src/session-runtime/workflow-agents-api/onboarding.mjs +11 -4
- package/src/session-runtime/workflow-agents-api/shared.mjs +5 -1
- package/src/session-runtime/workflow-agents-api/style-and-mode.mjs +14 -1
- package/src/session-runtime/workflow-agents-api/workflow-packs.mjs +6 -3
- package/src/session-runtime/workspace/workspace-state.mjs +7 -6
- package/src/standalone/daemon-agent-control.mjs +4 -1
- package/src/standalone/daemon-session-control.mjs +60 -11
- package/src/standalone/daemon.mjs +34 -4
- package/src/standalone/local-session-runtime.mjs +22 -14
- package/src/standalone/session-client.mjs +7 -2
- package/src/standalone/session-protocol.mjs +7 -0
- package/src/standalone/session-service/agent-tree/agent-turns.mjs +46 -3
- package/src/standalone/session-service/agent-tree.mjs +4 -3
- package/src/standalone/session-service/session-calls/session-turns.mjs +19 -0
- package/src/standalone/session-service.mjs +11 -0
- package/src/standalone/session-state-projection.mjs +19 -9
- package/src/standalone/session-tool-output.mjs +35 -9
- package/src/tui/app/maintenance-pickers/auto-clear-picker.mjs +19 -13
- package/src/tui/app/settings-picker/settings-rows.mjs +2 -2
- package/src/tui/app/slash-commands.mjs +1 -1
- package/src/tui/app/usage-context-panels/context-model.mjs +8 -2
- package/src/tui/dist/index.mjs +599 -342
- package/src/tui/prompt-history-store.mjs +16 -21
- package/src/tui/session/context-state.mjs +4 -0
- package/src/tui/session/notice-surface.mjs +3 -4
- package/src/tui/session/session-api/intake/abort.mjs +19 -1
- package/src/tui/session/session-api/media.mjs +2 -1
- package/src/tui/session/session-api/routes-agent-definitions.mjs +75 -0
- package/src/tui/session/session-api/routes-write.mjs +203 -0
- package/src/tui/session/session-api/routes.mjs +23 -236
- package/src/tui/session/session-api/settings.mjs +14 -1
- package/src/tui/session/session-flow/drain.mjs +28 -3
- package/src/tui/session/session-flow/failed-turn-rewind.mjs +4 -2
- package/src/tui/session/session-flow/queue/take-entries.mjs +8 -0
- package/src/tui/session/session-flow/steering.mjs +8 -3
- package/src/tui/session/tool-approval.mjs +185 -20
- package/src/tui/session/transcript-intake.mjs +4 -0
- package/src/tui/session/turn-live-call.mjs +11 -3
- package/src/tui/session/turn.mjs +36 -17
- package/src/tui/transcript-tool-failures.mjs +8 -2
- package/src/vendor/statusline/src/gateway/route-meta.mjs +7 -8
- package/src/vendor/statusline/src/gateway/session-routes.mjs +6 -7
- package/src/rules/agent-mode/ROUTINE.md +0 -6
|
@@ -9,7 +9,20 @@ import { readAgentFrontmatterPermission } from '../services/agent-tool/helpers.m
|
|
|
9
9
|
import { LEAD_DISALLOWED_TOOLS } from '../../runtime/agent/orchestrator/runtime-core/tool-defs.mjs';
|
|
10
10
|
import { HEADLESS_TOOL_PROFILE } from '../../runtime/agent/orchestrator/runtime-core/tool-profile.mjs';
|
|
11
11
|
import { AGENT_MODE, resolveSessionMode } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
|
|
12
|
-
import { MIXY_AGENT_ID } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
12
|
+
import { MIXY_AGENT_ID, agentIdOfHomeSession } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
13
|
+
import { roomMemberOfSession } from '../../runtime/agent/orchestrator/session/agent-room.mjs';
|
|
14
|
+
import { unattendedApprovalPort } from '../../runtime/agent/orchestrator/session/human-gate/gate.mjs';
|
|
15
|
+
|
|
16
|
+
/** Where a bot created its task session, recorded after its id in the
|
|
17
|
+
* session's `sourceName` (`agent:<id>@home|room|run`): the desktop lets the
|
|
18
|
+
* task act as the bot (its standing allows, "always allow") only when it came
|
|
19
|
+
* from the bot's own attended chat. None when the origin is anything else. */
|
|
20
|
+
function taskOriginSuffix(taskOrigin) {
|
|
21
|
+
const from = clean(taskOrigin?.sessionId);
|
|
22
|
+
if (roomMemberOfSession(from)) return '@room';
|
|
23
|
+
if (unattendedApprovalPort()?.runOf?.(from)) return '@run';
|
|
24
|
+
return agentIdOfHomeSession(from) === clean(taskOrigin?.agentId) ? '@home' : '';
|
|
25
|
+
}
|
|
13
26
|
|
|
14
27
|
// Ownership and permission fields an agent-owned session inherits from its profile.
|
|
15
28
|
function agentOwnedSessionFields(sessionProfile) {
|
|
@@ -83,7 +96,7 @@ export function sessionOptions(deps, coreMemoryContext) {
|
|
|
83
96
|
sourceName: agentOwned
|
|
84
97
|
? sessionProfile?.sourceName || sessionProfile?.agent || 'agent'
|
|
85
98
|
: taskOrigin
|
|
86
|
-
? `agent:${taskOrigin.agentId}`
|
|
99
|
+
? `agent:${taskOrigin.agentId}${taskOriginSuffix(taskOrigin)}`
|
|
87
100
|
: 'main',
|
|
88
101
|
...(taskOrigin ? { taskOrigin } : {}),
|
|
89
102
|
...(rt.approvalMode ? { approvalMode: rt.approvalMode } : {}),
|
|
@@ -8,8 +8,10 @@ import {
|
|
|
8
8
|
setBuiltinInstalledInConfig,
|
|
9
9
|
} from '../runtime/agent/orchestrator/runtime-core/builtin-features.mjs';
|
|
10
10
|
import { featureEnvOverride, moduleEnabled } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
11
|
+
import { normalizeAgentAvatar } from '../runtime/shared/agent-avatar.mjs';
|
|
11
12
|
import { LOCAL_PROVIDER_ID } from '../runtime/local-provider/managed-runtime.mjs';
|
|
12
13
|
import { INSTRUCTION_FILES_MODES, normalizeInstructionFilesMode } from '../runtime/shared/instruction-files-mode.mjs';
|
|
14
|
+
import { AUTO_EFFORT_BASES, autoEffortBase } from '../runtime/agent/orchestrator/providers/auto-effort.mjs';
|
|
13
15
|
import { getEmbeddingInfo } from '../runtime/memory/lib/embedding-provider.mjs';
|
|
14
16
|
import { onnxRuntimeSupported } from '../runtime/shared/onnx-runtime-support.mjs';
|
|
15
17
|
import {
|
|
@@ -21,6 +23,14 @@ import {
|
|
|
21
23
|
shutdownEffortJudge,
|
|
22
24
|
} from '../runtime/effort-judge/judge-client.mjs';
|
|
23
25
|
|
|
26
|
+
const MAX_BOT_ORDER_IDS = 500;
|
|
27
|
+
const isBotOrderId = (id) => typeof id === 'string' && id.trim().length > 0 && id.trim().length <= 128;
|
|
28
|
+
/** A stored bot order as trimmed, de-duplicated ids; anything else is no order (null). */
|
|
29
|
+
function normalizeBotOrder(value) {
|
|
30
|
+
if (!Array.isArray(value)) return null;
|
|
31
|
+
return [...new Set(value.filter(isBotOrderId).map((id) => id.trim()))].slice(0, MAX_BOT_ORDER_IDS);
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
const TOGGLEABLE_BUILTINS = ['git', 'office', 'tidy', 'localProvider', 'autoEffort', 'visualize', 'media'];
|
|
25
35
|
|
|
26
36
|
function setLocalProviderEnabledInConfig(configLike, enabled) {
|
|
@@ -85,12 +95,50 @@ export function createBuiltinToolSettings(
|
|
|
85
95
|
saveConfigAndAdopt({ ...getConfig(), aiSessionTitles: enabled !== false });
|
|
86
96
|
return this.getSessionTitleSettings();
|
|
87
97
|
},
|
|
98
|
+
// The one pixel face every Lead row on the bot page wears, shared by every
|
|
99
|
+
// device that follows this host. Only a mascot look counts; null (the
|
|
100
|
+
// default grey pup) is stored as no key.
|
|
101
|
+
getLeadAppearance() {
|
|
102
|
+
const avatar = normalizeAgentAvatar(getConfig()?.leadAvatar);
|
|
103
|
+
return { avatar: avatar?.kind === 'mascot' ? avatar : null };
|
|
104
|
+
},
|
|
105
|
+
setLeadAppearance(avatar) {
|
|
106
|
+
const config = { ...getConfig() };
|
|
107
|
+
if (avatar == null) {
|
|
108
|
+
delete config.leadAvatar;
|
|
109
|
+
} else {
|
|
110
|
+
const normalized = normalizeAgentAvatar(avatar);
|
|
111
|
+
if (normalized?.kind !== 'mascot') throw new Error('usage: setLeadAppearance(a mascot appearance or null)');
|
|
112
|
+
config.leadAvatar = normalized;
|
|
113
|
+
}
|
|
114
|
+
saveConfigAndAdopt(config);
|
|
115
|
+
return this.getLeadAppearance();
|
|
116
|
+
},
|
|
117
|
+
// The one bot order every device that follows this host shows (Bots page
|
|
118
|
+
// and the Sessions bot section): agent ids only. Mixy is pinned first by
|
|
119
|
+
// the UI and is not part of it; ids of unknown or deleted bots are ignored
|
|
120
|
+
// where the order is applied. No key = the UI's current order.
|
|
121
|
+
getBotOrder() {
|
|
122
|
+
return { order: normalizeBotOrder(getConfig()?.botOrder) ?? [] };
|
|
123
|
+
},
|
|
124
|
+
setBotOrder(order) {
|
|
125
|
+
if (!Array.isArray(order) || order.length > MAX_BOT_ORDER_IDS || order.some((id) => !isBotOrderId(id))) {
|
|
126
|
+
throw new Error('usage: setBotOrder(an array of agent ids)');
|
|
127
|
+
}
|
|
128
|
+
const config = { ...getConfig() };
|
|
129
|
+
const ids = normalizeBotOrder(order);
|
|
130
|
+
if (!ids.length) delete config.botOrder;
|
|
131
|
+
else config.botOrder = ids;
|
|
132
|
+
saveConfigAndAdopt(config);
|
|
133
|
+
return this.getBotOrder();
|
|
134
|
+
},
|
|
88
135
|
getToolModuleSettings() {
|
|
89
136
|
const config = getConfig();
|
|
90
137
|
const localProvider = getLocalProviderStatus?.() || {};
|
|
91
138
|
const localProviderRuntimeInstalled = localProvider?.runtime?.installed === true;
|
|
92
139
|
return {
|
|
93
140
|
instructionFiles: normalizeInstructionFilesMode(config?.instructionFiles),
|
|
141
|
+
autoEffortBase: autoEffortBase(config?.autoEffortBase),
|
|
94
142
|
webSearch: { enabled: webSearchEnabled() },
|
|
95
143
|
memory: {
|
|
96
144
|
enabled: memoryToolsEnabledFn(),
|
|
@@ -152,6 +200,14 @@ export function createBuiltinToolSettings(
|
|
|
152
200
|
await refreshEmptySessionToolPolicy?.();
|
|
153
201
|
return this.getToolModuleSettings();
|
|
154
202
|
},
|
|
203
|
+
/** The global "Auto reasoning base": the effort Auto works around. */
|
|
204
|
+
setAutoEffortBase(level) {
|
|
205
|
+
if (!AUTO_EFFORT_BASES.includes(level)) {
|
|
206
|
+
throw new TypeError(`Auto reasoning base must be one of ${AUTO_EFFORT_BASES.join(', ')}.`);
|
|
207
|
+
}
|
|
208
|
+
saveConfigAndAdopt({ ...getConfig(), autoEffortBase: level });
|
|
209
|
+
return this.getToolModuleSettings();
|
|
210
|
+
},
|
|
155
211
|
async setMemoryToolsEnabled(enabled) {
|
|
156
212
|
const config = getConfig();
|
|
157
213
|
const memoryEnabled = enabled !== false;
|
|
@@ -202,11 +258,17 @@ export function createBuiltinToolSettings(
|
|
|
202
258
|
/** Extensions → Built-in Install: run the feature's preparation adapter
|
|
203
259
|
* (model pre-download, component verification), then mark it installed
|
|
204
260
|
* and enabled in one step. New sessions pick up the tool surface. */
|
|
205
|
-
async installBuiltinFeature(name) {
|
|
261
|
+
async installBuiltinFeature(name, options = null) {
|
|
206
262
|
if (!INSTALLABLE_BUILTIN_IDS.includes(name)) {
|
|
207
263
|
throw new TypeError('Built-in feature must be git, memory, office, tidy, localProvider, or autoEffort.');
|
|
208
264
|
}
|
|
209
265
|
if (name === 'autoEffort' && !onnxRuntimeSupported()) throw new Error(EFFORT_JUDGE_UNSUPPORTED);
|
|
266
|
+
// Code Tidy retry for named engines: fetch just those and leave the
|
|
267
|
+
// feature's installed/enabled state exactly as the user set it.
|
|
268
|
+
if (name === 'tidy' && Array.isArray(options?.engines)) {
|
|
269
|
+
await prepareBuiltinFeature?.(name, { engines: options.engines });
|
|
270
|
+
return this.getToolModuleSettings();
|
|
271
|
+
}
|
|
210
272
|
await prepareBuiltinFeature?.(name);
|
|
211
273
|
const config = getConfig();
|
|
212
274
|
let nextConfig = setBuiltinInstalledInConfig({ ...config }, name, true);
|
|
@@ -3,6 +3,8 @@ import {
|
|
|
3
3
|
refreshLiveSessionsProviderCacheOpts,
|
|
4
4
|
refreshSessionProviderCacheOpts,
|
|
5
5
|
} from '../runtime/agent/orchestrator/session/manager/session-lifecycle.mjs';
|
|
6
|
+
import { isAutoClearUnlimited } from '../runtime/agent/orchestrator/runtime-core/config-helpers.mjs';
|
|
7
|
+
import { COMPACTION_SUMMARY_MODES } from '../runtime/agent/orchestrator/session/compact/summary-mode.mjs';
|
|
6
8
|
|
|
7
9
|
// Every spelling of the main-context buffer budget; a new representation
|
|
8
10
|
// replaces the previous one.
|
|
@@ -32,9 +34,60 @@ const SESSION_COMPACTION_KEYS = [
|
|
|
32
34
|
'recallWindowSize',
|
|
33
35
|
'recallConcurrency',
|
|
34
36
|
'recallCycle1DeadlineMs',
|
|
37
|
+
// Replaced by summaryMode.
|
|
38
|
+
'useMaintainer',
|
|
35
39
|
...MAIN_BUFFER_KEYS,
|
|
36
40
|
];
|
|
37
41
|
|
|
42
|
+
// Unlimited (never auto-clear) typed as a duration.
|
|
43
|
+
const UNLIMITED_DURATION = /^(?:unlimited|never)$/i;
|
|
44
|
+
|
|
45
|
+
/** Fold the recognised compaction input fields into `next` (mutated and returned). */
|
|
46
|
+
function applyCompactionInput(next, input, hasOwn) {
|
|
47
|
+
if (hasOwn(input, 'auto')) next.auto = input.auto !== false;
|
|
48
|
+
if (hasOwn(input, 'enabled')) next.auto = input.enabled !== false;
|
|
49
|
+
if (hasOwn(input, 'onModelChange')) next.onModelChange = input.onModelChange !== false;
|
|
50
|
+
if (hasOwn(input, 'summaryMode')) {
|
|
51
|
+
if (!COMPACTION_SUMMARY_MODES.includes(input.summaryMode)) {
|
|
52
|
+
throw new Error(`usage: summaryMode ${COMPACTION_SUMMARY_MODES.join(' | ')}`);
|
|
53
|
+
}
|
|
54
|
+
next.summaryMode = input.summaryMode;
|
|
55
|
+
}
|
|
56
|
+
// Legacy Compact type fields are intentionally ignored. There is one
|
|
57
|
+
// fresh-context Compact contract for every session.
|
|
58
|
+
// A new budget representation replaces the previous one. Otherwise a
|
|
59
|
+
// saved token override silently outranks a later percentage edit.
|
|
60
|
+
if (MAIN_BUFFER_KEYS.some((key) => hasOwn(input, key))) {
|
|
61
|
+
for (const old of MAIN_BUFFER_KEYS) delete next[old];
|
|
62
|
+
}
|
|
63
|
+
for (const key of MAIN_BUFFER_KEYS) {
|
|
64
|
+
if (hasOwn(input, key)) next[key] = input[key];
|
|
65
|
+
}
|
|
66
|
+
return next;
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/** Replace the live session's compaction fields with the saved config's. */
|
|
70
|
+
function adoptSessionCompaction(session, saved) {
|
|
71
|
+
if (!session) return;
|
|
72
|
+
const currentSessionCompaction = { ...(session.compaction || {}) };
|
|
73
|
+
for (const key of SESSION_COMPACTION_KEYS) delete currentSessionCompaction[key];
|
|
74
|
+
session.compaction = { ...currentSessionCompaction, ...saved };
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
// Advanced picker shows only providers the user actually has enabled
|
|
78
|
+
// (config.providers[*].enabled), plus the active route provider, any
|
|
79
|
+
// provider with a custom override, and the 'default' fallback row —
|
|
80
|
+
// not the full built-in table.
|
|
81
|
+
function enabledProviderKeys(config, provider) {
|
|
82
|
+
const enabledProviders = new Set(
|
|
83
|
+
Object.entries(config?.providers || {})
|
|
84
|
+
.filter(([, v]) => v && typeof v === 'object' && v.enabled !== false)
|
|
85
|
+
.map(([k]) => String(k).toLowerCase())
|
|
86
|
+
);
|
|
87
|
+
if (provider) enabledProviders.add(String(provider).toLowerCase());
|
|
88
|
+
return enabledProviders;
|
|
89
|
+
}
|
|
90
|
+
|
|
38
91
|
export function createCompactionSettings({
|
|
39
92
|
getConfig,
|
|
40
93
|
getRoute,
|
|
@@ -63,9 +116,21 @@ export function createCompactionSettings({
|
|
|
63
116
|
if (input.resetProvider === true || (hasOwn(input, 'idleMs') && input.idleMs == null)) {
|
|
64
117
|
delete providerIdleMs[providerKey];
|
|
65
118
|
} else {
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
119
|
+
// Unlimited (never auto-clear) is stored as 0: `unlimited: true`, a
|
|
120
|
+
// duration of 'unlimited'/'never', or idleMs 0.
|
|
121
|
+
const unlimited =
|
|
122
|
+
input.unlimited === true ||
|
|
123
|
+
(hasOwn(input, 'duration') && UNLIMITED_DURATION.test(String(input.duration ?? '').trim())) ||
|
|
124
|
+
(!hasOwn(input, 'duration') && hasOwn(input, 'idleMs') && input.idleMs === 0);
|
|
125
|
+
if (unlimited) {
|
|
126
|
+
providerIdleMs[providerKey] = 0;
|
|
127
|
+
} else {
|
|
128
|
+
const idleMs = hasOwn(input, 'duration') ? parseDurationMs(input.duration) : Number(input.idleMs);
|
|
129
|
+
if (!idleMs || !Number.isFinite(idleMs) || idleMs <= 0) {
|
|
130
|
+
throw new Error('usage: duration like 10m, 1h, 24h, or unlimited');
|
|
131
|
+
}
|
|
132
|
+
providerIdleMs[providerKey] = Math.max(60_000, Math.round(idleMs));
|
|
133
|
+
}
|
|
69
134
|
}
|
|
70
135
|
saveConfigAndAdopt({ ...config, autoClear: { ...next, providerIdleMs } });
|
|
71
136
|
refreshLeadCacheOpts();
|
|
@@ -79,28 +144,10 @@ export function createCompactionSettings({
|
|
|
79
144
|
setCompactionSettings(input = {}) {
|
|
80
145
|
const config = getConfig();
|
|
81
146
|
const current = normalizeCompactionConfig(config.compaction);
|
|
82
|
-
const next = { ...current };
|
|
83
|
-
if (hasOwn(input, 'auto')) next.auto = input.auto !== false;
|
|
84
|
-
if (hasOwn(input, 'enabled')) next.auto = input.enabled !== false;
|
|
85
|
-
if (hasOwn(input, 'onModelChange')) next.onModelChange = input.onModelChange !== false;
|
|
86
|
-
// Legacy Compact type fields are intentionally ignored. There is one
|
|
87
|
-
// fresh-context Compact contract for every session.
|
|
88
|
-
// A new budget representation replaces the previous one. Otherwise a
|
|
89
|
-
// saved token override silently outranks a later percentage edit.
|
|
90
|
-
if (MAIN_BUFFER_KEYS.some((key) => hasOwn(input, key))) {
|
|
91
|
-
for (const old of MAIN_BUFFER_KEYS) delete next[old];
|
|
92
|
-
}
|
|
93
|
-
for (const key of MAIN_BUFFER_KEYS) {
|
|
94
|
-
if (hasOwn(input, key)) next[key] = input[key];
|
|
95
|
-
}
|
|
147
|
+
const next = applyCompactionInput({ ...current }, input, hasOwn);
|
|
96
148
|
saveConfigAndAdopt({ ...config, compaction: normalizeCompactionConfig(next) });
|
|
97
149
|
const saved = normalizeCompactionConfig(getConfig().compaction);
|
|
98
|
-
|
|
99
|
-
if (session) {
|
|
100
|
-
const currentSessionCompaction = { ...(session.compaction || {}) };
|
|
101
|
-
for (const key of SESSION_COMPACTION_KEYS) delete currentSessionCompaction[key];
|
|
102
|
-
session.compaction = { ...currentSessionCompaction, ...saved };
|
|
103
|
-
}
|
|
150
|
+
adoptSessionCompaction(getSession(), saved);
|
|
104
151
|
invalidateContextStatusCache();
|
|
105
152
|
return saved;
|
|
106
153
|
},
|
|
@@ -113,22 +160,17 @@ export function createCompactionSettings({
|
|
|
113
160
|
const idleMs = resolveAutoClearIdleMs(config, provider);
|
|
114
161
|
const key = String(provider || '').toLowerCase();
|
|
115
162
|
const providerCustom = Boolean(key && key !== 'default' && normalized.providerIdleMs?.[key]);
|
|
116
|
-
|
|
117
|
-
//
|
|
118
|
-
//
|
|
119
|
-
|
|
120
|
-
const enabledProviders = new Set(
|
|
121
|
-
Object.entries(config?.providers || {})
|
|
122
|
-
.filter(([, v]) => v && typeof v === 'object' && v.enabled !== false)
|
|
123
|
-
.map(([k]) => String(k).toLowerCase())
|
|
124
|
-
);
|
|
125
|
-
if (provider) enabledProviders.add(String(provider).toLowerCase());
|
|
126
|
-
const providerDefaults = autoClearProviderDefaults(normalized.providerIdleMs).filter(
|
|
163
|
+
const enabledProviders = enabledProviderKeys(config, provider);
|
|
164
|
+
// Every enabled provider gets its row, including ones without a
|
|
165
|
+
// built-in window (they resolve through the 'default' row).
|
|
166
|
+
const providerDefaults = autoClearProviderDefaults(normalized.providerIdleMs, [...enabledProviders]).filter(
|
|
127
167
|
(entry) => entry.provider === 'default' || entry.custom === true || enabledProviders.has(entry.provider)
|
|
128
168
|
);
|
|
129
169
|
return {
|
|
130
170
|
enabled: normalized.enabled,
|
|
131
171
|
idleMs,
|
|
172
|
+
unlimited: isAutoClearUnlimited(idleMs),
|
|
173
|
+
label: isAutoClearUnlimited(idleMs) ? 'unlimited' : formatDurationMs(idleMs),
|
|
132
174
|
custom: normalized.custom,
|
|
133
175
|
providerCustom,
|
|
134
176
|
providerDefault,
|
|
@@ -148,11 +190,17 @@ export function createCompactionSettings({
|
|
|
148
190
|
throw new Error('autoclear minContextPercent must be a number between 0 and 100');
|
|
149
191
|
next.minContextPercent = Math.min(100, Math.max(0, Math.round(rawMinPct)));
|
|
150
192
|
}
|
|
151
|
-
|
|
193
|
+
// `/autoclear unlimited` names no provider: it means the current route's.
|
|
194
|
+
const wantsUnlimited = hasOwn(input, 'duration') && UNLIMITED_DURATION.test(String(input.duration ?? '').trim());
|
|
195
|
+
const providerKey = String(input.provider || (wantsUnlimited ? getRoute()?.provider : '') || '')
|
|
152
196
|
.trim()
|
|
153
197
|
.toLowerCase();
|
|
154
198
|
const editsProviderDefault =
|
|
155
|
-
providerKey &&
|
|
199
|
+
providerKey &&
|
|
200
|
+
(input.resetProvider === true ||
|
|
201
|
+
input.unlimited === true ||
|
|
202
|
+
hasOwn(input, 'duration') ||
|
|
203
|
+
hasOwn(input, 'idleMs'));
|
|
156
204
|
if (editsProviderDefault) {
|
|
157
205
|
saveProviderIdle(config, next, providerKey, input);
|
|
158
206
|
} else {
|
|
@@ -165,15 +213,14 @@ export function createCompactionSettings({
|
|
|
165
213
|
}
|
|
166
214
|
if (hasOwn(input, 'duration')) {
|
|
167
215
|
const idleMs = parseDurationMs(input.duration);
|
|
168
|
-
if (!idleMs) throw new Error('usage: /autoclear [on|off|status|<minutes|1h|90m
|
|
216
|
+
if (!idleMs) throw new Error('usage: /autoclear [on|off|status|<minutes|1h|90m>|unlimited]');
|
|
169
217
|
next.idleMs = idleMs;
|
|
170
218
|
if (!hasOwn(input, 'enabled')) next.enabled = true;
|
|
171
219
|
}
|
|
172
220
|
saveConfigAndAdopt({ ...config, autoClear: next });
|
|
173
221
|
refreshLeadCacheOpts();
|
|
174
222
|
}
|
|
175
|
-
|
|
176
|
-
return { ...resolved, label: formatDurationMs(resolved.idleMs) };
|
|
223
|
+
return this.getAutoClear();
|
|
177
224
|
},
|
|
178
225
|
};
|
|
179
226
|
}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* registers the tool executor before it finishes assembling the API object. */
|
|
6
6
|
import { builtinFeatureActive } from '../../runtime/agent/orchestrator/runtime-core/builtin-features.mjs';
|
|
7
7
|
import { ORCHESTRATION_MODES } from '../../runtime/shared/orchestration.mjs';
|
|
8
|
+
import { AUTO_EFFORT_BASES } from '../../runtime/agent/orchestrator/providers/auto-effort.mjs';
|
|
8
9
|
import { INSTRUCTION_FILES_MODES } from '../../runtime/shared/instruction-files-mode.mjs';
|
|
9
10
|
import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
|
|
10
11
|
import { SETUP_DESKTOP_DOMAINS, SETUP_HANDOFFS } from './settings-contract.mjs';
|
|
@@ -377,6 +378,17 @@ const SETUP_STATUS_READERS = {
|
|
|
377
378
|
// schema, the per-action field list and the route/object-argument minimums.
|
|
378
379
|
function validateSetupInput(args) {
|
|
379
380
|
const action = requireEnum(args?.action, SETUP_ACTIONS, 'action');
|
|
381
|
+
// Old callers still ask to connect GitHub: it is the signed-in GitHub CLI, not a catalog connector.
|
|
382
|
+
if (
|
|
383
|
+
action === 'connect_connector' &&
|
|
384
|
+
String(args.connector ?? '')
|
|
385
|
+
.trim()
|
|
386
|
+
.toLowerCase() === 'github'
|
|
387
|
+
) {
|
|
388
|
+
throw new Error(
|
|
389
|
+
'GitHub uses the signed-in GitHub CLI; no connector needed. Use the github tool or Settings → Git.'
|
|
390
|
+
);
|
|
391
|
+
}
|
|
380
392
|
const validationError = schemaValueError({ ...args, action }, SETUP_TOOL_DEFS[0].inputSchema, 'setup');
|
|
381
393
|
if (validationError) throw new Error(`[tool-input-validation] ${validationError}`);
|
|
382
394
|
const fields = SETUP_ACTION_FIELDS[action].split(' ').filter(Boolean);
|
|
@@ -392,8 +404,11 @@ function validateSetupInput(args) {
|
|
|
392
404
|
if (action !== 'set_agent_route' && Object.hasOwn(args.route, 'disabled')) {
|
|
393
405
|
throw new Error('route.disabled is only accepted by set_agent_route');
|
|
394
406
|
}
|
|
395
|
-
if (
|
|
396
|
-
|
|
407
|
+
if (
|
|
408
|
+
Object.hasOwn(args.route, 'fallbacks') &&
|
|
409
|
+
!['set_route', 'set_agent_route', 'set_web_search_route'].includes(action)
|
|
410
|
+
) {
|
|
411
|
+
throw new Error('route.fallbacks is only accepted by set_route, set_agent_route and set_web_search_route');
|
|
397
412
|
}
|
|
398
413
|
for (const field of ['contextPercent', 'contextTokens', 'autoEffort']) {
|
|
399
414
|
if (action !== 'set_route' && action !== 'set_agent_route' && Object.hasOwn(args.route, field)) {
|
|
@@ -522,6 +537,8 @@ const SETUP_ACTION_HANDLERS = {
|
|
|
522
537
|
set_web_search_enabled: (rt, args) => rt.setWebSearchEnabled(requireBoolean(args.enabled)),
|
|
523
538
|
set_instruction_files: (rt, args) =>
|
|
524
539
|
rt.setInstructionFiles(requireEnum(args.instructionFiles, INSTRUCTION_FILES_MODES, 'instructionFiles')),
|
|
540
|
+
set_auto_effort_base: (rt, args) =>
|
|
541
|
+
rt.setAutoEffortBase(requireEnum(args.autoEffortBase, AUTO_EFFORT_BASES, 'autoEffortBase')),
|
|
525
542
|
set_builtin_enabled: (rt, args, { requestDesktop }) => {
|
|
526
543
|
const name = requireEnum(args.name, SETUP_BUILTIN_TOGGLE_FEATURES, 'name');
|
|
527
544
|
if (DESKTOP_HOSTED_FEATURES.includes(name)) return requestDesktop(args);
|
|
@@ -647,7 +664,7 @@ const SETUP_ACTION_HANDLERS = {
|
|
|
647
664
|
const entry = connectorById(requireText(args.connector, 'connector'));
|
|
648
665
|
if (!entry || entry.ownKey) throw new Error(`connector must be one of ${CONNECTOR_IDS.join(', ')}`);
|
|
649
666
|
const server = (rt.mcpStatus?.()?.servers || []).find((row) => row.connector === entry.id) || null;
|
|
650
|
-
const connected =
|
|
667
|
+
const connected = server?.connected === true;
|
|
651
668
|
return {
|
|
652
669
|
connector: entry.id,
|
|
653
670
|
name: entry.name,
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { SETUP_EXTENDED_PROPERTIES, SETUP_DESKTOP_ACTIONS } from './settings-contract.mjs';
|
|
2
2
|
import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
|
|
3
3
|
import { OPENAI_COMPAT_PRESETS } from '../../runtime/agent/orchestrator/providers/openai-compat-presets.mjs';
|
|
4
|
-
import { agentIdOfHomeSession } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
4
|
+
import { MIXY_AGENT_ID, agentIdOfHomeSession } from '../../runtime/agent/orchestrator/session/agent-home.mjs';
|
|
5
|
+
import { AGENT_MODE, resolveSessionMode } from '../../runtime/agent/orchestrator/session/agent-mode.mjs';
|
|
6
|
+
import { BOT_AGENT_KIND, WORKFLOW_AGENT_KIND } from '../../runtime/shared/agent-route-config.mjs';
|
|
5
7
|
import { assertAutomationAccess, scheduleCallerScope } from '../services/schedule-access.mjs';
|
|
6
8
|
|
|
7
9
|
const own = (value, key) => Object.hasOwn(value || {}, key);
|
|
@@ -164,13 +166,20 @@ async function readDefinition(rt, kind, name) {
|
|
|
164
166
|
};
|
|
165
167
|
}
|
|
166
168
|
|
|
167
|
-
|
|
169
|
+
// A created agent's explicit marker: the one given, else a bot when Mixy's
|
|
170
|
+
// agent-mode chat creates it (Mixy creates bots), else a workflow agent.
|
|
171
|
+
function createdAgentKind(input, caller) {
|
|
172
|
+
if (own(input, 'kind')) return input.kind;
|
|
173
|
+
const { mode, agentId } = resolveSessionMode({ session: caller });
|
|
174
|
+
return mode === AGENT_MODE && agentId === MIXY_AGENT_ID ? BOT_AGENT_KIND : WORKFLOW_AGENT_KIND;
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function saveDefinition(rt, args, context = {}) {
|
|
168
178
|
const kind = args.definitionKind;
|
|
169
179
|
const input = args.definition;
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
: ['id', 'name', 'description', 'body'];
|
|
180
|
+
let allowed = ['id', 'name', 'description', 'body'];
|
|
181
|
+
if (kind === 'skill') allowed = ['originalName', 'name', 'description', 'body', 'whenToUse', 'toolDependencies'];
|
|
182
|
+
else if (kind === 'agent') allowed = [...allowed, 'kind'];
|
|
174
183
|
const unexpected = Object.keys(input).find((key) => !allowed.includes(key));
|
|
175
184
|
if (unexpected) throw new Error(`${unexpected} is not a ${kind} definition field`);
|
|
176
185
|
const creating = args.action === 'create_definition';
|
|
@@ -200,7 +209,10 @@ async function saveDefinition(rt, args) {
|
|
|
200
209
|
const agents = await rt.listAgents();
|
|
201
210
|
if (agents.some((agent) => agent.id === input.id)) throw new Error(`agent "${input.id}" already exists`);
|
|
202
211
|
}
|
|
203
|
-
return rt.saveAgentDefinition(
|
|
212
|
+
if (creating) return rt.saveAgentDefinition({ ...next, kind: createdAgentKind(input, context.caller) });
|
|
213
|
+
// The stored kind is kept as it is; an edit naming one is refused by the editor.
|
|
214
|
+
const { kind: _storedKind, ...edit } = { ...pick(current, definitionKeys), ...input };
|
|
215
|
+
return rt.saveAgentDefinition({ ...edit, ...(own(input, 'kind') ? { kind: input.kind } : {}), id: current.id });
|
|
204
216
|
}
|
|
205
217
|
return creating ? rt.addSkill(next) : rt.saveSkill({ ...next, originalName: current.originalName });
|
|
206
218
|
}
|
|
@@ -157,7 +157,17 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
|
157
157
|
name: text,
|
|
158
158
|
description: text,
|
|
159
159
|
body: text,
|
|
160
|
-
|
|
160
|
+
kind: {
|
|
161
|
+
type: 'string',
|
|
162
|
+
enum: ['bot', 'agent'],
|
|
163
|
+
description:
|
|
164
|
+
'Agent create only: "bot" (a contact the user chats with) or "agent" (a workflow sub-agent). Omitted: a bot when created from the representative bot\'s chat, else a workflow agent. Fixed after creation.',
|
|
165
|
+
},
|
|
166
|
+
whenToUse: {
|
|
167
|
+
...text,
|
|
168
|
+
description:
|
|
169
|
+
'Skill only: the SKILL.md when_to_use trigger line shown in the model\'s skill listing; "" clears it.',
|
|
170
|
+
},
|
|
161
171
|
toolDependencies: {
|
|
162
172
|
type: ['array', 'null'],
|
|
163
173
|
items: object({ type: { type: 'string', enum: ['tool', 'mcp'] }, value: text }, ['type', 'value']),
|
|
@@ -232,6 +242,32 @@ export const SETUP_EXTENDED_PROPERTIES = Object.freeze({
|
|
|
232
242
|
markdownDefaultView: { type: 'string', enum: ['preview', 'rich', 'source'] },
|
|
233
243
|
linkPreview: boolean,
|
|
234
244
|
toolActivityExpansion: { type: 'string', enum: ['collapsed', 'commands', 'all'] },
|
|
245
|
+
uiFont: { ...text, description: 'Installed font family for the UI; "" restores the built-in font.' },
|
|
246
|
+
codeFont: { ...text, description: 'Installed font family for code; "" restores the built-in font.' },
|
|
247
|
+
skinTransparency: {
|
|
248
|
+
type: 'integer',
|
|
249
|
+
minimum: 0,
|
|
250
|
+
maximum: 100,
|
|
251
|
+
description: 'Sets both skin transparency sliders at once, 0-100 (defaults: outer 20, main 40).',
|
|
252
|
+
},
|
|
253
|
+
skinOuterTransparency: {
|
|
254
|
+
type: 'integer',
|
|
255
|
+
minimum: 0,
|
|
256
|
+
maximum: 100,
|
|
257
|
+
description:
|
|
258
|
+
'How much of the skin picture shows through the outer panels (window frame, titlebar, rail, sidebar, side dock), 0-100 (default 20).',
|
|
259
|
+
},
|
|
260
|
+
skinMainTransparency: {
|
|
261
|
+
type: 'integer',
|
|
262
|
+
minimum: 0,
|
|
263
|
+
maximum: 100,
|
|
264
|
+
description:
|
|
265
|
+
'How much of the skin picture shows through the main panel (conversation area, composer card, status island), 0-100 (default 40).',
|
|
266
|
+
},
|
|
267
|
+
colorTheme: {
|
|
268
|
+
...text,
|
|
269
|
+
description: 'Imported JSON color theme id from status appearance colorThemes; "builtin" turns themes off.',
|
|
270
|
+
},
|
|
235
271
|
}),
|
|
236
272
|
hookRule: object(
|
|
237
273
|
{
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from './settings-contract.mjs';
|
|
7
7
|
import { MEDIA_KINDS } from '../../runtime/media/tool-defs.mjs';
|
|
8
8
|
import { INSTRUCTION_FILES_MODES } from '../../runtime/shared/instruction-files-mode.mjs';
|
|
9
|
+
import { AUTO_EFFORT_BASES } from '../../runtime/agent/orchestrator/providers/auto-effort.mjs';
|
|
9
10
|
import { WORKTREE_NEW_TASK_DEFAULTS } from '../../runtime/shared/worktrees/settings.mjs';
|
|
10
11
|
import { CONNECTOR_IDS } from '../../runtime/shared/connector-catalog.mjs';
|
|
11
12
|
|
|
@@ -83,6 +84,7 @@ export const SETUP_ACTION_FIELDS = Object.freeze({
|
|
|
83
84
|
set_recap_enabled: 'enabled',
|
|
84
85
|
set_web_search_enabled: 'enabled',
|
|
85
86
|
set_instruction_files: 'instructionFiles',
|
|
87
|
+
set_auto_effort_base: 'autoEffortBase',
|
|
86
88
|
set_builtin_enabled: 'name enabled',
|
|
87
89
|
install_builtin: 'name',
|
|
88
90
|
install_local_model: 'modelId',
|
|
@@ -160,7 +162,8 @@ const ROUTE_SCHEMA = {
|
|
|
160
162
|
|
|
161
163
|
ROUTE_SCHEMA.properties.fallbacks = {
|
|
162
164
|
type: 'array',
|
|
163
|
-
description:
|
|
165
|
+
description:
|
|
166
|
+
'Lead (set_route), agent (bots included) and Web Search routes only: ordered fallback models tried when the model hits its usage limit or is unavailable; [] clears the list.',
|
|
164
167
|
items: {
|
|
165
168
|
type: 'object',
|
|
166
169
|
additionalProperties: false,
|
|
@@ -224,8 +227,16 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
224
227
|
additionalProperties: false,
|
|
225
228
|
properties: {
|
|
226
229
|
enabled: { type: 'boolean' },
|
|
227
|
-
duration: {
|
|
228
|
-
|
|
230
|
+
duration: {
|
|
231
|
+
type: 'string',
|
|
232
|
+
description:
|
|
233
|
+
'Idle window such as "45m" or "2h" (minimum 1m), or "unlimited"/"never" to stop idle clearing. Without provider, "unlimited" applies to the current route provider.',
|
|
234
|
+
},
|
|
235
|
+
provider: {
|
|
236
|
+
type: 'string',
|
|
237
|
+
description:
|
|
238
|
+
'Scope the duration to one provider; "default" is the fallback for providers without a built-in window.',
|
|
239
|
+
},
|
|
229
240
|
reset: { type: 'boolean', description: 'Restore the global idle duration default.' },
|
|
230
241
|
resetProvider: { type: 'boolean', description: 'Restore the given provider idle duration default.' },
|
|
231
242
|
minContextPercent: { type: 'number', minimum: 0, maximum: 100 },
|
|
@@ -251,6 +262,12 @@ export const SETUP_TOOL_DEFS = Object.freeze([
|
|
|
251
262
|
description:
|
|
252
263
|
"set_instruction_files: which user instruction files new sessions load (global ~/.codex/AGENTS.md, ~/.claude/CLAUDE.md, then the Project root's AGENTS.md/CLAUDE.md).",
|
|
253
264
|
},
|
|
265
|
+
autoEffortBase: {
|
|
266
|
+
type: 'string',
|
|
267
|
+
enum: [...AUTO_EFFORT_BASES],
|
|
268
|
+
description:
|
|
269
|
+
"set_auto_effort_base: the reasoning effort Auto works around (global; default medium). Auto moves one step down to two steps up from it, within the model's supported efforts.",
|
|
270
|
+
},
|
|
254
271
|
name: {
|
|
255
272
|
type: 'string',
|
|
256
273
|
description: `set_builtin_enabled: ${SETUP_BUILTIN_TOGGLE_FEATURES.join('|')}; install_builtin also accepts memory. Memory toggles use set_memory_enabled. revoke_linked_device: client id from status connection, not its display name; set_developer_option: option id from status developer; read_definition/delete_definition: the definition id; reconnect_mcp: optional MCP server name (omit for all); else MCP/plugin/provider id.`,
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
// Skill surface (status listing, resource load, tool envelope, global skill
|
|
2
2
|
// creation/editing). The runtime facade only wires the mutable cwd and the
|
|
3
3
|
// context module into it.
|
|
4
|
-
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync
|
|
4
|
+
import { existsSync, mkdirSync, readFileSync, renameSync, rmSync } from 'node:fs';
|
|
5
5
|
import { basename, dirname, isAbsolute, join, relative, resolve } from 'node:path';
|
|
6
|
+
import { holdsNoData, writeFileAtomicSync } from '../runtime/shared/atomic-file.mjs';
|
|
6
7
|
import { resolvePluginData } from '../runtime/shared/plugin-paths.mjs';
|
|
7
8
|
import {
|
|
8
9
|
createSkillDocument,
|
|
@@ -21,6 +22,10 @@ import { loadSkillToolDependencies } from '../runtime/agent/orchestrator/runtime
|
|
|
21
22
|
|
|
22
23
|
const DEFAULT_SKILL_BODY = '# Instructions\n\nDescribe how to use this skill.';
|
|
23
24
|
|
|
25
|
+
// SKILL.md is user-authored: written atomically (a crash never leaves it torn
|
|
26
|
+
// or NUL-filled), the replaced copy kept as SKILL.md.bak.
|
|
27
|
+
const writeSkillFile = (filePath, text) => writeFileAtomicSync(filePath, text, { backup: true, mode: 0o644 });
|
|
28
|
+
|
|
24
29
|
export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
25
30
|
const globalSkillsRoot = () => resolve(resolvePluginData(), 'skills');
|
|
26
31
|
|
|
@@ -114,9 +119,11 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
|
114
119
|
: normalizeSkillToolDependencies(input.toolDependencies, { strict: true });
|
|
115
120
|
const dir = join(globalSkillsRoot(), name);
|
|
116
121
|
const filePath = join(dir, 'SKILL.md');
|
|
117
|
-
|
|
122
|
+
// A SKILL.md holding no data (empty, NUL-filled by a crash) is no skill:
|
|
123
|
+
// creating over it is allowed.
|
|
124
|
+
if (existsSync(filePath) && !holdsNoData(readFileSync(filePath))) throw new Error(`skill already exists: ${name}`);
|
|
118
125
|
mkdirSync(dir, { recursive: true });
|
|
119
|
-
|
|
126
|
+
writeSkillFile(filePath, createSkillDocument({ name, description, whenToUse, body }));
|
|
120
127
|
if (dependencies !== undefined) saveSkillToolDependencies(filePath, dependencies);
|
|
121
128
|
invalidateSkills();
|
|
122
129
|
return { name, filePath };
|
|
@@ -177,13 +184,13 @@ export function createSkillsApi({ contextMod, getCwd, getTools = () => [] }) {
|
|
|
177
184
|
renameSync(currentDir, nextDir);
|
|
178
185
|
filePath = join(nextDir, 'SKILL.md');
|
|
179
186
|
try {
|
|
180
|
-
|
|
187
|
+
writeSkillFile(filePath, updated);
|
|
181
188
|
} catch (error) {
|
|
182
189
|
renameSync(nextDir, currentDir);
|
|
183
190
|
throw error;
|
|
184
191
|
}
|
|
185
192
|
} else {
|
|
186
|
-
|
|
193
|
+
writeSkillFile(filePath, updated);
|
|
187
194
|
}
|
|
188
195
|
if (dependencies !== undefined) saveSkillToolDependencies(filePath, dependencies);
|
|
189
196
|
else if (filePath !== resource.filePath && resource.dependencySource === 'override') {
|