@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
|
@@ -4,9 +4,26 @@ import type { ParsedIrcMessage } from "./utils/irc-message";
|
|
|
4
4
|
|
|
5
5
|
type InlineMode = "persistent" | "ephemeral";
|
|
6
6
|
|
|
7
|
-
const
|
|
8
|
-
const
|
|
9
|
-
const
|
|
7
|
+
export const IRC_OBSERVATION_LEDGER_MAX_RECORDS = 10_000;
|
|
8
|
+
export const IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES = 16 * 1024 * 1024;
|
|
9
|
+
export const IRC_OBSERVATION_LEDGER_MAX_SEEN_IDENTITIES = 100_000;
|
|
10
|
+
|
|
11
|
+
export const __ircLedgerPerfCounters = {
|
|
12
|
+
enabled: false,
|
|
13
|
+
epochAdvances: 0,
|
|
14
|
+
snapshot() {
|
|
15
|
+
return { epochAdvances: this.epochAdvances };
|
|
16
|
+
},
|
|
17
|
+
enable(): void {
|
|
18
|
+
this.enabled = true;
|
|
19
|
+
},
|
|
20
|
+
disable(): void {
|
|
21
|
+
this.enabled = false;
|
|
22
|
+
},
|
|
23
|
+
reset(): void {
|
|
24
|
+
this.epochAdvances = 0;
|
|
25
|
+
},
|
|
26
|
+
};
|
|
10
27
|
|
|
11
28
|
export type IrcObservationRecord = Readonly<
|
|
12
29
|
ParsedIrcMessage & {
|
|
@@ -22,7 +39,7 @@ function measureRetainedUtf8Bytes(message: ParsedIrcMessage): number {
|
|
|
22
39
|
let bytes = 4;
|
|
23
40
|
for (const value of [message.observationId, message.from, message.to, message.text, message.kind]) {
|
|
24
41
|
bytes += Buffer.byteLength(value, "utf8");
|
|
25
|
-
if (bytes >
|
|
42
|
+
if (bytes > IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES) return bytes;
|
|
26
43
|
}
|
|
27
44
|
return bytes;
|
|
28
45
|
}
|
|
@@ -43,12 +60,28 @@ export class IrcObservationLedger {
|
|
|
43
60
|
#nextSequence = 0;
|
|
44
61
|
#seenObservationIdentities = new Set<string>();
|
|
45
62
|
#identityCapacityExhausted = false;
|
|
63
|
+
#retiredSessionIdentities = new Set<string>();
|
|
46
64
|
#evictedObservationIds = new Set<string>();
|
|
65
|
+
#mutationEpoch = 0;
|
|
66
|
+
|
|
67
|
+
get mutationEpoch(): number {
|
|
68
|
+
return this.#mutationEpoch;
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
#advanceMutationEpoch(): void {
|
|
72
|
+
this.#mutationEpoch++;
|
|
73
|
+
if (__ircLedgerPerfCounters.enabled) __ircLedgerPerfCounters.epochAdvances++;
|
|
74
|
+
}
|
|
47
75
|
|
|
48
76
|
#rememberObservationIdentity(observationId: string): boolean {
|
|
49
77
|
const identity = tombstoneIdentity(observationId);
|
|
50
|
-
if (
|
|
51
|
-
|
|
78
|
+
if (
|
|
79
|
+
this.#seenObservationIdentities.has(identity) ||
|
|
80
|
+
this.#retiredSessionIdentities.has(identity) ||
|
|
81
|
+
this.#identityCapacityExhausted
|
|
82
|
+
)
|
|
83
|
+
return false;
|
|
84
|
+
if (this.#seenObservationIdentities.size >= IRC_OBSERVATION_LEDGER_MAX_SEEN_IDENTITIES) {
|
|
52
85
|
this.#identityCapacityExhausted = true;
|
|
53
86
|
return false;
|
|
54
87
|
}
|
|
@@ -56,6 +89,18 @@ export class IrcObservationLedger {
|
|
|
56
89
|
return true;
|
|
57
90
|
}
|
|
58
91
|
|
|
92
|
+
#retireCurrentSessionIdentities(): void {
|
|
93
|
+
for (const identity of this.#seenObservationIdentities) {
|
|
94
|
+
this.#retiredSessionIdentities.delete(identity);
|
|
95
|
+
this.#retiredSessionIdentities.add(identity);
|
|
96
|
+
while (this.#retiredSessionIdentities.size > IRC_OBSERVATION_LEDGER_MAX_SEEN_IDENTITIES) {
|
|
97
|
+
const oldest = this.#retiredSessionIdentities.values().next().value;
|
|
98
|
+
if (oldest === undefined) break;
|
|
99
|
+
this.#retiredSessionIdentities.delete(oldest);
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
|
|
59
104
|
#evict(observationId: string): void {
|
|
60
105
|
const record = this.#records.get(observationId);
|
|
61
106
|
if (!record) return;
|
|
@@ -65,7 +110,10 @@ export class IrcObservationLedger {
|
|
|
65
110
|
}
|
|
66
111
|
|
|
67
112
|
#enforceBounds(): void {
|
|
68
|
-
while (
|
|
113
|
+
while (
|
|
114
|
+
this.#records.size > IRC_OBSERVATION_LEDGER_MAX_RECORDS ||
|
|
115
|
+
this.#retainedUtf8Bytes > IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES
|
|
116
|
+
) {
|
|
69
117
|
const oldestObservationId = this.#records.keys().next().value;
|
|
70
118
|
if (oldestObservationId === undefined) return;
|
|
71
119
|
this.#evict(oldestObservationId);
|
|
@@ -76,10 +124,9 @@ export class IrcObservationLedger {
|
|
|
76
124
|
observe(message: ParsedIrcMessage, panelVisibleAtObservation: boolean): IrcObservationRecord | undefined {
|
|
77
125
|
const existing = this.#records.get(message.observationId);
|
|
78
126
|
if (existing) return existing;
|
|
79
|
-
if (!this.#rememberObservationIdentity(message.observationId)) return undefined;
|
|
80
|
-
|
|
81
127
|
const estimatedBytes = measureRetainedUtf8Bytes(message);
|
|
82
|
-
if (estimatedBytes >
|
|
128
|
+
if (estimatedBytes > IRC_OBSERVATION_LEDGER_MAX_RETAINED_UTF8_BYTES) return undefined;
|
|
129
|
+
if (!this.#rememberObservationIdentity(message.observationId)) return undefined;
|
|
83
130
|
|
|
84
131
|
const observedAt = Date.now();
|
|
85
132
|
const mode: InlineMode = panelVisibleAtObservation ? "ephemeral" : "persistent";
|
|
@@ -94,6 +141,7 @@ export class IrcObservationLedger {
|
|
|
94
141
|
this.#records.set(record.observationId, record);
|
|
95
142
|
this.#retainedUtf8Bytes += estimatedBytes;
|
|
96
143
|
this.#enforceBounds();
|
|
144
|
+
this.#advanceMutationEpoch();
|
|
97
145
|
return this.#records.get(record.observationId);
|
|
98
146
|
}
|
|
99
147
|
|
|
@@ -116,12 +164,20 @@ export class IrcObservationLedger {
|
|
|
116
164
|
return observationIds;
|
|
117
165
|
}
|
|
118
166
|
|
|
119
|
-
reset(): void {
|
|
120
|
-
|
|
121
|
-
|
|
167
|
+
reset(options?: { retireCurrentSessionIdentities?: boolean }): void {
|
|
168
|
+
const retainedRecordsChanged = this.#records.size > 0;
|
|
169
|
+
if (options?.retireCurrentSessionIdentities) this.#retireCurrentSessionIdentities();
|
|
170
|
+
else this.#retiredSessionIdentities.clear();
|
|
171
|
+
if (retainedRecordsChanged) {
|
|
172
|
+
for (const observationId of this.#records.keys()) {
|
|
173
|
+
this.#evictedObservationIds.add(observationId);
|
|
174
|
+
}
|
|
175
|
+
this.#records.clear();
|
|
176
|
+
this.#retainedUtf8Bytes = 0;
|
|
122
177
|
}
|
|
123
|
-
this.#records.clear();
|
|
124
|
-
this.#retainedUtf8Bytes = 0;
|
|
125
178
|
this.#nextSequence = 0;
|
|
179
|
+
this.#seenObservationIdentities.clear();
|
|
180
|
+
this.#identityCapacityExhausted = false;
|
|
181
|
+
if (retainedRecordsChanged) this.#advanceMutationEpoch();
|
|
126
182
|
}
|
|
127
183
|
}
|
|
@@ -3,12 +3,10 @@ import {
|
|
|
3
3
|
type AutocompleteProvider,
|
|
4
4
|
CombinedAutocompleteProvider,
|
|
5
5
|
extractSlashCommandTokenPrefix,
|
|
6
|
-
getKeybindings,
|
|
7
6
|
getSlashCommandMatchRank,
|
|
8
7
|
type SlashCommand,
|
|
9
8
|
} from "@sayknow-cli/tui";
|
|
10
9
|
import type { KeybindingsManager } from "../config/keybindings";
|
|
11
|
-
import { formatKeyHints } from "../config/keybindings";
|
|
12
10
|
import { isSettingsInitialized, settings } from "../config/settings";
|
|
13
11
|
import { applyEmojiCompletion, getEmojiSuggestions, isEmojiPrefix, tryEmojiInlineReplace } from "./emoji-autocomplete";
|
|
14
12
|
|
|
@@ -44,6 +42,11 @@ interface PromptActionAutocompleteOptions {
|
|
|
44
42
|
moveCursorToMessageStart: () => void;
|
|
45
43
|
moveCursorToLineStart: () => void;
|
|
46
44
|
moveCursorToLineEnd: () => void;
|
|
45
|
+
/**
|
|
46
|
+
* Ghost-text next-prompt prediction shown in the empty composer as a dim
|
|
47
|
+
* inline hint (Tab accepts it via the editor's onTab handler).
|
|
48
|
+
*/
|
|
49
|
+
getPromptSuggestion?: () => string | null;
|
|
47
50
|
}
|
|
48
51
|
|
|
49
52
|
function fuzzyMatch(query: string, target: string): boolean {
|
|
@@ -186,11 +189,18 @@ export class PromptActionAutocompleteProvider implements AutocompleteProvider {
|
|
|
186
189
|
#baseProvider: CombinedAutocompleteProvider;
|
|
187
190
|
#actions: PromptActionDefinition[];
|
|
188
191
|
#commands: SlashCommand[];
|
|
189
|
-
|
|
190
|
-
|
|
192
|
+
#getPromptSuggestion: (() => string | null) | undefined;
|
|
193
|
+
|
|
194
|
+
constructor(
|
|
195
|
+
commands: SlashCommand[],
|
|
196
|
+
basePath: string,
|
|
197
|
+
actions: PromptActionDefinition[],
|
|
198
|
+
getPromptSuggestion?: () => string | null,
|
|
199
|
+
) {
|
|
191
200
|
this.#baseProvider = new CombinedAutocompleteProvider(commands, basePath);
|
|
192
201
|
this.#actions = actions;
|
|
193
202
|
this.#commands = commands;
|
|
203
|
+
this.#getPromptSuggestion = getPromptSuggestion;
|
|
194
204
|
}
|
|
195
205
|
|
|
196
206
|
async getSuggestions(
|
|
@@ -309,6 +319,11 @@ export class PromptActionAutocompleteProvider implements AutocompleteProvider {
|
|
|
309
319
|
}
|
|
310
320
|
|
|
311
321
|
getInlineHint(lines: string[], cursorLine: number, cursorCol: number): string | null {
|
|
322
|
+
// An empty composer renders the pending prompt suggestion as ghost text.
|
|
323
|
+
if (lines.every(line => line === "")) {
|
|
324
|
+
const suggestion = this.#getPromptSuggestion?.();
|
|
325
|
+
if (suggestion) return suggestion;
|
|
326
|
+
}
|
|
312
327
|
return this.#baseProvider.getInlineHint?.(lines, cursorLine, cursorCol) ?? null;
|
|
313
328
|
}
|
|
314
329
|
trySyncSlashCompletion(textBeforeCursor: string): { items: AutocompleteItem[]; prefix: string } | null {
|
|
@@ -382,12 +397,11 @@ export class PromptActionAutocompleteProvider implements AutocompleteProvider {
|
|
|
382
397
|
export function createPromptActionAutocompleteProvider(
|
|
383
398
|
options: PromptActionAutocompleteOptions,
|
|
384
399
|
): PromptActionAutocompleteProvider {
|
|
385
|
-
const editorKeybindings = getKeybindings();
|
|
386
400
|
const actions: PromptActionDefinition[] = [
|
|
387
401
|
{
|
|
388
402
|
id: "new-session",
|
|
389
403
|
label: "Start new session",
|
|
390
|
-
description:
|
|
404
|
+
description: options.keybindings.getDisplayString("app.session.new"),
|
|
391
405
|
keywords: ["new", "session", "fresh", "clear", "start", "conversation"],
|
|
392
406
|
execute: options.newSession,
|
|
393
407
|
},
|
|
@@ -401,21 +415,21 @@ export function createPromptActionAutocompleteProvider(
|
|
|
401
415
|
{
|
|
402
416
|
id: "copy-line",
|
|
403
417
|
label: "Copy current line",
|
|
404
|
-
description:
|
|
418
|
+
description: options.keybindings.getDisplayString("app.clipboard.copyLine"),
|
|
405
419
|
keywords: ["copy", "line", "clipboard", "current"],
|
|
406
420
|
execute: options.copyCurrentLine,
|
|
407
421
|
},
|
|
408
422
|
{
|
|
409
423
|
id: "copy-prompt",
|
|
410
424
|
label: "Copy whole prompt",
|
|
411
|
-
description:
|
|
425
|
+
description: options.keybindings.getDisplayString("app.clipboard.copyPrompt"),
|
|
412
426
|
keywords: ["copy", "prompt", "clipboard", "message"],
|
|
413
427
|
execute: options.copyPrompt,
|
|
414
428
|
},
|
|
415
429
|
{
|
|
416
430
|
id: "paste-image",
|
|
417
431
|
label: "Paste image from clipboard",
|
|
418
|
-
description:
|
|
432
|
+
description: options.keybindings.getDisplayString("app.clipboard.pasteImage"),
|
|
419
433
|
keywords: ["paste", "image", "clipboard", "screenshot", "attach", "vision"],
|
|
420
434
|
execute: options.pasteImage,
|
|
421
435
|
},
|
|
@@ -429,7 +443,7 @@ export function createPromptActionAutocompleteProvider(
|
|
|
429
443
|
{
|
|
430
444
|
id: "undo",
|
|
431
445
|
label: "Undo",
|
|
432
|
-
description:
|
|
446
|
+
description: options.keybindings.getDisplayString("tui.editor.undo"),
|
|
433
447
|
keywords: ["undo", "revert", "edit", "history"],
|
|
434
448
|
execute: options.undo,
|
|
435
449
|
},
|
|
@@ -450,18 +464,23 @@ export function createPromptActionAutocompleteProvider(
|
|
|
450
464
|
{
|
|
451
465
|
id: "cursor-line-start",
|
|
452
466
|
label: "Move cursor to beginning of line",
|
|
453
|
-
description:
|
|
467
|
+
description: options.keybindings.getDisplayString("tui.editor.cursorLineStart"),
|
|
454
468
|
keywords: ["move", "cursor", "line", "start", "beginning", "home"],
|
|
455
469
|
execute: options.moveCursorToLineStart,
|
|
456
470
|
},
|
|
457
471
|
{
|
|
458
472
|
id: "cursor-line-end",
|
|
459
473
|
label: "Move cursor to end of line",
|
|
460
|
-
description:
|
|
474
|
+
description: options.keybindings.getDisplayString("tui.editor.cursorLineEnd"),
|
|
461
475
|
keywords: ["move", "cursor", "line", "end"],
|
|
462
476
|
execute: options.moveCursorToLineEnd,
|
|
463
477
|
},
|
|
464
478
|
];
|
|
465
479
|
|
|
466
|
-
return new PromptActionAutocompleteProvider(
|
|
480
|
+
return new PromptActionAutocompleteProvider(
|
|
481
|
+
options.commands,
|
|
482
|
+
options.basePath,
|
|
483
|
+
actions,
|
|
484
|
+
options.getPromptSuggestion,
|
|
485
|
+
);
|
|
467
486
|
}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { logger } from "@sayknow-cli/utils";
|
|
2
|
+
import { generatePromptSuggestion } from "../utils/prompt-suggestion";
|
|
3
|
+
import type { InteractiveModeContext } from "./types";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Owns the ghost-text next-prompt prediction lifecycle for interactive mode.
|
|
7
|
+
*
|
|
8
|
+
* After each agent turn ends (and only when `promptSuggestions` is enabled
|
|
9
|
+
* and the composer is empty), a smol-model prediction of the user's next
|
|
10
|
+
* prompt is generated in the background. The result renders as dim ghost
|
|
11
|
+
* text in the empty composer via the autocomplete provider's inline hint;
|
|
12
|
+
* Tab accepts it, typing dismisses it, and a new turn clears it.
|
|
13
|
+
*/
|
|
14
|
+
export class PromptSuggestionController {
|
|
15
|
+
#ctx: InteractiveModeContext;
|
|
16
|
+
#current: string | null = null;
|
|
17
|
+
/** Monotonic token; bumping it invalidates any in-flight generation. */
|
|
18
|
+
#generation = 0;
|
|
19
|
+
|
|
20
|
+
constructor(ctx: InteractiveModeContext) {
|
|
21
|
+
this.#ctx = ctx;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/** Current suggestion to render as ghost text, or null. */
|
|
25
|
+
get current(): string | null {
|
|
26
|
+
return this.#current;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
/** Drop the current suggestion and invalidate any in-flight generation. */
|
|
30
|
+
clear(): void {
|
|
31
|
+
this.#generation++;
|
|
32
|
+
if (this.#current === null) return;
|
|
33
|
+
this.#current = null;
|
|
34
|
+
this.#ctx.ui.requestRender();
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** A new agent turn started; any pending suggestion is stale. */
|
|
38
|
+
onAgentStart(): void {
|
|
39
|
+
this.clear();
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Editor content changed. A non-empty composer means the user is writing
|
|
44
|
+
* their own prompt: dismiss the suggestion and cancel pending generation.
|
|
45
|
+
*/
|
|
46
|
+
notifyEditorChanged(text: string): void {
|
|
47
|
+
if (text.length > 0) this.clear();
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Agent turn ended; kick off background generation when the feature is
|
|
52
|
+
* enabled and the composer is idle and empty.
|
|
53
|
+
*/
|
|
54
|
+
onAgentEnd(): void {
|
|
55
|
+
if (!this.#ctx.settings.get("promptSuggestions")) return;
|
|
56
|
+
if (this.#ctx.shutdownRequested) return;
|
|
57
|
+
if (this.#ctx.session.isStreaming) return;
|
|
58
|
+
if (this.#ctx.editor.getText().trim() !== "") return;
|
|
59
|
+
|
|
60
|
+
const generation = ++this.#generation;
|
|
61
|
+
void generatePromptSuggestion(
|
|
62
|
+
this.#ctx.session.messages,
|
|
63
|
+
this.#ctx.session.modelRegistry,
|
|
64
|
+
this.#ctx.settings,
|
|
65
|
+
this.#ctx.session.sessionId,
|
|
66
|
+
this.#ctx.session.model,
|
|
67
|
+
provider => this.#ctx.session.agent.metadataForProvider(provider),
|
|
68
|
+
)
|
|
69
|
+
.then(suggestion => {
|
|
70
|
+
if (generation !== this.#generation) return;
|
|
71
|
+
if (!suggestion) return;
|
|
72
|
+
// The world may have moved on while the model was thinking.
|
|
73
|
+
if (this.#ctx.session.isStreaming) return;
|
|
74
|
+
if (this.#ctx.editor.getText().trim() !== "") return;
|
|
75
|
+
this.#current = suggestion;
|
|
76
|
+
this.#ctx.ui.requestRender();
|
|
77
|
+
})
|
|
78
|
+
.catch(error => {
|
|
79
|
+
logger.debug("prompt-suggestion: generation failed", { error: String(error) });
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
/**
|
|
84
|
+
* Tab handler for the composer: accept the suggestion when the composer
|
|
85
|
+
* is empty. Returns true when Tab was consumed.
|
|
86
|
+
*/
|
|
87
|
+
tryAcceptOnTab(text: string): boolean {
|
|
88
|
+
const suggestion = this.#current;
|
|
89
|
+
if (!suggestion || text.trim() !== "") return false;
|
|
90
|
+
// setText fires onChange with non-empty text, which clears #current.
|
|
91
|
+
this.#ctx.editor.setText(suggestion);
|
|
92
|
+
this.clear();
|
|
93
|
+
this.#ctx.ui.requestRender();
|
|
94
|
+
return true;
|
|
95
|
+
}
|
|
96
|
+
}
|
|
@@ -115,6 +115,7 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
115
115
|
compact: instructionsOrOptions => runExtensionCompact(session, instructionsOrOptions),
|
|
116
116
|
clearContext: () => session.clearContext(),
|
|
117
117
|
cycleModel: () => session.cycleModel(),
|
|
118
|
+
setModelProfile: name => session.activateModelProfileForControl(name),
|
|
118
119
|
cycleThinkingLevel: () => session.cycleThinkingLevel(),
|
|
119
120
|
setQueueMode: (kind, mode) => {
|
|
120
121
|
if (kind === "steering" && (mode === "all" || mode === "one-at-a-time")) {
|
|
@@ -131,7 +132,7 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
131
132
|
}
|
|
132
133
|
return false;
|
|
133
134
|
},
|
|
134
|
-
invokeSkill: (name, args) => session.invokeSkill(name, args),
|
|
135
|
+
invokeSkill: (name, args, options) => session.invokeSkill(name, args, options),
|
|
135
136
|
setPlanMode: on => session.setSdkPlanMode(on),
|
|
136
137
|
operateGoal: (op, objective) => session.operateGoal(op, objective),
|
|
137
138
|
getSkillState: () => session.skills.map(skill => ({ name: skill.name, description: skill.description })),
|
|
@@ -379,7 +380,24 @@ export async function initializeExtensions(session: AgentSession, options: Initi
|
|
|
379
380
|
const disabled = [...(session.settings.get("disabledExtensions") ?? [])];
|
|
380
381
|
const on = input.on === true;
|
|
381
382
|
const next = on ? disabled.filter(value => value !== id) : [...new Set([...disabled, id])];
|
|
382
|
-
session.settings.
|
|
383
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
384
|
+
throw Object.assign(
|
|
385
|
+
new Error(
|
|
386
|
+
"Cannot change settings while config.yml has invalid YAML syntax. Repair config.yml and reload settings.",
|
|
387
|
+
),
|
|
388
|
+
{ code: "invalid_request" },
|
|
389
|
+
);
|
|
390
|
+
}
|
|
391
|
+
try {
|
|
392
|
+
session.settings.set("disabledExtensions", next);
|
|
393
|
+
} catch (error) {
|
|
394
|
+
if (!session.settings.canWriteDurableConfig()) {
|
|
395
|
+
throw Object.assign(new Error(error instanceof Error ? error.message : String(error)), {
|
|
396
|
+
code: "invalid_request",
|
|
397
|
+
});
|
|
398
|
+
}
|
|
399
|
+
throw error;
|
|
400
|
+
}
|
|
383
401
|
return { changed: true, enabled: on };
|
|
384
402
|
}
|
|
385
403
|
case "session.delete":
|
|
@@ -219,9 +219,9 @@ export async function dispatchRpcCommand(
|
|
|
219
219
|
case "set_host_tools": {
|
|
220
220
|
const tools = normalizeHostToolDefinitions(command.tools);
|
|
221
221
|
const rpcTools = hostToolRegistry.setTools(tools);
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
222
|
+
// TODO(upstream-v0.11): AgentSession.refreshRpcHostTools was removed; the host-tool
|
|
223
|
+
// registry already holds the updated set via hostToolRegistry.setTools above.
|
|
224
|
+
void rpcTools;
|
|
225
225
|
return rpcSuccess(id, "set_host_tools", { toolNames: tools.map(tool => tool.name) });
|
|
226
226
|
}
|
|
227
227
|
|
|
@@ -95,7 +95,7 @@ export interface AskSelectedAckRecoveryParticipant {
|
|
|
95
95
|
|
|
96
96
|
/** SDK-native surface for emitting a workflow gate and awaiting its answer. */
|
|
97
97
|
export interface WorkflowGateEmitter {
|
|
98
|
-
|
|
98
|
+
supportsRemoteGateAnswers(): boolean;
|
|
99
99
|
emitGate(input: OpenGateInput): Promise<unknown>;
|
|
100
100
|
onGateEmitted?(listener: (gate: WorkflowGate) => void): () => void;
|
|
101
101
|
resolveGate?(response: WorkflowGateResponse): Promise<WorkflowGateResolution>;
|
|
@@ -167,7 +167,7 @@ export class BrokerWorkflowGateEmitter implements WorkflowGateEmitter {
|
|
|
167
167
|
});
|
|
168
168
|
}
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
supportsRemoteGateAnswers(): boolean {
|
|
171
171
|
return true;
|
|
172
172
|
}
|
|
173
173
|
setRuntimeTurnProvider(provider: (() => string | undefined) | null): void {
|
package/src/modes/types.ts
CHANGED
|
@@ -32,6 +32,7 @@ import type { ToolExecutionHandle } from "./components/tool-execution";
|
|
|
32
32
|
import type { StatusLineComponent } from "./components/tool-status-header";
|
|
33
33
|
import type { IrcObservationLedger } from "./irc-observation-ledger";
|
|
34
34
|
import type { OAuthManualInputManager } from "./oauth-manual-input";
|
|
35
|
+
import type { PromptSuggestionController } from "./prompt-suggestion-controller";
|
|
35
36
|
import type { Theme } from "./theme/theme";
|
|
36
37
|
import type { ParsedIrcMessage } from "./utils/irc-message";
|
|
37
38
|
|
|
@@ -156,6 +157,8 @@ export interface InteractiveModeContext {
|
|
|
156
157
|
skillCommands: Map<string, Skill>;
|
|
157
158
|
oauthManualInput: OAuthManualInputManager;
|
|
158
159
|
todoPhases: TodoPhase[];
|
|
160
|
+
/** Ghost-text next-prompt prediction; absent in ACP/lightweight test contexts. */
|
|
161
|
+
promptSuggestion?: PromptSuggestionController;
|
|
159
162
|
|
|
160
163
|
// Lifecycle
|
|
161
164
|
init(): Promise<void>;
|
|
@@ -245,6 +248,8 @@ export interface InteractiveModeContext {
|
|
|
245
248
|
getAssistantViewportAnchorId?(message: AssistantMessage): string;
|
|
246
249
|
findLastAssistantMessage(): AssistantMessage | undefined;
|
|
247
250
|
extractAssistantText(message: AssistantMessage): string;
|
|
251
|
+
/** Records one semantic visible-transcript mutation for the sticky viewport. */
|
|
252
|
+
recordVisibleTranscriptMutation?(): void;
|
|
248
253
|
updateEditorTopBorder(): void;
|
|
249
254
|
updateEditorBorderColor(): void;
|
|
250
255
|
rebuildChatFromMessages(policy: TranscriptRebuildPolicy): void;
|
|
@@ -338,6 +343,7 @@ export interface InteractiveModeContext {
|
|
|
338
343
|
handleBackgroundCommand(): void;
|
|
339
344
|
handleImagePaste(): Promise<boolean>;
|
|
340
345
|
handleBtwCommand(question: string): Promise<void>;
|
|
346
|
+
handleBtwFollowUp(question: string): Promise<"accepted" | "busy" | "closed" | "rejected">;
|
|
341
347
|
hasActiveBtw(): boolean;
|
|
342
348
|
handleBtwEscape(): boolean;
|
|
343
349
|
cycleThinkingLevel(): void;
|
|
@@ -1,60 +1,88 @@
|
|
|
1
|
+
import type { Keybinding } from "@sayknow-cli/tui";
|
|
1
2
|
import type { AppKeybinding, KeybindingsManager } from "../../config/keybindings";
|
|
2
3
|
|
|
3
4
|
export interface HotkeysMarkdownBindings {
|
|
4
|
-
keybindings: Pick<KeybindingsManager, "
|
|
5
|
+
keybindings: Pick<KeybindingsManager, "formatAccessibleKeyHint" | "getAccessibleDisplayString">;
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
function key(bindings: HotkeysMarkdownBindings, action: Keybinding): string {
|
|
9
|
+
return bindings.keybindings.getAccessibleDisplayString(action) || "Disabled";
|
|
5
10
|
}
|
|
6
11
|
|
|
7
12
|
function appKey(bindings: HotkeysMarkdownBindings, action: AppKeybinding): string {
|
|
8
|
-
return bindings
|
|
13
|
+
return key(bindings, action);
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
export function formatHotkeyMarkdownCode(label: string, escapeTablePipes = true): string {
|
|
17
|
+
const escaped = escapeTablePipes ? label.replace(/\|/g, "\\|") : label;
|
|
18
|
+
let longestBacktickRun = 0;
|
|
19
|
+
for (const match of escaped.matchAll(/`+/g)) {
|
|
20
|
+
longestBacktickRun = Math.max(longestBacktickRun, match[0].length);
|
|
21
|
+
}
|
|
22
|
+
const fence = "`".repeat(longestBacktickRun + 1);
|
|
23
|
+
const padding = escaped.startsWith("`") || escaped.endsWith("`") ? " " : "";
|
|
24
|
+
return `${fence}${padding}${escaped}${padding}${fence}`;
|
|
9
25
|
}
|
|
10
26
|
|
|
11
27
|
export function buildHotkeysMarkdown(bindings: HotkeysMarkdownBindings): string {
|
|
28
|
+
const displayKey = (action: Keybinding): string => formatHotkeyMarkdownCode(key(bindings, action));
|
|
29
|
+
const displayAppKey = (action: AppKeybinding): string => formatHotkeyMarkdownCode(appKey(bindings, action));
|
|
30
|
+
const displayKeys = (...labels: string[]): string => formatHotkeyMarkdownCode(labels.join("/"));
|
|
31
|
+
const formatFixedKey = (key: string): string => bindings.keybindings.formatAccessibleKeyHint(key);
|
|
32
|
+
const displayKeyWithFixed = (action: Keybinding, fixedKey: string): string => {
|
|
33
|
+
const configured = key(bindings, action);
|
|
34
|
+
const fixed = formatFixedKey(fixedKey);
|
|
35
|
+
const labels = configured.split("/");
|
|
36
|
+
if (!labels.includes(fixed)) labels.push(fixed);
|
|
37
|
+
return displayKeys(...labels);
|
|
38
|
+
};
|
|
39
|
+
|
|
12
40
|
return [
|
|
13
41
|
"**Navigation**",
|
|
14
42
|
"| Key | Action |",
|
|
15
43
|
"|-----|--------|",
|
|
16
|
-
"
|
|
17
|
-
"
|
|
18
|
-
"
|
|
19
|
-
"
|
|
44
|
+
`| ${displayKeys(key(bindings, "tui.editor.cursorUp"), key(bindings, "tui.editor.cursorDown"))} | Move cursor / browse history (Up when empty) |`,
|
|
45
|
+
`| ${displayKeys(key(bindings, "tui.editor.cursorWordLeft"), key(bindings, "tui.editor.cursorWordRight"))} | Move by word |`,
|
|
46
|
+
`| ${displayKeyWithFixed("tui.editor.cursorLineStart", "ctrl+a")} | Start of line |`,
|
|
47
|
+
`| ${displayKeyWithFixed("tui.editor.cursorLineEnd", "ctrl+e")} | End of line |`,
|
|
20
48
|
"",
|
|
21
49
|
"**Editing**",
|
|
22
50
|
"| Key | Action |",
|
|
23
51
|
"|-----|--------|",
|
|
24
|
-
"
|
|
25
|
-
`|
|
|
26
|
-
`|
|
|
27
|
-
|
|
28
|
-
"
|
|
29
|
-
"
|
|
30
|
-
"
|
|
31
|
-
`|
|
|
32
|
-
`|
|
|
52
|
+
`| ${displayKey("tui.input.submit")} | Send / queue while busy |`,
|
|
53
|
+
`| ${displayAppKey("app.message.queue")} | Queue message for next turn |`,
|
|
54
|
+
`| ${displayAppKey("app.message.dequeue")} | Select queued message to edit |`,
|
|
55
|
+
`| ${displayKeys(key(bindings, "tui.input.newLine"), formatFixedKey("ctrl+j"))} | New line |`,
|
|
56
|
+
`| ${displayKeys(formatFixedKey("ctrl+w"), formatFixedKey("alt+backspace"))} | Delete word backwards |`,
|
|
57
|
+
`| ${displayKeys(formatFixedKey("ctrl+u"))} | Delete to start of line |`,
|
|
58
|
+
`| ${displayKeys(formatFixedKey("ctrl+k"))} | Delete to end of line |`,
|
|
59
|
+
`| ${displayAppKey("app.clipboard.copyLine")} | Copy current line |`,
|
|
60
|
+
`| ${displayAppKey("app.clipboard.copyPrompt")} | Copy whole prompt |`,
|
|
33
61
|
"",
|
|
34
62
|
"**Other**",
|
|
35
63
|
"| Key | Action |",
|
|
36
64
|
"|-----|--------|",
|
|
37
|
-
"
|
|
38
|
-
`|
|
|
39
|
-
`|
|
|
40
|
-
`|
|
|
41
|
-
`|
|
|
42
|
-
`|
|
|
43
|
-
`|
|
|
44
|
-
`|
|
|
45
|
-
`|
|
|
46
|
-
`|
|
|
47
|
-
`|
|
|
48
|
-
`|
|
|
49
|
-
`|
|
|
50
|
-
`|
|
|
51
|
-
`|
|
|
52
|
-
`|
|
|
53
|
-
`|
|
|
54
|
-
`|
|
|
55
|
-
`|
|
|
56
|
-
`|
|
|
57
|
-
`|
|
|
65
|
+
`| ${displayKey("tui.input.tab")} | Path completion / accept autocomplete |`,
|
|
66
|
+
`| ${displayAppKey("app.interrupt")} | Cancel autocomplete / interrupt active work |`,
|
|
67
|
+
`| ${displayAppKey("app.clear")} | Clear editor (first) / exit (second) |`,
|
|
68
|
+
`| ${displayAppKey("app.exit")} | Exit (when editor is empty) |`,
|
|
69
|
+
`| ${displayAppKey("app.suspend")} | Suspend to background |`,
|
|
70
|
+
`| ${displayAppKey("app.commandPalette.open")} | Open command palette |`,
|
|
71
|
+
`| ${displayAppKey("app.session.new")} | Start a fresh session |`,
|
|
72
|
+
`| ${displayAppKey("app.thinking.cycle")} | Cycle thinking level |`,
|
|
73
|
+
`| ${displayAppKey("app.model.cycleForward")} | Cycle configured model roles |`,
|
|
74
|
+
`| ${displayAppKey("app.model.cycleBackward")} | Cycle configured model roles temporarily |`,
|
|
75
|
+
`| ${displayAppKey("app.model.selectTemporary")} | Select model (temporary) |`,
|
|
76
|
+
`| ${displayAppKey("app.model.select")} | Select default model |`,
|
|
77
|
+
`| ${displayAppKey("app.plan.toggle")} | Toggle plan mode |`,
|
|
78
|
+
`| ${displayAppKey("app.history.search")} | Search prompt history |`,
|
|
79
|
+
`| ${displayAppKey("app.tools.expand")} | Toggle tool output expansion |`,
|
|
80
|
+
`| ${displayAppKey("app.tool.backgroundFold")} twice | Fold supported foreground bash into a background job |`,
|
|
81
|
+
`| ${displayAppKey("app.thinking.toggle")} | Toggle thinking block visibility |`,
|
|
82
|
+
`| ${displayAppKey("app.editor.external")} | Edit message in external editor |`,
|
|
83
|
+
`| ${displayAppKey("app.clipboard.pasteImage")} | Paste image from clipboard |`,
|
|
84
|
+
`| ${displayAppKey("app.stt.toggle")} | Toggle speech-to-text recording |`,
|
|
85
|
+
`| ${displayAppKey("app.irc.sidebar.toggle")} | Toggle IRC sidebar |`,
|
|
58
86
|
"| `?` | Show help / shortcuts |",
|
|
59
87
|
"| `#` | Prompt actions (command-palette style actions) |",
|
|
60
88
|
"| `/` | Slash commands (try `/help` or `/new`) |",
|