zidane 7.0.31 → 7.1.1

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.
Files changed (125) hide show
  1. package/README.md +21 -2
  2. package/dist/{acp-m3TLCY_C.js → acp-B5UfEhMd.js} +4 -4
  3. package/dist/{acp-m3TLCY_C.js.map → acp-B5UfEhMd.js.map} +1 -1
  4. package/dist/acp-cli.js +6 -6
  5. package/dist/acp.d.ts +2 -2
  6. package/dist/acp.js +1 -1
  7. package/dist/{agent-9gf8ZlBR.js → agent-_xxElOgH.js} +307 -33
  8. package/dist/agent-_xxElOgH.js.map +1 -0
  9. package/dist/agent.d.ts +1 -1
  10. package/dist/agent.js +1 -1
  11. package/dist/{anthropic-B4UmPm4H.js → anthropic-DPPs3wjJ.js} +111 -7
  12. package/dist/anthropic-DPPs3wjJ.js.map +1 -0
  13. package/dist/{approvals-DaCEPCTV.js → approvals-u2T19Dc-.js} +297 -95
  14. package/dist/approvals-u2T19Dc-.js.map +1 -0
  15. package/dist/{auth-CJogE9q7.js → auth-HRKkOErn.js} +3 -3
  16. package/dist/{auth-CJogE9q7.js.map → auth-HRKkOErn.js.map} +1 -1
  17. package/dist/chat/pure.d.ts +3 -3
  18. package/dist/chat/pure.js +1 -1
  19. package/dist/chat.d.ts +6 -6
  20. package/dist/chat.js +8 -8
  21. package/dist/contexts/daytona.d.ts +3 -3
  22. package/dist/contexts/docker.d.ts +1 -1
  23. package/dist/contexts/e2b.d.ts +2 -2
  24. package/dist/contexts/sandbox.d.ts +1 -1
  25. package/dist/{contexts-BSFQVclW.js → contexts-CRE9pw07.js} +544 -17
  26. package/dist/contexts-CRE9pw07.js.map +1 -0
  27. package/dist/contexts.d.ts +4 -4
  28. package/dist/contexts.js +2 -2
  29. package/dist/daemon-cli.js +1 -1
  30. package/dist/eval.d.ts +1 -1
  31. package/dist/eval.js +3 -3
  32. package/dist/extensions.d.ts +1 -1
  33. package/dist/extensions.js +1 -1
  34. package/dist/headless.d.ts +1 -1
  35. package/dist/headless.js +3 -3
  36. package/dist/{index-B6FkK6ZN.d.ts → index-C37_ppWv.d.ts} +2 -2
  37. package/dist/index-C37_ppWv.d.ts.map +1 -0
  38. package/dist/{index-JkEO3MBV.d.ts → index-D3TTaaQ5.d.ts} +39 -7
  39. package/dist/index-D3TTaaQ5.d.ts.map +1 -0
  40. package/dist/{index-hd4zLhp8.d.ts → index-DZhrTn-v.d.ts} +307 -16
  41. package/dist/index-DZhrTn-v.d.ts.map +1 -0
  42. package/dist/index.d.ts +5 -5
  43. package/dist/index.js +8 -8
  44. package/dist/{ipc-BtN5SIc0.js → ipc-DwauKEE-.js} +3 -3
  45. package/dist/{ipc-BtN5SIc0.js.map → ipc-DwauKEE-.js.map} +1 -1
  46. package/dist/ipc.d.ts +5 -5
  47. package/dist/ipc.js +3 -3
  48. package/dist/{types-U-rIVUDw.d.ts → isolation-Kfoof0MM.d.ts} +93 -2
  49. package/dist/isolation-Kfoof0MM.d.ts.map +1 -0
  50. package/dist/mcp.d.ts +1 -1
  51. package/dist/output/stream-json.d.ts +1 -1
  52. package/dist/output/terminal.d.ts +1 -1
  53. package/dist/{plugins-B531Tz5b.js → plugins-gbI7SBA6.js} +3 -3
  54. package/dist/{plugins-B531Tz5b.js.map → plugins-gbI7SBA6.js.map} +1 -1
  55. package/dist/plugins.d.ts +1 -1
  56. package/dist/plugins.js +1 -1
  57. package/dist/presets.d.ts +1 -1
  58. package/dist/presets.js +1 -1
  59. package/dist/providers/anthropic.d.ts +2 -2
  60. package/dist/providers/anthropic.js +2 -2
  61. package/dist/providers/arcee.d.ts +1 -1
  62. package/dist/providers/baseten.d.ts +1 -1
  63. package/dist/providers/cerebras.d.ts +1 -1
  64. package/dist/providers/local.d.ts +1 -1
  65. package/dist/providers/openai-compat.d.ts +1 -1
  66. package/dist/providers/openai.d.ts +1 -1
  67. package/dist/providers/openrouter.d.ts +1 -1
  68. package/dist/providers/xai.d.ts +1 -1
  69. package/dist/providers.d.ts +2 -2
  70. package/dist/providers.js +1 -1
  71. package/dist/restate.d.ts +2 -2
  72. package/dist/restate.js +1 -1
  73. package/dist/{sandbox-CDl9tfTo.d.ts → sandbox-BH0WQkXn.d.ts} +2 -2
  74. package/dist/{sandbox-CDl9tfTo.d.ts.map → sandbox-BH0WQkXn.d.ts.map} +1 -1
  75. package/dist/{server-ktOMu5gk.js → server-DvPnPSZb.js} +8 -8
  76. package/dist/{server-ktOMu5gk.js.map → server-DvPnPSZb.js.map} +1 -1
  77. package/dist/session/sqlite.d.ts +1 -1
  78. package/dist/session/sqlite.d.ts.map +1 -1
  79. package/dist/session/sqlite.js +7 -0
  80. package/dist/session/sqlite.js.map +1 -1
  81. package/dist/{session-CVy-2mAy.js → session-BqRP1hS7.js} +33 -3
  82. package/dist/session-BqRP1hS7.js.map +1 -0
  83. package/dist/session.d.ts +1 -1
  84. package/dist/session.js +1 -1
  85. package/dist/{skills-PJyiSRCp.js → skills-BC3dodWp.js} +2 -2
  86. package/dist/{skills-PJyiSRCp.js.map → skills-BC3dodWp.js.map} +1 -1
  87. package/dist/skills.d.ts +1 -1
  88. package/dist/skills.js +1 -1
  89. package/dist/{src-CjkY6fBj.js → src-CkNQKFKr.js} +3 -3
  90. package/dist/{src-CjkY6fBj.js.map → src-CkNQKFKr.js.map} +1 -1
  91. package/dist/{tool-formatters-C4QIFCNa.d.ts → tool-formatters-C5s88MUd.d.ts} +2 -2
  92. package/dist/{tool-formatters-C4QIFCNa.d.ts.map → tool-formatters-C5s88MUd.d.ts.map} +1 -1
  93. package/dist/tools/fetch-url.d.ts +1 -1
  94. package/dist/tools/web-search.d.ts +1 -1
  95. package/dist/tools.d.ts +1 -1
  96. package/dist/tools.js +1 -1
  97. package/dist/{transcript-anchors-Bbn1HX5D.d.ts → transcript-anchors-DxofXw_y.d.ts} +3 -3
  98. package/dist/transcript-anchors-DxofXw_y.d.ts.map +1 -0
  99. package/dist/tui.d.ts +21 -28
  100. package/dist/tui.d.ts.map +1 -1
  101. package/dist/tui.js +200 -74
  102. package/dist/tui.js.map +1 -1
  103. package/dist/{turn-operations-BgqpLlOG.js → turn-operations-6JDu2ewy.js} +24 -2
  104. package/dist/{turn-operations-BgqpLlOG.js.map → turn-operations-6JDu2ewy.js.map} +1 -1
  105. package/dist/{turn-operations-BhHCpCkP.d.ts → turn-operations-BaQnxzhr.d.ts} +14 -4
  106. package/dist/{turn-operations-BhHCpCkP.d.ts.map → turn-operations-BaQnxzhr.d.ts.map} +1 -1
  107. package/dist/types-CWgENVLY.js.map +1 -1
  108. package/dist/types.d.ts +3 -3
  109. package/docs/ARCHITECTURE.md +13 -3
  110. package/docs/CHAT.md +9 -0
  111. package/docs/EXECUTION_CONTEXT.md +64 -3
  112. package/docs/INTERACTIONS.md +14 -2
  113. package/docs/SKILL.md +31 -1
  114. package/docs/TUI.md +6 -5
  115. package/package.json +1 -1
  116. package/dist/agent-9gf8ZlBR.js.map +0 -1
  117. package/dist/anthropic-B4UmPm4H.js.map +0 -1
  118. package/dist/approvals-DaCEPCTV.js.map +0 -1
  119. package/dist/contexts-BSFQVclW.js.map +0 -1
  120. package/dist/index-B6FkK6ZN.d.ts.map +0 -1
  121. package/dist/index-JkEO3MBV.d.ts.map +0 -1
  122. package/dist/index-hd4zLhp8.d.ts.map +0 -1
  123. package/dist/session-CVy-2mAy.js.map +0 -1
  124. package/dist/transcript-anchors-Bbn1HX5D.d.ts.map +0 -1
  125. package/dist/types-U-rIVUDw.d.ts.map +0 -1
