@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
package/src/cli.ts
CHANGED
|
@@ -5,9 +5,17 @@
|
|
|
5
5
|
* lightweight CLI runner from pi-utils.
|
|
6
6
|
*/
|
|
7
7
|
import "@sayknow-cli/utils/postmortem";
|
|
8
|
+
import { THINKING_EFFORTS } from "@sayknow-cli/ai";
|
|
8
9
|
import { Args, type CliConfig, Command, type CommandEntry, Flags, run } from "@sayknow-cli/utils/cli";
|
|
9
10
|
import { APP_NAME, formatBunRuntimeError, MIN_BUN_VERSION, VERSION } from "@sayknow-cli/utils/dirs";
|
|
11
|
+
import { loadNative as loadNativeBindings } from "../../natives/native/loader-state.js";
|
|
10
12
|
import { runFixtureReport } from "./cli/fixture-report";
|
|
13
|
+
import { admitManagedOwnerBeforeCli, completeManagedOwnerRecovery } from "./skc-runtime/managed-owner-admission";
|
|
14
|
+
import {
|
|
15
|
+
isManagedOwnerSupervisorArgv,
|
|
16
|
+
MANAGED_OWNER_CHILD_TOKEN_ENV,
|
|
17
|
+
runManagedOwnerSupervisor,
|
|
18
|
+
} from "./skc-runtime/managed-owner-supervisor";
|
|
11
19
|
import { isTmuxOwnerIsolationCliArgv, runTmuxOwnerIsolationCliFromStdin } from "./skc-runtime/tmux-owner-isolation-cli";
|
|
12
20
|
import { smokeTestTabWorker } from "./tools/browser/tab-worker-smoke";
|
|
13
21
|
|
|
@@ -56,6 +64,7 @@ export const commands: CommandEntry[] = [
|
|
|
56
64
|
{ name: "migrate", load: () => import("./commands/migrate").then(m => m.default) },
|
|
57
65
|
{ name: "rlm", load: () => import("./commands/rlm").then(m => m.default) },
|
|
58
66
|
{ name: "update", load: () => import("./commands/update").then(m => m.default) },
|
|
67
|
+
{ name: "read", load: () => import("./commands/read").then(m => m.default) },
|
|
59
68
|
{ name: "plugin", load: () => import("./commands/plugin").then(m => m.default) },
|
|
60
69
|
{ name: "completion", load: () => import("./commands/completion").then(m => m.default) },
|
|
61
70
|
{ name: "launch", load: () => import("./commands/launch").then(m => m.default) },
|
|
@@ -112,6 +121,36 @@ Options:
|
|
|
112
121
|
`);
|
|
113
122
|
}
|
|
114
123
|
|
|
124
|
+
export function interactiveBootstrapText(
|
|
125
|
+
argv: readonly string[],
|
|
126
|
+
stdinIsTTY = process.stdin.isTTY,
|
|
127
|
+
stdoutIsTTY = process.stdout.isTTY,
|
|
128
|
+
): string | undefined {
|
|
129
|
+
if (!stdinIsTTY || !stdoutIsTTY || argv[0] !== "launch") return undefined;
|
|
130
|
+
for (let index = 1; index < argv.length; index++) {
|
|
131
|
+
const arg = argv[index];
|
|
132
|
+
if (
|
|
133
|
+
arg === "--print" ||
|
|
134
|
+
arg?.startsWith("--print=") ||
|
|
135
|
+
arg === "-p" ||
|
|
136
|
+
arg === "--export" ||
|
|
137
|
+
arg?.startsWith("--export=") ||
|
|
138
|
+
arg === "--list-models" ||
|
|
139
|
+
arg?.startsWith("--list-models=") ||
|
|
140
|
+
arg === "--mode" ||
|
|
141
|
+
arg?.startsWith("--mode=") ||
|
|
142
|
+
arg === "--help" ||
|
|
143
|
+
arg?.startsWith("--help=") ||
|
|
144
|
+
arg === "-h" ||
|
|
145
|
+
arg === "--version" ||
|
|
146
|
+
arg?.startsWith("--version=") ||
|
|
147
|
+
arg === "-v"
|
|
148
|
+
)
|
|
149
|
+
return undefined;
|
|
150
|
+
}
|
|
151
|
+
return "\u001b[?25h\u001b[38;5;45mSKC\u001b[0m warming workspace\r\n\r\n> ";
|
|
152
|
+
}
|
|
153
|
+
|
|
115
154
|
function isNotifyDaemonInternalFastPath(argv: string[]): boolean {
|
|
116
155
|
return argv[0] === "notify" && argv[1] === "daemon-internal";
|
|
117
156
|
}
|
|
@@ -138,6 +177,46 @@ async function runChatDaemonInternalFastPath(argv: string[]): Promise<void> {
|
|
|
138
177
|
await runChatDaemonInternal(action === "discord-internal" ? "discord" : "slack", argv.slice(2));
|
|
139
178
|
}
|
|
140
179
|
|
|
180
|
+
type MemoryGuardNativeSmokeLoad = () => Record<string, unknown>;
|
|
181
|
+
type WindowsJobMemoryProbeResult = Record<string, unknown> & { kind: string };
|
|
182
|
+
type MemoryGuardNativeSmokeReceipt = {
|
|
183
|
+
api: "memory_guard_windows_job_probe_v1";
|
|
184
|
+
source: "pi_natives";
|
|
185
|
+
result: WindowsJobMemoryProbeResult;
|
|
186
|
+
};
|
|
187
|
+
|
|
188
|
+
export function isMemoryGuardNativeSmokeFastPath(argv: readonly string[]): boolean {
|
|
189
|
+
return (
|
|
190
|
+
argv.length === 3 && argv[0] === "internal" && argv[1] === "memory-guard-native-smoke" && argv[2] === "--json"
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
function parseWindowsJobMemoryProbeResult(value: unknown): WindowsJobMemoryProbeResult {
|
|
195
|
+
if (!value || typeof value !== "object") {
|
|
196
|
+
throw new Error("memory-guard-native-smoke: native probe returned a non-object result");
|
|
197
|
+
}
|
|
198
|
+
const result = value as Record<string, unknown>;
|
|
199
|
+
if (typeof result.kind !== "string") {
|
|
200
|
+
throw new Error("memory-guard-native-smoke: native probe result is missing a string kind tag");
|
|
201
|
+
}
|
|
202
|
+
return result as WindowsJobMemoryProbeResult;
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
export function runMemoryGuardNativeSmokeFastPath(
|
|
206
|
+
options: { loadNative?: MemoryGuardNativeSmokeLoad; writeStdout?: (text: string) => void } = {},
|
|
207
|
+
): void {
|
|
208
|
+
const probe = (options.loadNative ?? loadNativeBindings)().probeWindowsJobMemory;
|
|
209
|
+
if (typeof probe !== "function") {
|
|
210
|
+
throw new Error("memory-guard-native-smoke: probeWindowsJobMemory export missing from native addon");
|
|
211
|
+
}
|
|
212
|
+
const receipt: MemoryGuardNativeSmokeReceipt = {
|
|
213
|
+
api: "memory_guard_windows_job_probe_v1",
|
|
214
|
+
source: "pi_natives",
|
|
215
|
+
result: parseWindowsJobMemoryProbeResult((probe as () => unknown)()),
|
|
216
|
+
};
|
|
217
|
+
(options.writeStdout ?? (text => process.stdout.write(text)))(`${JSON.stringify(receipt)}\n`);
|
|
218
|
+
}
|
|
219
|
+
|
|
141
220
|
function rootFixtureArg(argv: string[]): { present: boolean; id: string | undefined } {
|
|
142
221
|
for (let i = 0; i < argv.length; i++) {
|
|
143
222
|
const arg = argv[i];
|
|
@@ -208,8 +287,8 @@ export class RootHelpCommand extends Command {
|
|
|
208
287
|
tmux: Flags.boolean({ description: "Launch interactive startup inside tmux" }),
|
|
209
288
|
tools: Flags.string({ description: "Comma-separated list of tools to enable (default: all)" }),
|
|
210
289
|
thinking: Flags.string({
|
|
211
|
-
description:
|
|
212
|
-
options: [
|
|
290
|
+
description: `Set thinking level: ${THINKING_EFFORTS.join(", ")}`,
|
|
291
|
+
options: [...THINKING_EFFORTS],
|
|
213
292
|
}),
|
|
214
293
|
hook: Flags.string({ description: "Load a hook/extension file (can be used multiple times)", multiple: true }),
|
|
215
294
|
extension: Flags.string({
|
|
@@ -287,9 +366,34 @@ export function normalizeResumeAlias(argv: readonly string[]): string[] {
|
|
|
287
366
|
return argv.length === 1 && argv[0] === "resume" ? ["--resume"] : [...argv];
|
|
288
367
|
}
|
|
289
368
|
|
|
369
|
+
function routeLegacyRootArgv(argv: readonly string[]): string[] | undefined {
|
|
370
|
+
if (argv[0] === "coordinator-mcp") return ["mcp-serve", "coordinator", ...argv.slice(1)];
|
|
371
|
+
if (argv[0] !== "--team") return undefined;
|
|
372
|
+
const sizeValues: string[] = [];
|
|
373
|
+
const remaining: string[] = [];
|
|
374
|
+
for (let index = 1; index < argv.length; index++) {
|
|
375
|
+
const arg = argv[index] ?? "";
|
|
376
|
+
if (arg === "--team-size") {
|
|
377
|
+
sizeValues.push(argv[index + 1] ?? "");
|
|
378
|
+
index++;
|
|
379
|
+
} else if (arg.startsWith("--team-size=")) {
|
|
380
|
+
sizeValues.push(arg.slice("--team-size=".length));
|
|
381
|
+
} else {
|
|
382
|
+
remaining.push(arg);
|
|
383
|
+
}
|
|
384
|
+
}
|
|
385
|
+
const size = sizeValues[0];
|
|
386
|
+
if (sizeValues.length !== 1 || !size || !/^[1-9]\d*$/.test(size)) {
|
|
387
|
+
return ["team", "0", "invalid legacy --team-size"];
|
|
388
|
+
}
|
|
389
|
+
return ["team", size, ...remaining];
|
|
390
|
+
}
|
|
391
|
+
|
|
290
392
|
/** Apply the same default-launch routing used by runCli after root fast paths. */
|
|
291
393
|
export function routeRootArgv(argv: readonly string[]): string[] {
|
|
292
394
|
const normalizedArgv = normalizeResumeAlias(argv);
|
|
395
|
+
const legacyArgv = routeLegacyRootArgv(normalizedArgv);
|
|
396
|
+
if (legacyArgv) return legacyArgv;
|
|
293
397
|
const first = normalizedArgv[0];
|
|
294
398
|
return first === "--help" || first === "-h" || first === "--version" || first === "-v" || first === "help"
|
|
295
399
|
? normalizedArgv
|
|
@@ -321,10 +425,26 @@ export async function runCli(argv: string[]): Promise<void> {
|
|
|
321
425
|
}
|
|
322
426
|
// Re-exec could not be spawned; fall through and run in this process.
|
|
323
427
|
}
|
|
428
|
+
if (isMemoryGuardNativeSmokeFastPath(argv)) {
|
|
429
|
+
runMemoryGuardNativeSmokeFastPath();
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
324
432
|
if (isTmuxOwnerIsolationCliArgv(argv)) {
|
|
325
433
|
await runTmuxOwnerIsolationCliFromStdin();
|
|
326
434
|
return;
|
|
327
435
|
}
|
|
436
|
+
if (isManagedOwnerSupervisorArgv(argv)) {
|
|
437
|
+
await runManagedOwnerSupervisor();
|
|
438
|
+
return;
|
|
439
|
+
}
|
|
440
|
+
if (process.env[MANAGED_OWNER_CHILD_TOKEN_ENV] !== undefined) {
|
|
441
|
+
const admission = await admitManagedOwnerBeforeCli();
|
|
442
|
+
if (admission.kind === "blocked") return;
|
|
443
|
+
if (admission.kind === "recovery") {
|
|
444
|
+
await completeManagedOwnerRecovery(admission.context);
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
}
|
|
328
448
|
if (isNotifyDaemonInternalFastPath(argv)) {
|
|
329
449
|
await runNotifyDaemonInternalFastPath(argv);
|
|
330
450
|
return;
|
|
@@ -348,11 +468,9 @@ export async function runCli(argv: string[]): Promise<void> {
|
|
|
348
468
|
process.exitCode = await runFixtureReport(id);
|
|
349
469
|
return;
|
|
350
470
|
}
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
}
|
|
355
|
-
if (hasRootHelpFlag(argv)) {
|
|
471
|
+
const normalizedArgv = normalizeResumeAlias(argv);
|
|
472
|
+
const legacyArgv = routeLegacyRootArgv(normalizedArgv);
|
|
473
|
+
if (!legacyArgv && hasRootHelpFlag(normalizedArgv)) {
|
|
356
474
|
const { renderRootHelp } = await import("@sayknow-cli/utils/cli");
|
|
357
475
|
const { getExtraHelpText } = await import("./cli/fast-help");
|
|
358
476
|
renderRootHelp({ bin: APP_NAME, version: VERSION, commands: new Map([["launch", RootHelpCommand]]) });
|
|
@@ -362,14 +480,18 @@ export async function runCli(argv: string[]): Promise<void> {
|
|
|
362
480
|
}
|
|
363
481
|
return;
|
|
364
482
|
}
|
|
365
|
-
if (hasRootVersionFlag(
|
|
483
|
+
if (!legacyArgv && hasRootVersionFlag(normalizedArgv)) {
|
|
366
484
|
process.stdout.write(`${APP_NAME}/${VERSION}\n`);
|
|
367
485
|
return;
|
|
368
486
|
}
|
|
487
|
+
const runArgv = legacyArgv ?? routeRootArgv(normalizedArgv);
|
|
488
|
+
if (isStatsHelpFastPath(runArgv)) {
|
|
489
|
+
showStatsFastHelp();
|
|
490
|
+
return;
|
|
491
|
+
}
|
|
492
|
+
const bootstrap = interactiveBootstrapText(runArgv);
|
|
493
|
+
if (bootstrap) process.stdout.write(bootstrap);
|
|
369
494
|
await installRuntimeGlobals();
|
|
370
|
-
// --help and --version are handled by run() directly, don't rewrite those.
|
|
371
|
-
// Everything else that isn't a known subcommand routes to "launch".
|
|
372
|
-
const runArgv = routeRootArgv(argv);
|
|
373
495
|
return run({ bin: APP_NAME, version: VERSION, argv: runArgv, commands, help: showHelp });
|
|
374
496
|
}
|
|
375
497
|
|
package/src/commands/daemon.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Manage SKC background daemons (status/list/stop/reload).
|
|
3
3
|
*/
|
|
4
|
-
import { Args, Command, Flags } from "@sayknow-cli/utils/cli";
|
|
4
|
+
import { Args, CliParseError, Command, Flags } from "@sayknow-cli/utils/cli";
|
|
5
5
|
import {
|
|
6
6
|
type DaemonCommandAction,
|
|
7
7
|
type DaemonCommandArgs,
|
|
@@ -15,6 +15,18 @@ import { runSdkSessionCli } from "../sdk/cli";
|
|
|
15
15
|
|
|
16
16
|
const ACTIONS = [...DAEMON_ACTION_TOKENS, "discord-internal", "slack-internal", "session"] as const;
|
|
17
17
|
|
|
18
|
+
function parsePositiveTimeout(raw: string | undefined, flagName: string): number | undefined {
|
|
19
|
+
if (raw === undefined) return undefined;
|
|
20
|
+
if (!/^[0-9]+$/.test(raw)) {
|
|
21
|
+
throw new CliParseError(`Expected ${flagName} to be a positive safe integer, got "${raw}"`);
|
|
22
|
+
}
|
|
23
|
+
const value = Number(raw);
|
|
24
|
+
if (!Number.isSafeInteger(value) || value <= 0) {
|
|
25
|
+
throw new CliParseError(`Expected ${flagName} to be a positive safe integer, got "${raw}"`);
|
|
26
|
+
}
|
|
27
|
+
return value;
|
|
28
|
+
}
|
|
29
|
+
|
|
18
30
|
export default class Daemon extends Command {
|
|
19
31
|
static description =
|
|
20
32
|
"Manage SKC background daemons and SDK sessions. Routine use: `skc daemon status` to check, `skc daemon restart` to reload (spawns one if none is running). `stop`/`list` and the escalation flags below are advanced primitives.";
|
|
@@ -41,8 +53,8 @@ export default class Daemon extends Command {
|
|
|
41
53
|
all: Flags.boolean({ description: "Target all registered daemon kinds" }),
|
|
42
54
|
json: Flags.boolean({ description: "Emit JSON output" }),
|
|
43
55
|
force: Flags.boolean({ description: "Allow hard-kill escalation when graceful stop times out" }),
|
|
44
|
-
"graceful-timeout-ms": Flags.
|
|
45
|
-
"kill-timeout-ms": Flags.
|
|
56
|
+
"graceful-timeout-ms": Flags.string({ description: "Cooperative stop timeout before escalation" }),
|
|
57
|
+
"kill-timeout-ms": Flags.string({ description: "Wait for old pid death after SIGKILL" }),
|
|
46
58
|
"spawn-if-stopped": Flags.boolean({ description: "On reload, spawn even when no daemon is running" }),
|
|
47
59
|
smoke: Flags.boolean({ description: "Internal: run worker smoke without configuration or network" }),
|
|
48
60
|
"owner-id": Flags.string({ description: "Internal: daemon owner id" }),
|
|
@@ -64,6 +76,11 @@ export default class Daemon extends Command {
|
|
|
64
76
|
const rawAction = args.action ?? "status";
|
|
65
77
|
const positional = Array.isArray(args.kind) ? args.kind : args.kind ? [args.kind] : [];
|
|
66
78
|
const flagRec = flags as Record<string, unknown>;
|
|
79
|
+
const gracefulTimeoutMs = parsePositiveTimeout(
|
|
80
|
+
flagRec["graceful-timeout-ms"] as string | undefined,
|
|
81
|
+
"--graceful-timeout-ms",
|
|
82
|
+
);
|
|
83
|
+
const killTimeoutMs = parsePositiveTimeout(flagRec["kill-timeout-ms"] as string | undefined, "--kill-timeout-ms");
|
|
67
84
|
if (rawAction === "session") {
|
|
68
85
|
await runSdkSessionCli({
|
|
69
86
|
action: positional[0],
|
|
@@ -91,8 +108,8 @@ export default class Daemon extends Command {
|
|
|
91
108
|
json: Boolean(flags.json),
|
|
92
109
|
force: Boolean(flags.force),
|
|
93
110
|
verbose: Boolean(flags.verbose),
|
|
94
|
-
gracefulTimeoutMs
|
|
95
|
-
killTimeoutMs
|
|
111
|
+
gracefulTimeoutMs,
|
|
112
|
+
killTimeoutMs,
|
|
96
113
|
spawnIfStopped: flagRec["spawn-if-stopped"] as boolean | undefined,
|
|
97
114
|
smoke: Boolean(flags.smoke),
|
|
98
115
|
ownerId: flagRec["owner-id"] as string | undefined,
|
|
@@ -2,7 +2,22 @@ import { Command, Flags } from "@sayknow-cli/utils/cli";
|
|
|
2
2
|
import { runNativeDeepInterviewCommand } from "../skc-runtime/deep-interview-runtime";
|
|
3
3
|
|
|
4
4
|
export default class DeepInterview extends Command {
|
|
5
|
-
static description =
|
|
5
|
+
static description = `Run native SKC deep-interview workflow.
|
|
6
|
+
|
|
7
|
+
All deep-interview state operations go through this command — no skc state needed:
|
|
8
|
+
read Print the persisted envelope, revision, content sha, and any pending draft
|
|
9
|
+
write One-shot incremental JSON merge into state (--reset replaces; the locked
|
|
10
|
+
intent contract survives a reset)
|
|
11
|
+
stage Stage one JSON transition draft (--for <transition> --input '<json>'|@file)
|
|
12
|
+
check Dry-run the staged draft against current state (same merge apply performs)
|
|
13
|
+
apply Commit the staged draft with runtime-owned revision+sha CAS
|
|
14
|
+
discard Remove the pending draft
|
|
15
|
+
clear Clear deep-interview state for the session (lifecycle passthrough)
|
|
16
|
+
handoff Hand off to the next workflow skill (lifecycle passthrough)
|
|
17
|
+
|
|
18
|
+
Ambiguity is runtime-owned: apply/write derive current_ambiguity from the latest valid scored
|
|
19
|
+
round and clamp it to the deterministic floor. Sessions resolve from --session-id, payload
|
|
20
|
+
session_id, or SKC_SESSION_ID.`;
|
|
6
21
|
static strict = false;
|
|
7
22
|
static flags = {
|
|
8
23
|
quick: Flags.boolean({ description: "Seed a quick deep-interview run" }),
|
|
@@ -14,6 +29,11 @@ export default class DeepInterview extends Command {
|
|
|
14
29
|
"session-id": Flags.string({
|
|
15
30
|
description: "Route state/spec handoff through a session-scoped .skc/_session-{sessionid} directory",
|
|
16
31
|
}),
|
|
32
|
+
input: Flags.string({ description: "JSON payload (or @file) for the write/stage verbs" }),
|
|
33
|
+
for: Flags.string({
|
|
34
|
+
description: "Transition for stage: initialize-context | record-round | update-facts | merge-state",
|
|
35
|
+
}),
|
|
36
|
+
reset: Flags.boolean({ description: "With write: replace state instead of incremental merge" }),
|
|
17
37
|
write: Flags.boolean({ description: "Persist a final deep-interview spec through the sanctioned SKC CLI/API" }),
|
|
18
38
|
stage: Flags.string({ description: 'Spec stage for --write (currently "final")' }),
|
|
19
39
|
slug: Flags.string({ description: "Safe slug for .skc/_session-{sessionid}/specs/deep-interview-<slug>.md" }),
|
|
@@ -27,6 +47,11 @@ export default class DeepInterview extends Command {
|
|
|
27
47
|
};
|
|
28
48
|
static examples = [
|
|
29
49
|
'$ skc deep-interview --trace --standard "<idea>"',
|
|
50
|
+
"$ skc deep-interview read --json",
|
|
51
|
+
'$ skc deep-interview write --input \'{"state":{"threshold":0.05}}\' --json',
|
|
52
|
+
'$ skc deep-interview stage --for record-round --input \'{"state":{"rounds":[{"round":1,"round_key":"r1"}]}}\' --json',
|
|
53
|
+
"$ skc deep-interview check --json",
|
|
54
|
+
"$ skc deep-interview apply --json",
|
|
30
55
|
"$ skc deep-interview --write --stage final --slug my-feature --spec ./final-spec.md",
|
|
31
56
|
"$ skc deep-interview --write --stage final --slug my-feature --spec ./final-spec.md --deliberate",
|
|
32
57
|
];
|
package/src/commands/harness.ts
CHANGED
|
@@ -14,6 +14,7 @@ import { existsSync, readFileSync } from "node:fs";
|
|
|
14
14
|
import * as fs from "node:fs/promises";
|
|
15
15
|
import * as path from "node:path";
|
|
16
16
|
import { Args, Command, Flags } from "@sayknow-cli/utils/cli";
|
|
17
|
+
import { $credentialEnv } from "@sayknow-cli/utils/env";
|
|
17
18
|
import { classifyRecovery } from "../harness-control-plane/classifier";
|
|
18
19
|
import { callEndpoint, EndpointUnreachableError } from "../harness-control-plane/control-endpoint";
|
|
19
20
|
import {
|
|
@@ -565,20 +566,42 @@ function ownerIsolationPlatform(): NodeJS.Platform {
|
|
|
565
566
|
: "linux";
|
|
566
567
|
}
|
|
567
568
|
|
|
569
|
+
/**
|
|
570
|
+
* Operator override for the process-start probe command, resolved from trusted
|
|
571
|
+
* environment sources only.
|
|
572
|
+
*
|
|
573
|
+
* The result is spawned, so whatever can set it chooses which binary runs.
|
|
574
|
+
* `$env` merges the caller's `cwd/.env` into `process.env`, so reading it there
|
|
575
|
+
* would let repository content pick the command; resolve it the same way
|
|
576
|
+
* provider credentials are (launching shell plus SKC/user-owned `.env` files,
|
|
577
|
+
* never the project `.env`). A malformed override stays fatal rather than
|
|
578
|
+
* silently falling back to `ps`, matching the previous behavior.
|
|
579
|
+
*/
|
|
580
|
+
type ProcessStartCommandOverride = { kind: "none" } | { kind: "invalid" } | { kind: "command"; command: string[] };
|
|
581
|
+
|
|
582
|
+
function processStartCommandOverride(): ProcessStartCommandOverride {
|
|
583
|
+
const configured = $credentialEnv("SKC_HARNESS_PROCESS_START_COMMAND");
|
|
584
|
+
if (!configured) return { kind: "none" };
|
|
585
|
+
try {
|
|
586
|
+
const parsed = JSON.parse(configured) as unknown;
|
|
587
|
+
if (!Array.isArray(parsed) || parsed.length === 0 || parsed.some(value => typeof value !== "string" || !value))
|
|
588
|
+
return { kind: "invalid" };
|
|
589
|
+
return { kind: "command", command: parsed as string[] };
|
|
590
|
+
} catch {
|
|
591
|
+
return { kind: "invalid" };
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
|
|
595
|
+
/** Test seam: the process-start command override as resolved from trusted env. */
|
|
596
|
+
export function processStartCommandOverrideForTest(): ProcessStartCommandOverride {
|
|
597
|
+
return processStartCommandOverride();
|
|
598
|
+
}
|
|
599
|
+
|
|
568
600
|
function portableProcessStartTime(pid: number): string | null {
|
|
569
601
|
if (process.platform === "linux") return null;
|
|
570
|
-
const
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
try {
|
|
574
|
-
const parsed = JSON.parse(configured) as unknown;
|
|
575
|
-
if (!Array.isArray(parsed) || parsed.length === 0 || parsed.some(value => typeof value !== "string" || !value))
|
|
576
|
-
return null;
|
|
577
|
-
command = parsed;
|
|
578
|
-
} catch {
|
|
579
|
-
return null;
|
|
580
|
-
}
|
|
581
|
-
}
|
|
602
|
+
const override = processStartCommandOverride();
|
|
603
|
+
if (override.kind === "invalid") return null;
|
|
604
|
+
const command: string[] = override.kind === "command" ? override.command : ["ps", "-o", "lstart=", "-p"];
|
|
582
605
|
const result = Bun.spawnSync([...command, String(pid)], {
|
|
583
606
|
stdout: "pipe",
|
|
584
607
|
stderr: "ignore",
|
package/src/commands/read.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Show what the read tool will return for a given path.
|
|
3
3
|
*/
|
|
4
|
-
import { Args, Command } from "@sayknow-cli/utils/cli";
|
|
4
|
+
import { Args, Command, Flags } from "@sayknow-cli/utils/cli";
|
|
5
5
|
import { type ReadCommandArgs, runReadCommand } from "../cli/read-cli";
|
|
6
6
|
import { initTheme } from "../modes/theme/theme";
|
|
7
7
|
|
|
@@ -15,8 +15,16 @@ export default class Read extends Command {
|
|
|
15
15
|
}),
|
|
16
16
|
};
|
|
17
17
|
|
|
18
|
+
static flags = {
|
|
19
|
+
truncation: Flags.string({
|
|
20
|
+
options: ["head", "last", "both"],
|
|
21
|
+
description: "Which end of an over-budget result to keep",
|
|
22
|
+
}),
|
|
23
|
+
};
|
|
24
|
+
|
|
18
25
|
static examples = [
|
|
19
26
|
"skc read src/foo.ts",
|
|
27
|
+
"skc read src/foo.ts --truncation head",
|
|
20
28
|
"skc read src/foo.ts:50-100",
|
|
21
29
|
"skc read src/foo.ts:raw",
|
|
22
30
|
"skc read https://example.com",
|
|
@@ -25,9 +33,10 @@ export default class Read extends Command {
|
|
|
25
33
|
];
|
|
26
34
|
|
|
27
35
|
async run(): Promise<void> {
|
|
28
|
-
const { args } = await this.parse(Read);
|
|
36
|
+
const { args, flags } = await this.parse(Read);
|
|
29
37
|
const cmd: ReadCommandArgs = {
|
|
30
38
|
path: args.path ?? "",
|
|
39
|
+
truncation: flags.truncation as ReadCommandArgs["truncation"],
|
|
31
40
|
};
|
|
32
41
|
await initTheme();
|
|
33
42
|
await runReadCommand(cmd);
|
package/src/commands/sdk.ts
CHANGED
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import * as fs from "node:fs/promises";
|
|
3
|
+
import * as os from "node:os";
|
|
3
4
|
import * as path from "node:path";
|
|
4
|
-
import { Args, Command, Flags } from "@sayknow-cli/utils/cli";
|
|
5
|
+
import { Args, CliParseError, Command, Flags, renderCommandHelp } from "@sayknow-cli/utils/cli";
|
|
5
6
|
import type { Args as ParsedArgs } from "../cli/args";
|
|
6
7
|
import { Settings } from "../config/settings";
|
|
7
8
|
import { applyStartupModelProfiles, createSessionManager } from "../main";
|
|
8
9
|
import { initializeExtensions } from "../modes/runtime-init";
|
|
10
|
+
import { ACP_MCP_REQUEST_TIMEOUT_MS, ACP_MCP_STARTUP_HEADROOM_MS } from "../sdk/acp/mcp";
|
|
9
11
|
import { Broker } from "../sdk/broker/broker";
|
|
10
12
|
import { completeBrokerProcess } from "../sdk/broker/internal";
|
|
11
13
|
import {
|
|
@@ -25,6 +27,7 @@ import {
|
|
|
25
27
|
type SdkStartupRollbackResult,
|
|
26
28
|
SdkStartupRollbackTracker,
|
|
27
29
|
} from "../sdk/startup-capability";
|
|
30
|
+
import { runSdkServe } from "../sdk/transport/serve-cli";
|
|
28
31
|
import {
|
|
29
32
|
type CapturedSessionTranscriptSnapshot,
|
|
30
33
|
type ResumeSessionIdentity,
|
|
@@ -284,24 +287,106 @@ export async function runSessionHost(
|
|
|
284
287
|
throw new Error("SDK startup did not complete before readiness cutoff.");
|
|
285
288
|
}
|
|
286
289
|
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
created = await createLifecycleAgentSession({ cwd, agentDir, sessionManager: opened.sessionManager });
|
|
292
|
-
} catch (error) {
|
|
290
|
+
// Inlined rather than extracted to a helper: TypeScript's definite-assignment
|
|
291
|
+
// analysis does not see a `Promise<never>` helper as terminating, so hoisting
|
|
292
|
+
// this would make `opened`/`created` "used before assigned" below.
|
|
293
|
+
const registrationFailure = async (error: unknown): Promise<SdkStartupFailure> => {
|
|
293
294
|
const rollback = new SdkStartupRollbackTracker();
|
|
294
295
|
rollback.recordAbsent();
|
|
295
296
|
const failure = normalizeSdkStartupFailure("registration", "failed", error);
|
|
296
297
|
await writeFailure(failure, rollback.result);
|
|
297
|
-
|
|
298
|
+
return failure;
|
|
299
|
+
};
|
|
300
|
+
|
|
301
|
+
let opened: { parsed: ParsedArgs; sessionManager: SessionManager | undefined };
|
|
302
|
+
let created: CreateLifecycleAgentSessionResult;
|
|
303
|
+
let mcpConfigDirectory: string | undefined;
|
|
304
|
+
try {
|
|
305
|
+
let mcpConfigPath: string | undefined;
|
|
306
|
+
try {
|
|
307
|
+
opened = await openLifecycleSessionManager(request, cwd, agentDir);
|
|
308
|
+
if (request.mcpServers && request.mcpServers.length > 0) {
|
|
309
|
+
mcpConfigDirectory = await fs.realpath(await fs.mkdtemp(path.join(os.tmpdir(), "skc-acp-mcp-")));
|
|
310
|
+
mcpConfigPath = path.join(mcpConfigDirectory, "mcp.json");
|
|
311
|
+
await Bun.write(
|
|
312
|
+
mcpConfigPath,
|
|
313
|
+
JSON.stringify({
|
|
314
|
+
mcpServers: Object.fromEntries(
|
|
315
|
+
request.mcpServers.map(server => [
|
|
316
|
+
server.name,
|
|
317
|
+
"url" in server
|
|
318
|
+
? {
|
|
319
|
+
type: server.type,
|
|
320
|
+
url: server.url,
|
|
321
|
+
...(server.headers ? { headers: server.headers } : {}),
|
|
322
|
+
timeout: ACP_MCP_REQUEST_TIMEOUT_MS,
|
|
323
|
+
}
|
|
324
|
+
: {
|
|
325
|
+
type: "stdio",
|
|
326
|
+
command: server.command,
|
|
327
|
+
args: server.args,
|
|
328
|
+
...(server.env ? { env: server.env } : {}),
|
|
329
|
+
noInheritEnv: true,
|
|
330
|
+
timeout: ACP_MCP_REQUEST_TIMEOUT_MS,
|
|
331
|
+
},
|
|
332
|
+
]),
|
|
333
|
+
),
|
|
334
|
+
}),
|
|
335
|
+
);
|
|
336
|
+
}
|
|
337
|
+
} catch (error) {
|
|
338
|
+
throw await registrationFailure(error);
|
|
339
|
+
}
|
|
340
|
+
|
|
341
|
+
// The longer MCP startup ceiling is scoped to ACP lifecycle launches only:
|
|
342
|
+
// it applies when this request actually carried `mcpServers`. Ordinary
|
|
343
|
+
// CLI/SDK `mcpConfigPath` consumers keep the manager's short default.
|
|
344
|
+
//
|
|
345
|
+
// This recheck deliberately sits OUTSIDE the registration catch above.
|
|
346
|
+
// Inside it, the throw would be caught, reclassified as
|
|
347
|
+
// `registration`/`failed`, and written a second time, losing the
|
|
348
|
+
// `startup`/`pending` outcome the readiness cutoff is supposed to report.
|
|
349
|
+
// Session-manager open and MCP config write already consumed part of the
|
|
350
|
+
// budget, so re-read the clock here rather than reusing the earlier check.
|
|
351
|
+
let mcpStartupTimeoutMs: number | undefined;
|
|
352
|
+
if (mcpConfigPath !== undefined) {
|
|
353
|
+
const remaining = request.semanticReadyDeadlineAt - now() - ACP_MCP_STARTUP_HEADROOM_MS;
|
|
354
|
+
if (remaining <= 0) {
|
|
355
|
+
const absent = new SdkStartupRollbackTracker();
|
|
356
|
+
absent.recordAbsent();
|
|
357
|
+
await writeFailure(
|
|
358
|
+
{
|
|
359
|
+
phase: "startup",
|
|
360
|
+
reason: "pending",
|
|
361
|
+
message: "SDK startup did not complete before readiness cutoff.",
|
|
362
|
+
},
|
|
363
|
+
absent.result,
|
|
364
|
+
);
|
|
365
|
+
throw new Error("SDK startup did not complete before readiness cutoff.");
|
|
366
|
+
}
|
|
367
|
+
mcpStartupTimeoutMs = remaining;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
try {
|
|
371
|
+
created = await createLifecycleAgentSession({
|
|
372
|
+
cwd,
|
|
373
|
+
agentDir,
|
|
374
|
+
sessionManager: opened.sessionManager,
|
|
375
|
+
...(mcpConfigPath ? { mcpConfigPath } : {}),
|
|
376
|
+
...(mcpStartupTimeoutMs !== undefined ? { mcpStartupTimeoutMs } : {}),
|
|
377
|
+
});
|
|
378
|
+
} catch (error) {
|
|
379
|
+
throw await registrationFailure(error);
|
|
380
|
+
}
|
|
381
|
+
} finally {
|
|
382
|
+
if (mcpConfigDirectory) await fs.rm(mcpConfigDirectory, { recursive: true, force: true });
|
|
298
383
|
}
|
|
299
384
|
const { parsed } = opened;
|
|
300
385
|
if ("failure" in created) {
|
|
301
386
|
created.rollback.recordAbsent();
|
|
302
387
|
await writeFailure(created.failure, created.rollback.result);
|
|
303
388
|
|
|
304
|
-
throw
|
|
389
|
+
throw created.failure;
|
|
305
390
|
}
|
|
306
391
|
const { session, capability, rollback } = created;
|
|
307
392
|
let sessionDisposal: Promise<void> | undefined;
|
|
@@ -423,19 +508,51 @@ export async function runSessionHost(
|
|
|
423
508
|
await new Promise<void>(() => {});
|
|
424
509
|
}
|
|
425
510
|
|
|
511
|
+
export type SdkInternalArgv = { action: "broker-internal"; agentDir: string } | { action: "session-host-internal" };
|
|
512
|
+
|
|
513
|
+
/** Parses the exact private argv contracts used by SDK child-process spawns. */
|
|
514
|
+
export function parseSdkInternalArgv(argv: readonly string[]): SdkInternalArgv {
|
|
515
|
+
if (argv[0] === "session-host-internal" && argv.length === 1) return { action: "session-host-internal" };
|
|
516
|
+
if (argv[0] === "broker-internal" && argv.length === 3 && argv[1] === "--agent-dir" && argv[2])
|
|
517
|
+
return { action: "broker-internal", agentDir: argv[2] };
|
|
518
|
+
throw new CliParseError("Invalid internal SDK invocation.");
|
|
519
|
+
}
|
|
520
|
+
|
|
521
|
+
class SdkServeHelp extends Command {
|
|
522
|
+
static description = "skc sdk serve --stdio | --socket <path> [--session <id>] [--pending-ceiling <bytes>]";
|
|
523
|
+
static flags = {
|
|
524
|
+
stdio: Flags.boolean({ description: "Serve SDK frames over standard input and output" }),
|
|
525
|
+
socket: Flags.string({ description: "Serve SDK frames over a Unix socket path" }),
|
|
526
|
+
session: Flags.string({ description: "Attach to a specific SDK session" }),
|
|
527
|
+
"pending-ceiling": Flags.string({ description: "Maximum queued relay bytes per direction" }),
|
|
528
|
+
};
|
|
529
|
+
async run(): Promise<void> {}
|
|
530
|
+
}
|
|
531
|
+
|
|
426
532
|
export default class Sdk extends Command {
|
|
427
|
-
static description = "
|
|
428
|
-
static hidden =
|
|
429
|
-
static
|
|
430
|
-
static
|
|
533
|
+
static description = "skc sdk serve --stdio | --socket <path> [--session <id>] [--pending-ceiling <bytes>]";
|
|
534
|
+
static hidden = false;
|
|
535
|
+
static delegateHelp = true;
|
|
536
|
+
static args = { action: Args.string({ required: false, options: ["serve"] }) };
|
|
537
|
+
static flags = SdkServeHelp.flags;
|
|
431
538
|
async run(): Promise<void> {
|
|
432
|
-
const
|
|
433
|
-
if (
|
|
539
|
+
const action = this.argv[0];
|
|
540
|
+
if (this.argv.includes("--help") || this.argv.includes("-h")) {
|
|
541
|
+
renderCommandHelp("skc", action === "serve" ? "sdk serve" : "sdk", action === "serve" ? SdkServeHelp : Sdk);
|
|
542
|
+
return;
|
|
543
|
+
}
|
|
544
|
+
if (action === "serve") {
|
|
545
|
+
await runSdkServe(this.argv.slice(1));
|
|
546
|
+
return;
|
|
547
|
+
}
|
|
548
|
+
if (action !== "broker-internal" && action !== "session-host-internal")
|
|
549
|
+
throw new CliParseError("Expected action to be serve.");
|
|
550
|
+
const internal = parseSdkInternalArgv(this.argv);
|
|
551
|
+
if (internal.action === "session-host-internal") {
|
|
434
552
|
await runSessionHost();
|
|
435
553
|
return;
|
|
436
554
|
}
|
|
437
|
-
const agentDir =
|
|
438
|
-
if (!agentDir) throw new Error("--agent-dir is required for sdk broker-internal.");
|
|
555
|
+
const agentDir = internal.agentDir;
|
|
439
556
|
const broker = new Broker({
|
|
440
557
|
agentDir,
|
|
441
558
|
resolveDirectoryMigration: async cwd => {
|
package/src/commands/team.ts
CHANGED
|
@@ -173,7 +173,7 @@ export default class Team extends Command {
|
|
|
173
173
|
"Supported operations:",
|
|
174
174
|
"send-message broadcast mailbox-list mailbox-mark-delivered mailbox-mark-notified notification-list notification-read notification-replay notification-mark-pane-attempt worker-startup-ack",
|
|
175
175
|
"create-task read-task list-tasks update-task claim-task transition-task-status release-task-claim",
|
|
176
|
-
"read-config read-manifest read-worker-status update-worker-status read-worker-heartbeat recover-stale-claims update-worker-heartbeat write-worker-inbox write-worker-identity",
|
|
176
|
+
"read-config read-manifest read-worker-status update-worker-status read-worker-heartbeat recover-stale-claims update-worker-heartbeat read-worker-memory-guard update-worker-memory-guard apply-worker-memory-guard write-worker-inbox write-worker-identity",
|
|
177
177
|
"append-event read-events read-traces await-event write-shutdown-request read-shutdown-ack read-monitor-snapshot write-monitor-snapshot read-task-approval write-task-approval",
|
|
178
178
|
"Completion example:",
|
|
179
179
|
'transition-task-status --input \'{"team_name":"demo","task_id":"task-1","to":"completed","claim_token":"...","completion_evidence":{"summary":"done","items":[{"kind":"command","status":"passed","summary":"focused tests passed","command":"bun test packages/coding-agent/test/skc-runtime/team-runtime.test.ts"}]}}\' --json',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as path from "node:path";
|
|
2
2
|
import { createInterface } from "node:readline/promises";
|
|
3
|
-
import { $env, getProjectDir, isEnoent, prompt } from "@sayknow-cli/utils";
|
|
3
|
+
import { $env, $pickenv, getProjectDir, isEnoent, prompt } from "@sayknow-cli/utils";
|
|
4
4
|
import { applyChangelogProposals } from "../../commit/changelog";
|
|
5
5
|
import { detectChangelogBoundaries } from "../../commit/changelog/detect";
|
|
6
6
|
import { parseUnreleasedSection } from "../../commit/changelog/parse";
|
|
@@ -88,7 +88,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
88
88
|
} else {
|
|
89
89
|
process.stdout.write(" └─ (none found)\n");
|
|
90
90
|
}
|
|
91
|
-
const forceFallback = $
|
|
91
|
+
const forceFallback = $pickenv("SKC_COMMIT_TEST_FALLBACK", "PI_COMMIT_TEST_FALLBACK")?.toLowerCase() === "true";
|
|
92
92
|
if (forceFallback) {
|
|
93
93
|
process.stdout.write("● Forcing fallback commit generation...\n");
|
|
94
94
|
const fallbackProposal = generateFallbackProposal(numstat);
|
|
@@ -152,7 +152,7 @@ export async function runAgenticCommit(args: CommitCommandArgs): Promise<void> {
|
|
|
152
152
|
}
|
|
153
153
|
|
|
154
154
|
if (!usedFallback && !commitState.proposal && !commitState.splitProposal) {
|
|
155
|
-
if ($
|
|
155
|
+
if ($pickenv("SKC_COMMIT_NO_FALLBACK", "PI_COMMIT_NO_FALLBACK")?.toLowerCase() !== "true") {
|
|
156
156
|
process.stdout.write("● Agent did not provide proposal, using fallback...\n");
|
|
157
157
|
commitState.proposal = generateFallbackProposal(numstat);
|
|
158
158
|
usedFallback = true;
|