@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
|
@@ -12,7 +12,7 @@ import {
|
|
|
12
12
|
readArgsTargetInternalUrl,
|
|
13
13
|
} from "../../modes/components/read-tool-group";
|
|
14
14
|
import { TodoReminderComponent } from "../../modes/components/todo-reminder";
|
|
15
|
-
import { ToolExecutionComponent } from "../../modes/components/tool-execution";
|
|
15
|
+
import { ToolExecutionComponent, type ToolExecutionHandle } from "../../modes/components/tool-execution";
|
|
16
16
|
import { TtsrNotificationComponent } from "../../modes/components/ttsr-notification";
|
|
17
17
|
import { getSymbolTheme, theme } from "../../modes/theme/theme";
|
|
18
18
|
import type { InteractiveModeContext, TodoPhase } from "../../modes/types";
|
|
@@ -23,6 +23,7 @@ import type { AgentSessionEvent } from "../../session/agent-session";
|
|
|
23
23
|
import { type CustomMessage, isSilentAbort, readPendingDisplayTag } from "../../session/messages";
|
|
24
24
|
import { transferSessionMessageIdentity } from "../../session/session-manager";
|
|
25
25
|
import type { ResolveToolDetails } from "../../tools/resolve";
|
|
26
|
+
import { computeIrcSplitWidths, getIrcSidebarSemanticToken } from "../components/irc-sidebar";
|
|
26
27
|
import type { IrcObservationRecord } from "../irc-observation-ledger";
|
|
27
28
|
import { interruptHint } from "../shared";
|
|
28
29
|
import { buildAbortDisplayMessage } from "../utils/abort-message";
|
|
@@ -36,7 +37,14 @@ type AgentSessionEventKind = AgentSessionEvent["type"];
|
|
|
36
37
|
|
|
37
38
|
/** Test-only performance counters for advisory baseline tests. */
|
|
38
39
|
export const __eventControllerPerfCounters = {
|
|
40
|
+
enabled: false,
|
|
39
41
|
messageUpdateContentVisits: 0,
|
|
42
|
+
enable(): void {
|
|
43
|
+
this.enabled = true;
|
|
44
|
+
},
|
|
45
|
+
disable(): void {
|
|
46
|
+
this.enabled = false;
|
|
47
|
+
},
|
|
40
48
|
reset(): void {
|
|
41
49
|
this.messageUpdateContentVisits = 0;
|
|
42
50
|
},
|
|
@@ -118,6 +126,9 @@ export class EventController {
|
|
|
118
126
|
#toolIntentCache = new Map<string, { args: unknown; intent: string | undefined }>();
|
|
119
127
|
#thinkingContentIndices = new Set<number>();
|
|
120
128
|
#handlers: AgentSessionEventHandlers;
|
|
129
|
+
#visibleTranscriptChanged = false;
|
|
130
|
+
#handlingEvent = false;
|
|
131
|
+
#eventQueue: Promise<void> = Promise.resolve();
|
|
121
132
|
|
|
122
133
|
constructor(private ctx: InteractiveModeContext) {
|
|
123
134
|
this.#handlers = {
|
|
@@ -162,6 +173,26 @@ export class EventController {
|
|
|
162
173
|
this.clearIrcExpiryTimers();
|
|
163
174
|
}
|
|
164
175
|
|
|
176
|
+
#recordVisibleTranscriptMutation(): void {
|
|
177
|
+
this.#visibleTranscriptChanged = true;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
#observeVisibleTranscriptMutation(): void {
|
|
181
|
+
if (this.#handlingEvent) {
|
|
182
|
+
this.#recordVisibleTranscriptMutation();
|
|
183
|
+
return;
|
|
184
|
+
}
|
|
185
|
+
this.ctx.recordVisibleTranscriptMutation?.();
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
#consumeToolVisibleChange(handle: ToolExecutionHandle): void {
|
|
189
|
+
// Structural third-party renderers may not implement the optional exact-consume
|
|
190
|
+
// capability; preserve revision correctness conservatively until they opt in.
|
|
191
|
+
if (typeof handle.consumeVisibleTranscriptChange !== "function" || handle.consumeVisibleTranscriptChange()) {
|
|
192
|
+
this.#recordVisibleTranscriptMutation();
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
165
196
|
#resetReadGroup(): void {
|
|
166
197
|
this.#lastReadGroup = undefined;
|
|
167
198
|
}
|
|
@@ -228,20 +259,30 @@ export class EventController {
|
|
|
228
259
|
});
|
|
229
260
|
}
|
|
230
261
|
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
this.ctx.statusLine.invalidate();
|
|
237
|
-
this.ctx.updateEditorTopBorder();
|
|
262
|
+
handleEvent(event: AgentSessionEvent): Promise<void> {
|
|
263
|
+
const dispatch = this.#eventQueue.then(() => this.#dispatchEvent(event));
|
|
264
|
+
this.#eventQueue = dispatch.catch(() => {});
|
|
265
|
+
return dispatch;
|
|
266
|
+
}
|
|
238
267
|
|
|
239
|
-
|
|
240
|
-
await
|
|
241
|
-
|
|
268
|
+
async #dispatchEvent(event: AgentSessionEvent): Promise<void> {
|
|
269
|
+
if (!this.ctx.isInitialized) await this.ctx.init();
|
|
270
|
+
this.#visibleTranscriptChanged = false;
|
|
271
|
+
this.#handlingEvent = true;
|
|
272
|
+
try {
|
|
273
|
+
this.ctx.statusLine.invalidate();
|
|
274
|
+
this.ctx.updateEditorTopBorder();
|
|
275
|
+
const run = this.#handlers[event.type] as (e: AgentSessionEvent) => Promise<void>;
|
|
276
|
+
await run(event);
|
|
277
|
+
if (this.#visibleTranscriptChanged) this.ctx.recordVisibleTranscriptMutation?.();
|
|
278
|
+
if (this.ctx.isTranscriptViewerOpen?.()) this.ctx.refreshTranscriptViewer?.();
|
|
279
|
+
} finally {
|
|
280
|
+
this.#handlingEvent = false;
|
|
281
|
+
}
|
|
242
282
|
}
|
|
243
283
|
|
|
244
284
|
async #handleAgentStart(_event: Extract<AgentSessionEvent, { type: "agent_start" }>): Promise<void> {
|
|
285
|
+
this.ctx.promptSuggestion?.onAgentStart();
|
|
245
286
|
this.#lastIntent = undefined;
|
|
246
287
|
this.#readToolCallArgs.clear();
|
|
247
288
|
this.#readToolCallAssistantComponents.clear();
|
|
@@ -267,8 +308,12 @@ export class EventController {
|
|
|
267
308
|
const parsed = parseIrcMessage(message);
|
|
268
309
|
if (!parsed) return;
|
|
269
310
|
const arrival = this.ctx.captureIrcArrivalSnapshot();
|
|
311
|
+
const rightWidth = arrival.panelVisible
|
|
312
|
+
? computeIrcSplitWidths(this.ctx.ui.terminal?.columns ?? 0).rightWidth
|
|
313
|
+
: 0;
|
|
314
|
+
const beforeToken = rightWidth > 0 ? getIrcSidebarSemanticToken(this.ctx.ircLedger, rightWidth) : "";
|
|
270
315
|
const record = this.ctx.ircLedger.observe(parsed, arrival.panelVisible);
|
|
271
|
-
this.#
|
|
316
|
+
const evictedInlineRemoved = this.#cleanupIrcObservationIds(this.ctx.ircLedger.drainEvictedObservationIds());
|
|
272
317
|
if (!record) return;
|
|
273
318
|
const signature = `irc:${record.observationId}`;
|
|
274
319
|
if (this.#renderedCustomMessages.has(signature)) return;
|
|
@@ -278,9 +323,13 @@ export class EventController {
|
|
|
278
323
|
this.#renderedIrcComponents.set(record.observationId, components);
|
|
279
324
|
this.#scheduleIrcExpiry(record, components);
|
|
280
325
|
this.ctx.ui.requestRender();
|
|
326
|
+
const afterToken = rightWidth > 0 ? getIrcSidebarSemanticToken(this.ctx.ircLedger, rightWidth) : "";
|
|
327
|
+
if (components.length > 0 || evictedInlineRemoved || (rightWidth > 0 && beforeToken !== afterToken)) {
|
|
328
|
+
this.#recordVisibleTranscriptMutation();
|
|
329
|
+
}
|
|
281
330
|
}
|
|
282
331
|
|
|
283
|
-
#cleanupIrcObservationIds(observationIds: readonly string[]):
|
|
332
|
+
#cleanupIrcObservationIds(observationIds: readonly string[]): boolean {
|
|
284
333
|
const removedComponents = new Set<Component>();
|
|
285
334
|
for (const observationId of observationIds) {
|
|
286
335
|
const timer = this.#ircExpiryTimers.get(observationId);
|
|
@@ -293,23 +342,26 @@ export class EventController {
|
|
|
293
342
|
for (const component of this.ctx.removeRenderedIrcInlineComponents(observationId) ?? []) {
|
|
294
343
|
removedComponents.add(component);
|
|
295
344
|
}
|
|
296
|
-
|
|
297
345
|
this.#renderedCustomMessages.delete(`irc:${observationId}`);
|
|
298
346
|
}
|
|
299
347
|
for (const component of removedComponents) this.ctx.chatContainer.removeChild(component);
|
|
348
|
+
return removedComponents.size > 0;
|
|
300
349
|
}
|
|
301
350
|
|
|
302
351
|
#cleanupEvictedIrcObservations(): void {
|
|
303
|
-
this.#cleanupIrcObservationIds(this.ctx.ircLedger.drainEvictedObservationIds())
|
|
352
|
+
if (this.#cleanupIrcObservationIds(this.ctx.ircLedger.drainEvictedObservationIds())) {
|
|
353
|
+
this.#recordVisibleTranscriptMutation();
|
|
354
|
+
}
|
|
304
355
|
}
|
|
305
356
|
|
|
306
|
-
#cleanupExpiredIrcInlineComponents(observationId: string):
|
|
357
|
+
#cleanupExpiredIrcInlineComponents(observationId: string): boolean {
|
|
307
358
|
const removedComponents = new Set<Component>(this.#renderedIrcComponents.get(observationId));
|
|
308
359
|
this.#renderedIrcComponents.delete(observationId);
|
|
309
360
|
for (const component of this.ctx.removeRenderedIrcInlineComponents(observationId) ?? []) {
|
|
310
361
|
removedComponents.add(component);
|
|
311
362
|
}
|
|
312
363
|
for (const component of removedComponents) this.ctx.chatContainer.removeChild(component);
|
|
364
|
+
return removedComponents.size > 0;
|
|
313
365
|
}
|
|
314
366
|
|
|
315
367
|
async #handleMessageStart(event: Extract<AgentSessionEvent, { type: "message_start" }>): Promise<void> {
|
|
@@ -325,6 +377,7 @@ export class EventController {
|
|
|
325
377
|
this.#renderedCustomMessages.add(signature);
|
|
326
378
|
this.#resetReadGroup();
|
|
327
379
|
this.ctx.addMessageToChat(event.message);
|
|
380
|
+
if (event.message.display) this.#recordVisibleTranscriptMutation();
|
|
328
381
|
// Tag-keyed pending-bar refresh: when AgentSession.#handleAgentEvent
|
|
329
382
|
// spliced this dequeued custom message out of #steeringMessages /
|
|
330
383
|
// #followUpMessages (it ran before this emit), the array state is
|
|
@@ -372,10 +425,12 @@ export class EventController {
|
|
|
372
425
|
this.ctx.updatePendingMessagesDisplay();
|
|
373
426
|
}
|
|
374
427
|
this.ctx.ui.requestRender();
|
|
428
|
+
if (!wasOptimistic) this.#recordVisibleTranscriptMutation();
|
|
375
429
|
} else if (event.message.role === "fileMention") {
|
|
376
430
|
this.#resetReadGroup();
|
|
377
431
|
this.ctx.addMessageToChat(event.message);
|
|
378
432
|
this.ctx.ui.requestRender();
|
|
433
|
+
this.#recordVisibleTranscriptMutation();
|
|
379
434
|
} else if (event.message.role === "assistant") {
|
|
380
435
|
this.#lastThinkingCount = 0;
|
|
381
436
|
this.#resetReadGroup();
|
|
@@ -386,6 +441,7 @@ export class EventController {
|
|
|
386
441
|
this.ctx.hideThinkingBlock,
|
|
387
442
|
() => this.ctx.ui.requestRender(),
|
|
388
443
|
this.ctx.getAssistantViewportAnchorId?.(event.message),
|
|
444
|
+
() => this.#observeVisibleTranscriptMutation(),
|
|
389
445
|
);
|
|
390
446
|
this.ctx.streamingMessage = event.message;
|
|
391
447
|
addChatChild(this.ctx, this.ctx.streamingComponent);
|
|
@@ -428,15 +484,10 @@ export class EventController {
|
|
|
428
484
|
this.#cleanupEvictedIrcObservations();
|
|
429
485
|
const projectedObservationIds = new Set(inlineProjection.map(record => record.observationId));
|
|
430
486
|
for (const [observationId, components] of componentsByObservationId) {
|
|
431
|
-
|
|
432
|
-
if (
|
|
433
|
-
!projectedObservationIds.has(observationId) ||
|
|
434
|
-
(record?.mode === "ephemeral" && record.expiresAt! - now <= 0)
|
|
435
|
-
) {
|
|
487
|
+
if (!projectedObservationIds.has(observationId)) {
|
|
436
488
|
for (const component of components) {
|
|
437
489
|
this.ctx.chatContainer.removeChild(component);
|
|
438
490
|
}
|
|
439
|
-
this.#renderedIrcComponents.delete(observationId);
|
|
440
491
|
componentsByObservationId.delete(observationId);
|
|
441
492
|
}
|
|
442
493
|
}
|
|
@@ -467,12 +518,12 @@ export class EventController {
|
|
|
467
518
|
}
|
|
468
519
|
const remainingMs = record.expiresAt! - Date.now();
|
|
469
520
|
if (remainingMs <= 0) {
|
|
470
|
-
this.#cleanupExpiredIrcInlineComponents(record.observationId);
|
|
521
|
+
if (this.#cleanupExpiredIrcInlineComponents(record.observationId)) this.#observeVisibleTranscriptMutation();
|
|
471
522
|
return false;
|
|
472
523
|
}
|
|
473
524
|
const timer = setTimeout(() => {
|
|
474
525
|
this.#ircExpiryTimers.delete(record.observationId);
|
|
475
|
-
this.#cleanupExpiredIrcInlineComponents(record.observationId);
|
|
526
|
+
if (this.#cleanupExpiredIrcInlineComponents(record.observationId)) this.#observeVisibleTranscriptMutation();
|
|
476
527
|
this.ctx.ui.requestRender();
|
|
477
528
|
}, remainingMs);
|
|
478
529
|
timer.unref?.();
|
|
@@ -495,6 +546,7 @@ export class EventController {
|
|
|
495
546
|
this.#resetReadGroup();
|
|
496
547
|
this.ctx.addMessageToChat(event.message);
|
|
497
548
|
this.ctx.ui.requestRender();
|
|
549
|
+
this.#recordVisibleTranscriptMutation();
|
|
498
550
|
}
|
|
499
551
|
|
|
500
552
|
async #handleModelFallbackSwitched(
|
|
@@ -548,19 +600,24 @@ export class EventController {
|
|
|
548
600
|
}
|
|
549
601
|
|
|
550
602
|
for (const content of contentsToProcess) {
|
|
551
|
-
__eventControllerPerfCounters.messageUpdateContentVisits += 1;
|
|
603
|
+
if (__eventControllerPerfCounters.enabled) __eventControllerPerfCounters.messageUpdateContentVisits += 1;
|
|
552
604
|
if (content.type !== "toolCall") continue;
|
|
553
605
|
if (content.name === "read") {
|
|
554
606
|
if (!readArgsHaveTarget(content.arguments)) continue;
|
|
555
607
|
if (!readArgsTargetInternalUrl(content.arguments)) {
|
|
556
608
|
this.#trackReadToolCall(content.id, content.arguments);
|
|
557
609
|
const component = this.ctx.pendingTools.get(content.id);
|
|
558
|
-
if (component)
|
|
559
|
-
|
|
610
|
+
if (component) {
|
|
611
|
+
component.updateArgs(content.arguments, content.id);
|
|
612
|
+
this.#consumeToolVisibleChange(component);
|
|
613
|
+
} else {
|
|
560
614
|
const group = this.#getReadGroup();
|
|
561
615
|
group.updateArgs(content.arguments, content.id);
|
|
562
616
|
this.ctx.pendingTools.set(content.id, group);
|
|
617
|
+
this.#recordVisibleTranscriptMutation();
|
|
618
|
+
group.consumeVisibleTranscriptChange();
|
|
563
619
|
}
|
|
620
|
+
|
|
564
621
|
continue;
|
|
565
622
|
}
|
|
566
623
|
}
|
|
@@ -581,6 +638,7 @@ export class EventController {
|
|
|
581
638
|
editFuzzyThreshold: settings.get("edit.fuzzyThreshold"),
|
|
582
639
|
editAllowFuzzy: settings.get("edit.fuzzyMatch"),
|
|
583
640
|
hashlineAutoDropPureInsertDuplicates: settings.get("edit.hashlineAutoDropPureInsertDuplicates"),
|
|
641
|
+
onVisibleTranscriptMutation: () => this.#observeVisibleTranscriptMutation(),
|
|
584
642
|
},
|
|
585
643
|
tool,
|
|
586
644
|
this.ctx.ui,
|
|
@@ -590,8 +648,10 @@ export class EventController {
|
|
|
590
648
|
component.setExpanded(this.ctx.toolOutputExpanded);
|
|
591
649
|
this.ctx.pendingTools.set(content.id, component);
|
|
592
650
|
addChatChild(this.ctx, component);
|
|
651
|
+
this.#recordVisibleTranscriptMutation();
|
|
593
652
|
} else {
|
|
594
653
|
this.ctx.pendingTools.get(content.id)?.updateArgs(renderArgs, content.id);
|
|
654
|
+
this.#consumeToolVisibleChange(this.ctx.pendingTools.get(content.id)!);
|
|
595
655
|
}
|
|
596
656
|
|
|
597
657
|
const args = content.arguments;
|
|
@@ -658,6 +718,7 @@ export class EventController {
|
|
|
658
718
|
if (this.ctx.streamingMessage.stopReason !== "aborted" && this.ctx.streamingMessage.stopReason !== "error") {
|
|
659
719
|
for (const [toolCallId, component] of this.ctx.pendingTools.entries()) {
|
|
660
720
|
component.setArgsComplete(toolCallId);
|
|
721
|
+
this.#consumeToolVisibleChange(component);
|
|
661
722
|
}
|
|
662
723
|
}
|
|
663
724
|
this.#lastAssistantComponent = this.ctx.streamingComponent;
|
|
@@ -684,6 +745,8 @@ export class EventController {
|
|
|
684
745
|
this.ctx.pendingTools.set(event.toolCallId, group);
|
|
685
746
|
}
|
|
686
747
|
this.ctx.ui.requestRender();
|
|
748
|
+
this.#consumeToolVisibleChange(this.ctx.pendingTools.get(event.toolCallId)!);
|
|
749
|
+
|
|
687
750
|
return;
|
|
688
751
|
}
|
|
689
752
|
|
|
@@ -697,6 +760,7 @@ export class EventController {
|
|
|
697
760
|
editFuzzyThreshold: settings.get("edit.fuzzyThreshold"),
|
|
698
761
|
editAllowFuzzy: settings.get("edit.fuzzyMatch"),
|
|
699
762
|
hashlineAutoDropPureInsertDuplicates: settings.get("edit.hashlineAutoDropPureInsertDuplicates"),
|
|
763
|
+
onVisibleTranscriptMutation: () => this.#observeVisibleTranscriptMutation(),
|
|
700
764
|
},
|
|
701
765
|
tool,
|
|
702
766
|
this.ctx.ui,
|
|
@@ -706,6 +770,8 @@ export class EventController {
|
|
|
706
770
|
component.setExpanded(this.ctx.toolOutputExpanded);
|
|
707
771
|
this.ctx.pendingTools.set(event.toolCallId, component);
|
|
708
772
|
addChatChild(this.ctx, component);
|
|
773
|
+
this.#recordVisibleTranscriptMutation();
|
|
774
|
+
|
|
709
775
|
this.ctx.ui.requestRender();
|
|
710
776
|
}
|
|
711
777
|
}
|
|
@@ -722,6 +788,8 @@ export class EventController {
|
|
|
722
788
|
!isFinalAsyncState,
|
|
723
789
|
event.toolCallId,
|
|
724
790
|
);
|
|
791
|
+
this.#consumeToolVisibleChange(component);
|
|
792
|
+
|
|
725
793
|
if (isFinalAsyncState) {
|
|
726
794
|
this.ctx.pendingTools.delete(event.toolCallId);
|
|
727
795
|
this.#backgroundToolCallIds.delete(event.toolCallId);
|
|
@@ -736,6 +804,8 @@ export class EventController {
|
|
|
736
804
|
const component = this.ctx.pendingTools.get(event.toolCallId);
|
|
737
805
|
if (component) {
|
|
738
806
|
component.updateResult({ ...event.result, isError: event.isError }, false, event.toolCallId);
|
|
807
|
+
this.#consumeToolVisibleChange(component);
|
|
808
|
+
|
|
739
809
|
this.ctx.pendingTools.delete(event.toolCallId);
|
|
740
810
|
}
|
|
741
811
|
const asyncState = (event.result.details as { async?: { state?: string } } | undefined)?.async?.state;
|
|
@@ -760,6 +830,8 @@ export class EventController {
|
|
|
760
830
|
const asyncState = (event.result.details as { async?: { state?: string } } | undefined)?.async?.state;
|
|
761
831
|
const isBackgroundRunning = asyncState === "running";
|
|
762
832
|
component.updateResult({ ...event.result, isError: event.isError }, isBackgroundRunning, event.toolCallId);
|
|
833
|
+
this.#consumeToolVisibleChange(component);
|
|
834
|
+
|
|
763
835
|
if (isBackgroundRunning) {
|
|
764
836
|
this.#backgroundToolCallIds.add(event.toolCallId);
|
|
765
837
|
} else {
|
|
@@ -775,6 +847,8 @@ export class EventController {
|
|
|
775
847
|
const asyncState = (event.result.details as { async?: { state?: string } } | undefined)?.async?.state;
|
|
776
848
|
const isBackgroundRunning = asyncState === "running";
|
|
777
849
|
component.updateResult({ ...event.result, isError: event.isError }, isBackgroundRunning, event.toolCallId);
|
|
850
|
+
this.#consumeToolVisibleChange(component);
|
|
851
|
+
|
|
778
852
|
if (isBackgroundRunning) {
|
|
779
853
|
this.#backgroundToolCallIds.add(event.toolCallId);
|
|
780
854
|
} else {
|
|
@@ -836,6 +910,7 @@ export class EventController {
|
|
|
836
910
|
this.ctx.ui.requestRender();
|
|
837
911
|
this.#scheduleIdleCompaction();
|
|
838
912
|
this.sendCompletionNotification();
|
|
913
|
+
this.ctx.promptSuggestion?.onAgentEnd();
|
|
839
914
|
}
|
|
840
915
|
|
|
841
916
|
async #handleAutoCompactionStart(
|
|
@@ -847,6 +922,10 @@ export class EventController {
|
|
|
847
922
|
this.ctx.editor.onEscape = () => {
|
|
848
923
|
this.ctx.session.abortCompaction();
|
|
849
924
|
};
|
|
925
|
+
if (this.ctx.loadingAnimation) {
|
|
926
|
+
this.ctx.loadingAnimation.stop();
|
|
927
|
+
this.ctx.loadingAnimation = undefined;
|
|
928
|
+
}
|
|
850
929
|
this.ctx.statusContainer.clear();
|
|
851
930
|
const reasonText =
|
|
852
931
|
event.reason === "overflow" ? "Context overflow detected, " : event.reason === "idle" ? "Idle " : "";
|
|
@@ -887,6 +966,12 @@ export class EventController {
|
|
|
887
966
|
} else if (event.willRetry && !isHandoffAction) {
|
|
888
967
|
this.ctx.showStatus("Context overflow maintenance completed");
|
|
889
968
|
}
|
|
969
|
+
} else if (
|
|
970
|
+
event.skipped &&
|
|
971
|
+
event.errorMessage?.startsWith("Context overflow recovery skipped: nothing eligible to compact.") &&
|
|
972
|
+
!isHandoffAction
|
|
973
|
+
) {
|
|
974
|
+
this.ctx.showStatus(event.errorMessage);
|
|
890
975
|
} else if (event.errorMessage) {
|
|
891
976
|
this.ctx.showWarning(event.errorMessage);
|
|
892
977
|
} else if (isHandoffAction) {
|
|
@@ -939,6 +1024,10 @@ export class EventController {
|
|
|
939
1024
|
this.ctx.session.abortRetry();
|
|
940
1025
|
}
|
|
941
1026
|
};
|
|
1027
|
+
if (this.ctx.loadingAnimation) {
|
|
1028
|
+
this.ctx.loadingAnimation.stop();
|
|
1029
|
+
this.ctx.loadingAnimation = undefined;
|
|
1030
|
+
}
|
|
942
1031
|
this.ctx.statusContainer.clear();
|
|
943
1032
|
// Stop any prior retry loader/timer before installing a new one.
|
|
944
1033
|
this.ctx.retryLoader?.stop();
|
|
@@ -989,12 +1078,15 @@ export class EventController {
|
|
|
989
1078
|
const component = new TtsrNotificationComponent(event.rules);
|
|
990
1079
|
component.setExpanded(this.ctx.toolOutputExpanded);
|
|
991
1080
|
addChatChild(this.ctx, component);
|
|
1081
|
+
this.#recordVisibleTranscriptMutation();
|
|
1082
|
+
|
|
992
1083
|
this.ctx.ui.requestRender();
|
|
993
1084
|
}
|
|
994
1085
|
|
|
995
1086
|
async #handleTodoReminder(event: Extract<AgentSessionEvent, { type: "todo_reminder" }>): Promise<void> {
|
|
996
1087
|
const component = new TodoReminderComponent(event.todos, event.attempt, event.maxAttempts);
|
|
997
1088
|
addChatChild(this.ctx, component);
|
|
1089
|
+
this.#recordVisibleTranscriptMutation();
|
|
998
1090
|
this.ctx.ui.requestRender();
|
|
999
1091
|
}
|
|
1000
1092
|
|
|
@@ -282,7 +282,24 @@ export class ExtensionUiController {
|
|
|
282
282
|
const disabled = [...(session.settings.get("disabledExtensions") ?? [])];
|
|
283
283
|
const on = input.on === true;
|
|
284
284
|
const next = on ? disabled.filter(value => value !== id) : [...new Set([...disabled, id])];
|
|
285
|
-
session.settings.
|
|
285
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
286
|
+
throw Object.assign(
|
|
287
|
+
new Error(
|
|
288
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
289
|
+
),
|
|
290
|
+
{ code: "invalid_request" },
|
|
291
|
+
);
|
|
292
|
+
}
|
|
293
|
+
try {
|
|
294
|
+
session.settings.set("disabledExtensions", next);
|
|
295
|
+
} catch (error) {
|
|
296
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
297
|
+
throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), {
|
|
298
|
+
code: "invalid_request",
|
|
299
|
+
});
|
|
300
|
+
}
|
|
301
|
+
throw error;
|
|
302
|
+
}
|
|
286
303
|
return { changed: true, enabled: on };
|
|
287
304
|
}
|
|
288
305
|
case "session.delete":
|
|
@@ -426,6 +443,7 @@ export class ExtensionUiController {
|
|
|
426
443
|
getSystemPrompt: () => this.ctx.session.systemPrompt,
|
|
427
444
|
clearContext: () => this.ctx.session.clearContext(),
|
|
428
445
|
cycleModel: () => this.ctx.session.cycleModel(),
|
|
446
|
+
setModelProfile: name => this.ctx.session.activateModelProfileForControl(name),
|
|
429
447
|
cycleThinkingLevel: () => this.ctx.session.cycleThinkingLevel(),
|
|
430
448
|
setQueueMode: (kind, mode) => {
|
|
431
449
|
if (kind === "steering" && (mode === "all" || mode === "one-at-a-time")) {
|
|
@@ -442,16 +460,12 @@ export class ExtensionUiController {
|
|
|
442
460
|
}
|
|
443
461
|
return false;
|
|
444
462
|
},
|
|
445
|
-
invokeSkill: (name, args) => this.ctx.session.invokeSkill(name, args),
|
|
463
|
+
invokeSkill: (name, args, options) => this.ctx.session.invokeSkill(name, args, options),
|
|
446
464
|
setPlanMode: on => this.ctx.session.setSdkPlanMode(on),
|
|
447
465
|
operateGoal: (op, objective) => this.ctx.session.operateGoal(op, objective),
|
|
448
466
|
getSkillState: () =>
|
|
449
467
|
this.ctx.session.skills.map(skill => ({ name: skill.name, description: skill.description })),
|
|
450
|
-
getConfigItems: () => (
|
|
451
|
-
steeringMode: this.ctx.session.steeringMode,
|
|
452
|
-
followUpMode: this.ctx.session.followUpMode,
|
|
453
|
-
interruptMode: this.ctx.session.interruptMode,
|
|
454
|
-
}),
|
|
468
|
+
getConfigItems: () => this.ctx.session.getSdkConfigItems(),
|
|
455
469
|
getBranchCandidates: () => this.ctx.sessionManager.getTree(),
|
|
456
470
|
getExtensions: () => this.ctx.session.extensionRunner?.getExtensionPaths() ?? [],
|
|
457
471
|
setSdkPermissionProvider: provider => this.ctx.session.setSdkPermissionProvider(provider),
|
|
@@ -728,6 +742,7 @@ export class ExtensionUiController {
|
|
|
728
742
|
getSystemPrompt: () => this.ctx.session.systemPrompt,
|
|
729
743
|
clearContext: () => this.ctx.session.clearContext(),
|
|
730
744
|
cycleModel: () => this.ctx.session.cycleModel(),
|
|
745
|
+
setModelProfile: name => this.ctx.session.activateModelProfileForControl(name),
|
|
731
746
|
cycleThinkingLevel: () => this.ctx.session.cycleThinkingLevel(),
|
|
732
747
|
setQueueMode: (kind, mode) => {
|
|
733
748
|
if (kind === "steering" && (mode === "all" || mode === "one-at-a-time")) {
|
|
@@ -746,11 +761,7 @@ export class ExtensionUiController {
|
|
|
746
761
|
},
|
|
747
762
|
getSkillState: () =>
|
|
748
763
|
this.ctx.session.skills.map(skill => ({ name: skill.name, description: skill.description })),
|
|
749
|
-
getConfigItems: () => (
|
|
750
|
-
steeringMode: this.ctx.session.steeringMode,
|
|
751
|
-
followUpMode: this.ctx.session.followUpMode,
|
|
752
|
-
interruptMode: this.ctx.session.interruptMode,
|
|
753
|
-
}),
|
|
764
|
+
getConfigItems: () => this.ctx.session.getSdkConfigItems(),
|
|
754
765
|
getBranchCandidates: () => this.ctx.sessionManager.getTree(),
|
|
755
766
|
getExtensions: () => this.ctx.session.extensionRunner?.getExtensionPaths() ?? [],
|
|
756
767
|
setSdkPermissionProvider: provider => this.ctx.session.setSdkPermissionProvider(provider),
|
|
@@ -2,7 +2,7 @@ import * as fs from "node:fs/promises";
|
|
|
2
2
|
import * as path from "node:path";
|
|
3
3
|
import { type AgentMessage, ThinkingLevel } from "@sayknow-cli/agent-core";
|
|
4
4
|
import { type AutocompleteProvider, matchesKey, type SlashCommand } from "@sayknow-cli/tui";
|
|
5
|
-
import { $
|
|
5
|
+
import { $pickenv, logger, sanitizeText } from "@sayknow-cli/utils";
|
|
6
6
|
import { type AppKeybinding, KEYBINDINGS } from "../../config/keybindings";
|
|
7
7
|
import { isSettingsInitialized, settings } from "../../config/settings";
|
|
8
8
|
import { resolveSubskillActivationForSkillInvocation } from "../../extensibility/skc-plugins";
|
|
@@ -33,6 +33,13 @@ import type { PasteTextContext } from "../components/custom-editor";
|
|
|
33
33
|
import { QueuePaneComponent } from "../components/queue-pane";
|
|
34
34
|
import { type QueuedMessageMoveDirection, QueuedMessageSelectorComponent } from "../components/queued-message-selector";
|
|
35
35
|
|
|
36
|
+
const QUEUE_SELECTOR_NAVIGATION_ACTIONS = [
|
|
37
|
+
"tui.select.up",
|
|
38
|
+
"tui.select.down",
|
|
39
|
+
"tui.select.pageUp",
|
|
40
|
+
"tui.select.pageDown",
|
|
41
|
+
] as const;
|
|
42
|
+
|
|
36
43
|
interface Expandable {
|
|
37
44
|
setExpanded(expanded: boolean): void;
|
|
38
45
|
setManuallyExpanded?(expanded: boolean): void;
|
|
@@ -151,15 +158,24 @@ export class InputController {
|
|
|
151
158
|
case "app.editor.external":
|
|
152
159
|
return Boolean(getEditorCommand());
|
|
153
160
|
case "app.message.followUp":
|
|
154
|
-
case "app.message.queue":
|
|
155
161
|
return (
|
|
156
162
|
this.ctx.session.isStreaming ||
|
|
157
163
|
this.ctx.session.isCompacting ||
|
|
158
164
|
this.ctx.session.isBashRunning ||
|
|
159
165
|
this.ctx.session.isEvalRunning
|
|
160
166
|
);
|
|
167
|
+
case "app.message.queue":
|
|
168
|
+
return (
|
|
169
|
+
this.ctx.editor.getText().trim().length > 0 &&
|
|
170
|
+
(this.ctx.session.isStreaming ||
|
|
171
|
+
this.ctx.session.isCompacting ||
|
|
172
|
+
this.ctx.session.isBashRunning ||
|
|
173
|
+
this.ctx.session.isEvalRunning)
|
|
174
|
+
);
|
|
161
175
|
case "app.message.dequeue":
|
|
162
|
-
return
|
|
176
|
+
return (
|
|
177
|
+
this.ctx.session.getQueuedMessageEntries().length > 0 || this.ctx.compactionQueuedMessages.length > 0
|
|
178
|
+
);
|
|
163
179
|
case "app.clipboard.copyPrompt":
|
|
164
180
|
return this.ctx.editor.getText().length > 0;
|
|
165
181
|
case "app.session.tree":
|
|
@@ -725,8 +741,12 @@ export class InputController {
|
|
|
725
741
|
});
|
|
726
742
|
}
|
|
727
743
|
|
|
744
|
+
// Tab on an empty composer accepts the pending ghost-text prompt suggestion.
|
|
745
|
+
this.ctx.editor.onTab = (text: string) => this.ctx.promptSuggestion?.tryAcceptOnTab(text) === true;
|
|
746
|
+
|
|
728
747
|
this.ctx.editor.onChange = (text: string) => {
|
|
729
748
|
this.#resetEscapeGestures();
|
|
749
|
+
this.ctx.promptSuggestion?.notifyEditorChanged(text);
|
|
730
750
|
const wasBashMode = this.ctx.isBashMode;
|
|
731
751
|
const wasBashNoContext = this.ctx.isBashNoContext;
|
|
732
752
|
const wasPythonMode = this.ctx.isPythonMode;
|
|
@@ -752,6 +772,29 @@ export class InputController {
|
|
|
752
772
|
async submitText(text: string, composer: ComposerSubmissionOptions): Promise<void> {
|
|
753
773
|
text = text.trim();
|
|
754
774
|
if ((!isSettingsInitialized() || settings.get("emojiAutocomplete")) && text) text = expandEmoticons(text);
|
|
775
|
+
if (this.ctx.hasActiveBtw()) {
|
|
776
|
+
if (!text) return;
|
|
777
|
+
if (!text.startsWith("/")) {
|
|
778
|
+
const result = await this.ctx.handleBtwFollowUp(text);
|
|
779
|
+
if (result === "accepted" && this.#canModifyComposer(composer)) {
|
|
780
|
+
this.ctx.editor.setText("");
|
|
781
|
+
this.ctx.pendingImages = [];
|
|
782
|
+
}
|
|
783
|
+
return;
|
|
784
|
+
}
|
|
785
|
+
}
|
|
786
|
+
|
|
787
|
+
if (/^\/btw(?:\s|$)/.test(text)) {
|
|
788
|
+
const slashResult = await executeBuiltinSlashCommand(text, {
|
|
789
|
+
ctx: this.ctx,
|
|
790
|
+
handleBackgroundCommand: () => this.handleBackgroundCommand(),
|
|
791
|
+
composer,
|
|
792
|
+
});
|
|
793
|
+
if (slashResult === true) {
|
|
794
|
+
this.ctx.pendingImages = [];
|
|
795
|
+
return;
|
|
796
|
+
}
|
|
797
|
+
}
|
|
755
798
|
|
|
756
799
|
// Empty submit while streaming with queued messages: flush queues immediately
|
|
757
800
|
if (!text && this.ctx.session.isStreaming && this.ctx.session.queuedMessageCount > 0) {
|
|
@@ -907,7 +950,7 @@ export class InputController {
|
|
|
907
950
|
|
|
908
951
|
// Generate session title on first message
|
|
909
952
|
const hasUserMessages = this.ctx.session.messages.some((m: AgentMessage) => m.role === "user");
|
|
910
|
-
if (!hasUserMessages && !this.ctx.sessionManager.getSessionName() && !$
|
|
953
|
+
if (!hasUserMessages && !this.ctx.sessionManager.getSessionName() && !$pickenv("SKC_NO_TITLE", "PI_NO_TITLE")) {
|
|
911
954
|
const registry = this.ctx.session.modelRegistry;
|
|
912
955
|
generateSessionTitle(
|
|
913
956
|
text,
|
|
@@ -1010,6 +1053,21 @@ export class InputController {
|
|
|
1010
1053
|
};
|
|
1011
1054
|
const pane = new QueuePaneComponent(entries, {
|
|
1012
1055
|
selectedIndex,
|
|
1056
|
+
formatKeyHint: key => this.ctx.keybindings.formatKeyHint(key),
|
|
1057
|
+
formatSelectAction: action => this.ctx.keybindings.getDisplayString(action),
|
|
1058
|
+
matchesSelectAction: (keyData, action) =>
|
|
1059
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1060
|
+
resolveSelectNavigation: keyData =>
|
|
1061
|
+
QUEUE_SELECTOR_NAVIGATION_ACTIONS.find(action =>
|
|
1062
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1063
|
+
),
|
|
1064
|
+
onSelect: entry => {
|
|
1065
|
+
const restored = this.#restoreQueuedMessageToEditor(entry);
|
|
1066
|
+
close();
|
|
1067
|
+
this.ctx.showStatus(
|
|
1068
|
+
restored === 0 ? "Queued message is no longer available" : "Restored queued message to editor",
|
|
1069
|
+
);
|
|
1070
|
+
},
|
|
1013
1071
|
onDelete: (entry, index) => {
|
|
1014
1072
|
const deleted = this.ctx.session.removeQueuedMessageForEditing(entry.id) !== undefined;
|
|
1015
1073
|
const remaining = this.ctx.session.getQueuedMessageEntries();
|
|
@@ -1182,7 +1240,17 @@ export class InputController {
|
|
|
1182
1240
|
this.#restoreEditorFocus();
|
|
1183
1241
|
this.ctx.ui.requestRender();
|
|
1184
1242
|
},
|
|
1185
|
-
{
|
|
1243
|
+
{
|
|
1244
|
+
selectedIndex,
|
|
1245
|
+
formatKeyHint: key => this.ctx.keybindings.formatKeyHint(key),
|
|
1246
|
+
formatSelectAction: action => this.ctx.keybindings.getDisplayString(action),
|
|
1247
|
+
matchesSelectAction: (keyData, action) =>
|
|
1248
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1249
|
+
resolveSelectNavigation: keyData =>
|
|
1250
|
+
QUEUE_SELECTOR_NAVIGATION_ACTIONS.find(action =>
|
|
1251
|
+
this.ctx.keybindings.getKeys(action).some(key => matchesKey(keyData, key)),
|
|
1252
|
+
),
|
|
1253
|
+
},
|
|
1186
1254
|
);
|
|
1187
1255
|
this.ctx.editorContainer.clear();
|
|
1188
1256
|
this.ctx.editorContainer.addChild(selector);
|
|
@@ -1357,6 +1425,14 @@ export class InputController {
|
|
|
1357
1425
|
async handleFollowUp(): Promise<void> {
|
|
1358
1426
|
const text = this.ctx.editor.getText().trim();
|
|
1359
1427
|
if (!text) return;
|
|
1428
|
+
// While /btw is open, plain text stays in the side chat. Slash-origin
|
|
1429
|
+
// input keeps normal dispatch so commands remain available.
|
|
1430
|
+
if (this.ctx.hasActiveBtw() && !text.startsWith("/")) {
|
|
1431
|
+
if ((await this.ctx.handleBtwFollowUp(text)) === "accepted") {
|
|
1432
|
+
this.ctx.editor.setText("");
|
|
1433
|
+
}
|
|
1434
|
+
return;
|
|
1435
|
+
}
|
|
1360
1436
|
|
|
1361
1437
|
// Compaction first: while compacting, queue free text and `/skill:*`
|
|
1362
1438
|
// commands in the compaction-local queue. `flushCompactionQueue`
|
|
@@ -1758,6 +1834,7 @@ export class InputController {
|
|
|
1758
1834
|
moveCursorToMessageStart: () => this.ctx.editor.moveToMessageStart(),
|
|
1759
1835
|
moveCursorToLineStart: () => this.ctx.editor.moveToLineStart(),
|
|
1760
1836
|
moveCursorToLineEnd: () => this.ctx.editor.moveToLineEnd(),
|
|
1837
|
+
getPromptSuggestion: () => this.ctx.promptSuggestion?.current ?? null,
|
|
1761
1838
|
});
|
|
1762
1839
|
}
|
|
1763
1840
|
|
|
@@ -1967,9 +2044,24 @@ export class InputController {
|
|
|
1967
2044
|
}
|
|
1968
2045
|
|
|
1969
2046
|
toggleThinkingBlockVisibility(): void {
|
|
1970
|
-
|
|
1971
|
-
|
|
1972
|
-
|
|
2047
|
+
if (!settings.canWriteDurableConfig()) {
|
|
2048
|
+
this.ctx.showError(
|
|
2049
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
2050
|
+
);
|
|
2051
|
+
return;
|
|
2052
|
+
}
|
|
2053
|
+
const hideThinkingBlock = !this.ctx.hideThinkingBlock;
|
|
2054
|
+
try {
|
|
2055
|
+
settings.set("hideThinkingBlock", hideThinkingBlock);
|
|
2056
|
+
} catch (error) {
|
|
2057
|
+
if (!settings.canWriteDurableConfig()) {
|
|
2058
|
+
this.ctx.showError(error instanceof Error ? error.message : String(error));
|
|
2059
|
+
return;
|
|
2060
|
+
}
|
|
2061
|
+
throw error;
|
|
2062
|
+
}
|
|
2063
|
+
this.ctx.hideThinkingBlock = hideThinkingBlock;
|
|
2064
|
+
this.ctx.session.setThinkingVisibility(hideThinkingBlock ? "hidden" : "visible");
|
|
1973
2065
|
|
|
1974
2066
|
// Rebuild chat from session messages
|
|
1975
2067
|
// Detach the live streaming component before the disposing clear() so the
|