@sayknow-cli/coding-agent 0.4.6 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -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 +27 -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
|
@@ -129,6 +129,21 @@ function stabilizeStreamingPreviews(previews: PerFileDiffPreview[]): PerFileDiff
|
|
|
129
129
|
return changed ? next : previews;
|
|
130
130
|
}
|
|
131
131
|
|
|
132
|
+
function previewsAreEqual(a: PerFileDiffPreview[] | undefined, b: PerFileDiffPreview[]): boolean {
|
|
133
|
+
return (
|
|
134
|
+
a?.length === b.length &&
|
|
135
|
+
a.every((preview, index) => {
|
|
136
|
+
const next = b[index];
|
|
137
|
+
return (
|
|
138
|
+
preview.path === next?.path &&
|
|
139
|
+
preview.diff === next.diff &&
|
|
140
|
+
preview.error === next.error &&
|
|
141
|
+
preview.firstChangedLine === next.firstChangedLine
|
|
142
|
+
);
|
|
143
|
+
})
|
|
144
|
+
);
|
|
145
|
+
}
|
|
146
|
+
|
|
132
147
|
function isEditLikeToolName(toolName: string): boolean {
|
|
133
148
|
return toolName === "edit" || toolName === "apply_patch";
|
|
134
149
|
}
|
|
@@ -144,6 +159,8 @@ export interface ToolExecutionOptions {
|
|
|
144
159
|
editFuzzyThreshold?: number;
|
|
145
160
|
editAllowFuzzy?: boolean;
|
|
146
161
|
hashlineAutoDropPureInsertDuplicates?: boolean;
|
|
162
|
+
/** Internal observer for visible asynchronous renderer mutations. */
|
|
163
|
+
onVisibleTranscriptMutation?: () => void;
|
|
147
164
|
}
|
|
148
165
|
|
|
149
166
|
export interface ToolExecutionHandle {
|
|
@@ -168,6 +185,11 @@ export interface ToolExecutionHandle {
|
|
|
168
185
|
* back to {@link setExpanded}.
|
|
169
186
|
*/
|
|
170
187
|
setManuallyExpanded?(expanded: boolean): void;
|
|
188
|
+
/**
|
|
189
|
+
* Internal capability for dispatchers that need exact synchronous visible-output
|
|
190
|
+
* detection. Optional so existing structural handles remain source compatible.
|
|
191
|
+
*/
|
|
192
|
+
consumeVisibleTranscriptChange?(): boolean;
|
|
171
193
|
}
|
|
172
194
|
|
|
173
195
|
/**
|
|
@@ -213,8 +235,11 @@ export class ToolExecutionComponent extends Container {
|
|
|
213
235
|
#argsIdentityVersion = 0;
|
|
214
236
|
#lastArgsReference: any;
|
|
215
237
|
#shareArgsWithRenderer = false;
|
|
216
|
-
// Cached converted images for Kitty protocol (which requires PNG), keyed by index
|
|
217
|
-
#convertedImages: Map<number, { data: string; mimeType: string }> = new Map();
|
|
238
|
+
// Cached converted images for Kitty protocol (which requires PNG), keyed by index and source.
|
|
239
|
+
#convertedImages: Map<number, { data: string; mimeType: string; source: string }> = new Map();
|
|
240
|
+
#imageConversionGenerations = new Map<number, number>();
|
|
241
|
+
#imageConversionsInFlight = new Map<number, string>();
|
|
242
|
+
|
|
218
243
|
// Spinner animation for partial task results
|
|
219
244
|
#spinnerFrame?: number;
|
|
220
245
|
#spinnerAnimation?: AnimationRegistration;
|
|
@@ -229,6 +254,10 @@ export class ToolExecutionComponent extends Container {
|
|
|
229
254
|
expanded: false,
|
|
230
255
|
isPartial: true,
|
|
231
256
|
};
|
|
257
|
+
#onVisibleTranscriptMutation?: () => void;
|
|
258
|
+
#visibleTranscriptChanged = false;
|
|
259
|
+
#visibleProjection = "";
|
|
260
|
+
#disposed = false;
|
|
232
261
|
|
|
233
262
|
constructor(
|
|
234
263
|
toolName: string,
|
|
@@ -246,6 +275,8 @@ export class ToolExecutionComponent extends Container {
|
|
|
246
275
|
this.#editFuzzyThreshold = options.editFuzzyThreshold;
|
|
247
276
|
this.#editAllowFuzzy = options.editAllowFuzzy;
|
|
248
277
|
this.#hashlineAutoDropPureInsertDuplicates = options.hashlineAutoDropPureInsertDuplicates;
|
|
278
|
+
this.#onVisibleTranscriptMutation = options.onVisibleTranscriptMutation;
|
|
279
|
+
|
|
249
280
|
this.#tool = tool;
|
|
250
281
|
this.#ui = ui;
|
|
251
282
|
this.#cwd = cwd;
|
|
@@ -273,18 +304,23 @@ export class ToolExecutionComponent extends Container {
|
|
|
273
304
|
this.#editMode = resolveEditModeForTool(toolName, tool);
|
|
274
305
|
|
|
275
306
|
this.#updateDisplay();
|
|
307
|
+
this.#visibleProjection = this.#captureLogicalVisibleProjection();
|
|
308
|
+
|
|
276
309
|
void this.#runPreviewDiff();
|
|
277
310
|
}
|
|
278
311
|
|
|
279
312
|
updateArgs(args: any, _toolCallId?: string): void {
|
|
313
|
+
const argsChanged = !Bun.deepEquals(this.#args, args);
|
|
314
|
+
if (!argsChanged && !this.#editMode) return;
|
|
280
315
|
if (args !== this.#lastArgsReference) {
|
|
281
316
|
this.#lastArgsReference = args;
|
|
282
317
|
this.#argsIdentityVersion += 1;
|
|
283
318
|
}
|
|
284
|
-
this.#args = this.#shareArgsWithRenderer ? args : cloneToolArgs(args);
|
|
319
|
+
this.#args = argsChanged ? (this.#shareArgsWithRenderer ? args : cloneToolArgs(args)) : this.#args;
|
|
285
320
|
this.#updateSpinnerAnimation();
|
|
286
321
|
void this.#runPreviewDiff();
|
|
287
322
|
this.#updateDisplay();
|
|
323
|
+
this.#markVisibleMutationIfChanged();
|
|
288
324
|
}
|
|
289
325
|
|
|
290
326
|
/**
|
|
@@ -295,6 +331,8 @@ export class ToolExecutionComponent extends Container {
|
|
|
295
331
|
this.#argsComplete = true;
|
|
296
332
|
this.#updateSpinnerAnimation();
|
|
297
333
|
void this.#runPreviewDiff();
|
|
334
|
+
this.#updateDisplay();
|
|
335
|
+
this.#markVisibleMutationIfChanged();
|
|
298
336
|
}
|
|
299
337
|
|
|
300
338
|
async #runPreviewDiff(): Promise<void> {
|
|
@@ -338,14 +376,17 @@ export class ToolExecutionComponent extends Container {
|
|
|
338
376
|
hashlineAutoDropPureInsertDuplicates: this.#hashlineAutoDropPureInsertDuplicates,
|
|
339
377
|
isStreaming,
|
|
340
378
|
});
|
|
341
|
-
if (controller.signal.aborted) return;
|
|
379
|
+
if (this.#disposed || controller.signal.aborted) return;
|
|
342
380
|
if (previews) {
|
|
343
|
-
|
|
381
|
+
const nextPreview = isStreaming ? stabilizeStreamingPreviews(previews) : previews;
|
|
382
|
+
const changed = !previewsAreEqual(this.#editDiffPreview, nextPreview);
|
|
383
|
+
this.#editDiffPreview = nextPreview;
|
|
344
384
|
this.#updateDisplay();
|
|
345
385
|
this.#ui.requestRender();
|
|
386
|
+
if (changed) this.#markVisibleMutationIfChanged(true);
|
|
346
387
|
}
|
|
347
388
|
} catch (err) {
|
|
348
|
-
if (controller.signal.aborted) return;
|
|
389
|
+
if (this.#disposed || controller.signal.aborted) return;
|
|
349
390
|
logger.warn("Edit preview diff failed", { tool: this.#toolName, error: String(err) });
|
|
350
391
|
}
|
|
351
392
|
}
|
|
@@ -359,8 +400,10 @@ export class ToolExecutionComponent extends Container {
|
|
|
359
400
|
isPartial = false,
|
|
360
401
|
_toolCallId?: string,
|
|
361
402
|
): void {
|
|
403
|
+
if (this.#isPartial === isPartial && Bun.deepEquals(this.#result, result)) return;
|
|
362
404
|
this.#textOutputCache = undefined;
|
|
363
405
|
this.#result = result;
|
|
406
|
+
this.#invalidateStaleKittyConversions();
|
|
364
407
|
this.#isPartial = isPartial;
|
|
365
408
|
// When tool is complete, ensure args are marked complete so spinner stops
|
|
366
409
|
if (!isPartial) {
|
|
@@ -370,6 +413,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
370
413
|
this.#updateDisplay();
|
|
371
414
|
// Convert non-PNG images to PNG for Kitty protocol (async)
|
|
372
415
|
this.#maybeConvertImagesForKitty();
|
|
416
|
+
this.#markVisibleMutationIfChanged();
|
|
373
417
|
}
|
|
374
418
|
|
|
375
419
|
/**
|
|
@@ -383,40 +427,101 @@ export class ToolExecutionComponent extends Container {
|
|
|
383
427
|
return [...contentImages, ...detailImages];
|
|
384
428
|
}
|
|
385
429
|
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
*/
|
|
390
|
-
#maybeConvertImagesForKitty(): void {
|
|
391
|
-
// Only needed for Kitty protocol
|
|
392
|
-
if (TERMINAL.imageProtocol !== ImageProtocol.Kitty) return;
|
|
393
|
-
if (!this.#result) return;
|
|
394
|
-
|
|
395
|
-
const imageBlocks = this.#getAllImageBlocks();
|
|
430
|
+
#imageSource(image: { data?: string; mimeType?: string }): string | undefined {
|
|
431
|
+
return image.data && image.mimeType ? `${image.mimeType}\u0000${image.data}` : undefined;
|
|
432
|
+
}
|
|
396
433
|
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
if (
|
|
434
|
+
#invalidateStaleKittyConversions(): void {
|
|
435
|
+
const images = this.#getAllImageBlocks();
|
|
436
|
+
const indices = new Set<number>();
|
|
437
|
+
for (let index = 0; index < images.length; index++) {
|
|
438
|
+
const source = this.#imageSource(images[index]);
|
|
439
|
+
if (!source) continue;
|
|
440
|
+
indices.add(index);
|
|
441
|
+
if (this.#convertedImages.get(index)?.source !== source) this.#convertedImages.delete(index);
|
|
442
|
+
if (this.#imageConversionsInFlight.get(index) !== source) {
|
|
443
|
+
this.#imageConversionsInFlight.delete(index);
|
|
444
|
+
this.#imageConversionGenerations.set(index, (this.#imageConversionGenerations.get(index) ?? 0) + 1);
|
|
445
|
+
}
|
|
446
|
+
}
|
|
447
|
+
for (const index of this.#convertedImages.keys()) {
|
|
448
|
+
if (!indices.has(index)) this.#convertedImages.delete(index);
|
|
449
|
+
}
|
|
450
|
+
for (const index of this.#imageConversionsInFlight.keys()) {
|
|
451
|
+
if (!indices.has(index)) {
|
|
452
|
+
this.#imageConversionsInFlight.delete(index);
|
|
453
|
+
this.#imageConversionGenerations.set(index, (this.#imageConversionGenerations.get(index) ?? 0) + 1);
|
|
454
|
+
}
|
|
455
|
+
}
|
|
456
|
+
}
|
|
403
457
|
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
458
|
+
/** Convert non-PNG images to PNG for Kitty graphics protocol. */
|
|
459
|
+
#maybeConvertImagesForKitty(): void {
|
|
460
|
+
if (TERMINAL.imageProtocol !== ImageProtocol.Kitty) return;
|
|
461
|
+
for (const [index, image] of this.#getAllImageBlocks().entries()) {
|
|
462
|
+
const source = this.#imageSource(image);
|
|
463
|
+
if (!source || image.mimeType === "image/png") continue;
|
|
464
|
+
if (
|
|
465
|
+
this.#convertedImages.get(index)?.source === source ||
|
|
466
|
+
this.#imageConversionsInFlight.get(index) === source
|
|
467
|
+
)
|
|
468
|
+
continue;
|
|
469
|
+
const generation = this.#imageConversionGenerations.get(index) ?? 0;
|
|
470
|
+
this.#imageConversionsInFlight.set(index, source);
|
|
471
|
+
new Bun.Image(Buffer.from(image.data!, "base64"))
|
|
407
472
|
.png()
|
|
408
473
|
.toBase64()
|
|
409
474
|
.then(data => {
|
|
410
|
-
|
|
475
|
+
if (
|
|
476
|
+
this.#disposed ||
|
|
477
|
+
this.#imageConversionGenerations.get(index) !== generation ||
|
|
478
|
+
this.#imageConversionsInFlight.get(index) !== source ||
|
|
479
|
+
this.#imageSource(this.#getAllImageBlocks()[index] ?? {}) !== source
|
|
480
|
+
)
|
|
481
|
+
return;
|
|
482
|
+
this.#imageConversionsInFlight.delete(index);
|
|
483
|
+
this.#convertedImages.set(index, { data, mimeType: "image/png", source });
|
|
411
484
|
this.#updateDisplay();
|
|
412
485
|
this.#ui.requestRender();
|
|
486
|
+
this.#markVisibleMutationIfChanged(true);
|
|
413
487
|
})
|
|
414
488
|
.catch(() => {
|
|
415
|
-
|
|
489
|
+
if (
|
|
490
|
+
this.#disposed ||
|
|
491
|
+
this.#imageConversionGenerations.get(index) !== generation ||
|
|
492
|
+
this.#imageConversionsInFlight.get(index) !== source
|
|
493
|
+
)
|
|
494
|
+
return;
|
|
495
|
+
this.#imageConversionsInFlight.delete(index);
|
|
416
496
|
});
|
|
417
497
|
}
|
|
418
498
|
}
|
|
419
499
|
|
|
500
|
+
#captureLogicalVisibleProjection(): string {
|
|
501
|
+
return this.render(10_000).join("\n");
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
#markVisibleMutationIfChanged(notify = false): void {
|
|
505
|
+
const projection = this.#captureLogicalVisibleProjection();
|
|
506
|
+
if (projection === this.#visibleProjection) return;
|
|
507
|
+
this.#visibleProjection = projection;
|
|
508
|
+
this.#markVisibleMutation(notify);
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
#markVisibleMutation(notify = false): void {
|
|
512
|
+
if (notify) {
|
|
513
|
+
this.#onVisibleTranscriptMutation?.();
|
|
514
|
+
return;
|
|
515
|
+
}
|
|
516
|
+
this.#visibleTranscriptChanged = true;
|
|
517
|
+
}
|
|
518
|
+
|
|
519
|
+
consumeVisibleTranscriptChange(): boolean {
|
|
520
|
+
const changed = this.#visibleTranscriptChanged;
|
|
521
|
+
this.#visibleTranscriptChanged = false;
|
|
522
|
+
return changed;
|
|
523
|
+
}
|
|
524
|
+
|
|
420
525
|
/**
|
|
421
526
|
* Start or stop spinner animation based on whether this is a partial task result.
|
|
422
527
|
*/
|
|
@@ -430,6 +535,7 @@ export class ToolExecutionComponent extends Container {
|
|
|
430
535
|
const needsSpinner = isStreamingArgs || isPartialTask;
|
|
431
536
|
if (needsSpinner && !this.#spinnerAnimation) {
|
|
432
537
|
this.#spinnerAnimation = registerAnimationCallback(() => {
|
|
538
|
+
if (this.#disposed) return;
|
|
433
539
|
const frameCount = theme.spinnerFrames.length;
|
|
434
540
|
if (frameCount === 0) return;
|
|
435
541
|
this.#spinnerFrame = ((this.#spinnerFrame ?? -1) + 1) % frameCount;
|
|
@@ -456,6 +562,11 @@ export class ToolExecutionComponent extends Container {
|
|
|
456
562
|
}
|
|
457
563
|
|
|
458
564
|
override dispose(): void {
|
|
565
|
+
if (this.#disposed) return;
|
|
566
|
+
this.#disposed = true;
|
|
567
|
+
this.#imageConversionGenerations.clear();
|
|
568
|
+
this.#imageConversionsInFlight.clear();
|
|
569
|
+
this.#convertedImages.clear();
|
|
459
570
|
this.stopAnimation();
|
|
460
571
|
super.dispose();
|
|
461
572
|
}
|
|
@@ -3,8 +3,12 @@ import * as fs from "node:fs";
|
|
|
3
3
|
import { type Component, truncateToWidth, visibleWidth } from "@sayknow-cli/tui";
|
|
4
4
|
import { formatCount, getProjectDir } from "@sayknow-cli/utils";
|
|
5
5
|
import { $ } from "bun";
|
|
6
|
-
import
|
|
7
|
-
|
|
6
|
+
import {
|
|
7
|
+
type AppKeybinding,
|
|
8
|
+
KEYBINDINGS,
|
|
9
|
+
type KeybindingsManager,
|
|
10
|
+
type KeyDisplayContext,
|
|
11
|
+
} from "../../config/keybindings";
|
|
8
12
|
import { settings } from "../../config/settings";
|
|
9
13
|
import type { StatusLinePreset, StatusLineSegmentId, StatusLineSeparatorStyle } from "../../config/settings-schema";
|
|
10
14
|
import { theme } from "../../modes/theme/theme";
|
|
@@ -46,6 +50,7 @@ export interface StatusLineSettings {
|
|
|
46
50
|
previewHighlightSegment?: StatusLineSegmentId;
|
|
47
51
|
showHookStatus?: boolean;
|
|
48
52
|
showSkillHud?: boolean;
|
|
53
|
+
showActionHints?: boolean;
|
|
49
54
|
sessionAccent?: boolean;
|
|
50
55
|
maxRows?: number;
|
|
51
56
|
}
|
|
@@ -55,6 +60,7 @@ export interface StatusLineComponentOptions {
|
|
|
55
60
|
actionRegistry?: ActionRegistry<void>;
|
|
56
61
|
getKeybindings?: () => KeybindingsManager;
|
|
57
62
|
focusDomain?: FocusDomain;
|
|
63
|
+
keyDisplayContext?: KeyDisplayContext;
|
|
58
64
|
}
|
|
59
65
|
|
|
60
66
|
export interface StatusLineActionHint {
|
|
@@ -64,16 +70,13 @@ export interface StatusLineActionHint {
|
|
|
64
70
|
|
|
65
71
|
const ACTION_HINT_PRIORITY: readonly AppKeybinding[] = [
|
|
66
72
|
"app.message.sendNow",
|
|
67
|
-
"app.message.queue",
|
|
68
73
|
"app.message.followUp",
|
|
74
|
+
"app.message.queue",
|
|
69
75
|
"app.message.dequeue",
|
|
70
76
|
"app.commandPalette.open",
|
|
71
77
|
"app.plan.toggle",
|
|
72
78
|
"app.mode.cycle",
|
|
73
|
-
"app.thinking.cycle",
|
|
74
|
-
"app.model.select",
|
|
75
79
|
"app.model.cycleForward",
|
|
76
|
-
"app.history.search",
|
|
77
80
|
"app.session.togglePath",
|
|
78
81
|
"app.session.toggleSort",
|
|
79
82
|
"app.session.rename",
|
|
@@ -92,6 +95,7 @@ export function getAvailableActionHints(
|
|
|
92
95
|
getKeybindings: (() => KeybindingsManager) | undefined,
|
|
93
96
|
width: number,
|
|
94
97
|
domain: FocusDomain = "composer",
|
|
98
|
+
keyDisplayContext?: KeyDisplayContext,
|
|
95
99
|
): StatusLineActionHint[] {
|
|
96
100
|
if (!actionRegistry || !getKeybindings || width <= 0) return [];
|
|
97
101
|
const keybindings = getKeybindings();
|
|
@@ -108,7 +112,9 @@ export function getAvailableActionHints(
|
|
|
108
112
|
if (!(bindingId in KEYBINDINGS)) continue;
|
|
109
113
|
const keys = keybindings.getKeys(bindingId);
|
|
110
114
|
if (keys.length === 0) continue;
|
|
111
|
-
const content =
|
|
115
|
+
const content =
|
|
116
|
+
theme.fg("dim", keybindings.getDisplayString(bindingId, keyDisplayContext)) +
|
|
117
|
+
theme.fg("muted", ` ${action.title}`);
|
|
112
118
|
const nextWidth = visibleWidth(content) + (selected.length === 0 ? 0 : 3);
|
|
113
119
|
if (used + nextWidth > width) break;
|
|
114
120
|
selected.push({ id: action.id, content });
|
|
@@ -160,6 +166,7 @@ export class StatusLineComponent implements Component {
|
|
|
160
166
|
#actionRegistry: ActionRegistry<void> | undefined;
|
|
161
167
|
#getKeybindings: (() => KeybindingsManager) | undefined;
|
|
162
168
|
#focusDomain: FocusDomain;
|
|
169
|
+
#keyDisplayContext: KeyDisplayContext | undefined;
|
|
163
170
|
|
|
164
171
|
#resolvedSettingsCache:
|
|
165
172
|
| (Required<Pick<StatusLineSettings, "leftSegments" | "rightSegments" | "separator" | "segmentOptions">> &
|
|
@@ -199,6 +206,7 @@ export class StatusLineComponent implements Component {
|
|
|
199
206
|
separator: settings.get("statusLine.separator"),
|
|
200
207
|
showHookStatus: settings.get("statusLine.showHookStatus"),
|
|
201
208
|
showSkillHud: settings.get("statusLine.showSkillHud"),
|
|
209
|
+
showActionHints: settings.get("statusLine.showActionHints"),
|
|
202
210
|
segmentOptions: settings.getGroup("statusLine").segmentOptions,
|
|
203
211
|
sessionAccent: settings.get("statusLine.sessionAccent"),
|
|
204
212
|
maxRows: settings.get("statusLine.maxRows"),
|
|
@@ -207,6 +215,7 @@ export class StatusLineComponent implements Component {
|
|
|
207
215
|
this.#actionRegistry = options.actionRegistry;
|
|
208
216
|
this.#getKeybindings = options.getKeybindings;
|
|
209
217
|
this.#focusDomain = options.focusDomain ?? "composer";
|
|
218
|
+
this.#keyDisplayContext = options.keyDisplayContext;
|
|
210
219
|
}
|
|
211
220
|
|
|
212
221
|
updateSettings(settings: StatusLineSettings): void {
|
|
@@ -791,7 +800,16 @@ export class StatusLineComponent implements Component {
|
|
|
791
800
|
}
|
|
792
801
|
|
|
793
802
|
const right: string[] = [];
|
|
794
|
-
const actionHints =
|
|
803
|
+
const actionHints =
|
|
804
|
+
effectiveSettings.showActionHints === false
|
|
805
|
+
? []
|
|
806
|
+
: getAvailableActionHints(
|
|
807
|
+
this.#actionRegistry,
|
|
808
|
+
this.#getKeybindings,
|
|
809
|
+
width,
|
|
810
|
+
this.#focusDomain,
|
|
811
|
+
this.#keyDisplayContext,
|
|
812
|
+
);
|
|
795
813
|
for (const segId of effectiveSettings.rightSegments) {
|
|
796
814
|
const rendered = renderSegment(segId, ctx);
|
|
797
815
|
if (rendered.visible && rendered.content) {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Component, padding, TERMINAL, truncateToWidth, visibleWidth } from "@sayknow-cli/tui";
|
|
2
2
|
import { APP_NAME } from "@sayknow-cli/utils";
|
|
3
3
|
import { formatBuildLabel } from "../../build-metadata";
|
|
4
|
+
import { formatKeyHint, type KeyDisplayContext } from "../../config/keybindings";
|
|
4
5
|
import { t } from "../../i18n";
|
|
5
6
|
import { type ThemeColor, theme } from "../../modes/theme/theme";
|
|
6
7
|
|
|
@@ -20,28 +21,31 @@ export interface WelcomeComponentOptions {
|
|
|
20
21
|
getViewportRows?: () => number | undefined;
|
|
21
22
|
getReservedBottomRows?: (termWidth: number) => number;
|
|
22
23
|
changelogMarkdown?: string;
|
|
24
|
+
rightGutterWidth?: number;
|
|
23
25
|
collapseChangelog?: boolean;
|
|
24
26
|
buildLabel?: string;
|
|
27
|
+
keyDisplayContext?: KeyDisplayContext;
|
|
25
28
|
}
|
|
26
29
|
|
|
27
30
|
const WELCOME_STATIC_RIGHT_ROWS_EXCLUDING_DYNAMIC_SECTIONS = 15;
|
|
28
31
|
const DEFAULT_WHATS_NEW_ROWS = 3;
|
|
29
32
|
const MAX_WHATS_NEW_ROWS = 12;
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
];
|
|
33
|
+
|
|
34
|
+
function flowKeyItems(context: KeyDisplayContext): ReadonlyArray<{ key: string; label: string }> {
|
|
35
|
+
const newlineKey = context.platform === "win32" ? "alt+enter" : "ctrl+j";
|
|
36
|
+
return [
|
|
37
|
+
{ key: "/", label: "commands" },
|
|
38
|
+
{ key: "#", label: "actions" },
|
|
39
|
+
{ key: "!", label: "shell" },
|
|
40
|
+
{ key: "$", label: "python" },
|
|
41
|
+
{ key: "?", label: "keymap" },
|
|
42
|
+
{ key: "ctrl+l", label: "model" },
|
|
43
|
+
{ key: "shift+tab", label: "reasoning" },
|
|
44
|
+
{ key: "tab", label: "complete" },
|
|
45
|
+
{ key: newlineKey, label: "newline" },
|
|
46
|
+
{ key: "ctrl+c", label: "clear" },
|
|
47
|
+
];
|
|
48
|
+
}
|
|
45
49
|
|
|
46
50
|
/**
|
|
47
51
|
* Sayknow-CLI launch surface: a blue-gradient SAYKNOW wordmark, compact
|
|
@@ -109,7 +113,8 @@ export class WelcomeComponent implements Component {
|
|
|
109
113
|
}
|
|
110
114
|
|
|
111
115
|
render(termWidth: number): string[] {
|
|
112
|
-
const
|
|
116
|
+
const rightGutterWidth = this.#rightGutterWidth(termWidth);
|
|
117
|
+
const boxWidth = Math.max(0, termWidth - rightGutterWidth);
|
|
113
118
|
if (boxWidth < 4) {
|
|
114
119
|
return [];
|
|
115
120
|
}
|
|
@@ -264,7 +269,7 @@ export class WelcomeComponent implements Component {
|
|
|
264
269
|
lines.push(tl + titleStyled + theme.fg("dim", hChar.repeat(afterTitle)) + tr);
|
|
265
270
|
}
|
|
266
271
|
if (outputRows === 1) {
|
|
267
|
-
return lines;
|
|
272
|
+
return this.#withRightGutter(lines, rightGutterWidth);
|
|
268
273
|
}
|
|
269
274
|
|
|
270
275
|
if (showRightColumn) {
|
|
@@ -292,7 +297,7 @@ export class WelcomeComponent implements Component {
|
|
|
292
297
|
lines.push(bl + h.repeat(leftCol) + br);
|
|
293
298
|
}
|
|
294
299
|
|
|
295
|
-
return lines;
|
|
300
|
+
return this.#withRightGutter(lines, rightGutterWidth);
|
|
296
301
|
}
|
|
297
302
|
|
|
298
303
|
/** Center text within a given width */
|
|
@@ -314,6 +319,19 @@ export class WelcomeComponent implements Component {
|
|
|
314
319
|
}
|
|
315
320
|
return str + padding(width - visLen);
|
|
316
321
|
}
|
|
322
|
+
#rightGutterWidth(termWidth: number): number {
|
|
323
|
+
const configured = this.options.rightGutterWidth ?? 0;
|
|
324
|
+
if (!Number.isFinite(configured) || configured <= 0) return 0;
|
|
325
|
+
const gutterWidth = Math.floor(configured);
|
|
326
|
+
return Math.min(gutterWidth, Math.max(0, termWidth - 4));
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
#withRightGutter(lines: string[], rightGutterWidth: number): string[] {
|
|
330
|
+
if (rightGutterWidth <= 0) return lines;
|
|
331
|
+
const gutter = padding(rightGutterWidth);
|
|
332
|
+
return lines.map(line => line + gutter);
|
|
333
|
+
}
|
|
334
|
+
|
|
317
335
|
#targetRows(termWidth: number): number | undefined {
|
|
318
336
|
const viewportRows = this.options.getViewportRows?.();
|
|
319
337
|
if (typeof viewportRows !== "number" || !Number.isFinite(viewportRows) || viewportRows <= 0) {
|
|
@@ -347,7 +365,8 @@ export class WelcomeComponent implements Component {
|
|
|
347
365
|
}
|
|
348
366
|
|
|
349
367
|
#flowKeyItemText(item: { key: string; label: string }): string {
|
|
350
|
-
|
|
368
|
+
const context = this.options.keyDisplayContext ?? { platform: process.platform };
|
|
369
|
+
return `${theme.fg("dim", formatKeyHint(item.key, context))}${theme.fg("muted", ` ${this.#flowKeyLabel(item.label)}`)}`;
|
|
351
370
|
}
|
|
352
371
|
|
|
353
372
|
#flowKeyLabel(label: string): string {
|
|
@@ -376,7 +395,7 @@ export class WelcomeComponent implements Component {
|
|
|
376
395
|
const separator = ` ${theme.fg("dim", "·")} `;
|
|
377
396
|
const rows: string[] = [];
|
|
378
397
|
let current = "";
|
|
379
|
-
for (const item of
|
|
398
|
+
for (const item of flowKeyItems(this.options.keyDisplayContext ?? { platform: process.platform })) {
|
|
380
399
|
const segment = this.#flowKeyItemText(item);
|
|
381
400
|
const next = current ? `${current}${separator}${segment}` : segment;
|
|
382
401
|
if (current && visibleWidth(next) > contentWidth) {
|
|
@@ -395,7 +414,7 @@ export class WelcomeComponent implements Component {
|
|
|
395
414
|
const rowLimit = Math.max(1, Math.floor(maxRows));
|
|
396
415
|
if (rows.length <= rowLimit) return rows;
|
|
397
416
|
if (rowLimit === 1) {
|
|
398
|
-
const firstItem =
|
|
417
|
+
const firstItem = flowKeyItems(this.options.keyDisplayContext ?? { platform: process.platform })[0];
|
|
399
418
|
const firstSegment = firstItem ? this.#flowKeyItemText(firstItem) : theme.fg("dim", "keys");
|
|
400
419
|
return [this.#fitToWidth(` ${firstSegment} ${theme.fg("dim", "· … ")}${theme.bold("/help")}`, width)];
|
|
401
420
|
}
|
|
@@ -679,8 +698,16 @@ function gradientLogo(lines: readonly string[], phase = 0, shine?: ShineConfig):
|
|
|
679
698
|
|
|
680
699
|
/** Total length of the intro animation. */
|
|
681
700
|
const INTRO_MS = 3000;
|
|
682
|
-
/**
|
|
683
|
-
|
|
701
|
+
/** Resolve the intro cadence without making tests mutate global process state. */
|
|
702
|
+
export function resolveWelcomeIntroTickMs(
|
|
703
|
+
platform: NodeJS.Platform = process.platform,
|
|
704
|
+
tmux = process.env.TMUX,
|
|
705
|
+
): number {
|
|
706
|
+
return platform === "win32" && tmux ? 100 : 33;
|
|
707
|
+
}
|
|
708
|
+
|
|
709
|
+
/** Render at 30fps directly, but cap native Windows multiplexers at 10fps to avoid ConPTY output backpressure. */
|
|
710
|
+
const INTRO_TICK_MS = resolveWelcomeIntroTickMs();
|
|
684
711
|
/** Number of full gradient rotations the sweep performs before settling. */
|
|
685
712
|
const INTRO_SWEEPS = 2.5;
|
|
686
713
|
/** Number of times the shine highlight crosses the diagonal across the intro. */
|