@sayknow-cli/coding-agent 0.4.7 → 0.5.1
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/CHANGELOG.md +122 -0
- package/dist/types/capability/index.d.ts +10 -20
- package/dist/types/capability/types.d.ts +3 -0
- package/dist/types/cli/args.d.ts +0 -2
- package/dist/types/cli/read-cli.d.ts +1 -0
- package/dist/types/cli.d.ts +9 -1
- package/dist/types/commands/daemon.d.ts +2 -2
- package/dist/types/commands/deep-interview.d.ts +9 -0
- package/dist/types/commands/harness.d.ts +22 -0
- package/dist/types/commands/read.d.ts +6 -0
- package/dist/types/commands/sdk.d.ts +20 -2
- package/dist/types/config/keybindings.d.ts +34 -4
- package/dist/types/config/model-profile-contract.d.ts +40 -0
- package/dist/types/config/model-profiles.d.ts +2 -3
- package/dist/types/config/model-registry.d.ts +5 -0
- package/dist/types/config/provider-auth-health.d.ts +14 -0
- package/dist/types/config/provider-ranking.d.ts +59 -0
- package/dist/types/config/settings-schema.d.ts +156 -10
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/edit/modes/patch.d.ts +13 -0
- package/dist/types/edit/path-mutation-lock.d.ts +15 -0
- package/dist/types/eval/py/executor.d.ts +1 -1
- package/dist/types/eval/py/runner-artifact.d.ts +8 -0
- package/dist/types/eval/py/tool-bridge.d.ts +1 -2
- package/dist/types/extensibility/extensions/types.d.ts +43 -2
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
- package/dist/types/main.d.ts +33 -2
- package/dist/types/memories/index.d.ts +2 -0
- package/dist/types/modes/acp/acp-agent.d.ts +22 -9
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/btw-panel.d.ts +1 -0
- package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
- package/dist/types/modes/components/queue-pane.d.ts +8 -0
- package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
- package/dist/types/modes/components/read-tool-group.d.ts +4 -4
- package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +2 -1
- package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/tool-status-header.d.ts +4 -2
- package/dist/types/modes/components/welcome.d.ts +5 -0
- package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/event-controller.d.ts +3 -0
- package/dist/types/modes/interactive-mode.d.ts +13 -2
- package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
- package/dist/types/modes/prompt-action-autocomplete.d.ts +6 -1
- package/dist/types/modes/prompt-suggestion-controller.d.ts +35 -0
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -2
- package/dist/types/modes/types.d.ts +6 -0
- package/dist/types/modes/utils/hotkeys-markdown.d.ts +2 -1
- package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
- package/dist/types/runtime/memory-domain.d.ts +9 -0
- package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
- package/dist/types/runtime/memory-guard.d.ts +39 -0
- package/dist/types/runtime/memory-limit.d.ts +11 -0
- package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
- package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +1 -1
- package/dist/types/runtime-mcp/manager.d.ts +9 -1
- package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -5
- package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +14 -0
- package/dist/types/runtime-mcp/redaction.d.ts +2 -0
- package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
- package/dist/types/sdk/acp/final-text.d.ts +19 -0
- package/dist/types/sdk/acp/mcp.d.ts +23 -0
- package/dist/types/sdk/broker/broker.d.ts +2 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +13 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +9 -1
- package/dist/types/sdk/bus/config-commands.d.ts +2 -2
- package/dist/types/sdk/bus/config.d.ts +2 -0
- package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +1 -0
- package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +52 -4
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
- package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
- package/dist/types/sdk/bus/notification-orchestration.d.ts +1 -0
- package/dist/types/sdk/bus/notification-service.d.ts +34 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +106 -0
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +33 -9
- package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +286 -12
- package/dist/types/sdk/bus/telegram-reference.d.ts +2 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
- package/dist/types/sdk/client/discovery.d.ts +2 -0
- package/dist/types/sdk/client/liveness.d.ts +7 -0
- package/dist/types/sdk/host/control/operations.d.ts +3 -2
- package/dist/types/sdk/host/host.d.ts +3 -1
- package/dist/types/sdk/host/query/handlers.d.ts +14 -0
- package/dist/types/sdk/index.d.ts +2 -0
- package/dist/types/sdk/lifecycle-session.d.ts +10 -1
- package/dist/types/sdk/prompt-status.d.ts +88 -0
- package/dist/types/sdk/session-directory.d.ts +1 -1
- package/dist/types/sdk/session.d.ts +7 -0
- package/dist/types/sdk/startup-capability.d.ts +9 -0
- package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
- package/dist/types/sdk/transport/index.d.ts +12 -0
- package/dist/types/sdk/transport/relay.d.ts +43 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
- package/dist/types/sdk/transport/socket.d.ts +7 -0
- package/dist/types/sdk/transport/stdio.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +83 -24
- package/dist/types/session/btw-contract.d.ts +16 -0
- package/dist/types/session/fallback-chain-controller.d.ts +18 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +70 -10
- package/dist/types/session/internal/managed-session-storage.d.ts +34 -12
- package/dist/types/session/internal/native-publish-outcome.d.ts +48 -0
- package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
- package/dist/types/session/session-manager.d.ts +89 -18
- package/dist/types/session/session-storage.d.ts +31 -0
- package/dist/types/session/streaming-output.d.ts +60 -5
- package/dist/types/setup/credential-import.d.ts +5 -1
- package/dist/types/setup/provider-onboarding.d.ts +2 -0
- package/dist/types/skc-runtime/deep-interview-runtime.d.ts +1 -1
- package/dist/types/skc-runtime/deep-interview-stage.d.ts +37 -0
- package/dist/types/skc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/skc-runtime/linux-proc.d.ts +22 -14
- package/dist/types/skc-runtime/memory-guard-owner-claims.d.ts +47 -0
- package/dist/types/skc-runtime/ralplan-runtime.d.ts +112 -1
- package/dist/types/skc-runtime/repository-binding.d.ts +63 -0
- package/dist/types/skc-runtime/state-runtime.d.ts +3 -1
- package/dist/types/skc-runtime/state-writer.d.ts +5 -1
- package/dist/types/skc-runtime/team-launch.d.ts +1 -1
- package/dist/types/skc-runtime/team-runtime.d.ts +9 -2
- package/dist/types/skc-runtime/team-store.d.ts +12 -0
- package/dist/types/skc-runtime/team-worker-memory-guard.d.ts +92 -0
- package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +7 -0
- package/dist/types/skc-runtime/ultragoal-guard.d.ts +6 -5
- package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +28 -0
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +43 -5
- package/dist/types/skill-state/workflow-hud.d.ts +3 -0
- package/dist/types/ssh/utils.d.ts +1 -0
- package/dist/types/task/discovery.d.ts +3 -1
- package/dist/types/task/executor.d.ts +6 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/task/provider-retry-status.d.ts +13 -0
- package/dist/types/task/receipt.d.ts +2 -0
- package/dist/types/task/types.d.ts +133 -0
- package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
- package/dist/types/tools/browser/launch.d.ts +7 -0
- package/dist/types/tools/fetch.d.ts +22 -9
- package/dist/types/tools/image-gen.d.ts +63 -1
- package/dist/types/tools/index.d.ts +7 -1
- package/dist/types/tools/output-meta.d.ts +21 -1
- package/dist/types/tools/read-internals.d.ts +12 -0
- package/dist/types/tools/read.d.ts +45 -1
- package/dist/types/tools/resource-gc.d.ts +23 -0
- package/dist/types/tools/skill-discovery.d.ts +7 -0
- package/dist/types/tools/sqlite-reader.d.ts +7 -0
- package/dist/types/tools/tool-result.d.ts +7 -1
- package/dist/types/utils/prompt-suggestion.d.ts +33 -0
- package/dist/types/utils/shell-snapshot.d.ts +12 -0
- package/dist/types/web/insane/bridge.d.ts +1 -0
- package/dist/types/web/insane/url-guard.d.ts +17 -0
- package/package.json +8 -12
- package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
- package/scripts/capture-platform-shortcut-labels-showcase.ts +342 -0
- package/scripts/capture-sticky-viewport-showcase.ts +292 -0
- package/scripts/compile-args.ts +0 -1
- package/scripts/dogfood-repository-binding.ts +209 -0
- package/scripts/generate-docs-index.ts +4 -1
- package/scripts/generate-sdk-operation-inventory.ts +9 -0
- package/scripts/run-test-manifest.ts +6 -4
- package/scripts/verify-skc-sdk-canonicalization.ts +122 -18
- package/scripts/verify-sticky-viewport-showcase.ts +611 -0
- package/src/capability/index.ts +58 -42
- package/src/capability/types.ts +3 -0
- package/src/cli/args.ts +16 -100
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/mcp-cli.ts +4 -21
- package/src/cli/notify-cli.ts +6 -38
- package/src/cli/read-cli.ts +2 -1
- package/src/cli/setup-cli.ts +10 -4
- package/src/cli.ts +133 -11
- package/src/commands/daemon.ts +22 -5
- package/src/commands/deep-interview.ts +26 -1
- package/src/commands/harness.ts +35 -12
- package/src/commands/read.ts +11 -2
- package/src/commands/sdk.ts +134 -17
- package/src/commands/team.ts +1 -1
- package/src/commit/agentic/index.ts +3 -3
- package/src/commit/map-reduce/index.ts +2 -2
- package/src/config/keybindings.ts +158 -25
- package/src/config/model-profile-contract.ts +174 -0
- package/src/config/model-profiles.ts +51 -10
- package/src/config/model-registry.ts +24 -4
- package/src/config/model-resolver.ts +2 -2
- package/src/config/provider-auth-health.ts +42 -0
- package/src/config/provider-ranking.ts +119 -0
- package/src/config/settings-schema.ts +157 -10
- package/src/config/settings.ts +254 -108
- package/src/coordinator-mcp/model-preset.ts +21 -74
- package/src/defaults/skc/skills/deep-interview/SKILL.md +147 -24
- package/src/defaults/skc/skills/ralplan/SKILL.md +91 -34
- package/src/defaults/skc/skills/team/SKILL.md +1 -1
- package/src/defaults/skc/skills/ultragoal/SKILL.md +68 -17
- package/src/discovery/ssh.ts +12 -1
- package/src/edit/index.ts +3 -6
- package/src/edit/modes/patch.ts +38 -1
- package/src/edit/modes/replace.ts +42 -0
- package/src/edit/path-mutation-lock.ts +112 -0
- package/src/eval/js/tool-bridge.ts +1 -1
- package/src/eval/py/executor.ts +37 -13
- package/src/eval/py/kernel.ts +1 -21
- package/src/eval/py/prelude.py +2 -2
- package/src/eval/py/runner-artifact.ts +84 -0
- package/src/eval/py/tool-bridge.ts +34 -18
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +42 -4
- package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
- package/src/extensibility/shared-events.ts +5 -0
- package/src/extensibility/skc-plugins/runtime-adapters.ts +2 -1
- package/src/hooks/native-skill-hook.ts +17 -4
- package/src/internal-urls/docs-index.generated.ts +17 -16
- package/src/internal-urls/local-protocol.ts +87 -25
- package/src/internal-urls/local-root-gc.ts +127 -0
- package/src/internal-urls/mcp-protocol.ts +73 -11
- package/src/main.ts +120 -42
- package/src/memories/index.ts +10 -0
- package/src/modes/DESIGN.md +52 -0
- package/src/modes/acp/acp-agent.ts +647 -83
- package/src/modes/acp/acp-event-mapper.ts +106 -12
- package/src/modes/acp/acp-mode.ts +39 -3
- package/src/modes/action-registry.ts +1 -1
- package/src/modes/components/assistant-message.ts +123 -22
- package/src/modes/components/btw-panel.ts +82 -16
- package/src/modes/components/irc-sidebar.ts +176 -62
- package/src/modes/components/model-selector.ts +61 -4
- package/src/modes/components/notifications-settings-editor.ts +1 -1
- package/src/modes/components/oauth-selector.ts +42 -12
- package/src/modes/components/plan-preview-overlay.ts +1 -1
- package/src/modes/components/queue-pane.ts +55 -9
- package/src/modes/components/queued-message-selector.ts +53 -10
- package/src/modes/components/read-tool-group.ts +82 -14
- package/src/modes/components/runtime-mcp-add-wizard.ts +5 -0
- package/src/modes/components/sayknow-pet-widget.ts +20 -8
- package/src/modes/components/session-observer-overlay.ts +187 -32
- package/src/modes/components/settings-selector.ts +60 -18
- package/src/modes/components/tool-execution.ts +138 -27
- package/src/modes/components/tool-status-header.ts +26 -8
- package/src/modes/components/welcome.ts +50 -23
- package/src/modes/controllers/btw-controller.ts +119 -36
- package/src/modes/controllers/command-controller.ts +101 -54
- package/src/modes/controllers/event-controller.ts +119 -27
- package/src/modes/controllers/extension-ui-controller.ts +23 -12
- package/src/modes/controllers/input-controller.ts +100 -8
- package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -6
- package/src/modes/controllers/selector-controller.ts +4 -1
- package/src/modes/interactive-mode.ts +201 -60
- package/src/modes/irc-observation-ledger.ts +71 -15
- package/src/modes/prompt-action-autocomplete.ts +32 -13
- package/src/modes/prompt-suggestion-controller.ts +96 -0
- package/src/modes/runtime-init.ts +20 -2
- package/src/modes/shared/agent-wire/command-dispatch.ts +3 -3
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -2
- package/src/modes/types.ts +6 -0
- package/src/modes/utils/hotkeys-markdown.ts +64 -36
- package/src/modes/utils/ui-helpers.ts +99 -4
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/architect.md +17 -3
- package/src/prompts/agents/critic.md +17 -2
- package/src/prompts/agents/executor.md +1 -1
- package/src/prompts/agents/planner.md +8 -1
- package/src/prompts/system/btw-user.md +3 -8
- package/src/prompts/system/prompt-suggestion-system.md +32 -0
- package/src/prompts/system/system-prompt.md +6 -3
- package/src/prompts/tools/cron.md +3 -1
- package/src/prompts/tools/read.md +4 -2
- package/src/prompts/tools/skill-discovery.md +1 -0
- package/src/runtime/memory-domain.ts +66 -0
- package/src/runtime/memory-guard-contract.ts +73 -0
- package/src/runtime/memory-guard.ts +292 -0
- package/src/runtime/memory-limit.ts +50 -0
- package/src/runtime-mcp/client.ts +41 -55
- package/src/runtime-mcp/content-limits.ts +71 -0
- package/src/runtime-mcp/discoverable-tool-metadata.ts +1 -1
- package/src/runtime-mcp/json-rpc.ts +28 -11
- package/src/runtime-mcp/manager.ts +77 -59
- package/src/runtime-mcp/oauth-flow.ts +0 -72
- package/src/runtime-mcp/plugin-network-boundary.ts +101 -0
- package/src/runtime-mcp/redaction.ts +30 -0
- package/src/runtime-mcp/smithery-auth.ts +17 -2
- package/src/runtime-mcp/smithery-connect.ts +11 -1
- package/src/runtime-mcp/transports/http.ts +63 -22
- package/src/sdk/acp/adapter.ts +8 -1
- package/src/sdk/acp/final-text.ts +40 -0
- package/src/sdk/acp/mcp.ts +26 -0
- package/src/sdk/broker/broker.ts +34 -20
- package/src/sdk/broker/identity.ts +22 -12
- package/src/sdk/broker/lifecycle.ts +293 -43
- package/src/sdk/broker/session-index.ts +11 -1
- package/src/sdk/bus/chat-daemon-cli.ts +2 -2
- package/src/sdk/bus/chat-daemon-control.ts +22 -5
- package/src/sdk/bus/config-commands.ts +2 -2
- package/src/sdk/bus/config.ts +10 -2
- package/src/sdk/bus/control-drain-lease.ts +104 -0
- package/src/sdk/bus/conversation-store.ts +40 -6
- package/src/sdk/bus/daemon-paths.ts +2 -0
- package/src/sdk/bus/index.ts +793 -121
- package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
- package/src/sdk/bus/lifecycle-commands.ts +63 -10
- package/src/sdk/bus/lifecycle-control-runtime.ts +11 -2
- package/src/sdk/bus/lifecycle-orchestrator.ts +32 -1
- package/src/sdk/bus/notification-orchestration.ts +12 -0
- package/src/sdk/bus/notification-service.ts +87 -25
- package/src/sdk/bus/operator-runtime.ts +31 -5
- package/src/sdk/bus/prompt-reconciliation.ts +240 -0
- package/src/sdk/bus/rate-limit-pool.ts +8 -0
- package/src/sdk/bus/recent-activity.ts +90 -26
- package/src/sdk/bus/reconciliation-store.ts +224 -0
- package/src/sdk/bus/telegram-cli.ts +6 -13
- package/src/sdk/bus/telegram-daemon-cli.ts +8 -3
- package/src/sdk/bus/telegram-daemon-contract.ts +34 -9
- package/src/sdk/bus/telegram-daemon-control.ts +161 -40
- package/src/sdk/bus/telegram-daemon.ts +3649 -593
- package/src/sdk/bus/telegram-reference.ts +20 -2
- package/src/sdk/bus/topic-registry.ts +451 -12
- package/src/sdk/cli/session-cli.ts +15 -2
- package/src/sdk/client/discovery.ts +19 -3
- package/src/sdk/client/liveness.ts +49 -0
- package/src/sdk/host/control/dispatch.ts +8 -2
- package/src/sdk/host/control/operations.ts +3 -2
- package/src/sdk/host/host.ts +27 -9
- package/src/sdk/host/query/handlers.ts +125 -5
- package/src/sdk/index.ts +12 -0
- package/src/sdk/lifecycle-session.ts +19 -3
- package/src/sdk/mcp/server.ts +46 -18
- package/src/sdk/prompt-status.ts +97 -0
- package/src/sdk/protocol/operation-inventory.generated.json +145 -0
- package/src/sdk/protocol/operation-registry.ts +24 -4
- package/src/sdk/session-directory.ts +5 -1
- package/src/sdk/session.ts +69 -8
- package/src/sdk/startup-capability.ts +15 -1
- package/src/sdk/transport/auth-preface.ts +82 -0
- package/src/sdk/transport/index.ts +18 -0
- package/src/sdk/transport/relay.ts +252 -0
- package/src/sdk/transport/serve-cli.ts +105 -0
- package/src/sdk/transport/socket.ts +197 -0
- package/src/sdk/transport/stdio.ts +17 -0
- package/src/session/agent-session.ts +1112 -314
- package/src/session/blob-store.ts +25 -7
- package/src/session/btw-contract.ts +59 -0
- package/src/session/fallback-chain-controller.ts +47 -8
- package/src/session/internal/managed-session-scope.ts +1426 -259
- package/src/session/internal/managed-session-storage.ts +414 -238
- package/src/session/internal/native-publish-outcome.ts +271 -0
- package/src/session/memory-guard-checkpoint-participant.ts +131 -0
- package/src/session/session-manager.ts +2079 -469
- package/src/session/session-storage.ts +151 -11
- package/src/session/streaming-output.ts +262 -43
- package/src/setup/credential-import.ts +28 -3
- package/src/setup/provider-onboarding.ts +49 -5
- package/src/setup/provider-presets.json +2 -1
- package/src/skc-runtime/deep-interview-runtime.ts +303 -36
- package/src/skc-runtime/deep-interview-stage.ts +1016 -0
- package/src/skc-runtime/deep-interview-state.ts +8 -5
- package/src/skc-runtime/gc-render.ts +1 -0
- package/src/skc-runtime/gc-runtime.ts +11 -1
- package/src/skc-runtime/linux-proc.ts +70 -36
- package/src/skc-runtime/managed-owner-supervisor.ts +83 -4
- package/src/skc-runtime/memory-guard-owner-claims.ts +389 -0
- package/src/skc-runtime/ralplan-runtime.ts +1057 -75
- package/src/skc-runtime/repository-binding.ts +267 -0
- package/src/skc-runtime/session-state-sidecar.ts +25 -9
- package/src/skc-runtime/state-runtime.ts +50 -12
- package/src/skc-runtime/state-writer.ts +68 -56
- package/src/skc-runtime/team-launch.ts +34 -5
- package/src/skc-runtime/team-runtime.ts +41 -1
- package/src/skc-runtime/team-store.ts +32 -0
- package/src/skc-runtime/team-worker-memory-guard.ts +363 -0
- package/src/skc-runtime/team-workers.ts +1 -0
- package/src/skc-runtime/tmux-common.ts +13 -2
- package/src/skc-runtime/tmux-owner-isolation.ts +20 -1
- package/src/skc-runtime/tmux-sessions.ts +45 -6
- package/src/skc-runtime/ultragoal-guard.ts +93 -15
- package/src/skc-runtime/ultragoal-receipt-freshness.ts +123 -0
- package/src/skc-runtime/ultragoal-runtime.ts +469 -38
- package/src/skc-runtime/workflow-manifest.generated.json +195 -5
- package/src/skc-runtime/workflow-manifest.ts +67 -3
- package/src/skill-state/workflow-hud.ts +25 -2
- package/src/skill-state/workflow-mutation-guard.ts +104 -12
- package/src/slash-commands/builtin-registry.ts +1 -1
- package/src/ssh/utils.ts +14 -0
- package/src/task/discovery.ts +8 -2
- package/src/task/executor.ts +165 -47
- package/src/task/index.ts +123 -15
- package/src/task/provider-retry-status.ts +88 -0
- package/src/task/receipt.ts +3 -0
- package/src/task/render.ts +45 -26
- package/src/task/skc-command.ts +2 -2
- package/src/task/types.ts +55 -10
- package/src/task/ultragoal-redteam-activation.ts +75 -0
- package/src/tools/ask.ts +1 -1
- package/src/tools/ast-edit.ts +2 -2
- package/src/tools/bash-allowed-prefixes.ts +45 -1
- package/src/tools/bash-pty-selection.ts +2 -2
- package/src/tools/browser/launch.ts +41 -6
- package/src/tools/browser/screenshot-format.ts +6 -1
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +127 -154
- package/src/tools/image-gen.ts +476 -23
- package/src/tools/index.ts +7 -1
- package/src/tools/output-meta.ts +176 -9
- package/src/tools/path-utils.ts +5 -1
- package/src/tools/read-internals.ts +44 -0
- package/src/tools/read.ts +1544 -310
- package/src/tools/resource-gc.ts +665 -125
- package/src/tools/skill-discovery.ts +39 -3
- package/src/tools/sqlite-reader.ts +63 -5
- package/src/tools/subagent-render.ts +74 -16
- package/src/tools/subagent.ts +2 -0
- package/src/tools/tool-result.ts +14 -1
- package/src/utils/edit-mode.ts +2 -2
- package/src/utils/pasted-image-path.ts +15 -6
- package/src/utils/prompt-suggestion.ts +265 -0
- package/src/utils/shell-snapshot.ts +173 -63
- package/src/utils/sixel.ts +3 -3
- package/src/web/insane/bridge.ts +5 -1
- package/src/web/insane/url-guard.ts +140 -27
- package/src/web/scrapers/docs-rs.ts +30 -5
- package/src/web/scrapers/types.ts +19 -49
- package/src/web/scrapers/utils.ts +12 -26
- package/src/web/search/providers/codex.ts +1 -1
- package/src/workflow/workflow-intent-diff.ts +4 -1
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
2
2
|
import type { Api, Model } from "@sayknow-cli/ai";
|
|
3
|
-
import { $
|
|
3
|
+
import { $pickenv } from "@sayknow-cli/utils";
|
|
4
4
|
import { parseFileDiffs } from "../../commit/git/diff";
|
|
5
5
|
import type { ConventionalAnalysis } from "../../commit/types";
|
|
6
6
|
import { isExcludedFile } from "../../commit/utils/exclusions";
|
|
@@ -34,7 +34,7 @@ export interface MapReduceInput {
|
|
|
34
34
|
}
|
|
35
35
|
|
|
36
36
|
export function shouldUseMapReduce(diff: string, settings?: MapReduceSettings): boolean {
|
|
37
|
-
if ($
|
|
37
|
+
if ($pickenv("SKC_COMMIT_MAP_REDUCE", "PI_COMMIT_MAP_REDUCE")?.toLowerCase() === "false") return false;
|
|
38
38
|
if (settings?.enabled === false) return false;
|
|
39
39
|
const minFiles = settings?.minFiles ?? MIN_FILES_FOR_MAP_REDUCE;
|
|
40
40
|
const maxFileTokens = settings?.maxFileTokens ?? MAX_FILE_TOKENS;
|
|
@@ -5,6 +5,7 @@ import {
|
|
|
5
5
|
type KeybindingDefinitions,
|
|
6
6
|
type KeybindingsConfig,
|
|
7
7
|
type KeyId,
|
|
8
|
+
parseKeyId,
|
|
8
9
|
setKeybindings,
|
|
9
10
|
TUI_KEYBINDINGS,
|
|
10
11
|
KeybindingsManager as TuiKeybindingsManager,
|
|
@@ -172,7 +173,7 @@ export const KEYBINDINGS = {
|
|
|
172
173
|
},
|
|
173
174
|
"app.session.fork": {
|
|
174
175
|
defaultKeys: [],
|
|
175
|
-
description: "
|
|
176
|
+
description: "Branch from message",
|
|
176
177
|
},
|
|
177
178
|
"app.session.resume": {
|
|
178
179
|
defaultKeys: [],
|
|
@@ -352,10 +353,29 @@ function toKeybindingsConfig(value: unknown): KeybindingsConfig {
|
|
|
352
353
|
logger.info("Ignoring unknown keybinding entry", { key });
|
|
353
354
|
continue;
|
|
354
355
|
}
|
|
355
|
-
if (val === undefined)
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
356
|
+
if (val === undefined) {
|
|
357
|
+
config[key] = undefined;
|
|
358
|
+
continue;
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
const keys = typeof val === "string" ? [val] : Array.isArray(val) ? val : undefined;
|
|
362
|
+
if (!keys?.every(keyValue => typeof keyValue === "string")) {
|
|
363
|
+
logger.info("Ignoring malformed keybinding entry", { key });
|
|
364
|
+
continue;
|
|
365
|
+
}
|
|
366
|
+
|
|
367
|
+
const normalizedKeys: KeyId[] = [];
|
|
368
|
+
for (const keyValue of keys) {
|
|
369
|
+
const parsedKey = parseKeyId(keyValue);
|
|
370
|
+
if (!parsedKey) {
|
|
371
|
+
logger.info("Ignoring invalid keybinding entry", { key, category: "invalid-keybinding" });
|
|
372
|
+
normalizedKeys.length = 0;
|
|
373
|
+
break;
|
|
374
|
+
}
|
|
375
|
+
normalizedKeys.push(parsedKey.keyId);
|
|
376
|
+
}
|
|
377
|
+
if (normalizedKeys.length !== keys.length) continue;
|
|
378
|
+
config[key] = typeof val === "string" ? normalizedKeys[0] : normalizedKeys;
|
|
359
379
|
}
|
|
360
380
|
return config;
|
|
361
381
|
}
|
|
@@ -461,11 +481,18 @@ function migrateKeybindingsConfigFile(agentDir: string): void {
|
|
|
461
481
|
*/
|
|
462
482
|
export class KeybindingsManager extends TuiKeybindingsManager {
|
|
463
483
|
#configPath: string | undefined;
|
|
484
|
+
#displayContext: KeyDisplayContext = runtimeKeyDisplayContext;
|
|
464
485
|
|
|
465
486
|
constructor(userBindings: KeybindingsConfig = {}, configPath?: string) {
|
|
466
|
-
super(KEYBINDINGS, userBindings);
|
|
487
|
+
super(KEYBINDINGS, toKeybindingsConfig(userBindings));
|
|
467
488
|
this.#configPath = configPath;
|
|
468
489
|
}
|
|
490
|
+
/**
|
|
491
|
+
* Replace user bindings only after canonical grammar validation.
|
|
492
|
+
*/
|
|
493
|
+
override setUserBindings(userBindings: KeybindingsConfig): void {
|
|
494
|
+
super.setUserBindings(toKeybindingsConfig(userBindings));
|
|
495
|
+
}
|
|
469
496
|
|
|
470
497
|
/**
|
|
471
498
|
* Create from config file at agentDir/keybindings.json.
|
|
@@ -485,6 +512,13 @@ export class KeybindingsManager extends TuiKeybindingsManager {
|
|
|
485
512
|
static inMemory(userBindings: KeybindingsConfig = {}): KeybindingsManager {
|
|
486
513
|
return new KeybindingsManager(userBindings);
|
|
487
514
|
}
|
|
515
|
+
/**
|
|
516
|
+
* Set the default display context used by composed surfaces that do not
|
|
517
|
+
* supply an explicit context.
|
|
518
|
+
*/
|
|
519
|
+
setDisplayContext(context: KeyDisplayContext): void {
|
|
520
|
+
this.#displayContext = context;
|
|
521
|
+
}
|
|
488
522
|
|
|
489
523
|
/**
|
|
490
524
|
* Reload keybindings from the config file.
|
|
@@ -504,9 +538,29 @@ export class KeybindingsManager extends TuiKeybindingsManager {
|
|
|
504
538
|
/**
|
|
505
539
|
* Get display string for a keybinding (e.g., "ctrl+c/escape").
|
|
506
540
|
*/
|
|
507
|
-
getDisplayString(keybinding: Keybinding): string {
|
|
541
|
+
getDisplayString(keybinding: Keybinding, context: KeyDisplayContext = this.#displayContext): string {
|
|
542
|
+
const keys = this.getKeys(keybinding);
|
|
543
|
+
return formatKeyHints(keys, context);
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Get an accessibility-oriented display string for help surfaces.
|
|
547
|
+
* Darwin chords include both the concise glyphs and expanded key names.
|
|
548
|
+
*/
|
|
549
|
+
getAccessibleDisplayString(keybinding: Keybinding, context: KeyDisplayContext = this.#displayContext): string {
|
|
508
550
|
const keys = this.getKeys(keybinding);
|
|
509
|
-
return
|
|
551
|
+
return formatAccessibleKeyHints(keys, context);
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Format a fixed key chord using this manager's display context.
|
|
555
|
+
*/
|
|
556
|
+
formatKeyHint(key: string): string {
|
|
557
|
+
return formatKeyHint(key, this.#displayContext);
|
|
558
|
+
}
|
|
559
|
+
/**
|
|
560
|
+
* Format a fixed key chord for accessibility-oriented help surfaces.
|
|
561
|
+
*/
|
|
562
|
+
formatAccessibleKeyHint(key: string): string {
|
|
563
|
+
return formatAccessibleKeyHint(key, this.#displayContext);
|
|
510
564
|
}
|
|
511
565
|
|
|
512
566
|
/**
|
|
@@ -520,13 +574,20 @@ export class KeybindingsManager extends TuiKeybindingsManager {
|
|
|
520
574
|
/**
|
|
521
575
|
* Key hint formatting utilities for UI labels.
|
|
522
576
|
*/
|
|
523
|
-
|
|
577
|
+
export interface KeyDisplayContext {
|
|
578
|
+
platform: NodeJS.Platform;
|
|
579
|
+
}
|
|
580
|
+
|
|
581
|
+
const runtimeKeyDisplayContext: KeyDisplayContext = { platform: process.platform };
|
|
582
|
+
|
|
583
|
+
const TEXTUAL_MODIFIER_LABELS: Record<string, string> = {
|
|
524
584
|
ctrl: "Ctrl",
|
|
525
|
-
shift: "Shift",
|
|
526
585
|
alt: "Alt",
|
|
586
|
+
shift: "Shift",
|
|
587
|
+
super: "Super",
|
|
527
588
|
};
|
|
528
589
|
|
|
529
|
-
const
|
|
590
|
+
const TEXTUAL_KEY_LABELS: Record<string, string> = {
|
|
530
591
|
esc: "Esc",
|
|
531
592
|
escape: "Esc",
|
|
532
593
|
enter: "Enter",
|
|
@@ -535,33 +596,105 @@ const KEY_LABELS: Record<string, string> = {
|
|
|
535
596
|
tab: "Tab",
|
|
536
597
|
backspace: "Backspace",
|
|
537
598
|
delete: "Delete",
|
|
599
|
+
insert: "Insert",
|
|
600
|
+
clear: "Clear",
|
|
538
601
|
home: "Home",
|
|
539
602
|
end: "End",
|
|
540
|
-
|
|
541
|
-
|
|
603
|
+
pageUp: "PgUp",
|
|
604
|
+
pageDown: "PgDn",
|
|
542
605
|
up: "Up",
|
|
543
606
|
down: "Down",
|
|
544
607
|
left: "Left",
|
|
545
608
|
right: "Right",
|
|
546
609
|
};
|
|
547
610
|
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
611
|
+
const DARWIN_MODIFIER_LABELS: Record<string, string> = {
|
|
612
|
+
ctrl: "⌃",
|
|
613
|
+
alt: "⌥",
|
|
614
|
+
shift: "⇧",
|
|
615
|
+
super: "⌘",
|
|
616
|
+
};
|
|
617
|
+
|
|
618
|
+
const DARWIN_KEY_LABELS: Record<string, string> = {
|
|
619
|
+
...TEXTUAL_KEY_LABELS,
|
|
620
|
+
esc: "⎋",
|
|
621
|
+
escape: "⎋",
|
|
622
|
+
enter: "↩",
|
|
623
|
+
return: "↩",
|
|
624
|
+
tab: "⇥",
|
|
625
|
+
backspace: "⌫",
|
|
626
|
+
delete: "⌦",
|
|
627
|
+
up: "↑",
|
|
628
|
+
down: "↓",
|
|
629
|
+
left: "←",
|
|
630
|
+
right: "→",
|
|
631
|
+
};
|
|
632
|
+
const DARWIN_ACCESSIBLE_MODIFIER_LABELS: Record<string, string> = {
|
|
633
|
+
ctrl: "Control",
|
|
634
|
+
alt: "Option",
|
|
635
|
+
shift: "Shift",
|
|
636
|
+
super: "Command",
|
|
637
|
+
};
|
|
638
|
+
|
|
639
|
+
const DARWIN_ACCESSIBLE_KEY_LABELS: Record<string, string> = {
|
|
640
|
+
...TEXTUAL_KEY_LABELS,
|
|
641
|
+
esc: "Escape",
|
|
642
|
+
escape: "Escape",
|
|
643
|
+
pageUp: "Page Up",
|
|
644
|
+
pageDown: "Page Down",
|
|
645
|
+
};
|
|
646
|
+
|
|
647
|
+
const DISPLAY_MODIFIER_ORDER = ["ctrl", "alt", "shift", "super"] as const;
|
|
648
|
+
const INVALID_KEYBINDING_DISPLAY = "Invalid keybinding";
|
|
649
|
+
|
|
650
|
+
function formatBaseKey(baseKey: string, labels: Record<string, string>): string {
|
|
651
|
+
const label = labels[baseKey];
|
|
553
652
|
if (label) return label;
|
|
554
|
-
if (
|
|
555
|
-
return `${
|
|
653
|
+
if (baseKey.length === 1) return baseKey.toUpperCase();
|
|
654
|
+
return `${baseKey.charAt(0).toUpperCase()}${baseKey.slice(1)}`;
|
|
655
|
+
}
|
|
656
|
+
|
|
657
|
+
export function formatKeyHint(key: string, context: KeyDisplayContext = runtimeKeyDisplayContext): string {
|
|
658
|
+
const parsed = parseKeyId(key);
|
|
659
|
+
if (!parsed) return INVALID_KEYBINDING_DISPLAY;
|
|
660
|
+
|
|
661
|
+
const darwin = context.platform === "darwin";
|
|
662
|
+
const modifierLabels = darwin ? DARWIN_MODIFIER_LABELS : TEXTUAL_MODIFIER_LABELS;
|
|
663
|
+
const baseLabels = darwin ? DARWIN_KEY_LABELS : TEXTUAL_KEY_LABELS;
|
|
664
|
+
const modifiers = DISPLAY_MODIFIER_ORDER.filter(modifier => parsed.modifiers.includes(modifier)).map(
|
|
665
|
+
modifier => modifierLabels[modifier],
|
|
666
|
+
);
|
|
667
|
+
const parts = [...modifiers, formatBaseKey(parsed.baseKey, baseLabels)];
|
|
668
|
+
return parts.join(darwin ? "" : "+");
|
|
669
|
+
}
|
|
670
|
+
|
|
671
|
+
export function formatAccessibleKeyHint(key: string, context: KeyDisplayContext = runtimeKeyDisplayContext): string {
|
|
672
|
+
const concise = formatKeyHint(key, context);
|
|
673
|
+
if (context.platform !== "darwin" || concise === INVALID_KEYBINDING_DISPLAY) return concise;
|
|
674
|
+
|
|
675
|
+
const parsed = parseKeyId(key);
|
|
676
|
+
if (!parsed) return INVALID_KEYBINDING_DISPLAY;
|
|
677
|
+
const modifiers = DISPLAY_MODIFIER_ORDER.filter(modifier => parsed.modifiers.includes(modifier)).map(
|
|
678
|
+
modifier => DARWIN_ACCESSIBLE_MODIFIER_LABELS[modifier],
|
|
679
|
+
);
|
|
680
|
+
const expanded = [...modifiers, formatBaseKey(parsed.baseKey, DARWIN_ACCESSIBLE_KEY_LABELS)].join("+");
|
|
681
|
+
return concise === expanded ? concise : `${concise} (${expanded})`;
|
|
556
682
|
}
|
|
557
683
|
|
|
558
|
-
export function
|
|
559
|
-
|
|
684
|
+
export function formatKeyHints(
|
|
685
|
+
keys: string | readonly string[],
|
|
686
|
+
context: KeyDisplayContext = runtimeKeyDisplayContext,
|
|
687
|
+
): string {
|
|
688
|
+
const list: readonly string[] = typeof keys === "string" ? [keys] : keys;
|
|
689
|
+
return list.map(key => formatKeyHint(key, context)).join("/");
|
|
560
690
|
}
|
|
561
691
|
|
|
562
|
-
export function
|
|
563
|
-
|
|
564
|
-
|
|
692
|
+
export function formatAccessibleKeyHints(
|
|
693
|
+
keys: string | readonly string[],
|
|
694
|
+
context: KeyDisplayContext = runtimeKeyDisplayContext,
|
|
695
|
+
): string {
|
|
696
|
+
const list: readonly string[] = typeof keys === "string" ? [keys] : keys;
|
|
697
|
+
return list.map(key => formatAccessibleKeyHint(key, context)).join("/");
|
|
565
698
|
}
|
|
566
699
|
|
|
567
700
|
export type { Keybinding, KeybindingsConfig, KeyId };
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
import { formatModelProfileDisplayLabel, type ModelProfileDefinition } from "./model-profiles";
|
|
2
|
+
|
|
3
|
+
export const MODEL_PROFILE_DISCOVERY_QUERY = "models.profiles.list";
|
|
4
|
+
export const MODEL_PROFILE_ERROR_DETAIL_MAX_BYTES = 2048;
|
|
5
|
+
const REQUESTED_PROFILE_MAX_BYTES = 256;
|
|
6
|
+
|
|
7
|
+
const LEGACY_MODEL_PROFILE_ALIASES: ReadonlyMap<string, string> = new Map([["codex-standard", "codex-medium"]]);
|
|
8
|
+
|
|
9
|
+
export interface ModelProfileCatalogItem {
|
|
10
|
+
id: string;
|
|
11
|
+
displayName: string;
|
|
12
|
+
source: "builtin" | "configured";
|
|
13
|
+
available?: boolean;
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export interface UnknownModelProfileDetails {
|
|
17
|
+
requestedProfile: string;
|
|
18
|
+
availableProfiles: string[];
|
|
19
|
+
discoveryQuery: typeof MODEL_PROFILE_DISCOVERY_QUERY;
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
export interface ModelProfileRegistryErrorDetails {
|
|
23
|
+
requestedProfile?: string;
|
|
24
|
+
availableProfiles: [];
|
|
25
|
+
discoveryQuery: typeof MODEL_PROFILE_DISCOVERY_QUERY;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
export type ModelProfileErrorDetails = UnknownModelProfileDetails | ModelProfileRegistryErrorDetails;
|
|
29
|
+
export type ModelProfileErrorCode = "unknown_model_profile" | "model_profile_registry_error";
|
|
30
|
+
|
|
31
|
+
function truncateUtf8(value: string, maxBytes: number): string {
|
|
32
|
+
if (Buffer.byteLength(value) <= maxBytes) return value;
|
|
33
|
+
let end = value.length;
|
|
34
|
+
while (end > 0 && Buffer.byteLength(value.slice(0, end)) > maxBytes) end--;
|
|
35
|
+
return value.slice(0, end);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
function diagnosticProfileEcho(value: string): string {
|
|
39
|
+
return truncateUtf8(value.normalize("NFKC").replace(/[\p{Cc}\p{Cf}]+/gu, " "), REQUESTED_PROFILE_MAX_BYTES);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function boundedAvailableProfiles(requestedProfile: string, profiles: ReadonlyMap<string, unknown>): string[] {
|
|
43
|
+
const availableProfiles: string[] = [];
|
|
44
|
+
for (const id of [...new Set(profiles.keys())].sort((left, right) => left.localeCompare(right))) {
|
|
45
|
+
const candidate: UnknownModelProfileDetails = {
|
|
46
|
+
requestedProfile,
|
|
47
|
+
availableProfiles: [...availableProfiles, id],
|
|
48
|
+
discoveryQuery: MODEL_PROFILE_DISCOVERY_QUERY,
|
|
49
|
+
};
|
|
50
|
+
if (Buffer.byteLength(JSON.stringify(candidate)) > MODEL_PROFILE_ERROR_DETAIL_MAX_BYTES) continue;
|
|
51
|
+
availableProfiles.push(id);
|
|
52
|
+
}
|
|
53
|
+
return availableProfiles;
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
export class UnknownModelProfileError extends Error {
|
|
57
|
+
readonly code = "unknown_model_profile" as const;
|
|
58
|
+
readonly details: UnknownModelProfileDetails;
|
|
59
|
+
|
|
60
|
+
constructor(requestedProfile: string, profiles: ReadonlyMap<string, unknown>) {
|
|
61
|
+
const echoed = diagnosticProfileEcho(requestedProfile);
|
|
62
|
+
const availableProfiles = boundedAvailableProfiles(echoed, profiles);
|
|
63
|
+
const available = availableProfiles.length > 0 ? availableProfiles.join(", ") : "none";
|
|
64
|
+
super(
|
|
65
|
+
truncateUtf8(
|
|
66
|
+
`Unknown model profile ${JSON.stringify(echoed)}. Available profiles: ${available}. Query ${MODEL_PROFILE_DISCOVERY_QUERY} for the complete catalog.`,
|
|
67
|
+
512,
|
|
68
|
+
),
|
|
69
|
+
);
|
|
70
|
+
this.name = "UnknownModelProfileError";
|
|
71
|
+
this.details = {
|
|
72
|
+
requestedProfile: echoed,
|
|
73
|
+
availableProfiles,
|
|
74
|
+
discoveryQuery: MODEL_PROFILE_DISCOVERY_QUERY,
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
export class ModelProfileRegistryError extends Error {
|
|
80
|
+
readonly code = "model_profile_registry_error" as const;
|
|
81
|
+
readonly details: ModelProfileRegistryErrorDetails;
|
|
82
|
+
|
|
83
|
+
constructor(requestedProfile?: string) {
|
|
84
|
+
super(
|
|
85
|
+
`The model profile registry is unavailable. Query ${MODEL_PROFILE_DISCOVERY_QUERY} after fixing models.yml.`,
|
|
86
|
+
);
|
|
87
|
+
this.name = "ModelProfileRegistryError";
|
|
88
|
+
const echoed = requestedProfile === undefined ? undefined : diagnosticProfileEcho(requestedProfile);
|
|
89
|
+
this.details = {
|
|
90
|
+
...(echoed ? { requestedProfile: echoed } : {}),
|
|
91
|
+
availableProfiles: [],
|
|
92
|
+
discoveryQuery: MODEL_PROFILE_DISCOVERY_QUERY,
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
export function resolveModelProfileName(profileName: string, profiles: ReadonlyMap<string, unknown>): string {
|
|
98
|
+
if (profiles.has(profileName)) return profileName;
|
|
99
|
+
const replacement = LEGACY_MODEL_PROFILE_ALIASES.get(profileName);
|
|
100
|
+
return replacement && profiles.has(replacement) ? replacement : profileName;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
export function validateModelProfileName(
|
|
104
|
+
profileName: string,
|
|
105
|
+
profiles: ReadonlyMap<string, unknown>,
|
|
106
|
+
registryError?: unknown,
|
|
107
|
+
): string {
|
|
108
|
+
if (registryError !== undefined) throw new ModelProfileRegistryError(profileName);
|
|
109
|
+
const resolved = resolveModelProfileName(profileName, profiles);
|
|
110
|
+
if (!profiles.has(resolved)) throw new UnknownModelProfileError(profileName, profiles);
|
|
111
|
+
return resolved;
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
export function projectModelProfileCatalog(
|
|
115
|
+
profiles: ReadonlyMap<string, ModelProfileDefinition>,
|
|
116
|
+
registryError?: unknown,
|
|
117
|
+
): ModelProfileCatalogItem[] {
|
|
118
|
+
if (registryError !== undefined) throw new ModelProfileRegistryError();
|
|
119
|
+
return [...profiles.entries()]
|
|
120
|
+
.map(([id, definition]) => ({
|
|
121
|
+
id,
|
|
122
|
+
displayName: formatModelProfileDisplayLabel(definition),
|
|
123
|
+
source: definition.source === "user" ? ("configured" as const) : ("builtin" as const),
|
|
124
|
+
}))
|
|
125
|
+
.sort((left, right) => left.id.localeCompare(right.id));
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
export function isModelProfileProviderAvailable(
|
|
129
|
+
profile: ModelProfileDefinition,
|
|
130
|
+
authenticatedProviders: ReadonlySet<string>,
|
|
131
|
+
): boolean {
|
|
132
|
+
const alternativeGroups = profile.alternativeProviderGroups ?? [];
|
|
133
|
+
const alternativeProviders = new Set(alternativeGroups.flat());
|
|
134
|
+
for (const provider of profile.requiredProviders) {
|
|
135
|
+
if (!alternativeProviders.has(provider) && !authenticatedProviders.has(provider)) return false;
|
|
136
|
+
}
|
|
137
|
+
return alternativeGroups.every(group => group.some(provider => authenticatedProviders.has(provider)));
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
export function isModelProfileError(value: unknown): value is {
|
|
141
|
+
code: ModelProfileErrorCode;
|
|
142
|
+
message: string;
|
|
143
|
+
details: ModelProfileErrorDetails;
|
|
144
|
+
} {
|
|
145
|
+
if (!value || typeof value !== "object" || Array.isArray(value)) return false;
|
|
146
|
+
const error = value as Record<string, unknown>;
|
|
147
|
+
if (
|
|
148
|
+
(error.code !== "unknown_model_profile" && error.code !== "model_profile_registry_error") ||
|
|
149
|
+
typeof error.message !== "string" ||
|
|
150
|
+
!error.details ||
|
|
151
|
+
typeof error.details !== "object" ||
|
|
152
|
+
Array.isArray(error.details)
|
|
153
|
+
)
|
|
154
|
+
return false;
|
|
155
|
+
const details = error.details as Record<string, unknown>;
|
|
156
|
+
const detailKeys = Object.keys(details);
|
|
157
|
+
if (
|
|
158
|
+
!detailKeys.every(key => key === "requestedProfile" || key === "availableProfiles" || key === "discoveryQuery") ||
|
|
159
|
+
details.discoveryQuery !== MODEL_PROFILE_DISCOVERY_QUERY ||
|
|
160
|
+
!Array.isArray(details.availableProfiles) ||
|
|
161
|
+
!details.availableProfiles.every(id => typeof id === "string") ||
|
|
162
|
+
Buffer.byteLength(JSON.stringify(details)) > MODEL_PROFILE_ERROR_DETAIL_MAX_BYTES ||
|
|
163
|
+
(typeof details.requestedProfile === "string" &&
|
|
164
|
+
Buffer.byteLength(details.requestedProfile) > REQUESTED_PROFILE_MAX_BYTES)
|
|
165
|
+
)
|
|
166
|
+
return false;
|
|
167
|
+
if (error.code === "unknown_model_profile")
|
|
168
|
+
return detailKeys.length === 3 && typeof details.requestedProfile === "string";
|
|
169
|
+
return (
|
|
170
|
+
detailKeys.length === (details.requestedProfile === undefined ? 2 : 3) &&
|
|
171
|
+
details.availableProfiles.length === 0 &&
|
|
172
|
+
(details.requestedProfile === undefined || typeof details.requestedProfile === "string")
|
|
173
|
+
);
|
|
174
|
+
}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
import { sanitizeText } from "@sayknow-cli/utils";
|
|
2
|
-
import type { SkcModelAssignmentTargetId } from "./model-registry";
|
|
3
2
|
import { type ModelSelectorValue, normalizeModelSelectorValue } from "./model-selector-value";
|
|
4
|
-
import type { ModelsConfig } from "./models-config-schema";
|
|
3
|
+
import type { ModelsConfig, SKC_MODEL_ASSIGNMENT_TARGET_IDS } from "./models-config-schema";
|
|
5
4
|
|
|
6
|
-
export type ModelProfileRole =
|
|
5
|
+
export type ModelProfileRole = (typeof SKC_MODEL_ASSIGNMENT_TARGET_IDS)[number];
|
|
7
6
|
|
|
8
7
|
export interface ModelProfileDefinition {
|
|
9
8
|
name: string;
|
|
@@ -101,11 +100,11 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
101
100
|
architect: "opencode-go/deepseek-v4-pro",
|
|
102
101
|
}),
|
|
103
102
|
profile("claude-opus", ["anthropic"], {
|
|
104
|
-
default: "anthropic/claude-opus-
|
|
103
|
+
default: "anthropic/claude-opus-5:xhigh",
|
|
105
104
|
executor: "anthropic/claude-sonnet-5",
|
|
106
|
-
planner: "anthropic/claude-opus-
|
|
107
|
-
critic: "anthropic/claude-opus-
|
|
108
|
-
architect: "anthropic/claude-opus-
|
|
105
|
+
planner: "anthropic/claude-opus-5:low",
|
|
106
|
+
critic: "anthropic/claude-opus-5:high",
|
|
107
|
+
architect: "anthropic/claude-opus-5:xhigh",
|
|
109
108
|
}),
|
|
110
109
|
profile("claude-fable", ["anthropic"], {
|
|
111
110
|
default: "anthropic/claude-fable-5:xhigh",
|
|
@@ -208,6 +207,27 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
208
207
|
critic: "xai/grok-4.3:xhigh",
|
|
209
208
|
architect: "xai/grok-4.3:xhigh",
|
|
210
209
|
}),
|
|
210
|
+
profile("grok-45-eco", ["xai"], {
|
|
211
|
+
default: "xai/grok-4.5:low",
|
|
212
|
+
executor: "xai/grok-4.5:minimal",
|
|
213
|
+
planner: "xai/grok-4.5:low",
|
|
214
|
+
critic: "xai/grok-4.5:medium",
|
|
215
|
+
architect: "xai/grok-4.5:high",
|
|
216
|
+
}),
|
|
217
|
+
profile("grok-45-medium", ["xai"], {
|
|
218
|
+
default: "xai/grok-4.5:medium",
|
|
219
|
+
executor: "xai/grok-4.5:low",
|
|
220
|
+
planner: "xai/grok-4.5:medium",
|
|
221
|
+
critic: "xai/grok-4.5:high",
|
|
222
|
+
architect: "xai/grok-4.5:high",
|
|
223
|
+
}),
|
|
224
|
+
profile("grok-45-pro", ["xai"], {
|
|
225
|
+
default: "xai/grok-4.5:high",
|
|
226
|
+
executor: "xai/grok-4.5:medium",
|
|
227
|
+
planner: "xai/grok-4.5:high",
|
|
228
|
+
critic: "xai/grok-4.5:high",
|
|
229
|
+
architect: "xai/grok-4.5:high",
|
|
230
|
+
}),
|
|
211
231
|
profile("grok-build-pro", ["grok-build"], {
|
|
212
232
|
default: "grok-build/grok-composer-2.5-fast",
|
|
213
233
|
executor: "grok-build/grok-build",
|
|
@@ -257,8 +277,22 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
257
277
|
critic: "minimax-code/minimax-m3:xhigh",
|
|
258
278
|
architect: "minimax-code/minimax-m3:xhigh",
|
|
259
279
|
}),
|
|
280
|
+
profile("alibaba-token-plan-balanced", ["alibaba-token-plan"], {
|
|
281
|
+
default: "alibaba-token-plan/qwen3.8-max-preview:medium",
|
|
282
|
+
executor: "alibaba-token-plan/deepseek-v4-pro:xhigh",
|
|
283
|
+
planner: "alibaba-token-plan/glm-5.2:high",
|
|
284
|
+
architect: "alibaba-token-plan/qwen3.8-max-preview:xhigh",
|
|
285
|
+
critic: "alibaba-token-plan/glm-5.2:high",
|
|
286
|
+
}),
|
|
287
|
+
profile("alibaba-token-plan-qwenmaxxing", ["alibaba-token-plan"], {
|
|
288
|
+
default: "alibaba-token-plan/qwen3.8-max-preview:medium",
|
|
289
|
+
executor: "alibaba-token-plan/qwen3.8-max-preview:low",
|
|
290
|
+
planner: "alibaba-token-plan/qwen3.8-max-preview:medium",
|
|
291
|
+
architect: "alibaba-token-plan/qwen3.8-max-preview:xhigh",
|
|
292
|
+
critic: "alibaba-token-plan/qwen3.8-max-preview:xhigh",
|
|
293
|
+
}),
|
|
260
294
|
profile("opus-codex", ["anthropic", "openai-codex"], {
|
|
261
|
-
default: "anthropic/claude-opus-
|
|
295
|
+
default: "anthropic/claude-opus-5:xhigh",
|
|
262
296
|
executor: "openai-codex/gpt-5.6-terra:low",
|
|
263
297
|
planner: "anthropic/claude-sonnet-5",
|
|
264
298
|
critic: "openai-codex/gpt-5.6-sol:xhigh",
|
|
@@ -274,8 +308,8 @@ export const BUILTIN_MODEL_PROFILES: readonly ModelProfileDefinition[] = [
|
|
|
274
308
|
profile("fable-opus-codex", ["anthropic", "openai-codex"], {
|
|
275
309
|
default: "anthropic/claude-fable-5:high",
|
|
276
310
|
executor: "openai-codex/gpt-5.6-terra:medium",
|
|
277
|
-
planner: "anthropic/claude-opus-
|
|
278
|
-
critic: "anthropic/claude-opus-
|
|
311
|
+
planner: "anthropic/claude-opus-5:medium",
|
|
312
|
+
critic: "anthropic/claude-opus-5:high",
|
|
279
313
|
architect: "openai-codex/gpt-5.6-sol:xhigh",
|
|
280
314
|
}),
|
|
281
315
|
];
|
|
@@ -308,6 +342,9 @@ const PROFILE_PRESENTATION: Record<string, ModelProfilePresentation> = {
|
|
|
308
342
|
"grok-eco": { displayName: "Grok Eco", providerGroup: "GROK" },
|
|
309
343
|
"grok-medium": { displayName: "Grok Medium", providerGroup: "GROK" },
|
|
310
344
|
"grok-pro": { displayName: "Grok Pro", providerGroup: "GROK" },
|
|
345
|
+
"grok-45-eco": { displayName: "Grok 4.5 Eco", providerGroup: "GROK" },
|
|
346
|
+
"grok-45-medium": { displayName: "Grok 4.5 Medium", providerGroup: "GROK" },
|
|
347
|
+
"grok-45-pro": { displayName: "Grok 4.5 Pro", providerGroup: "GROK" },
|
|
311
348
|
"grok-build-pro": { displayName: "Grok Build Pro", providerGroup: "GROK" },
|
|
312
349
|
"cursor-eco": { displayName: "Cursor Eco", providerGroup: "CURSOR" },
|
|
313
350
|
"cursor-medium": { displayName: "Cursor Medium", providerGroup: "CURSOR" },
|
|
@@ -315,6 +352,8 @@ const PROFILE_PRESENTATION: Record<string, ModelProfilePresentation> = {
|
|
|
315
352
|
"minimax-eco": { displayName: "MiniMax Eco", providerGroup: "MINIMAX" },
|
|
316
353
|
"minimax-medium": { displayName: "MiniMax Medium", providerGroup: "MINIMAX" },
|
|
317
354
|
"minimax-pro": { displayName: "MiniMax Pro", providerGroup: "MINIMAX" },
|
|
355
|
+
"alibaba-token-plan-balanced": { displayName: "Balanced", providerGroup: "ALIBABA TOKEN PLAN" },
|
|
356
|
+
"alibaba-token-plan-qwenmaxxing": { displayName: "QwenMaxxing", providerGroup: "ALIBABA TOKEN PLAN" },
|
|
318
357
|
"opus-codex": { displayName: "Opus + Codex", providerGroup: "COMBOS" },
|
|
319
358
|
"codex-opencodego": { displayName: "Codex + OpenCodeGo", providerGroup: "COMBOS" },
|
|
320
359
|
"fable-opus-codex": { displayName: "Fable + Opus + Codex", providerGroup: "COMBOS" },
|
|
@@ -330,6 +369,7 @@ const PROFILE_GROUP_ORDER = [
|
|
|
330
369
|
"GROK",
|
|
331
370
|
"CURSOR",
|
|
332
371
|
"MINIMAX",
|
|
372
|
+
"ALIBABA TOKEN PLAN",
|
|
333
373
|
"COMBOS",
|
|
334
374
|
];
|
|
335
375
|
|
|
@@ -347,6 +387,7 @@ const PROFILE_RECOMMENDATIONS: Record<string, string> = {
|
|
|
347
387
|
"grok-build": "grok-build-pro",
|
|
348
388
|
cursor: "cursor-medium",
|
|
349
389
|
"minimax-code": "minimax-medium",
|
|
390
|
+
"alibaba-token-plan": "alibaba-token-plan-balanced",
|
|
350
391
|
};
|
|
351
392
|
|
|
352
393
|
export function getModelProfilePresentation(
|
|
@@ -33,7 +33,7 @@ const DEFAULT_LOCAL_TOKEN = "lm-studio-local";
|
|
|
33
33
|
|
|
34
34
|
import { registerOAuthProvider, unregisterOAuthProviders } from "@sayknow-cli/ai/utils/oauth";
|
|
35
35
|
import type { OAuthCredentials, OAuthLoginCallbacks } from "@sayknow-cli/ai/utils/oauth/types";
|
|
36
|
-
import { $
|
|
36
|
+
import { $pickCredentialEnv, isRecord, logger } from "@sayknow-cli/utils";
|
|
37
37
|
import { parseModelString, resolveProviderModelReference } from "../config/model-resolver";
|
|
38
38
|
import { isValidThemeColor, type ThemeColor } from "../modes/theme/theme";
|
|
39
39
|
import type { AuthStorage, OAuthCredential } from "../session/auth-storage";
|
|
@@ -52,6 +52,7 @@ import {
|
|
|
52
52
|
type ModelProfileDefinition,
|
|
53
53
|
mergeModelProfiles,
|
|
54
54
|
} from "./model-profiles";
|
|
55
|
+
import type { ModelSelectorValue } from "./model-selector-value";
|
|
55
56
|
import {
|
|
56
57
|
type ModelOverride,
|
|
57
58
|
type ModelProfileConfig,
|
|
@@ -61,7 +62,6 @@ import {
|
|
|
61
62
|
type ProviderAuthMode,
|
|
62
63
|
type ProviderDiscovery,
|
|
63
64
|
} from "./models-config-schema";
|
|
64
|
-
import { type ModelSelectorValue } from "./model-selector-value";
|
|
65
65
|
import { type Settings, settings } from "./settings";
|
|
66
66
|
|
|
67
67
|
export type { CanonicalModelIndex, CanonicalModelRecord, CanonicalModelVariant, ModelEquivalenceConfig };
|
|
@@ -438,8 +438,20 @@ function getProviderBaseUrlEnvKeys(provider: string): string[] {
|
|
|
438
438
|
return keys;
|
|
439
439
|
}
|
|
440
440
|
|
|
441
|
+
/**
|
|
442
|
+
* Provider base URL from the environment, trusted sources only.
|
|
443
|
+
*
|
|
444
|
+
* The result is baked into the provider override and reaches `model.baseUrl`,
|
|
445
|
+
* which the provider resolvers use as the request endpoint that carries the
|
|
446
|
+
* provider credential. `$env` (and therefore `$pickenv`) merges the caller's
|
|
447
|
+
* `cwd/.env`, so reading it there would let repository content redirect
|
|
448
|
+
* authenticated traffic for any provider — including re-admitting a redirect
|
|
449
|
+
* that the provider-level resolvers already reject. Resolve it the same way
|
|
450
|
+
* provider credentials are: launching shell plus SKC/user-owned `.env` files,
|
|
451
|
+
* never the project `.env`.
|
|
452
|
+
*/
|
|
441
453
|
function resolveProviderBaseUrlFromEnv(provider: string): string | undefined {
|
|
442
|
-
return $
|
|
454
|
+
return $pickCredentialEnv(...getProviderBaseUrlEnvKeys(provider));
|
|
443
455
|
}
|
|
444
456
|
|
|
445
457
|
function normalizeLocalOpenAICompatBaseUrl(baseUrl: string): string {
|
|
@@ -2613,6 +2625,13 @@ export class ModelRegistry {
|
|
|
2613
2625
|
return this.#keylessProviders.has(model.provider) || this.authStorage.hasAuth(model.provider);
|
|
2614
2626
|
}
|
|
2615
2627
|
|
|
2628
|
+
/**
|
|
2629
|
+
* Check whether auth is configured for a provider.
|
|
2630
|
+
*/
|
|
2631
|
+
hasConfiguredProviderAuth(provider: string): boolean {
|
|
2632
|
+
return this.#keylessProviders.has(provider) || this.authStorage.hasAuth(provider);
|
|
2633
|
+
}
|
|
2634
|
+
|
|
2616
2635
|
getDiscoverableProviders(): string[] {
|
|
2617
2636
|
const disabledProviders = getDisabledProviderIdsFromSettings();
|
|
2618
2637
|
return this.#discoverableProviders
|
|
@@ -2663,7 +2682,7 @@ export class ModelRegistry {
|
|
|
2663
2682
|
async getApiKey(
|
|
2664
2683
|
model: Model<Api>,
|
|
2665
2684
|
sessionId?: string,
|
|
2666
|
-
options: { credentialSelector?: AuthCredentialSelector } = {},
|
|
2685
|
+
options: { credentialSelector?: AuthCredentialSelector; signal?: AbortSignal } = {},
|
|
2667
2686
|
): Promise<string | undefined> {
|
|
2668
2687
|
if (this.#keylessProviders.has(model.provider) && !this.authStorage.hasAuth(model.provider)) {
|
|
2669
2688
|
return kNoAuth;
|
|
@@ -2672,6 +2691,7 @@ export class ModelRegistry {
|
|
|
2672
2691
|
baseUrl: model.baseUrl,
|
|
2673
2692
|
modelId: model.id,
|
|
2674
2693
|
credentialSelector: options.credentialSelector,
|
|
2694
|
+
signal: options.signal,
|
|
2675
2695
|
});
|
|
2676
2696
|
}
|
|
2677
2697
|
|
|
@@ -355,7 +355,7 @@ function findExactCanonicalModelMatch(
|
|
|
355
355
|
modelReference: string,
|
|
356
356
|
availableModels: Model<Api>[],
|
|
357
357
|
modelRegistry: CanonicalModelRegistry | undefined,
|
|
358
|
-
|
|
358
|
+
_sessionId?: string,
|
|
359
359
|
): Model<Api> | undefined {
|
|
360
360
|
if (!modelRegistry) {
|
|
361
361
|
return undefined;
|
|
@@ -378,7 +378,7 @@ function findExactEquivalentModelMatch(
|
|
|
378
378
|
modelReference: string,
|
|
379
379
|
availableModels: Model<Api>[],
|
|
380
380
|
modelRegistry: CanonicalModelRegistry | undefined,
|
|
381
|
-
|
|
381
|
+
_sessionId?: string,
|
|
382
382
|
): Model<Api> | undefined {
|
|
383
383
|
if (!modelRegistry?.getCanonicalId || !modelRegistry.resolveCanonicalModel) return undefined;
|
|
384
384
|
const trimmedReference = modelReference.trim();
|