package/dist/tui.js CHANGED
@@ -1,29 +1,29 @@
1
1
  import { C as estimateRebilledCostUsd } from "./openai-compat-Dy56weK8.js";
2
2
  import { n as THINKING_LEVELS } from "./types-CWgENVLY.js";
3
3
  import { t as buildContextSegments } from "./context-segments-BrEsRhA0.js";
4
- import { $ as installExtensionFromSpec, A as selectFilesFromSession, C as resolveLegacySessionDir, Cn as createDebugLog, D as resolveTasksDir, Dn as coerceExtensionConfigInput, Dt as isSpawnTool, E as resolveSessionDir, Fn as createExtensionBus, Ft as tailTruncate, G as summaryToTurn, Gn as refreshArtifact, Jt as artifacts_default, Kn as renderArtifactRow, Lt as looksBinary, M as compactConversation, Mn as sanitizeExtensionConfigActionPatch, O as buildPostCompactAttachments, Rn as artifactKindLabel, S as resolveLegacyPersistDir, Sn as scanExtensionDirectories, T as resolvePersistDir, X as createExtensionPromptBridge, Xn as OUTPUT_RESERVE_TOKENS, Z as ExtensionInstallError, Zn as effectiveContextWindow, an as matchesBinding, at as createExtensionHud, dt as filterExtensionRegistry, en as KEYBINDING_KEY_COL_WIDTH, f as applyCompactSummaryCutoff, ft as filterRegistryPlugins, gt as createExtensionHostRuntimeBridge, hn as registerExtensionHostModules, in as keybindingsPath, it as updateInstalledExtension, jn as resolveExtensionConfigValue, lt as composeExtensionPreset, mt as partitionExtensionCatalog, nn as formatBindingForDisplay, ot as discoverAndBuildExtensionRegistry, rn as groupBindings, rt as removeInstalledExtension, t as createAgent, tn as ensureKeybindingsFile, un as resolveExtensionKeybindings, ut as disposeExtensionRegistry, v as cleanupPersistedSession, vt as composePresets, w as resolveMcpWarningsDir, wn as setDebugLogSink, x as rehomePersistedStubs, xn as parseExtensionScanPathEnv, xt as basic_default, yn as inlineLoadedExtension, zt as createModelSearchTool } from "./agent-9gf8ZlBR.js";
5
- import { D as shouldAutoGenerateTitle, E as generateSessionTitle, F as parseCommandInvocation, M as commandBlocksToContent, P as executeCommand, S as resolveInlineSuggestion, a as loginMcpServer, b as createPathAutocompleteProvider, c as SKILL_EDIT_METADATA_KEY, g as readSkillEditMarker, h as extensionScaffold, j as commandBlockToEvent, l as ZIDANE_EXTENSION_SKILL_NAME, m as extensionDirForCwd, p as editSessionMetadata, u as ZIDANE_SKILL_EDIT_SKILL_NAME, v as withZidaneExtensionSkill, w as generateStructuredData, x as patchInlineGhost, y as withZidaneSkillEditSkill } from "./src-CjkY6fBj.js";
4
+ import { $ as ExtensionInstallError, $n as effectiveContextWindow, A as buildPostCompactAttachments, Bn as artifactKindLabel, C as rehomePersistedStubs, Cn as parseExtensionScanPathEnv, Ct as basic_default, D as resolvePersistDir, E as resolveMcpWarningsDir, En as setDebugLogSink, Jn as renderArtifactRow, Ln as createExtensionBus, Lt as tailTruncate, M as selectFilesFromSession, Nn as resolveExtensionConfigValue, O as resolveSessionDir, P as compactConversation, Pn as sanitizeExtensionConfigActionPatch, Q as createExtensionPromptBridge, Qn as OUTPUT_RESERVE_TOKENS, T as resolveLegacySessionDir, Tn as createDebugLog, Vt as createModelSearchTool, Xt as artifacts_default, _n as registerExtensionHostModules, an as groupBindings, at as removeInstalledExtension, b as cleanupPersistedSession, bt as composePresets, ct as discoverAndBuildExtensionRegistry, dt as composeExtensionPreset, f as applyCompactSummaryCutoff, fn as resolveExtensionKeybindings, ft as disposeExtensionRegistry, gt as partitionExtensionCatalog, in as formatBindingForDisplay, k as resolveTasksDir, kn as coerceExtensionConfigInput, kt as isSpawnTool, mt as filterRegistryPlugins, nn as KEYBINDING_KEY_COL_WIDTH, on as keybindingsPath, ot as updateInstalledExtension, pt as filterExtensionRegistry, q as summaryToTurn, qn as refreshArtifact, rn as ensureKeybindingsFile, sn as matchesBinding, st as createExtensionHud, t as createAgent, tt as installExtensionFromSpec, vt as createExtensionHostRuntimeBridge, w as resolveLegacyPersistDir, wn as scanExtensionDirectories, xn as inlineLoadedExtension, zt as looksBinary } from "./agent-_xxElOgH.js";
5
+ import { D as shouldAutoGenerateTitle, E as generateSessionTitle, F as parseCommandInvocation, M as commandBlocksToContent, P as executeCommand, S as resolveInlineSuggestion, a as loginMcpServer, b as createPathAutocompleteProvider, c as SKILL_EDIT_METADATA_KEY, g as readSkillEditMarker, h as extensionScaffold, j as commandBlockToEvent, l as ZIDANE_EXTENSION_SKILL_NAME, m as extensionDirForCwd, p as editSessionMetadata, u as ZIDANE_SKILL_EDIT_SKILL_NAME, v as withZidaneExtensionSkill, w as generateStructuredData, x as patchInlineGhost, y as withZidaneSkillEditSkill } from "./src-CkNQKFKr.js";
6
6
  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";
7
+ import { i as killProcessGroup, n as SUPPORTS_PROCESS_GROUPS, r as createProcessContext } from "./contexts-CRE9pw07.js";
7
8
  import { n as appendCapped } from "./output-cap-C9zukcCj.js";
8
- import { i as killProcessGroup, n as SUPPORTS_PROCESS_GROUPS, r as createProcessContext } from "./contexts-BSFQVclW.js";
9
9
  import { u as errorMessage } from "./errors-DKiMrOKq.js";
10
- import { E as buildCatalog, R as findGitRoot, c as SkillInstallError, l as installSkillFromSpec } from "./skills-PJyiSRCp.js";
10
+ import { E as buildCatalog, R as findGitRoot, c as SkillInstallError, l as installSkillFromSpec } from "./skills-BC3dodWp.js";
11
11
  import { i as nextLogLevel, n as filterLogRecords, r as formatLogLine } from "./logs-view-CWG8aUAG.js";
12
12
  import { a as createRingBufferSink, c as logFileTimestamp, i as createLoggingHooks, n as createFileSink, o as fanoutSink, r as createLogger } from "./logger--C1VQjwJ.js";
13
13
  import { i as sniffImageMediaType } from "./media-sniff-UKijEaiQ.js";
14
14
  import { _ as hasAuthorizationHeader, h as McpOAuthProvider, n as connectMcpServers, s as nonOwningMcpView } from "./mcp-CgNd-f3F.js";
15
15
  import { replaceDynamicSection, splitSystemPrompt } from "./prompt.js";
16
- import { a as getExtensionSessionState, c as setExtensionSessionState, i as demoteStaleRunningStatus, o as loadSession, t as createSession } from "./session-CVy-2mAy.js";
16
+ import { a as getExtensionSessionState, c as setExtensionSessionState, i as demoteStaleRunningStatus, l as withExtensionSession, o as loadSession, t as createSession } from "./session-BqRP1hS7.js";
17
17
  import { t as effectiveInputFromTurn } from "./stats-DAKBEKjc.js";
18
18
  import { s as withTimeout } from "./timeout-CjOG2mea.js";
19
19
  import { i as installCacheBreakLogger } from "./cache-telemetry-ehVdWsg2.js";
20
20
  import { s as resolveCompletionSubmit } from "./completion-core-BRo86R_L.js";
21
21
  import { n as JsonRpcRemoteError, t as JsonRpcConnectionClosedError } from "./json-rpc-rSWMUh9b.js";
