zidane 6.2.11 → 6.2.12
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/dist/{acp-DuEMbOoQ.js → acp-C-auiVTk.js} +2 -2
- package/dist/{acp-DuEMbOoQ.js.map → acp-C-auiVTk.js.map} +1 -1
- package/dist/acp-cli.js +4 -4
- package/dist/acp.d.ts +1 -1
- package/dist/acp.js +1 -1
- package/dist/{agent-6iGNP46b.js → agent-DhfdXgL2.js} +81 -1
- package/dist/{agent-6iGNP46b.js.map → agent-DhfdXgL2.js.map} +1 -1
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +1 -1
- package/dist/{anthropic-BD-lwEKp.js → anthropic-uXfsormU.js} +87 -2
- package/dist/anthropic-uXfsormU.js.map +1 -0
- package/dist/{auth-BH6G59RL.js → auth-TZg3MVi2.js} +2 -2
- package/dist/{auth-BH6G59RL.js.map → auth-TZg3MVi2.js.map} +1 -1
- package/dist/chat/pure.d.ts +3 -3
- package/dist/chat.d.ts +4 -4
- package/dist/chat.js +3 -3
- package/dist/contexts/daytona.d.ts +1 -1
- package/dist/contexts/e2b.d.ts +1 -1
- package/dist/eval.d.ts +1 -1
- package/dist/extensions.d.ts +1 -1
- package/dist/extensions.js +1 -1
- package/dist/headless.d.ts +1 -1
- package/dist/headless.js +1 -1
- package/dist/{index-BFNt9GAs.d.ts → index-l0wehkWU.d.ts} +44 -6
- package/dist/index-l0wehkWU.d.ts.map +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +4 -4
- package/dist/{login-B5nMPF8w.js → login-Clf-R27F.js} +2 -2
- package/dist/{login-B5nMPF8w.js.map → login-Clf-R27F.js.map} +1 -1
- package/dist/mcp.d.ts +1 -1
- package/dist/output/stream-json.d.ts +1 -1
- package/dist/output/terminal.d.ts +1 -1
- package/dist/presets.d.ts +1 -1
- package/dist/presets.js +1 -1
- package/dist/providers/anthropic.d.ts +1 -1
- package/dist/providers/anthropic.js +1 -1
- package/dist/providers/arcee.d.ts +1 -1
- package/dist/providers/baseten.d.ts +1 -1
- package/dist/providers/cerebras.d.ts +1 -1
- package/dist/providers/local.d.ts +1 -1
- package/dist/providers/openai-compat.d.ts +1 -1
- package/dist/providers/openai.d.ts +1 -1
- package/dist/providers/openrouter.d.ts +1 -1
- package/dist/providers/xai.d.ts +1 -1
- package/dist/providers.d.ts +2 -2
- package/dist/providers.js +1 -1
- package/dist/restate.d.ts +1 -1
- package/dist/session/sqlite.d.ts +1 -1
- package/dist/session.d.ts +1 -1
- package/dist/{skills-CDpejYOf.js → skills-DKWqoaYH.js} +4 -3
- package/dist/skills-DKWqoaYH.js.map +1 -0
- package/dist/skills.d.ts +1 -1
- package/dist/skills.js +1 -1
- package/dist/{tool-formatters-B_zQsYfa.d.ts → tool-formatters-BSwVkSX2.d.ts} +2 -2
- package/dist/{tool-formatters-B_zQsYfa.d.ts.map → tool-formatters-BSwVkSX2.d.ts.map} +1 -1
- package/dist/tools/fetch-url.d.ts +1 -1
- package/dist/tools/web-search.d.ts +1 -1
- package/dist/tools.d.ts +1 -1
- package/dist/tools.js +1 -1
- package/dist/{transcript-anchors-B_kUHJ16.js → transcript-anchors-BzcuKnq8.js} +106 -34
- package/dist/transcript-anchors-BzcuKnq8.js.map +1 -0
- package/dist/{transcript-anchors-2wafjV-s.d.ts → transcript-anchors-DKjXpQ0h.d.ts} +2 -2
- package/dist/{transcript-anchors-2wafjV-s.d.ts.map → transcript-anchors-DKjXpQ0h.d.ts.map} +1 -1
- package/dist/tui.d.ts +3 -3
- package/dist/tui.d.ts.map +1 -1
- package/dist/tui.js +199 -115
- package/dist/tui.js.map +1 -1
- package/dist/{turn-operations-DVA52KMG.d.ts → turn-operations-CjkgQKmR.d.ts} +3 -3
- package/dist/{turn-operations-DVA52KMG.d.ts.map → turn-operations-CjkgQKmR.d.ts.map} +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
- package/dist/anthropic-BD-lwEKp.js.map +0 -1
- package/dist/index-BFNt9GAs.d.ts.map +0 -1
- package/dist/skills-CDpejYOf.js.map +0 -1
- package/dist/transcript-anchors-B_kUHJ16.js.map +0 -1
package/dist/tui.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { $ as useMcpAuthState, $n as buildPlanSystem, $t as restoreChainFallbacks, A as runOAuthLogin, Bt as createDiscoverySlot, Ct as SETTINGS_CHOICES, D as formatPathForCwd, Dt as clampFps, Et as SettingsProvider, G as buildVisibleMcpRows, Gt as useConfig, Ht as useDiscovery, J as createFileMcpCredentialStore, Jt as buildRunModel, K as indexOfServerRow, Kt as resolveConfig, L as loadMcpToolsCache, M as buildMcpServers, Mt as resolveTheme, O as fetchOAuthRedirect, Ot as useSettings, P as discoverProjectMcps, Q as useMcpAuthDispatch, Qn as buildBuildSystem, Qt as providerKeySetChanged, R as mcpToolsCachePath, St as SETTINGS_CATEGORIES, T as suggestSafelistEntries, Tn as accentColor, Tt as SETTINGS_TOGGLES, U as useMcpToolToggleMap, Ut as useDiscoveryOptional, V as subscribeMcpToolsCache, Vn as useActiveTodos, Vt as DiscoveryProvider, Wt as ConfigProvider, Xt as chainsEqual, Yt as chainPositionOf, Z as McpAuthProvider, Zt as filterChainFallbacks, _ as useSafeModeQueue, _n as discoverAgentsMd, _r as toolCallPreview, _t as buildHints, a as useSurfaces, an as bootTick, at as buildResumedToolResultsTurn, b as getSafelist, br as usageByModel, bt as useEnabledToggleSet, c as useStreamBuffer, cr as lastContextSizeFromTurns, ct as makeRequestInteraction, d as discoverProjectSkills, dr as marginTopFor, dt as useInteractionsActions, er as envSection, et as getMcpAuthStatus, ft as useInteractionsQueue, g as useSafeModeActions, gn as chatAutoCompactBehavior, gt as truncateTrailing, h as SafeModeProvider, hr as sumRunCosts, ht as hintsLength, i as useSelectStyle, ir as compactSummaryEvent, it as PRESENT_PLAN_TOOL, j as supportsOAuth, jn as TODO_STATUS_GLYPHS, jt as resolveChipColor, k as oauthUsesManualCodePaste, l as buildSkillsConfig, lr as listSessionMeta, lt as pendingInteractionsFromTurns, m as writeSessionExport, mr as stripSpawnTokensLine, mt as clipHintsToWidth, n as ThemeProvider, nn as useCompletion, nr as createChatTurnsReadTool, nt as ASK_USER_TOOL, on as buildUpdateHint, or as deriveSessionTitle, ot as createInteractionTools, pr as serverToolResultSummary, pt as EMPTY_HINTS, q as parentServerName, qt as resolveStoragePaths, r as useColors, rn as tryOpenBrowser, rt as InteractionsProvider, s as useTheme, sn as useUpdateCheck, sr as eventsFromTurns, t as computeTurnAnchors, tn as toggleChainEntry, tr as chatReferenceTokensForPrompt, u as defaultSkillScanPaths, ur as loadState, vr as toolResultText, wt as SETTINGS_INPUTS, x as isOnSafelist, xt as DEFAULT_SETTINGS, y as addToSafelist, yr as updateToolEventOutcomes, yt as listProjectFiles, z as refreshMcpToolsCatalog } from "./transcript-anchors-
|
|
2
|
-
import { $ as composeExtensionPreset, B as ExtensionInstallError, Bt as ensureKeybindingsFile, Et as createModelSearchTool, H as installExtensionFromSpec, Ht as groupBindings, J as createExtensionHud, K as removeInstalledExtension, P as summaryToTurn, St as tailTruncate, Ut as keybindingsPath, Vt as formatBindingForDisplay, Wt as matchesBinding, X as discoverAndBuildExtensionRegistry, Y as registerExtensionHostModules, Yt as resolveExtensionKeybindings, _ as buildPostCompactAttachments, c as applyCompactSummaryCutoff, dn as sanitizeExtensionConfigActionPatch, en as inlineLoadedExtension, et as disposeExtensionRegistry, f as cleanupPersistedSession, g as resolveTasksDir, h as resolvePersistDir, hn as effectiveContextWindow, ht as isSpawnTool, it as createExtensionHostRuntimeBridge, lt as basic_default, m as resolveMcpWarningsDir, mn as OUTPUT_RESERVE_TOKENS, nn as parseExtensionScanPathEnv, on as coerceExtensionConfigInput, q as updateInstalledExtension, rn as scanExtensionDirectories, rt as partitionExtensionCatalog, t as createAgent, tt as filterExtensionRegistry, un as resolveExtensionConfigValue, wt as looksBinary, x as compactConversation, y as selectFilesFromSession, z as createExtensionPromptBridge, zt as KEYBINDING_KEY_COL_WIDTH } from "./agent-
|
|
1
|
+
import { $ as useMcpAuthState, $n as buildPlanSystem, $t as restoreChainFallbacks, A as runOAuthLogin, Bt as createDiscoverySlot, Ct as SETTINGS_CHOICES, D as formatPathForCwd, Dt as clampFps, Et as SettingsProvider, G as buildVisibleMcpRows, Gt as useConfig, Ht as useDiscovery, J as createFileMcpCredentialStore, Jt as buildRunModel, K as indexOfServerRow, Kt as resolveConfig, L as loadMcpToolsCache, M as buildMcpServers, Mt as resolveTheme, O as fetchOAuthRedirect, Ot as useSettings, P as discoverProjectMcps, Q as useMcpAuthDispatch, Qn as buildBuildSystem, Qt as providerKeySetChanged, R as mcpToolsCachePath, St as SETTINGS_CATEGORIES, T as suggestSafelistEntries, Tn as accentColor, Tt as SETTINGS_TOGGLES, U as useMcpToolToggleMap, Ut as useDiscoveryOptional, V as subscribeMcpToolsCache, Vn as useActiveTodos, Vt as DiscoveryProvider, Wt as ConfigProvider, Xt as chainsEqual, Yt as chainPositionOf, Z as McpAuthProvider, Zt as filterChainFallbacks, _ as useSafeModeQueue, _n as discoverAgentsMd, _r as toolCallPreview, _t as buildHints, a as useSurfaces, an as bootTick, at as buildResumedToolResultsTurn, b as getSafelist, br as usageByModel, bt as useEnabledToggleSet, c as useStreamBuffer, cr as lastContextSizeFromTurns, ct as makeRequestInteraction, d as discoverProjectSkills, dr as marginTopFor, dt as useInteractionsActions, er as envSection, et as getMcpAuthStatus, ft as useInteractionsQueue, g as useSafeModeActions, gn as chatAutoCompactBehavior, gt as truncateTrailing, h as SafeModeProvider, hr as sumRunCosts, ht as hintsLength, i as useSelectStyle, ir as compactSummaryEvent, it as PRESENT_PLAN_TOOL, j as supportsOAuth, jn as TODO_STATUS_GLYPHS, jt as resolveChipColor, k as oauthUsesManualCodePaste, l as buildSkillsConfig, lr as listSessionMeta, lt as pendingInteractionsFromTurns, m as writeSessionExport, mr as stripSpawnTokensLine, mt as clipHintsToWidth, n as ThemeProvider, nn as useCompletion, nr as createChatTurnsReadTool, nt as ASK_USER_TOOL, on as buildUpdateHint, or as deriveSessionTitle, ot as createInteractionTools, pr as serverToolResultSummary, pt as EMPTY_HINTS, q as parentServerName, qt as resolveStoragePaths, r as useColors, rn as tryOpenBrowser, rt as InteractionsProvider, s as useTheme, sn as useUpdateCheck, sr as eventsFromTurns, t as computeTurnAnchors, tn as toggleChainEntry, tr as chatReferenceTokensForPrompt, u as defaultSkillScanPaths, ur as loadState, vr as toolResultText, wt as SETTINGS_INPUTS, x as isOnSafelist, xt as DEFAULT_SETTINGS, y as addToSafelist, yr as updateToolEventOutcomes, yt as listProjectFiles, z as refreshMcpToolsCatalog } from "./transcript-anchors-BzcuKnq8.js";
|
|
2
|
+
import { $ as composeExtensionPreset, B as ExtensionInstallError, Bt as ensureKeybindingsFile, Et as createModelSearchTool, H as installExtensionFromSpec, Ht as groupBindings, J as createExtensionHud, K as removeInstalledExtension, P as summaryToTurn, St as tailTruncate, Ut as keybindingsPath, Vt as formatBindingForDisplay, Wt as matchesBinding, X as discoverAndBuildExtensionRegistry, Y as registerExtensionHostModules, Yt as resolveExtensionKeybindings, _ as buildPostCompactAttachments, c as applyCompactSummaryCutoff, dn as sanitizeExtensionConfigActionPatch, en as inlineLoadedExtension, et as disposeExtensionRegistry, f as cleanupPersistedSession, g as resolveTasksDir, h as resolvePersistDir, hn as effectiveContextWindow, ht as isSpawnTool, it as createExtensionHostRuntimeBridge, lt as basic_default, m as resolveMcpWarningsDir, mn as OUTPUT_RESERVE_TOKENS, nn as parseExtensionScanPathEnv, on as coerceExtensionConfigInput, q as updateInstalledExtension, rn as scanExtensionDirectories, rt as partitionExtensionCatalog, t as createAgent, tt as filterExtensionRegistry, un as resolveExtensionConfigValue, wt as looksBinary, x as compactConversation, y as selectFilesFromSession, z as createExtensionPromptBridge, zt as KEYBINDING_KEY_COL_WIDTH } from "./agent-DhfdXgL2.js";
|
|
3
3
|
import { a as formatDuration, c as previewLine, i as fmtTokens, l as shortId, n as compactPath, o as formatTaskStatus, r as fmtCost, s as formatTaskSummary, t as ageString } from "./format-BF745pLL.js";
|
|
4
4
|
import { n as appendCapped } from "./output-cap-kBUHBlnq.js";
|
|
5
5
|
import { i as killProcessGroup, n as SUPPORTS_PROCESS_GROUPS, r as createProcessContext } from "./contexts-A4ep-iJs.js";
|
|
@@ -14,9 +14,9 @@ import { o as withTimeout } from "./timeout-BDetbuN6.js";
|
|
|
14
14
|
import { n as connectMcpServers, u as McpOAuthProvider } from "./mcp-BCaN_Gyg.js";
|
|
15
15
|
import { a as generateStructuredData, c as shouldAutoGenerateTitle, f as commandBlockToEvent, g as parseCommandInvocation, h as executeCommand, n as patchInlineGhost, p as commandBlocksToContent, r as resolveInlineSuggestion, s as generateSessionTitle, t as createPathAutocompleteProvider } from "./inline-autocomplete-BAwBcZtD.js";
|
|
16
16
|
import { s as resolveCompletionSubmit } from "./completion-core-BRo86R_L.js";
|
|
17
|
-
import { i as installSkillFromSpec, r as SkillInstallError } from "./skills-
|
|
18
|
-
import { i as ZIDANE_EXTENSION_SKILL_NAME, l as withZidaneExtensionSkill, o as extensionDirForCwd, r as EXTENSION_EDIT_METADATA_KEY, s as extensionScaffold, t as loginMcpServer } from "./login-
|
|
19
|
-
import { C as restoreModelOptions, S as piIdOf, _ as modelOptionsFor, m as getContextWindow, p as enabledModelOptions, s as setProviderCredential, t as detectAuth, v as modelSupportsReasoning } from "./auth-
|
|
17
|
+
import { i as installSkillFromSpec, r as SkillInstallError } from "./skills-DKWqoaYH.js";
|
|
18
|
+
import { i as ZIDANE_EXTENSION_SKILL_NAME, l as withZidaneExtensionSkill, o as extensionDirForCwd, r as EXTENSION_EDIT_METADATA_KEY, s as extensionScaffold, t as loginMcpServer } from "./login-Clf-R27F.js";
|
|
19
|
+
import { C as restoreModelOptions, S as piIdOf, _ as modelOptionsFor, m as getContextWindow, p as enabledModelOptions, s as setProviderCredential, t as detectAuth, v as modelSupportsReasoning } from "./auth-TZg3MVi2.js";
|
|
20
20
|
import { createDockerContext } from "./contexts/docker.js";
|
|
21
21
|
import { createTuiStore } from "./session/sqlite.js";
|
|
22
22
|
import { $ as buildEditOutcomesAnnotation, A as blendHsl, B as turnSelectionOwnership, C as stripHtmlCommentsOutsideCode, E as uniqueSkillNamesFromReferences, F as isTurnHighlighted, H as buildContextualDiff, I as isUserBashEvent, J as filetypeFromPath, L as isVisible, M as BASH_CALL_ID_PREFIX, N as EDIT_TOOL_NAMES, O as createFilesCompletionProvider, P as isEditErrorResult, R as promptHistoryFromEvents, S as splitMarkdownCodeBlocks, T as createSkillsCompletionProvider, U as buildUnifiedDiff, W as clipDiffForRender, Y as previewEditPayload, Z as summarizeEditPayload, _ as filterModelCatalog, a as TOOL_DISPLAY, at as stripEditOutcomesAnnotation, b as chunkMarkdownForRender, d as finalizeStreamingMarkdown, f as finalizeStreamingMarkdownForOwner, g as buildModelCatalog, h as splitPromptSegments, i as turnAsText, it as rewriteMultiEditHeader, j as buildLinearRamp, lt as createChatsCompletionProvider, m as turnContextSize, n as deleteTurnSafely, nt as parseEditOutcomesFromResult, o as displayNameFor, ot as summarizeOutcomes, q as extractEditPayload, r as truncateTurnsAt, rt as resolveApprovalForPayload, s as formatToolCall, tt as mergeApprovalAndBodyOutcomes, u as capTranscriptEvents, v as indexOfEntry, x as normalizeMarkdownCodeFences, z as selectableTurnIds } from "./turn-operations-CXjRaltC.js";
|
|
@@ -1505,7 +1505,7 @@ const BASH_RESULT_MAX_LINES = 10;
|
|
|
1505
1505
|
* same-turn events read as one continuous highlighted block instead of a
|
|
1506
1506
|
* striped list.
|
|
1507
1507
|
*/
|
|
1508
|
-
const EventLine = memo(({ event, previous, depthOffset = 0, selected = false, anchorId, hideChildLabel = false, settleCodeEpoch = 0 }) => {
|
|
1508
|
+
const EventLine = memo(({ event, previous, depthOffset = 0, selected = false, anchorId, hideChildLabel = false, settleCodeEpoch = 0, liveSpawn }) => {
|
|
1509
1509
|
const SURFACE = useSurfaces();
|
|
1510
1510
|
const gap = marginTopFor(event, previous);
|
|
1511
1511
|
return /* @__PURE__ */ jsx$1("box", {
|
|
@@ -1524,7 +1524,8 @@ const EventLine = memo(({ event, previous, depthOffset = 0, selected = false, an
|
|
|
1524
1524
|
depthOffset,
|
|
1525
1525
|
hideChildLabel,
|
|
1526
1526
|
selected,
|
|
1527
|
-
settleCodeEpoch
|
|
1527
|
+
settleCodeEpoch,
|
|
1528
|
+
liveSpawn
|
|
1528
1529
|
})
|
|
1529
1530
|
});
|
|
1530
1531
|
});
|
|
@@ -1977,10 +1978,12 @@ function Transcript({ events, settings, selectedTurnId = null, busy = false }) {
|
|
|
1977
1978
|
for (let i = items.length - 1; i >= 0 && open.size > 0; i--) {
|
|
1978
1979
|
const item = items[i];
|
|
1979
1980
|
const here = [];
|
|
1980
|
-
for (const [id,
|
|
1981
|
+
for (const [id, child] of open) if (item.kind === "child-run" ? item.events.some((e) => e.childId === id) : item.event.kind === "spawn-start" && item.event.childId === id) {
|
|
1981
1982
|
here.push({
|
|
1982
1983
|
id,
|
|
1983
|
-
activity: spawnActivity(
|
|
1984
|
+
activity: spawnActivity(child.events),
|
|
1985
|
+
startedAt: child.start.spawn?.startedAt ?? Date.now(),
|
|
1986
|
+
turns: observedSpawnTurns(child.events)
|
|
1984
1987
|
});
|
|
1985
1988
|
open.delete(id);
|
|
1986
1989
|
}
|
|
@@ -2030,18 +2033,14 @@ function Transcript({ events, settings, selectedTurnId = null, busy = false }) {
|
|
|
2030
2033
|
children: [items.map((item, i) => {
|
|
2031
2034
|
if (item.kind === "event") {
|
|
2032
2035
|
const live = liveByItem.get(i);
|
|
2033
|
-
|
|
2036
|
+
return /* @__PURE__ */ jsx$1(EventLine, {
|
|
2034
2037
|
event: item.event,
|
|
2035
2038
|
previous: item.previous,
|
|
2036
2039
|
selected: isTurnHighlighted(item.event, selectedTurnId, ownership),
|
|
2037
2040
|
anchorId: anchors.ids[i][0],
|
|
2038
|
-
settleCodeEpoch: codeSettle.current.targets.has(item.event) ? codeSettle.current.epoch : 0
|
|
2039
|
-
|
|
2040
|
-
|
|
2041
|
-
return /* @__PURE__ */ jsxs("box", { children: [line, live.map((spawn) => /* @__PURE__ */ jsx$1(LiveSpawnRow, {
|
|
2042
|
-
spawn,
|
|
2043
|
-
showLabel: true
|
|
2044
|
-
}, spawn.id))] }, i);
|
|
2041
|
+
settleCodeEpoch: codeSettle.current.targets.has(item.event) ? codeSettle.current.epoch : 0,
|
|
2042
|
+
liveSpawn: live?.[0]
|
|
2043
|
+
}, i);
|
|
2045
2044
|
}
|
|
2046
2045
|
return /* @__PURE__ */ jsx$1(SubagentBlock, {
|
|
2047
2046
|
events: item.events,
|
|
@@ -2068,27 +2067,37 @@ function Transcript({ events, settings, selectedTurnId = null, busy = false }) {
|
|
|
2068
2067
|
* events they've produced since. Computed against the FULL event list — a
|
|
2069
2068
|
* parent-depth row (e.g. a background-task banner) can split one child's
|
|
2070
2069
|
* events across two boxes, and only a global scan knows whether the child
|
|
2071
|
-
* actually finished. `spawn:
|
|
2072
|
-
*
|
|
2073
|
-
*
|
|
2074
|
-
*
|
|
2070
|
+
* actually finished. `spawn:complete` fires for EVERY terminal state
|
|
2071
|
+
* (success/abort/timeout/error \u2014 see spawn.ts), so a `spawn-end` marker is
|
|
2072
|
+
* the normal close; a child-tagged `error` event (`spawn:error`, e.g. a
|
|
2073
|
+
* destroy failure surfaced after completion) also closes, covering
|
|
2074
|
+
* whichever order the two arrive in. Live-only signal: replayed sessions
|
|
2075
|
+
* always synthesize a `spawn-end` per child run, so nothing stays open
|
|
2076
|
+
* after a reload.
|
|
2075
2077
|
*/
|
|
2076
2078
|
function openSpawns(events) {
|
|
2077
2079
|
const open = /* @__PURE__ */ new Map();
|
|
2078
2080
|
for (const event of events) {
|
|
2079
2081
|
if (!event.childId || (event.depth ?? 0) === 0) continue;
|
|
2080
2082
|
if (event.kind === "spawn-start") {
|
|
2081
|
-
open.set(event.childId,
|
|
2083
|
+
open.set(event.childId, {
|
|
2084
|
+
start: event,
|
|
2085
|
+
events: []
|
|
2086
|
+
});
|
|
2082
2087
|
continue;
|
|
2083
2088
|
}
|
|
2084
2089
|
if (event.kind === "spawn-end" || event.kind === "error") {
|
|
2085
2090
|
open.delete(event.childId);
|
|
2086
2091
|
continue;
|
|
2087
2092
|
}
|
|
2088
|
-
open.get(event.childId)?.push(event);
|
|
2093
|
+
open.get(event.childId)?.events.push(event);
|
|
2089
2094
|
}
|
|
2090
2095
|
return open;
|
|
2091
2096
|
}
|
|
2097
|
+
/** Distinct child-loop turns observed in the streamed event tail. */
|
|
2098
|
+
function observedSpawnTurns(events) {
|
|
2099
|
+
return new Set(events.flatMap((event) => event.turnId ? [event.turnId] : [])).size;
|
|
2100
|
+
}
|
|
2092
2101
|
/**
|
|
2093
2102
|
* One-word-ish description of what a running child is doing right now,
|
|
2094
2103
|
* derived from its trailing events: `text` while prose streams, `thinking`
|
|
@@ -2114,8 +2123,30 @@ function spawnActivity(events) {
|
|
|
2114
2123
|
default: return "working";
|
|
2115
2124
|
}
|
|
2116
2125
|
}
|
|
2126
|
+
/**
|
|
2127
|
+
* Pair lifecycle markers from the end so reused labels (`child-1` in a
|
|
2128
|
+
* later top-level run) don't make an old terminal hide a new active start.
|
|
2129
|
+
* Exported for the layout invariant test; renderers otherwise use it only
|
|
2130
|
+
* through {@link partitionTranscript}.
|
|
2131
|
+
*/
|
|
2132
|
+
function collapseCompletedSpawnStarts(events) {
|
|
2133
|
+
const keep = Array.from({ length: events.length }).fill(true);
|
|
2134
|
+
const terminalByChild = /* @__PURE__ */ new Map();
|
|
2135
|
+
for (let i = events.length - 1; i >= 0; i--) {
|
|
2136
|
+
const event = events[i];
|
|
2137
|
+
if (event.kind === "spawn-end" && event.childId) terminalByChild.set(event.childId, (terminalByChild.get(event.childId) ?? 0) + 1);
|
|
2138
|
+
else if (event.kind === "spawn-start" && event.childId) {
|
|
2139
|
+
const terminals = terminalByChild.get(event.childId) ?? 0;
|
|
2140
|
+
if (terminals > 0) {
|
|
2141
|
+
keep[i] = false;
|
|
2142
|
+
terminalByChild.set(event.childId, terminals - 1);
|
|
2143
|
+
}
|
|
2144
|
+
}
|
|
2145
|
+
}
|
|
2146
|
+
return events.filter((_, i) => keep[i]);
|
|
2147
|
+
}
|
|
2117
2148
|
function partitionTranscript(events, settings) {
|
|
2118
|
-
const visible = events.filter((e) => isVisible(e, settings));
|
|
2149
|
+
const visible = collapseCompletedSpawnStarts(events).filter((e) => isVisible(e, settings));
|
|
2119
2150
|
if (visible.length === 0) return [];
|
|
2120
2151
|
if (settings.hideSubagentOutput) return visible.map((event, i) => ({
|
|
2121
2152
|
kind: "event",
|
|
@@ -2171,7 +2202,7 @@ function SubagentBlock({ events, previous, selectedTurnId = null, anchorIds, cod
|
|
|
2171
2202
|
const title = childIds.length === 0 ? " subagent " : childIds.length === 1 ? ` ${childIds[0]} ` : ` subagents · ${childIds.join(", ")} `;
|
|
2172
2203
|
const marginTop = previous ? 1 : 0;
|
|
2173
2204
|
const hideChildLabel = childIds.length === 1;
|
|
2174
|
-
return /* @__PURE__ */
|
|
2205
|
+
return /* @__PURE__ */ jsx$1("box", {
|
|
2175
2206
|
title,
|
|
2176
2207
|
style: {
|
|
2177
2208
|
border: true,
|
|
@@ -2185,38 +2216,81 @@ function SubagentBlock({ events, previous, selectedTurnId = null, anchorIds, cod
|
|
|
2185
2216
|
flexShrink: 0,
|
|
2186
2217
|
alignSelf: "stretch"
|
|
2187
2218
|
},
|
|
2188
|
-
children:
|
|
2219
|
+
children: events.map((evt, i) => /* @__PURE__ */ jsx$1(EventLine, {
|
|
2189
2220
|
event: evt,
|
|
2190
2221
|
previous: events[i - 1],
|
|
2191
2222
|
depthOffset: 1,
|
|
2192
2223
|
selected: selectedTurnId !== null && evt.turnId === selectedTurnId,
|
|
2193
2224
|
anchorId: anchorIds?.[i],
|
|
2194
2225
|
hideChildLabel,
|
|
2195
|
-
settleCodeEpoch: codeSettleTargets?.has(evt) ? codeSettleEpoch : 0
|
|
2196
|
-
|
|
2197
|
-
|
|
2198
|
-
children: /* @__PURE__ */ jsx$1(LiveSpawnRow, {
|
|
2199
|
-
spawn,
|
|
2200
|
-
showLabel: !hideChildLabel
|
|
2201
|
-
})
|
|
2202
|
-
}, spawn.id))]
|
|
2226
|
+
settleCodeEpoch: codeSettleTargets?.has(evt) ? codeSettleEpoch : 0,
|
|
2227
|
+
liveSpawn: evt.kind === "spawn-start" ? live?.find((spawn) => spawn.id === evt.childId) : void 0
|
|
2228
|
+
}, i))
|
|
2203
2229
|
});
|
|
2204
2230
|
}
|
|
2205
|
-
/**
|
|
2206
|
-
|
|
2231
|
+
/**
|
|
2232
|
+
* Stable one-row subagent lifecycle layout. Identity/model/task stay in
|
|
2233
|
+
* the left lane for the whole run; only the right tail changes:
|
|
2234
|
+
* active `2 turns · 14s · ⠋ tool call`, done `4 turns`.
|
|
2235
|
+
*/
|
|
2236
|
+
function SpawnLifecycleMarker({ row, dim, event, hideChildLabel, live }) {
|
|
2207
2237
|
const COLOR = useColors();
|
|
2208
|
-
|
|
2209
|
-
|
|
2238
|
+
const frame = useSpinnerFrame();
|
|
2239
|
+
const terminal = event.kind === "spawn-end";
|
|
2240
|
+
const failed = terminal && (event.text.startsWith("error") || event.text.startsWith("aborted"));
|
|
2241
|
+
const turns = terminal ? event.spawn?.turns : live?.turns;
|
|
2242
|
+
const turnLabel = `${turns ?? 0} turn${turns === 1 ? "" : "s"}`;
|
|
2243
|
+
const elapsed = live ? formatDuration(Math.max(0, Date.now() - live.startedAt)) : null;
|
|
2244
|
+
return /* @__PURE__ */ jsxs("box", {
|
|
2245
|
+
style: {
|
|
2246
|
+
...row,
|
|
2247
|
+
flexDirection: "row",
|
|
2248
|
+
alignItems: "center"
|
|
2249
|
+
},
|
|
2210
2250
|
children: [
|
|
2211
|
-
/* @__PURE__ */
|
|
2212
|
-
|
|
2213
|
-
|
|
2214
|
-
|
|
2215
|
-
|
|
2251
|
+
/* @__PURE__ */ jsxs("text", {
|
|
2252
|
+
fg: dim,
|
|
2253
|
+
wrapMode: "none",
|
|
2254
|
+
style: { flexShrink: 1 },
|
|
2255
|
+
children: [
|
|
2256
|
+
/* @__PURE__ */ jsx$1("span", {
|
|
2257
|
+
fg: failed ? COLOR.error : COLOR.accent,
|
|
2258
|
+
children: terminal ? failed ? "✗ " : "🌳 " : "🌱 "
|
|
2259
|
+
}),
|
|
2260
|
+
!hideChildLabel && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx$1("span", {
|
|
2261
|
+
fg: COLOR.brand,
|
|
2262
|
+
children: event.childId ?? "child"
|
|
2263
|
+
}), /* @__PURE__ */ jsx$1("span", {
|
|
2264
|
+
fg: COLOR.mute,
|
|
2265
|
+
children: " · "
|
|
2266
|
+
})] }),
|
|
2267
|
+
event.model !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx$1("span", {
|
|
2268
|
+
fg: COLOR.model,
|
|
2269
|
+
children: event.model
|
|
2270
|
+
}), /* @__PURE__ */ jsx$1("span", {
|
|
2271
|
+
fg: COLOR.mute,
|
|
2272
|
+
children: " · "
|
|
2273
|
+
})] }),
|
|
2274
|
+
/* @__PURE__ */ jsx$1("span", {
|
|
2275
|
+
fg: COLOR.dim,
|
|
2276
|
+
children: terminal ? event.spawn?.task ?? event.text : event.text
|
|
2277
|
+
})
|
|
2278
|
+
]
|
|
2279
|
+
}),
|
|
2280
|
+
/* @__PURE__ */ jsx$1("box", { style: { flexGrow: 1 } }),
|
|
2281
|
+
/* @__PURE__ */ jsxs("text", {
|
|
2216
2282
|
fg: COLOR.mute,
|
|
2217
|
-
|
|
2218
|
-
|
|
2219
|
-
|
|
2283
|
+
wrapMode: "none",
|
|
2284
|
+
style: { flexShrink: 0 },
|
|
2285
|
+
children: [/* @__PURE__ */ jsx$1("span", { children: turnLabel }), live && /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
2286
|
+
/* @__PURE__ */ jsx$1("span", { children: ` · ${elapsed} · ` }),
|
|
2287
|
+
/* @__PURE__ */ jsx$1("span", {
|
|
2288
|
+
fg: COLOR.warn,
|
|
2289
|
+
children: frame
|
|
2290
|
+
}),
|
|
2291
|
+
/* @__PURE__ */ jsx$1("span", { children: ` ${live.activity}` })
|
|
2292
|
+
] })]
|
|
2293
|
+
})
|
|
2220
2294
|
]
|
|
2221
2295
|
});
|
|
2222
2296
|
}
|
|
@@ -2259,7 +2333,7 @@ function rowStyle(paddingLeft) {
|
|
|
2259
2333
|
alignSelf: "stretch"
|
|
2260
2334
|
};
|
|
2261
2335
|
}
|
|
2262
|
-
function EventLineImpl({ event, previous, depthOffset = 0, hideChildLabel = false, selected = false, settleCodeEpoch = 0 }) {
|
|
2336
|
+
function EventLineImpl({ event, previous, depthOffset = 0, hideChildLabel = false, selected = false, settleCodeEpoch = 0, liveSpawn }) {
|
|
2263
2337
|
const COLOR = useColors();
|
|
2264
2338
|
const { settings } = useSettings();
|
|
2265
2339
|
const cleanText = stripTerminalControlChars(event.text);
|
|
@@ -2382,58 +2456,18 @@ function EventLineImpl({ event, previous, depthOffset = 0, hideChildLabel = fals
|
|
|
2382
2456
|
settleCodeEpoch
|
|
2383
2457
|
})
|
|
2384
2458
|
});
|
|
2385
|
-
case "spawn-start": return /* @__PURE__ */ jsx$1(
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
|
|
2390
|
-
|
|
2391
|
-
fg: COLOR.accent,
|
|
2392
|
-
children: "🌱 "
|
|
2393
|
-
}),
|
|
2394
|
-
!hideChildLabel && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx$1("span", {
|
|
2395
|
-
fg: COLOR.brand,
|
|
2396
|
-
children: event.childId ?? "child"
|
|
2397
|
-
}), /* @__PURE__ */ jsx$1("span", {
|
|
2398
|
-
fg: COLOR.mute,
|
|
2399
|
-
children: " · "
|
|
2400
|
-
})] }),
|
|
2401
|
-
event.model !== void 0 && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx$1("span", {
|
|
2402
|
-
fg: COLOR.model,
|
|
2403
|
-
children: event.model
|
|
2404
|
-
}), /* @__PURE__ */ jsx$1("span", {
|
|
2405
|
-
fg: COLOR.mute,
|
|
2406
|
-
children: " · "
|
|
2407
|
-
})] }),
|
|
2408
|
-
/* @__PURE__ */ jsx$1("span", {
|
|
2409
|
-
fg: COLOR.dim,
|
|
2410
|
-
children: safeText
|
|
2411
|
-
})
|
|
2412
|
-
]
|
|
2413
|
-
})
|
|
2459
|
+
case "spawn-start": return /* @__PURE__ */ jsx$1(SpawnLifecycleMarker, {
|
|
2460
|
+
row,
|
|
2461
|
+
dim: COLOR.dim,
|
|
2462
|
+
event,
|
|
2463
|
+
hideChildLabel,
|
|
2464
|
+
live: liveSpawn
|
|
2414
2465
|
});
|
|
2415
|
-
case "spawn-end": return /* @__PURE__ */ jsx$1(
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
|
|
2419
|
-
|
|
2420
|
-
/* @__PURE__ */ jsx$1("span", {
|
|
2421
|
-
fg: COLOR.accent,
|
|
2422
|
-
children: "🌳 "
|
|
2423
|
-
}),
|
|
2424
|
-
!hideChildLabel && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx$1("span", {
|
|
2425
|
-
fg: COLOR.brand,
|
|
2426
|
-
children: event.childId ?? "child"
|
|
2427
|
-
}), /* @__PURE__ */ jsx$1("span", {
|
|
2428
|
-
fg: COLOR.mute,
|
|
2429
|
-
children: " · "
|
|
2430
|
-
})] }),
|
|
2431
|
-
/* @__PURE__ */ jsx$1("span", {
|
|
2432
|
-
fg: COLOR.mute,
|
|
2433
|
-
children: safeText
|
|
2434
|
-
})
|
|
2435
|
-
]
|
|
2436
|
-
})
|
|
2466
|
+
case "spawn-end": return /* @__PURE__ */ jsx$1(SpawnLifecycleMarker, {
|
|
2467
|
+
row,
|
|
2468
|
+
dim: COLOR.dim,
|
|
2469
|
+
event,
|
|
2470
|
+
hideChildLabel
|
|
2437
2471
|
});
|
|
2438
2472
|
case "compact-summary": return /* @__PURE__ */ jsx$1(CompactSummaryBlock, {
|
|
2439
2473
|
event,
|
|
@@ -4651,6 +4685,44 @@ function CwdPickerModal({ currentCwd, onPick }) {
|
|
|
4651
4685
|
});
|
|
4652
4686
|
}
|
|
4653
4687
|
//#endregion
|
|
4688
|
+
//#region src/tui/project-location-context.tsx
|
|
4689
|
+
const ProjectLocationContext = createContext(null);
|
|
4690
|
+
/** Resolve the project root used by BOTH discovery and agent activation. */
|
|
4691
|
+
function resolveProjectLocation(cwd) {
|
|
4692
|
+
return {
|
|
4693
|
+
cwd,
|
|
4694
|
+
projectDir: findGitRoot(cwd) ?? cwd
|
|
4695
|
+
};
|
|
4696
|
+
}
|
|
4697
|
+
/**
|
|
4698
|
+
* Single source of truth for the TUI's active cwd/project root. It must
|
|
4699
|
+
* sit ABOVE both `DiscoveryShell` and `AppShell`: discovery used to derive
|
|
4700
|
+
* a frozen root from `process.cwd()` while AppShell independently honored
|
|
4701
|
+
* `launch.cwd` and runtime project switches, causing `.agents` skills/MCPs
|
|
4702
|
+
* to be read from the wrong repository.
|
|
4703
|
+
*/
|
|
4704
|
+
function ProjectLocationProvider({ initialCwd, children }) {
|
|
4705
|
+
const [location, setLocation] = useState(() => resolveProjectLocation(initialCwd));
|
|
4706
|
+
const setCwd = useCallback((next) => {
|
|
4707
|
+
process.chdir(next);
|
|
4708
|
+
setLocation(resolveProjectLocation(next));
|
|
4709
|
+
}, []);
|
|
4710
|
+
const value = useMemo(() => ({
|
|
4711
|
+
cwd: location.cwd,
|
|
4712
|
+
projectDir: location.projectDir,
|
|
4713
|
+
setCwd
|
|
4714
|
+
}), [location, setCwd]);
|
|
4715
|
+
return /* @__PURE__ */ jsx(ProjectLocationContext.Provider, {
|
|
4716
|
+
value,
|
|
4717
|
+
children
|
|
4718
|
+
});
|
|
4719
|
+
}
|
|
4720
|
+
function useProjectLocation() {
|
|
4721
|
+
const value = useContext(ProjectLocationContext);
|
|
4722
|
+
if (!value) throw new Error("useProjectLocation must be used inside ProjectLocationProvider");
|
|
4723
|
+
return value;
|
|
4724
|
+
}
|
|
4725
|
+
//#endregion
|
|
4654
4726
|
//#region src/tui/discovery-shell.tsx
|
|
4655
4727
|
/**
|
|
4656
4728
|
* SWR throttles. `files` is short so a long-open `@` popover picks up
|
|
@@ -4670,7 +4742,7 @@ function DiscoveryShell({ children }) {
|
|
|
4670
4742
|
const dispatchAuth = useMcpAuthDispatch();
|
|
4671
4743
|
const dispatchAuthRef = useRef(dispatchAuth);
|
|
4672
4744
|
dispatchAuthRef.current = dispatchAuth;
|
|
4673
|
-
const
|
|
4745
|
+
const { projectDir } = useProjectLocation();
|
|
4674
4746
|
const dataDir = config.paths.userDir;
|
|
4675
4747
|
const mcpCredentialStore = useMemo(() => createFileMcpCredentialStore(dataDir), [dataDir]);
|
|
4676
4748
|
const [skillsCatalog, setSkillsCatalog] = useState([]);
|
|
@@ -12670,11 +12742,13 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
12670
12742
|
})).catch((err) => {
|
|
12671
12743
|
if (err instanceof SkillInstallError && err.code === "multiple-candidates" && err.candidates && err.candidates.length > 0) {
|
|
12672
12744
|
setSkillOp(null);
|
|
12673
|
-
const
|
|
12745
|
+
const fullCatalog = err.details !== void 0 && err.details.length === err.candidates.length;
|
|
12746
|
+
const items = fullCatalog && err.details ? err.details : err.candidates.map((rel) => ({ rel }));
|
|
12674
12747
|
setSkillImportAll({
|
|
12675
12748
|
source: req.source,
|
|
12676
12749
|
scope: req.choice,
|
|
12677
|
-
items
|
|
12750
|
+
items,
|
|
12751
|
+
fullCatalog
|
|
12678
12752
|
});
|
|
12679
12753
|
return;
|
|
12680
12754
|
}
|
|
@@ -13551,7 +13625,7 @@ function SettingsModal({ skillsCatalog: skillsCatalogProp, mcpsCatalog: mcpsCata
|
|
|
13551
13625
|
onConfirm: (selected) => {
|
|
13552
13626
|
const req = skillImportAll;
|
|
13553
13627
|
setSkillImportAll(null);
|
|
13554
|
-
runSkillInstall(selected.length === req.items.length ? {
|
|
13628
|
+
runSkillInstall(req.fullCatalog && selected.length === req.items.length ? {
|
|
13555
13629
|
source: req.source,
|
|
13556
13630
|
all: true,
|
|
13557
13631
|
choice: req.scope
|
|
@@ -15991,7 +16065,8 @@ function App({ config }) {
|
|
|
15991
16065
|
*/
|
|
15992
16066
|
function ThemedShell() {
|
|
15993
16067
|
const { settings } = useSettings();
|
|
15994
|
-
const
|
|
16068
|
+
const config = useConfig();
|
|
16069
|
+
const [extensionRegistry, setExtensionRegistry] = useState(config.extensions);
|
|
15995
16070
|
useEffect(() => () => {
|
|
15996
16071
|
disposeExtensionRegistry(extensionRegistry);
|
|
15997
16072
|
}, [extensionRegistry]);
|
|
@@ -16008,7 +16083,10 @@ function ThemedShell() {
|
|
|
16008
16083
|
registry: renderersRegistry,
|
|
16009
16084
|
children: /* @__PURE__ */ jsx$1(ThemeProvider, {
|
|
16010
16085
|
theme,
|
|
16011
|
-
children: /* @__PURE__ */ jsx$1(MdStyleProvider, { children: /* @__PURE__ */ jsx$1(ChipStyleProvider, { children: /* @__PURE__ */ jsx$1(SafeModeProvider, { children: /* @__PURE__ */ jsx$1(InteractionsProvider, { children: /* @__PURE__ */ jsx$1(McpAuthProvider, { children: /* @__PURE__ */ jsx$1(
|
|
16086
|
+
children: /* @__PURE__ */ jsx$1(MdStyleProvider, { children: /* @__PURE__ */ jsx$1(ChipStyleProvider, { children: /* @__PURE__ */ jsx$1(SafeModeProvider, { children: /* @__PURE__ */ jsx$1(InteractionsProvider, { children: /* @__PURE__ */ jsx$1(McpAuthProvider, { children: /* @__PURE__ */ jsx$1(ProjectLocationProvider, {
|
|
16087
|
+
initialCwd: config.launch?.cwd ?? process.cwd(),
|
|
16088
|
+
children: /* @__PURE__ */ jsx$1(DiscoveryShell, { children: /* @__PURE__ */ jsx$1(ModalRoot, { children: /* @__PURE__ */ jsx$1(AppShell, {}) }) })
|
|
16089
|
+
}) }) }) }) }) })
|
|
16012
16090
|
})
|
|
16013
16091
|
})
|
|
16014
16092
|
});
|
|
@@ -16184,16 +16262,9 @@ function AppShell() {
|
|
|
16184
16262
|
useEffect(() => {
|
|
16185
16263
|
smoothStreamingRef.current = settings.smoothStreaming;
|
|
16186
16264
|
}, [settings.smoothStreaming]);
|
|
16187
|
-
const
|
|
16188
|
-
const [projectDir, setProjectDir] = useState(() => findGitRoot(initialCwd) ?? initialCwd);
|
|
16189
|
-
const [cwd, setCwdRaw] = useState(() => initialCwd);
|
|
16265
|
+
const { cwd, projectDir, setCwd } = useProjectLocation();
|
|
16190
16266
|
const cwdRef = useRef(cwd);
|
|
16191
16267
|
cwdRef.current = cwd;
|
|
16192
|
-
const setCwd = useCallback((next) => {
|
|
16193
|
-
process.chdir(next);
|
|
16194
|
-
setCwdRaw(next);
|
|
16195
|
-
setProjectDir(findGitRoot(next) ?? next);
|
|
16196
|
-
}, []);
|
|
16197
16268
|
const safelistRef = useRef(null);
|
|
16198
16269
|
const readSafelist = useCallback(() => {
|
|
16199
16270
|
if (safelistRef.current === null) safelistRef.current = getSafelist(dataDir, projectDir);
|
|
@@ -17578,19 +17649,26 @@ function AppShell() {
|
|
|
17578
17649
|
});
|
|
17579
17650
|
const spawnStartedAt = /* @__PURE__ */ new Map();
|
|
17580
17651
|
agent.hooks.hook("spawn:before", ({ id, task, depth, model }) => {
|
|
17581
|
-
|
|
17652
|
+
const startedAt = Date.now();
|
|
17582
17653
|
const taskPreview = previewLine(task, 80);
|
|
17654
|
+
spawnStartedAt.set(id, {
|
|
17655
|
+
startedAt,
|
|
17656
|
+
task: taskPreview,
|
|
17657
|
+
...model ? { model } : {}
|
|
17658
|
+
});
|
|
17583
17659
|
stream.appendImmediate({
|
|
17584
17660
|
kind: "spawn-start",
|
|
17585
17661
|
text: taskPreview,
|
|
17586
17662
|
childId: id,
|
|
17587
17663
|
depth: depth ?? 1,
|
|
17664
|
+
spawn: { startedAt },
|
|
17588
17665
|
...model ? { model } : {}
|
|
17589
17666
|
});
|
|
17590
17667
|
});
|
|
17591
17668
|
agent.hooks.hook("spawn:complete", ({ id, depth, status, stats }) => {
|
|
17592
17669
|
const tag = status === "aborted" ? "aborted" : status === "error" ? "error" : "done";
|
|
17593
|
-
const
|
|
17670
|
+
const started = spawnStartedAt.get(id);
|
|
17671
|
+
const startedAt = started?.startedAt;
|
|
17594
17672
|
spawnStartedAt.delete(id);
|
|
17595
17673
|
const elapsed = startedAt !== void 0 ? ` · ${formatDuration(Date.now() - startedAt)}` : "";
|
|
17596
17674
|
const cost = flattenTurns(stats).reduce((sum, turn) => sum + (turn.cost ?? 0), 0);
|
|
@@ -17599,7 +17677,13 @@ function AppShell() {
|
|
|
17599
17677
|
kind: "spawn-end",
|
|
17600
17678
|
text: segments ? `${tag}${segments} · ${formatTokenUsage(stats)}` : `${tag} ${formatTokenUsage(stats)}`,
|
|
17601
17679
|
childId: id,
|
|
17602
|
-
depth: depth ?? 1
|
|
17680
|
+
depth: depth ?? 1,
|
|
17681
|
+
spawn: {
|
|
17682
|
+
startedAt: startedAt ?? Date.now(),
|
|
17683
|
+
...started?.task ? { task: started.task } : {},
|
|
17684
|
+
turns: stats.turns
|
|
17685
|
+
},
|
|
17686
|
+
...started?.model ? { model: started.model } : {}
|
|
17603
17687
|
});
|
|
17604
17688
|
});
|
|
17605
17689
|
agent.hooks.hook("spawn:error", ({ id, depth, error }) => {
|