@sayknow-cli/coding-agent 0.4.7 → 0.5.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +122 -0
- package/dist/types/capability/index.d.ts +10 -20
- package/dist/types/capability/types.d.ts +3 -0
- package/dist/types/cli/args.d.ts +0 -2
- package/dist/types/cli/read-cli.d.ts +1 -0
- package/dist/types/cli.d.ts +9 -1
- package/dist/types/commands/daemon.d.ts +2 -2
- package/dist/types/commands/deep-interview.d.ts +9 -0
- package/dist/types/commands/harness.d.ts +22 -0
- package/dist/types/commands/read.d.ts +6 -0
- package/dist/types/commands/sdk.d.ts +20 -2
- package/dist/types/config/keybindings.d.ts +34 -4
- package/dist/types/config/model-profile-contract.d.ts +40 -0
- package/dist/types/config/model-profiles.d.ts +2 -3
- package/dist/types/config/model-registry.d.ts +5 -0
- package/dist/types/config/provider-auth-health.d.ts +14 -0
- package/dist/types/config/provider-ranking.d.ts +59 -0
- package/dist/types/config/settings-schema.d.ts +156 -10
- package/dist/types/config/settings.d.ts +3 -0
- package/dist/types/edit/modes/patch.d.ts +13 -0
- package/dist/types/edit/path-mutation-lock.d.ts +15 -0
- package/dist/types/eval/py/executor.d.ts +1 -1
- package/dist/types/eval/py/runner-artifact.d.ts +8 -0
- package/dist/types/eval/py/tool-bridge.d.ts +1 -2
- package/dist/types/extensibility/extensions/types.d.ts +43 -2
- package/dist/types/extensibility/shared-events.d.ts +6 -0
- package/dist/types/internal-urls/local-root-gc.d.ts +2 -0
- package/dist/types/main.d.ts +33 -2
- package/dist/types/memories/index.d.ts +2 -0
- package/dist/types/modes/acp/acp-agent.d.ts +22 -9
- package/dist/types/modes/components/assistant-message.d.ts +3 -1
- package/dist/types/modes/components/btw-panel.d.ts +1 -0
- package/dist/types/modes/components/irc-sidebar.d.ts +41 -0
- package/dist/types/modes/components/queue-pane.d.ts +8 -0
- package/dist/types/modes/components/queued-message-selector.d.ts +6 -0
- package/dist/types/modes/components/read-tool-group.d.ts +4 -4
- package/dist/types/modes/components/runtime-mcp-add-wizard.d.ts +2 -1
- package/dist/types/modes/components/session-observer-overlay.d.ts +4 -0
- package/dist/types/modes/components/settings-selector.d.ts +2 -0
- package/dist/types/modes/components/tool-execution.d.ts +8 -0
- package/dist/types/modes/components/tool-status-header.d.ts +4 -2
- package/dist/types/modes/components/welcome.d.ts +5 -0
- package/dist/types/modes/controllers/btw-controller.d.ts +5 -0
- package/dist/types/modes/controllers/command-controller.d.ts +2 -0
- package/dist/types/modes/controllers/event-controller.d.ts +3 -0
- package/dist/types/modes/interactive-mode.d.ts +13 -2
- package/dist/types/modes/irc-observation-ledger.d.ts +17 -1
- package/dist/types/modes/prompt-action-autocomplete.d.ts +6 -1
- package/dist/types/modes/prompt-suggestion-controller.d.ts +35 -0
- package/dist/types/modes/shared/agent-wire/workflow-gate-broker.d.ts +2 -2
- package/dist/types/modes/types.d.ts +6 -0
- package/dist/types/modes/utils/hotkeys-markdown.d.ts +2 -1
- package/dist/types/modes/utils/ui-helpers.d.ts +16 -0
- package/dist/types/runtime/memory-domain.d.ts +9 -0
- package/dist/types/runtime/memory-guard-contract.d.ts +71 -0
- package/dist/types/runtime/memory-guard.d.ts +39 -0
- package/dist/types/runtime/memory-limit.d.ts +11 -0
- package/dist/types/runtime-mcp/content-limits.d.ts +7 -0
- package/dist/types/runtime-mcp/discoverable-tool-metadata.d.ts +1 -1
- package/dist/types/runtime-mcp/manager.d.ts +9 -1
- package/dist/types/runtime-mcp/oauth-flow.d.ts +0 -5
- package/dist/types/runtime-mcp/plugin-network-boundary.d.ts +14 -0
- package/dist/types/runtime-mcp/redaction.d.ts +2 -0
- package/dist/types/runtime-mcp/smithery-auth.d.ts +5 -0
- package/dist/types/sdk/acp/final-text.d.ts +19 -0
- package/dist/types/sdk/acp/mcp.d.ts +23 -0
- package/dist/types/sdk/broker/broker.d.ts +2 -0
- package/dist/types/sdk/broker/lifecycle.d.ts +13 -0
- package/dist/types/sdk/bus/chat-daemon-control.d.ts +9 -1
- package/dist/types/sdk/bus/config-commands.d.ts +2 -2
- package/dist/types/sdk/bus/config.d.ts +2 -0
- package/dist/types/sdk/bus/control-drain-lease.d.ts +52 -0
- package/dist/types/sdk/bus/conversation-store.d.ts +1 -0
- package/dist/types/sdk/bus/daemon-paths.d.ts +1 -0
- package/dist/types/sdk/bus/index.d.ts +52 -4
- package/dist/types/sdk/bus/kind-aware-reconciliation.d.ts +37 -0
- package/dist/types/sdk/bus/lifecycle-commands.d.ts +5 -4
- package/dist/types/sdk/bus/notification-orchestration.d.ts +1 -0
- package/dist/types/sdk/bus/notification-service.d.ts +34 -0
- package/dist/types/sdk/bus/operator-runtime.d.ts +1 -0
- package/dist/types/sdk/bus/prompt-reconciliation.d.ts +106 -0
- package/dist/types/sdk/bus/rate-limit-pool.d.ts +2 -0
- package/dist/types/sdk/bus/reconciliation-store.d.ts +65 -0
- package/dist/types/sdk/bus/telegram-daemon-contract.d.ts +33 -9
- package/dist/types/sdk/bus/telegram-daemon-control.d.ts +5 -1
- package/dist/types/sdk/bus/telegram-daemon.d.ts +286 -12
- package/dist/types/sdk/bus/telegram-reference.d.ts +2 -0
- package/dist/types/sdk/bus/topic-registry.d.ts +88 -2
- package/dist/types/sdk/client/discovery.d.ts +2 -0
- package/dist/types/sdk/client/liveness.d.ts +7 -0
- package/dist/types/sdk/host/control/operations.d.ts +3 -2
- package/dist/types/sdk/host/host.d.ts +3 -1
- package/dist/types/sdk/host/query/handlers.d.ts +14 -0
- package/dist/types/sdk/index.d.ts +2 -0
- package/dist/types/sdk/lifecycle-session.d.ts +10 -1
- package/dist/types/sdk/prompt-status.d.ts +88 -0
- package/dist/types/sdk/session-directory.d.ts +1 -1
- package/dist/types/sdk/session.d.ts +7 -0
- package/dist/types/sdk/startup-capability.d.ts +9 -0
- package/dist/types/sdk/transport/auth-preface.d.ts +9 -0
- package/dist/types/sdk/transport/index.d.ts +12 -0
- package/dist/types/sdk/transport/relay.d.ts +43 -0
- package/dist/types/sdk/transport/serve-cli.d.ts +4 -0
- package/dist/types/sdk/transport/socket.d.ts +7 -0
- package/dist/types/sdk/transport/stdio.d.ts +3 -0
- package/dist/types/session/agent-session.d.ts +83 -24
- package/dist/types/session/btw-contract.d.ts +16 -0
- package/dist/types/session/fallback-chain-controller.d.ts +18 -2
- package/dist/types/session/internal/managed-session-scope.d.ts +70 -10
- package/dist/types/session/internal/managed-session-storage.d.ts +34 -12
- package/dist/types/session/internal/native-publish-outcome.d.ts +48 -0
- package/dist/types/session/memory-guard-checkpoint-participant.d.ts +69 -0
- package/dist/types/session/session-manager.d.ts +89 -18
- package/dist/types/session/session-storage.d.ts +31 -0
- package/dist/types/session/streaming-output.d.ts +60 -5
- package/dist/types/setup/credential-import.d.ts +5 -1
- package/dist/types/setup/provider-onboarding.d.ts +2 -0
- package/dist/types/skc-runtime/deep-interview-runtime.d.ts +1 -1
- package/dist/types/skc-runtime/deep-interview-stage.d.ts +37 -0
- package/dist/types/skc-runtime/gc-runtime.d.ts +1 -1
- package/dist/types/skc-runtime/linux-proc.d.ts +22 -14
- package/dist/types/skc-runtime/memory-guard-owner-claims.d.ts +47 -0
- package/dist/types/skc-runtime/ralplan-runtime.d.ts +112 -1
- package/dist/types/skc-runtime/repository-binding.d.ts +63 -0
- package/dist/types/skc-runtime/state-runtime.d.ts +3 -1
- package/dist/types/skc-runtime/state-writer.d.ts +5 -1
- package/dist/types/skc-runtime/team-launch.d.ts +1 -1
- package/dist/types/skc-runtime/team-runtime.d.ts +9 -2
- package/dist/types/skc-runtime/team-store.d.ts +12 -0
- package/dist/types/skc-runtime/team-worker-memory-guard.d.ts +92 -0
- package/dist/types/skc-runtime/tmux-owner-isolation.d.ts +7 -0
- package/dist/types/skc-runtime/ultragoal-guard.d.ts +6 -5
- package/dist/types/skc-runtime/ultragoal-receipt-freshness.d.ts +28 -0
- package/dist/types/skc-runtime/ultragoal-runtime.d.ts +43 -5
- package/dist/types/skill-state/workflow-hud.d.ts +3 -0
- package/dist/types/ssh/utils.d.ts +1 -0
- package/dist/types/task/discovery.d.ts +3 -1
- package/dist/types/task/executor.d.ts +6 -0
- package/dist/types/task/index.d.ts +3 -1
- package/dist/types/task/provider-retry-status.d.ts +13 -0
- package/dist/types/task/receipt.d.ts +2 -0
- package/dist/types/task/types.d.ts +133 -0
- package/dist/types/task/ultragoal-redteam-activation.d.ts +33 -0
- package/dist/types/tools/browser/launch.d.ts +7 -0
- package/dist/types/tools/fetch.d.ts +22 -9
- package/dist/types/tools/image-gen.d.ts +63 -1
- package/dist/types/tools/index.d.ts +7 -1
- package/dist/types/tools/output-meta.d.ts +21 -1
- package/dist/types/tools/read-internals.d.ts +12 -0
- package/dist/types/tools/read.d.ts +45 -1
- package/dist/types/tools/resource-gc.d.ts +23 -0
- package/dist/types/tools/skill-discovery.d.ts +7 -0
- package/dist/types/tools/sqlite-reader.d.ts +7 -0
- package/dist/types/tools/tool-result.d.ts +7 -1
- package/dist/types/utils/prompt-suggestion.d.ts +33 -0
- package/dist/types/utils/shell-snapshot.d.ts +12 -0
- package/dist/types/web/insane/bridge.d.ts +1 -0
- package/dist/types/web/insane/url-guard.d.ts +17 -0
- package/package.json +8 -12
- package/scripts/benchmark-sticky-viewport-pr1.ts +239 -0
- package/scripts/capture-platform-shortcut-labels-showcase.ts +342 -0
- package/scripts/capture-sticky-viewport-showcase.ts +292 -0
- package/scripts/compile-args.ts +0 -1
- package/scripts/dogfood-repository-binding.ts +209 -0
- package/scripts/generate-docs-index.ts +4 -1
- package/scripts/generate-sdk-operation-inventory.ts +9 -0
- package/scripts/run-test-manifest.ts +6 -4
- package/scripts/verify-skc-sdk-canonicalization.ts +122 -18
- package/scripts/verify-sticky-viewport-showcase.ts +611 -0
- package/src/capability/index.ts +58 -42
- package/src/capability/types.ts +3 -0
- package/src/cli/args.ts +16 -100
- package/src/cli/fast-help.ts +1 -1
- package/src/cli/mcp-cli.ts +4 -21
- package/src/cli/notify-cli.ts +6 -38
- package/src/cli/read-cli.ts +2 -1
- package/src/cli/setup-cli.ts +10 -4
- package/src/cli.ts +133 -11
- package/src/commands/daemon.ts +22 -5
- package/src/commands/deep-interview.ts +26 -1
- package/src/commands/harness.ts +35 -12
- package/src/commands/read.ts +11 -2
- package/src/commands/sdk.ts +134 -17
- package/src/commands/team.ts +1 -1
- package/src/commit/agentic/index.ts +3 -3
- package/src/commit/map-reduce/index.ts +2 -2
- package/src/config/keybindings.ts +158 -25
- package/src/config/model-profile-contract.ts +174 -0
- package/src/config/model-profiles.ts +51 -10
- package/src/config/model-registry.ts +24 -4
- package/src/config/model-resolver.ts +2 -2
- package/src/config/provider-auth-health.ts +42 -0
- package/src/config/provider-ranking.ts +119 -0
- package/src/config/settings-schema.ts +157 -10
- package/src/config/settings.ts +254 -108
- package/src/coordinator-mcp/model-preset.ts +21 -74
- package/src/defaults/skc/skills/deep-interview/SKILL.md +147 -24
- package/src/defaults/skc/skills/ralplan/SKILL.md +91 -34
- package/src/defaults/skc/skills/team/SKILL.md +1 -1
- package/src/defaults/skc/skills/ultragoal/SKILL.md +68 -17
- package/src/discovery/ssh.ts +12 -1
- package/src/edit/index.ts +3 -6
- package/src/edit/modes/patch.ts +38 -1
- package/src/edit/modes/replace.ts +42 -0
- package/src/edit/path-mutation-lock.ts +112 -0
- package/src/eval/js/tool-bridge.ts +1 -1
- package/src/eval/py/executor.ts +37 -13
- package/src/eval/py/kernel.ts +1 -21
- package/src/eval/py/prelude.py +2 -2
- package/src/eval/py/runner-artifact.ts +84 -0
- package/src/eval/py/tool-bridge.ts +34 -18
- package/src/extensibility/extensions/runner.ts +4 -0
- package/src/extensibility/extensions/types.ts +42 -4
- package/src/extensibility/plugins/marketplace/fetcher.ts +191 -7
- package/src/extensibility/shared-events.ts +5 -0
- package/src/extensibility/skc-plugins/runtime-adapters.ts +2 -1
- package/src/hooks/native-skill-hook.ts +17 -4
- package/src/internal-urls/docs-index.generated.ts +17 -16
- package/src/internal-urls/local-protocol.ts +87 -25
- package/src/internal-urls/local-root-gc.ts +127 -0
- package/src/internal-urls/mcp-protocol.ts +73 -11
- package/src/main.ts +120 -42
- package/src/memories/index.ts +10 -0
- package/src/modes/DESIGN.md +52 -0
- package/src/modes/acp/acp-agent.ts +647 -83
- package/src/modes/acp/acp-event-mapper.ts +106 -12
- package/src/modes/acp/acp-mode.ts +39 -3
- package/src/modes/action-registry.ts +1 -1
- package/src/modes/components/assistant-message.ts +123 -22
- package/src/modes/components/btw-panel.ts +82 -16
- package/src/modes/components/irc-sidebar.ts +176 -62
- package/src/modes/components/model-selector.ts +61 -4
- package/src/modes/components/notifications-settings-editor.ts +1 -1
- package/src/modes/components/oauth-selector.ts +42 -12
- package/src/modes/components/plan-preview-overlay.ts +1 -1
- package/src/modes/components/queue-pane.ts +55 -9
- package/src/modes/components/queued-message-selector.ts +53 -10
- package/src/modes/components/read-tool-group.ts +82 -14
- package/src/modes/components/runtime-mcp-add-wizard.ts +5 -0
- package/src/modes/components/sayknow-pet-widget.ts +20 -8
- package/src/modes/components/session-observer-overlay.ts +187 -32
- package/src/modes/components/settings-selector.ts +60 -18
- package/src/modes/components/tool-execution.ts +138 -27
- package/src/modes/components/tool-status-header.ts +26 -8
- package/src/modes/components/welcome.ts +50 -23
- package/src/modes/controllers/btw-controller.ts +119 -36
- package/src/modes/controllers/command-controller.ts +101 -54
- package/src/modes/controllers/event-controller.ts +119 -27
- package/src/modes/controllers/extension-ui-controller.ts +23 -12
- package/src/modes/controllers/input-controller.ts +100 -8
- package/src/modes/controllers/runtime-mcp-command-controller.ts +29 -6
- package/src/modes/controllers/selector-controller.ts +4 -1
- package/src/modes/interactive-mode.ts +201 -60
- package/src/modes/irc-observation-ledger.ts +71 -15
- package/src/modes/prompt-action-autocomplete.ts +32 -13
- package/src/modes/prompt-suggestion-controller.ts +96 -0
- package/src/modes/runtime-init.ts +20 -2
- package/src/modes/shared/agent-wire/command-dispatch.ts +3 -3
- package/src/modes/shared/agent-wire/workflow-gate-broker.ts +2 -2
- package/src/modes/types.ts +6 -0
- package/src/modes/utils/hotkeys-markdown.ts +64 -36
- package/src/modes/utils/ui-helpers.ts +99 -4
- package/src/prompts/agent-fragments/restricted-bash.md +1 -1
- package/src/prompts/agents/architect.md +17 -3
- package/src/prompts/agents/critic.md +17 -2
- package/src/prompts/agents/executor.md +1 -1
- package/src/prompts/agents/planner.md +8 -1
- package/src/prompts/system/btw-user.md +3 -8
- package/src/prompts/system/prompt-suggestion-system.md +32 -0
- package/src/prompts/system/system-prompt.md +6 -3
- package/src/prompts/tools/cron.md +3 -1
- package/src/prompts/tools/read.md +4 -2
- package/src/prompts/tools/skill-discovery.md +1 -0
- package/src/runtime/memory-domain.ts +66 -0
- package/src/runtime/memory-guard-contract.ts +73 -0
- package/src/runtime/memory-guard.ts +292 -0
- package/src/runtime/memory-limit.ts +50 -0
- package/src/runtime-mcp/client.ts +41 -55
- package/src/runtime-mcp/content-limits.ts +71 -0
- package/src/runtime-mcp/discoverable-tool-metadata.ts +1 -1
- package/src/runtime-mcp/json-rpc.ts +28 -11
- package/src/runtime-mcp/manager.ts +77 -59
- package/src/runtime-mcp/oauth-flow.ts +0 -72
- package/src/runtime-mcp/plugin-network-boundary.ts +101 -0
- package/src/runtime-mcp/redaction.ts +30 -0
- package/src/runtime-mcp/smithery-auth.ts +17 -2
- package/src/runtime-mcp/smithery-connect.ts +11 -1
- package/src/runtime-mcp/transports/http.ts +63 -22
- package/src/sdk/acp/adapter.ts +8 -1
- package/src/sdk/acp/final-text.ts +40 -0
- package/src/sdk/acp/mcp.ts +26 -0
- package/src/sdk/broker/broker.ts +34 -20
- package/src/sdk/broker/identity.ts +22 -12
- package/src/sdk/broker/lifecycle.ts +293 -43
- package/src/sdk/broker/session-index.ts +11 -1
- package/src/sdk/bus/chat-daemon-cli.ts +2 -2
- package/src/sdk/bus/chat-daemon-control.ts +22 -5
- package/src/sdk/bus/config-commands.ts +2 -2
- package/src/sdk/bus/config.ts +10 -2
- package/src/sdk/bus/control-drain-lease.ts +104 -0
- package/src/sdk/bus/conversation-store.ts +40 -6
- package/src/sdk/bus/daemon-paths.ts +2 -0
- package/src/sdk/bus/index.ts +793 -121
- package/src/sdk/bus/kind-aware-reconciliation.ts +242 -0
- package/src/sdk/bus/lifecycle-commands.ts +63 -10
- package/src/sdk/bus/lifecycle-control-runtime.ts +11 -2
- package/src/sdk/bus/lifecycle-orchestrator.ts +32 -1
- package/src/sdk/bus/notification-orchestration.ts +12 -0
- package/src/sdk/bus/notification-service.ts +87 -25
- package/src/sdk/bus/operator-runtime.ts +31 -5
- package/src/sdk/bus/prompt-reconciliation.ts +240 -0
- package/src/sdk/bus/rate-limit-pool.ts +8 -0
- package/src/sdk/bus/recent-activity.ts +90 -26
- package/src/sdk/bus/reconciliation-store.ts +224 -0
- package/src/sdk/bus/telegram-cli.ts +6 -13
- package/src/sdk/bus/telegram-daemon-cli.ts +8 -3
- package/src/sdk/bus/telegram-daemon-contract.ts +34 -9
- package/src/sdk/bus/telegram-daemon-control.ts +161 -40
- package/src/sdk/bus/telegram-daemon.ts +3649 -593
- package/src/sdk/bus/telegram-reference.ts +20 -2
- package/src/sdk/bus/topic-registry.ts +451 -12
- package/src/sdk/cli/session-cli.ts +15 -2
- package/src/sdk/client/discovery.ts +19 -3
- package/src/sdk/client/liveness.ts +49 -0
- package/src/sdk/host/control/dispatch.ts +8 -2
- package/src/sdk/host/control/operations.ts +3 -2
- package/src/sdk/host/host.ts +27 -9
- package/src/sdk/host/query/handlers.ts +125 -5
- package/src/sdk/index.ts +12 -0
- package/src/sdk/lifecycle-session.ts +19 -3
- package/src/sdk/mcp/server.ts +46 -18
- package/src/sdk/prompt-status.ts +97 -0
- package/src/sdk/protocol/operation-inventory.generated.json +145 -0
- package/src/sdk/protocol/operation-registry.ts +24 -4
- package/src/sdk/session-directory.ts +5 -1
- package/src/sdk/session.ts +69 -8
- package/src/sdk/startup-capability.ts +15 -1
- package/src/sdk/transport/auth-preface.ts +82 -0
- package/src/sdk/transport/index.ts +18 -0
- package/src/sdk/transport/relay.ts +252 -0
- package/src/sdk/transport/serve-cli.ts +105 -0
- package/src/sdk/transport/socket.ts +197 -0
- package/src/sdk/transport/stdio.ts +17 -0
- package/src/session/agent-session.ts +1112 -314
- package/src/session/blob-store.ts +25 -7
- package/src/session/btw-contract.ts +59 -0
- package/src/session/fallback-chain-controller.ts +47 -8
- package/src/session/internal/managed-session-scope.ts +1426 -259
- package/src/session/internal/managed-session-storage.ts +414 -238
- package/src/session/internal/native-publish-outcome.ts +271 -0
- package/src/session/memory-guard-checkpoint-participant.ts +131 -0
- package/src/session/session-manager.ts +2079 -469
- package/src/session/session-storage.ts +151 -11
- package/src/session/streaming-output.ts +262 -43
- package/src/setup/credential-import.ts +28 -3
- package/src/setup/provider-onboarding.ts +49 -5
- package/src/setup/provider-presets.json +2 -1
- package/src/skc-runtime/deep-interview-runtime.ts +303 -36
- package/src/skc-runtime/deep-interview-stage.ts +1016 -0
- package/src/skc-runtime/deep-interview-state.ts +8 -5
- package/src/skc-runtime/gc-render.ts +1 -0
- package/src/skc-runtime/gc-runtime.ts +11 -1
- package/src/skc-runtime/linux-proc.ts +70 -36
- package/src/skc-runtime/managed-owner-supervisor.ts +83 -4
- package/src/skc-runtime/memory-guard-owner-claims.ts +389 -0
- package/src/skc-runtime/ralplan-runtime.ts +1057 -75
- package/src/skc-runtime/repository-binding.ts +267 -0
- package/src/skc-runtime/session-state-sidecar.ts +25 -9
- package/src/skc-runtime/state-runtime.ts +50 -12
- package/src/skc-runtime/state-writer.ts +68 -56
- package/src/skc-runtime/team-launch.ts +34 -5
- package/src/skc-runtime/team-runtime.ts +41 -1
- package/src/skc-runtime/team-store.ts +32 -0
- package/src/skc-runtime/team-worker-memory-guard.ts +363 -0
- package/src/skc-runtime/team-workers.ts +1 -0
- package/src/skc-runtime/tmux-common.ts +13 -2
- package/src/skc-runtime/tmux-owner-isolation.ts +20 -1
- package/src/skc-runtime/tmux-sessions.ts +45 -6
- package/src/skc-runtime/ultragoal-guard.ts +93 -15
- package/src/skc-runtime/ultragoal-receipt-freshness.ts +123 -0
- package/src/skc-runtime/ultragoal-runtime.ts +469 -38
- package/src/skc-runtime/workflow-manifest.generated.json +195 -5
- package/src/skc-runtime/workflow-manifest.ts +67 -3
- package/src/skill-state/workflow-hud.ts +25 -2
- package/src/skill-state/workflow-mutation-guard.ts +104 -12
- package/src/slash-commands/builtin-registry.ts +1 -1
- package/src/ssh/utils.ts +14 -0
- package/src/task/discovery.ts +8 -2
- package/src/task/executor.ts +165 -47
- package/src/task/index.ts +123 -15
- package/src/task/provider-retry-status.ts +88 -0
- package/src/task/receipt.ts +3 -0
- package/src/task/render.ts +45 -26
- package/src/task/skc-command.ts +2 -2
- package/src/task/types.ts +55 -10
- package/src/task/ultragoal-redteam-activation.ts +75 -0
- package/src/tools/ask.ts +1 -1
- package/src/tools/ast-edit.ts +2 -2
- package/src/tools/bash-allowed-prefixes.ts +45 -1
- package/src/tools/bash-pty-selection.ts +2 -2
- package/src/tools/browser/launch.ts +41 -6
- package/src/tools/browser/screenshot-format.ts +6 -1
- package/src/tools/cron.ts +1 -1
- package/src/tools/fetch.ts +127 -154
- package/src/tools/image-gen.ts +476 -23
- package/src/tools/index.ts +7 -1
- package/src/tools/output-meta.ts +176 -9
- package/src/tools/path-utils.ts +5 -1
- package/src/tools/read-internals.ts +44 -0
- package/src/tools/read.ts +1544 -310
- package/src/tools/resource-gc.ts +665 -125
- package/src/tools/skill-discovery.ts +39 -3
- package/src/tools/sqlite-reader.ts +63 -5
- package/src/tools/subagent-render.ts +74 -16
- package/src/tools/subagent.ts +2 -0
- package/src/tools/tool-result.ts +14 -1
- package/src/utils/edit-mode.ts +2 -2
- package/src/utils/pasted-image-path.ts +15 -6
- package/src/utils/prompt-suggestion.ts +265 -0
- package/src/utils/shell-snapshot.ts +173 -63
- package/src/utils/sixel.ts +3 -3
- package/src/web/insane/bridge.ts +5 -1
- package/src/web/insane/url-guard.ts +140 -27
- package/src/web/scrapers/docs-rs.ts +30 -5
- package/src/web/scrapers/types.ts +19 -49
- package/src/web/scrapers/utils.ts +12 -26
- package/src/web/search/providers/codex.ts +1 -1
- package/src/workflow/workflow-intent-diff.ts +4 -1
|
@@ -96,7 +96,6 @@ export interface GuardedStateWriterOptions extends StateWriterOptions {
|
|
|
96
96
|
policy: StateWritePolicy;
|
|
97
97
|
expectedRevision?: number;
|
|
98
98
|
sourceRevision?: number;
|
|
99
|
-
lockHeld?: boolean;
|
|
100
99
|
}
|
|
101
100
|
|
|
102
101
|
export type GuardedWriteResult =
|
|
@@ -114,6 +113,11 @@ export interface StateWriterOptions {
|
|
|
114
113
|
* `withFileLock` defaults.
|
|
115
114
|
*/
|
|
116
115
|
lock?: FileLockOptions;
|
|
116
|
+
/**
|
|
117
|
+
* Caller already holds the workflow state lock for this target path (via
|
|
118
|
+
* `withWorkflowStateLock`). Skip re-acquisition to avoid self-deadlock.
|
|
119
|
+
*/
|
|
120
|
+
lockHeld?: boolean;
|
|
117
121
|
}
|
|
118
122
|
|
|
119
123
|
export class StateWriteConflictError extends Error {
|
|
@@ -681,63 +685,71 @@ export async function writeWorkflowEnvelopeAtomic(
|
|
|
681
685
|
options?: StateWriterOptions,
|
|
682
686
|
): Promise<string> {
|
|
683
687
|
const filePath = resolveSkcTarget(targetPath, cwdForOptions(options));
|
|
684
|
-
const
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
692
|
-
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
|
|
713
|
-
|
|
714
|
-
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
|
|
726
|
-
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
|
|
733
|
-
|
|
734
|
-
|
|
688
|
+
const write = async (): Promise<string> => {
|
|
689
|
+
const withReceipt = withWorkflowReceipt(value, buildReceipt(options));
|
|
690
|
+
const stamped = stampWorkflowEnvelopeChecksum(withReceipt, filePath);
|
|
691
|
+
const parsed = RequiredOnWriteEnvelopeSchema.safeParse(stamped);
|
|
692
|
+
if (!parsed.success) {
|
|
693
|
+
throw new Error(
|
|
694
|
+
`Refusing to write invalid workflow state envelope to ${filePath}: ${parsed.error.issues
|
|
695
|
+
.map(issue => `${issue.path.join(".") || "<root>"}: ${issue.message}`)
|
|
696
|
+
.join("; ")}`,
|
|
697
|
+
);
|
|
698
|
+
}
|
|
699
|
+
// #658: internal runtime writers (ralplan/ultragoal/deep-interview/team) persist
|
|
700
|
+
// envelopes directly, bypassing the `skc state` CLI transition gate (`isValidTransition`,
|
|
701
|
+
// historically the sole call site in state-runtime.ts). Re-assert that gate on every
|
|
702
|
+
// sanctioned envelope write so internal writes cannot persist invalid state-machine phase
|
|
703
|
+
// transitions silently. Forced writes (`skc state ... --force`, reconcile repairs) carry
|
|
704
|
+
// `audit.forced` and bypass, mirroring the CLI's `use --force to bypass`.
|
|
705
|
+
//
|
|
706
|
+
// The gate governs ACTIVE workflow progression only. Deactivation/teardown writes
|
|
707
|
+
// (`active: false`, e.g. `skc state clear`, which persists the universal `complete`
|
|
708
|
+
// sentinel that is not a per-skill manifest state) leave the transition graph and are
|
|
709
|
+
// intentionally exempt.
|
|
710
|
+
if (options?.audit?.forced !== true && parsed.data.active === true) {
|
|
711
|
+
const toPhase = parsed.data.current_phase.trim();
|
|
712
|
+
if (toPhase) {
|
|
713
|
+
// Lazy import: workflow-manifest dereferences CANONICAL_SKC_WORKFLOW_SKILLS at
|
|
714
|
+
// module load, and active-state -> state-writer -> workflow-manifest -> active-state
|
|
715
|
+
// is a load-time cycle. Importing at call time (after init) avoids the TDZ.
|
|
716
|
+
const { isKnownWorkflowState, isValidTransition } = await import("./workflow-manifest");
|
|
717
|
+
const skill = parsed.data.skill;
|
|
718
|
+
// Structural invariant (hard): a `current_phase` absent from the skill's manifest is
|
|
719
|
+
// never a legitimate internal write, matching the CLI/reconcile unknown-phase gate.
|
|
720
|
+
if (!isKnownWorkflowState(skill, toPhase)) {
|
|
721
|
+
throw new Error(
|
|
722
|
+
`Refusing to write unknown ${skill} phase "${toPhase}" to ${filePath}: not a known ${skill} manifest state (forced writes bypass via audit.forced)`,
|
|
723
|
+
);
|
|
724
|
+
}
|
|
725
|
+
// Transition invariant (#658, diagnostic-only safety net): resolve the prior phase
|
|
726
|
+
// (caller-supplied `audit.fromPhase`, else the active persisted envelope on disk) and
|
|
727
|
+
// flag edges the manifest does not define. Intentionally NON-blocking and audit-only
|
|
728
|
+
// — the CLI path already hard-fails invalid edges before reaching here, and legitimate
|
|
729
|
+
// internal repairs / ralplan short-mode stage skips move between valid states without a
|
|
730
|
+
// direct manifest edge. It records an `invalid_transition_detected` audit entry (no
|
|
731
|
+
// stderr) so such transitions are non-silent without breaking those flows.
|
|
732
|
+
const fromPhase = (options?.audit?.fromPhase ?? (await readPersistedPhase(filePath)))?.trim();
|
|
733
|
+
if (
|
|
734
|
+
fromPhase &&
|
|
735
|
+
fromPhase !== toPhase &&
|
|
736
|
+
isKnownWorkflowState(skill, fromPhase) &&
|
|
737
|
+
!isValidTransition(skill, fromPhase, toPhase)
|
|
738
|
+
) {
|
|
739
|
+
await recordInvalidWorkflowTransition({ filePath, skill, fromPhase, toPhase, options });
|
|
740
|
+
}
|
|
735
741
|
}
|
|
736
742
|
}
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
743
|
+
await atomicWrite(filePath, jsonText(stamped));
|
|
744
|
+
await maybeAudit(filePath, options);
|
|
745
|
+
return filePath;
|
|
746
|
+
};
|
|
747
|
+
// Serialize with every other writer of the same state path. Without this, a
|
|
748
|
+
// revision-preserving envelope write (seed/spec persistence) can interleave
|
|
749
|
+
// inside a staged apply's check-then-write window and be silently overwritten
|
|
750
|
+
// (#3387 architect finding 1). Callers already inside `withWorkflowStateLock`
|
|
751
|
+
// for this path pass `lockHeld: true`.
|
|
752
|
+
return options?.lockHeld ? write() : lockResolvedWorkflowTarget(filePath, write, options?.lock);
|
|
741
753
|
}
|
|
742
754
|
|
|
743
755
|
export async function writeTextAtomic(targetPath: string, text: string, options?: StateWriterOptions): Promise<string> {
|
|
@@ -12,6 +12,7 @@ import type {
|
|
|
12
12
|
SkcTeamWorkerLifecycle,
|
|
13
13
|
SkcTeamWorktreeMode,
|
|
14
14
|
} from "./team-runtime";
|
|
15
|
+
import { createInitialSkcTeamWorkerMemoryGuardLedger, workerMemoryGuardLedgerPath } from "./team-worker-memory-guard";
|
|
15
16
|
|
|
16
17
|
/** Launch-specific option wiring kept separate from runtime dispatch. */
|
|
17
18
|
export function withTeamLaunchTransport(
|
|
@@ -34,6 +35,7 @@ export function buildWorkerCommand(
|
|
|
34
35
|
config: SkcTeamConfig,
|
|
35
36
|
worker: SkcTeamWorker,
|
|
36
37
|
platform: NodeJS.Platform = process.platform,
|
|
38
|
+
promptOverride?: string,
|
|
37
39
|
): string {
|
|
38
40
|
const quote = platform === "win32" ? powershellQuote : shellQuote;
|
|
39
41
|
const envAssignment = (key: string, value: string): string =>
|
|
@@ -41,7 +43,8 @@ export function buildWorkerCommand(
|
|
|
41
43
|
const workspace = worker.worktree_path
|
|
42
44
|
? `Worker worktree: ${worker.worktree_path}.`
|
|
43
45
|
: `Worker cwd: ${config.leader.cwd}.`;
|
|
44
|
-
const
|
|
46
|
+
const initialPrompt =
|
|
47
|
+
promptOverride ??
|
|
45
48
|
[
|
|
46
49
|
`You are ${worker.id} in skc team ${config.team_name}.`,
|
|
47
50
|
`Team state root: ${config.state_root}.`,
|
|
@@ -50,8 +53,9 @@ export function buildWorkerCommand(
|
|
|
50
53
|
"Before implementation, claim your worker-owned task and treat the claimed task record as the source of truth. Do not implement directly from the broad team brief.",
|
|
51
54
|
`Before claiming work, send startup ACK: skc team api worker-startup-ack --input '{"team_name":"${config.team_name}","worker_id":"${worker.id}","protocol_version":"1"}' --json.`,
|
|
52
55
|
"Use skc team api update-worker-status to report task-local activity, then claim-task/transition-task-status with this worker id; keep heartbeat current during long work, record completion_evidence (summary plus a passed command or verified inspection/artifact item) before completed, and do not mutate leader-owned goal state.",
|
|
53
|
-
]
|
|
54
|
-
|
|
56
|
+
].join("\n");
|
|
57
|
+
const prompt =
|
|
58
|
+
initialPrompt
|
|
55
59
|
.replace(/[\uFEFF\u200B]/g, "")
|
|
56
60
|
.replace(/\r?\n+/g, " ")
|
|
57
61
|
.trim() || `Worker ${worker.id} ready.`;
|
|
@@ -66,6 +70,10 @@ export function buildWorkerCommand(
|
|
|
66
70
|
envAssignment("SKC_TEAM_DISPLAY_NAME", config.display_name),
|
|
67
71
|
envAssignment(SPAWN_PROVENANCE_ENV, config.leader.session_id.trim() || config.team_name),
|
|
68
72
|
...(worker.worktree_path ? [envAssignment("SKC_TEAM_WORKTREE_PATH", worker.worktree_path)] : []),
|
|
73
|
+
envAssignment(
|
|
74
|
+
"SKC_TEAM_WORKER_MEMORY_GUARD_PATH",
|
|
75
|
+
workerMemoryGuardLedgerPath(path.join(config.state_root, config.team_name), worker.id),
|
|
76
|
+
),
|
|
69
77
|
];
|
|
70
78
|
const joined = envLines.join(" ");
|
|
71
79
|
const clearInheritedSession = config.skc_session_id
|
|
@@ -146,6 +154,7 @@ async function initializeStateDirs(
|
|
|
146
154
|
runtime: SkcTeamLaunchRuntime,
|
|
147
155
|
dir: string,
|
|
148
156
|
workers: SkcTeamWorker[],
|
|
157
|
+
platform: NodeJS.Platform,
|
|
149
158
|
): Promise<void> {
|
|
150
159
|
await fs.mkdir(path.join(dir, "mailbox"), { recursive: true });
|
|
151
160
|
for (const worker of workers) {
|
|
@@ -167,6 +176,14 @@ async function initializeStateDirs(
|
|
|
167
176
|
turn_count: 0,
|
|
168
177
|
alive: true,
|
|
169
178
|
});
|
|
179
|
+
await runtime.writeJson(
|
|
180
|
+
workerMemoryGuardLedgerPath(dir, worker.id),
|
|
181
|
+
createInitialSkcTeamWorkerMemoryGuardLedger({
|
|
182
|
+
workerId: worker.id,
|
|
183
|
+
platform,
|
|
184
|
+
now: runtime.now(),
|
|
185
|
+
}),
|
|
186
|
+
);
|
|
170
187
|
}
|
|
171
188
|
await fs.mkdir(runtime.mailboxDirPath(dir, "leader-fixed"), { recursive: true });
|
|
172
189
|
await runtime.writeJson(runtime.mailboxPath(dir, "leader-fixed"), { messages: [] });
|
|
@@ -217,6 +234,18 @@ export async function startSkcTeamLaunch(
|
|
|
217
234
|
await runtime.rollbackCreatedWorktrees(workers);
|
|
218
235
|
throw error;
|
|
219
236
|
}
|
|
237
|
+
const tasksByOwner = new Map<string, string[]>();
|
|
238
|
+
for (const task of initialTasks) {
|
|
239
|
+
const owner = task.owner?.trim();
|
|
240
|
+
if (!owner) continue;
|
|
241
|
+
const assigned = tasksByOwner.get(owner) ?? [];
|
|
242
|
+
assigned.push(task.id);
|
|
243
|
+
tasksByOwner.set(owner, assigned);
|
|
244
|
+
}
|
|
245
|
+
const workersWithAssignments = workers.map(worker => ({
|
|
246
|
+
...worker,
|
|
247
|
+
assigned_tasks: tasksByOwner.get(worker.id) ?? worker.assigned_tasks,
|
|
248
|
+
}));
|
|
220
249
|
const config: SkcTeamConfig = {
|
|
221
250
|
team_name: teamName,
|
|
222
251
|
display_name: displayName,
|
|
@@ -242,11 +271,11 @@ export async function startSkcTeamLaunch(
|
|
|
242
271
|
},
|
|
243
272
|
leader_cwd: cwd,
|
|
244
273
|
team_state_root: stateRoot,
|
|
245
|
-
workers,
|
|
274
|
+
workers: workersWithAssignments,
|
|
246
275
|
created_at: createdAt,
|
|
247
276
|
updated_at: createdAt,
|
|
248
277
|
};
|
|
249
|
-
await initializeStateDirs(runtime, dir, config.workers);
|
|
278
|
+
await initializeStateDirs(runtime, dir, config.workers, platform);
|
|
250
279
|
await runtime.writeJson(path.join(dir, "config.json"), config);
|
|
251
280
|
await runtime.writeJson(path.join(dir, "manifest.v2.json"), {
|
|
252
281
|
version: 2,
|
|
@@ -455,7 +455,32 @@ export interface WorkerHeartbeatFile {
|
|
|
455
455
|
last_turn_at: string;
|
|
456
456
|
turn_count: number;
|
|
457
457
|
alive: boolean;
|
|
458
|
+
/** Linux process start time, so a recycled PID cannot impersonate this worker. */
|
|
459
|
+
process_start_time?: string;
|
|
458
460
|
}
|
|
461
|
+
/**
|
|
462
|
+
* Linux process start time (field 22 of /proc/<pid>/stat), used to pin a heartbeat
|
|
463
|
+
* to one specific process. PIDs are recycled, so without this a reaper can match a
|
|
464
|
+
* stale record against an unrelated process that later took the same PID.
|
|
465
|
+
* Returns undefined off Linux or when the process is gone.
|
|
466
|
+
*/
|
|
467
|
+
async function readLinuxProcessStartTime(pid: number): Promise<string | undefined> {
|
|
468
|
+
if (process.platform !== "linux" || !Number.isSafeInteger(pid) || pid <= 0) return undefined;
|
|
469
|
+
try {
|
|
470
|
+
const stat = await Bun.file(`/proc/${pid}/stat`).text();
|
|
471
|
+
const commandEnd = stat.lastIndexOf(")");
|
|
472
|
+
if (commandEnd < 0) return undefined;
|
|
473
|
+
const fields = stat
|
|
474
|
+
.slice(commandEnd + 2)
|
|
475
|
+
.trim()
|
|
476
|
+
.split(/\s+/);
|
|
477
|
+
const startTime = fields[19];
|
|
478
|
+
return startTime && /^\d+$/.test(startTime) ? startTime : undefined;
|
|
479
|
+
} catch {
|
|
480
|
+
return undefined;
|
|
481
|
+
}
|
|
482
|
+
}
|
|
483
|
+
|
|
459
484
|
interface GitResult {
|
|
460
485
|
ok: boolean;
|
|
461
486
|
stdout: string;
|
|
@@ -491,7 +516,7 @@ interface SkcWorkerIntegrationDedupeState {
|
|
|
491
516
|
|
|
492
517
|
export interface SkcWorkerIntegrationAttemptRequestResult {
|
|
493
518
|
requested: boolean;
|
|
494
|
-
reason: "requested" | "not_worker" | "missing_worktree" | "no_changes" | "deduped" | "git_error";
|
|
519
|
+
reason: "requested" | "not_worker" | "missing_worktree" | "no_changes" | "deduped" | "git_error" | "cancelled";
|
|
495
520
|
worker?: string;
|
|
496
521
|
team_name?: string;
|
|
497
522
|
fingerprint?: string;
|
|
@@ -499,6 +524,12 @@ export interface SkcWorkerIntegrationAttemptRequestResult {
|
|
|
499
524
|
status?: SkcWorkerCheckpointClassification["kind"];
|
|
500
525
|
}
|
|
501
526
|
|
|
527
|
+
/** Caller-supplied controls for a worker integration attempt. */
|
|
528
|
+
export interface SkcWorkerIntegrationAttemptOptions {
|
|
529
|
+
/** Abort the attempt between its blocking git probes. */
|
|
530
|
+
signal?: AbortSignal;
|
|
531
|
+
}
|
|
532
|
+
|
|
502
533
|
function isSkcTeamTaskStatus(value: string): value is SkcTeamTaskStatus {
|
|
503
534
|
return ["pending", "blocked", "in_progress", "completed", "failed"].includes(value);
|
|
504
535
|
}
|
|
@@ -2973,7 +3004,13 @@ function workerIntegrationFingerprint(head: string | null, classification: SkcWo
|
|
|
2973
3004
|
export async function requestSkcWorkerIntegrationAttempt(
|
|
2974
3005
|
cwd = process.cwd(),
|
|
2975
3006
|
env: NodeJS.ProcessEnv = process.env,
|
|
3007
|
+
options: SkcWorkerIntegrationAttemptOptions = {},
|
|
2976
3008
|
): Promise<SkcWorkerIntegrationAttemptRequestResult> {
|
|
3009
|
+
// The probes below shell out to git, which can block for a long time on a large
|
|
3010
|
+
// or network-backed worktree. The caller (session shutdown) needs to stop waiting,
|
|
3011
|
+
// so bail at each boundary instead of running to completion regardless.
|
|
3012
|
+
const cancelled = (): SkcWorkerIntegrationAttemptRequestResult => ({ requested: false, reason: "cancelled" });
|
|
3013
|
+
if (options.signal?.aborted) return cancelled();
|
|
2977
3014
|
const teamName = env.SKC_TEAM_NAME?.trim();
|
|
2978
3015
|
const worker = env.SKC_TEAM_WORKER_ID?.trim() || env.SKC_TEAM_INTERNAL_WORKER?.split("/").pop()?.trim();
|
|
2979
3016
|
if (!teamName || !worker) return { requested: false, reason: "not_worker" };
|
|
@@ -2983,7 +3020,9 @@ export async function requestSkcWorkerIntegrationAttempt(
|
|
|
2983
3020
|
const worktreePath = env.SKC_TEAM_WORKTREE_PATH?.trim() || configuredWorker?.worktree_path;
|
|
2984
3021
|
if (!worktreePath || !(await pathExists(worktreePath)))
|
|
2985
3022
|
return { requested: false, reason: "missing_worktree", worker, team_name: teamName };
|
|
3023
|
+
if (options.signal?.aborted) return cancelled();
|
|
2986
3024
|
const classification = classifyWorkerCheckpointStatus(worktreePath);
|
|
3025
|
+
if (options.signal?.aborted) return cancelled();
|
|
2987
3026
|
const head = resolveHead(worktreePath);
|
|
2988
3027
|
if (classification.kind === "git_error") {
|
|
2989
3028
|
return { requested: false, reason: "git_error", worker, team_name: teamName, head, status: classification.kind };
|
|
@@ -4346,6 +4385,7 @@ export async function executeSkcTeamApiOperation(
|
|
|
4346
4385
|
last_turn_at: now(),
|
|
4347
4386
|
turn_count: Number(input.turn_count ?? 0),
|
|
4348
4387
|
alive: Boolean(input.alive ?? true),
|
|
4388
|
+
process_start_time: await readLinuxProcessStartTime(Number(input.pid ?? 0)),
|
|
4349
4389
|
},
|
|
4350
4390
|
cwd,
|
|
4351
4391
|
env,
|
|
@@ -126,6 +126,38 @@ export interface SkcTeamApiClaimResult {
|
|
|
126
126
|
claim_token?: string;
|
|
127
127
|
reason?: string;
|
|
128
128
|
}
|
|
129
|
+
export type SkcTeamWorkerClaimSelection =
|
|
130
|
+
| { kind: "none" }
|
|
131
|
+
| { kind: "exact"; task: SkcTeamTask; claim: SkcTeamTaskClaim }
|
|
132
|
+
| { kind: "ambiguous"; tasks: SkcTeamTask[] };
|
|
133
|
+
|
|
134
|
+
export function selectCurrentClaimedTaskForWorker(
|
|
135
|
+
tasks: readonly SkcTeamTask[],
|
|
136
|
+
workerId: string,
|
|
137
|
+
): SkcTeamWorkerClaimSelection {
|
|
138
|
+
const claimed = tasks.filter(
|
|
139
|
+
task =>
|
|
140
|
+
task.status === "in_progress" &&
|
|
141
|
+
task.assignee === workerId &&
|
|
142
|
+
task.claim?.owner === workerId &&
|
|
143
|
+
task.owner === workerId,
|
|
144
|
+
);
|
|
145
|
+
if (claimed.length === 0) return { kind: "none" };
|
|
146
|
+
if (claimed.length === 1) {
|
|
147
|
+
const task = claimed[0]!;
|
|
148
|
+
return { kind: "exact", task, claim: task.claim! };
|
|
149
|
+
}
|
|
150
|
+
return { kind: "ambiguous", tasks: claimed };
|
|
151
|
+
}
|
|
152
|
+
export function findSkcTeamClaimedTaskForWorker(
|
|
153
|
+
tasks: readonly SkcTeamTask[],
|
|
154
|
+
workerId: string,
|
|
155
|
+
): SkcTeamTask | undefined {
|
|
156
|
+
const active = selectCurrentClaimedTaskForWorker(tasks, workerId);
|
|
157
|
+
if (active.kind === "exact") return active.task;
|
|
158
|
+
if (active.kind === "ambiguous") return undefined;
|
|
159
|
+
return tasks.find(task => task.status === "blocked" && task.assignee === workerId && task.claim?.owner === workerId);
|
|
160
|
+
}
|
|
129
161
|
|
|
130
162
|
type EventAppender = (event: {
|
|
131
163
|
type: string;
|