22
- import { $ as reorderKeyed, $t as formatTokenCount, A as chunkMarkdownForRender, B as streamingLabel, C as usageTone, Ct as retagUserPromptEvents, Dt as streamEventSearchText, E as filterModelCatalog, Et as selectionAfterTurnRemoval, F as stripHtmlCommentsOutsideCode, G as chainPositionOf, Gt as shortSessionId, H as DAEMON_HEALTH_STYLE, Ht as sessionEventExcerpt, I as cacheBreakChip, It as isMainSession, J as filterChainFallbacks, Jt as fitRunReceiptCells, K as chainsEqual, Kt as truncateTitle, L as compactingLabel, M as codeTokenHasClosingFence, Mt as SESSION_EVENT_STATUS_STYLE, N as normalizeMarkdownCodeFences, O as parseCustomModelQuery, Ot as turnSelectionOwnership, P as splitMarkdownCodeBlocks, Q as providerKeySetChanged, Qt as formatRunReceiptLine, R as liveSessionCost, S as resetLabel, Sn as summarizeOutcomes, T as buildModelCatalog, Tn as createChatsCompletionProvider, Tt as selectableTurnIds, U as buildRunModel, Vt as sessionDirLabel, Wt as sessionEventMeta, Y as pickChainPrimary, Yt as formatCostUsd, Zt as formatRunReceiptCells, _ as turnContextSize, _n as mergeApprovalAndBodyOutcomes, _t as isTurnHighlighted, a as TOOL_DISPLAY, an as buildUnifiedDiff, at as createSkillsCompletionProvider, b as formatUsagePercent, bn as rewriteMultiEditHeader, bt as isVisibleDuringSearch, ct as createFilesCompletionProvider, d as finalizeStreamingMarkdown, dn as previewEditPayload, dt as createCommandsCompletionProvider, et as restoreChainFallbacks, f as finalizeStreamingMarkdownForOwner, ft as blendHsl, g as revealEarlierTranscriptEvents, gt as isEditErrorResult, h as replaceTranscriptTurnEvents, hn as buildEditOutcomesAnnotation, ht as EDIT_TOOL_NAMES, i as turnAsText, in as buildContextualDiff, j as closeDanglingCodeFence, ln as extractEditPayload, mt as BASH_CALL_ID_PREFIX, n as deleteTurnSafely, nn as runReceiptFromRun, nt as toggleChainEntry, o as displayNameFor, on as clipDiffForRender, ot as uniqueSkillNamesFromReferences, p as hiddenEarlierTranscriptCount, pn as summarizeEditPayload, pt as buildLinearRamp, r as truncateTurnsAt, s as formatToolCall, tn as hasRunReceipt, u as capTranscriptEvents, un as filetypeFromPath, v as formatBalance, vn as parseEditOutcomesFromResult, vt as isUserBashEvent, w as splitPromptSegments, wt as retagUserPromptEventsFromRefs, x as mostConstrainedWindow, xn as stripEditOutcomesAnnotation, xt as promptHistoryFromEvents, yn as resolveApprovalForPayload, yt as isVisible } from "./turn-operations-BgqpLlOG.js";
22
+ import { $ as providerKeySetChanged, $t as formatRunReceiptLine, A as chunkMarkdownForRender, C as usageTone, Cn as summarizeOutcomes, Dt as selectionAfterTurnRemoval, E as filterModelCatalog, En as createChatsCompletionProvider, Et as selectableTurnIds, F as stripHtmlCommentsOutsideCode, Gt as sessionEventMeta, Ht as sessionDirLabel, I as cacheBreakChip, K as chainPositionOf, Kt as shortSessionId, Lt as isMainSession, M as codeTokenHasClosingFence, N as normalizeMarkdownCodeFences, Nt as SESSION_EVENT_STATUS_STYLE, O as parseCustomModelQuery, Ot as streamEventSearchText, P as splitMarkdownCodeBlocks, Qt as formatRunReceiptCells, R as compactingLabel, S as resetLabel, Sn as stripEditOutcomesAnnotation, St as promptHistoryFromEvents, T as buildModelCatalog, Tt as retagUserPromptEventsFromRefs, U as DAEMON_HEALTH_STYLE, Ut as sessionEventExcerpt, V as streamingLabel, W as buildRunModel, X as pickChainPrimary, Xt as formatCostUsd, Y as filterChainFallbacks, Yt as fitRunReceiptCells, _ as turnContextSize, _t as isEditErrorResult, a as TOOL_DISPLAY, an as buildContextualDiff, b as formatUsagePercent, bn as resolveApprovalForPayload, bt as isVisible, d as finalizeStreamingMarkdown, dn as filetypeFromPath, en as formatTokenCount, et as reorderKeyed, f as finalizeStreamingMarkdownForOwner, fn as previewEditPayload, ft as createCommandsCompletionProvider, g as revealEarlierTranscriptEvents, gn as buildEditOutcomesAnnotation, gt as EDIT_TOOL_NAMES, h as replaceTranscriptTurnEvents, ht as BASH_CALL_ID_PREFIX, i as turnAsText, j as closeDanglingCodeFence, kt as turnSelectionOwnership, lt as createFilesCompletionProvider, mn as summarizeEditPayload, mt as buildLinearRamp, n as deleteTurnSafely, nn as hasRunReceipt, o as displayNameFor, on as buildUnifiedDiff, ot as createSkillsCompletionProvider, p as hiddenEarlierTranscriptCount, pt as blendHsl, q as chainsEqual, qt as truncateTitle, r as truncateTurnsAt, rn as runReceiptFromRun, rt as toggleChainEntry, s as formatToolCall, sn as clipDiffForRender, st as uniqueSkillNamesFromReferences, tt as restoreChainFallbacks, u as capTranscriptEvents, un as extractEditPayload, v as formatBalance, vn as mergeApprovalAndBodyOutcomes, vt as isTurnHighlighted, w as splitPromptSegments, wt as retagUserPromptEvents, x as mostConstrainedWindow, xn as rewriteMultiEditHeader, xt as isVisibleDuringSearch, yn as parseEditOutcomesFromResult, yt as isUserBashEvent, z as liveSessionCost } from "./turn-operations-6JDu2ewy.js";
23
23
  import { a as searchHighlightRanges, c as searchSessionHistoryIndexAsync, i as highlightSegments, n as buildSessionSearchIndexAsync, r as filterSessionSearchCatalog, u as searchSessionIndexAsync } from "./history-search-C4bk1Wz_.js";
