@sayknow-cli/coding-agent 0.4.6 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +112 -0
- package/dist/types/capability/index.d.ts +10 -20
- package/dist/types/capability/types.d.ts +3 -0
- package/dist/types/cli/args.d.ts +0 -2
- package/dist/types/cli/read-cli.d.ts +1 -0
- package/dist/types/cli.d.ts +9 -1
- package/dist/types/commands/daemon.d.ts +2 -2
- package/dist/types/commands/deep-interview.d.ts +9 -0
- package/dist/types/commands/harness.d.ts +22 -0
- package/dist/types/commands/read.d.ts +6 -0
- package/dist/types/commands/sdk.d.ts +20 -2
- package/dist/types/config/keybindings.d.ts +34 -4
- package/dist/types/config/model-profile-contract.d.ts +40 -0
- package/dist/types/config/model-profiles.d.ts +2 -3
- package/dist/types/config/model-registry.d.ts +5 -0
- package/dist/types/config/provider-auth-health.d.ts +14 -0
- package/dist/types/config/provider-ranking.d.ts +59 -0
- package/dist/types/config/settings-schema.d.ts +156 -10
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/edit/modes/patch.d.ts +13 -0
- package/dist/types/edit/path-mutation-lock.d.ts +15 -0
- package/dist/types/eval/py/executor.d.ts +1 -1
- package/dist/types/eval/py/runner-artifact.d.ts +8 -0
- package/dist/types/eval/py/tool-bridge.d.ts +1 -2
- package/dist/types/extensibility/extensions/types.d.ts +43 -2
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
- package/dist/types/main.d.ts +33 -2
- package/dist/types/memories/index.d.ts +2 -0
- package/dist/types/modes/acp/acp-agent.d.ts +22 -9
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/btw-panel.d.ts +1 -0
- package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
- package/dist/types/modes/components/queue-pane.d.ts +8 -0
- package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
- package/dist/types/modes/components/read-tool-group.d.ts +4 -4
- package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +2 -1
- package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/tool-status-header.d.ts +4 -2
- package/dist/types/modes/components/welcome.d.ts +5 -0
- package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/event-controller.d.ts +3 -0
- package/dist/types/modes/interactive-mode.d.ts +13 -2
- package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
- package/dist/types/modes/prompt-action-autocomplete.d.ts +6 -1
- package/dist/types/modes/prompt-suggestion-controller.d.ts +35 -0
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -2
- package/dist/types/modes/types.d.ts +6 -0
- package/dist/types/modes/utils/hotkeys-markdown.d.ts +2 -1
- package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
- package/dist/types/runtime/memory-domain.d.ts +9 -0
- package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
- package/dist/types/runtime/memory-guard.d.ts +39 -0
- package/dist/types/runtime/memory-limit.d.ts +11 -0
- package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
- package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +1 -1
- package/dist/types/runtime-mcp/manager.d.ts +9 -1
- package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -5
- package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +14 -0
- package/dist/types/runtime-mcp/redaction.d.ts +2 -0
- package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
- package/dist/types/sdk/acp/final-text.d.ts +19 -0
- package/dist/types/sdk/acp/mcp.d.ts +23 -0
- package/dist/types/sdk/broker/broker.d.ts +2 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +13 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +9 -1
- package/dist/types/sdk/bus/config-commands.d.ts +2 -2
- package/dist/types/sdk/bus/config.d.ts +2 -0
- package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +1 -0
- package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +52 -4
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
- package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
- package/dist/types/sdk/bus/notification-orchestration.d.ts +1 -0
- package/dist/types/sdk/bus/notification-service.d.ts +34 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +106 -0
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +33 -9
- package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +286 -12
- package/dist/types/sdk/bus/telegram-reference.d.ts +2 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
- package/dist/types/sdk/client/discovery.d.ts +2 -0
- package/dist/types/sdk/client/liveness.d.ts +7 -0
- package/dist/types/sdk/host/control/operations.d.ts +3 -2
- package/dist/types/sdk/host/host.d.ts +3 -1
- package/dist/types/sdk/host/query/handlers.d.ts +14 -0
- package/dist/types/sdk/index.d.ts +2 -0
- package/dist/types/sdk/lifecycle-session.d.ts +10 -1
- package/dist/types/sdk/prompt-status.d.ts +88 -0
- package/dist/types/sdk/session-directory.d.ts +1 -1
- package/dist/types/sdk/session.d.ts +7 -0
- package/dist/types/sdk/startup-capability.d.ts +9 -0
- package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
- package/dist/types/sdk/transport/index.d.ts +12 -0
- package/dist/types/sdk/transport/relay.d.ts +43 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
- package/dist/types/sdk/transport/socket.d.ts +7 -0
- package/dist/types/sdk/transport/stdio.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +83 -24
- package/dist/types/session/btw-contract.d.ts +16 -0
- package/dist/types/session/fallback-chain-controller.d.ts +18 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +70 -10
- package/dist/types/session/internal/managed-session-storage.d.ts +34 -12
- package/dist/types/session/internal/native-publish-outcome.d.ts +48 -0
- package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
- package/dist/types/session/session-manager.d.ts +89 -18
- package/dist/types/session/session-storage.d.ts +31 -0
- package/dist/types/session/streaming-output.d.ts +60 -5
- package/dist/types/setup/credential-import.d.ts +5 -1
- package/dist/types/setup/provider-onboarding.d.ts +2 -0
- package/dist/types/skc-runtime/deep-interview-runtime.d.ts +1 -1
- package/dist/types/skc-runtime/deep-interview-stage.d.ts +37 -0
- package/dist/types/skc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/skc-runtime/linux-proc.d.ts +22 -14
- package/dist/types/skc-runtime/memory-guard-owner-claims.d.ts +47 -0
- package/dist/types/skc-runtime/ralplan-runtime.d.ts +112 -1
- package/dist/types/skc-runtime/repository-binding.d.ts +63 -0
- package/dist/types/skc-runtime/state-runtime.d.ts +3 -1
- package/dist/types/skc-runtime/state-writer.d.ts +5 -1
- package/dist/types/skc-runtime/team-launch.d.ts +1 -1
- package/dist/types/skc-runtime/team-runtime.d.ts +9 -2
- package/dist/types/skc-runtime/team-store.d.ts +12 -0
- package/dist/types/skc-runtime/team-worker-memory-guard.d.ts +92 -0
- package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +7 -0
- package/dist/types/skc-runtime/ultragoal-guard.d.ts +6 -5
- package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +28 -0
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +43 -5
- package/dist/types/skill-state/workflow-hud.d.ts +3 -0
- package/dist/types/ssh/utils.d.ts +1 -0
- package/dist/types/task/discovery.d.ts +3 -1
- package/dist/types/task/executor.d.ts +6 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/task/provider-retry-status.d.ts +13 -0
- package/dist/types/task/receipt.d.ts +2 -0
- package/dist/types/task/types.d.ts +133 -0
- package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
- package/dist/types/tools/browser/launch.d.ts +7 -0
- package/dist/types/tools/fetch.d.ts +22 -9
- package/dist/types/tools/image-gen.d.ts +63 -1
- package/dist/types/tools/index.d.ts +7 -1
- package/dist/types/tools/output-meta.d.ts +21 -1
- package/dist/types/tools/read-internals.d.ts +12 -0
- package/dist/types/tools/read.d.ts +45 -1
- package/dist/types/tools/resource-gc.d.ts +23 -0
- package/dist/types/tools/skill-discovery.d.ts +7 -0
- package/dist/types/tools/sqlite-reader.d.ts +7 -0
- package/dist/types/tools/tool-result.d.ts +7 -1
- package/dist/types/utils/prompt-suggestion.d.ts +33 -0
- package/dist/types/utils/shell-snapshot.d.ts +12 -0
- package/dist/types/web/insane/bridge.d.ts +1 -0
- package/dist/types/web/insane/url-guard.d.ts +17 -0
- package/package.json +8 -12
- package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
- package/scripts/capture-platform-shortcut-labels-showcase.ts +342 -0
- package/scripts/capture-sticky-viewport-showcase.ts +292 -0
- package/scripts/compile-args.ts +0 -1
- package/scripts/dogfood-repository-binding.ts +209 -0
- package/scripts/generate-docs-index.ts +4 -1
- package/scripts/generate-sdk-operation-inventory.ts +9 -0
- package/scripts/run-test-manifest.ts +6 -4
- package/scripts/verify-skc-sdk-canonicalization.ts +122 -18
- package/scripts/verify-sticky-viewport-showcase.ts +611 -0
- package/src/capability/index.ts +58 -42
- package/src/capability/types.ts +3 -0
- package/src/cli/args.ts +16 -100
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/mcp-cli.ts +4 -21
- package/src/cli/notify-cli.ts +6 -38
- package/src/cli/read-cli.ts +2 -1
- package/src/cli/setup-cli.ts +10 -4
- package/src/cli.ts +133 -11
- package/src/commands/daemon.ts +22 -5
- package/src/commands/deep-interview.ts +26 -1
- package/src/commands/harness.ts +35 -12
- package/src/commands/read.ts +11 -2
- package/src/commands/sdk.ts +134 -17
- package/src/commands/team.ts +1 -1
- package/src/commit/agentic/index.ts +3 -3
- package/src/commit/map-reduce/index.ts +2 -2
- package/src/config/keybindings.ts +158 -25
- package/src/config/model-profile-contract.ts +174 -0
- package/src/config/model-profiles.ts +51 -10
- package/src/config/model-registry.ts +24 -4
- package/src/config/model-resolver.ts +2 -2
- package/src/config/provider-auth-health.ts +42 -0
- package/src/config/provider-ranking.ts +119 -0
- package/src/config/settings-schema.ts +157 -10
- package/src/config/settings.ts +254 -108
- package/src/coordinator-mcp/model-preset.ts +21 -74
- package/src/defaults/skc/skills/deep-interview/SKILL.md +147 -24
- package/src/defaults/skc/skills/ralplan/SKILL.md +91 -34
- package/src/defaults/skc/skills/team/SKILL.md +1 -1
- package/src/defaults/skc/skills/ultragoal/SKILL.md +68 -17
- package/src/discovery/ssh.ts +12 -1
- package/src/edit/index.ts +3 -6
- package/src/edit/modes/patch.ts +38 -1
- package/src/edit/modes/replace.ts +42 -0
- package/src/edit/path-mutation-lock.ts +112 -0
- package/src/eval/js/tool-bridge.ts +1 -1
- package/src/eval/py/executor.ts +37 -13
- package/src/eval/py/kernel.ts +1 -21
- package/src/eval/py/prelude.py +2 -2
- package/src/eval/py/runner-artifact.ts +84 -0
- package/src/eval/py/tool-bridge.ts +34 -18
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +42 -4
- package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
- package/src/extensibility/shared-events.ts +5 -0
- package/src/extensibility/skc-plugins/runtime-adapters.ts +2 -1
- package/src/hooks/native-skill-hook.ts +17 -4
- package/src/internal-urls/docs-index.generated.ts +17 -16
- package/src/internal-urls/local-protocol.ts +87 -25
- package/src/internal-urls/local-root-gc.ts +127 -0
- package/src/internal-urls/mcp-protocol.ts +73 -11
- package/src/main.ts +120 -42
- package/src/memories/index.ts +10 -0
- package/src/modes/DESIGN.md +52 -0
- package/src/modes/acp/acp-agent.ts +647 -83
- package/src/modes/acp/acp-event-mapper.ts +106 -12
- package/src/modes/acp/acp-mode.ts +39 -3
- package/src/modes/action-registry.ts +1 -1
- package/src/modes/components/assistant-message.ts +123 -22
- package/src/modes/components/btw-panel.ts +82 -16
- package/src/modes/components/irc-sidebar.ts +176 -62
- package/src/modes/components/model-selector.ts +61 -4
- package/src/modes/components/notifications-settings-editor.ts +1 -1
- package/src/modes/components/oauth-selector.ts +42 -12
- package/src/modes/components/plan-preview-overlay.ts +1 -1
- package/src/modes/components/queue-pane.ts +55 -9
- package/src/modes/components/queued-message-selector.ts +53 -10
- package/src/modes/components/read-tool-group.ts +82 -14
- package/src/modes/components/runtime-mcp-add-wizard.ts +5 -0
- package/src/modes/components/sayknow-pet-widget.ts +27 -8
- package/src/modes/components/session-observer-overlay.ts +187 -32
- package/src/modes/components/settings-selector.ts +60 -18
- package/src/modes/components/tool-execution.ts +138 -27
- package/src/modes/components/tool-status-header.ts +26 -8
- package/src/modes/components/welcome.ts +50 -23
- package/src/modes/controllers/btw-controller.ts +119 -36
- package/src/modes/controllers/command-controller.ts +101 -54
- package/src/modes/controllers/event-controller.ts +119 -27
- package/src/modes/controllers/extension-ui-controller.ts +23 -12
- package/src/modes/controllers/input-controller.ts +100 -8
- package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -6
- package/src/modes/controllers/selector-controller.ts +4 -1
- package/src/modes/interactive-mode.ts +201 -60
- package/src/modes/irc-observation-ledger.ts +71 -15
- package/src/modes/prompt-action-autocomplete.ts +32 -13
- package/src/modes/prompt-suggestion-controller.ts +96 -0
- package/src/modes/runtime-init.ts +20 -2
- package/src/modes/shared/agent-wire/command-dispatch.ts +3 -3
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -2
- package/src/modes/types.ts +6 -0
- package/src/modes/utils/hotkeys-markdown.ts +64 -36
- package/src/modes/utils/ui-helpers.ts +99 -4
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/architect.md +17 -3
- package/src/prompts/agents/critic.md +17 -2
- package/src/prompts/agents/executor.md +1 -1
- package/src/prompts/agents/planner.md +8 -1
- package/src/prompts/system/btw-user.md +3 -8
- package/src/prompts/system/prompt-suggestion-system.md +32 -0
- package/src/prompts/system/system-prompt.md +6 -3
- package/src/prompts/tools/cron.md +3 -1
- package/src/prompts/tools/read.md +4 -2
- package/src/prompts/tools/skill-discovery.md +1 -0
- package/src/runtime/memory-domain.ts +66 -0
- package/src/runtime/memory-guard-contract.ts +73 -0
- package/src/runtime/memory-guard.ts +292 -0
- package/src/runtime/memory-limit.ts +50 -0
- package/src/runtime-mcp/client.ts +41 -55
- package/src/runtime-mcp/content-limits.ts +71 -0
- package/src/runtime-mcp/discoverable-tool-metadata.ts +1 -1
- package/src/runtime-mcp/json-rpc.ts +28 -11
- package/src/runtime-mcp/manager.ts +77 -59
- package/src/runtime-mcp/oauth-flow.ts +0 -72
- package/src/runtime-mcp/plugin-network-boundary.ts +101 -0
- package/src/runtime-mcp/redaction.ts +30 -0
- package/src/runtime-mcp/smithery-auth.ts +17 -2
- package/src/runtime-mcp/smithery-connect.ts +11 -1
- package/src/runtime-mcp/transports/http.ts +63 -22
- package/src/sdk/acp/adapter.ts +8 -1
- package/src/sdk/acp/final-text.ts +40 -0
- package/src/sdk/acp/mcp.ts +26 -0
- package/src/sdk/broker/broker.ts +34 -20
- package/src/sdk/broker/identity.ts +22 -12
- package/src/sdk/broker/lifecycle.ts +293 -43
- package/src/sdk/broker/session-index.ts +11 -1
- package/src/sdk/bus/chat-daemon-cli.ts +2 -2
- package/src/sdk/bus/chat-daemon-control.ts +22 -5
- package/src/sdk/bus/config-commands.ts +2 -2
- package/src/sdk/bus/config.ts +10 -2
- package/src/sdk/bus/control-drain-lease.ts +104 -0
- package/src/sdk/bus/conversation-store.ts +40 -6
- package/src/sdk/bus/daemon-paths.ts +2 -0
- package/src/sdk/bus/index.ts +793 -121
- package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
- package/src/sdk/bus/lifecycle-commands.ts +63 -10
- package/src/sdk/bus/lifecycle-control-runtime.ts +11 -2
- package/src/sdk/bus/lifecycle-orchestrator.ts +32 -1
- package/src/sdk/bus/notification-orchestration.ts +12 -0
- package/src/sdk/bus/notification-service.ts +87 -25
- package/src/sdk/bus/operator-runtime.ts +31 -5
- package/src/sdk/bus/prompt-reconciliation.ts +240 -0
- package/src/sdk/bus/rate-limit-pool.ts +8 -0
- package/src/sdk/bus/recent-activity.ts +90 -26
- package/src/sdk/bus/reconciliation-store.ts +224 -0
- package/src/sdk/bus/telegram-cli.ts +6 -13
- package/src/sdk/bus/telegram-daemon-cli.ts +8 -3
- package/src/sdk/bus/telegram-daemon-contract.ts +34 -9
- package/src/sdk/bus/telegram-daemon-control.ts +161 -40
- package/src/sdk/bus/telegram-daemon.ts +3649 -593
- package/src/sdk/bus/telegram-reference.ts +20 -2
- package/src/sdk/bus/topic-registry.ts +451 -12
- package/src/sdk/cli/session-cli.ts +15 -2
- package/src/sdk/client/discovery.ts +19 -3
- package/src/sdk/client/liveness.ts +49 -0
- package/src/sdk/host/control/dispatch.ts +8 -2
- package/src/sdk/host/control/operations.ts +3 -2
- package/src/sdk/host/host.ts +27 -9
- package/src/sdk/host/query/handlers.ts +125 -5
- package/src/sdk/index.ts +12 -0
- package/src/sdk/lifecycle-session.ts +19 -3
- package/src/sdk/mcp/server.ts +46 -18
- package/src/sdk/prompt-status.ts +97 -0
- package/src/sdk/protocol/operation-inventory.generated.json +145 -0
- package/src/sdk/protocol/operation-registry.ts +24 -4
- package/src/sdk/session-directory.ts +5 -1
- package/src/sdk/session.ts +69 -8
- package/src/sdk/startup-capability.ts +15 -1
- package/src/sdk/transport/auth-preface.ts +82 -0
- package/src/sdk/transport/index.ts +18 -0
- package/src/sdk/transport/relay.ts +252 -0
- package/src/sdk/transport/serve-cli.ts +105 -0
- package/src/sdk/transport/socket.ts +197 -0
- package/src/sdk/transport/stdio.ts +17 -0
- package/src/session/agent-session.ts +1112 -314
- package/src/session/blob-store.ts +25 -7
- package/src/session/btw-contract.ts +59 -0
- package/src/session/fallback-chain-controller.ts +47 -8
- package/src/session/internal/managed-session-scope.ts +1426 -259
- package/src/session/internal/managed-session-storage.ts +414 -238
- package/src/session/internal/native-publish-outcome.ts +271 -0
- package/src/session/memory-guard-checkpoint-participant.ts +131 -0
- package/src/session/session-manager.ts +2079 -469
- package/src/session/session-storage.ts +151 -11
- package/src/session/streaming-output.ts +262 -43
- package/src/setup/credential-import.ts +28 -3
- package/src/setup/provider-onboarding.ts +49 -5
- package/src/setup/provider-presets.json +2 -1
- package/src/skc-runtime/deep-interview-runtime.ts +303 -36
- package/src/skc-runtime/deep-interview-stage.ts +1016 -0
- package/src/skc-runtime/deep-interview-state.ts +8 -5
- package/src/skc-runtime/gc-render.ts +1 -0
- package/src/skc-runtime/gc-runtime.ts +11 -1
- package/src/skc-runtime/linux-proc.ts +70 -36
- package/src/skc-runtime/managed-owner-supervisor.ts +83 -4
- package/src/skc-runtime/memory-guard-owner-claims.ts +389 -0
- package/src/skc-runtime/ralplan-runtime.ts +1057 -75
- package/src/skc-runtime/repository-binding.ts +267 -0
- package/src/skc-runtime/session-state-sidecar.ts +25 -9
- package/src/skc-runtime/state-runtime.ts +50 -12
- package/src/skc-runtime/state-writer.ts +68 -56
- package/src/skc-runtime/team-launch.ts +34 -5
- package/src/skc-runtime/team-runtime.ts +41 -1
- package/src/skc-runtime/team-store.ts +32 -0
- package/src/skc-runtime/team-worker-memory-guard.ts +363 -0
- package/src/skc-runtime/team-workers.ts +1 -0
- package/src/skc-runtime/tmux-common.ts +13 -2
- package/src/skc-runtime/tmux-owner-isolation.ts +20 -1
- package/src/skc-runtime/tmux-sessions.ts +45 -6
- package/src/skc-runtime/ultragoal-guard.ts +93 -15
- package/src/skc-runtime/ultragoal-receipt-freshness.ts +123 -0
- package/src/skc-runtime/ultragoal-runtime.ts +469 -38
- package/src/skc-runtime/workflow-manifest.generated.json +195 -5
- package/src/skc-runtime/workflow-manifest.ts +67 -3
- package/src/skill-state/workflow-hud.ts +25 -2
- package/src/skill-state/workflow-mutation-guard.ts +104 -12
- package/src/slash-commands/builtin-registry.ts +1 -1
- package/src/ssh/utils.ts +14 -0
- package/src/task/discovery.ts +8 -2
- package/src/task/executor.ts +165 -47
- package/src/task/index.ts +123 -15
- package/src/task/provider-retry-status.ts +88 -0
- package/src/task/receipt.ts +3 -0
- package/src/task/render.ts +45 -26
- package/src/task/skc-command.ts +2 -2
- package/src/task/types.ts +55 -10
- package/src/task/ultragoal-redteam-activation.ts +75 -0
- package/src/tools/ask.ts +1 -1
- package/src/tools/ast-edit.ts +2 -2
- package/src/tools/bash-allowed-prefixes.ts +45 -1
- package/src/tools/bash-pty-selection.ts +2 -2
- package/src/tools/browser/launch.ts +41 -6
- package/src/tools/browser/screenshot-format.ts +6 -1
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +127 -154
- package/src/tools/image-gen.ts +476 -23
- package/src/tools/index.ts +7 -1
- package/src/tools/output-meta.ts +176 -9
- package/src/tools/path-utils.ts +5 -1
- package/src/tools/read-internals.ts +44 -0
- package/src/tools/read.ts +1544 -310
- package/src/tools/resource-gc.ts +665 -125
- package/src/tools/skill-discovery.ts +39 -3
- package/src/tools/sqlite-reader.ts +63 -5
- package/src/tools/subagent-render.ts +74 -16
- package/src/tools/subagent.ts +2 -0
- package/src/tools/tool-result.ts +14 -1
- package/src/utils/edit-mode.ts +2 -2
- package/src/utils/pasted-image-path.ts +15 -6
- package/src/utils/prompt-suggestion.ts +265 -0
- package/src/utils/shell-snapshot.ts +173 -63
- package/src/utils/sixel.ts +3 -3
- package/src/web/insane/bridge.ts +5 -1
- package/src/web/insane/url-guard.ts +140 -27
- package/src/web/scrapers/docs-rs.ts +30 -5
- package/src/web/scrapers/types.ts +19 -49
- package/src/web/scrapers/utils.ts +12 -26
- package/src/web/search/providers/codex.ts +1 -1
- package/src/workflow/workflow-intent-diff.ts +4 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Product-surface dogfood for #2901 repository binding.
|
|
3
|
+
*
|
|
4
|
+
* Creates two sibling git repos, runs real `skc ultragoal` / `skc ralplan`
|
|
5
|
+
* CLI entrypoints from source, and prints fail-closed mismatch evidence.
|
|
6
|
+
*
|
|
7
|
+
* Usage (from monorepo root):
|
|
8
|
+
* bun packages/coding-agent/scripts/dogfood-repository-binding.ts
|
|
9
|
+
*/
|
|
10
|
+
import * as fsp from "node:fs/promises";
|
|
11
|
+
import * as os from "node:os";
|
|
12
|
+
import * as path from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import {
|
|
15
|
+
assertCwdMatchesRepositoryBinding,
|
|
16
|
+
assertPathUnderRepositoryBinding,
|
|
17
|
+
parseRepositoryBinding,
|
|
18
|
+
resolveTaskRepositoryBinding,
|
|
19
|
+
} from "../src/skc-runtime/repository-binding";
|
|
20
|
+
import { readUltragoalPlan, startNextUltragoalGoal } from "../src/skc-runtime/ultragoal-runtime";
|
|
21
|
+
|
|
22
|
+
const repoRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "../../..");
|
|
23
|
+
const cli = path.join(repoRoot, "packages/coding-agent/src/cli.ts");
|
|
24
|
+
|
|
25
|
+
async function runGit(cwd: string, args: string[]): Promise<void> {
|
|
26
|
+
const proc = Bun.spawn(["git", ...args], { cwd, stdout: "pipe", stderr: "pipe" });
|
|
27
|
+
const code = await proc.exited;
|
|
28
|
+
if (code !== 0) throw new Error(`git ${args.join(" ")} failed: ${await new Response(proc.stderr).text()}`);
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
async function initRepo(root: string): Promise<void> {
|
|
32
|
+
await fsp.mkdir(root, { recursive: true });
|
|
33
|
+
await runGit(root, ["init"]);
|
|
34
|
+
await runGit(root, ["config", "user.email", "dogfood@example.com"]);
|
|
35
|
+
await runGit(root, ["config", "user.name", "Dogfood"]);
|
|
36
|
+
await fsp.writeFile(path.join(root, "README.md"), `repo ${path.basename(root)}\n`);
|
|
37
|
+
await runGit(root, ["add", "README.md"]);
|
|
38
|
+
await runGit(root, ["commit", "-m", `init ${path.basename(root)}`]);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
async function runCli(
|
|
42
|
+
cwd: string,
|
|
43
|
+
args: string[],
|
|
44
|
+
env: NodeJS.ProcessEnv,
|
|
45
|
+
): Promise<{ code: number; stdout: string; stderr: string }> {
|
|
46
|
+
const proc = Bun.spawn(["bun", cli, ...args], { cwd, env, stdout: "pipe", stderr: "pipe" });
|
|
47
|
+
const [code, stdout, stderr] = await Promise.all([
|
|
48
|
+
proc.exited,
|
|
49
|
+
new Response(proc.stdout).text(),
|
|
50
|
+
new Response(proc.stderr).text(),
|
|
51
|
+
]);
|
|
52
|
+
return { code, stdout, stderr };
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
async function main(): Promise<void> {
|
|
56
|
+
const dogfoodRoot = await fsp.mkdtemp(path.join(os.tmpdir(), "skc-dogfood-2901-"));
|
|
57
|
+
const left = path.join(dogfoodRoot, "sayknow-cli");
|
|
58
|
+
const right = path.join(dogfoodRoot, "oh-my-openagent-senpi");
|
|
59
|
+
await initRepo(left);
|
|
60
|
+
await initRepo(right);
|
|
61
|
+
|
|
62
|
+
const sessionId = `dogfood-2901-${process.pid}`;
|
|
63
|
+
const env = { ...process.env, SKC_SESSION_ID: sessionId };
|
|
64
|
+
|
|
65
|
+
console.log("# Dogfood: repository binding (#2901)");
|
|
66
|
+
console.log(`root=${dogfoodRoot}`);
|
|
67
|
+
console.log(`left=${left}`);
|
|
68
|
+
console.log(`right=${right}`);
|
|
69
|
+
console.log(`session=${sessionId}`);
|
|
70
|
+
console.log(`cli=${cli}`);
|
|
71
|
+
console.log(`bun=${Bun.version}`);
|
|
72
|
+
console.log(
|
|
73
|
+
`commit=${Bun.spawnSync(["git", "-C", repoRoot, "rev-parse", "--short", "HEAD"]).stdout.toString().trim()}`,
|
|
74
|
+
);
|
|
75
|
+
console.log();
|
|
76
|
+
|
|
77
|
+
// 1) Product CLI: create goals stamps binding
|
|
78
|
+
const create = await runCli(
|
|
79
|
+
left,
|
|
80
|
+
[
|
|
81
|
+
"ultragoal",
|
|
82
|
+
"create-goals",
|
|
83
|
+
"--brief",
|
|
84
|
+
"@goal dogfood binding\nProve repository binding stamps and fail-closed sibling mismatch.",
|
|
85
|
+
"--json",
|
|
86
|
+
],
|
|
87
|
+
env,
|
|
88
|
+
);
|
|
89
|
+
console.log("## 1) skc ultragoal create-goals (LEFT)");
|
|
90
|
+
console.log(`exit=${create.code}`);
|
|
91
|
+
console.log(create.stdout.trim() || create.stderr.trim());
|
|
92
|
+
if (create.code !== 0) process.exit(1);
|
|
93
|
+
|
|
94
|
+
const plan = await readUltragoalPlan(left, sessionId);
|
|
95
|
+
if (!plan?.repositoryBinding) {
|
|
96
|
+
console.error("FAIL: plan missing repositoryBinding");
|
|
97
|
+
process.exit(1);
|
|
98
|
+
}
|
|
99
|
+
console.log();
|
|
100
|
+
console.log("## 2) goals.json repositoryBinding");
|
|
101
|
+
console.log(JSON.stringify(plan.repositoryBinding, null, 2));
|
|
102
|
+
|
|
103
|
+
// 2) Matching cwd starts goal
|
|
104
|
+
console.log();
|
|
105
|
+
console.log("## 3) startNextUltragoalGoal on LEFT (match)");
|
|
106
|
+
const started = await startNextUltragoalGoal({ cwd: left, sessionId });
|
|
107
|
+
console.log(`ok goal=${started.goal?.id} status=${started.goal?.status}`);
|
|
108
|
+
|
|
109
|
+
// 3) Sibling mismatch fails closed
|
|
110
|
+
console.log();
|
|
111
|
+
console.log("## 4) assertCwdMatchesRepositoryBinding on RIGHT (sibling)");
|
|
112
|
+
try {
|
|
113
|
+
await assertCwdMatchesRepositoryBinding(right, plan.repositoryBinding);
|
|
114
|
+
console.error("FAIL: expected identity_mismatch");
|
|
115
|
+
process.exit(1);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
console.log(`fail_closed: ${error instanceof Error ? error.message : String(error)}`);
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
// 4) Path escape fails closed
|
|
121
|
+
console.log();
|
|
122
|
+
console.log("## 5) assertPathUnderRepositoryBinding sibling absolute path");
|
|
123
|
+
try {
|
|
124
|
+
assertPathUnderRepositoryBinding(plan.repositoryBinding, path.join(right, "README.md"));
|
|
125
|
+
console.error("FAIL: expected path_outside_root");
|
|
126
|
+
process.exit(1);
|
|
127
|
+
} catch (error) {
|
|
128
|
+
console.log(`fail_closed: ${error instanceof Error ? error.message : String(error)}`);
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
// 5) Task binding stamp + sibling fail-closed (pre-discovery authority)
|
|
132
|
+
console.log();
|
|
133
|
+
console.log("## 6) task binding stamp (omit declaration) + sibling reject");
|
|
134
|
+
const stamped = await resolveTaskRepositoryBinding(left, undefined);
|
|
135
|
+
console.log(`stamped_worktreeRoot=${stamped.worktreeRoot}`);
|
|
136
|
+
await assertCwdMatchesRepositoryBinding(left, stamped);
|
|
137
|
+
console.log("task_stamp_ok on LEFT");
|
|
138
|
+
const taskBinding = parseRepositoryBinding(plan.repositoryBinding);
|
|
139
|
+
try {
|
|
140
|
+
await resolveTaskRepositoryBinding(right, taskBinding);
|
|
141
|
+
console.error("FAIL: task binding should reject RIGHT");
|
|
142
|
+
process.exit(1);
|
|
143
|
+
} catch (error) {
|
|
144
|
+
console.log(`task_binding_fail_closed on RIGHT: ${error instanceof Error ? error.message : String(error)}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// 6) Ralplan seed stamps binding via product CLI
|
|
148
|
+
console.log();
|
|
149
|
+
console.log("## 7) skc ralplan seed (LEFT)");
|
|
150
|
+
const ralplan = await runCli(left, ["ralplan", "--json", "dogfood multi-repo binding"], env);
|
|
151
|
+
console.log(`exit=${ralplan.code}`);
|
|
152
|
+
console.log(ralplan.stdout.trim() || ralplan.stderr.trim());
|
|
153
|
+
if (ralplan.code !== 0) process.exit(1);
|
|
154
|
+
const statePath = path.join(left, ".skc", `_session-${sessionId}`, "state", "ralplan-state.json");
|
|
155
|
+
const state = JSON.parse(await fsp.readFile(statePath, "utf8")) as {
|
|
156
|
+
repository_binding?: unknown;
|
|
157
|
+
run_id?: string;
|
|
158
|
+
};
|
|
159
|
+
console.log();
|
|
160
|
+
console.log("## 8) ralplan-state.json repository_binding");
|
|
161
|
+
console.log(JSON.stringify({ run_id: state.run_id, repository_binding: state.repository_binding }, null, 2));
|
|
162
|
+
if (!state.repository_binding) {
|
|
163
|
+
console.error("FAIL: ralplan state missing repository_binding");
|
|
164
|
+
process.exit(1);
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
// 7) Ralplan stage write on LEFT succeeds and echoes repository_binding
|
|
168
|
+
console.log();
|
|
169
|
+
console.log("## 9) skc ralplan --write planner on LEFT (match)");
|
|
170
|
+
const notePath = path.join(left, "dogfood-planner.md");
|
|
171
|
+
await fsp.writeFile(notePath, "# dogfood planner\n");
|
|
172
|
+
const writeLeft = await runCli(
|
|
173
|
+
left,
|
|
174
|
+
["ralplan", "--write", "--stage", "planner", "--stage_n", "1", "--artifact", notePath, "--json"],
|
|
175
|
+
env,
|
|
176
|
+
);
|
|
177
|
+
console.log(`exit=${writeLeft.code}`);
|
|
178
|
+
console.log(writeLeft.stdout.trim() || writeLeft.stderr.trim());
|
|
179
|
+
if (writeLeft.code !== 0) process.exit(1);
|
|
180
|
+
const writePayload = JSON.parse(writeLeft.stdout) as { repository_binding?: { worktreeRoot?: string } };
|
|
181
|
+
if (!writePayload.repository_binding?.worktreeRoot) {
|
|
182
|
+
console.error("FAIL: write receipt missing repository_binding");
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// 8) Copy seed authority into RIGHT session layout → stage write fails closed
|
|
187
|
+
console.log();
|
|
188
|
+
console.log("## 10) ralplan --write on RIGHT with LEFT binding (fail-closed)");
|
|
189
|
+
const rightStateDir = path.join(right, ".skc", `_session-${sessionId}`, "state");
|
|
190
|
+
await fsp.mkdir(rightStateDir, { recursive: true });
|
|
191
|
+
await fsp.copyFile(statePath, path.join(rightStateDir, "ralplan-state.json"));
|
|
192
|
+
const writeRight = await runCli(
|
|
193
|
+
right,
|
|
194
|
+
["ralplan", "--write", "--stage", "architect", "--stage_n", "1", "--artifact", "# arch\n", "--json"],
|
|
195
|
+
env,
|
|
196
|
+
);
|
|
197
|
+
console.log(`exit=${writeRight.code}`);
|
|
198
|
+
console.log((writeRight.stderr || writeRight.stdout).trim());
|
|
199
|
+
if (writeRight.code === 0) {
|
|
200
|
+
console.error("FAIL: expected sibling write to fail closed");
|
|
201
|
+
process.exit(1);
|
|
202
|
+
}
|
|
203
|
+
console.log("fail_closed: ralplan write on sibling rejected");
|
|
204
|
+
|
|
205
|
+
console.log();
|
|
206
|
+
console.log("DOGFOOD_OK");
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
await main();
|
|
@@ -3,6 +3,7 @@
|
|
|
3
3
|
import * as fs from "node:fs/promises";
|
|
4
4
|
import * as path from "node:path";
|
|
5
5
|
import { Glob } from "bun";
|
|
6
|
+
import { isEmbeddableDoc } from "../../../scripts/docs-index-contract";
|
|
6
7
|
|
|
7
8
|
async function pathExists(candidate: string): Promise<boolean> {
|
|
8
9
|
try {
|
|
@@ -40,7 +41,9 @@ if (docsDir === undefined) {
|
|
|
40
41
|
const glob = new Glob("**/*.md");
|
|
41
42
|
const entries: string[] = [];
|
|
42
43
|
for await (const relativePath of glob.scan(docsDir)) {
|
|
43
|
-
|
|
44
|
+
const rel = relativePath.split(path.sep).join("/");
|
|
45
|
+
if (!isEmbeddableDoc(rel)) continue;
|
|
46
|
+
entries.push(rel);
|
|
44
47
|
}
|
|
45
48
|
entries.sort();
|
|
46
49
|
|
|
@@ -39,6 +39,8 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
39
39
|
"agent_session:setForcedToolChoice": "internal accessor/plumbing, not a user-facing control seam",
|
|
40
40
|
"agent_session:getActiveSkillState": "internal accessor/plumbing, not a user-facing control seam",
|
|
41
41
|
"agent_session:getActiveSkillPhase": "internal accessor/plumbing, not a user-facing control seam",
|
|
42
|
+
"agent_session:getDeepInterviewAskStage":
|
|
43
|
+
"internal AskTool schema-selection accessor, not a user-facing SDK control seam",
|
|
42
44
|
"agent_session:peekQueueInvoker": "internal accessor/plumbing, not a user-facing control seam",
|
|
43
45
|
"agent_session:peekStandingResolveHandler": "internal accessor/plumbing, not a user-facing control seam",
|
|
44
46
|
"agent_session:setStandingResolveHandler": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -68,6 +70,7 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
68
70
|
"agent_session:getAsyncDeliveryStateForAcp":
|
|
69
71
|
"internal ACP lifecycle quiescence plumbing, not a user-facing control seam",
|
|
70
72
|
"agent_session:getToolByName": "internal accessor/plumbing, not a user-facing control seam",
|
|
73
|
+
"agent_session:getToolForExecution": "internal accessor/plumbing, not a user-facing control seam",
|
|
71
74
|
"agent_session:registerForegroundBashBackgroundRequestHandler":
|
|
72
75
|
"internal accessor/plumbing, not a user-facing control seam",
|
|
73
76
|
"agent_session:hasForegroundBashBackgroundRequestHandler":
|
|
@@ -83,6 +86,7 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
83
86
|
"agent_session:refreshMCPTools": "internal accessor/plumbing, not a user-facing control seam",
|
|
84
87
|
"agent_session:refreshSkcSubskillTools": "internal accessor/plumbing, not a user-facing control seam",
|
|
85
88
|
"agent_session:buildDisplaySessionContext": "internal accessor/plumbing, not a user-facing control seam",
|
|
89
|
+
"agent_session:buildPreparedDisplaySessionContext": "internal accessor/plumbing, not a user-facing control seam",
|
|
86
90
|
"agent_session:convertMessagesToLlm": "internal accessor/plumbing, not a user-facing control seam",
|
|
87
91
|
"agent_session:prepareSimpleStreamOptions": "internal accessor/plumbing, not a user-facing control seam",
|
|
88
92
|
"agent_session:getPlanModeState": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -115,6 +119,8 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
115
119
|
"agent_session:continuePersistedHistory": "internal startup lifecycle plumbing, not a user-facing control seam",
|
|
116
120
|
"agent_session:promoteRecoveryHydrationAfterOwnershipReadyFence":
|
|
117
121
|
"internal owner-recovery authority transition after a durable writer fence, never a user-facing SDK operation",
|
|
122
|
+
"agent_session:restoreFromMemoryGuardCheckpoint":
|
|
123
|
+
"internal owner-recovery staged restore builder after durable claims/fencing, never a user-facing SDK operation",
|
|
118
124
|
"agent_session:setActiveModelProfile": "internal accessor/plumbing, not a user-facing control seam",
|
|
119
125
|
"agent_session:getActiveModelProfile": "internal accessor/plumbing, not a user-facing control seam",
|
|
120
126
|
"agent_session:getSessionDefaultModelSelector": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -147,6 +153,8 @@ const LOCKED_EXCLUSIONS: Readonly<Record<string, string>> = {
|
|
|
147
153
|
"agent_session:prepareContributionPrep": "internal accessor/plumbing, not a user-facing control seam",
|
|
148
154
|
"agent_session:setResourceSampler": "internal accessor/plumbing, not a user-facing control seam",
|
|
149
155
|
"agent_session:setRetainedMemorySampler": "internal accessor/plumbing, not a user-facing control seam",
|
|
156
|
+
"agent_session:createBtwConversationScope":
|
|
157
|
+
"internal privacy-scoped side-chat snapshot factory, not a user-facing SDK control seam",
|
|
150
158
|
"agent_session:recordBashResult": "internal accessor/plumbing, not a user-facing control seam",
|
|
151
159
|
"agent_session:executePython": "internal accessor/plumbing, not a user-facing control seam",
|
|
152
160
|
"agent_session:assertEvalExecutionAllowed": "internal accessor/plumbing, not a user-facing control seam",
|
|
@@ -193,6 +201,7 @@ const SEAM_TO_SDK: Readonly<Record<string, string>> = {
|
|
|
193
201
|
"agent_session:setSessionName": "session.rename",
|
|
194
202
|
"agent_session:setModel": "model.set",
|
|
195
203
|
"agent_session:setDefaultModelSelection": "model.set",
|
|
204
|
+
"agent_session:activateModelProfileForControl": "model.profile.set",
|
|
196
205
|
"agent_session:cycleModel": "model.cycle",
|
|
197
206
|
"agent_session:setThinkingLevel": "thinking.set",
|
|
198
207
|
"agent_session:cycleThinkingLevel": "thinking.cycle",
|
|
@@ -36,6 +36,8 @@ try {
|
|
|
36
36
|
function validateRowReceipts(rows: ManifestAdapterRow[]): void {
|
|
37
37
|
const ids = new Set<string>();
|
|
38
38
|
const counts = new Map<string, number>();
|
|
39
|
+
// Each operation has one receipt, plus the dedicated config.patch secret-input receipt.
|
|
40
|
+
const expectedRowsPerAdapter = OPERATIONS.length + 1;
|
|
39
41
|
for (const row of rows) {
|
|
40
42
|
if (ids.has(row.adapterTestId)) throw new Error(`Duplicate adapter test ID: ${row.adapterTestId}`);
|
|
41
43
|
ids.add(row.adapterTestId);
|
|
@@ -60,11 +62,11 @@ function validateRowReceipts(rows: ManifestAdapterRow[]): void {
|
|
|
60
62
|
}
|
|
61
63
|
counts.set(row.adapter, (counts.get(row.adapter) ?? 0) + 1);
|
|
62
64
|
}
|
|
63
|
-
if (rows.length !== ADAPTERS.length *
|
|
64
|
-
throw new Error(`Expected ${ADAPTERS.length *
|
|
65
|
+
if (rows.length !== ADAPTERS.length * expectedRowsPerAdapter)
|
|
66
|
+
throw new Error(`Expected ${ADAPTERS.length * expectedRowsPerAdapter} adapter rows; received ${rows.length}.`);
|
|
65
67
|
for (const adapter of ADAPTERS) {
|
|
66
|
-
if (counts.get(adapter) !==
|
|
67
|
-
throw new Error(`Expected
|
|
68
|
+
if (counts.get(adapter) !== expectedRowsPerAdapter)
|
|
69
|
+
throw new Error(`Expected ${expectedRowsPerAdapter} ${adapter} rows; received ${counts.get(adapter) ?? 0}.`);
|
|
68
70
|
}
|
|
69
71
|
process.stdout.write(
|
|
70
72
|
`manifest check: ${rows.length} row receipts (${[...counts].map(([adapter, count]) => `${adapter}=${count}`).join(", ")})\n`,
|
|
@@ -1421,13 +1421,107 @@ function braceBlockRange(contents: string, openingBrace: number): ShellRange | u
|
|
|
1421
1421
|
return undefined;
|
|
1422
1422
|
}
|
|
1423
1423
|
|
|
1424
|
-
function
|
|
1425
|
-
|
|
1424
|
+
function scopeMatches<T extends RegExpMatchArray>(matches: T[], range: ShellRange): T[] {
|
|
1425
|
+
return matches.filter(match => {
|
|
1426
|
+
const index = match.index ?? -1;
|
|
1427
|
+
return index >= range.start && index < range.end;
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
|
|
1431
|
+
function findFunctionRange(contents: string, headerPattern: RegExp): ShellRange | undefined {
|
|
1432
|
+
const header = headerPattern.exec(contents);
|
|
1433
|
+
if (!header) return undefined;
|
|
1434
|
+
const openingBrace = (header.index ?? 0) + header[0].lastIndexOf("{");
|
|
1435
|
+
return braceBlockRange(contents, openingBrace);
|
|
1436
|
+
}
|
|
1437
|
+
|
|
1438
|
+
/**
|
|
1439
|
+
* `relaunchWorkerPaneForMemoryGuard` intentionally re-runs the same sanctioned
|
|
1440
|
+
* tmux send-keys fallback shape as `startTmuxSession` (see
|
|
1441
|
+
* `exactTeamRuntimeSendKeysRanges` below) but through `input.config` /
|
|
1442
|
+
* `newPaneId` instead of `config` / `paneId`, since it dispatches a single
|
|
1443
|
+
* successor pane rather than looping over `config.workers`. Exact-match its
|
|
1444
|
+
* shape the same way so a second legitimate call site does not get treated as
|
|
1445
|
+
* an unsanctioned duplicate.
|
|
1446
|
+
*/
|
|
1447
|
+
function exactMemoryGuardSendKeysRanges(contents: string): ShellRange[] {
|
|
1448
|
+
const fnRange = findFunctionRange(
|
|
1449
|
+
contents,
|
|
1450
|
+
/async\s+function\s+relaunchWorkerPaneForMemoryGuard\s*\([\s\S]{0,600}?\)\s*:\s*Promise<string>\s*\{/,
|
|
1451
|
+
);
|
|
1452
|
+
if (!fnRange) return [];
|
|
1453
|
+
const body = contents.slice(fnRange.start, fnRange.end);
|
|
1454
|
+
const guardMatches = [...body.matchAll(/if\s*\(\s*useSendKeysFallback\s*\)\s*\{/g)];
|
|
1426
1455
|
const payloadMatches = [
|
|
1427
|
-
...
|
|
1428
|
-
/Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*
|
|
1456
|
+
...body.matchAll(
|
|
1457
|
+
/Bun\.spawnSync\(\s*\[\s*input\.config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*newPaneId\s*,\s*workerCommand\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
|
|
1458
|
+
),
|
|
1459
|
+
];
|
|
1460
|
+
const enterMatches = [
|
|
1461
|
+
...body.matchAll(
|
|
1462
|
+
/Bun\.spawnSync\(\s*\[\s*input\.config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*newPaneId\s*,\s*["']Enter["']\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
|
|
1429
1463
|
),
|
|
1430
1464
|
];
|
|
1465
|
+
const useFallbackMatches = [
|
|
1466
|
+
...body.matchAll(
|
|
1467
|
+
/const\s+useSendKeysFallback\s*=\s*shouldDispatchWorkerWithSendKeys\(input\.config\.tmux_command\s*,\s*input\.platform\)\s*;/g,
|
|
1468
|
+
),
|
|
1469
|
+
];
|
|
1470
|
+
const splitWorkerCommandMatches = [
|
|
1471
|
+
...body.matchAll(/\.\.\.\(useSendKeysFallback\s*\?\s*\[\]\s*:\s*\[workerCommand\]\)\s*,/g),
|
|
1472
|
+
];
|
|
1473
|
+
if (
|
|
1474
|
+
guardMatches.length !== 1 ||
|
|
1475
|
+
payloadMatches.length !== 1 ||
|
|
1476
|
+
enterMatches.length !== 1 ||
|
|
1477
|
+
useFallbackMatches.length !== 1 ||
|
|
1478
|
+
splitWorkerCommandMatches.length !== 1
|
|
1479
|
+
)
|
|
1480
|
+
return [];
|
|
1481
|
+
const guardStart = guardMatches[0].index ?? 0;
|
|
1482
|
+
const payloadStart = payloadMatches[0].index ?? 0;
|
|
1483
|
+
const enterStart = enterMatches[0].index ?? 0;
|
|
1484
|
+
if (
|
|
1485
|
+
(useFallbackMatches[0].index ?? 0) >= (splitWorkerCommandMatches[0].index ?? 0) ||
|
|
1486
|
+
(splitWorkerCommandMatches[0].index ?? 0) >= guardStart ||
|
|
1487
|
+
payloadStart >= enterStart
|
|
1488
|
+
)
|
|
1489
|
+
return [];
|
|
1490
|
+
const guard = guardMatches[0];
|
|
1491
|
+
const openingBrace = (guard.index ?? 0) + guard[0].lastIndexOf("{");
|
|
1492
|
+
const range = braceBlockRange(body, openingBrace);
|
|
1493
|
+
if (
|
|
1494
|
+
!range ||
|
|
1495
|
+
payloadStart < range.start ||
|
|
1496
|
+
payloadStart >= range.end ||
|
|
1497
|
+
enterStart < range.start ||
|
|
1498
|
+
enterStart >= range.end
|
|
1499
|
+
)
|
|
1500
|
+
return [];
|
|
1501
|
+
return [
|
|
1502
|
+
{ start: fnRange.start + payloadStart, end: fnRange.start + payloadStart + payloadMatches[0][0].length },
|
|
1503
|
+
{ start: fnRange.start + enterStart, end: fnRange.start + enterStart + enterMatches[0][0].length },
|
|
1504
|
+
];
|
|
1505
|
+
}
|
|
1506
|
+
function exactTeamRuntimeSendKeysRanges(contents: string): ShellRange[] {
|
|
1507
|
+
// Scope the loop-dispatch counts to `startTmuxSession` so the second
|
|
1508
|
+
// sanctioned call site (`relaunchWorkerPaneForMemoryGuard`, matched by
|
|
1509
|
+
// `exactMemoryGuardSendKeysRanges`) does not read as a duplicate. Fixtures
|
|
1510
|
+
// that carry the canonical shape without the enclosing function keep the
|
|
1511
|
+
// original whole-file scope, so exact-match strictness is unchanged.
|
|
1512
|
+
const mainFnRange = findFunctionRange(
|
|
1513
|
+
contents,
|
|
1514
|
+
/async\s+function\s+startTmuxSession\s*\([\s\S]{0,600}?\)\s*:\s*Promise<SkcTeamWorker\[\]>\s*\{/,
|
|
1515
|
+
) ?? { start: 0, end: contents.length };
|
|
1516
|
+
const guardMatches = scopeMatches([...contents.matchAll(/if\s*\(\s*useSendKeysFallback\s*\)\s*\{/g)], mainFnRange);
|
|
1517
|
+
const payloadMatches = scopeMatches(
|
|
1518
|
+
[
|
|
1519
|
+
...contents.matchAll(
|
|
1520
|
+
/Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*workerCommand\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
|
|
1521
|
+
),
|
|
1522
|
+
],
|
|
1523
|
+
mainFnRange,
|
|
1524
|
+
);
|
|
1431
1525
|
const continuationPromptMatches = [
|
|
1432
1526
|
...contents.matchAll(
|
|
1433
1527
|
/(?:const\s+SKC_TEAM_CONTINUATION_PROMPT\s*=\s*["']Continue only your current claimed SKC team task\. Re-read current SKC team state; do not replay prior output; report status\.["']\s*;|import\s*\{[\s\S]{0,1000}?\bSKC_TEAM_CONTINUATION_PROMPT\b[\s\S]{0,1000}?\}\s*from\s*["']\.\/team-workers["']\s*;)/g,
|
|
@@ -1438,24 +1532,31 @@ function exactTeamRuntimeSendKeysRanges(contents: string): ShellRange[] {
|
|
|
1438
1532
|
/const\s+args\s*=\s*Object\.freeze\(\s*\[\s*["']send-keys["']\s*,\s*["']-l["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*SKC_TEAM_CONTINUATION_PROMPT\s*,\s*["'];["']\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*worker\.pane_id\s*,\s*["']Enter["']\s*,?\s*\]\s*\)\s*;\s*const\s+dispatch\s*=\s*skcTeamRuntimeTestSeams\?\.continuationTmuxDispatch\s*\?\s*skcTeamRuntimeTestSeams\.continuationTmuxDispatch\(config\.tmux_command\s*,\s*args\)\s*:\s*Bun\.spawnSync\(\[config\.tmux_command\s*,\s*\.\.\.args\]\s*,\s*\{\s*stdout\s*:\s*["']ignore["']\s*,\s*stderr\s*:\s*["']ignore["']\s*,\s*timeout\s*:\s*SKC_TEAM_CONTINUATION_DISPATCH_TIMEOUT_MS\s*,?\s*\}\s*\)\s*;/g,
|
|
1439
1533
|
),
|
|
1440
1534
|
];
|
|
1441
|
-
const enterMatches =
|
|
1442
|
-
|
|
1443
|
-
|
|
1444
|
-
|
|
1445
|
-
|
|
1535
|
+
const enterMatches = scopeMatches(
|
|
1536
|
+
[
|
|
1537
|
+
...contents.matchAll(
|
|
1538
|
+
/const\s+sendKeys\s*=\s*Bun\.spawnSync\(\s*\[\s*config\.tmux_command\s*,\s*["']send-keys["']\s*,\s*["']-t["']\s*,\s*paneId\s*,\s*["']Enter["']\s*\]\s*,\s*\{[\s\S]{0,200}?stdout\s*:\s*["']ignore["'][\s\S]{0,200}?stderr\s*:\s*["']ignore["'][\s\S]{0,100}?\}\s*\)\s*;/g,
|
|
1539
|
+
),
|
|
1540
|
+
],
|
|
1541
|
+
mainFnRange,
|
|
1542
|
+
);
|
|
1446
1543
|
const fallbackPredicateMatches = [
|
|
1447
1544
|
...contents.matchAll(
|
|
1448
1545
|
/function\s+shouldDispatchWorkerWithSendKeys\([^)]*\)\s*:\s*boolean\s*\{\s*return\s+platform\s*===\s*["']win32["']\s*\|\|\s*path\.basename\(tmuxCommand\)\.toLowerCase\(\)\s*===\s*["']psmux["']\s*;\s*\}/g,
|
|
1449
1546
|
),
|
|
1450
1547
|
];
|
|
1451
|
-
const useFallbackMatches =
|
|
1452
|
-
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
|
|
1456
|
-
|
|
1457
|
-
|
|
1458
|
-
|
|
1548
|
+
const useFallbackMatches = scopeMatches(
|
|
1549
|
+
[
|
|
1550
|
+
...contents.matchAll(
|
|
1551
|
+
/const\s+useSendKeysFallback\s*=\s*shouldDispatchWorkerWithSendKeys\(config\.tmux_command\)\s*;/g,
|
|
1552
|
+
),
|
|
1553
|
+
],
|
|
1554
|
+
mainFnRange,
|
|
1555
|
+
);
|
|
1556
|
+
const splitWorkerCommandMatches = scopeMatches(
|
|
1557
|
+
[...contents.matchAll(/\.\.\.\(useSendKeysFallback\s*\?\s*\[\]\s*:\s*\[workerCommand\]\)\s*,/g)],
|
|
1558
|
+
mainFnRange,
|
|
1559
|
+
);
|
|
1459
1560
|
if (
|
|
1460
1561
|
guardMatches.length !== 1 ||
|
|
1461
1562
|
payloadMatches.length !== 1 ||
|
|
@@ -1543,7 +1644,10 @@ function isTypeOnlyTmuxPrimitiveOccurrence(contents: string, occurrence: TmuxPri
|
|
|
1543
1644
|
|
|
1544
1645
|
function tmuxMachineBusViolations(file: string, contents: string): string[] {
|
|
1545
1646
|
if (isGeneratedDocumentationIndex(file)) return [];
|
|
1546
|
-
const allowedTeamFallbackRanges =
|
|
1647
|
+
const allowedTeamFallbackRanges =
|
|
1648
|
+
file === teamRuntimeTmuxPath
|
|
1649
|
+
? [...exactTeamRuntimeSendKeysRanges(contents), ...exactMemoryGuardSendKeysRanges(contents)]
|
|
1650
|
+
: [];
|
|
1547
1651
|
const violations: string[] = [];
|
|
1548
1652
|
for (const occurrence of tmuxPrimitiveOccurrences(contents)) {
|
|
1549
1653
|
const isExactTeamFallback =
|