@duckmind/dm-windows-x64 0.61.4 → 0.61.9
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/dm.exe +0 -0
- package/extensions/.dm-extensions.json +211 -67
- package/extensions/dm-subagents/agents/claude-code-writer.md +15 -0
- package/extensions/dm-subagents/agents/claude-code.md +15 -0
- package/extensions/dm-subagents/agents/codex-exec-writer.md +15 -0
- package/extensions/dm-subagents/agents/codex-exec.md +15 -0
- package/extensions/dm-subagents/agents/cursor-agent-writer.md +14 -0
- package/extensions/dm-subagents/agents/cursor-agent.md +14 -0
- package/extensions/dm-subagents/agents/delegate.md +3 -2
- package/extensions/dm-subagents/agents/oracle.md +10 -5
- package/extensions/dm-subagents/agents/researcher.md +2 -2
- package/extensions/dm-subagents/agents/reviewer.md +17 -7
- package/extensions/dm-subagents/agents/scout.md +5 -5
- package/extensions/dm-subagents/agents/worker.md +6 -2
- package/extensions/dm-subagents/async-retention-discovery-worker.mjs +167 -0
- package/extensions/dm-subagents/index.js +4 -0
- package/extensions/dm-subagents/inspector-runner.mjs +10 -0
- package/extensions/dm-subagents/install.mjs +3 -2
- package/extensions/dm-subagents/package.json +2 -2
- package/extensions/dm-subagents/prompts/council.md +60 -0
- package/extensions/dm-subagents/prompts/parallel-review.md +5 -1
- package/extensions/dm-subagents/prompts/review-loop.md +13 -7
- package/extensions/dm-subagents/skills/council-mode/SKILL.md +59 -0
- package/extensions/dm-subagents/skills/council-mode/references/pass-contracts.md +150 -0
- package/extensions/dm-subagents/skills/dm-subagents/SKILL.md +96 -911
- package/extensions/dm-subagents/skills/dm-subagents/references/constraints-and-recipes.md +70 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/execution-controls.md +539 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/management-authoring-rpc.md +161 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/multi-lane-orchestration.md +51 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/prompting-and-roles.md +295 -0
- package/extensions/dm-subagents/skills/dm-subagents/references/review-and-validation.md +73 -0
- package/extensions/dm-subagents/src/agents/agent-management.js +716 -484
- package/extensions/dm-subagents/src/agents/agent-refinements.js +563 -0
- package/extensions/dm-subagents/src/agents/agent-serializer.js +70 -5
- package/extensions/dm-subagents/src/agents/agents.js +1447 -299
- package/extensions/dm-subagents/src/agents/builtin-names.js +15 -0
- package/extensions/dm-subagents/src/agents/chain-serializer.js +12 -7
- package/extensions/dm-subagents/src/agents/frontmatter.js +64 -14
- package/extensions/dm-subagents/src/agents/identity.js +1 -1
- package/extensions/dm-subagents/src/agents/proactive-skills.js +14 -11
- package/extensions/dm-subagents/src/agents/runtime-agent-events.js +49 -0
- package/extensions/dm-subagents/src/agents/runtime-agent-registry.js +412 -0
- package/extensions/dm-subagents/src/agents/skills.js +52 -35
- package/extensions/dm-subagents/src/api/agents.js +6 -0
- package/extensions/dm-subagents/src/api/background-work.js +151 -0
- package/extensions/dm-subagents/src/api/capability-ceiling.js +12 -0
- package/extensions/dm-subagents/src/api/control-channel.js +3 -0
- package/extensions/dm-subagents/src/api/delegation.js +5 -0
- package/extensions/dm-subagents/src/api/dm-args.js +3 -0
- package/extensions/dm-subagents/src/api/external-job-provider.js +137 -0
- package/extensions/dm-subagents/src/api/external-runs.js +233 -0
- package/extensions/dm-subagents/src/api/intercom-bridge.js +3 -0
- package/extensions/dm-subagents/src/api/preflight.js +322 -0
- package/extensions/dm-subagents/src/api/project-panes.js +11 -0
- package/extensions/dm-subagents/src/api/shared-types.js +4 -0
- package/extensions/dm-subagents/src/extension/config.js +175 -0
- package/extensions/dm-subagents/src/extension/control-notices.js +4 -43
- package/extensions/dm-subagents/src/extension/doctor.js +71 -17
- package/extensions/dm-subagents/src/extension/fanout-child.js +49 -32
- package/extensions/dm-subagents/src/extension/index.js +711 -265
- package/extensions/dm-subagents/src/extension/public-execution.js +114 -0
- package/extensions/dm-subagents/src/extension/rpc.js +427 -22
- package/extensions/dm-subagents/src/extension/schemas.js +158 -65
- package/extensions/dm-subagents/src/extension/steering-notices.js +23 -0
- package/extensions/dm-subagents/src/extension/subagent-guide.js +31 -0
- package/extensions/dm-subagents/src/extension/tool-description.js +92 -74
- package/extensions/dm-subagents/src/extension/tool-result.js +7 -0
- package/extensions/dm-subagents/src/inspectors/herdr/actions.js +218 -0
- package/extensions/dm-subagents/src/inspectors/herdr/client.js +123 -0
- package/extensions/dm-subagents/src/inspectors/herdr/focus.js +47 -0
- package/extensions/dm-subagents/src/inspectors/herdr/inspector-runner.js +160 -0
- package/extensions/dm-subagents/src/inspectors/herdr/project-panes.js +618 -0
- package/extensions/dm-subagents/src/inspectors/herdr/session-roots-codec.js +21 -0
- package/extensions/dm-subagents/src/inspectors/herdr/shell-command.js +15 -0
- package/extensions/dm-subagents/src/integrations/herdr-status.js +377 -0
- package/extensions/dm-subagents/src/intercom/intercom-bridge.js +17 -13
- package/extensions/dm-subagents/src/intercom/native-supervisor-channel.js +371 -79
- package/extensions/dm-subagents/src/intercom/result-intercom.js +47 -7
- package/extensions/dm-subagents/src/missions/actions.js +394 -0
- package/extensions/dm-subagents/src/missions/goal-driver.js +149 -0
- package/extensions/dm-subagents/src/missions/lifecycle.js +331 -0
- package/extensions/dm-subagents/src/missions/store.js +548 -0
- package/extensions/dm-subagents/src/missions/types.js +9 -0
- package/extensions/dm-subagents/src/missions/workflow-state.js +245 -0
- package/extensions/dm-subagents/src/policy/authority.js +37 -0
- package/extensions/dm-subagents/src/profiles/profiles.js +36 -18
- package/extensions/dm-subagents/src/runs/background/active-async-capacity.js +427 -0
- package/extensions/dm-subagents/src/runs/background/active-run-index.js +122 -0
- package/extensions/dm-subagents/src/runs/background/async-execution.js +925 -137
- package/extensions/dm-subagents/src/runs/background/async-job-tracker.js +515 -148
- package/extensions/dm-subagents/src/runs/background/async-resume.js +378 -51
- package/extensions/dm-subagents/src/runs/background/async-retention.js +828 -0
- package/extensions/dm-subagents/src/runs/background/async-status-snapshot.js +31 -0
- package/extensions/dm-subagents/src/runs/background/async-status.js +259 -22
- package/extensions/dm-subagents/src/runs/background/auto-drain.js +46 -0
- package/extensions/dm-subagents/src/runs/background/chain-append.js +50 -15
- package/extensions/dm-subagents/src/runs/background/chain-root-attachment.js +67 -12
- package/extensions/dm-subagents/src/runs/background/completion-batcher.js +5 -1
- package/extensions/dm-subagents/src/runs/background/completion-dedupe.js +3 -11
- package/extensions/dm-subagents/src/runs/background/completion-replay.js +245 -0
- package/extensions/dm-subagents/src/runs/background/control-channel.js +423 -36
- package/extensions/dm-subagents/src/runs/background/fleet-view.js +132 -59
- package/extensions/dm-subagents/src/runs/background/index-segment.js +38 -0
- package/extensions/dm-subagents/src/runs/background/inspect-rpc.js +373 -0
- package/extensions/dm-subagents/src/runs/background/notify.js +357 -57
- package/extensions/dm-subagents/src/runs/background/owned-process-tree.js +86 -0
- package/extensions/dm-subagents/src/runs/background/process-terminal.js +269 -0
- package/extensions/dm-subagents/src/runs/background/result-delivery-ownership.js +34 -0
- package/extensions/dm-subagents/src/runs/background/result-files.js +469 -0
- package/extensions/dm-subagents/src/runs/background/result-watcher.js +540 -75
- package/extensions/dm-subagents/src/runs/background/resume-guidance.js +44 -0
- package/extensions/dm-subagents/src/runs/background/retained-children.js +119 -0
- package/extensions/dm-subagents/src/runs/background/run-id-query.js +5 -0
- package/extensions/dm-subagents/src/runs/background/run-id-resolver.js +93 -9
- package/extensions/dm-subagents/src/runs/background/run-status.js +303 -32
- package/extensions/dm-subagents/src/runs/background/scheduled-runs.js +784 -376
- package/extensions/dm-subagents/src/runs/background/stale-run-reconciler.js +75 -34
- package/extensions/dm-subagents/src/runs/background/steering.js +221 -0
- package/extensions/dm-subagents/src/runs/background/subagent-runner.js +3106 -844
- package/extensions/dm-subagents/src/runs/background/subagent-wait.js +529 -0
- package/extensions/dm-subagents/src/runs/background/terminal-run-index.js +106 -0
- package/extensions/dm-subagents/src/runs/background/top-level-async.js +1 -1
- package/extensions/dm-subagents/src/runs/background/wait-completions.js +155 -0
- package/extensions/dm-subagents/src/runs/background/wait-config.js +46 -0
- package/extensions/dm-subagents/src/runs/background/wait-subscriptions.js +278 -0
- package/extensions/dm-subagents/src/runs/background/wait-tool.js +47 -0
- package/extensions/dm-subagents/src/runs/foreground/async-dismiss-action.js +81 -0
- package/extensions/dm-subagents/src/runs/foreground/async-steering-action.js +245 -0
- package/extensions/dm-subagents/src/runs/foreground/async-stop-action.js +74 -0
- package/extensions/dm-subagents/src/runs/foreground/execution.js +1401 -342
- package/extensions/dm-subagents/src/runs/foreground/foreground-control.js +133 -0
- package/extensions/dm-subagents/src/runs/foreground/foreground-history.js +148 -0
- package/extensions/dm-subagents/src/runs/foreground/prompt-audit.js +139 -0
- package/extensions/dm-subagents/src/runs/foreground/subagent-executor.js +4278 -1441
- package/extensions/dm-subagents/src/runs/foreground/workflow-detach-reconcile.js +278 -0
- package/extensions/dm-subagents/src/runs/foreground/workflow-foreground-steering.js +155 -0
- package/extensions/dm-subagents/src/runs/shared/abort-recovery.js +97 -0
- package/extensions/dm-subagents/src/runs/shared/acceptance.js +597 -148
- package/extensions/dm-subagents/src/runs/shared/agent-contract.js +35 -0
- package/extensions/dm-subagents/src/runs/shared/async-status-projection.js +472 -0
- package/extensions/dm-subagents/src/runs/shared/background-process-options.js +6 -0
- package/extensions/dm-subagents/src/runs/shared/capability-ceiling.js +175 -0
- package/extensions/dm-subagents/src/runs/shared/child-identity.js +32 -0
- package/extensions/dm-subagents/src/runs/shared/child-launch-plan.js +65 -0
- package/extensions/dm-subagents/src/runs/shared/child-protocol.js +447 -0
- package/extensions/dm-subagents/src/runs/shared/claude-code-adapter.js +120 -0
- package/extensions/dm-subagents/src/runs/shared/codex-exec-adapter.js +129 -0
- package/extensions/dm-subagents/src/runs/shared/completion-evidence.js +40 -0
- package/extensions/dm-subagents/src/runs/shared/completion-guard.js +140 -83
- package/extensions/dm-subagents/src/runs/shared/context-mode.js +38 -0
- package/extensions/dm-subagents/src/runs/shared/cursor-agent-adapter.js +101 -0
- package/extensions/dm-subagents/src/runs/shared/dm-args.js +445 -72
- package/extensions/dm-subagents/src/runs/shared/dm-spawn.js +27 -16
- package/extensions/dm-subagents/src/runs/shared/dynamic-fanout.js +19 -6
- package/extensions/dm-subagents/src/runs/shared/extension-bindings.js +81 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-contract.js +134 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-preflight.js +98 -0
- package/extensions/dm-subagents/src/runs/shared/external-cli-runner.js +419 -0
- package/extensions/dm-subagents/src/runs/shared/external-job-bridge.js +404 -0
- package/extensions/dm-subagents/src/runs/shared/external-job-runner.js +334 -0
- package/extensions/dm-subagents/src/runs/shared/fast-mode-extension.js +8 -0
- package/extensions/dm-subagents/src/runs/shared/host-step-status.js +228 -0
- package/extensions/dm-subagents/src/runs/shared/lane-metadata.js +104 -0
- package/extensions/dm-subagents/src/runs/shared/launch-cwd.js +17 -0
- package/extensions/dm-subagents/src/runs/shared/llm-intent-arbiter.js +190 -0
- package/extensions/dm-subagents/src/runs/shared/long-running-guard.js +48 -3
- package/extensions/dm-subagents/src/runs/shared/mcp-config-sources.js +387 -0
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-allowlist.js +212 -137
- package/extensions/dm-subagents/src/runs/shared/mcp-direct-tool-grant.js +131 -0
- package/extensions/dm-subagents/src/runs/shared/model-exclusions.js +207 -0
- package/extensions/dm-subagents/src/runs/shared/model-fallback.js +225 -55
- package/extensions/dm-subagents/src/runs/shared/model-scope.js +85 -28
- package/extensions/dm-subagents/src/runs/shared/mutation-evidence.js +182 -0
- package/extensions/dm-subagents/src/runs/shared/nested-events.js +264 -102
- package/extensions/dm-subagents/src/runs/shared/nested-render.js +15 -5
- package/extensions/dm-subagents/src/runs/shared/orca-progress-tabs.js +505 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-handoff.js +653 -0
- package/extensions/dm-subagents/src/runs/shared/parallel-utils.js +29 -12
- package/extensions/dm-subagents/src/runs/shared/permissions.js +108 -0
- package/extensions/dm-subagents/src/runs/shared/process-signal.js +13 -0
- package/extensions/dm-subagents/src/runs/shared/run-fanout-budget.js +257 -0
- package/extensions/dm-subagents/src/runs/shared/run-history.js +133 -13
- package/extensions/dm-subagents/src/runs/shared/runtime-acknowledged-extensions.js +62 -0
- package/extensions/dm-subagents/src/runs/shared/session-lease.js +225 -0
- package/extensions/dm-subagents/src/runs/shared/single-output.js +129 -27
- package/extensions/dm-subagents/src/runs/shared/spawn-budget.js +95 -0
- package/extensions/dm-subagents/src/runs/shared/structured-output.js +129 -10
- package/extensions/dm-subagents/src/runs/shared/subagent-control.js +66 -11
- package/extensions/dm-subagents/src/runs/shared/subagent-prompt-runtime.js +548 -70
- package/extensions/dm-subagents/src/runs/shared/subagent-startup-retry.js +50 -0
- package/extensions/dm-subagents/src/runs/shared/task-intent.js +130 -0
- package/extensions/dm-subagents/src/runs/shared/tool-availability.js +59 -0
- package/extensions/dm-subagents/src/runs/shared/tool-budget.js +7 -5
- package/extensions/dm-subagents/src/runs/shared/tool-timeout.js +64 -0
- package/extensions/dm-subagents/src/runs/shared/usage-budget.js +74 -0
- package/extensions/dm-subagents/src/runs/shared/workflow-graph.js +22 -0
- package/extensions/dm-subagents/src/runs/shared/worktree-cleanup-plan.js +721 -0
- package/extensions/dm-subagents/src/runs/shared/worktree.js +168 -19
- package/extensions/dm-subagents/src/shared/accessible-dir.js +35 -0
- package/extensions/dm-subagents/src/shared/agent-stream-options.js +3 -0
- package/extensions/dm-subagents/src/shared/artifacts.js +170 -11
- package/extensions/dm-subagents/src/shared/atomic-json.js +36 -38
- package/extensions/dm-subagents/src/shared/capacity-resilient-json.js +77 -0
- package/extensions/dm-subagents/src/shared/child-session-name.js +15 -0
- package/extensions/dm-subagents/src/shared/child-transcript.js +57 -2
- package/extensions/dm-subagents/src/shared/completion-owner.js +7 -0
- package/extensions/dm-subagents/src/shared/display-text.js +142 -0
- package/extensions/dm-subagents/src/shared/extension-context.js +17 -0
- package/extensions/dm-subagents/src/shared/file-coalescer.js +9 -0
- package/extensions/dm-subagents/src/shared/file-system-retry.js +56 -0
- package/extensions/dm-subagents/src/shared/fork-context.js +96 -33
- package/extensions/dm-subagents/src/shared/formatters.js +21 -7
- package/extensions/dm-subagents/src/shared/launch-contract.js +94 -0
- package/extensions/dm-subagents/src/shared/model-info.js +10 -5
- package/extensions/dm-subagents/src/shared/node-executable.js +19 -0
- package/extensions/dm-subagents/src/shared/prompt-resources.js +10 -0
- package/extensions/dm-subagents/src/shared/pruned-fork.js +427 -0
- package/extensions/dm-subagents/src/shared/session-file-trust.js +19 -0
- package/extensions/dm-subagents/src/shared/session-tokens.js +14 -3
- package/extensions/dm-subagents/src/shared/settings.js +39 -47
- package/extensions/dm-subagents/src/shared/shortcuts.js +16 -0
- package/extensions/dm-subagents/src/shared/status-format.js +9 -2
- package/extensions/dm-subagents/src/shared/thinking-ceiling.js +41 -0
- package/extensions/dm-subagents/src/shared/types.js +47 -7
- package/extensions/dm-subagents/src/shared/utf8.js +12 -0
- package/extensions/dm-subagents/src/shared/utils.js +151 -131
- package/extensions/dm-subagents/src/shared/watch-strategy.js +3 -0
- package/extensions/dm-subagents/src/shared/workflow-child-permit.js +84 -0
- package/extensions/dm-subagents/src/slash/delegation-adapters.js +274 -0
- package/extensions/dm-subagents/src/slash/delegation-json.js +113 -0
- package/extensions/dm-subagents/src/slash/delegation-request.js +152 -0
- package/extensions/dm-subagents/src/slash/prompt-template-bridge.js +294 -243
- package/extensions/dm-subagents/src/slash/prompt-workflows.js +35 -73
- package/extensions/dm-subagents/src/slash/selector.js +101 -0
- package/extensions/dm-subagents/src/slash/slash-bridge.js +17 -1
- package/extensions/dm-subagents/src/slash/slash-commands.js +722 -732
- package/extensions/dm-subagents/src/slash/slash-live-state.js +37 -19
- package/extensions/dm-subagents/src/slash/subagents-admin.js +410 -0
- package/extensions/dm-subagents/src/tui/fleet-status.js +824 -0
- package/extensions/dm-subagents/src/tui/fleet-transcript.js +479 -0
- package/extensions/dm-subagents/src/tui/fleet.js +1326 -0
- package/extensions/dm-subagents/src/tui/render-helpers.js +22 -0
- package/extensions/dm-subagents/src/tui/render.js +1511 -261
- package/extensions/dm-subagents/src/watchdog/change-signature.js +220 -0
- package/extensions/dm-subagents/src/watchdog/child-status.js +151 -0
- package/extensions/dm-subagents/src/watchdog/emission-guard.js +90 -0
- package/extensions/dm-subagents/src/watchdog/lsp-diagnostics.js +484 -0
- package/extensions/dm-subagents/src/watchdog/model-selection.js +154 -0
- package/extensions/dm-subagents/src/watchdog/permission-arbiter.js +138 -0
- package/extensions/dm-subagents/src/watchdog/register-child.js +112 -0
- package/extensions/dm-subagents/src/watchdog/register-main.js +419 -0
- package/extensions/dm-subagents/src/watchdog/render.js +54 -0
- package/extensions/dm-subagents/src/watchdog/review.js +251 -0
- package/extensions/dm-subagents/src/watchdog/runtime.js +803 -0
- package/extensions/dm-subagents/src/watchdog/scope.js +56 -0
- package/extensions/dm-subagents/src/watchdog/settings.js +515 -0
- package/extensions/dm-subagents/src/watchdog/tool-actions.js +151 -0
- package/extensions/dm-subagents/src/watchdog/turn-delta.js +169 -0
- package/extensions/dm-subagents/src/watchdog/types.js +29 -0
- package/extensions/dm-subagents/src/watchdog/warning-format.js +58 -0
- package/extensions/dm-subagents/src/workflows/chat-progress.js +116 -0
- package/extensions/dm-subagents/src/workflows/host-command.js +227 -0
- package/extensions/dm-subagents/src/workflows/scripted-workflow.js +2011 -0
- package/extensions/dm-subagents/src/workflows/workflow-child-summary.js +116 -0
- package/extensions/dm-subagents/src/workflows/workflow-preflight.js +243 -0
- package/extensions/dm-subagents/src/workflows/workflow-receipt.js +387 -0
- package/extensions/dm-subagents/src/workflows/workflow-settlement.js +189 -0
- package/package.json +4 -3
- package/extensions/dm-fff/package.json +0 -21
- package/extensions/dm-fff/src/index.js +0 -691
- package/extensions/dm-fff/src/query.js +0 -60
- package/extensions/dm-subagents/agents/context-builder.md +0 -46
- package/extensions/dm-subagents/agents/planner.md +0 -55
- package/extensions/dm-subagents/prompts/parallel-context-build.md +0 -55
- package/extensions/dm-subagents/prompts/parallel-handoff-plan.md +0 -61
- package/extensions/dm-subagents/src/runs/background/wait.js +0 -206
- package/extensions/dm-subagents/src/runs/foreground/chain-clarify.js +0 -1013
- package/extensions/dm-subagents/src/runs/foreground/chain-execution.js +0 -981
- package/extensions/dm-subagents/src/runs/shared/turn-budget.js +0 -50
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
export const MISSING_IMPLEMENTATION_MUTATION_MESSAGE = "Subagent completed without making edits for an implementation task.";
|
|
2
|
+
export const MISSING_IMPLEMENTATION_MUTATION_ERROR = `${MISSING_IMPLEMENTATION_MUTATION_MESSAGE}
|
|
3
|
+
It appears to have returned planning or scratchpad output instead of applying changes.`;
|
|
4
|
+
export function planCompletionEvidence(input) {
|
|
5
|
+
const guardBlocked = input.guard?.blocked === true;
|
|
6
|
+
const guardTriggered = input.guardTriggered ?? (input.guard?.triggered === true && !input.mutationAttemptObserved);
|
|
7
|
+
const mutationExpected = input.guard?.expectedMutation ?? (input.completionGuardEnabled && input.mutationCapable && input.implementationMutationExpected);
|
|
8
|
+
const mutationAttempted = input.guard?.attemptedMutation === true || input.mutationAttemptObserved;
|
|
9
|
+
const fileMutation = input.guard ? {
|
|
10
|
+
status: guardBlocked ? "blocked" : input.guard.expectedMutation ? guardTriggered ? "missing" : input.arbiterRescued ? "not-applicable" : "observed" : "not-applicable",
|
|
11
|
+
expected: input.guard.expectedMutation,
|
|
12
|
+
attempted: guardBlocked ? false : mutationAttempted,
|
|
13
|
+
...input.mutationEvidence ? { evidence: input.mutationEvidence } : {},
|
|
14
|
+
...guardBlocked && input.guard.message ? { message: input.guard.message } : {},
|
|
15
|
+
...guardTriggered ? { message: MISSING_IMPLEMENTATION_MUTATION_MESSAGE } : {},
|
|
16
|
+
...input.arbiterRescued ? { resolvedBy: "llm-intent-arbiter" } : {}
|
|
17
|
+
} : undefined;
|
|
18
|
+
return {
|
|
19
|
+
guardTriggered,
|
|
20
|
+
guardBlocked,
|
|
21
|
+
mutationExpected,
|
|
22
|
+
mutationAttempted,
|
|
23
|
+
fileMutation,
|
|
24
|
+
legacyFailureError: guardTriggered && !input.agentContractV1 ? MISSING_IMPLEMENTATION_MUTATION_ERROR : undefined
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
export function projectSettlementDiagnostic(plan, input) {
|
|
28
|
+
if (!input.terminalFailed && !plan.guardTriggered && !plan.guardBlocked)
|
|
29
|
+
return;
|
|
30
|
+
return {
|
|
31
|
+
finalTextPresent: input.finalTextPresent,
|
|
32
|
+
mutation: {
|
|
33
|
+
expected: plan.mutationExpected,
|
|
34
|
+
attempted: plan.mutationAttempted,
|
|
35
|
+
observed: input.mutationObserved
|
|
36
|
+
},
|
|
37
|
+
...input.requiredOutput ? { requiredOutput: input.requiredOutput } : {},
|
|
38
|
+
afterCompactionSettlement: input.afterCompactionSettlement === true
|
|
39
|
+
};
|
|
40
|
+
}
|
|
@@ -1,50 +1,7 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
/\bonly return findings\b/i,
|
|
6
|
-
/\breturn findings only\b/i
|
|
7
|
-
];
|
|
8
|
-
const REVIEWER_REQUIRED_EDIT_PATTERNS = [
|
|
9
|
-
/\bmust\s+(?:edit|modify|change|fix|patch|apply)\b/i,
|
|
10
|
-
/\brequired\s+to\s+(?:edit|modify|change|fix|patch|apply)\b/i,
|
|
11
|
-
/\bregardless\s+of\s+findings\b/i,
|
|
12
|
-
/\balways\s+(?:edit|modify|change|fix|patch|apply)\b/i,
|
|
13
|
-
/\bapply\s+(?:the\s+)?fix(?:es)?\s+directly\b/i,
|
|
14
|
-
/\bmake\s+(?:the\s+)?code\s+changes\b/i
|
|
15
|
-
];
|
|
16
|
-
const EXPLICIT_NO_EDIT_PATTERNS = [
|
|
17
|
-
/\bdo not edit\b/i,
|
|
18
|
-
/\bdon't edit\b/i,
|
|
19
|
-
/\bdo not modify\b/i,
|
|
20
|
-
/\bdo not change files\b/i
|
|
21
|
-
];
|
|
22
|
-
const SCOPED_NO_EDIT_CONSTRAINT_PATTERNS = [
|
|
23
|
-
/\bdo not edit files?\s+outside\b/i,
|
|
24
|
-
/\bdo not edit\s+outside\b/i,
|
|
25
|
-
/\bdo not edit\s+unrelated files?\b/i,
|
|
26
|
-
/\bdo not change\s+unrelated files?\b/i,
|
|
27
|
-
/\bdo not modify\s+unrelated files?\b/i
|
|
28
|
-
];
|
|
29
|
-
const RESEARCH_AGENT_PATTERNS = [
|
|
30
|
-
/\binvestigate\b/i,
|
|
31
|
-
/\bscout\b/i,
|
|
32
|
-
/\bresearch(?:er)?\b/i
|
|
33
|
-
];
|
|
34
|
-
const WORKER_IMPLEMENTATION_PATTERNS = [
|
|
35
|
-
/\b(?:implement|fix|edit|modify|patch|refactor|delete)\b/i,
|
|
36
|
-
/\b(?:update|add|remove|replace|create)\b(?!\s+(?:(?:a|an|the)\s+)?(?:report|summary|findings?)(?:\b|$))/i,
|
|
37
|
-
/\bapply\s+(?:the\s+)?(?:changes?|fix(?:es)?|patch)\b/i,
|
|
38
|
-
/\bmake\s+(?:the\s+)?changes\b/i,
|
|
39
|
-
/\bdo those fixes\b/i
|
|
40
|
-
];
|
|
41
|
-
const GENERAL_IMPLEMENTATION_PATTERNS = [
|
|
42
|
-
/\b(?:implement|fix|edit|modify|patch|refactor)\b/i,
|
|
43
|
-
/\bapply\s+(?:the\s+)?(?:changes?|fix(?:es)?|patch)\b/i,
|
|
44
|
-
/\bmake\s+(?:the\s+)?changes\b/i,
|
|
45
|
-
/\bdo those fixes\b/i,
|
|
46
|
-
/\b(?:update|add|remove|replace|delete|create)\s+(?:the\s+)?(?:file|files|code|source|implementation|test|tests|component|function|module|class|method|logic|import|imports|readme|docs?|changelog|package\.json|config|manifest|extension|prompt|command)\b/i
|
|
47
|
-
];
|
|
1
|
+
import { isMutatingTool } from "./long-running-guard.js";
|
|
2
|
+
import { classifyTaskMutationIntent, expectsImplementationMutation, taskMayMutate } from "./task-intent.js";
|
|
3
|
+
|
|
4
|
+
export { expectsImplementationMutation };
|
|
48
5
|
const READ_ONLY_BUILTIN_TOOLS = new Set([
|
|
49
6
|
"read",
|
|
50
7
|
"grep",
|
|
@@ -54,63 +11,163 @@ const READ_ONLY_BUILTIN_TOOLS = new Set([
|
|
|
54
11
|
"fetch_content",
|
|
55
12
|
"get_search_content",
|
|
56
13
|
"intercom",
|
|
57
|
-
"contact_supervisor"
|
|
14
|
+
"contact_supervisor",
|
|
15
|
+
"structured_output"
|
|
58
16
|
]);
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
17
|
+
const CURSOR_FILE_MUTATION_THINKING = /(?:^|\n)\s*Cursor (?:edit|write)\s*:/i;
|
|
18
|
+
const REVIVED_TASK_PREFIX = /^You are reviving a previous subagent conversation\.\n\nOriginal run: .+\nOriginal agent: .+(?:\nOriginal session file: .+)?\n\nUse the stored session context as background\. Answer the orchestrator's follow-up below\. Do not assume the original child process is still alive\.\n\nFollow-up:\n/;
|
|
19
|
+
const IMPLEMENTATION_CHALLENGE_FOLLOW_UP_PATTERN = /^(?:Run )?implementation challenge pass (?:one|two|\d+)(?:\s+and implement any better current[- ]scope change\.?|\s+for the accepted candidate\.\s+Reconsider it and implement any better current[- ]scope change\.?)?$/i;
|
|
20
|
+
const NO_BETTER_CHANGE_NEEDED_PATTERN = /^\s*no (?:better|further|additional) (?:current[- ]scope )?(?:code |source |file )?(?:change|changes|edit|edits|patch|patches) (?:is|are) needed\b/i;
|
|
21
|
+
const KEPT_CURRENT_IMPLEMENTATION_PATTERN = /\b(?:kept (?:the )?current (?:implementation|candidate|shape)|(?:the )?current (?:implementation|candidate|shape) was kept)\b/i;
|
|
22
|
+
const NO_CHANGE_MADE_PATTERN = /\bno (?:new )?(?:(?:code|source|file|test)(?:\s*(?:,\s*or|,|\/|or)\s*(?:code|source|file|test))* changes?|changes?) (?:were|was) made\b/i;
|
|
23
|
+
const NO_BETTER_CHANGE_QUALIFIER_PATTERN = /\b(?:do\s+not|don't|dont|not|never|cannot|can't|cant|unable|uncertain|unsure|unclear|disagree|wrong|false|reject|rejected|rejecting|maybe|might|may|\w+n['’]t)\b/i;
|
|
24
|
+
const REPORT_SENTENCE_PATTERN = /[^.!?]+(?:[.!?]+(?=(?:["”'’]?\s)|["”'’]?$)|$)/g;
|
|
25
|
+
const QUOTED_CLAIM_PATTERN = /["“]([^"”]+)["”]([.!?]?\s*[^.!?]*)/g;
|
|
26
|
+
const QUOTED_CLAIM_REFERENCE_PATTERN = /\b(?:that|this|it|claim|report|message|disagree)\b/i;
|
|
27
|
+
const CLAIM_CONTRADICTION_PATTERN = /\bbut\b[^.!?]*\b(?:uncertain|unsure|unclear|disagree|wrong|false|reject|rejected|rejecting)\b/i;
|
|
28
|
+
const IMPLEMENTATION_RETRACTION_PATTERN = /\b(?:found|identified)\s+(?:(?:a|an|the)\s+)?(?:required|necessary|additional|better)?\s*(?:(?:code|source|file|test)\s+)?(?:changes?|edits?|patches?)\b|\b(?:(?:implementation|code|source|file|test)\s+)?work\s+(?:remains?|is\s+(?:needed|required))\b|\b(?:(?:a|an|the)\s+)?(?:(?:code|source|file|test)\s+)?(?:changes?|edits?|patches?)\s+(?:are|is)\s+(?:needed|required)\b|\b(?:required|necessary|additional|better)\s+(?:(?:code|source|file|test)\s+)?(?:changes?|edits?|patches?)\b|\b(?:I|we)?\s*need\s+(?:(?:code|source|file|test)\s+)?(?:changes?|edits?|patches?)\b|\b(?:need|needs|require|requires)\s+(?:to\s+)?(?:implement|make|apply)\b/i;
|
|
29
|
+
const IMPLEMENTATION_RETRACTION_GLOBAL_PATTERN = new RegExp(IMPLEMENTATION_RETRACTION_PATTERN.source, "gi");
|
|
30
|
+
const DIRECT_CLAIM_RETRACTION_PATTERN = /^\s*(?:I\s+)?(?:disagree|reject|retract)\b|\b(?:disagree|retract|retracted|retracting|reject|rejected|rejecting)\b[^.!?]*\b(?:that|this|it|claim|report|message)\b|\b(?:that|this|it|claim|report|message)\b[^.!?]*\b(?:is|was)\s+(?:rejected|retracted)\b/i;
|
|
31
|
+
const NEGATED_RETRACTION_PREFIX_PATTERN = /\b(?:no|not|\w+n['’]t)\b(?:\s+\w+){0,2}\s*$/i;
|
|
32
|
+
const REPORTED_CLAIM_PREFIX_PATTERN = /["“]|\b(?:prior|previous)\s+(?:message|report)\b|\b(?:said|stated|reported)\b/i;
|
|
33
|
+
const POST_CLAIM_SEPARATOR_PATTERN = /^[\s,;:.—–'"“‘’-]+/;
|
|
34
|
+
export function hasMutationToolCapability(tools, mcpDirectTools) {
|
|
35
|
+
if ((mcpDirectTools?.length ?? 0) > 0)
|
|
36
|
+
return true;
|
|
37
|
+
if (tools === undefined)
|
|
38
|
+
return true;
|
|
39
|
+
return !tools.every((tool) => READ_ONLY_BUILTIN_TOOLS.has(tool));
|
|
63
40
|
}
|
|
64
|
-
function
|
|
65
|
-
|
|
66
|
-
for (const pattern of SCOPED_NO_EDIT_CONSTRAINT_PATTERNS) {
|
|
67
|
-
stripped = stripped.replace(pattern, " ");
|
|
68
|
-
}
|
|
69
|
-
return stripped;
|
|
41
|
+
function hasBuiltinMutationTool(tools) {
|
|
42
|
+
return tools === undefined || tools.some((tool) => !READ_ONLY_BUILTIN_TOOLS.has(tool));
|
|
70
43
|
}
|
|
71
|
-
function
|
|
72
|
-
return
|
|
44
|
+
function isWriterRole(agent, acceptanceRole) {
|
|
45
|
+
return acceptanceRole === "writer" || acceptanceRole === undefined && /\bworker\b/i.test(agent);
|
|
73
46
|
}
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
if (
|
|
47
|
+
const WRITER_DELIVERY_PATTERN = /\b(?:address|resolve|work)\s+(?:backlog\s+)?(?:item|issue)\b|\b(?:land|ship)\s+(?:the\s+)?(?:change|changes|fix|feature|implementation)\b/i;
|
|
48
|
+
export function validateImplementationToolContract(input) {
|
|
49
|
+
if (input.completionGuard === false)
|
|
50
|
+
return;
|
|
51
|
+
const requestedMutationTools = input.requestedTools?.filter((tool) => !READ_ONLY_BUILTIN_TOOLS.has(tool)) ?? [];
|
|
52
|
+
const declaredMutationToolsWereRemoved = requestedMutationTools.length > 0 && !hasBuiltinMutationTool(input.tools);
|
|
53
|
+
const configuredExtensionCapability = (input.configuredExtensions?.length ?? 0) > 0 && !declaredMutationToolsWereRemoved;
|
|
54
|
+
if (hasMutationToolCapability(input.tools, input.mcpDirectTools) || configuredExtensionCapability)
|
|
55
|
+
return;
|
|
56
|
+
const intent = classifyTaskMutationIntent(input.agent, input.task);
|
|
57
|
+
if (intent.kind === "read-only")
|
|
58
|
+
return;
|
|
59
|
+
const writerTaskMayMutate = isWriterRole(input.agent, input.acceptanceRole) && (taskMayMutate(input.task) || WRITER_DELIVERY_PATTERN.test(input.task));
|
|
60
|
+
if (intent.kind !== "implementation" && !writerTaskMayMutate && !declaredMutationToolsWereRemoved)
|
|
61
|
+
return;
|
|
62
|
+
return `Agent '${input.agent}' was given an implementation task, but its tool allowlist has no mutation-capable tools. Add bash, edit, write, or another mutation-capable tool to the agent, or use a read-only task/agent.`;
|
|
63
|
+
}
|
|
64
|
+
function hasCheckpointMutationEvidence(message) {
|
|
65
|
+
const record = message;
|
|
66
|
+
if (record.role !== "custom" && record.type !== "custom" || record.customType !== "dm-checkpoint")
|
|
82
67
|
return false;
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
if (workerIntent)
|
|
87
|
-
return true;
|
|
88
|
-
return GENERAL_IMPLEMENTATION_PATTERNS.some((pattern) => pattern.test(taskText));
|
|
68
|
+
const details = typeof record.details === "object" && record.details !== null && !Array.isArray(record.details) ? record.details : undefined;
|
|
69
|
+
const data = typeof record.data === "object" && record.data !== null && !Array.isArray(record.data) ? record.data : typeof details?.beforeCommit === "string" || typeof details?.afterCommit === "string" ? details : details?.data && typeof details.data === "object" && !Array.isArray(details.data) ? details.data : undefined;
|
|
70
|
+
return typeof data?.beforeCommit === "string" && typeof data.afterCommit === "string" && data.beforeCommit !== data.afterCommit;
|
|
89
71
|
}
|
|
90
|
-
export function hasMutationToolCall(messages) {
|
|
72
|
+
export function hasMutationToolCall(messages, mutationTools) {
|
|
91
73
|
for (const message of messages) {
|
|
74
|
+
if (hasCheckpointMutationEvidence(message))
|
|
75
|
+
return true;
|
|
92
76
|
if (message.role !== "assistant")
|
|
93
77
|
continue;
|
|
94
78
|
for (const part of message.content) {
|
|
95
|
-
if (part.type
|
|
96
|
-
continue;
|
|
97
|
-
if (part.name === "edit" || part.name === "write")
|
|
79
|
+
if (part.type === "thinking" && CURSOR_FILE_MUTATION_THINKING.test(part.thinking))
|
|
98
80
|
return true;
|
|
99
|
-
if (part.
|
|
81
|
+
if (part.type !== "toolCall")
|
|
100
82
|
continue;
|
|
101
83
|
const args = typeof part.arguments === "object" && part.arguments !== null && !Array.isArray(part.arguments) ? part.arguments : {};
|
|
102
|
-
if (
|
|
84
|
+
if (isMutatingTool(part.name, args, mutationTools))
|
|
103
85
|
return true;
|
|
104
86
|
}
|
|
105
87
|
}
|
|
106
88
|
return false;
|
|
107
89
|
}
|
|
90
|
+
function hasImplementationRetraction(text) {
|
|
91
|
+
return Array.from(text.matchAll(IMPLEMENTATION_RETRACTION_GLOBAL_PATTERN)).some((retraction) => !NEGATED_RETRACTION_PREFIX_PATTERN.test(text.slice(0, retraction.index)));
|
|
92
|
+
}
|
|
93
|
+
function hasDirectClaimRetraction(text) {
|
|
94
|
+
return DIRECT_CLAIM_RETRACTION_PATTERN.test(text.replace(POST_CLAIM_SEPARATOR_PATTERN, ""));
|
|
95
|
+
}
|
|
96
|
+
function isInsideQuotedText(report, index) {
|
|
97
|
+
let quote;
|
|
98
|
+
for (const char of report.slice(0, index)) {
|
|
99
|
+
if (quote === "double") {
|
|
100
|
+
if (char === '"' || char === "”")
|
|
101
|
+
quote = undefined;
|
|
102
|
+
} else if (quote === "single") {
|
|
103
|
+
if (char === "’")
|
|
104
|
+
quote = undefined;
|
|
105
|
+
} else if (char === '"' || char === "“") {
|
|
106
|
+
quote = "double";
|
|
107
|
+
} else if (char === "‘") {
|
|
108
|
+
quote = "single";
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return quote !== undefined;
|
|
112
|
+
}
|
|
113
|
+
function unqualifiedClaimIndex(report, sentences, pattern) {
|
|
114
|
+
return sentences.findIndex((sentence) => {
|
|
115
|
+
const claim = sentence.text.match(pattern);
|
|
116
|
+
if (claim === null)
|
|
117
|
+
return false;
|
|
118
|
+
const before = sentence.text.slice(0, claim.index);
|
|
119
|
+
const after = sentence.text.slice(claim.index + claim[0].length);
|
|
120
|
+
const previous = before.trimEnd().at(-1);
|
|
121
|
+
return previous !== "'" && previous !== "‘" && !isInsideQuotedText(report, sentence.offset + claim.index) && !REPORTED_CLAIM_PREFIX_PATTERN.test(before) && !NO_BETTER_CHANGE_QUALIFIER_PATTERN.test(before) && !CLAIM_CONTRADICTION_PATTERN.test(after) && !hasImplementationRetraction(after) && !hasDirectClaimRetraction(after);
|
|
122
|
+
});
|
|
123
|
+
}
|
|
124
|
+
function hasLaterClaimRetraction(sentences, claimIndex) {
|
|
125
|
+
return sentences.slice(claimIndex + 1).some((sentence) => hasImplementationRetraction(sentence.text) || hasDirectClaimRetraction(sentence.text));
|
|
126
|
+
}
|
|
127
|
+
function explicitlyRejectsQuotedClaim(report) {
|
|
128
|
+
for (const [, claim, response] of report.matchAll(QUOTED_CLAIM_PATTERN)) {
|
|
129
|
+
if ((KEPT_CURRENT_IMPLEMENTATION_PATTERN.test(claim) || NO_CHANGE_MADE_PATTERN.test(claim)) && NO_BETTER_CHANGE_QUALIFIER_PATTERN.test(response) && QUOTED_CLAIM_REFERENCE_PATTERN.test(response))
|
|
130
|
+
return true;
|
|
131
|
+
}
|
|
132
|
+
return false;
|
|
133
|
+
}
|
|
134
|
+
function isImplementationChallengeTask(task) {
|
|
135
|
+
const followUp = task.replace(REVIVED_TASK_PREFIX, "");
|
|
136
|
+
return followUp !== task && IMPLEMENTATION_CHALLENGE_FOLLOW_UP_PATTERN.test(followUp.trim());
|
|
137
|
+
}
|
|
138
|
+
function reportsNoBetterChallengeChange(messages) {
|
|
139
|
+
const report = messages.filter((message) => message.role === "assistant").flatMap((message) => message.content).flatMap((part) => part.type === "text" ? [part.text] : []).join(`
|
|
140
|
+
`);
|
|
141
|
+
if (explicitlyRejectsQuotedClaim(report))
|
|
142
|
+
return false;
|
|
143
|
+
const sentences = Array.from(report.matchAll(REPORT_SENTENCE_PATTERN), (match) => ({
|
|
144
|
+
text: match[0],
|
|
145
|
+
offset: match.index
|
|
146
|
+
}));
|
|
147
|
+
const noBetterIndex = unqualifiedClaimIndex(report, sentences, NO_BETTER_CHANGE_NEEDED_PATTERN);
|
|
148
|
+
if (noBetterIndex >= 0)
|
|
149
|
+
return !hasLaterClaimRetraction(sentences, noBetterIndex);
|
|
150
|
+
const keptIndex = unqualifiedClaimIndex(report, sentences, KEPT_CURRENT_IMPLEMENTATION_PATTERN);
|
|
151
|
+
const noChangeIndex = unqualifiedClaimIndex(report, sentences, NO_CHANGE_MADE_PATTERN);
|
|
152
|
+
return keptIndex >= 0 && noChangeIndex >= 0 && !hasLaterClaimRetraction(sentences, Math.min(keptIndex, noChangeIndex));
|
|
153
|
+
}
|
|
108
154
|
export function evaluateCompletionMutationGuard(input) {
|
|
109
|
-
|
|
110
|
-
|
|
155
|
+
if (input.toolAvailabilityError && expectsImplementationMutation(input.agent, input.task)) {
|
|
156
|
+
return {
|
|
157
|
+
expectedMutation: true,
|
|
158
|
+
attemptedMutation: false,
|
|
159
|
+
triggered: false,
|
|
160
|
+
blocked: true,
|
|
161
|
+
message: input.toolAvailabilityError
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
const expectedMutation = hasMutationToolCapability(input.tools, input.mcpDirectTools) ? expectsImplementationMutation(input.agent, input.task) : false;
|
|
165
|
+
const attemptedMutation = hasMutationToolCall(input.messages, input.mutationTools) || input.mutationEvidence?.attemptedMutation === true;
|
|
166
|
+
const noEditChallengeComplete = isImplementationChallengeTask(input.task) && reportsNoBetterChallengeChange(input.messages);
|
|
111
167
|
return {
|
|
112
168
|
expectedMutation,
|
|
113
169
|
attemptedMutation,
|
|
114
|
-
triggered: expectedMutation && !attemptedMutation
|
|
170
|
+
triggered: expectedMutation && !attemptedMutation && !noEditChallengeComplete,
|
|
171
|
+
blocked: false
|
|
115
172
|
};
|
|
116
173
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
export function isContextMode(value) {
|
|
2
|
+
return value === "fresh" || value === "fork";
|
|
3
|
+
}
|
|
4
|
+
export function isContextSummary(value) {
|
|
5
|
+
return isContextMode(value) || value === "mixed";
|
|
6
|
+
}
|
|
7
|
+
export function summarizeContextModes(modes) {
|
|
8
|
+
const resolved = modes.filter(isContextMode);
|
|
9
|
+
if (resolved.length === 0)
|
|
10
|
+
return;
|
|
11
|
+
const first = resolved[0];
|
|
12
|
+
return resolved.every((mode) => mode === first) ? first : "mixed";
|
|
13
|
+
}
|
|
14
|
+
export function contextModeLabel(mode) {
|
|
15
|
+
if (mode === "fork")
|
|
16
|
+
return "[fork]";
|
|
17
|
+
if (mode === "fresh")
|
|
18
|
+
return "[fresh]";
|
|
19
|
+
if (mode === "mixed")
|
|
20
|
+
return "[mixed]";
|
|
21
|
+
return "";
|
|
22
|
+
}
|
|
23
|
+
export function contextModeBadge(theme, mode) {
|
|
24
|
+
const label = contextModeLabel(mode);
|
|
25
|
+
if (!label)
|
|
26
|
+
return "";
|
|
27
|
+
if (mode === "fork")
|
|
28
|
+
return theme.fg("warning", ` ${label}`);
|
|
29
|
+
return theme.fg("dim", ` ${label}`);
|
|
30
|
+
}
|
|
31
|
+
export function contextModePrefix(theme, mode) {
|
|
32
|
+
const label = contextModeLabel(mode);
|
|
33
|
+
if (!label)
|
|
34
|
+
return "";
|
|
35
|
+
if (mode === "fork")
|
|
36
|
+
return `${theme.fg("warning", label)} `;
|
|
37
|
+
return `${theme.fg("dim", label)} `;
|
|
38
|
+
}
|
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import * as path from "node:path";
|
|
2
|
+
import { parseExternalCliJsonlEvent } from "./external-cli-runner.js";
|
|
3
|
+
const MAX_EVENT_TYPE_LENGTH = 128;
|
|
4
|
+
const MAX_ERROR_LENGTH = 4096;
|
|
5
|
+
const MAX_OVERSIZED_TOOL_CALL_BYTES = 1024 * 1024;
|
|
6
|
+
export const CURSOR_AGENT_ADAPTER_ID = "cursor-agent";
|
|
7
|
+
export const CURSOR_AGENT_WRITER_ADAPTER_ID = "cursor-agent-writer";
|
|
8
|
+
export const CURSOR_AGENT_ENV_ALLOWLIST = [
|
|
9
|
+
"PATH",
|
|
10
|
+
"HOME",
|
|
11
|
+
"USERPROFILE",
|
|
12
|
+
"CURSOR_API_KEY",
|
|
13
|
+
"HTTP_PROXY",
|
|
14
|
+
"HTTPS_PROXY",
|
|
15
|
+
"NO_PROXY",
|
|
16
|
+
"http_proxy",
|
|
17
|
+
"https_proxy",
|
|
18
|
+
"no_proxy",
|
|
19
|
+
"SSL_CERT_FILE",
|
|
20
|
+
"SSL_CERT_DIR"
|
|
21
|
+
];
|
|
22
|
+
function terminalError(event) {
|
|
23
|
+
for (const value of [event.result, event.error, event.message]) {
|
|
24
|
+
if (typeof value === "string" && value.trim())
|
|
25
|
+
return value.trim().slice(0, MAX_ERROR_LENGTH);
|
|
26
|
+
}
|
|
27
|
+
const subtype = typeof event.subtype === "string" && event.subtype ? event.subtype : "unknown";
|
|
28
|
+
return `Cursor Agent reported terminal result ${subtype}.`;
|
|
29
|
+
}
|
|
30
|
+
export function createCursorAgentJsonlParser() {
|
|
31
|
+
let eventCount = 0;
|
|
32
|
+
let terminal;
|
|
33
|
+
return {
|
|
34
|
+
parseLine(line) {
|
|
35
|
+
const event = parseExternalCliJsonlEvent(line, "Cursor Agent", MAX_EVENT_TYPE_LENGTH);
|
|
36
|
+
if (terminal)
|
|
37
|
+
throw new Error("Cursor Agent emitted an event after its terminal state.");
|
|
38
|
+
eventCount += 1;
|
|
39
|
+
if (event.type === "error")
|
|
40
|
+
terminal = { state: "failed", error: terminalError(event) };
|
|
41
|
+
else if (event.type === "result") {
|
|
42
|
+
if (event.subtype === "success" && event.is_error === false && typeof event.result === "string" && event.result.trim()) {
|
|
43
|
+
terminal = { state: "completed", output: event.result.trim() };
|
|
44
|
+
} else
|
|
45
|
+
terminal = { state: "failed", error: terminalError(event) };
|
|
46
|
+
}
|
|
47
|
+
return { phase: terminal ? terminal.state : "streaming", eventCount };
|
|
48
|
+
},
|
|
49
|
+
skipOversizedLine(prefix, byteLength) {
|
|
50
|
+
if (terminal || byteLength > MAX_OVERSIZED_TOOL_CALL_BYTES || !/^\s*\{\s*"type"\s*:\s*"tool_call"\s*,/.test(prefix))
|
|
51
|
+
return;
|
|
52
|
+
eventCount += 1;
|
|
53
|
+
return { phase: "streaming", eventCount };
|
|
54
|
+
},
|
|
55
|
+
finish() {
|
|
56
|
+
return terminal;
|
|
57
|
+
}
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
export function resolveCursorAgentLaunch(input) {
|
|
61
|
+
const writer = input.adapter === CURSOR_AGENT_WRITER_ADAPTER_ID;
|
|
62
|
+
const promptDirectory = path.join(input.asyncDir, `external-${input.stepIndex}.cursor-prompt`);
|
|
63
|
+
const promptFilePath = path.join(promptDirectory, "handoff.txt");
|
|
64
|
+
const promptRelative = path.relative(input.cwd, promptDirectory);
|
|
65
|
+
const promptOutsideWorkspace = promptRelative.startsWith("..") || path.isAbsolute(promptRelative);
|
|
66
|
+
const prefix = [...input.commandPrefixArgs ?? []];
|
|
67
|
+
const args = [
|
|
68
|
+
...prefix,
|
|
69
|
+
"-p",
|
|
70
|
+
"--output-format",
|
|
71
|
+
"stream-json",
|
|
72
|
+
...writer ? [] : ["--mode", "ask"],
|
|
73
|
+
"--sandbox",
|
|
74
|
+
"enabled",
|
|
75
|
+
"--workspace",
|
|
76
|
+
input.cwd,
|
|
77
|
+
...promptOutsideWorkspace ? ["--add-dir", promptDirectory] : [],
|
|
78
|
+
`Read the complete handoff from the private file at ${promptFilePath}. Follow it and return only the final answer.`
|
|
79
|
+
];
|
|
80
|
+
return {
|
|
81
|
+
command: input.command,
|
|
82
|
+
args,
|
|
83
|
+
promptFilePath,
|
|
84
|
+
temporaryDirectories: [promptDirectory],
|
|
85
|
+
environment: { allowlist: CURSOR_AGENT_ENV_ALLOWLIST },
|
|
86
|
+
preflight: {
|
|
87
|
+
id: input.adapter,
|
|
88
|
+
versionArgs: [...prefix, "--version"],
|
|
89
|
+
helpArgs: [...prefix, "--help"],
|
|
90
|
+
validate(result) {
|
|
91
|
+
if (!/^\d{4}\.\d{2}\.\d{2}-[0-9a-f]+$/.test(result.version))
|
|
92
|
+
throw new Error(`Unsupported Cursor Agent version response: ${JSON.stringify(result.version)}.`);
|
|
93
|
+
for (const required of ["Start the Cursor Agent", "--print", "stream-json", "--sandbox <mode>", "enabled", "--workspace <path-or-name>", "--add-dir <path>", ...writer ? ["all tools", "including write and shell"] : ["--mode <mode>", "ask:", "read-only"]]) {
|
|
94
|
+
if (!result.help.includes(required))
|
|
95
|
+
throw new Error(`Cursor Agent help does not document required option ${JSON.stringify(required)}.`);
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
},
|
|
99
|
+
parser: createCursorAgentJsonlParser()
|
|
100
|
+
};
|
|
101
|
+
}
|