24
- import { $ as supportsOAuth, $r as pruneTodosByRun, A as useSafeModeQueue, Ai as noticeTurnContent, An as quoteForShell, Ar as discoverAgentsMd, At as makeRequestInteraction, Bn as createArtifactsCompletionProvider, Ci as deriveSessionTitle, Ct as InteractionsProvider, Di as listSessionMeta, Dr as chatAutoCompactBehavior, Dt as createInteractionTools, Ei as lastContextSizeFromTurns, Et as createAutomaticInteractionResponse, Fn as ConfigProvider, G as usageChecksOptedOut, Gn as importFromClaudeCode, Gr as TODO_STATUS_GLYPHS, Gt as createMainSession, H as fetchAllProviderUsage, Hn as useCompletion, Ii as toolCallPreview, In as useConfig, J as fetchOAuthRedirect, Jn as upsertMcpServer, Jt as runEndNotice, Kn as mcpsWritePath, Kt as modelChainMetadata, Li as toolResultText, Ln as resolveConfig, M as addToSafelist, Mi as serverToolResultSummary, Mn as DiscoveryProvider, N as getSafelist, Ni as stripSpawnTokensLine, Nn as useDiscovery, Nt as useInteractionsActions, O as SafeModeProvider, Oi as loadState, Or as groupArtifacts, P as isOnSafelist, Pi as sumRunCosts, Pn as useDiscoveryOptional, Pt as useInteractionsQueue, Q as runOAuthLogin, Qn as discoverProjectMcps, Qr as pickActiveRunId, Qt as attachMcpWarnLog, R as suggestSafelistEntries, Ri as updateToolEventOutcomes, Rn as resolveStoragePaths, Rr as accentColor, Rt as installProviderDiagnosticHook, St as HOST_INTERACTION_ID_PREFIX, Ti as getSessionMeta, Tt as buildResumedToolResultsTurn, U as fetchProviderUsage, Un as countClaudeSessionFiles, V as clearProviderUsageCache, W as providerUsageSupported, Wn as hasClaudeCodeSetup, Wt as createBuiltinCommands, X as redirectUriFromAuthUrl, Xn as dedupMcpServersByName, Xt as discoverProjectPlugins, Yn as buildMcpServers, Yt as buildPluginContributions, Z as oauthUsesManualCodePaste, Zt as parsePluginScanPathEnv, _ as buildSpawnEndEvent, _i as envSection, _n as useSettings, _t as useMcpAuthState, an as buildHints, ar as buildRestartHint, at as subscribeMcpToolsCache, b as defaultSkillScanPaths, bn as resolveChipColor, bt as ASK_USER_TOOL, c as useSelectStyle, cn as useEnabledToggleSet, d as useTheme, dn as SETTINGS_CHOICES, dt as parentServerName, er as tryOpenBrowser, f as discoverSystemMd, fn as SETTINGS_INPUTS, ft as createFileMcpCredentialStore, g as useStreamBuffer, gi as buildPlanSystem, gt as useMcpAuthDispatch, h as userSystemMdPath, hi as buildBuildSystem, hn as clampFps, ht as McpAuthProvider, ii as useActiveTodos, in as truncateTrailing, jn as createDiscoverySlot, jt as pendingInteractionsFromTurns, k as useSafeModeActions, ki as marginTopFor, kn as parseEditorCommand, kt as isModelInteraction, l as useSurfaces, ln as DEFAULT_SETTINGS, lt as buildVisibleMcpRows, m as userScopeOverridesLoad, mn as SettingsProvider, mr as useRestartRequired, ni as setTodosForRun, nn as clipHintsToWidth, nt as mcpToolsCachePath, o as ThemeProvider, or as buildUpdateHint, p as renderSystemMdSeed, pn as SETTINGS_TOGGLES, q as formatPathForCwd, qn as removeMcpServer, qr as applyTodosSnapshot, r as computeTurnAnchors, ri as todoProgressLabel, rn as hintsLength, rr as bootTick, rt as refreshMcpToolsCatalog, s as useColors, sn as listProjectFiles, sr as useUpdateCheck, st as useMcpToolToggleMap, ti as selectActiveTodos, tn as EMPTY_HINTS, tr as tryRevealPath, tt as loadMcpToolsCache, un as SETTINGS_CATEGORIES, ut as indexOfServerRow, v as buildSpawnStartEvent, vi as chatReferenceTokensForPrompt, vt as getMcpAuthStatus, w as writeSessionExport, wi as eventsFromTurns, wt as PRESENT_PLAN_TOOL, x as discoverProjectSkills, xi as compactSummaryEvent, xn as resolveTheme, y as buildSkillsConfig, yi as createChatTurnsReadTool, zi as usageByModel } from "./approvals-DaCEPCTV.js";
25
- import { E as renderDefaultCallbackPage, T as restoreModelOptions, b as modelSupportsReasoning, c as setPreferredCredential, g as getContextWindow, h as enabledModelOptions, l as setProviderCredential, n as applyApiKeyEnv, t as detectAuth, w as piIdOf, y as modelOptionsFor } from "./auth-CJogE9q7.js";
26
- import { a as connectIpcClient, d as defaultSocketPath, f as ensureDaemonRunning, m as selfDaemonSpawnCommand, o as connectOrSpawnDaemon } from "./server-ktOMu5gk.js";
24
+ import { $ as supportsOAuth, $t as parsePluginScanPathEnv, A as useSafeModeQueue, Ai as listSessionMeta, Ar as chatWindowBehavior, At as useInteractionsActions, Bi as toolResultText, Bn as resolveStoragePaths, Cn as resolveTheme, Ct as createAutomaticInteractionResponse, Di as eventsFromTurns, Dt as makeRequestInteraction, Ei as deriveSessionTitle, Et as isModelInteraction, Fi as serverToolResultSummary, Fn as useDiscovery, Ft as installProviderDiagnosticHook, G as usageChecksOptedOut, Gn as countClaudeSessionFiles, H as fetchAllProviderUsage, Hi as usageByModel, Hn as createArtifactsCompletionProvider, Ht as applyThinkingBindingSetting, Ii as stripSpawnTokensLine, In as useDiscoveryOptional, J as fetchOAuthRedirect, Jn as mcpsWritePath, Jr as TODO_STATUS_GLYPHS, Kn as hasClaudeCodeSetup, Kt as resolveSandboxFromSettings, Li as sumRunCosts, Ln as ConfigProvider, M as addToSafelist, Mi as marginTopFor, Mn as quoteForShell, N as getSafelist, Ni as noticeTurnContent, Nn as createDiscoverySlot, Nr as discoverAgentsMd, O as SafeModeProvider, Oi as getSessionMeta, Ot as pendingInteractionsFromTurns, P as isOnSafelist, Pn as DiscoveryProvider, Q as runOAuthLogin, Qn as dedupMcpServersByName, Qt as discoverProjectPlugins, R as suggestSafelistEntries, Rn as useConfig, Si as createChatTurnsReadTool, Sn as resolveChipColor, St as buildResumedToolResultsTurn, U as fetchProviderUsage, Ut as createMainSession, V as clearProviderUsageCache, Vi as updateToolEventOutcomes, Vr as accentColor, Vt as createBuiltinCommands, W as providerUsageSupported, Wn as useCompletion, Wt as modelChainMetadata, X as redirectUriFromAuthUrl, Xn as upsertMcpServer, Xr as applyTodosSnapshot, Xt as runEndNotice, Yn as removeMcpServer, Z as oauthUsesManualCodePaste, Zn as buildMcpServers, Zt as buildPluginContributions, _ as buildSpawnEndEvent, _n as clampFps, _t as ASK_USER_TOOL, ai as setTodosForRun, an as hintsLength, ar as bootTick, at as subscribeMcpToolsCache, b as defaultSkillScanPaths, bi as envSection, bt as InteractionsProvider, c as useSelectStyle, cr as buildUpdateHint, d as useTheme, dn as DEFAULT_SETTINGS, dt as parentServerName, en as attachMcpWarnLog, er as discoverProjectMcps, f as discoverSystemMd, fn as SETTINGS_CATEGORIES, ft as McpAuthProvider, g as useStreamBuffer, gn as SettingsProvider, gr as useRestartRequired, h as userSystemMdPath, hn as SETTINGS_TOGGLES, ht as getMcpAuthStatus, ii as selectActiveTodos, in as clipHintsToWidth, ji as loadState, jn as parseEditorCommand, jr as groupArtifacts, jt as useInteractionsQueue, k as useSafeModeActions, ki as lastContextSizeFromTurns, l as useSurfaces, ln as listProjectFiles, lr as useUpdateCheck, lt as buildVisibleMcpRows, m as userScopeOverridesLoad, mn as SETTINGS_INPUTS, mt as useMcpAuthState, ni as pruneTodosByRun, nr as tryOpenBrowser, nt as mcpToolsCachePath, o as ThemeProvider, oi as todoProgressLabel, on as truncateTrailing, p as renderSystemMdSeed, pn as SETTINGS_CHOICES, pt as useMcpAuthDispatch, q as formatPathForCwd, qn as importFromClaudeCode, qt as createFileMcpCredentialStore, r as computeTurnAnchors, rn as EMPTY_HINTS, rr as tryRevealPath, rt as refreshMcpToolsCatalog, s as useColors, si as useActiveTodos, sn as buildHints, sr as buildRestartHint, st as useMcpToolToggleMap, ti as pickActiveRunId, tt as loadMcpToolsCache, un as useEnabledToggleSet, ut as indexOfServerRow, v as buildSpawnStartEvent, vi as buildBuildSystem, w as writeSessionExport, wi as compactSummaryEvent, wt as createInteractionTools, x as discoverProjectSkills, xi as chatReferenceTokensForPrompt, xt as PRESENT_PLAN_TOOL, y as buildSkillsConfig, yi as buildPlanSystem, yn as useSettings, yt as HOST_INTERACTION_ID_PREFIX, zi as toolCallPreview, zn as resolveConfig } from "./approvals-u2T19Dc-.js";
25
+ import { E as renderDefaultCallbackPage, T as restoreModelOptions, b as modelSupportsReasoning, c as setPreferredCredential, g as getContextWindow, h as enabledModelOptions, l as setProviderCredential, n as applyApiKeyEnv, t as detectAuth, w as piIdOf, y as modelOptionsFor } from "./auth-HRKkOErn.js";
26
+ import { a as connectIpcClient, d as defaultSocketPath, f as ensureDaemonRunning, m as selfDaemonSpawnCommand, o as connectOrSpawnDaemon } from "./server-DvPnPSZb.js";
27
27
  import { createDockerContext } from "./contexts/docker.js";
28
28
  import { createTuiStore } from "./session/sqlite.js";
29
29
  import { _ as buildVisibleAuthRows, a as editTodo, b as parentProviderKey, c as NOTICE_GLYPH, f as validateMcpForm, g as instructionPreviewLines, h as instructionOriginBadge, i as cycleTodoStatus, l as MCP_TRANSPORTS, m as buildVisibleInstructionRows, n as buildTodoRetryMessage, r as clearTodos, s as removeTodo, t as addTodo, v as indexOfProviderRow, x as selectableSources } from "./todo-edits-Dw2oO2ON.js";
@@ -31,9 +31,9 @@ import { basename, dirname, join, relative, resolve } from "node:path";
31
31
  import { Buffer } from "node:buffer";
32
32
  import * as fs from "node:fs";
33
33
  import { existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, rmSync, statSync, writeFileSync } from "node:fs";
34
+ import { homedir, tmpdir } from "node:os";
34
35
  import { readFile, unlink } from "node:fs/promises";
35
36
  import { spawn, spawnSync } from "node:child_process";
36
- import { homedir, tmpdir } from "node:os";
37
37
  import { Fzf, byLengthAsc } from "fzf";
38
38
  import * as React from "react";
