@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,44 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { readAsyncRecoveryDescriptor } from "./async-resume.js";
|
|
3
|
+
const INTERCOM_DETACH_ERROR = "detached for intercom coordination";
|
|
4
|
+
function isIntercomDetached(run) {
|
|
5
|
+
return run.steps.some((step) => step.execution?.status === "detached" || step.error?.toLowerCase().includes(INTERCOM_DETACH_ERROR) === true) || run.error?.toLowerCase().includes(INTERCOM_DETACH_ERROR) === true;
|
|
6
|
+
}
|
|
7
|
+
function formatIntercomDetachGuidance(run) {
|
|
8
|
+
if (!isIntercomDetached(run))
|
|
9
|
+
return;
|
|
10
|
+
return `Run "${run.id}" detached for intercom coordination. Reply to the supervisor request first, then wait with bg_wait({ id: "${run.id}" }). Use subagent({ action: "status", id: "${run.id}" }) to recover the result; do not resume or launch a replacement while it remains detached.`;
|
|
11
|
+
}
|
|
12
|
+
export function formatAsyncReviveCommand(run) {
|
|
13
|
+
const step = run.steps.find((candidate) => candidate.status === "failed");
|
|
14
|
+
const sessionFile = step?.sessionFile ?? (run.steps.length === 1 ? run.sessionFile : undefined);
|
|
15
|
+
if (!step || !sessionFile || !fs.existsSync(sessionFile))
|
|
16
|
+
return;
|
|
17
|
+
try {
|
|
18
|
+
const descriptor = readAsyncRecoveryDescriptor(run.asyncDir);
|
|
19
|
+
if (!descriptor || descriptor.sourceRunId !== run.id || descriptor.agent !== step.agent)
|
|
20
|
+
return;
|
|
21
|
+
} catch {
|
|
22
|
+
return;
|
|
23
|
+
}
|
|
24
|
+
const index = run.steps.length === 1 ? "" : `, index: ${step.index}`;
|
|
25
|
+
return `subagent({ action: "resume", id: "${run.id}"${index}, message: "Continue from the persisted child session and report the result." })`;
|
|
26
|
+
}
|
|
27
|
+
export function formatResumeFirstFailedRunDetail(run) {
|
|
28
|
+
if (run.state !== "failed")
|
|
29
|
+
return;
|
|
30
|
+
const detachGuidance = formatIntercomDetachGuidance(run);
|
|
31
|
+
if (detachGuidance)
|
|
32
|
+
return detachGuidance;
|
|
33
|
+
const command = formatAsyncReviveCommand(run);
|
|
34
|
+
if (!command)
|
|
35
|
+
return;
|
|
36
|
+
return `Resume-first: failed run "${run.id}" has a persisted child session. Revive the original run with ${command} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
|
|
37
|
+
}
|
|
38
|
+
export function formatResumeFirstFailedRunsNote(runs) {
|
|
39
|
+
const failedRuns = runs.filter((run) => run.state === "failed" || run.state === "partial");
|
|
40
|
+
const detachGuidance = failedRuns.map(formatIntercomDetachGuidance).filter((guidance) => Boolean(guidance));
|
|
41
|
+
const resumable = failedRuns.filter((run) => !isIntercomDetached(run)).map((run) => ({ run, command: formatAsyncReviveCommand(run) })).filter((entry) => Boolean(entry.command));
|
|
42
|
+
const resumeGuidance = resumable.length === 0 ? "" : resumable.length === 1 ? ` Resume-first: failed run "${resumable[0].run.id}" has a persisted child session. Revive the original run with ${resumable[0].command} before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.` : ` Resume-first: ${resumable.length} failed runs have persisted child sessions. Inspect status and revive each original run before reporting failure or launching a replacement. Launch a replacement only if revive fails or the user explicitly asks for one.`;
|
|
43
|
+
return `${detachGuidance.length > 0 ? ` ${detachGuidance.join(" ")}` : ""}${resumeGuidance}`;
|
|
44
|
+
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import * as fs from "node:fs";
|
|
2
|
+
import { listAsyncRuns } from "./async-status.js";
|
|
3
|
+
import { readAsyncRecoveryDescriptor } from "./async-resume.js";
|
|
4
|
+
import { parallelHandoffPath, resolveRetainedWorktreeCwd } from "../shared/parallel-handoff.js";
|
|
5
|
+
const MAX_RETAINED_CHILDREN = 10;
|
|
6
|
+
const MAX_RETAINED_CHILD_CANDIDATES = 100;
|
|
7
|
+
const MAX_TASK_SUMMARY_LENGTH = 120;
|
|
8
|
+
function isRetainedChildState(state) {
|
|
9
|
+
return state === "complete" || state === "failed" || state === "partial" || state === "paused" || state === "stopped";
|
|
10
|
+
}
|
|
11
|
+
function isTerminalStepStatus(status) {
|
|
12
|
+
return status === "complete" || status === "completed" || status === "failed" || status === "paused" || status === "stopped";
|
|
13
|
+
}
|
|
14
|
+
function retainedSessionFile(sessionFile) {
|
|
15
|
+
if (!sessionFile)
|
|
16
|
+
return { state: "not-resumable", reason: "no persisted session file" };
|
|
17
|
+
if (!sessionFile.endsWith(".jsonl"))
|
|
18
|
+
return { state: "not-resumable", reason: "persisted session file is not a .jsonl file" };
|
|
19
|
+
try {
|
|
20
|
+
const stat = fs.lstatSync(sessionFile);
|
|
21
|
+
if (!stat.isFile() || stat.isSymbolicLink())
|
|
22
|
+
return { state: "not-resumable", reason: "persisted session file is not a regular file" };
|
|
23
|
+
return { state: "resumable", sessionPath: sessionFile };
|
|
24
|
+
} catch (error) {
|
|
25
|
+
if (typeof error === "object" && error !== null && "code" in error && error.code === "ENOENT") {
|
|
26
|
+
return { state: "not-resumable", reason: `persisted session file is missing: ${sessionFile}` };
|
|
27
|
+
}
|
|
28
|
+
return { state: "not-resumable", reason: `persisted session file could not be inspected: ${error instanceof Error ? error.message : String(error)}` };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
function childResumability(run, step) {
|
|
32
|
+
if (run.state === "stopped" || step.status === "stopped")
|
|
33
|
+
return { state: "not-resumable", reason: "stopped run" };
|
|
34
|
+
if (step.runner?.type === "external-cli" || step.runner?.type === "external-job")
|
|
35
|
+
return { state: "not-resumable", reason: "external runner" };
|
|
36
|
+
const session = retainedSessionFile(step.sessionFile ?? run.sessionFile);
|
|
37
|
+
if (session.state === "not-resumable")
|
|
38
|
+
return session;
|
|
39
|
+
let recoveryDescriptor;
|
|
40
|
+
try {
|
|
41
|
+
recoveryDescriptor = readAsyncRecoveryDescriptor(run.asyncDir);
|
|
42
|
+
if (!recoveryDescriptor)
|
|
43
|
+
return { state: "not-resumable", reason: "missing recovery descriptor" };
|
|
44
|
+
if (recoveryDescriptor.sourceRunId !== run.id)
|
|
45
|
+
return { state: "not-resumable", reason: `recovery descriptor belongs to run ${recoveryDescriptor.sourceRunId}` };
|
|
46
|
+
if (recoveryDescriptor.agent !== step.agent)
|
|
47
|
+
return { state: "not-resumable", reason: `recovery descriptor belongs to agent ${recoveryDescriptor.agent}` };
|
|
48
|
+
} catch (error) {
|
|
49
|
+
return { state: "not-resumable", reason: `invalid recovery descriptor: ${error instanceof Error ? error.message : String(error)}` };
|
|
50
|
+
}
|
|
51
|
+
let requiredCwd;
|
|
52
|
+
try {
|
|
53
|
+
requiredCwd = resolveRetainedWorktreeCwd(parallelHandoffPath(run.asyncDir), run.id, step.index) ?? recoveryDescriptor.cwd ?? run.cwd;
|
|
54
|
+
if (!requiredCwd || !fs.statSync(requiredCwd).isDirectory())
|
|
55
|
+
return { state: "not-resumable", reason: `required cwd is missing: ${requiredCwd ?? "unknown"}` };
|
|
56
|
+
} catch (error) {
|
|
57
|
+
return { state: "not-resumable", reason: `resume dependency unavailable: ${error instanceof Error ? error.message : String(error)}` };
|
|
58
|
+
}
|
|
59
|
+
return session;
|
|
60
|
+
}
|
|
61
|
+
function boundedTaskSummary(value) {
|
|
62
|
+
const normalized = value?.replace(/\s+/g, " ").trim() ?? "";
|
|
63
|
+
return normalized.length > MAX_TASK_SUMMARY_LENGTH ? `${normalized.slice(0, MAX_TASK_SUMMARY_LENGTH - 1)}…` : normalized;
|
|
64
|
+
}
|
|
65
|
+
export function listRetainedChildren(asyncDirRoot, sessionId) {
|
|
66
|
+
const children = listAsyncRuns(asyncDirRoot, { sessionId, states: ["complete", "failed", "paused", "stopped"], entryLimit: MAX_RETAINED_CHILD_CANDIDATES, reconcile: false }).flatMap((run) => {
|
|
67
|
+
if (!run.parentWorkflowRunId || run.steps.length !== 1)
|
|
68
|
+
return [];
|
|
69
|
+
if (!isRetainedChildState(run.state))
|
|
70
|
+
return [];
|
|
71
|
+
const step = run.steps[0];
|
|
72
|
+
if (!isTerminalStepStatus(step.status))
|
|
73
|
+
return [];
|
|
74
|
+
const completedAt = run.endedAt ?? run.lastUpdate;
|
|
75
|
+
if (completedAt === undefined)
|
|
76
|
+
return [];
|
|
77
|
+
const resumability = childResumability(run, step);
|
|
78
|
+
return [{
|
|
79
|
+
runId: run.id,
|
|
80
|
+
...run.parentWorkflowRunId ? { parentRunId: run.parentWorkflowRunId } : {},
|
|
81
|
+
...run.workflowKey ? { workflowKey: run.workflowKey } : {},
|
|
82
|
+
state: run.state,
|
|
83
|
+
agent: step.agent,
|
|
84
|
+
taskSummary: boundedTaskSummary(step.description),
|
|
85
|
+
completedAt,
|
|
86
|
+
resumability,
|
|
87
|
+
...resumability.state === "resumable" ? { sessionPath: resumability.sessionPath } : {},
|
|
88
|
+
...step.tokens ?? run.totalTokens ? { tokenTotals: step.tokens ?? run.totalTokens } : {}
|
|
89
|
+
}];
|
|
90
|
+
}).sort((left, right) => right.completedAt - left.completedAt);
|
|
91
|
+
return children;
|
|
92
|
+
}
|
|
93
|
+
export function formatRetainedChildren(children) {
|
|
94
|
+
if (children.length === 0)
|
|
95
|
+
return "No retained workflow children in the active parent session. If a retained-writer challenge is required, launch a same-role fallback challenge and label it as fallback.";
|
|
96
|
+
const retained = children.slice(0, MAX_RETAINED_CHILDREN);
|
|
97
|
+
if (!retained.some((child) => child.resumability.state === "resumable")) {
|
|
98
|
+
const resumable = children.slice(MAX_RETAINED_CHILDREN).find((child) => child.resumability.state === "resumable");
|
|
99
|
+
if (resumable && retained.length === MAX_RETAINED_CHILDREN)
|
|
100
|
+
retained[MAX_RETAINED_CHILDREN - 1] = resumable;
|
|
101
|
+
}
|
|
102
|
+
const hasResumableChild = retained.some((child) => child.resumability.state === "resumable");
|
|
103
|
+
return [
|
|
104
|
+
`Retained workflow children (up to ${MAX_RETAINED_CHILDREN}; newest first, with a resumable child retained when available):`,
|
|
105
|
+
...retained.flatMap((child) => [
|
|
106
|
+
`- ${child.runId} | ${child.agent} | ${child.state} | ${new Date(child.completedAt).toISOString()}`,
|
|
107
|
+
...child.parentRunId ? [` workflow: ${child.parentRunId}${child.workflowKey ? ` (${child.workflowKey})` : ""}`] : [],
|
|
108
|
+
` task: ${child.taskSummary || "(no task summary)"}`,
|
|
109
|
+
child.resumability.state === "resumable" ? " resumability: resumable" : ` resumability: not resumable (${child.resumability.reason})`,
|
|
110
|
+
...child.resumability.state === "resumable" ? [
|
|
111
|
+
` session: ${child.resumability.sessionPath}`,
|
|
112
|
+
` resume: subagent({ action: "resume", id: "${child.runId}", message: "..." })`
|
|
113
|
+
] : [],
|
|
114
|
+
...child.tokenTotals ? [` tokens: input ${child.tokenTotals.input}, output ${child.tokenTotals.output}, total ${child.tokenTotals.total}`] : []
|
|
115
|
+
]),
|
|
116
|
+
...hasResumableChild ? [] : ["No resumable retained child is listed. Launch a same-role fallback challenge and label it as fallback."]
|
|
117
|
+
].join(`
|
|
118
|
+
`);
|
|
119
|
+
}
|
|
@@ -1,23 +1,99 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
-
import {
|
|
3
|
+
import { DIRS } from "../../shared/types.js";
|
|
4
|
+
import { readStatus } from "../../shared/utils.js";
|
|
4
5
|
import { findAsyncRunPrefixMatches } from "./async-resume.js";
|
|
6
|
+
import { resultCandidateFilesForToolCall, resultFilePath, resultPayloadPathForIndexedRun } from "./result-files.js";
|
|
7
|
+
import { readActiveRunToolCallIndex } from "./active-run-index.js";
|
|
5
8
|
import { assertSafeNestedId, findNestedRunMatchesById } from "../shared/nested-events.js";
|
|
6
9
|
function exactAsyncLocation(id, asyncDirRoot, resultsDir) {
|
|
7
10
|
const asyncDir = path.join(asyncDirRoot, id);
|
|
8
|
-
const
|
|
9
|
-
|
|
11
|
+
const asyncDirExists = fs.existsSync(asyncDir);
|
|
12
|
+
const resultPath = resultPathFor(resultsDir, id);
|
|
13
|
+
if (!asyncDirExists && !resultPath)
|
|
10
14
|
return;
|
|
11
15
|
return {
|
|
12
|
-
asyncDir:
|
|
13
|
-
resultPath
|
|
16
|
+
asyncDir: asyncDirExists ? asyncDir : null,
|
|
17
|
+
resultPath,
|
|
14
18
|
resolvedId: id
|
|
15
19
|
};
|
|
16
20
|
}
|
|
21
|
+
function readWorkflowResultIdentity(resultPath) {
|
|
22
|
+
let parsed;
|
|
23
|
+
try {
|
|
24
|
+
parsed = JSON.parse(fs.readFileSync(resultPath, "utf-8"));
|
|
25
|
+
} catch {
|
|
26
|
+
return;
|
|
27
|
+
}
|
|
28
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed))
|
|
29
|
+
return;
|
|
30
|
+
const record = parsed;
|
|
31
|
+
return {
|
|
32
|
+
...typeof record.id === "string" ? { id: record.id } : {},
|
|
33
|
+
...typeof record.runId === "string" ? { runId: record.runId } : {},
|
|
34
|
+
...typeof record.toolCallId === "string" ? { toolCallId: record.toolCallId } : {}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
function resultPathFor(resultsDir, runId) {
|
|
38
|
+
const resultPath = resultPayloadPathForIndexedRun(resultsDir, runId) ?? resultFilePath(resultsDir, runId);
|
|
39
|
+
return fs.existsSync(resultPath) ? resultPath : null;
|
|
40
|
+
}
|
|
41
|
+
function toolCallIdMatches(value, query) {
|
|
42
|
+
return value === query;
|
|
43
|
+
}
|
|
44
|
+
function indexedToolCallIdAsyncLocations(toolCallId, asyncDirRoot, resultsDir) {
|
|
45
|
+
const byId = new Map;
|
|
46
|
+
for (const entry of readActiveRunToolCallIndex(asyncDirRoot, toolCallId)) {
|
|
47
|
+
const asyncDir = path.join(asyncDirRoot, entry);
|
|
48
|
+
const status = readStatus(asyncDir);
|
|
49
|
+
if (!status || !toolCallIdMatches(status.toolCallId, toolCallId))
|
|
50
|
+
continue;
|
|
51
|
+
const runId = status.runId || entry;
|
|
52
|
+
byId.set(runId, { asyncDir, resultPath: resultPathFor(resultsDir, runId), resolvedId: runId });
|
|
53
|
+
}
|
|
54
|
+
for (const entry of resultCandidateFilesForToolCall(resultsDir, toolCallId)) {
|
|
55
|
+
const runIdFromFile = entry.slice(0, -".json".length);
|
|
56
|
+
const resultPath = resultPayloadPathForIndexedRun(resultsDir, runIdFromFile) ?? path.join(resultsDir, entry);
|
|
57
|
+
const identity = readWorkflowResultIdentity(resultPath);
|
|
58
|
+
if (!identity || !toolCallIdMatches(identity.toolCallId, toolCallId))
|
|
59
|
+
continue;
|
|
60
|
+
const runId = identity.runId ?? identity.id ?? runIdFromFile;
|
|
61
|
+
const asyncDir = path.join(asyncDirRoot, runId);
|
|
62
|
+
byId.set(runId, { asyncDir: fs.existsSync(asyncDir) ? asyncDir : null, resultPath, resolvedId: runId });
|
|
63
|
+
}
|
|
64
|
+
return [...byId.entries()].map(([id, location]) => ({ id, location }));
|
|
65
|
+
}
|
|
17
66
|
function foregroundIds(state) {
|
|
18
67
|
if (!state)
|
|
19
68
|
return [];
|
|
20
|
-
|
|
69
|
+
const remembered = state.currentSessionId ? [...state.foregroundRuns?.values() ?? []].filter((run) => run.sessionId === state.currentSessionId).map((run) => run.runId) : [];
|
|
70
|
+
return [...new Set([...state.foregroundControls.keys(), ...remembered])];
|
|
71
|
+
}
|
|
72
|
+
function hasExactForegroundId(state, id) {
|
|
73
|
+
if (!state)
|
|
74
|
+
return false;
|
|
75
|
+
if (state.foregroundControls.has(id))
|
|
76
|
+
return true;
|
|
77
|
+
const remembered = state.foregroundRuns?.get(id);
|
|
78
|
+
return Boolean(remembered && state.currentSessionId && remembered.sessionId === state.currentSessionId);
|
|
79
|
+
}
|
|
80
|
+
function exactLiveAsyncToolCallMatch(state, toolCallId, asyncDirRoot, resultsDir) {
|
|
81
|
+
if (!state?.asyncJobs)
|
|
82
|
+
return;
|
|
83
|
+
const matches = [...state.asyncJobs.values()].filter((job) => job.toolCallId === toolCallId);
|
|
84
|
+
if (matches.length > 1)
|
|
85
|
+
throw new Error(`Subagent tool-call id '${toolCallId}' is ambiguous across async runs. Use the returned asyncId instead.`);
|
|
86
|
+
const match = matches[0];
|
|
87
|
+
if (!match)
|
|
88
|
+
return;
|
|
89
|
+
return {
|
|
90
|
+
id: match.asyncId,
|
|
91
|
+
location: {
|
|
92
|
+
asyncDir: fs.existsSync(match.asyncDir) ? match.asyncDir : path.join(asyncDirRoot, match.asyncId),
|
|
93
|
+
resultPath: resultPathFor(resultsDir, match.asyncId),
|
|
94
|
+
resolvedId: match.asyncId
|
|
95
|
+
}
|
|
96
|
+
};
|
|
21
97
|
}
|
|
22
98
|
function nestedScopeFromState(state) {
|
|
23
99
|
if (!state)
|
|
@@ -44,14 +120,22 @@ function asyncPrefixMatches(prefix, asyncDirRoot, resultsDir) {
|
|
|
44
120
|
}
|
|
45
121
|
export function resolveSubagentRunId(id, deps = {}) {
|
|
46
122
|
assertSafeNestedId("id", id);
|
|
47
|
-
const asyncDirRoot = deps.asyncDirRoot ??
|
|
48
|
-
const resultsDir = deps.resultsDir ??
|
|
123
|
+
const asyncDirRoot = deps.asyncDirRoot ?? DIRS.async;
|
|
124
|
+
const resultsDir = deps.resultsDir ?? DIRS.results;
|
|
49
125
|
const nestedScope = deps.nested ?? nestedScopeFromState(deps.state);
|
|
50
|
-
if (deps.state
|
|
126
|
+
if (hasExactForegroundId(deps.state, id))
|
|
51
127
|
return { kind: "foreground", id };
|
|
52
128
|
const exactAsync = exactAsyncLocation(id, asyncDirRoot, resultsDir);
|
|
53
129
|
if (exactAsync)
|
|
54
130
|
return { kind: "async", id, location: exactAsync };
|
|
131
|
+
const exactLiveToolCallMatch = exactLiveAsyncToolCallMatch(deps.state, id, asyncDirRoot, resultsDir);
|
|
132
|
+
if (exactLiveToolCallMatch)
|
|
133
|
+
return { kind: "async", id: exactLiveToolCallMatch.id, location: exactLiveToolCallMatch.location };
|
|
134
|
+
const exactToolCallIdMatches = indexedToolCallIdAsyncLocations(id, asyncDirRoot, resultsDir);
|
|
135
|
+
if (exactToolCallIdMatches.length > 1)
|
|
136
|
+
throw new Error(`Subagent tool-call id '${id}' is ambiguous across async runs. Use the returned asyncId instead.`);
|
|
137
|
+
if (exactToolCallIdMatches[0])
|
|
138
|
+
return { kind: "async", id: exactToolCallIdMatches[0].id, location: exactToolCallIdMatches[0].location };
|
|
55
139
|
const exactNested = findNestedRunMatchesById(id, nestedScope ? { scope: nestedScope } : {});
|
|
56
140
|
if (exactNested.length > 1)
|
|
57
141
|
throw new Error(`Nested run id '${id}' is ambiguous across authorized registries. Provide the full id after stale registries are cleaned up.`);
|