@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
|
@@ -1,14 +1,16 @@
|
|
|
1
1
|
import * as fs from "node:fs";
|
|
2
2
|
import * as path from "node:path";
|
|
3
|
+
import { safeTerminalText } from "../../shared/display-text.js";
|
|
3
4
|
import { formatDuration, formatModelThinking, formatTokens, shortenPath } from "../../shared/formatters.js";
|
|
4
5
|
import { formatActivityLabel } from "../../shared/status-format.js";
|
|
5
6
|
import {
|
|
6
|
-
|
|
7
|
-
RESULTS_DIR
|
|
7
|
+
DIRS
|
|
8
8
|
} from "../../shared/types.js";
|
|
9
9
|
import { readStatus } from "../../shared/utils.js";
|
|
10
10
|
import { formatNestedRunStatusLines } from "../shared/nested-render.js";
|
|
11
|
+
import { contextModeLabel, summarizeContextModes } from "../shared/context-mode.js";
|
|
11
12
|
import { formatAsyncRunOutputPath, formatAsyncRunProgressLabel, listAsyncRuns } from "./async-status.js";
|
|
13
|
+
import { isTrustedRecordedSessionFile } from "../../shared/session-file-trust.js";
|
|
12
14
|
const DEFAULT_TRANSCRIPT_LINES = 80;
|
|
13
15
|
const MAX_TRANSCRIPT_LINES = 500;
|
|
14
16
|
const TRANSCRIPT_TAIL_BYTES = 256 * 1024;
|
|
@@ -30,6 +32,12 @@ function uniqueStrings(values) {
|
|
|
30
32
|
}
|
|
31
33
|
return result;
|
|
32
34
|
}
|
|
35
|
+
function fleetChildDisplayName(child, fallback = "subagent") {
|
|
36
|
+
return child.sessionName?.trim() || child.agent || fallback;
|
|
37
|
+
}
|
|
38
|
+
function fleetStepDisplayName(step) {
|
|
39
|
+
return step.sessionName?.trim() || (step.label ? `${step.label} (${step.agent})` : step.agent);
|
|
40
|
+
}
|
|
33
41
|
function resolveMaybeRelative(asyncDir, filePath) {
|
|
34
42
|
if (!filePath)
|
|
35
43
|
return;
|
|
@@ -78,11 +86,12 @@ function readTextTail(filePath, maxLines) {
|
|
|
78
86
|
fs.closeSync(fd);
|
|
79
87
|
}
|
|
80
88
|
}
|
|
81
|
-
function readContainedTextTail(filePath, maxLines, trustedRoots, label) {
|
|
82
|
-
if (trustedRoots.length === 0)
|
|
89
|
+
function readContainedTextTail(filePath, maxLines, trustedRoots, label, trustedFiles = [], trustedFileRoot) {
|
|
90
|
+
if (trustedRoots.length === 0 && (!trustedFileRoot || trustedFiles.length === 0))
|
|
83
91
|
return { path: filePath, lines: [], truncated: false, error: `Refusing to read ${label} transcript path without a trusted root: ${filePath}` };
|
|
84
92
|
const resolvedPath = path.resolve(filePath);
|
|
85
|
-
|
|
93
|
+
const recordedCandidate = trustedFileRoot && pathWithin(trustedFileRoot, resolvedPath) && trustedFiles.some((file) => path.resolve(file) === resolvedPath);
|
|
94
|
+
if (!trustedRoots.some((root) => pathWithin(root, resolvedPath)) && !recordedCandidate) {
|
|
86
95
|
return { path: filePath, lines: [], truncated: false, error: `Refusing to read ${label} transcript path outside trusted roots: ${filePath}` };
|
|
87
96
|
}
|
|
88
97
|
let lstat;
|
|
@@ -105,7 +114,7 @@ function readContainedTextTail(filePath, maxLines, trustedRoots, label) {
|
|
|
105
114
|
} catch (error) {
|
|
106
115
|
return { path: filePath, lines: [], truncated: false, error: getErrorMessage(error) };
|
|
107
116
|
}
|
|
108
|
-
if (!realRoots.some((root) => pathWithin(root, realPath))) {
|
|
117
|
+
if (!realRoots.some((root) => pathWithin(root, realPath)) && !isTrustedRecordedSessionFile(realPath, trustedFiles, trustedFileRoot)) {
|
|
109
118
|
return { path: filePath, lines: [], truncated: false, error: `Refusing to read ${label} transcript path outside trusted roots: ${filePath}` };
|
|
110
119
|
}
|
|
111
120
|
return readTextTail(resolvedPath, maxLines);
|
|
@@ -118,45 +127,84 @@ function stringifyJsonPreview(value, maxLength = 240) {
|
|
|
118
127
|
raw = JSON.stringify(value);
|
|
119
128
|
return raw.length > maxLength ? `${raw.slice(0, maxLength)}…` : raw;
|
|
120
129
|
}
|
|
121
|
-
function
|
|
130
|
+
function sessionMessageParts(record) {
|
|
131
|
+
if (!record || typeof record !== "object")
|
|
132
|
+
return [];
|
|
133
|
+
const outer = record;
|
|
134
|
+
const message = outer.message && typeof outer.message === "object" ? outer.message : outer;
|
|
135
|
+
const role = typeof message.role === "string" ? message.role : undefined;
|
|
136
|
+
if (!role)
|
|
137
|
+
return [];
|
|
138
|
+
const content = message.content;
|
|
122
139
|
if (typeof content === "string")
|
|
123
|
-
return content;
|
|
140
|
+
return content.trim() ? [{ role, kind: "text", text: content }] : [];
|
|
124
141
|
if (!Array.isArray(content))
|
|
125
|
-
return
|
|
126
|
-
|
|
142
|
+
return [];
|
|
143
|
+
const parts = [];
|
|
144
|
+
for (const part of content) {
|
|
127
145
|
if (!part || typeof part !== "object")
|
|
128
|
-
|
|
146
|
+
continue;
|
|
129
147
|
const entry = part;
|
|
130
|
-
if (typeof entry.text === "string")
|
|
131
|
-
|
|
148
|
+
if (typeof entry.text === "string") {
|
|
149
|
+
if (entry.text.trim())
|
|
150
|
+
parts.push({ role, kind: "text", text: entry.text });
|
|
151
|
+
continue;
|
|
152
|
+
}
|
|
132
153
|
if (entry.type === "toolCall" || entry.type === "tool_call") {
|
|
133
154
|
const name = typeof entry.name === "string" ? entry.name : typeof entry.toolName === "string" ? entry.toolName : "tool";
|
|
134
|
-
|
|
155
|
+
parts.push({ role, kind: "toolCall", name, text: `[tool: ${name}${entry.args === undefined ? "" : ` ${stringifyJsonPreview(entry.args)}`}]` });
|
|
156
|
+
continue;
|
|
135
157
|
}
|
|
136
158
|
if (entry.type === "toolResult" || entry.type === "tool_result") {
|
|
137
|
-
|
|
159
|
+
const name = typeof entry.name === "string" ? entry.name : typeof entry.toolName === "string" ? entry.toolName : undefined;
|
|
160
|
+
parts.push({ role, kind: "toolResult", ...name ? { name } : {}, ...entry.isError === true ? { isError: true } : {}, text: `[tool result${entry.result === undefined ? "" : `: ${stringifyJsonPreview(entry.result)}`}]` });
|
|
161
|
+
continue;
|
|
138
162
|
}
|
|
139
|
-
if (entry.content !== undefined)
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
163
|
+
if (entry.content !== undefined) {
|
|
164
|
+
const preview = stringifyJsonPreview(entry.content);
|
|
165
|
+
if (preview.trim())
|
|
166
|
+
parts.push({ role, kind: "text", text: preview });
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
return parts;
|
|
144
170
|
}
|
|
145
171
|
function sessionMessageLine(record) {
|
|
146
|
-
|
|
172
|
+
const parts = sessionMessageParts(record);
|
|
173
|
+
if (parts.length === 0)
|
|
147
174
|
return;
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
const role = typeof message.role === "string" ? message.role : undefined;
|
|
151
|
-
if (!role)
|
|
152
|
-
return;
|
|
153
|
-
const text = contentText(message.content).trim();
|
|
175
|
+
const text = parts.map((part) => part.text).join(`
|
|
176
|
+
`).trim();
|
|
154
177
|
if (!text)
|
|
155
178
|
return;
|
|
156
|
-
return `${role}: ${text}`;
|
|
179
|
+
return `${parts[0].role}: ${text}`;
|
|
157
180
|
}
|
|
158
|
-
function
|
|
159
|
-
const tail = readContainedTextTail(sessionFile, Math.max(
|
|
181
|
+
export function readSessionMessagesTail(sessionFile, maxMessages, trustedRoots, trustedFiles = [], trustedFileRoot) {
|
|
182
|
+
const tail = readContainedTextTail(sessionFile, Math.max(maxMessages * 4, maxMessages), trustedRoots, "session", trustedFiles, trustedFileRoot);
|
|
183
|
+
const warnings = [];
|
|
184
|
+
if (tail.error)
|
|
185
|
+
warnings.push(`Session read failed for ${sessionFile}: ${tail.error}`);
|
|
186
|
+
const parsedMessages = [];
|
|
187
|
+
let malformed = 0;
|
|
188
|
+
let recordIndex = 0;
|
|
189
|
+
for (const line of tail.lines) {
|
|
190
|
+
if (!line.trim())
|
|
191
|
+
continue;
|
|
192
|
+
try {
|
|
193
|
+
const parsed = JSON.parse(line);
|
|
194
|
+
for (const part of sessionMessageParts(parsed))
|
|
195
|
+
parsedMessages.push({ ...part, recordIndex });
|
|
196
|
+
} catch {
|
|
197
|
+
malformed++;
|
|
198
|
+
}
|
|
199
|
+
recordIndex++;
|
|
200
|
+
}
|
|
201
|
+
if (malformed > 0)
|
|
202
|
+
warnings.push(`Skipped ${malformed} malformed session tail line${malformed === 1 ? "" : "s"}.`);
|
|
203
|
+
const messages = parsedMessages.slice(-maxMessages);
|
|
204
|
+
return { messages, warnings, truncated: tail.truncated || parsedMessages.length > messages.length };
|
|
205
|
+
}
|
|
206
|
+
function readSessionTranscriptTail(sessionFile, maxLines, trustedRoots, trustedFiles = [], trustedFileRoot) {
|
|
207
|
+
const tail = readContainedTextTail(sessionFile, Math.max(maxLines * 4, maxLines), trustedRoots, "session", trustedFiles, trustedFileRoot);
|
|
160
208
|
const warnings = [];
|
|
161
209
|
if (tail.error)
|
|
162
210
|
warnings.push(`Session read failed for ${sessionFile}: ${tail.error}`);
|
|
@@ -169,7 +217,7 @@ function readSessionTranscriptTail(sessionFile, maxLines, trustedRoots) {
|
|
|
169
217
|
const parsed = JSON.parse(line);
|
|
170
218
|
const messageLine = sessionMessageLine(parsed);
|
|
171
219
|
if (messageLine)
|
|
172
|
-
lines.push(messageLine);
|
|
220
|
+
lines.push(...messageLine.split(/\r?\n/));
|
|
173
221
|
} catch {
|
|
174
222
|
malformed++;
|
|
175
223
|
}
|
|
@@ -196,8 +244,9 @@ function formatActivityFacts(input) {
|
|
|
196
244
|
return activity || facts.length ? [activity, ...facts].filter(Boolean).join(" | ") : undefined;
|
|
197
245
|
}
|
|
198
246
|
function foregroundModeName(control) {
|
|
199
|
-
|
|
200
|
-
|
|
247
|
+
const currentDisplayName = control.sessionName?.trim() || control.currentAgent;
|
|
248
|
+
if (control.mode === "single" && currentDisplayName)
|
|
249
|
+
return currentDisplayName;
|
|
201
250
|
return control.mode;
|
|
202
251
|
}
|
|
203
252
|
function formatForegroundFleetLines(controls) {
|
|
@@ -216,7 +265,8 @@ function formatForegroundFleetLines(controls) {
|
|
|
216
265
|
toolCount: control.toolCount,
|
|
217
266
|
...control.tokens !== undefined ? { tokens: { total: control.tokens } } : {}
|
|
218
267
|
});
|
|
219
|
-
const
|
|
268
|
+
const currentDisplayName = control.sessionName?.trim() || control.currentAgent;
|
|
269
|
+
const current = currentDisplayName ? ` | ${currentDisplayName}${control.currentIndex !== undefined ? ` #${control.currentIndex}` : ""}` : "";
|
|
220
270
|
lines.push(`- ${control.runId} | running | ${foregroundModeName(control)}${current}${activity ? ` | ${activity}` : ""}`);
|
|
221
271
|
lines.push(` status: subagent({ action: "status", id: "${control.runId}" })`);
|
|
222
272
|
lines.push(" transcript: live in the expanded foreground result; persisted session transcript appears after completion when sessions are enabled.");
|
|
@@ -224,6 +274,20 @@ function formatForegroundFleetLines(controls) {
|
|
|
224
274
|
}
|
|
225
275
|
return lines;
|
|
226
276
|
}
|
|
277
|
+
function formatDetachedForegroundFleetLines(runs) {
|
|
278
|
+
if (runs.length === 0)
|
|
279
|
+
return [];
|
|
280
|
+
const lines = ["Detached foreground runs:"];
|
|
281
|
+
const ordered = [...runs].sort((left, right) => right.updatedAt - left.updatedAt);
|
|
282
|
+
for (const run of ordered) {
|
|
283
|
+
const detachedChildren = run.children.filter((child) => child.status === "detached");
|
|
284
|
+
const childSummary = detachedChildren.map((child) => `${fleetChildDisplayName(child)} #${child.index}`).join(", ");
|
|
285
|
+
lines.push(`- ${run.runId} | detached | ${run.mode}${childSummary ? ` | ${childSummary}` : ""}`);
|
|
286
|
+
lines.push(` status: subagent({ action: "status", id: "${run.runId}" })`);
|
|
287
|
+
lines.push(` recovery: reply to the supervisor request first, then wait with bg_wait({ id: "${run.runId}" }); do not resume or launch a replacement while any child remains detached.`);
|
|
288
|
+
}
|
|
289
|
+
return lines;
|
|
290
|
+
}
|
|
227
291
|
function formatAsyncFleetLines(runs) {
|
|
228
292
|
if (runs.length === 0)
|
|
229
293
|
return [];
|
|
@@ -233,15 +297,17 @@ function formatAsyncFleetLines(runs) {
|
|
|
233
297
|
const activity = formatActivityFacts(run);
|
|
234
298
|
const cwd = run.cwd ? shortenPath(run.cwd) : shortenPath(run.asyncDir);
|
|
235
299
|
const pending = run.pendingAppends ? ` | ${run.pendingAppends} pending append${run.pendingAppends === 1 ? "" : "s"}` : "";
|
|
236
|
-
|
|
300
|
+
const runContext = contextModeLabel(run.context);
|
|
301
|
+
lines.push(`- ${run.id} | ${run.state}${activity ? ` | ${activity}` : ""} | ${run.mode}${runContext ? ` ${runContext}` : ""} | ${progress}${pending} | ${cwd}`);
|
|
237
302
|
lines.push(` status: subagent({ action: "status", id: "${run.id}" })`);
|
|
238
303
|
lines.push(` transcript: subagent({ action: "status", id: "${run.id}", view: "transcript" })`);
|
|
239
304
|
for (const step of run.steps) {
|
|
240
|
-
const display =
|
|
305
|
+
const display = fleetStepDisplayName(step);
|
|
306
|
+
const stepContext = contextModeLabel(step.context);
|
|
241
307
|
const phase = step.phase ? `[${step.phase}] ` : "";
|
|
242
308
|
const stepActivity = formatActivityFacts(step);
|
|
243
309
|
const modelThinking = formatModelThinking(step.model, step.thinking);
|
|
244
|
-
const parts = [`${step.index}. ${phase}${display}`, step.status, stepActivity, modelThinking].filter(Boolean);
|
|
310
|
+
const parts = [`${step.index}. ${phase}${display}${stepContext ? ` ${stepContext}` : ""}`, step.status, stepActivity, modelThinking].filter(Boolean);
|
|
245
311
|
lines.push(` ${parts.join(" | ")}`);
|
|
246
312
|
const output = path.join(run.asyncDir, `output-${step.index}.log`);
|
|
247
313
|
if (fs.existsSync(output))
|
|
@@ -278,10 +344,10 @@ export function inspectSubagentFleet(_params, deps = {}) {
|
|
|
278
344
|
}
|
|
279
345
|
let asyncRuns;
|
|
280
346
|
try {
|
|
281
|
-
asyncRuns = listAsyncRuns(deps.asyncDirRoot ??
|
|
347
|
+
asyncRuns = listAsyncRuns(deps.asyncDirRoot ?? DIRS.async, {
|
|
282
348
|
states: ["queued", "running"],
|
|
283
349
|
sessionId: deps.state?.currentSessionId ?? undefined,
|
|
284
|
-
resultsDir: deps.resultsDir ??
|
|
350
|
+
resultsDir: deps.resultsDir ?? DIRS.results,
|
|
285
351
|
kill: deps.kill,
|
|
286
352
|
now: deps.now
|
|
287
353
|
});
|
|
@@ -290,17 +356,22 @@ export function inspectSubagentFleet(_params, deps = {}) {
|
|
|
290
356
|
return { content: [{ type: "text", text: message }], isError: true, details: { mode: "management", results: [] } };
|
|
291
357
|
}
|
|
292
358
|
const foregroundControls = deps.state ? [...deps.state.foregroundControls.values()] : [];
|
|
293
|
-
const
|
|
359
|
+
const activeForegroundIds = new Set(foregroundControls.map((control) => control.runId));
|
|
360
|
+
const detachedForegroundRuns = deps.state?.foregroundRuns ? [...deps.state.foregroundRuns.values()].filter((run) => run.sessionId === deps.state?.currentSessionId && !activeForegroundIds.has(run.runId) && run.children.some((child) => child.status === "detached")) : [];
|
|
361
|
+
const total = foregroundControls.length + detachedForegroundRuns.length + asyncRuns.length;
|
|
294
362
|
if (total === 0) {
|
|
295
363
|
return {
|
|
296
364
|
content: [{ type: "text", text: 'No active subagent fleet. Background runs that already finished are available through completion notifications or subagent({ action: "status", id: "..." }).' }],
|
|
297
365
|
details: { mode: "management", results: [] }
|
|
298
366
|
};
|
|
299
367
|
}
|
|
300
|
-
const lines = [`Subagent fleet: ${total}
|
|
368
|
+
const lines = [`Subagent fleet: ${total} tracked`, ""];
|
|
301
369
|
const foregroundLines = formatForegroundFleetLines(foregroundControls);
|
|
302
370
|
if (foregroundLines.length)
|
|
303
371
|
lines.push(...foregroundLines, "");
|
|
372
|
+
const detachedForegroundLines = formatDetachedForegroundFleetLines(detachedForegroundRuns);
|
|
373
|
+
if (detachedForegroundLines.length)
|
|
374
|
+
lines.push(...detachedForegroundLines, "");
|
|
304
375
|
const asyncLines = formatAsyncFleetLines(asyncRuns);
|
|
305
376
|
if (asyncLines.length)
|
|
306
377
|
lines.push(...asyncLines, "");
|
|
@@ -331,15 +402,16 @@ function selectTranscriptStep(status, options) {
|
|
|
331
402
|
}
|
|
332
403
|
}
|
|
333
404
|
const step = selectedIndex !== undefined ? steps[selectedIndex] : undefined;
|
|
334
|
-
const hint = options.index === undefined && steps.length > 1 ? `Tip: pass index to inspect a specific child transcript (${steps.map((candidate, index) => `${index}=${candidate
|
|
405
|
+
const hint = options.index === undefined && steps.length > 1 ? `Tip: pass index to inspect a specific child transcript (${steps.map((candidate, index) => `${index}=${fleetChildDisplayName(candidate)}`).join(", ")}).` : undefined;
|
|
335
406
|
return { index: selectedIndex, step, hint };
|
|
336
407
|
}
|
|
337
408
|
function stepStateLine(mode, index, step) {
|
|
338
409
|
if (index === undefined || !step)
|
|
339
410
|
return;
|
|
340
411
|
const modelThinking = formatModelThinking(step.model, step.thinking);
|
|
412
|
+
const context = contextModeLabel(step.context);
|
|
341
413
|
const parts = [
|
|
342
|
-
`${mode === "parallel" ? "Agent" : "Step"}: ${index} (${step
|
|
414
|
+
`${mode === "parallel" ? "Agent" : "Step"}: ${index} (${fleetChildDisplayName(step)})${context ? ` ${context}` : ""}`,
|
|
343
415
|
step.status,
|
|
344
416
|
formatActivityFacts(step),
|
|
345
417
|
modelThinking,
|
|
@@ -365,6 +437,10 @@ function appendKnownArtifacts(lines, input) {
|
|
|
365
437
|
for (const artifact of artifacts)
|
|
366
438
|
lines.push(` ${artifact}`);
|
|
367
439
|
}
|
|
440
|
+
function safeTranscriptLines(lines) {
|
|
441
|
+
return lines.map((line) => safeTerminalText(line)).join(`
|
|
442
|
+
`);
|
|
443
|
+
}
|
|
368
444
|
function appendTranscriptBody(lines, sourceLabel, sourceLines, truncated) {
|
|
369
445
|
lines.push(`${sourceLabel}${truncated ? " (tail truncated)" : ""}:`);
|
|
370
446
|
if (sourceLines.length === 0) {
|
|
@@ -383,14 +459,15 @@ export function formatAsyncRunTranscript(status, asyncDir, options = {}) {
|
|
|
383
459
|
const outputPaths = selected.index !== undefined ? uniqueStrings([stepOutputPath, runOutputPath && stepOutputPath && path.resolve(runOutputPath) === path.resolve(stepOutputPath) ? runOutputPath : undefined]) : uniqueStrings([runOutputPath]);
|
|
384
460
|
const sessionFile = selected.index !== undefined ? selected.step?.sessionFile : status.sessionFile;
|
|
385
461
|
const eventsPath = path.join(asyncDir, "events.jsonl");
|
|
462
|
+
const context = contextModeLabel(status.context ?? summarizeContextModes((status.steps ?? []).map((step) => step.context)));
|
|
386
463
|
const lines = [
|
|
387
464
|
`Run: ${status.runId}`,
|
|
388
465
|
`State: ${status.state}`,
|
|
389
|
-
`Mode: ${status.mode}`,
|
|
466
|
+
`Mode: ${status.mode}${context ? ` ${context}` : ""}`,
|
|
390
467
|
stepStateLine(status.mode, selected.index, selected.step),
|
|
391
468
|
selected.hint
|
|
392
469
|
].filter((line) => Boolean(line));
|
|
393
|
-
appendKnownArtifacts(lines, { outputPaths, sessionFile, eventsPath: fs.existsSync(eventsPath) ? eventsPath : undefined, logPath: fs.existsSync(logPath) ? logPath : undefined });
|
|
470
|
+
appendKnownArtifacts(lines, { outputPaths: outputPaths.filter((outputPath) => fs.existsSync(outputPath)), sessionFile, eventsPath: fs.existsSync(eventsPath) ? eventsPath : undefined, logPath: fs.existsSync(logPath) ? logPath : undefined });
|
|
394
471
|
const warnings = [];
|
|
395
472
|
let transcriptLines = [];
|
|
396
473
|
let transcriptSource = "Transcript tail";
|
|
@@ -411,7 +488,7 @@ export function formatAsyncRunTranscript(status, asyncDir, options = {}) {
|
|
|
411
488
|
transcriptSource = "Recent output from status.json";
|
|
412
489
|
}
|
|
413
490
|
if (transcriptLines.length === 0 && sessionFile) {
|
|
414
|
-
const sessionTail = readSessionTranscriptTail(sessionFile, lineLimit, options.sessionRoots ?? []);
|
|
491
|
+
const sessionTail = readSessionTranscriptTail(sessionFile, lineLimit, options.sessionRoots ?? [], options.trustedSessionFiles, options.trustedSessionFileRoot);
|
|
415
492
|
transcriptLines = sessionTail.lines;
|
|
416
493
|
warnings.push(...sessionTail.warnings);
|
|
417
494
|
if (transcriptLines.length > 0)
|
|
@@ -423,8 +500,7 @@ export function formatAsyncRunTranscript(status, asyncDir, options = {}) {
|
|
|
423
500
|
lines.push(` ${warning}`);
|
|
424
501
|
}
|
|
425
502
|
appendTranscriptBody(lines, transcriptSource, transcriptLines, truncated);
|
|
426
|
-
return lines
|
|
427
|
-
`);
|
|
503
|
+
return safeTranscriptLines(lines);
|
|
428
504
|
}
|
|
429
505
|
export function formatNestedRunTranscript(run, options = {}) {
|
|
430
506
|
if (run.asyncDir) {
|
|
@@ -437,28 +513,26 @@ export function formatNestedRunTranscript(run, options = {}) {
|
|
|
437
513
|
`Nested run: ${run.id}`,
|
|
438
514
|
`State: ${run.state}`,
|
|
439
515
|
run.mode ? `Mode: ${run.mode}` : undefined,
|
|
440
|
-
run.agent ? `Agent: ${run.agent}` : run.agents?.length ? `Agents: ${run.agents.join(", ")}` : undefined
|
|
516
|
+
run.sessionName?.trim() ? `Agent: ${run.sessionName.trim()}` : run.agent ? `Agent: ${run.agent}` : run.agents?.length ? `Agents: ${run.agents.join(", ")}` : undefined
|
|
441
517
|
].filter((line) => Boolean(line));
|
|
442
518
|
appendKnownArtifacts(lines, { outputPaths: [], sessionFile: run.sessionFile });
|
|
443
519
|
if (!run.sessionFile) {
|
|
444
520
|
appendTranscriptBody(lines, "Transcript tail", [], false);
|
|
445
|
-
return lines
|
|
446
|
-
`);
|
|
521
|
+
return safeTranscriptLines(lines);
|
|
447
522
|
}
|
|
448
|
-
const sessionTail = readSessionTranscriptTail(run.sessionFile, lineLimit, options.sessionRoots ?? []);
|
|
523
|
+
const sessionTail = readSessionTranscriptTail(run.sessionFile, lineLimit, options.sessionRoots ?? [], options.trustedSessionFiles, options.trustedSessionFileRoot);
|
|
449
524
|
if (sessionTail.warnings.length) {
|
|
450
525
|
lines.push("Warnings:");
|
|
451
526
|
for (const warning of sessionTail.warnings)
|
|
452
527
|
lines.push(` ${warning}`);
|
|
453
528
|
}
|
|
454
529
|
appendTranscriptBody(lines, `Session transcript tail from ${run.sessionFile}`, sessionTail.lines, false);
|
|
455
|
-
return lines
|
|
456
|
-
`);
|
|
530
|
+
return safeTranscriptLines(lines);
|
|
457
531
|
}
|
|
458
532
|
export function formatAsyncResultTranscript(data, resultPath, options = {}) {
|
|
459
533
|
const lineLimit = transcriptLineLimit(options.lines);
|
|
460
534
|
const runId = data.runId ?? data.id ?? path.basename(resultPath, ".json");
|
|
461
|
-
const children = Array.isArray(data.results) ? data.results : data.agent ? [{ agent: data.agent, output: data.output, summary: data.summary, sessionFile: data.sessionFile, state: data.state, success: data.success, exitCode: data.exitCode }] : [];
|
|
535
|
+
const children = Array.isArray(data.results) ? data.results : data.agent ? [{ agent: data.agent, sessionName: undefined, output: data.output, summary: data.summary, sessionFile: data.sessionFile, state: data.state, success: data.success, exitCode: data.exitCode }] : [];
|
|
462
536
|
let index = options.index;
|
|
463
537
|
if (index !== undefined && !Number.isInteger(index))
|
|
464
538
|
throw new Error("Transcript index must be an integer.");
|
|
@@ -473,11 +547,10 @@ export function formatAsyncResultTranscript(data, resultPath, options = {}) {
|
|
|
473
547
|
const lines = [
|
|
474
548
|
`Run: ${runId}`,
|
|
475
549
|
`State: ${data.state ?? (data.success ? "complete" : "failed")}`,
|
|
476
|
-
index !== undefined && child ? `Child: ${index} (${child
|
|
477
|
-
index === undefined && children.length > 1 ? `Tip: pass index to inspect a specific child transcript (${children.map((candidate, childIndex) => `${childIndex}=${candidate
|
|
550
|
+
index !== undefined && child ? `Child: ${index} (${fleetChildDisplayName(child)})` : undefined,
|
|
551
|
+
index === undefined && children.length > 1 ? `Tip: pass index to inspect a specific child transcript (${children.map((candidate, childIndex) => `${childIndex}=${fleetChildDisplayName(candidate)}`).join(", ")}).` : undefined
|
|
478
552
|
].filter((line) => Boolean(line));
|
|
479
553
|
appendKnownArtifacts(lines, { outputPaths: [], sessionFile, resultPath });
|
|
480
554
|
appendTranscriptBody(lines, "Result transcript tail", transcriptLines.filter((line) => line.trim()), output.split(/\r?\n/).length > lineLimit);
|
|
481
|
-
return lines
|
|
482
|
-
`);
|
|
555
|
+
return safeTranscriptLines(lines);
|
|
483
556
|
}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { createHash } from "node:crypto";
|
|
2
|
+
export const MAX_INDEX_SEGMENT_BYTES = 255;
|
|
3
|
+
const HASHED_INDEX_SEGMENT_PREFIX = "~sha256-";
|
|
4
|
+
const WINDOWS_RESERVED_NAME = /^(?:con|prn|aux|nul|com[1-9]|lpt[1-9])(?:\.|$)/i;
|
|
5
|
+
function hashedSegment(value) {
|
|
6
|
+
return `${HASHED_INDEX_SEGMENT_PREFIX}${createHash("sha256").update(value).digest("hex")}`;
|
|
7
|
+
}
|
|
8
|
+
function isPortableSegment(value) {
|
|
9
|
+
return value.length > 0 && value !== "." && value !== ".." && !value.endsWith(".") && !WINDOWS_RESERVED_NAME.test(value) && !/%5C/i.test(value) && !/\.[A-Za-z][A-Za-z0-9]{0,7}$/.test(value);
|
|
10
|
+
}
|
|
11
|
+
export function encodeIndexSegment(value, maxBytes = MAX_INDEX_SEGMENT_BYTES) {
|
|
12
|
+
let encoded;
|
|
13
|
+
try {
|
|
14
|
+
encoded = encodeURIComponent(value);
|
|
15
|
+
} catch {
|
|
16
|
+
return hashedSegment(value);
|
|
17
|
+
}
|
|
18
|
+
if (Buffer.byteLength(encoded, "utf-8") <= maxBytes && isPortableSegment(encoded))
|
|
19
|
+
return encoded;
|
|
20
|
+
return hashedSegment(value);
|
|
21
|
+
}
|
|
22
|
+
function historicallyReadableSegment(value, maxBytes) {
|
|
23
|
+
try {
|
|
24
|
+
const encoded = encodeURIComponent(value);
|
|
25
|
+
if (encoded.length === 0 || encoded === "." || encoded === ".." || encoded.endsWith(".") || WINDOWS_RESERVED_NAME.test(encoded))
|
|
26
|
+
return;
|
|
27
|
+
if (Buffer.byteLength(encoded, "utf-8") > maxBytes)
|
|
28
|
+
return;
|
|
29
|
+
return encoded;
|
|
30
|
+
} catch {
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
export function indexSegmentAliases(value, maxBytes = MAX_INDEX_SEGMENT_BYTES) {
|
|
35
|
+
const current = encodeIndexSegment(value, maxBytes);
|
|
36
|
+
const historical = historicallyReadableSegment(value, maxBytes);
|
|
37
|
+
return historical && historical !== current ? [current, historical] : [current];
|
|
38
|
+
}
|