39
39
  import { Component, createContext, createElement, memo, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
@@ -10517,14 +10517,18 @@ const COMMENT_TEXTAREA_BINDINGS = (() => {
10517
10517
  * accept/deny only happens through the picker below — same convention
10518
10518
  * as `ApprovalBlock`.
10519
10519
  */
10520
- function InteractionBlock({ request, onResolve }) {
10520
+ /** Default `abortRun` chord (`KEYBINDING_DEFS`), for callers that don't thread the resolved one. */
10521
+ const DEFAULT_ABORT_HINT = "ctrl+esc";
10522
+ function InteractionBlock({ request, onResolve, abortHint = DEFAULT_ABORT_HINT }) {
10521
10523
  if (request.kind === "plan") return /* @__PURE__ */ jsx$1(PlanInteractionBlock, {
10522
10524
  request,
10523
- onResolve
10525
+ onResolve,
10526
+ abortHint
10524
10527
  });
10525
10528
  return /* @__PURE__ */ jsx$1(QuestionInteractionBlock, {
10526
10529
  request,
10527
- onResolve
10530
+ onResolve,
10531
+ abortHint
10528
10532
  });
10529
10533
  }
10530
10534
  function InteractionShell({ title, maxHeight, minHeight, children }) {
@@ -10686,7 +10690,7 @@ const PLAN_OPTIONS = [
10686
10690
  description: "refuse the plan. The agent sees your note and the run stops"
10687
10691
  }
10688
10692
  ];
10689
- function PlanInteractionBlock({ request, onResolve }) {
10693
+ function PlanInteractionBlock({ request, onResolve, abortHint }) {
10690
10694
  const COLOR = useColors();
10691
10695
  const focused = useModalAwareFocus();
10692
10696
  const [stage, setStage] = useState("pick");
@@ -10720,7 +10724,7 @@ function PlanInteractionBlock({ request, onResolve }) {
10720
10724
  });
10721
10725
  }, [onResolve, decision]);
10722
10726
  if (stage === "comment") return /* @__PURE__ */ jsxs(InteractionShell, {
10723
- title: ` ${decision === "reject" ? "reject plan" : "revise plan"} · esc to abort run `,
10727
+ title: ` ${decision === "reject" ? "reject plan" : "revise plan"} · ${abortHint} to abort run `,
10724
10728
  children: [
10725
10729
  /* @__PURE__ */ jsxs("text", {
10726
10730
  fg: COLOR.dim,
@@ -10775,7 +10779,7 @@ function PlanInteractionBlock({ request, onResolve }) {
10775
10779
  ]
10776
10780
  }, "comment");
10777
10781
  return /* @__PURE__ */ jsxs(InteractionShell, {
10778
- title: " approve plan · esc to abort run ",
10782
+ title: ` approve plan · ${abortHint} to abort run `,
10779
10783
  children: [/* @__PURE__ */ jsx$1("text", {
10780
10784
  fg: COLOR.brand,
10781
10785
  wrapMode: "word",
@@ -10896,11 +10900,32 @@ function estimateQuestionRowHeight(question, status, width = Number.POSITIVE_INF
10896
10900
  }
10897
10901
  return height;
10898
10902
  }
10899
- function QuestionInteractionBlock({ request, onResolve }) {
10903
+ /**
10904
+ * Id of the synthetic "additional instructions" step every question wizard
10905
+ * ends on. Namespaced so it can never collide with a model-authored question
10906
+ * id; its answer is lifted out of `answers` into `QuestionResponse.instructions`
10907
+ * on resolve.
10908
+ */
10909
+ const INSTRUCTIONS_STEP_ID = "__zidane_instructions__";
10910
+ /**
10911
+ * The always-present last step: an optional textarea the user can leave empty.
10912
+ * Rendered through the same `QuestionRow` as model questions so it reads as
10913
+ * part of the form, not a second UI bolted on.
10914
+ */
10915
+ const INSTRUCTIONS_STEP = {
10916
+ id: INSTRUCTIONS_STEP_ID,
10917
+ type: "textarea",
10918
+ prompt: "Additional instructions",
10919
+ description: "optional: refine or override anything above. ↵ on an empty box sends the answers as they are",
10920
+ placeholder: "anything the agent should know or do differently…",
10921
+ required: false
10922
+ };
10923
+ function QuestionInteractionBlock({ request, onResolve, abortHint }) {
10900
10924
  const COLOR = useColors();
10901
10925
  const mdStyle = useMdStyle();
10902
10926
  const focused = useModalAwareFocus();
10903
- const { intro, questions } = request.payload;
10927
+ const { intro, questions: modelQuestions } = request.payload;
10928
+ const questions = useMemo(() => [...modelQuestions, INSTRUCTIONS_STEP], [modelQuestions]);
10904
10929
  const scrollboxRef = useRef(null);
10905
10930
  const [activeIndex, setActiveIndex] = useState(0);
10906
10931
  const [answers, setAnswers] = useState(() => {
@@ -10914,9 +10939,11 @@ function QuestionInteractionBlock({ request, onResolve }) {
10914
10939
  [id]: value
10915
10940
  };
10916
10941
  if (activeIndex + 1 >= questions.length) {
10942
+ const { [INSTRUCTIONS_STEP_ID]: instructions, ...modelAnswers } = next;
10917
10943
  onResolve({
10918
10944
  kind: "question",
10919
- answers: next
10945
+ answers: modelAnswers,
10946
+ ...typeof instructions === "string" && instructions.trim() ? { instructions } : {}
10920
10947
  });
10921
10948
  return;
10922
10949
  }
@@ -10968,7 +10995,7 @@ function QuestionInteractionBlock({ request, onResolve }) {
10968
10995
  maxRows
10969
10996
  ]);
10970
10997
  return /* @__PURE__ */ jsxs(InteractionShell, {
10971
- title: questions.length > 1 ? ` answer ${activeIndex + 1}/${questions.length} · esc to abort run ` : " answer · esc to abort run ",
10998
+ title: activeIndex >= modelQuestions.length ? ` additional instructions · ↵ to send · ${abortHint} to abort run ` : modelQuestions.length > 1 ? ` answer ${activeIndex + 1}/${modelQuestions.length} · ${abortHint} to abort run ` : ` answer · ${abortHint} to abort run `,
10972
10999
  maxHeight: maxRows,
10973
11000
  minHeight: Math.min(maxRows, contentRows + 2, Math.max(WIZARD_MIN_ROWS, termRows - 2)),
10974
11001
  children: [/* @__PURE__ */ jsxs("scrollbox", {
@@ -11047,7 +11074,7 @@ function QuestionRow({ anchorId, index, question, status, answer, initialAnswer,
11047
11074
  fg: markerColor,
11048
11075
  children: `${marker} `
11049
11076
  }),
11050
- /* @__PURE__ */ jsx$1("span", {
11077
+ question.id !== "__zidane_instructions__" && /* @__PURE__ */ jsx$1("span", {
11051
11078
  fg: COLOR.mute,
11052
11079
  children: `${index + 1}. `
11053
11080
  }),
@@ -11113,7 +11140,7 @@ function AnswerSummary({ question, answer }) {
11113
11140
  });
11114
11141
  }
11115
11142
  function formatAnswerForDisplay(question, answer) {
11116
- if (answer === void 0 || answer === "") return "(skipped)";
11143
+ if (answer === void 0 || answer === "" || typeof answer === "string" && !answer.trim()) return question.id === "__zidane_instructions__" ? "(none)" : "(skipped)";
11117
11144
  if (question.type === "confirm") return typeof answer === "boolean" ? answer ? question.affirmLabel ?? "yes" : question.denyLabel ?? "no" : "(invalid)";
11118
11145
  if (question.type === "select") {
11119
11146
  if (Array.isArray(answer)) {
@@ -11391,7 +11418,7 @@ function MultiSelectQuestionInput({ question, initialChoiceIds, onSubmit }) {
11391
11418
  }),
11392
11419
  choice.description && /* @__PURE__ */ jsx$1("span", {
11393
11420
  fg: COLOR.mute,
11394
- children: ` · ${choice.description}`
11421
+ children: choice.description.includes("\n") ? `\n${choice.description.split("\n").map((line) => ` ${line}`).join("\n")}` : ` · ${choice.description}`
11395
11422
  })
11396
11423
  ]
11397
11424
  }, choice.id);
@@ -12860,7 +12887,7 @@ const PAGE_JUMP = 6;
12860
12887
  function SessionsScreen({ sessions, currentId, focusedSessionId, onPick, onCreate, onFocusChange, contentMatches = /* @__PURE__ */ new Map(), contentSearching = false, contentSearchProgress = {
12861
12888
  done: 0,
12862
12889
  total: 0
12863
- }, onSearchQueryChange, showAllProjects = false, scopeLabel, presence, showArtifacts = true, onToggleScope, currentProjectRoot, mainSessionId = null }) {
12890
+ }, onSearchQueryChange, showAllProjects = false, scopeLabel, presence, showArtifacts = true, onToggleScope, currentProjectRoot, mainSessionId = null, notice = null }) {
12864
12891
  const focused = useModalAwareFocus();
12865
12892
  const COLOR = useColors();
12866
12893
  const inputRef = useRef(null);
@@ -13142,7 +13169,11 @@ function SessionsScreen({ sessions, currentId, focusedSessionId, onPick, onCreat
13142
13169
  height: 1,
13143
13170
  flexShrink: 0
13144
13171
  },
13145
- children: contentSearching && /* @__PURE__ */ jsx$1(Spinner, { label: `searching conversation history ${contentSearchProgress.done}/${contentSearchProgress.total}` })
13172
+ children: notice ? /* @__PURE__ */ jsx$1("text", {
13173
+ wrapMode: "none",
13174
+ fg: COLOR.warn,
13175
+ children: notice
13176
+ }) : contentSearching && /* @__PURE__ */ jsx$1(Spinner, { label: `searching conversation history ${contentSearchProgress.done}/${contentSearchProgress.total}` })
13146
13177
  })
13147
13178
  ]
13148
13179
  }), /* @__PURE__ */ jsx$1(TitleOverlay, {
@@ -13433,11 +13464,12 @@ const EMPTY_QUEUED_MESSAGES = [];
13433
13464
  function shouldRenderTranscriptSearch(searchMode, query) {
13434
13465
  return searchMode && query.trim().length > 0;
13435
13466
  }
13436
- function ChatScreen({ cwd, events, busy, compacting = false, queuedMessages = EMPTY_QUEUED_MESSAGES, queueSelectionIndex = null, queueShortcuts, onEnterQueueFromEmptyPrompt, settings, onSubmit, session, pending, onApproval, pendingInteraction, onInteraction, completionProviders, inlineAutocompleteProviders, onCompletionTab, enterSelectsCompletion, onPopupOpenChange, selectedTurnId, onSelectTurn, onOpenTurn, onOpenSessionEvent, transcriptSearchMode = false, transcriptSearchQuery = "", transcriptSearchEvents = [], transcriptSearchSearching = false, onTranscriptSearchModeChange, onTranscriptSearchQueryChange, onTranscriptSearchNavigate, onTranscriptSearchOpen, onLoadEarlierTranscript, promptTriggerHints, attachImageBinding, editorBinding, sessionDetailsBinding, frameWidth, artifactsAction = null, onDraftChange, remoteDraft, onDraftAttachmentsChange, remoteDraftAttachments, remoteSearchQuery, remoteSuggest, resolveGhostRemote }) {
13467
+ function ChatScreen({ cwd, events, busy, compacting = false, queuedMessages = EMPTY_QUEUED_MESSAGES, queueSelectionIndex = null, queueShortcuts, onEnterQueueFromEmptyPrompt, settings, onSubmit, session, pending, onApproval, pendingInteraction, onInteraction, completionProviders, inlineAutocompleteProviders, onCompletionTab, enterSelectsCompletion, onPopupOpenChange, selectedTurnId, onSelectTurn, onOpenTurn, onOpenSessionEvent, transcriptSearchMode = false, transcriptSearchQuery = "", transcriptSearchEvents = [], transcriptSearchSearching = false, onTranscriptSearchModeChange, onTranscriptSearchQueryChange, onTranscriptSearchNavigate, onTranscriptSearchOpen, onLoadEarlierTranscript, promptTriggerHints, attachImageBinding, editorBinding, abortBinding, sessionDetailsBinding, frameWidth, artifactsAction = null, onDraftChange, remoteDraft, onDraftAttachmentsChange, remoteDraftAttachments, remoteSearchQuery, remoteSuggest, resolveGhostRemote }) {
13437
13468
  const COLOR = useColors();
13438
13469
  const SURFACE = useSurfaces();
13439
13470
  const titleText = session?.title ?? "New session";
13440
13471
  const sessionShortcutKey = formatBindingForDisplay(sessionDetailsBinding);
13472
+ const abortHint = formatBindingForDisplay(abortBinding) || "ctrl+esc";
13441
13473
  const showSessionShortcut = !!session && !!sessionShortcutKey && !busy && !pending && !pendingInteraction && settings.uiMode !== "minimal";
13442
13474
  const userMessageCount = useMemo(() => events.filter((e) => e.kind === "user-prompt").length, [events]);
13443
13475
  const { width: termWidth } = useTerminalDimensions();
@@ -13571,11 +13603,13 @@ function ChatScreen({ cwd, events, busy, compacting = false, queuedMessages = EM
13571
13603
  children: [
13572
13604
  approvalPending && /* @__PURE__ */ jsx$1(ApprovalBlock, {
13573
13605
  request: approvalPending,
13574
- onPick: onApproval
13606
+ onPick: onApproval,
13607
+ abortHint
13575
13608
  }),
13576
13609
  pendingInteraction && !approvalPending && /* @__PURE__ */ jsx$1(InteractionBlock, {
13577
13610
  request: pendingInteraction,
13578
- onResolve: onInteraction
13611
+ onResolve: onInteraction,
13612
+ abortHint
13579
13613
  }, pendingInteraction.id),
13580
13614
  /* @__PURE__ */ jsxs("box", {
13581
13615
  style: {
@@ -13609,6 +13643,7 @@ function ChatScreen({ cwd, events, busy, compacting = false, queuedMessages = EM
13609
13643
  onEnterQueueFromEmpty: onEnterQueueFromEmptyPrompt,
13610
13644
  attachImageBinding,
13611
13645
  editorBinding,
13646
+ abortBinding,
13612
13647
  suspended: approvalPending != null || pendingInteraction != null,
13613
13648
  onDraftChange,
13614
13649
  remoteDraft,
@@ -13684,7 +13719,7 @@ function formatApprovalArgs(input) {
13684
13719
  * rows, and a `height: options.length` select would overdraw into the
13685
13720
  * summary above (the original bug).
13686
13721
  */
13687
- function ApprovalBlock({ request, onPick }) {
13722
+ function ApprovalBlock({ request, onPick, abortHint }) {
13688
13723
  const focused = useModalAwareFocus();
13689
13724
  const COLOR = useColors();
13690
13725
  const SELECT_THEME = useSelectStyle();
@@ -13715,7 +13750,7 @@ function ApprovalBlock({ request, onPick }) {
13715
13750
  }, [request.tool, request.input]);
13716
13751
  const height = 3 + options.length;
13717
13752
  return /* @__PURE__ */ jsxs("box", {
13718
- title: " approve tool call · esc to abort run ",
13753
+ title: ` approve tool call · ${abortHint} to abort run `,
13719
13754
  style: {
13720
13755
  border: true,
13721
13756
  borderColor: COLOR.warn,
@@ -13965,7 +14000,7 @@ const INLINE_GHOST_DEBOUNCE_MS = 120;
13965
14000
  function isTranscriptSearchExitKey(event, cursorOffset) {
13966
14001
  return event.name === "escape" || (event.name === "backspace" || event.name === "delete") && !event.ctrl && !event.meta && !event.shift && cursorOffset === 0;
13967
14002
  }
13968
- function PromptBlock({ userPrompts, onSubmit, completionProviders, inlineAutocompleteProviders, onCompletionTab, enterSelectsCompletion, onPopupOpenChange, searchMode = false, onSearchModeChange, onSearchQueryChange, onSearchNavigate, onSearchOpen, selectMode = null, triggerHints, busy = false, onEnterQueueFromEmpty, attachImageBinding, editorBinding, onDraftChange, remoteDraft, onDraftAttachmentsChange, remoteDraftAttachments, remoteSearchQuery, remoteSuggest, resolveGhostRemote, clipboardReader = readClipboardContent, suspended = false }) {
14003
+ function PromptBlock({ userPrompts, onSubmit, completionProviders, inlineAutocompleteProviders, onCompletionTab, enterSelectsCompletion, onPopupOpenChange, searchMode = false, onSearchModeChange, onSearchQueryChange, onSearchNavigate, onSearchOpen, selectMode = null, triggerHints, busy = false, onEnterQueueFromEmpty, attachImageBinding, editorBinding, abortBinding, onDraftChange, remoteDraft, onDraftAttachmentsChange, remoteDraftAttachments, remoteSearchQuery, remoteSuggest, resolveGhostRemote, clipboardReader = readClipboardContent, suspended = false }) {
13969
14004
  const focused = useModalAwareFocus();
13970
14005
  const renderer = useRenderer();
13971
14006
  const COLOR = useColors();
@@ -14746,7 +14781,8 @@ function PromptBlock({ userPrompts, onSubmit, completionProviders, inlineAutocom
14746
14781
  selectMode,
14747
14782
  searchMode,
14748
14783
  triggerHints,
14749
- busy
14784
+ busy,
14785
+ abortBinding
14750
14786
  })]
14751
14787
  })
14752
14788
  ]
@@ -14791,24 +14827,26 @@ const PROMPT_HINTS_NORMAL = [
14791
14827
  * swapped to "queue" — a streaming response means `↵` defers the next
14792
14828
  * prompt instead of firing it immediately.
14793
14829
  */
14794
- const PROMPT_HINTS_BUSY = [
14795
- {
14796
- key: "↵",
14797
- label: "queue"
14798
- },
14799
- {
14800
- key: "shift+↵",
14801
- label: "newline"
14802
- },
14803
- {
14804
- key: "↑↓",
14805
- label: "history"
14806
- },
14807
- {
14808
- key: "esc",
14809
- label: "abort"
14810
- }
14811
- ];
14830
+ function promptHintsBusy(abortBinding) {
14831
+ return [
14832
+ {
14833
+ key: "↵",
14834
+ label: "queue"
14835
+ },
14836
+ {
14837
+ key: "shift+↵",
14838
+ label: "newline"
14839
+ },
14840
+ {
14841
+ key: "↑↓",
14842
+ label: "history"
14843
+ },
14844
+ ...abortBinding ? [{
14845
+ key: formatBindingForDisplay(abortBinding),
14846
+ label: "abort"
14847
+ }] : []
14848
+ ];
14849
+ }
14812
14850
  /** Conversation search is the message selector with an optional filter. */
14813
14851
  const PROMPT_HINTS_SEARCH = [
14814
14852
  {
@@ -14855,11 +14893,12 @@ const PROMPT_HINTS_SELECT_QUEUE = [{
14855
14893
  * Swaps the hint set based on `selectMode` so the user sees only the
14856
14894
  * shortcuts that actually do something in the active mode.
14857
14895
  */
14858
- function PromptHints({ selectMode, searchMode = false, triggerHints, busy = false }) {
14896
+ function PromptHints({ selectMode, searchMode = false, triggerHints, busy = false, abortBinding }) {
14859
14897
  const { settings } = useSettings();
14860
14898
  const { width: termWidth } = useTerminalDimensions();
14861
14899
  const minimalResting = !selectMode && !searchMode && !busy && settings.uiMode === "minimal";
14862
- const primary = searchMode ? PROMPT_HINTS_SEARCH : selectMode === "queue" ? PROMPT_HINTS_SELECT_QUEUE : busy ? PROMPT_HINTS_BUSY : minimalResting ? EMPTY_HINTS : PROMPT_HINTS_NORMAL;
14900
+ const busyHints = useMemo(() => promptHintsBusy(abortBinding), [abortBinding]);
14901
+ const primary = searchMode ? PROMPT_HINTS_SEARCH : selectMode === "queue" ? PROMPT_HINTS_SELECT_QUEUE : busy ? busyHints : minimalResting ? EMPTY_HINTS : PROMPT_HINTS_NORMAL;
14863
14902
  const hints = useMemo(() => {
14864
14903
  const budget = Math.max(0, termWidth - 5);
14865
14904
  const tooLongCombined = !!triggerHints && triggerHints.length > 0 && !selectMode && primary.length > 0 && hintsLength(primary) + 3 + hintsLength(triggerHints) > budget;
@@ -21782,6 +21821,26 @@ function AppShell() {
21782
21821
  useEffect(() => {
21783
21822
  persistToolResultsRef.current = settings.persistToolResults;
21784
21823
  }, [settings.persistToolResults]);
21824
+ const stableToolListRef = useRef(settings.stableToolList);
21825
+ useEffect(() => {
21826
+ stableToolListRef.current = settings.stableToolList;
21827
+ }, [settings.stableToolList]);
21828
+ const sandboxSettingsRef = useRef({
21829
+ sandbox: settings.sandbox,
21830
+ sandboxNetwork: settings.sandboxNetwork,
21831
+ sandboxAllowWrite: settings.sandboxAllowWrite
21832
+ });
21833
+ useEffect(() => {
21834
+ sandboxSettingsRef.current = {
21835
+ sandbox: settings.sandbox,
21836
+ sandboxNetwork: settings.sandboxNetwork,
21837
+ sandboxAllowWrite: settings.sandboxAllowWrite
21838
+ };
21839
+ }, [
21840
+ settings.sandbox,
21841
+ settings.sandboxNetwork,
21842
+ settings.sandboxAllowWrite
21843
+ ]);
21785
21844
  const interactionModeRef = useRef(settings.interactionMode);
21786
21845
  useEffect(() => {
21787
21846
  interactionModeRef.current = settings.interactionMode;
@@ -21859,6 +21918,9 @@ function AppShell() {
21859
21918
  ]);
21860
21919
  const runCapsRef = useRef(runCaps);
21861
21920
  runCapsRef.current = runCaps;
21921
+ useEffect(() => {
21922
+ applyThinkingBindingSetting(settings.thinkingBinding);
21923
+ }, [settings.thinkingBinding]);
21862
21924
  /**
21863
21925
  * When THIS window's last local run settled, per session — exempts the
21864
21926
  * cross-process run guard from refusing our own settle-lagged
@@ -21903,10 +21965,16 @@ function AppShell() {
21903
21965
  return;
21904
21966
  }
21905
21967
  }, []);
21906
- const autoCompactBehaviorFor = useCallback((p) => {
21968
+ /**
21969
+ * Per-run window knobs: `autoCompact` (settings-driven) plus
21970
+ * `contextWindow` (always, when the catalog knows the model) so the loop's
21971
+ * window-relative wire budgets don't depend on the autocompact toggle.
21972
+ * Shared shape with the GUI/daemon engine via `chatWindowBehavior`.
21973
+ */
21974
+ const windowBehaviorFor = useCallback((p) => {
21907
21975
  const descriptor = providerRegistryRef.current[p.provider.key];
21908
21976
  const summarizer = resolveCompactionSummarizer(p);
21909
- return chatAutoCompactBehavior({
21977
+ return chatWindowBehavior({
21910
21978
  enabled: autoCompactRef.current,
21911
21979
  threshold: autoCompactThresholdRef.current,
21912
21980
  rawContextWindow: descriptor ? getContextWindow(descriptor, p.model) : null,
@@ -22581,6 +22649,16 @@ function AppShell() {
22581
22649
  queueSelectionIndexRef.current = queueSelectionIndex;
22582
22650
  const agentRef = useRef(null);
22583
22651
  /**
22652
+ * `<env> Date:` pinned per session activation. The `system:transform`
22653
+ * hook below re-renders the env block every turn; letting it read the
22654
+ * wall clock would rewrite `system` at midnight, and Anthropic binds every
22655
+ * replayed thinking block to the exact system bytes it was produced under
22656
+ * — one date rollover would drop the whole session's reasoning (and the
22657
+ * prompt cache). A session keeps the date it was activated with; the next
22658
+ * activation (new or resumed session) picks up the current day.
22659
+ */
22660
+ const envDateRef = useRef((/* @__PURE__ */ new Date()).toISOString().slice(0, 10));
22661
+ /**
22584
22662
  * Daemon runtime controller (experimental, `useDaemon` setting). When
22585
22663
  * set, execution lives in the shared daemon and `agentRef` stays null —
22586
22664
  * every `agentRef.current?.` consumer degrades soft by construction.
@@ -23170,7 +23248,8 @@ function AppShell() {
23170
23248
  const envOpts = {
23171
23249
  cwd,
23172
23250
  ...projectDir !== cwd ? { projectRoot: projectDir } : {},
23173
- allowInteraction
23251
+ allowInteraction,
23252
+ date: envDateRef.current
23174
23253
  };
23175
23254
  ctx.system = replaceDynamicSection(ctx.system, envSection(envOpts));
23176
23255
  });
@@ -23609,10 +23688,24 @@ function AppShell() {
23609
23688
  modelCatalogTools.model_search = createModelSearchTool(catalog);
23610
23689
  }
23611
23690
  }
23691
+ const sandbox = launch?.context === "docker" ? {
23692
+ isolation: void 0,
23693
+ warning: void 0
23694
+ } : resolveSandboxFromSettings(sandboxSettingsRef.current, actualCwd, { dataDir });
23612
23695
  const execution = launch?.context === "docker" ? createDockerContext({
23613
23696
  image: launch.image,
23614
23697
  cwd: actualCwd
23615
- }) : createProcessContext({ cwd: actualCwd });
23698
+ }) : createProcessContext({
23699
+ cwd: actualCwd,
23700
+ ...sandbox.isolation ? { isolation: sandbox.isolation } : {}
23701
+ });
23702
+ if (sandbox.warning) emitNotice({
23703
+ severity: "warn",
23704
+ label: "sandbox"
23705
+ }, sandbox.warning, {
23706
+ session,
23707
+ persist: false
23708
+ });
23616
23709
  const mergedSkills = {
23617
23710
  ...skillsConfig,
23618
23711
  ...composedPreset.skills ?? {}
@@ -23638,6 +23731,10 @@ function AppShell() {
23638
23731
  const mergedBehavior = {
23639
23732
  ...composedPreset.behavior ?? {},
23640
23733
  ...persistBehavior,
23734
+ ...stableToolListRef.current ? { toolSearch: {
23735
+ ...composedPreset.behavior?.toolSearch ?? {},
23736
+ mode: "dispatch"
23737
+ } } : {},
23641
23738
  tasksDir
23642
23739
  };
23643
23740
  const effectiveSystem = launch?.system !== void 0 ? launch.system : builtInSystem || composedPreset.system;
@@ -24699,7 +24796,7 @@ function AppShell() {
24699
24796
  ...currentPicked.effort ? { thinking: currentPicked.effort } : {},
24700
24797
  ...Object.keys(runModelOptions).length > 0 ? { modelOptions: runModelOptions } : {},
24701
24798
  behavior: {
24702
- autoCompact: autoCompactBehaviorFor(currentPicked),
24799
+ ...windowBehaviorFor(currentPicked),
24703
24800
  ...runCapsRef.current
24704
24801
  }
24705
24802
  });
@@ -24725,13 +24822,13 @@ function AppShell() {
24725
24822
  runningRef.current = false;
24726
24823
  wakeForTaskNotificationsRef.current();
24727
24824
  }
24728
- }, [stream, autoCompactBehaviorFor]);
24825
+ }, [stream, windowBehaviorFor]);
24729
24826
  const activateSession = useCallback(async (id, key, opts) => {
24730
24827
  const cleanup = teardown();
24731
24828
  const activation = connectionRef.current.begin();
24732
24829
  await cleanup;
24733
24830
  if (!activation.isCurrent()) return;
24734
- const loaded = id ? await loadSession(store, id) : null;
24831
+ const loaded = id ? await loadSession(store, id, { persistHeal: !(settingsRef.current.useDaemon && !isDaemonDisabledByEnv()) }) : null;
24735
24832
  if (!activation.isCurrent()) return;
24736
24833
  const freshProfile = loaded ? null : defaultAgentProfile();
24737
24834
  const session = loaded ?? await createSession({
@@ -24762,10 +24859,11 @@ function AppShell() {
24762
24859
  const useDaemon = settingsRef.current.useDaemon && !isDaemonDisabledByEnv();
24763
24860
  if (useDaemon) {
24764
24861
  setDaemonHealth("connecting");
24862
+ let seededFresh = false;
24765
24863
  await activation.connect({
24766
24864
  open: async (attempt) => {
24767
24865
  agentRef.current = null;
24768
- if (!loaded && typeof session.metadata.cwd !== "string") {
24866
+ if (!loaded && !seededFresh && typeof session.metadata.cwd !== "string") {
24769
24867
  session.setMeta("cwd", cwdRef.current ?? process.cwd());
24770
24868
  await session.save();
24771
24869
  if (!attempt.isCurrent()) throw new Error("activation superseded");
@@ -24781,11 +24879,12 @@ function AppShell() {
24781
24879
  if (sessionPick.effort && typeof session.metadata.effort !== "string") seedModelViaRpc = true;
24782
24880
  } else if (!hasSessionModel(session.metadata) && activePick) seedModelViaRpc = true;
24783
24881
  else activePick = null;
24784
- } else if (activePick) {
24882
+ } else if (activePick && !seededFresh) {
24785
24883
  for (const [k, v] of Object.entries(sessionModelMetadata(activePick))) session.setMeta(k, v);
24786
24884
  await session.save();
24787
24885
  if (!attempt.isCurrent()) throw new Error("activation superseded");
24788
24886
  }
24887
+ seededFresh = true;
24789
24888
  lastPushedModelRef.current = activePick ? modelPickTuple(activePick) : null;
24790
24889
  if (!attempt.isCurrent()) throw new Error("activation superseded");
24791
24890
  const sessionId = session.id;
@@ -24985,7 +25084,7 @@ function AppShell() {
24985
25084
  notifyTodosChanged();
24986
25085
  return;
24987
25086
  }
24988
- loadSession(store, sessionId).then((fresh) => {
25087
+ loadSession(store, sessionId, { persistHeal: false }).then((fresh) => {
24989
25088
  if (!attempt.isCurrent() || !fresh || sessionRef.current?.id !== sessionId) return;
24990
25089
  if (seq !== todosApplySeqRef.current) return;
24991
25090
  applyTodosSnapshot(fresh, snapshot);
@@ -25072,6 +25171,7 @@ function AppShell() {
25072
25171
  setDaemonConnected(true);
25073
25172
  if (stampedLegacyAgent) controller.setAgentId(pickedAgentRef.current.id);
25074
25173
  if (seedModelViaRpc && activePick) controller.applyModel(modelPickPayload(activePick));
25174
+ if (!loaded) controller.touchSession();
25075
25175
  return controller;
25076
25176
  },
25077
25177
  ready: () => {},
@@ -25109,6 +25209,7 @@ function AppShell() {
25109
25209
  }
25110
25210
  }
25111
25211
  lastPushedModelRef.current = primed ? modelPickTuple(primed) : null;
25212
+ envDateRef.current = (/* @__PURE__ */ new Date()).toISOString().slice(0, 10);
25112
25213
  agentRef.current = buildAgent(session, key);
25113
25214
  activation.localReady();
25114
25215
  }
@@ -25262,13 +25363,32 @@ function AppShell() {
25262
25363
  stateStore,
25263
25364
  refreshAvailableProviders
25264
25365
  ]);
25366
+ const [sessionsNotice, setSessionsNotice] = useState(null);
25367
+ const localRunBlocksSwitch = useCallback((targetId) => {
25368
+ if (daemonRef.current || !busy) return false;
25369
+ if (targetId !== null && targetId === sessionRef.current?.id) return false;
25370
+ setSessionsNotice(`a run is in progress in this window — ${formatBindingForDisplay(keybindings.abortRun)} to abort it first, or turn on the daemon (${formatBindingForDisplay(keybindings.openSettings)} settings) to keep runs going while you switch`);
25371
+ return true;
25372
+ }, [
25373
+ busy,
25374
+ keybindings.abortRun,
25375
+ keybindings.openSettings
25376
+ ]);
25377
+ useEffect(() => {
25378
+ if (screen !== "sessions") setSessionsNotice(null);
25379
+ }, [screen]);
25265
25380
  const onCreateSession = useCallback(async () => {
25266
- if (picked) await activateSession(null, picked.provider.key);
25267
- }, [picked, activateSession]);
25381
+ if (!picked || localRunBlocksSwitch(null)) return;
25382
+ await activateSession(null, picked.provider.key);
25383
+ }, [
25384
+ picked,
25385
+ activateSession,
25386
+ localRunBlocksSwitch
25387
+ ]);
25268
25388
  const pendingSessionSwitchRef = useRef(null);
25269
25389
  const [sessionSwitchNonce, setSessionSwitchNonce] = useState(0);
25270
25390
  const onSwitchSession = useCallback(async (id) => {
25271
- if (!picked) return;
25391
+ if (!picked || localRunBlocksSwitch(id)) return;
25272
25392
  const targetRoot = sessions.find((s) => s.id === id)?.projectRoot;
25273
25393
  if (targetRoot && targetRoot !== projectDir) {
25274
25394
  pendingSessionSwitchRef.current = {
@@ -25290,7 +25410,8 @@ function AppShell() {
25290
25410
  sessions,
25291
25411
  projectDir,
25292
25412
  setCwd,
25293
- activateSession
25413
+ activateSession,
25414
+ localRunBlocksSwitch
25294
25415
  ]);
25295
25416
  const orchestrationSeenRef = useRef(settings.orchestration);
25296
25417
  useEffect(() => {
@@ -26054,7 +26175,7 @@ function AppShell() {
26054
26175
  ...picked.effort ? { thinking: picked.effort } : {},
26055
26176
  ...Object.keys(runModelOptions).length > 0 ? { modelOptions: runModelOptions } : {},
26056
26177
  behavior: {
26057
- autoCompact: autoCompactBehaviorFor(picked),
26178
+ ...windowBehaviorFor(picked),
26058
26179
  ...runCapsRef.current
26059
26180
  }
26060
26181
  });
@@ -26085,7 +26206,7 @@ function AppShell() {
26085
26206
  }, [
26086
26207
  picked,
26087
26208
  stream,
26088
- autoCompactBehaviorFor
26209
+ windowBehaviorFor
26089
26210
  ]);
26090
26211
  /**
26091
26212
  * Run a `/` command: a workflow whose steps `emit` display-only output
@@ -26201,7 +26322,7 @@ function AppShell() {
26201
26322
  ...picked.effort ? { thinking: picked.effort } : {},
26202
26323
  ...Object.keys(runModelOptions).length > 0 ? { modelOptions: runModelOptions } : {},
26203
26324
  behavior: {
26204
- autoCompact: autoCompactBehaviorFor(picked),
26325
+ ...windowBehaviorFor(picked),
26205
26326
  ...runCapsRef.current
26206
26327
  }
26207
26328
  });
@@ -26437,7 +26558,7 @@ function AppShell() {
26437
26558
  text: ""
26438
26559
  });
26439
26560
  emitBlock({ text: `\`❯ /${invocation.name}${invocation.args ? ` ${invocation.args}` : ""}\`` });
26440
- const result = await executeCommand(command, ctx);
26561
+ const result = await withExtensionSession(session, () => executeCommand(command, ctx));
26441
26562
  if (result.error) emitNotice({
26442
26563
  severity: "error",
26443
26564
  label: "command"
@@ -26465,7 +26586,7 @@ function AppShell() {
26465
26586
  stream,
26466
26587
  cwd,
26467
26588
  picked,
26468
- autoCompactBehaviorFor,
26589
+ windowBehaviorFor,
26469
26590
  providerRegistry,
26470
26591
  interactions,
26471
26592
  credentialedModelEntries
@@ -28282,8 +28403,11 @@ function AppShell() {
28282
28403
  }
28283
28404
  return;
28284
28405
  }
28406
+ if (matchesBinding(key, keybindings.abortRun)) {
28407
+ if (busy || pendingApproval) onAbort();
28408
+ return;
28409
+ }
28285
28410
  if (key.name !== "escape") return;
28286
- if (busy || pendingApproval) return onAbort();
28287
28411
  if (popupOpenRef.current) return;
28288
28412
  if (screen === "chat") return onOpenSessions();
28289
28413
  if (screen === "sessions") {
@@ -28518,7 +28642,8 @@ function AppShell() {
28518
28642
  presence: sessionPresence,
28519
28643
  onToggleScope: toggleSessionsScope,
28520
28644
  currentProjectRoot: projectDir,
28521
- mainSessionId: settings.orchestration ? mainSessionId : null
28645
+ mainSessionId: settings.orchestration ? mainSessionId : null,
28646
+ notice: sessionsNotice
28522
28647
  }),
28523
28648
  screen === "chat" && /* @__PURE__ */ jsxs("box", {
28524
28649
  style: {
@@ -28586,7 +28711,8 @@ function AppShell() {
28586
28711
  promptTriggerHints,
28587
28712
  attachImageBinding: keybindings.attachClipboardImage,
28588
28713
  editorBinding: settings.externalEditor ? keybindings.openExternalEditor : void 0,
28589
- sessionDetailsBinding: keybindings.openSessionDetails
28714
+ sessionDetailsBinding: keybindings.openSessionDetails,
28715
+ abortBinding: keybindings.abortRun
28590
28716
  })
28591
28717
  }), artifactsPanelVisible && /* @__PURE__ */ jsx$1(ArtifactsPanel, {
28592
28718
  load: loadPanelArtifacts,