@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
|
@@ -2,8 +2,7 @@ import { randomUUID } from "node:crypto";
|
|
|
2
2
|
import * as fs from "node:fs";
|
|
3
3
|
import * as path from "node:path";
|
|
4
4
|
import {
|
|
5
|
-
|
|
6
|
-
RESULTS_DIR,
|
|
5
|
+
DIRS,
|
|
7
6
|
TEMP_ROOT_DIR
|
|
8
7
|
} from "../../shared/types.js";
|
|
9
8
|
import { isSafeNestedPathId, parseNestedPathEnv, sanitizeNestedPath } from "./nested-path.js";
|
|
@@ -18,9 +17,12 @@ import {
|
|
|
18
17
|
SUBAGENT_PARENT_RUN_ID_ENV
|
|
19
18
|
} from "./dm-args.js";
|
|
20
19
|
import { writeAtomicJson } from "../../shared/atomic-json.js";
|
|
20
|
+
import { sanitizeProcessTerminal } from "../background/process-terminal.js";
|
|
21
|
+
import { THINKING_LEVELS } from "../../shared/model-info.js";
|
|
21
22
|
export const NESTED_EVENTS_DIR = path.join(TEMP_ROOT_DIR, "nested-subagent-events");
|
|
22
23
|
const ROUTE_FILE = "route.json";
|
|
23
24
|
const REGISTRY_FILE = "registry.json";
|
|
25
|
+
const ROUTE_INDEX_DIR = ".route-index";
|
|
24
26
|
const MAX_EVENT_BYTES = 64 * 1024;
|
|
25
27
|
const MAX_STEPS = 12;
|
|
26
28
|
const MAX_CHILDREN = 16;
|
|
@@ -43,6 +45,15 @@ function containedPath(base, candidate) {
|
|
|
43
45
|
function commonRouteRoot(route) {
|
|
44
46
|
return path.dirname(path.resolve(route.eventSink));
|
|
45
47
|
}
|
|
48
|
+
function routeIndexRoot() {
|
|
49
|
+
return path.join(NESTED_EVENTS_DIR, ROUTE_INDEX_DIR, "roots");
|
|
50
|
+
}
|
|
51
|
+
function routeIndexDir(rootRunId) {
|
|
52
|
+
return path.join(routeIndexRoot(), encodeURIComponent(rootRunId));
|
|
53
|
+
}
|
|
54
|
+
function routeIndexPath(rootRunId, capabilityToken) {
|
|
55
|
+
return path.join(routeIndexDir(rootRunId), `${encodeURIComponent(capabilityToken)}.json`);
|
|
56
|
+
}
|
|
46
57
|
function validateRouteShape(route) {
|
|
47
58
|
assertSafeId("rootRunId", route.rootRunId);
|
|
48
59
|
assertSafeId("capabilityToken", route.capabilityToken);
|
|
@@ -61,8 +72,10 @@ export function createNestedRoute(rootRunId) {
|
|
|
61
72
|
const controlInbox = path.join(routeRoot, "controls");
|
|
62
73
|
fs.mkdirSync(eventSink, { recursive: true, mode: 448 });
|
|
63
74
|
fs.mkdirSync(controlInbox, { recursive: true, mode: 448 });
|
|
64
|
-
|
|
65
|
-
|
|
75
|
+
const createdAt = Date.now();
|
|
76
|
+
fs.mkdirSync(routeIndexDir(rootRunId), { recursive: true, mode: 448 });
|
|
77
|
+
writeAtomicJson(routeIndexPath(rootRunId, capabilityToken), { rootRunId, capabilityToken, routeRoot: path.basename(routeRoot), createdAt });
|
|
78
|
+
writeAtomicJson(path.join(routeRoot, ROUTE_FILE), { rootRunId, capabilityToken, createdAt });
|
|
66
79
|
return { rootRunId, eventSink, controlInbox, capabilityToken };
|
|
67
80
|
}
|
|
68
81
|
export function resolveNestedRouteFromEnv(env = process.env) {
|
|
@@ -121,7 +134,9 @@ function sanitizeTokenUsage(value) {
|
|
|
121
134
|
const input = clampNumber(raw.input);
|
|
122
135
|
const output = clampNumber(raw.output);
|
|
123
136
|
const total = clampNumber(raw.total);
|
|
124
|
-
|
|
137
|
+
const window = clampNumber(raw.window);
|
|
138
|
+
const windowPeak = clampNumber(raw.windowPeak);
|
|
139
|
+
return input !== undefined && output !== undefined && total !== undefined ? { input, output, total, ...window !== undefined ? { window } : {}, ...windowPeak !== undefined ? { windowPeak } : {} } : undefined;
|
|
125
140
|
}
|
|
126
141
|
function sanitizeCost(value) {
|
|
127
142
|
if (!value || typeof value !== "object")
|
|
@@ -132,6 +147,56 @@ function sanitizeCost(value) {
|
|
|
132
147
|
const costUsd = clampNumber(raw.costUsd);
|
|
133
148
|
return inputTokens !== undefined && outputTokens !== undefined && costUsd !== undefined ? { inputTokens, outputTokens, costUsd } : undefined;
|
|
134
149
|
}
|
|
150
|
+
function sanitizeLaunchResolvedExtensions(value) {
|
|
151
|
+
if (!value || typeof value !== "object")
|
|
152
|
+
return;
|
|
153
|
+
const raw = value;
|
|
154
|
+
if (raw.version !== 1 || raw.source !== "launch-resolved" || typeof raw.disableAmbientExtensions !== "boolean")
|
|
155
|
+
return;
|
|
156
|
+
const stringList = (input) => Array.isArray(input) ? input.filter((item) => typeof item === "string" && /^sha256:[a-f0-9]{16}$/.test(item)).slice(0, 32) : [];
|
|
157
|
+
const omitted = raw.omitted && typeof raw.omitted === "object" ? raw.omitted : {};
|
|
158
|
+
const omittedCount = (key) => Math.max(0, Math.floor(clampNumber(omitted[key]) ?? 0));
|
|
159
|
+
return {
|
|
160
|
+
version: 1,
|
|
161
|
+
source: "launch-resolved",
|
|
162
|
+
disableAmbientExtensions: raw.disableAmbientExtensions,
|
|
163
|
+
runtime: stringList(raw.runtime),
|
|
164
|
+
configured: stringList(raw.configured),
|
|
165
|
+
effective: stringList(raw.effective),
|
|
166
|
+
omitted: {
|
|
167
|
+
runtime: omittedCount("runtime"),
|
|
168
|
+
configured: omittedCount("configured"),
|
|
169
|
+
effective: omittedCount("effective")
|
|
170
|
+
}
|
|
171
|
+
};
|
|
172
|
+
}
|
|
173
|
+
function sanitizeRuntimeAcknowledgedExtensions(value) {
|
|
174
|
+
if (!value || typeof value !== "object")
|
|
175
|
+
return;
|
|
176
|
+
const raw = value;
|
|
177
|
+
if (raw.version !== 1 || raw.source !== "child-runtime" || !Array.isArray(raw.ids))
|
|
178
|
+
return;
|
|
179
|
+
const ids = [];
|
|
180
|
+
const seen = new Set;
|
|
181
|
+
for (const item of raw.ids) {
|
|
182
|
+
if (typeof item !== "string" || item.length === 0 || item.length > 128 || !/^[A-Za-z0-9._:@+-]+$/.test(item) || item.includes("..") || item.includes("/") || item.includes("\\") || seen.has(item))
|
|
183
|
+
continue;
|
|
184
|
+
seen.add(item);
|
|
185
|
+
ids.push(item);
|
|
186
|
+
}
|
|
187
|
+
if (ids.length === 0)
|
|
188
|
+
return;
|
|
189
|
+
return {
|
|
190
|
+
version: 1,
|
|
191
|
+
source: "child-runtime",
|
|
192
|
+
ids: ids.slice(0, 32),
|
|
193
|
+
omitted: Math.max(0, ids.length - 32) + Math.max(0, Math.floor(clampNumber(raw.omitted) ?? 0))
|
|
194
|
+
};
|
|
195
|
+
}
|
|
196
|
+
function runtimeAcknowledgedEntry(value) {
|
|
197
|
+
const sanitized = sanitizeRuntimeAcknowledgedExtensions(value);
|
|
198
|
+
return sanitized ? { runtimeAcknowledgedExtensions: sanitized } : {};
|
|
199
|
+
}
|
|
135
200
|
function sanitizeTurnBudget(value) {
|
|
136
201
|
if (!value || typeof value !== "object")
|
|
137
202
|
return;
|
|
@@ -139,7 +204,7 @@ function sanitizeTurnBudget(value) {
|
|
|
139
204
|
const maxTurns = clampNumber(raw.maxTurns);
|
|
140
205
|
const graceTurns = clampNumber(raw.graceTurns);
|
|
141
206
|
const turnCount = clampNumber(raw.turnCount);
|
|
142
|
-
const outcome = raw.outcome === "within-budget" || raw.outcome === "wrap-up-requested" || raw.outcome === "exceeded" ? raw.outcome : undefined;
|
|
207
|
+
const outcome = raw.outcome === "within-budget" || raw.outcome === "wrap-up-requested" || raw.outcome === "termination-deferred" || raw.outcome === "exceeded" ? raw.outcome : undefined;
|
|
143
208
|
if (maxTurns === undefined || graceTurns === undefined || turnCount === undefined || !outcome)
|
|
144
209
|
return;
|
|
145
210
|
return {
|
|
@@ -148,11 +213,12 @@ function sanitizeTurnBudget(value) {
|
|
|
148
213
|
turnCount,
|
|
149
214
|
outcome,
|
|
150
215
|
...clampNumber(raw.wrapUpRequestedAtTurn) !== undefined ? { wrapUpRequestedAtTurn: clampNumber(raw.wrapUpRequestedAtTurn) } : {},
|
|
216
|
+
...clampNumber(raw.terminationDeferredAtTurn) !== undefined ? { terminationDeferredAtTurn: clampNumber(raw.terminationDeferredAtTurn) } : {},
|
|
151
217
|
...clampNumber(raw.exceededAtTurn) !== undefined ? { exceededAtTurn: clampNumber(raw.exceededAtTurn) } : {}
|
|
152
218
|
};
|
|
153
219
|
}
|
|
154
220
|
function sanitizeState(value, fallback) {
|
|
155
|
-
return value === "queued" || value === "running" || value === "complete" || value === "failed" || value === "paused" ? value : fallback;
|
|
221
|
+
return value === "queued" || value === "running" || value === "complete" || value === "failed" || value === "partial" || value === "paused" || value === "stopped" ? value : fallback;
|
|
156
222
|
}
|
|
157
223
|
function sanitizeStep(input, depth) {
|
|
158
224
|
if (!input || typeof input !== "object")
|
|
@@ -161,10 +227,15 @@ function sanitizeStep(input, depth) {
|
|
|
161
227
|
const agent = stringValue(raw.agent, 128);
|
|
162
228
|
if (!agent)
|
|
163
229
|
return;
|
|
164
|
-
const status = raw.status === "pending" || raw.status === "running" || raw.status === "complete" || raw.status === "completed" || raw.status === "failed" || raw.status === "paused" ? raw.status : "pending";
|
|
230
|
+
const status = raw.status === "pending" || raw.status === "running" || raw.status === "complete" || raw.status === "completed" || raw.status === "failed" || raw.status === "paused" || raw.status === "stopped" ? raw.status : "pending";
|
|
231
|
+
const model = stringValue(raw.model);
|
|
232
|
+
const thinking = THINKING_LEVELS.find((level) => level === raw.thinking);
|
|
165
233
|
return {
|
|
166
234
|
agent,
|
|
167
235
|
status,
|
|
236
|
+
...model ? { model } : {},
|
|
237
|
+
...thinking ? { thinking } : {},
|
|
238
|
+
...stringValue(raw.sessionName, 256) ? { sessionName: stringValue(raw.sessionName, 256) } : {},
|
|
168
239
|
...stringValue(raw.sessionFile, 2048) ? { sessionFile: stringValue(raw.sessionFile, 2048) } : {},
|
|
169
240
|
...raw.activityState === "active_long_running" || raw.activityState === "needs_attention" ? { activityState: raw.activityState } : {},
|
|
170
241
|
...clampNumber(raw.lastActivityAt) !== undefined ? { lastActivityAt: clampNumber(raw.lastActivityAt) } : {},
|
|
@@ -177,9 +248,12 @@ function sanitizeStep(input, depth) {
|
|
|
177
248
|
...clampNumber(raw.endedAt) !== undefined ? { endedAt: clampNumber(raw.endedAt) } : {},
|
|
178
249
|
...stringValue(raw.error, 1024) ? { error: stringValue(raw.error, 1024) } : {},
|
|
179
250
|
...raw.timedOut === true ? { timedOut: true } : {},
|
|
251
|
+
...raw.stopped === true ? { stopped: true } : {},
|
|
180
252
|
...sanitizeTurnBudget(raw.turnBudget) ? { turnBudget: sanitizeTurnBudget(raw.turnBudget) } : {},
|
|
181
253
|
...raw.turnBudgetExceeded === true ? { turnBudgetExceeded: true } : {},
|
|
182
254
|
...raw.wrapUpRequested === true ? { wrapUpRequested: true } : {},
|
|
255
|
+
...sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) ? { launchResolvedExtensions: sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) } : {},
|
|
256
|
+
...sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) ? { runtimeAcknowledgedExtensions: sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) } : {},
|
|
183
257
|
...depth < MAX_DEPTH && Array.isArray(raw.children) ? { children: raw.children.map((child) => sanitizeSummary(child, depth + 1)).filter((child) => Boolean(child)).slice(0, MAX_CHILDREN) } : {}
|
|
184
258
|
};
|
|
185
259
|
}
|
|
@@ -201,6 +275,9 @@ export function sanitizeSummary(input, depth = 0) {
|
|
|
201
275
|
depth: Math.min(Math.max(0, clampNumber(raw.depth) ?? 0), MAX_DEPTH),
|
|
202
276
|
path: pathParts,
|
|
203
277
|
state: sanitizeState(raw.state, "running"),
|
|
278
|
+
...stringValue(raw.sessionName, 256) ? { sessionName: stringValue(raw.sessionName, 256) } : {},
|
|
279
|
+
...stringValue(raw.model) ? { model: stringValue(raw.model) } : {},
|
|
280
|
+
...THINKING_LEVELS.find((level) => level === raw.thinking) ? { thinking: THINKING_LEVELS.find((level) => level === raw.thinking) } : {},
|
|
204
281
|
...stringValue(raw.asyncDir, 2048) ? { asyncDir: stringValue(raw.asyncDir, 2048) } : {},
|
|
205
282
|
...clampNumber(raw.pid) !== undefined && clampNumber(raw.pid) > 0 && Number.isInteger(clampNumber(raw.pid)) ? { pid: clampNumber(raw.pid) } : {},
|
|
206
283
|
...stringValue(raw.sessionId, 256) ? { sessionId: stringValue(raw.sessionId, 256) } : {},
|
|
@@ -231,10 +308,13 @@ export function sanitizeSummary(input, depth = 0) {
|
|
|
231
308
|
...clampNumber(raw.timeoutMs) !== undefined ? { timeoutMs: clampNumber(raw.timeoutMs) } : {},
|
|
232
309
|
...clampNumber(raw.deadlineAt) !== undefined ? { deadlineAt: clampNumber(raw.deadlineAt) } : {},
|
|
233
310
|
...raw.timedOut === true ? { timedOut: true } : {},
|
|
311
|
+
...raw.stopped === true ? { stopped: true } : {},
|
|
234
312
|
...sanitizeTurnBudget(raw.turnBudget) ? { turnBudget: sanitizeTurnBudget(raw.turnBudget) } : {},
|
|
235
313
|
...raw.turnBudgetExceeded === true ? { turnBudgetExceeded: true } : {},
|
|
236
314
|
...raw.wrapUpRequested === true ? { wrapUpRequested: true } : {},
|
|
237
315
|
...stringValue(raw.error, 1024) ? { error: stringValue(raw.error, 1024) } : {},
|
|
316
|
+
...sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) ? { launchResolvedExtensions: sanitizeLaunchResolvedExtensions(raw.launchResolvedExtensions) } : {},
|
|
317
|
+
...sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) ? { runtimeAcknowledgedExtensions: sanitizeRuntimeAcknowledgedExtensions(raw.runtimeAcknowledgedExtensions) } : {},
|
|
238
318
|
...steps && steps.length > 0 ? { steps } : {},
|
|
239
319
|
...depth < MAX_DEPTH && Array.isArray(raw.children) ? { children: raw.children.map((child) => sanitizeSummary(child, depth + 1)).filter((child) => Boolean(child)).slice(0, MAX_CHILDREN) } : {}
|
|
240
320
|
};
|
|
@@ -290,7 +370,38 @@ export function parseNestedEventRecords(content, route) {
|
|
|
290
370
|
`) ? undefined : -1).map((line) => line.trim() ? parseRecord(line, route) : undefined).filter((event) => Boolean(event));
|
|
291
371
|
}
|
|
292
372
|
function terminal(state) {
|
|
293
|
-
return state === "complete" || state === "failed" || state === "paused";
|
|
373
|
+
return state === "complete" || state === "failed" || state === "partial" || state === "paused" || state === "stopped";
|
|
374
|
+
}
|
|
375
|
+
function mergeBoundedChildren(existing, incoming) {
|
|
376
|
+
if (incoming === undefined)
|
|
377
|
+
return existing?.slice(0, MAX_CHILDREN);
|
|
378
|
+
const incomingById = new Map(incoming.map((child) => [child.id, child]));
|
|
379
|
+
const merged = (existing ?? []).map((child) => incomingById.get(child.id) ?? child);
|
|
380
|
+
for (const child of incoming) {
|
|
381
|
+
if (!existing?.some((prior) => prior.id === child.id))
|
|
382
|
+
merged.push(child);
|
|
383
|
+
}
|
|
384
|
+
return merged.slice(0, MAX_CHILDREN);
|
|
385
|
+
}
|
|
386
|
+
function mergeStepSummary(existing, incoming) {
|
|
387
|
+
if (!existing || existing.agent !== incoming.agent)
|
|
388
|
+
return { ...incoming, ...incoming.children ? { children: incoming.children.slice(0, MAX_CHILDREN) } : {} };
|
|
389
|
+
const metadata = { ...existing };
|
|
390
|
+
delete metadata.status;
|
|
391
|
+
delete metadata.activityState;
|
|
392
|
+
delete metadata.lastActivityAt;
|
|
393
|
+
delete metadata.currentTool;
|
|
394
|
+
delete metadata.currentToolStartedAt;
|
|
395
|
+
delete metadata.currentPath;
|
|
396
|
+
delete metadata.turnCount;
|
|
397
|
+
delete metadata.toolCount;
|
|
398
|
+
delete metadata.children;
|
|
399
|
+
const children = mergeBoundedChildren(existing.children, incoming.children);
|
|
400
|
+
return {
|
|
401
|
+
...metadata,
|
|
402
|
+
...incoming,
|
|
403
|
+
...children ? { children } : {}
|
|
404
|
+
};
|
|
294
405
|
}
|
|
295
406
|
function mergeSummary(existing, event) {
|
|
296
407
|
const incomingState = event.type === "subagent.nested.completed" && event.child.state === "running" ? "complete" : event.child.state;
|
|
@@ -305,7 +416,18 @@ function mergeSummary(existing, event) {
|
|
|
305
416
|
return existing;
|
|
306
417
|
if (terminal(existing.state) && terminal(incoming.state) && incomingUpdate === existingUpdate)
|
|
307
418
|
return existing;
|
|
308
|
-
|
|
419
|
+
const existingSteps = existing.steps ?? [];
|
|
420
|
+
const incomingSteps = incoming.steps;
|
|
421
|
+
const steps = incomingSteps === undefined ? existing.steps : Array.from({ length: Math.min(MAX_STEPS, Math.max(existingSteps.length, incomingSteps.length)) }, (_, index) => incomingSteps[index] ? mergeStepSummary(existingSteps[index], incomingSteps[index]) : existingSteps[index]).filter((step) => Boolean(step));
|
|
422
|
+
const children = mergeBoundedChildren(existing.children, incoming.children);
|
|
423
|
+
return {
|
|
424
|
+
...existing,
|
|
425
|
+
...incoming,
|
|
426
|
+
...steps ? { steps } : {},
|
|
427
|
+
...children ? { children } : {},
|
|
428
|
+
state: incoming.state,
|
|
429
|
+
lastUpdate: Math.max(existingUpdate, incomingUpdate)
|
|
430
|
+
};
|
|
309
431
|
}
|
|
310
432
|
function attachChild(children, event) {
|
|
311
433
|
let updated = false;
|
|
@@ -340,67 +462,60 @@ export function applyNestedEvent(registry, event) {
|
|
|
340
462
|
function registryPath(route) {
|
|
341
463
|
return path.join(commonRouteRoot(route), REGISTRY_FILE);
|
|
342
464
|
}
|
|
465
|
+
function routeFromIndexEntry(rootRunId, filePath) {
|
|
466
|
+
try {
|
|
467
|
+
const metadata = JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
468
|
+
if (metadata.rootRunId !== rootRunId || typeof metadata.capabilityToken !== "string" || typeof metadata.routeRoot !== "string")
|
|
469
|
+
return;
|
|
470
|
+
const routeRoot = path.join(NESTED_EVENTS_DIR, path.basename(metadata.routeRoot));
|
|
471
|
+
const route = {
|
|
472
|
+
rootRunId,
|
|
473
|
+
eventSink: path.join(routeRoot, "events"),
|
|
474
|
+
controlInbox: path.join(routeRoot, "controls"),
|
|
475
|
+
capabilityToken: metadata.capabilityToken
|
|
476
|
+
};
|
|
477
|
+
validateRouteShape(route);
|
|
478
|
+
if (!fs.statSync(route.eventSink).isDirectory() || !fs.statSync(route.controlInbox).isDirectory())
|
|
479
|
+
return;
|
|
480
|
+
const routeFilePath = path.join(routeRoot, ROUTE_FILE);
|
|
481
|
+
try {
|
|
482
|
+
const routeFile = JSON.parse(fs.readFileSync(routeFilePath, "utf-8"));
|
|
483
|
+
if (routeFile.rootRunId !== rootRunId || routeFile.capabilityToken !== metadata.capabilityToken)
|
|
484
|
+
return;
|
|
485
|
+
} catch (error) {
|
|
486
|
+
if (error.code !== "ENOENT")
|
|
487
|
+
return;
|
|
488
|
+
try {
|
|
489
|
+
writeAtomicJson(routeFilePath, { rootRunId, capabilityToken: metadata.capabilityToken, createdAt: typeof metadata.createdAt === "number" ? metadata.createdAt : Date.now() });
|
|
490
|
+
} catch {}
|
|
491
|
+
}
|
|
492
|
+
return route;
|
|
493
|
+
} catch {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
}
|
|
343
497
|
export function findNestedRouteForRootId(rootRunId) {
|
|
344
498
|
assertSafeId("rootRunId", rootRunId);
|
|
345
499
|
let entries;
|
|
346
500
|
try {
|
|
347
|
-
entries = fs.readdirSync(
|
|
501
|
+
entries = fs.readdirSync(routeIndexDir(rootRunId));
|
|
348
502
|
} catch (error) {
|
|
349
503
|
if (error.code === "ENOENT")
|
|
350
504
|
return;
|
|
351
505
|
throw error;
|
|
352
506
|
}
|
|
353
507
|
for (const entry of entries) {
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
const routeRoot = path.join(NESTED_EVENTS_DIR, entry);
|
|
357
|
-
try {
|
|
358
|
-
const metadata = JSON.parse(fs.readFileSync(path.join(routeRoot, ROUTE_FILE), "utf-8"));
|
|
359
|
-
if (metadata.rootRunId !== rootRunId || typeof metadata.capabilityToken !== "string")
|
|
360
|
-
continue;
|
|
361
|
-
const route = {
|
|
362
|
-
rootRunId,
|
|
363
|
-
eventSink: path.join(routeRoot, "events"),
|
|
364
|
-
controlInbox: path.join(routeRoot, "controls"),
|
|
365
|
-
capabilityToken: metadata.capabilityToken
|
|
366
|
-
};
|
|
367
|
-
validateRouteShape(route);
|
|
508
|
+
const route = routeFromIndexEntry(rootRunId, path.join(routeIndexDir(rootRunId), entry));
|
|
509
|
+
if (route)
|
|
368
510
|
return route;
|
|
369
|
-
} catch {
|
|
370
|
-
continue;
|
|
371
|
-
}
|
|
372
511
|
}
|
|
373
512
|
return;
|
|
374
513
|
}
|
|
375
514
|
export function buildNestedRouteIndex() {
|
|
376
|
-
let entries;
|
|
377
|
-
try {
|
|
378
|
-
entries = fs.readdirSync(NESTED_EVENTS_DIR);
|
|
379
|
-
} catch (error) {
|
|
380
|
-
if (error.code === "ENOENT")
|
|
381
|
-
return new Map;
|
|
382
|
-
throw error;
|
|
383
|
-
}
|
|
384
515
|
const index = new Map;
|
|
385
|
-
for (const
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
const metadata = JSON.parse(fs.readFileSync(path.join(routeRoot, ROUTE_FILE), "utf-8"));
|
|
389
|
-
if (typeof metadata.rootRunId !== "string" || typeof metadata.capabilityToken !== "string")
|
|
390
|
-
continue;
|
|
391
|
-
if (index.has(metadata.rootRunId))
|
|
392
|
-
continue;
|
|
393
|
-
const route = {
|
|
394
|
-
rootRunId: metadata.rootRunId,
|
|
395
|
-
eventSink: path.join(routeRoot, "events"),
|
|
396
|
-
controlInbox: path.join(routeRoot, "controls"),
|
|
397
|
-
capabilityToken: metadata.capabilityToken
|
|
398
|
-
};
|
|
399
|
-
validateRouteShape(route);
|
|
400
|
-
index.set(metadata.rootRunId, route);
|
|
401
|
-
} catch {
|
|
402
|
-
continue;
|
|
403
|
-
}
|
|
516
|
+
for (const route of listNestedRoutes()) {
|
|
517
|
+
if (!index.has(route.rootRunId))
|
|
518
|
+
index.set(route.rootRunId, route);
|
|
404
519
|
}
|
|
405
520
|
return index;
|
|
406
521
|
}
|
|
@@ -442,29 +557,28 @@ function collectScopedNestedRuns(children, scope, output = []) {
|
|
|
442
557
|
return output;
|
|
443
558
|
}
|
|
444
559
|
function listNestedRoutes() {
|
|
445
|
-
let
|
|
560
|
+
let rootEntries;
|
|
446
561
|
try {
|
|
447
|
-
|
|
562
|
+
rootEntries = fs.readdirSync(routeIndexRoot());
|
|
448
563
|
} catch (error) {
|
|
449
564
|
if (error.code === "ENOENT")
|
|
450
565
|
return [];
|
|
451
566
|
throw error;
|
|
452
567
|
}
|
|
453
568
|
const routes = [];
|
|
454
|
-
for (const
|
|
455
|
-
|
|
569
|
+
for (const rootEntry of rootEntries) {
|
|
570
|
+
let rootRunId;
|
|
456
571
|
try {
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
routes.push(route);
|
|
572
|
+
rootRunId = decodeURIComponent(rootEntry);
|
|
573
|
+
} catch {
|
|
574
|
+
continue;
|
|
575
|
+
}
|
|
576
|
+
try {
|
|
577
|
+
for (const entry of fs.readdirSync(path.join(routeIndexRoot(), rootEntry))) {
|
|
578
|
+
const route = routeFromIndexEntry(rootRunId, path.join(routeIndexRoot(), rootEntry, entry));
|
|
579
|
+
if (route)
|
|
580
|
+
routes.push(route);
|
|
581
|
+
}
|
|
468
582
|
} catch {
|
|
469
583
|
continue;
|
|
470
584
|
}
|
|
@@ -534,7 +648,10 @@ export function projectNestedEvents(route) {
|
|
|
534
648
|
} catch {
|
|
535
649
|
continue;
|
|
536
650
|
}
|
|
537
|
-
|
|
651
|
+
const records = parseNestedEventRecords(content, route);
|
|
652
|
+
if (records.length === 0)
|
|
653
|
+
continue;
|
|
654
|
+
for (const event of records) {
|
|
538
655
|
registry = applyNestedEvent(registry, event);
|
|
539
656
|
changed = true;
|
|
540
657
|
}
|
|
@@ -542,8 +659,27 @@ export function projectNestedEvents(route) {
|
|
|
542
659
|
changed = true;
|
|
543
660
|
}
|
|
544
661
|
if (changed) {
|
|
545
|
-
|
|
662
|
+
const processedEvents = [...seen];
|
|
663
|
+
const retainedEvents = processedEvents.slice(-1000);
|
|
664
|
+
const evictedEvents = processedEvents.slice(0, -1000);
|
|
665
|
+
registry = { ...registry, processedEvents: retainedEvents };
|
|
546
666
|
writeAtomicJson(registryPath(route), registry);
|
|
667
|
+
for (const entry of evictedEvents) {
|
|
668
|
+
const eventPath = path.join(route.eventSink, entry);
|
|
669
|
+
if (!containedPath(route.eventSink, eventPath))
|
|
670
|
+
continue;
|
|
671
|
+
try {
|
|
672
|
+
const stat = fs.statSync(eventPath);
|
|
673
|
+
if (!stat.isFile() || stat.size > MAX_EVENT_BYTES)
|
|
674
|
+
continue;
|
|
675
|
+
const content = fs.readFileSync(eventPath, "utf-8");
|
|
676
|
+
const hasStatusRecord = parseNestedEventRecords(content, route).length > 0;
|
|
677
|
+
const hasControlResult = content.split(`
|
|
678
|
+
`).some((line) => line.trim() && parseControlResult(line.trim(), route));
|
|
679
|
+
if (hasStatusRecord && !hasControlResult)
|
|
680
|
+
fs.unlinkSync(eventPath);
|
|
681
|
+
} catch {}
|
|
682
|
+
}
|
|
547
683
|
}
|
|
548
684
|
return registry;
|
|
549
685
|
}
|
|
@@ -695,38 +831,46 @@ export function writeNestedControlResult(route, result) {
|
|
|
695
831
|
throw new Error("Nested control result failed validation.");
|
|
696
832
|
writeRouteRecord(route.eventSink, sanitized.ts, sanitized);
|
|
697
833
|
}
|
|
698
|
-
|
|
834
|
+
function readControlResultsFromFile(route, eventPath) {
|
|
835
|
+
if (!containedPath(route.eventSink, eventPath))
|
|
836
|
+
return [];
|
|
837
|
+
try {
|
|
838
|
+
const stat = fs.statSync(eventPath);
|
|
839
|
+
if (!stat.isFile() || stat.size > MAX_EVENT_BYTES)
|
|
840
|
+
return [];
|
|
841
|
+
const content = fs.readFileSync(eventPath, "utf-8");
|
|
842
|
+
const lines = content.includes(`
|
|
843
|
+
`) ? content.split(`
|
|
844
|
+
`).filter((line) => line.trim()) : [content];
|
|
845
|
+
return lines.map((line) => parseControlResult(line, route)).filter((result) => Boolean(result));
|
|
846
|
+
} catch {
|
|
847
|
+
return [];
|
|
848
|
+
}
|
|
849
|
+
}
|
|
850
|
+
function listNestedEventFiles(route) {
|
|
699
851
|
validateRouteShape(route);
|
|
700
|
-
let entries = [];
|
|
701
852
|
try {
|
|
702
|
-
|
|
853
|
+
return fs.readdirSync(route.eventSink).filter((entry) => entry.endsWith(".json") || entry.endsWith(".jsonl"));
|
|
703
854
|
} catch (error) {
|
|
704
|
-
if (error.code
|
|
705
|
-
|
|
855
|
+
if (error.code === "ENOENT")
|
|
856
|
+
return [];
|
|
857
|
+
throw error;
|
|
706
858
|
}
|
|
707
|
-
|
|
859
|
+
}
|
|
860
|
+
export function snapshotNestedEventFiles(route) {
|
|
861
|
+
return new Set(listNestedEventFiles(route));
|
|
862
|
+
}
|
|
863
|
+
export function findNestedControlResult(route, requestId, targetRunId, ignoredFiles) {
|
|
864
|
+
const entries = listNestedEventFiles(route).filter((entry) => !ignoredFiles.has(entry)).sort().reverse();
|
|
708
865
|
for (const entry of entries) {
|
|
709
|
-
const
|
|
710
|
-
if (
|
|
711
|
-
|
|
712
|
-
try {
|
|
713
|
-
const stat = fs.statSync(eventPath);
|
|
714
|
-
if (!stat.isFile() || stat.size > MAX_EVENT_BYTES)
|
|
715
|
-
continue;
|
|
716
|
-
const content = fs.readFileSync(eventPath, "utf-8");
|
|
717
|
-
const lines = content.includes(`
|
|
718
|
-
`) ? content.split(`
|
|
719
|
-
`).filter((line) => line.trim()) : [content];
|
|
720
|
-
for (const line of lines) {
|
|
721
|
-
const result = parseControlResult(line, route);
|
|
722
|
-
if (result)
|
|
723
|
-
results.push(result);
|
|
724
|
-
}
|
|
725
|
-
} catch {
|
|
726
|
-
continue;
|
|
727
|
-
}
|
|
866
|
+
const result = readControlResultsFromFile(route, path.join(route.eventSink, entry)).find((candidate) => candidate.requestId === requestId && candidate.targetRunId === targetRunId);
|
|
867
|
+
if (result)
|
|
868
|
+
return result;
|
|
728
869
|
}
|
|
729
|
-
return
|
|
870
|
+
return;
|
|
871
|
+
}
|
|
872
|
+
export function readNestedControlResults(route) {
|
|
873
|
+
return listNestedEventFiles(route).sort().flatMap((entry) => readControlResultsFromFile(route, path.join(route.eventSink, entry)));
|
|
730
874
|
}
|
|
731
875
|
export function nestedRouteEnv(route) {
|
|
732
876
|
return {
|
|
@@ -791,6 +935,14 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
|
|
|
791
935
|
...status.pid ? { pid: status.pid } : {},
|
|
792
936
|
...status.sessionId ? { sessionId: status.sessionId } : {},
|
|
793
937
|
mode: status.mode ?? fallback.mode,
|
|
938
|
+
...status.steps?.length === 1 && status.steps[0]?.model ? { model: status.steps[0].model } : {},
|
|
939
|
+
...status.steps?.length === 1 && status.steps[0]?.thinking ? { thinking: status.steps[0].thinking } : {},
|
|
940
|
+
...status.steps?.length === 1 && status.steps[0]?.sessionName ? { sessionName: status.steps[0].sessionName } : {},
|
|
941
|
+
...status.processTerminal ? { processTerminal: sanitizeProcessTerminal(status.processTerminal, { runId: status.runId || fallback.id, runnerProcessInstanceId: status.processTerminal.runnerProcessInstanceId }, `${asyncDir}/status.json`) } : {},
|
|
942
|
+
...status.launchResolvedExtensions ? { launchResolvedExtensions: status.launchResolvedExtensions } : {},
|
|
943
|
+
...runtimeAcknowledgedEntry(status.runtimeAcknowledgedExtensions),
|
|
944
|
+
...status.capabilityCeiling ? { capabilityCeiling: status.capabilityCeiling } : {},
|
|
945
|
+
...status.capabilityAudit ? { capabilityAudit: status.capabilityAudit } : {},
|
|
794
946
|
state: status.state,
|
|
795
947
|
...status.currentStep !== undefined ? { currentStep: status.currentStep } : {},
|
|
796
948
|
...status.chainStepCount !== undefined ? { chainStepCount: status.chainStepCount } : {},
|
|
@@ -805,6 +957,7 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
|
|
|
805
957
|
...status.timeoutMs !== undefined ? { timeoutMs: status.timeoutMs } : {},
|
|
806
958
|
...status.deadlineAt !== undefined ? { deadlineAt: status.deadlineAt } : {},
|
|
807
959
|
...status.timedOut !== undefined ? { timedOut: status.timedOut } : {},
|
|
960
|
+
...status.stopped !== undefined ? { stopped: status.stopped } : {},
|
|
808
961
|
...status.turnBudget ? { turnBudget: status.turnBudget } : {},
|
|
809
962
|
...status.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: status.turnBudgetExceeded } : {},
|
|
810
963
|
...status.wrapUpRequested !== undefined ? { wrapUpRequested: status.wrapUpRequested } : {},
|
|
@@ -813,9 +966,12 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
|
|
|
813
966
|
...status.endedAt !== undefined ? { endedAt: status.endedAt } : {},
|
|
814
967
|
lastUpdate: status.lastUpdate ?? fallback.ts,
|
|
815
968
|
...status.sessionFile ? { sessionFile: status.sessionFile } : {},
|
|
816
|
-
...status.steps?.length ? { steps: status.steps.map((step) => ({
|
|
969
|
+
...status.steps?.length ? { steps: status.steps.map((step, index) => ({
|
|
817
970
|
agent: step.agent,
|
|
971
|
+
...step.sessionName ? { sessionName: step.sessionName } : {},
|
|
818
972
|
status: step.status,
|
|
973
|
+
...step.model ? { model: step.model } : {},
|
|
974
|
+
...step.thinking ? { thinking: step.thinking } : {},
|
|
819
975
|
...step.sessionFile ? { sessionFile: step.sessionFile } : {},
|
|
820
976
|
...step.activityState ? { activityState: step.activityState } : {},
|
|
821
977
|
...step.lastActivityAt !== undefined ? { lastActivityAt: step.lastActivityAt } : {},
|
|
@@ -827,10 +983,16 @@ export function nestedSummaryFromAsyncStatus(status, asyncDir, fallback) {
|
|
|
827
983
|
...step.startedAt !== undefined ? { startedAt: step.startedAt } : {},
|
|
828
984
|
...step.endedAt !== undefined ? { endedAt: step.endedAt } : {},
|
|
829
985
|
...step.error ? { error: step.error } : {},
|
|
986
|
+
...step.launchResolvedExtensions ? { launchResolvedExtensions: step.launchResolvedExtensions } : {},
|
|
987
|
+
...runtimeAcknowledgedEntry(step.runtimeAcknowledgedExtensions),
|
|
830
988
|
...step.timedOut !== undefined ? { timedOut: step.timedOut } : {},
|
|
989
|
+
...step.stopped !== undefined ? { stopped: step.stopped } : {},
|
|
831
990
|
...step.turnBudget ? { turnBudget: step.turnBudget } : {},
|
|
832
991
|
...step.turnBudgetExceeded !== undefined ? { turnBudgetExceeded: step.turnBudgetExceeded } : {},
|
|
833
|
-
...step.wrapUpRequested !== undefined ? { wrapUpRequested: step.wrapUpRequested } : {}
|
|
992
|
+
...step.wrapUpRequested !== undefined ? { wrapUpRequested: step.wrapUpRequested } : {},
|
|
993
|
+
...step.processTerminal ? { processTerminal: sanitizeProcessTerminal(step.processTerminal, { runId: status.runId || fallback.id, runnerProcessInstanceId: step.processTerminal.runnerProcessInstanceId }, `${asyncDir}/status.json step ${index}`) } : {},
|
|
994
|
+
...step.capabilityCeiling ? { capabilityCeiling: step.capabilityCeiling } : {},
|
|
995
|
+
...step.capabilityAudit ? { capabilityAudit: step.capabilityAudit } : {}
|
|
834
996
|
})).slice(0, MAX_STEPS) } : {}
|
|
835
997
|
};
|
|
836
998
|
}
|
|
@@ -842,10 +1004,10 @@ export function nestedArtifactEnv(rootRunId, parentRunId) {
|
|
|
842
1004
|
}
|
|
843
1005
|
export function isTopLevelAsyncDir(asyncDir) {
|
|
844
1006
|
const resolved = path.resolve(asyncDir);
|
|
845
|
-
return containedPath(
|
|
1007
|
+
return containedPath(DIRS.async, resolved) && !containedPath(path.join(TEMP_ROOT_DIR, "nested-subagent-runs"), resolved);
|
|
846
1008
|
}
|
|
847
1009
|
export function nestedResultsPath(rootRunId, id) {
|
|
848
1010
|
assertSafeId("rootRunId", rootRunId);
|
|
849
1011
|
assertSafeId("id", id);
|
|
850
|
-
return path.join(
|
|
1012
|
+
return path.join(DIRS.results, "nested", rootRunId, `${id}.json`);
|
|
851
1013
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { formatDuration,
|
|
1
|
+
import { formatDuration, formatModelThinking, formatTokenUsage, shortenPath } from "../../shared/formatters.js";
|
|
2
2
|
import { formatActivityLabel } from "../../shared/status-format.js";
|
|
3
3
|
export function countNestedRuns(children) {
|
|
4
|
-
const counts = { total: 0, running: 0, paused: 0, complete: 0, failed: 0, queued: 0 };
|
|
4
|
+
const counts = { total: 0, running: 0, paused: 0, complete: 0, failed: 0, partial: 0, rejected: 0, stopped: 0, queued: 0 };
|
|
5
5
|
for (const child of children ?? []) {
|
|
6
6
|
counts.total++;
|
|
7
7
|
counts[child.state]++;
|
|
@@ -11,6 +11,9 @@ export function countNestedRuns(children) {
|
|
|
11
11
|
counts.paused += nested.paused;
|
|
12
12
|
counts.complete += nested.complete;
|
|
13
13
|
counts.failed += nested.failed;
|
|
14
|
+
counts.partial += nested.partial;
|
|
15
|
+
counts.rejected += nested.rejected;
|
|
16
|
+
counts.stopped += nested.stopped;
|
|
14
17
|
counts.queued += nested.queued;
|
|
15
18
|
}
|
|
16
19
|
return counts;
|
|
@@ -23,12 +26,17 @@ export function formatNestedAggregate(children) {
|
|
|
23
26
|
counts.running > 0 ? `${counts.running} running` : "",
|
|
24
27
|
counts.paused > 0 ? `${counts.paused} paused` : "",
|
|
25
28
|
counts.failed > 0 ? `${counts.failed} failed` : "",
|
|
29
|
+
counts.partial > 0 ? `${counts.partial} partial` : "",
|
|
30
|
+
counts.rejected > 0 ? `${counts.rejected} rejected` : "",
|
|
31
|
+
counts.stopped > 0 ? `${counts.stopped} stopped` : "",
|
|
26
32
|
counts.complete > 0 ? `${counts.complete} complete` : "",
|
|
27
33
|
counts.queued > 0 ? `${counts.queued} queued` : ""
|
|
28
34
|
].filter(Boolean);
|
|
29
35
|
return `+${counts.total} nested run${counts.total === 1 ? "" : "s"}${parts.length ? ` (${parts.join(", ")})` : ""}`;
|
|
30
36
|
}
|
|
31
37
|
function nestedRunLabel(run) {
|
|
38
|
+
if (run.sessionName?.trim())
|
|
39
|
+
return run.sessionName.trim();
|
|
32
40
|
if (run.agent)
|
|
33
41
|
return run.agent;
|
|
34
42
|
if (run.agents?.length)
|
|
@@ -48,7 +56,7 @@ function formatNestedActivity(input) {
|
|
|
48
56
|
if (input.toolCount !== undefined)
|
|
49
57
|
facts.push(`${input.toolCount} tools`);
|
|
50
58
|
if (input.totalTokens)
|
|
51
|
-
facts.push(
|
|
59
|
+
facts.push(formatTokenUsage(input.totalTokens));
|
|
52
60
|
const activity = formatActivityLabel(input.lastActivityAt, input.activityState);
|
|
53
61
|
return activity || facts.length ? [activity, ...facts].filter(Boolean).join(" | ") : undefined;
|
|
54
62
|
}
|
|
@@ -73,7 +81,8 @@ function formatNestedRunLines(children, options) {
|
|
|
73
81
|
}
|
|
74
82
|
const activity = child.state === "running" ? formatNestedActivity(child) : undefined;
|
|
75
83
|
const error = child.error ? ` | error: ${child.error}` : "";
|
|
76
|
-
|
|
84
|
+
const modelThinking = formatModelThinking(child.model, child.thinking);
|
|
85
|
+
lines.push(`${indent}↳ ${nestedRunLabel(child)} [${child.id}] ${child.state}${modelThinking ? ` | ${modelThinking}` : ""}${activity ? ` | ${activity}` : ""}${error}`);
|
|
77
86
|
if (options.commandHints && lines.length < options.maxLines)
|
|
78
87
|
lines.push(`${indent} Status: subagent({ action: "status", id: "${child.id}" })`);
|
|
79
88
|
if (depth === options.maxDepth) {
|
|
@@ -86,7 +95,8 @@ function formatNestedRunLines(children, options) {
|
|
|
86
95
|
if (lines.length >= options.maxLines)
|
|
87
96
|
return;
|
|
88
97
|
const stepActivity = step.status === "running" ? formatNestedActivity(step) : undefined;
|
|
89
|
-
|
|
98
|
+
const stepModelThinking = formatModelThinking(step.model, step.thinking);
|
|
99
|
+
lines.push(`${indent} ${stepIndex + 1}. ${step.sessionName?.trim() || step.agent} ${step.status}${stepModelThinking ? ` | ${stepModelThinking}` : ""}${stepActivity ? ` | ${stepActivity}` : ""}${step.error ? ` | error: ${step.error}` : ""}`);
|
|
90
100
|
append(step.children, depth + 1, `${indent} `);
|
|
91
101
|
}
|
|
92
102
|
append(child.children, depth + 1, `${indent} `);
|