@bastani/atomic 0.9.16-alpha.10 → 0.9.16-alpha.11

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 (155) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +4 -4
  3. package/dist/builtin/intercom/CHANGELOG.md +6 -0
  4. package/dist/builtin/intercom/README.md +2 -5
  5. package/dist/builtin/intercom/index.bundle.mjs +176 -132
  6. package/dist/builtin/intercom/package.json +2 -2
  7. package/dist/builtin/intercom/skills/intercom/SKILL.md +1 -1
  8. package/dist/builtin/mcp/index.bundle.mjs +176 -120
  9. package/dist/builtin/mcp/package.json +2 -2
  10. package/dist/builtin/subagents/CHANGELOG.md +11 -0
  11. package/dist/builtin/subagents/README.md +3 -3
  12. package/dist/builtin/subagents/package.json +3 -3
  13. package/dist/builtin/subagents/src/extension/index.bundle.mjs +396 -208
  14. package/dist/builtin/web-access/index.bundle.mjs +176 -120
  15. package/dist/builtin/web-access/package.json +2 -2
  16. package/dist/builtin/workflows/CHANGELOG.md +11 -0
  17. package/dist/builtin/workflows/README.md +1 -1
  18. package/dist/builtin/workflows/builtin/{chunk-tr5kqhba.js → chunk-3y1hmzw6.js} +1 -1
  19. package/dist/builtin/workflows/builtin/{chunk-xhrvz7wj.js → chunk-bz1c9732.js} +1 -1
  20. package/dist/builtin/workflows/builtin/{chunk-1ryp6jxq.js → chunk-dattsgxg.js} +1 -1
  21. package/dist/builtin/workflows/builtin/{chunk-peps7f1q.js → chunk-gdx0avpx.js} +329 -135
  22. package/dist/builtin/workflows/builtin/{chunk-5n8ras9g.js → chunk-w9c7rkrk.js} +1 -1
  23. package/dist/builtin/workflows/builtin/goal.js +3 -3
  24. package/dist/builtin/workflows/builtin/index.js +4 -4
  25. package/dist/builtin/workflows/builtin/open-claude-design.js +1 -1
  26. package/dist/builtin/workflows/builtin/ralph.js +3 -3
  27. package/dist/builtin/workflows/package.json +2 -2
  28. package/dist/builtin/workflows/src/extension/index.bundle.mjs +427 -196
  29. package/dist/builtin/workflows/src/index.js +186 -140
  30. package/dist/cli/args.js +6 -6
  31. package/dist/cli/args.js.map +1 -1
  32. package/dist/cli/config-selector.d.ts.map +1 -1
  33. package/dist/cli/config-selector.js +2 -1
  34. package/dist/cli/config-selector.js.map +1 -1
  35. package/dist/cli/session-picker.d.ts +2 -1
  36. package/dist/cli/session-picker.d.ts.map +1 -1
  37. package/dist/cli/session-picker.js +3 -2
  38. package/dist/cli/session-picker.js.map +1 -1
  39. package/dist/cli/startup-ui.d.ts.map +1 -1
  40. package/dist/cli/startup-ui.js +2 -1
  41. package/dist/cli/startup-ui.js.map +1 -1
  42. package/dist/core/agent-session-services.d.ts.map +1 -1
  43. package/dist/core/agent-session-services.js +6 -3
  44. package/dist/core/agent-session-services.js.map +1 -1
  45. package/dist/core/agent-session-state.d.ts.map +1 -1
  46. package/dist/core/agent-session-state.js +7 -5
  47. package/dist/core/agent-session-state.js.map +1 -1
  48. package/dist/core/agent-session-tool-hooks.d.ts.map +1 -1
  49. package/dist/core/agent-session-tool-hooks.js +9 -109
  50. package/dist/core/agent-session-tool-hooks.js.map +1 -1
  51. package/dist/core/agent-session-tool-registry.d.ts.map +1 -1
  52. package/dist/core/agent-session-tool-registry.js +9 -2
  53. package/dist/core/agent-session-tool-registry.js.map +1 -1
  54. package/dist/core/builtin-packages.d.ts +4 -0
  55. package/dist/core/builtin-packages.d.ts.map +1 -1
  56. package/dist/core/builtin-packages.js +22 -1
  57. package/dist/core/builtin-packages.js.map +1 -1
  58. package/dist/core/callback-activity.d.ts.map +1 -1
  59. package/dist/core/callback-activity.js +6 -3
  60. package/dist/core/callback-activity.js.map +1 -1
  61. package/dist/core/extensions/loader-core.d.ts +1 -0
  62. package/dist/core/extensions/loader-core.d.ts.map +1 -1
  63. package/dist/core/extensions/loader-core.js +11 -1
  64. package/dist/core/extensions/loader-core.js.map +1 -1
  65. package/dist/core/extensions/loader.d.ts +1 -1
  66. package/dist/core/extensions/loader.d.ts.map +1 -1
  67. package/dist/core/extensions/loader.js +1 -1
  68. package/dist/core/extensions/loader.js.map +1 -1
  69. package/dist/core/extensions/runner-registries.d.ts.map +1 -1
  70. package/dist/core/extensions/runner-registries.js +9 -4
  71. package/dist/core/extensions/runner-registries.js.map +1 -1
  72. package/dist/core/extensions/runner-shortcuts.d.ts.map +1 -1
  73. package/dist/core/extensions/runner-shortcuts.js +1 -0
  74. package/dist/core/extensions/runner-shortcuts.js.map +1 -1
  75. package/dist/core/keybindings.d.ts +5 -0
  76. package/dist/core/keybindings.d.ts.map +1 -1
  77. package/dist/core/keybindings.js +4 -0
  78. package/dist/core/keybindings.js.map +1 -1
  79. package/dist/core/mandatory-resource-loader.d.ts +6 -0
  80. package/dist/core/mandatory-resource-loader.d.ts.map +1 -0
  81. package/dist/core/mandatory-resource-loader.js +94 -0
  82. package/dist/core/mandatory-resource-loader.js.map +1 -0
  83. package/dist/core/mandatory-runtime-tools.d.ts +10 -0
  84. package/dist/core/mandatory-runtime-tools.d.ts.map +1 -0
  85. package/dist/core/mandatory-runtime-tools.js +31 -0
  86. package/dist/core/mandatory-runtime-tools.js.map +1 -0
  87. package/dist/core/resource-loader-reload.d.ts.map +1 -1
  88. package/dist/core/resource-loader-reload.js +24 -13
  89. package/dist/core/resource-loader-reload.js.map +1 -1
  90. package/dist/core/sdk.d.ts.map +1 -1
  91. package/dist/core/sdk.js +2 -0
  92. package/dist/core/sdk.js.map +1 -1
  93. package/dist/core/settings-manager-ui-accessors.d.ts +4 -1
  94. package/dist/core/settings-manager-ui-accessors.d.ts.map +1 -1
  95. package/dist/core/settings-manager-ui-accessors.js +22 -0
  96. package/dist/core/settings-manager-ui-accessors.js.map +1 -1
  97. package/dist/core/settings-types.d.ts +4 -0
  98. package/dist/core/settings-types.d.ts.map +1 -1
  99. package/dist/core/settings-types.js.map +1 -1
  100. package/dist/core/slash-commands.js +1 -1
  101. package/dist/core/slash-commands.js.map +1 -1
  102. package/dist/main-session.d.ts.map +1 -1
  103. package/dist/main-session.js +3 -2
  104. package/dist/main-session.js.map +1 -1
  105. package/dist/main.d.ts.map +1 -1
  106. package/dist/main.js +6 -0
  107. package/dist/main.js.map +1 -1
  108. package/dist/modes/interactive/components/fast-mode-selector.js +2 -2
  109. package/dist/modes/interactive/components/fast-mode-selector.js.map +1 -1
  110. package/dist/modes/interactive/components/settings-selector-handlers.d.ts.map +1 -1
  111. package/dist/modes/interactive/components/settings-selector-handlers.js +3 -0
  112. package/dist/modes/interactive/components/settings-selector-handlers.js.map +1 -1
  113. package/dist/modes/interactive/components/settings-selector-items.d.ts.map +1 -1
  114. package/dist/modes/interactive/components/settings-selector-items.js +7 -0
  115. package/dist/modes/interactive/components/settings-selector-items.js.map +1 -1
  116. package/dist/modes/interactive/components/settings-selector-types.d.ts +2 -0
  117. package/dist/modes/interactive/components/settings-selector-types.d.ts.map +1 -1
  118. package/dist/modes/interactive/components/settings-selector-types.js.map +1 -1
  119. package/dist/modes/interactive/interactive-deferred-startup.d.ts.map +1 -1
  120. package/dist/modes/interactive/interactive-deferred-startup.js +1 -0
  121. package/dist/modes/interactive/interactive-deferred-startup.js.map +1 -1
  122. package/dist/modes/interactive/interactive-input-handling.js +3 -0
  123. package/dist/modes/interactive/interactive-input-handling.js.map +1 -1
  124. package/dist/modes/interactive/interactive-mode-base.d.ts.map +1 -1
  125. package/dist/modes/interactive/interactive-mode-base.js +15 -1
  126. package/dist/modes/interactive/interactive-mode-base.js.map +1 -1
  127. package/dist/modes/interactive/interactive-mode-surface.d.ts +6 -1
  128. package/dist/modes/interactive/interactive-mode-surface.d.ts.map +1 -1
  129. package/dist/modes/interactive/interactive-mode-surface.js.map +1 -1
  130. package/dist/modes/interactive/interactive-selectors.js +6 -1
  131. package/dist/modes/interactive/interactive-selectors.js.map +1 -1
  132. package/dist/modes/interactive/interactive-session-runtime.js +3 -0
  133. package/dist/modes/interactive/interactive-session-runtime.js.map +1 -1
  134. package/dist/modes/interactive/interactive-slash-commands.js +7 -12
  135. package/dist/modes/interactive/interactive-slash-commands.js.map +1 -1
  136. package/dist/modes/interactive/interactive-tui.d.ts +1 -0
  137. package/dist/modes/interactive/interactive-tui.d.ts.map +1 -1
  138. package/dist/modes/interactive/interactive-tui.js +16 -0
  139. package/dist/modes/interactive/interactive-tui.js.map +1 -1
  140. package/dist/modes/rpc/rpc-session-binding.d.ts.map +1 -1
  141. package/dist/modes/rpc/rpc-session-binding.js +2 -0
  142. package/dist/modes/rpc/rpc-session-binding.js.map +1 -1
  143. package/docs/environment-variables.md +2 -0
  144. package/docs/extensions.md +1 -1
  145. package/docs/intercom.md +6 -7
  146. package/docs/keybindings.md +5 -2
  147. package/docs/packages.md +1 -1
  148. package/docs/providers.md +1 -1
  149. package/docs/sdk.md +9 -7
  150. package/docs/settings.md +9 -3
  151. package/docs/subagents.md +2 -2
  152. package/docs/usage.md +7 -6
  153. package/docs/workflows.md +9 -7
  154. package/npm-shrinkwrap.json +59 -77
  155. package/package.json +7 -7
@@ -1126,15 +1126,15 @@ ${chalk.bold("Options:")}
1126
1126
  --name, -n <name> Set session display name
1127
1127
  --models <patterns> Comma-separated model patterns for ctrl+p cycling
1128
1128
  Supports globs (anthropic/*, *sonnet*) and fuzzy matching
1129
- --no-tools, -nt Disable all tools by default (built-in and extension)
1129
+ --no-tools, -nt Disable every tool except mandatory ordinary intercom
1130
1130
  --no-builtin-tools, -nbt Disable built-in tools by default but keep extension/custom tools enabled
1131
- --tools, -t <tools> Comma-separated allowlist of tool names to enable
1132
- Applies to built-in, extension, and custom tools
1133
- --exclude-tools, -xt <tools> Comma-separated denylist of tool names to disable
1134
- Applies to built-in, extension, and custom tools
1131
+ --tools, -t <tools> Comma-separated allowlist of non-mandatory tool names
1132
+ Mandatory ordinary intercom remains available
1133
+ --exclude-tools, -xt <tools> Comma-separated denylist of non-mandatory tool names
1134
+ Mandatory ordinary intercom cannot be excluded
1135
1135
  --thinking <level> Set thinking level: off, minimal, low, medium, high, xhigh, max
1136
1136
  --extension, -e <path> Load an extension file (can be used multiple times)
1137
- --no-extensions, -ne Disable extension discovery (explicit -e paths still work)
1137
+ --no-extensions, -ne Disable optional extension discovery; mandatory bundled Intercom remains loaded
1138
1138
  --skill <path> Load a skill file or directory (can be used multiple times)
1139
1139
  --no-skills, -ns Disable skills discovery and loading
1140
1140
  --prompt-template <path> Load a prompt template file or directory (can be used multiple times)
@@ -10019,11 +10019,13 @@ function runSynchronousCallback(descriptor, callback) {
10019
10019
  }
10020
10020
  }
10021
10021
  async function runCallback(descriptor, callback) {
10022
+ if (!reporter)
10023
+ return callback();
10024
+ await yieldToEventLoop();
10022
10025
  const active = beginActivity(descriptor);
10023
10026
  if (!active)
10024
10027
  return callback();
10025
10028
  try {
10026
- await yieldToEventLoop();
10027
10029
  return await callback();
10028
10030
  } finally {
10029
10031
  active.reporter.finished(active.activity.id);
@@ -13013,12 +13015,45 @@ var init_runner_events = __esm(() => {
13013
13015
  init_callback_activity();
13014
13016
  });
13015
13017
 
13018
+ // src/core/mandatory-runtime-tools.ts
13019
+ function markTrustedMandatoryRuntimeExtension(extension) {
13020
+ extension.sourceInfo = { ...extension.sourceInfo, configurationOrigin: "bundled" };
13021
+ for (const registration of extension.tools.values()) {
13022
+ registration.sourceInfo = extension.sourceInfo;
13023
+ if (MANDATORY_TOOL_NAMES.has(registration.definition.name)) {
13024
+ TRUSTED_MANDATORY_DEFINITIONS.add(registration.definition);
13025
+ }
13026
+ }
13027
+ for (const command of extension.commands.values())
13028
+ command.sourceInfo = extension.sourceInfo;
13029
+ }
13030
+ function isTrustedMandatoryRuntimeTool(registration) {
13031
+ return MANDATORY_TOOL_NAMES.has(registration.definition.name) && TRUSTED_MANDATORY_DEFINITIONS.has(registration.definition);
13032
+ }
13033
+ function isMandatoryRuntimeTool(name) {
13034
+ return MANDATORY_TOOL_NAMES.has(name);
13035
+ }
13036
+ function appendRegisteredMandatoryTools(tools, registry) {
13037
+ for (const name of MANDATORY_TOOL_NAMES) {
13038
+ const tool = registry.get(name);
13039
+ if (tool && !tools.some((candidate) => candidate.name === name))
13040
+ tools.push(tool);
13041
+ }
13042
+ return tools;
13043
+ }
13044
+ var MANDATORY_TOOL_NAMES, TRUSTED_MANDATORY_DEFINITIONS;
13045
+ var init_mandatory_runtime_tools = __esm(() => {
13046
+ MANDATORY_TOOL_NAMES = new Set(["intercom"]);
13047
+ TRUSTED_MANDATORY_DEFINITIONS = new WeakSet;
13048
+ });
13049
+
13016
13050
  // src/core/extensions/runner-registries.ts
13017
13051
  function collectRegisteredTools(extensions) {
13018
13052
  const toolsByName = new Map;
13019
13053
  for (const ext of extensions) {
13020
13054
  for (const tool of ext.tools.values()) {
13021
- if (!toolsByName.has(tool.definition.name)) {
13055
+ const existing = toolsByName.get(tool.definition.name);
13056
+ if (!existing || isMandatoryRuntimeTool(tool.definition.name) && isTrustedMandatoryRuntimeTool(tool)) {
13022
13057
  toolsByName.set(tool.definition.name, tool);
13023
13058
  }
13024
13059
  }
@@ -13026,13 +13061,16 @@ function collectRegisteredTools(extensions) {
13026
13061
  return Array.from(toolsByName.values());
13027
13062
  }
13028
13063
  function findToolDefinition(extensions, toolName) {
13064
+ let first;
13029
13065
  for (const ext of extensions) {
13030
13066
  const tool = ext.tools.get(toolName);
13031
- if (tool) {
13067
+ if (!tool)
13068
+ continue;
13069
+ first ??= tool;
13070
+ if (isMandatoryRuntimeTool(toolName) && isTrustedMandatoryRuntimeTool(tool))
13032
13071
  return tool.definition;
13033
- }
13034
13072
  }
13035
- return;
13073
+ return first?.definition;
13036
13074
  }
13037
13075
  function collectFlags(extensions) {
13038
13076
  const allFlags = new Map;
@@ -13100,6 +13138,9 @@ function resolveRegisteredCommands(extensions) {
13100
13138
  return { ...command, invocationName };
13101
13139
  });
13102
13140
  }
13141
+ var init_runner_registries = __esm(() => {
13142
+ init_mandatory_runtime_tools();
13143
+ });
13103
13144
 
13104
13145
  // src/core/extensions/runner-shortcuts.ts
13105
13146
  function resolveExtensionShortcuts(extensions, resolvedKeybindings, hasUI) {
@@ -13163,6 +13204,7 @@ var init_runner_shortcuts = __esm(() => {
13163
13204
  "app.thinking.toggle",
13164
13205
  "app.editor.external",
13165
13206
  "app.message.followUp",
13207
+ "app.message.copy",
13166
13208
  "tui.input.submit",
13167
13209
  "tui.select.confirm",
13168
13210
  "tui.select.cancel",
@@ -13654,6 +13696,7 @@ var init_runner = __esm(() => {
13654
13696
  init_loader_runtime();
13655
13697
  init_runner_context();
13656
13698
  init_runner_events();
13699
+ init_runner_registries();
13657
13700
  init_runner_shortcuts();
13658
13701
  init_runner_ui();
13659
13702
  init_stale_context();
@@ -17600,14 +17643,13 @@ function getToolDefinition(name) {
17600
17643
  }
17601
17644
  function setActiveToolsByName(toolNames) {
17602
17645
  const tools = [];
17603
- const validToolNames = [];
17604
17646
  for (const name of toolNames) {
17605
17647
  const tool = this._toolRegistry.get(name);
17606
- if (tool) {
17648
+ if (tool)
17607
17649
  tools.push(tool);
17608
- validToolNames.push(name);
17609
- }
17610
17650
  }
17651
+ appendRegisteredMandatoryTools(tools, this._toolRegistry);
17652
+ const validToolNames = tools.map((tool) => tool.name);
17611
17653
  this.agent.state.tools = tools;
17612
17654
  this._baseSystemPrompt = this._rebuildSystemPrompt(validToolNames);
17613
17655
  this.agent.state.systemPrompt = this._systemPromptOverride ?? this._baseSystemPrompt;
@@ -17664,7 +17706,7 @@ function _rebuildSystemPrompt(toolNames) {
17664
17706
  customPrompt: loaderSystemPrompt,
17665
17707
  appendSystemPrompt,
17666
17708
  selectedTools: validToolNames,
17667
- excludedTools: this._excludedToolNames ? Array.from(this._excludedToolNames) : undefined,
17709
+ excludedTools: this._excludedToolNames ? Array.from(this._excludedToolNames).filter((name) => !isMandatoryRuntimeTool(name)) : undefined,
17668
17710
  toolSnippets,
17669
17711
  promptGuidelines
17670
17712
  };
@@ -17677,6 +17719,7 @@ function _refreshBaseSystemPromptFromActiveTools() {
17677
17719
  }
17678
17720
  var agentSessionStateMethods;
17679
17721
  var init_agent_session_state = __esm(() => {
17722
+ init_mandatory_runtime_tools();
17680
17723
  init_skill_catalog();
17681
17724
  init_system_prompt();
17682
17725
  agentSessionStateMethods = {
@@ -18705,31 +18748,14 @@ function _installAgentToolHooks() {
18705
18748
  function _installAgentNextTurnRefresh() {
18706
18749
  const previousPrepareNextTurnWithContext = this.agent.prepareNextTurnWithContext ?? (this.agent.prepareNextTurn ? async (_turn, signal) => await this.agent.prepareNextTurn?.(signal) : undefined);
18707
18750
  const previousShouldStopAfterTurn = this.agent.shouldStopAfterTurn;
18708
- let pendingStopResult;
18709
- const pendingStopMatches = (turn) => {
18710
- const pending = pendingStopResult;
18711
- return pending?.message === turn.message && pending.toolResults === turn.toolResults && pending.newMessages === turn.newMessages;
18712
- };
18713
- const clearPendingStopResult = (turn) => {
18714
- if (pendingStopMatches(turn))
18715
- pendingStopResult = undefined;
18716
- };
18717
18751
  this.agent.shouldStopAfterTurn = async (turn, signal) => {
18718
- const pending = pendingStopResult;
18719
- if (pending && pendingStopMatches(turn)) {
18720
- pendingStopResult = undefined;
18721
- return pending.shouldStop;
18722
- }
18723
- return await previousShouldStopAfterTurn?.(turn, signal) ?? false;
18724
- };
18725
- const cacheStopResult = async (turn, signal) => {
18752
+ const toolCallIds = turn.message.content.filter((part) => part.type === "toolCall").map((part) => part.id);
18753
+ const terminatingBatch = toolCallIds.length > 0 && toolCallIds.every((id) => this._terminatingToolCallIds.has(id));
18754
+ for (const id of toolCallIds)
18755
+ this._terminatingToolCallIds.delete(id);
18726
18756
  const shouldStop = await previousShouldStopAfterTurn?.(turn, signal) ?? false;
18727
- pendingStopResult = {
18728
- message: turn.message,
18729
- toolResults: turn.toolResults,
18730
- newMessages: turn.newMessages,
18731
- shouldStop
18732
- };
18757
+ this._stopAfterTurnBlockedContinuation = shouldStop;
18758
+ await settleFallbackAfterTurn(this, turn, terminatingBatch);
18733
18759
  return shouldStop;
18734
18760
  };
18735
18761
  const previousTransformContext = this.agent.transformContext;
@@ -18757,68 +18783,7 @@ function _installAgentNextTurnRefresh() {
18757
18783
  thinkingLevel: this.agent.state.thinkingLevel
18758
18784
  };
18759
18785
  };
18760
- let deferredPreparation;
18761
- const prepareDeferredTurn = async (loopConfig) => {
18762
- const deferred = deferredPreparation;
18763
- if (!deferred)
18764
- return;
18765
- deferredPreparation = undefined;
18766
- const snapshot = await prepareTurn(deferred.turn, deferred.signal);
18767
- const nextContext = snapshot.context ?? deferred.turn.context;
18768
- deferred.loopContext.systemPrompt = nextContext.systemPrompt;
18769
- deferred.loopContext.messages = nextContext.messages;
18770
- deferred.loopContext.tools = nextContext.tools;
18771
- loopConfig.model = snapshot.model ?? loopConfig.model;
18772
- loopConfig.reasoning = snapshot.thinkingLevel === undefined ? loopConfig.reasoning : snapshot.thinkingLevel === "off" ? undefined : snapshot.thinkingLevel;
18773
- };
18774
- const agentLoopDoor = this.agent;
18775
- const previousCreateLoopConfig = agentLoopDoor.createLoopConfig.bind(this.agent);
18776
- agentLoopDoor.createLoopConfig = (options) => {
18777
- deferredPreparation = undefined;
18778
- this._stopAfterTurnBlockedContinuation = false;
18779
- const loopConfig = previousCreateLoopConfig(options);
18780
- const wrapQueuePoll = (poll) => async function() {
18781
- const messages = await poll?.() ?? [];
18782
- if (messages.length > 0)
18783
- await prepareDeferredTurn(this);
18784
- return messages;
18785
- };
18786
- loopConfig.getSteeringMessages = wrapQueuePoll(loopConfig.getSteeringMessages);
18787
- loopConfig.getFollowUpMessages = wrapQueuePoll(loopConfig.getFollowUpMessages);
18788
- return loopConfig;
18789
- };
18790
- this.agent.prepareNextTurnWithContext = async (turn, signal) => {
18791
- const toolCallIds = turn.message.content.filter((part) => part.type === "toolCall").map((part) => part.id);
18792
- const terminatingBatch = toolCallIds.length > 0 && toolCallIds.every((id) => this._terminatingToolCallIds.has(id));
18793
- for (const id of toolCallIds)
18794
- this._terminatingToolCallIds.delete(id);
18795
- const shouldStop = await cacheStopResult(turn, signal);
18796
- try {
18797
- if (shouldStop) {
18798
- deferredPreparation = undefined;
18799
- this._stopAfterTurnBlockedContinuation = true;
18800
- await settleFallbackAfterTurn(this, turn, terminatingBatch);
18801
- return;
18802
- }
18803
- if (turn.toolResults.length > 0 && !terminatingBatch) {
18804
- deferredPreparation = undefined;
18805
- const snapshot = await prepareTurn(turn, signal);
18806
- await settleFallbackAfterTurn(this, turn, terminatingBatch);
18807
- return snapshot;
18808
- }
18809
- await settleFallbackAfterTurn(this, turn, terminatingBatch);
18810
- const loopContext = {
18811
- ...turn.context,
18812
- messages: turn.context.messages.slice(),
18813
- tools: turn.context.tools?.slice()
18814
- };
18815
- deferredPreparation = { turn, signal, loopContext };
18816
- return { context: loopContext };
18817
- } catch (error) {
18818
- clearPendingStopResult(turn);
18819
- throw error;
18820
- }
18821
- };
18786
+ this.agent.prepareNextTurnWithContext = prepareTurn;
18822
18787
  }
18823
18788
  async function settleFallbackAfterTurn(session, turn, terminatingBatch) {
18824
18789
  const preserveFallbackForFailure = turn.message.role === "assistant" && !session.agent.hasQueuedMessages() && (turn.message.stopReason === "length" || session._isEmptyCompletion?.(turn.message) === true || session._isSafetyRefusal?.(turn.message) === true);
@@ -19723,6 +19688,14 @@ var init_loader_virtual_modules = __esm(() => {
19723
19688
 
19724
19689
  // src/core/extensions/loader-core.ts
19725
19690
  import * as path7 from "node:path";
19691
+ function getExtensionRuntimeEventBus(runtime) {
19692
+ let eventBus = runtimeEventBuses.get(runtime);
19693
+ if (!eventBus) {
19694
+ eventBus = createEventBus();
19695
+ runtimeEventBuses.set(runtime, eventBus);
19696
+ }
19697
+ return eventBus;
19698
+ }
19726
19699
  function createExtension(extensionPath, resolvedPath) {
19727
19700
  const source = extensionPath.startsWith("<") && extensionPath.endsWith(">") ? extensionPath.slice(1, -1).split(":")[0] || "temporary" : "local";
19728
19701
  const baseDir = extensionPath.startsWith("<") ? undefined : path7.dirname(resolvedPath);
@@ -19788,6 +19761,7 @@ async function loadExtensionsInternal(paths, cwd, eventBus, workflowResourceProv
19788
19761
  const resolvedCwd = cacheToken?.cwd ?? resolvePath(cwd);
19789
19762
  const resolvedEventBus = eventBus ?? createEventBus();
19790
19763
  const resolvedRuntime = runtime ?? createExtensionRuntime();
19764
+ runtimeEventBuses.set(resolvedRuntime, resolvedEventBus);
19791
19765
  let processedExtensionCount = 0;
19792
19766
  let lastYieldAt = Date.now();
19793
19767
  for (const extPath of paths) {
@@ -19819,7 +19793,7 @@ async function loadExtensions(paths, cwd, eventBus, workflowResourceProvider = e
19819
19793
  async function loadExtensionsCached(paths, cwd, eventBus, workflowResourceProvider = emptyWorkflowResourceProvider, runtime, resourceLoaderInheritanceSnapshotProvider) {
19820
19794
  return loadExtensionsInternal(paths, cwd, eventBus, workflowResourceProvider, runtime, resourceLoaderInheritanceSnapshotProvider, true);
19821
19795
  }
19822
- var INTER_EXTENSION_YIELD_THRESHOLD_MS = 16;
19796
+ var runtimeEventBuses, INTER_EXTENSION_YIELD_THRESHOLD_MS = 16;
19823
19797
  var init_loader_core = __esm(() => {
19824
19798
  init_event_loop();
19825
19799
  init_paths();
@@ -19829,6 +19803,7 @@ var init_loader_core = __esm(() => {
19829
19803
  init_loader_resources();
19830
19804
  init_loader_runtime();
19831
19805
  init_loader_virtual_modules();
19806
+ runtimeEventBuses = new WeakMap;
19832
19807
  });
19833
19808
 
19834
19809
  // src/core/package-manager-manifest.ts
@@ -28367,7 +28342,7 @@ class FastModeSelectorComponent {
28367
28342
  }
28368
28343
  invalidate() {}
28369
28344
  render(width) {
28370
- const lines = [truncateToWidth10(theme.bold(theme.fg("accent", "Codex fast mode")), width)];
28345
+ const lines = [truncateToWidth10(theme.bold(theme.fg("accent", "Fast mode")), width)];
28371
28346
  for (const line of wrapTextWithAnsi3(DESCRIPTION, Math.max(20, width))) {
28372
28347
  lines.push(theme.fg("muted", line));
28373
28348
  }
@@ -28450,7 +28425,7 @@ class FastModeSelectorComponent {
28450
28425
  return this.getFocusedRow() === row ? theme.fg("muted", text) : theme.fg("dim", text);
28451
28426
  }
28452
28427
  }
28453
- var ROWS, LABEL_WIDTH = 16, DESCRIPTION = "Priority tier for supported OpenAI and shared ChatGPT Codex transports.", ROW_DETAILS;
28428
+ var ROWS, LABEL_WIDTH = 16, DESCRIPTION = "Use faster routing for the selected model when supported by its provider.", ROW_DETAILS;
28454
28429
  var init_fast_mode_selector = __esm(() => {
28455
28430
  init_theme();
28456
28431
  ROWS = ["chat", "workflow"];
@@ -29756,6 +29731,10 @@ var init_keybindings = __esm(() => {
29756
29731
  defaultKeys: windowsKeybindings ? "alt+q" : "alt+up",
29757
29732
  description: "Restore queued messages"
29758
29733
  },
29734
+ "app.message.copy": {
29735
+ defaultKeys: "ctrl+x",
29736
+ description: "Copy fullscreen selection or last agent message"
29737
+ },
29759
29738
  "app.clipboard.pasteImage": {
29760
29739
  defaultKeys: windowsKeybindings ? "alt+v" : "ctrl+v",
29761
29740
  description: "Paste image from clipboard (text fallback)"
@@ -31148,6 +31127,9 @@ function createSettingsChangeHandler(callbacks) {
31148
31127
  case "fullscreen-exit-output":
31149
31128
  callbacks.onFullscreenExitOutputChange(newValue);
31150
31129
  break;
31130
+ case "fullscreen-copy-on-select":
31131
+ callbacks.onFullscreenCopyOnSelectChange(newValue === "true");
31132
+ break;
31151
31133
  case "editor-padding":
31152
31134
  callbacks.onEditorPaddingXChange(parseInt(newValue, 10));
31153
31135
  break;
@@ -31535,6 +31517,13 @@ function insertUiToggles(items, config) {
31535
31517
  values: ["transcript", "resume-hint"]
31536
31518
  });
31537
31519
  insertAfter(items, "fullscreen-exit-output", {
31520
+ id: "fullscreen-copy-on-select",
31521
+ label: "Fullscreen copy on select",
31522
+ description: "Copy selected transcript text automatically on mouse release",
31523
+ currentValue: config.fullscreenCopyOnSelect ? "true" : "false",
31524
+ values: ["true", "false"]
31525
+ });
31526
+ insertAfter(items, "fullscreen-copy-on-select", {
31538
31527
  id: "editor-padding",
31539
31528
  label: "Editor padding",
31540
31529
  description: "Horizontal padding for input editor (0-3)",
@@ -44812,6 +44801,8 @@ function _refreshToolRegistry(options) {
44812
44801
  const allowedToolNames = this._allowedToolNames;
44813
44802
  const excludedToolNames = this._excludedToolNames;
44814
44803
  const isExposedTool = (name) => {
44804
+ if (isMandatoryRuntimeTool(name))
44805
+ return true;
44815
44806
  if (allowedToolNames && !allowedToolNames.has(name)) {
44816
44807
  return false;
44817
44808
  }
@@ -44820,10 +44811,10 @@ function _refreshToolRegistry(options) {
44820
44811
  }
44821
44812
  return true;
44822
44813
  };
44823
- const registeredTools = this._extensionRunner.getAllRegisteredTools();
44814
+ const registeredTools = this._extensionRunner.getAllRegisteredTools().filter((tool) => !isMandatoryRuntimeTool(tool.definition.name) || isTrustedMandatoryRuntimeTool(tool));
44824
44815
  const allCustomTools = [
44825
44816
  ...registeredTools,
44826
- ...this._customTools.map((definition) => ({
44817
+ ...this._customTools.filter((definition) => !isMandatoryRuntimeTool(definition.name)).map((definition) => ({
44827
44818
  definition,
44828
44819
  sourceInfo: createSyntheticSourceInfo(`<sdk:${definition.name}>`, { source: "sdk" })
44829
44820
  }))
@@ -44944,6 +44935,7 @@ function _buildRuntime(options) {
44944
44935
  var agentSessionToolRegistryMethods;
44945
44936
  var init_agent_session_tool_registry = __esm(() => {
44946
44937
  init_extensions();
44938
+ init_mandatory_runtime_tools();
44947
44939
  init_model_registry();
44948
44940
  init_tools();
44949
44941
  init_session_temp_dir();
@@ -46374,6 +46366,23 @@ function getBuiltinPackagePaths() {
46374
46366
  return packageDir ? [packageDir] : [];
46375
46367
  });
46376
46368
  }
46369
+ function getMandatoryBuiltinPackagePaths() {
46370
+ const context = getBuiltinPackageCandidateContext();
46371
+ return BUILTIN_PACKAGES.filter((descriptor) => descriptor.mandatory).flatMap((descriptor) => {
46372
+ const packageDir = firstExistingPackageDir([...descriptor.sourceCandidates(context), ...distCandidates(context, descriptor)], descriptor);
46373
+ return packageDir ? [packageDir] : [];
46374
+ });
46375
+ }
46376
+ function getMandatoryBuiltinExtensionPaths() {
46377
+ return getMandatoryBuiltinPackagePaths().flatMap((packageDir) => {
46378
+ try {
46379
+ const manifest = JSON.parse(stripBom(readFileSync21(join43(packageDir, "package.json"), "utf-8")));
46380
+ return (manifest.atomic?.extensions ?? manifest.pi?.extensions ?? []).map((entry) => resolve12(packageDir, entry));
46381
+ } catch {
46382
+ return [];
46383
+ }
46384
+ });
46385
+ }
46377
46386
  var WORKSPACE_BUILTINS, BUILTIN_PACKAGES;
46378
46387
  var init_builtin_packages = __esm(() => {
46379
46388
  init_config();
@@ -46384,11 +46393,12 @@ var init_builtin_packages = __esm(() => {
46384
46393
  { packageName: "@bastani/subagents", workspaceDirName: "subagents", distDirName: "subagents" },
46385
46394
  { packageName: "@bastani/mcp", workspaceDirName: "mcp", distDirName: "mcp" },
46386
46395
  { packageName: "@bastani/web-access", workspaceDirName: "web-access", distDirName: "web-access" },
46387
- { packageName: "@bastani/intercom", workspaceDirName: "intercom", distDirName: "intercom" }
46396
+ { packageName: "@bastani/intercom", workspaceDirName: "intercom", distDirName: "intercom", mandatory: true }
46388
46397
  ];
46389
46398
  BUILTIN_PACKAGES = WORKSPACE_BUILTINS.map((spec) => ({
46390
46399
  packageName: spec.packageName,
46391
46400
  distDirName: spec.distDirName,
46401
+ mandatory: spec.mandatory === true,
46392
46402
  requiredEntries: requiredEntriesForBuiltin(spec.distDirName),
46393
46403
  sourceCandidates: ({ here, packageDir, isSourceCheckout }) => isSourceCheckout ? [join43(packageDir, "..", spec.workspaceDirName), join43(here, "..", "..", "..", spec.workspaceDirName)] : []
46394
46404
  }));
@@ -52363,6 +52373,13 @@ function getEnabledResources(resources, metadataByPath) {
52363
52373
  function getEnabledPaths(resources, metadataByPath) {
52364
52374
  return getEnabledResources(resources, metadataByPath).map((r) => r.path);
52365
52375
  }
52376
+ function getBuiltinExtensionPaths(resources, metadataByPath, noExtensions) {
52377
+ for (const resource of resources) {
52378
+ if (!metadataByPath.has(resource.path))
52379
+ metadataByPath.set(resource.path, resource.metadata);
52380
+ }
52381
+ return noExtensions ? [] : resources.filter((resource) => resource.enabled).map((resource) => resource.path);
52382
+ }
52366
52383
  function mapSkillPath(resource, metadataByPath) {
52367
52384
  if (resource.metadata.source !== "auto" && resource.metadata.origin !== "package") {
52368
52385
  return resource.path;
@@ -52406,12 +52423,12 @@ async function loadProjectTrustExtensions(loader) {
52406
52423
  const metadataByPath = new Map;
52407
52424
  const cliEnabledExtensions = getEnabledPaths(cliExtensionPaths.extensions, metadataByPath);
52408
52425
  const enabledExtensions = getEnabledPaths(resolvedPaths.extensions, metadataByPath);
52409
- const builtinEnabledExtensions = state.noExtensions ? [] : getEnabledPaths(builtinPackagePaths.extensions, metadataByPath);
52426
+ const builtinEnabledExtensions = getBuiltinExtensionPaths(builtinPackagePaths.extensions, metadataByPath, state.noExtensions);
52410
52427
  const workflowResources = collectWorkflowResources(resolvedPaths, cliExtensionPaths, builtinPackagePaths);
52411
52428
  state.workflowResources = workflowResources;
52412
52429
  const workflowResourceProvider = createWorkflowResourceProvider(loader);
52413
52430
  const inheritanceSnapshotProvider = createInheritanceSnapshotProvider(loader);
52414
- const extensionPaths = state.noExtensions ? cliEnabledExtensions : mergeResourcePaths(state.cwd, cliEnabledExtensions, [...enabledExtensions, ...builtinEnabledExtensions]);
52431
+ const extensionPaths = mergeResourcePaths(state.cwd, cliEnabledExtensions, state.noExtensions ? builtinEnabledExtensions : [...enabledExtensions, ...builtinEnabledExtensions]);
52415
52432
  const extensionsResult = await loadExtensionsCached(extensionPaths, state.cwd, state.eventBus, workflowResourceProvider, undefined, inheritanceSnapshotProvider);
52416
52433
  const inlineExtensions = await loadExtensionFactories(loader, extensionsResult.runtime, workflowResourceProvider, inheritanceSnapshotProvider);
52417
52434
  extensionsResult.extensions.push(...inlineExtensions.extensions);
@@ -52491,7 +52508,7 @@ async function reloadDefaultResourceLoader(loader, options) {
52491
52508
  const enabledSkillResources = getEnabledResources(resolvedPaths.skills, metadataByPath);
52492
52509
  const enabledPrompts = getEnabledPaths(resolvedPaths.prompts, metadataByPath);
52493
52510
  const enabledThemes = getEnabledPaths(resolvedPaths.themes, metadataByPath);
52494
- const builtinEnabledExtensions = state.noExtensions ? [] : getEnabledPaths(builtinPackagePaths.extensions, metadataByPath);
52511
+ const builtinEnabledExtensions = getBuiltinExtensionPaths(builtinPackagePaths.extensions, metadataByPath, state.noExtensions);
52495
52512
  const builtinEnabledSkillResources = state.noSkills ? [] : getEnabledResources(builtinPackagePaths.skills, metadataByPath);
52496
52513
  const builtinEnabledPrompts = state.noPromptTemplates ? [] : getEnabledPaths(builtinPackagePaths.prompts, metadataByPath);
52497
52514
  const builtinEnabledThemes = state.noThemes ? [] : getEnabledPaths(builtinPackagePaths.themes, metadataByPath);
@@ -52505,9 +52522,13 @@ async function reloadDefaultResourceLoader(loader, options) {
52505
52522
  const workflowResources = collectWorkflowResources(resolvedPaths, cliExtensionPaths, builtinPackagePaths);
52506
52523
  state.workflowResources = workflowResources;
52507
52524
  const workflowResourceProvider = createWorkflowResourceProvider(loader);
52508
- const extensionPaths = state.noExtensions ? cliEnabledExtensions : mergeResourcePaths(state.cwd, cliEnabledExtensions, [...enabledExtensions, ...builtinEnabledExtensions]);
52525
+ const extensionPaths = mergeResourcePaths(state.cwd, cliEnabledExtensions, state.noExtensions ? builtinEnabledExtensions : [...enabledExtensions, ...builtinEnabledExtensions]);
52509
52526
  const inheritanceSnapshotProvider = createInheritanceSnapshotProvider(loader);
52510
52527
  const extensionsResult = options?.deferExtensions ? { extensions: [], errors: [], runtime: createExtensionRuntime() } : await loadFinalExtensionSet(loader, extensionPaths, preTrustExtensions, workflowResourceProvider, inheritanceSnapshotProvider);
52528
+ const mandatoryExtensionPaths = new Set(getMandatoryBuiltinExtensionPaths().map((path16) => resolvePath(path16, state.cwd, { normalizeUnicodeSpaces: true })));
52529
+ const loadedMandatoryExtensions = new Set(extensionsResult.extensions.filter((extension) => mandatoryExtensionPaths.has(resolvePath(extension.resolvedPath, state.cwd, { normalizeUnicodeSpaces: true }))));
52530
+ for (const extension of loadedMandatoryExtensions)
52531
+ markTrustedMandatoryRuntimeExtension(extension);
52511
52532
  for (const p of state.additionalExtensionPaths) {
52512
52533
  if (isLocalPath(p)) {
52513
52534
  const resolved = resolveResourcePath(state.cwd, p);
@@ -52518,6 +52539,12 @@ async function reloadDefaultResourceLoader(loader, options) {
52518
52539
  }
52519
52540
  state.extensionsResult = state.extensionsOverride ? state.extensionsOverride(extensionsResult) : extensionsResult;
52520
52541
  applyExtensionSourceInfo(loader, state.extensionsResult.extensions, metadataByPath);
52542
+ for (const extension of state.extensionsResult.extensions) {
52543
+ const registration = extension.tools.get("intercom");
52544
+ if (loadedMandatoryExtensions.has(extension) && registration && isTrustedMandatoryRuntimeTool(registration)) {
52545
+ markTrustedMandatoryRuntimeExtension(extension);
52546
+ }
52547
+ }
52521
52548
  resolveInheritedExtensionOverlaps(state.extensionsResult);
52522
52549
  const skillPaths = state.noSkills ? mergeResourcePaths(state.cwd, cliEnabledSkills, state.additionalSkillPaths) : mergeResourcePaths(state.cwd, [...cliEnabledSkills, ...enabledSkills, ...builtinEnabledSkills], state.additionalSkillPaths);
52523
52550
  state.lastSkillPaths = skillPaths;
@@ -52597,7 +52624,9 @@ async function reloadDefaultResourceLoader(loader, options) {
52597
52624
  var init_resource_loader_reload = __esm(() => {
52598
52625
  init_event_loop();
52599
52626
  init_paths();
52627
+ init_builtin_packages();
52600
52628
  init_loader();
52629
+ init_mandatory_runtime_tools();
52601
52630
  init_resource_loader_assets();
52602
52631
  init_resource_loader_context_files();
52603
52632
  init_resource_loader_discovery();
@@ -53754,6 +53783,28 @@ var init_settings_manager_ui_accessors = __esm(() => {
53754
53783
  state.markModified("fullscreenExitOutput");
53755
53784
  state.save();
53756
53785
  },
53786
+ getFullscreenCopyOnSelect() {
53787
+ return settingsInternals(this).settings.fullscreenCopyOnSelect !== false;
53788
+ },
53789
+ setFullscreenCopyOnSelect(enabled) {
53790
+ const state = settingsInternals(this);
53791
+ state.globalSettings.fullscreenCopyOnSelect = enabled;
53792
+ state.markModified("fullscreenCopyOnSelect");
53793
+ state.save();
53794
+ },
53795
+ getTerminalCapabilityOverrides() {
53796
+ const terminal = settingsInternals(this).settings.terminal;
53797
+ const overrides = {};
53798
+ if (typeof terminal?.hyperlinks === "boolean")
53799
+ overrides.hyperlinks = terminal.hyperlinks;
53800
+ if (terminal?.images === "kitty" || terminal?.images === "iterm2")
53801
+ overrides.images = terminal.images;
53802
+ else if (terminal?.images === false)
53803
+ overrides.images = null;
53804
+ if (typeof terminal?.trueColor === "boolean")
53805
+ overrides.trueColor = terminal.trueColor;
53806
+ return overrides;
53807
+ },
53757
53808
  getEditorPaddingX() {
53758
53809
  return settingsInternals(this).settings.editorPaddingX ?? 0;
53759
53810
  },
@@ -54304,6 +54355,105 @@ function restoreAnthropicReplayThinkingBlocks(payload, sourceMessages, model) {
54304
54355
  return { ...payload, messages: nextPayloadMessages };
54305
54356
  }
54306
54357
 
54358
+ // src/core/mandatory-resource-loader.ts
54359
+ function hasTrustedIntercom(extension) {
54360
+ const registration = extension.tools.get("intercom");
54361
+ return registration !== undefined && isTrustedMandatoryRuntimeTool(registration);
54362
+ }
54363
+ async function restoreMandatoryExtensions(target, cwd) {
54364
+ if (target.extensions.some(hasTrustedIntercom))
54365
+ return target;
54366
+ const loaded = await loadExtensions(getMandatoryBuiltinExtensionPaths(), cwd, getExtensionRuntimeEventBus(target.runtime), undefined, target.runtime);
54367
+ for (const extension of loaded.extensions)
54368
+ markTrustedMandatoryRuntimeExtension(extension);
54369
+ const restored = {
54370
+ ...target,
54371
+ extensions: [...target.extensions, ...loaded.extensions],
54372
+ errors: [...target.errors, ...loaded.errors]
54373
+ };
54374
+ if (!restored.extensions.some(hasTrustedIntercom)) {
54375
+ const detail = loaded.errors.map(({ error }) => error).join("; ") || "extension did not register intercom";
54376
+ throw new Error(`Mandatory bundled Intercom is unavailable: ${detail}`);
54377
+ }
54378
+ return restored;
54379
+ }
54380
+
54381
+ class MandatoryResourceLoader {
54382
+ delegate;
54383
+ cwd;
54384
+ extensionsResult;
54385
+ toolOnly = false;
54386
+ constructor(delegate, cwd, extensionsResult) {
54387
+ this.delegate = delegate;
54388
+ this.cwd = cwd;
54389
+ this.extensionsResult = extensionsResult;
54390
+ }
54391
+ limitToTool() {
54392
+ this.toolOnly = true;
54393
+ this.removeLocalInteractionSurfaces();
54394
+ }
54395
+ removeLocalInteractionSurfaces() {
54396
+ const extension = this.extensionsResult.extensions.find(hasTrustedIntercom);
54397
+ extension?.commands.delete("intercom");
54398
+ extension?.shortcuts.delete("alt+m");
54399
+ }
54400
+ getExtensions() {
54401
+ return this.extensionsResult;
54402
+ }
54403
+ getSkills() {
54404
+ return this.delegate.getSkills();
54405
+ }
54406
+ getSkillCatalog() {
54407
+ return this.delegate.getSkillCatalog?.() ?? buildSkillCatalog(this.delegate.getSkills().skills);
54408
+ }
54409
+ getPrompts() {
54410
+ return this.delegate.getPrompts();
54411
+ }
54412
+ getThemes() {
54413
+ return this.delegate.getThemes();
54414
+ }
54415
+ getAgentsFiles() {
54416
+ return this.delegate.getAgentsFiles();
54417
+ }
54418
+ getSystemPrompt() {
54419
+ return this.delegate.getSystemPrompt();
54420
+ }
54421
+ getSystemPromptSource() {
54422
+ return this.delegate.getSystemPromptSource();
54423
+ }
54424
+ getAppendSystemPrompt() {
54425
+ return this.delegate.getAppendSystemPrompt();
54426
+ }
54427
+ getAppendSystemPromptSources() {
54428
+ return this.delegate.getAppendSystemPromptSources();
54429
+ }
54430
+ extendResources(paths) {
54431
+ return this.delegate.extendResources(paths);
54432
+ }
54433
+ async reload(options) {
54434
+ await this.delegate.reload(options);
54435
+ this.extensionsResult = await restoreMandatoryExtensions(this.delegate.getExtensions(), this.cwd);
54436
+ if (this.toolOnly)
54437
+ this.removeLocalInteractionSurfaces();
54438
+ }
54439
+ }
54440
+ async function withMandatoryResourceLoader(loader, cwd) {
54441
+ if (loader instanceof MandatoryResourceLoader)
54442
+ return loader;
54443
+ const extensionsResult = await restoreMandatoryExtensions(loader.getExtensions(), cwd);
54444
+ return new MandatoryResourceLoader(loader, cwd, extensionsResult);
54445
+ }
54446
+ function limitMandatoryIntercomToTool(loader) {
54447
+ if (loader instanceof MandatoryResourceLoader)
54448
+ loader.limitToTool();
54449
+ }
54450
+ var init_mandatory_resource_loader = __esm(() => {
54451
+ init_builtin_packages();
54452
+ init_loader();
54453
+ init_mandatory_runtime_tools();
54454
+ init_skill_catalog();
54455
+ });
54456
+
54307
54457
  // src/core/model-resolver-defaults.ts
54308
54458
  function findPreferredAvailableModel(availableModels) {
54309
54459
  for (const [provider, defaultId] of Object.entries(defaultModelPerProvider)) {
@@ -55133,14 +55283,16 @@ async function createAgentSessionServices(options) {
55133
55283
  const settingsSpan = startTimingSpan("createAgentSessionServices.settingsManager");
55134
55284
  const settingsManager = options.settingsManager ?? SettingsManager.create(cwd, agentDir);
55135
55285
  endTimingSpan(settingsSpan);
55136
- const resourceLoader = new DefaultResourceLoader({
55137
- ...options.resourceLoaderOptions ?? {},
55286
+ const resourceLoaderOptions = options.resourceLoaderOptions ?? {};
55287
+ const defaultResourceLoader = new DefaultResourceLoader({
55288
+ ...resourceLoaderOptions,
55138
55289
  cwd,
55139
55290
  agentDir,
55140
55291
  settingsManager
55141
55292
  });
55142
55293
  const reloadSpan = startTimingSpan("createAgentSessionServices.resourceLoader.reload");
55143
- await resourceLoader.reload(options.resourceLoaderReloadOptions);
55294
+ await defaultResourceLoader.reload(options.resourceLoaderReloadOptions);
55295
+ const resourceLoader = await withMandatoryResourceLoader(defaultResourceLoader, cwd);
55144
55296
  endTimingSpan(reloadSpan);
55145
55297
  const diagnostics = [];
55146
55298
  const providerSpan = startTimingSpan("createAgentSessionServices.providerRegistrations");
@@ -55193,6 +55345,7 @@ async function createAgentSessionFromServices(options) {
55193
55345
  var init_agent_session_services = __esm(() => {
55194
55346
  init_config();
55195
55347
  init_paths();
55348
+ init_mandatory_resource_loader();
55196
55349
  init_model_runtime();
55197
55350
  init_resource_loader();
55198
55351
  init_sdk();
@@ -55575,6 +55728,7 @@ async function createAgentSession(options = {}) {
55575
55728
  await resourceLoader.reload();
55576
55729
  time("resourceLoader.reload");
55577
55730
  }
55731
+ resourceLoader = await withMandatoryResourceLoader(resourceLoader, cwd);
55578
55732
  const existingSession = sessionManager.buildSessionContext();
55579
55733
  const repairedMessages = repairOrphanToolResults(existingSession.messages, { repairTrailing: true });
55580
55734
  const existingMessages = options.initialContextTransform ? options.initialContextTransform(repairedMessages) : repairedMessages;
@@ -55800,6 +55954,7 @@ var init_sdk = __esm(() => {
55800
55954
  init_agent_session();
55801
55955
  init_auth_guidance();
55802
55956
  init_codex_fast_mode();
55957
+ init_mandatory_resource_loader();
55803
55958
  init_messages();
55804
55959
  init_model_resolver();
55805
55960
  init_model_runtime();
@@ -56376,8 +56531,14 @@ var init_list_models = __esm(() => {
56376
56531
 
56377
56532
  // src/cli/startup-ui.ts
56378
56533
  import { existsSync as existsSync45 } from "node:fs";
56379
- import { ProcessTerminal, setKeybindings, TuiMainScreen } from "@earendil-works/pi-tui";
56534
+ import {
56535
+ ProcessTerminal,
56536
+ setCapabilityOverrides,
56537
+ setKeybindings,
56538
+ TuiMainScreen
56539
+ } from "@earendil-works/pi-tui";
56380
56540
  function createStartupTui(settingsManager) {
56541
+ setCapabilityOverrides(settingsManager.getTerminalCapabilityOverrides());
56381
56542
  initTheme(settingsManager.getTheme());
56382
56543
  setKeybindings(KeybindingsManager.create());
56383
56544
  const ui = new TuiMainScreen(new ProcessTerminal, settingsManager.getShowHardwareCursor(), getAgentDir());
@@ -58207,8 +58368,9 @@ async function applyCliRuntimeApiKey(modelRuntime, providerId, apiKey, signal) {
58207
58368
  }
58208
58369
 
58209
58370
  // src/cli/session-picker.ts
58210
- import { ProcessTerminal as ProcessTerminal2, setKeybindings as setKeybindings2, TuiMainScreen as TuiMainScreen2 } from "@earendil-works/pi-tui";
58211
- async function selectSession(currentSessionsLoader, allSessionsLoader) {
58371
+ import { ProcessTerminal as ProcessTerminal2, setCapabilityOverrides as setCapabilityOverrides2, setKeybindings as setKeybindings2, TuiMainScreen as TuiMainScreen2 } from "@earendil-works/pi-tui";
58372
+ async function selectSession(currentSessionsLoader, allSessionsLoader, settingsManager) {
58373
+ setCapabilityOverrides2(settingsManager.getTerminalCapabilityOverrides());
58212
58374
  return new Promise((resolve23) => {
58213
58375
  const ui = new TuiMainScreen2(new ProcessTerminal2, undefined, getAgentDir());
58214
58376
  const keybindings = KeybindingsManager.create();
@@ -58246,7 +58408,7 @@ var init_session_picker = __esm(() => {
58246
58408
 
58247
58409
  // src/main-session.ts
58248
58410
  import { createInterface as createInterface3 } from "node:readline";
58249
- import { ProcessTerminal as ProcessTerminal3, setKeybindings as setKeybindings3, TuiMainScreen as TuiMainScreen3 } from "@earendil-works/pi-tui";
58411
+ import { ProcessTerminal as ProcessTerminal3, setCapabilityOverrides as setCapabilityOverrides3, setKeybindings as setKeybindings3, TuiMainScreen as TuiMainScreen3 } from "@earendil-works/pi-tui";
58250
58412
  import chalk10 from "chalk";
58251
58413
  async function findLocalSessionByExactId(sessionId, cwd, sessionDir) {
58252
58414
  const localSessions = await SessionManager.list(cwd, sessionDir);
@@ -58385,7 +58547,7 @@ async function createSessionManager(parsed, cwd, sessionDir, settingsManager) {
58385
58547
  if (parsed.resume) {
58386
58548
  initTheme(settingsManager.getTheme(), true);
58387
58549
  try {
58388
- const selectedPath = await selectSession((onProgress) => SessionManager.list(cwd, sessionDir, onProgress), (onProgress) => SessionManager.listAll(sessionDir, onProgress));
58550
+ const selectedPath = await selectSession((onProgress) => SessionManager.list(cwd, sessionDir, onProgress), (onProgress) => SessionManager.listAll(sessionDir, onProgress), settingsManager);
58389
58551
  if (!selectedPath) {
58390
58552
  console.log(chalk10.dim("No session selected"));
58391
58553
  process.exit(0);
@@ -58408,6 +58570,7 @@ async function createSessionManager(parsed, cwd, sessionDir, settingsManager) {
58408
58570
  return SessionManager.create(cwd, sessionDir, { id: parsed.sessionId });
58409
58571
  }
58410
58572
  async function promptForMissingSessionCwd(issue, settingsManager) {
58573
+ setCapabilityOverrides3(settingsManager.getTerminalCapabilityOverrides());
58411
58574
  initTheme(settingsManager.getTheme());
58412
58575
  setKeybindings3(KeybindingsManager.create());
58413
58576
  return new Promise((resolve23) => {
@@ -61993,7 +62156,7 @@ var init_slash_commands = __esm(() => {
61993
62156
  { name: "tree", description: "Navigate session tree (switch branches)" },
61994
62157
  { name: "thinking", description: "Set thinking level", argumentHint: "<level>" },
61995
62158
  { name: "scoped-models", description: "Enable/disable models for ctrl+p cycling" },
61996
- { name: "fast", description: "Configure OpenAI fast mode for chat and workflows in supported models" },
62159
+ { name: "fast", description: "Configure fast mode for chat and workflows on supported models" },
61997
62160
  { name: "export", description: "Export session (HTML default, or specify path: .html/.jsonl)" },
61998
62161
  { name: "import", description: "Import and resume a session from a JSONL file" },
61999
62162
  { name: "share", description: "Share session as a secret GitHub gist" },
@@ -62629,6 +62792,7 @@ function createFullscreenTui(options) {
62629
62792
  openUrl: openBrowser
62630
62793
  }),
62631
62794
  onRightClickPaste: options.onRightClickPaste,
62795
+ copyOnSelect: options.copyOnSelect,
62632
62796
  copySelection: options.copySelection ?? copySelectionToHostClipboard
62633
62797
  }, options.shouldHandleViewportInput, options.onOverlayUnhandledInput);
62634
62798
  }
@@ -62670,7 +62834,7 @@ function createInteractiveTuiReference(getTui) {
62670
62834
  getPrototypeOf: () => Reflect.getPrototypeOf(getTui())
62671
62835
  });
62672
62836
  }
62673
- var viewportInputListeners, viewportInputGates, overlayUnhandledInputHandlers, viewportInputReplays, viewportInputSubscriptions, SGR_MOUSE_SEQUENCE, LEFT_MOUSE_MODIFIER_MASK, AtomicTuiAltScreen, AtomicTuiMainScreen;
62837
+ var viewportInputListeners, viewportInputGates, overlayUnhandledInputHandlers, viewportInputReplays, overlayOwnedSelections, viewportInputSubscriptions, SGR_MOUSE_SEQUENCE, LEFT_MOUSE_MODIFIER_MASK, AtomicTuiAltScreen, AtomicTuiMainScreen;
62674
62838
  var init_interactive_tui = __esm(() => {
62675
62839
  init_clipboard();
62676
62840
  init_open_browser();
@@ -62679,6 +62843,7 @@ var init_interactive_tui = __esm(() => {
62679
62843
  viewportInputGates = new WeakMap;
62680
62844
  overlayUnhandledInputHandlers = new WeakMap;
62681
62845
  viewportInputReplays = new WeakSet;
62846
+ overlayOwnedSelections = new WeakSet;
62682
62847
  viewportInputSubscriptions = new WeakMap;
62683
62848
  SGR_MOUSE_SEQUENCE = /^\x1b\[<(\d+);\d+;\d+([Mm])/;
62684
62849
  LEFT_MOUSE_MODIFIER_MASK = 4 | 8 | 16;
@@ -62694,8 +62859,20 @@ var init_interactive_tui = __esm(() => {
62694
62859
  deferral.shouldDeferViewportInputToOverlay = () => !viewportInputReplays.has(this) && deferToOverlay?.() === true;
62695
62860
  }
62696
62861
  applyLineResets(lines) {
62862
+ if (overlayOwnedSelections.has(this) && !this.isFocusedOverlay())
62863
+ this.clearOverlayOwnedSelection();
62697
62864
  return stripOverlayActiveRowMarker(super.applyLineResets(lines));
62698
62865
  }
62866
+ clearOverlayOwnedSelection() {
62867
+ const selection = this;
62868
+ selection.selectionAnchor = undefined;
62869
+ selection.selectionFocus = undefined;
62870
+ selection.selectionInitialRange = undefined;
62871
+ selection.selectionPressActive = false;
62872
+ selection.selectionDragged = false;
62873
+ selection.lastClick = undefined;
62874
+ overlayOwnedSelections.delete(this);
62875
+ }
62699
62876
  isPiTuiMouseSequence(data) {
62700
62877
  if (parseMouseSequences(data))
62701
62878
  return true;
@@ -62772,6 +62949,7 @@ var init_interactive_tui = __esm(() => {
62772
62949
  if (isLeftMouseButton(sequence))
62773
62950
  viewportListener(sequence.data);
62774
62951
  }
62952
+ overlayOwnedSelections.add(this);
62775
62953
  }
62776
62954
  replayViewportInput(viewportListener, data) {
62777
62955
  viewportInputReplays.add(this);
@@ -62839,7 +63017,11 @@ var init_interactive_tui = __esm(() => {
62839
63017
  });
62840
63018
 
62841
63019
  // src/modes/interactive/interactive-mode-base.ts
62842
- import { isKeyRelease as isKeyRelease3, isViewportTUI } from "@earendil-works/pi-tui";
63020
+ import {
63021
+ isKeyRelease as isKeyRelease3,
63022
+ isViewportTUI,
63023
+ setCapabilityOverrides as setCapabilityOverrides4
63024
+ } from "@earendil-works/pi-tui";
62843
63025
  function isFullscreenViewportAction(data, keybindings) {
62844
63026
  return FULLSCREEN_VIEWPORT_ACTIONS.some((action) => keybindings.matches(data, action));
62845
63027
  }
@@ -62900,6 +63082,18 @@ class InteractiveModeBase {
62900
63082
  return false;
62901
63083
  return this.defaultEditor.handleInput(data);
62902
63084
  }
63085
+ setFullscreenCopyOnSelect(enabled) {
63086
+ if (this.renderer.mode === "fullscreen")
63087
+ this.renderer.setCopyOnSelect(enabled);
63088
+ }
63089
+ getFullscreenCopyOnSelect() {
63090
+ return this.renderer.mode === "fullscreen" ? this.renderer.getCopyOnSelect() : undefined;
63091
+ }
63092
+ async copyActiveFullscreenSelection() {
63093
+ if (this.renderer.mode !== "fullscreen" || !this.renderer.hasActiveSelection())
63094
+ return;
63095
+ return this.renderer.copyActiveSelectionToClipboard();
63096
+ }
62903
63097
  onRightClickPaste = () => {
62904
63098
  this.handleRightClickPaste();
62905
63099
  };
@@ -63099,11 +63293,13 @@ class InteractiveModeBase {
63099
63293
  await this.rebindCurrentSession();
63100
63294
  await this.themeController.applyFromSettings();
63101
63295
  });
63296
+ setCapabilityOverrides4(this.settingsManager.getTerminalCapabilityOverrides());
63102
63297
  this.version = VERSION;
63103
63298
  this.renderer = createInteractiveTui({
63104
63299
  showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
63105
63300
  logDirectory: runtimeHost.services.agentDir,
63106
63301
  terminal: options.terminal,
63302
+ copyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
63107
63303
  onRightClickPaste: this.onRightClickPaste,
63108
63304
  shouldHandleViewportInput: this.shouldHandleViewportInput,
63109
63305
  onOverlayUnhandledInput: this.onOverlayUnhandledInput,
@@ -64226,6 +64422,7 @@ var init_interactive_deferred_startup = __esm(() => {
64226
64422
  try {
64227
64423
  await this.bindCurrentSessionExtensions();
64228
64424
  await this.session.reload({ reason: "startup" });
64425
+ this.applyRuntimeSettings();
64229
64426
  this.rebuildChatFromMessages();
64230
64427
  if (!this.promptTurnWorkingLoaderActive) {
64231
64428
  this.stopWorkingLoader();
@@ -64914,6 +65111,7 @@ ${warningLines}`, 0, 0));
64914
65111
  });
64915
65112
 
64916
65113
  // src/modes/interactive/interactive-session-runtime.ts
65114
+ import { setCapabilityOverrides as setCapabilityOverrides5 } from "@earendil-works/pi-tui";
64917
65115
  var init_interactive_session_runtime = __esm(() => {
64918
65116
  init_interactive_mode_base();
64919
65117
  init_interactive_mode_deps();
@@ -65000,6 +65198,8 @@ var init_interactive_session_runtime = __esm(() => {
65000
65198
  }
65001
65199
  };
65002
65200
  InteractiveModeBase.prototype.applyRuntimeSettings = function() {
65201
+ setCapabilityOverrides5(this.settingsManager.getTerminalCapabilityOverrides());
65202
+ this.setFullscreenCopyOnSelect(this.settingsManager.getFullscreenCopyOnSelect());
65003
65203
  this.transcriptScrollView?.setScrollbar(this.settingsManager.getFullscreenScrollbar());
65004
65204
  this.footer.setSession(this.session);
65005
65205
  this.usageMeter.setSession(this.session);
@@ -66516,6 +66716,9 @@ var init_interactive_input_handling = __esm(() => {
66516
66716
  });
66517
66717
  this.defaultEditor.onAction("app.message.followUp", () => this.handleFollowUp());
66518
66718
  this.defaultEditor.onAction("app.message.dequeue", () => this.handleDequeue());
66719
+ this.defaultEditor.onAction("app.message.copy", () => {
66720
+ this.handleCopyCommand({ preferSelection: true });
66721
+ });
66519
66722
  this.defaultEditor.onAction("app.session.new", () => this.handleClearCommand());
66520
66723
  this.defaultEditor.onAction("app.session.tree", () => this.showTreeSelector());
66521
66724
  this.defaultEditor.onAction("app.session.fork", () => this.showUserMessageSelector());
@@ -68440,7 +68643,7 @@ var init_interactive_selectors = __esm(() => {
68440
68643
  };
68441
68644
  InteractiveModeBase.prototype.showFastModeSelector = function() {
68442
68645
  if (!this.hasCodexFastModeSupportedModels()) {
68443
- this.showWarning("Codex fast mode requires a supported OpenAI or shared ChatGPT Codex transport model.");
68646
+ this.showWarning("Fast mode isn't available for any configured model.");
68444
68647
  return;
68445
68648
  }
68446
68649
  this.showSelector((done) => {
@@ -68499,6 +68702,7 @@ var init_interactive_selectors = __esm(() => {
68499
68702
  showHardwareCursor: this.settingsManager.getShowHardwareCursor(),
68500
68703
  fullscreenScrollbar: this.settingsManager.getFullscreenScrollbar(),
68501
68704
  fullscreenExitOutput: this.settingsManager.getFullscreenExitOutput(),
68705
+ fullscreenCopyOnSelect: this.settingsManager.getFullscreenCopyOnSelect(),
68502
68706
  editorPaddingX: this.settingsManager.getEditorPaddingX(),
68503
68707
  outputPad: this.settingsManager.getOutputPad(),
68504
68708
  showCacheMissNotices: this.settingsManager.getShowCacheMissNotices(),
@@ -68616,6 +68820,10 @@ var init_interactive_selectors = __esm(() => {
68616
68820
  onFullscreenExitOutputChange: (output) => {
68617
68821
  this.settingsManager.setFullscreenExitOutput(output);
68618
68822
  },
68823
+ onFullscreenCopyOnSelectChange: (enabled) => {
68824
+ this.settingsManager.setFullscreenCopyOnSelect(enabled);
68825
+ this.setFullscreenCopyOnSelect(enabled);
68826
+ },
68619
68827
  onEditorPaddingXChange: (padding) => {
68620
68828
  this.settingsManager.setEditorPaddingX(padding);
68621
68829
  this.defaultEditor.setPaddingX(padding);
@@ -69602,18 +69810,8 @@ var init_interactive_slash_commands = __esm(() => {
69602
69810
  activeHeader.setExpanded(this.toolOutputExpanded);
69603
69811
  }
69604
69812
  setRegisteredThemes(this.session.resourceLoader.getThemes().themes);
69605
- this.hideThinkingBlock = this.settingsManager.getHideThinkingBlock();
69813
+ this.applyRuntimeSettings();
69606
69814
  await this.themeController.applyFromSettings();
69607
- const editorPaddingX = this.settingsManager.getEditorPaddingX();
69608
- const autocompleteMaxVisible = this.settingsManager.getAutocompleteMaxVisible();
69609
- this.defaultEditor.setPaddingX(editorPaddingX);
69610
- this.defaultEditor.setAutocompleteMaxVisible(autocompleteMaxVisible);
69611
- if (this.editor !== this.defaultEditor) {
69612
- this.editor.setPaddingX?.(editorPaddingX);
69613
- this.editor.setAutocompleteMaxVisible?.(autocompleteMaxVisible);
69614
- }
69615
- this.ui.setShowHardwareCursor(this.settingsManager.getShowHardwareCursor());
69616
- this.ui.setClearOnShrink(this.settingsManager.getClearOnShrink());
69617
69815
  this.setupAutocompleteProvider();
69618
69816
  const runner = this.session.extensionRunner;
69619
69817
  this.setupExtensionShortcuts(runner);
@@ -69806,7 +70004,12 @@ Gist: ${hyperlink3(gistUrl, gistUrl)}`);
69806
70004
  }
69807
70005
  }
69808
70006
  };
69809
- InteractiveModeBase.prototype.handleCopyCommand = async function() {
70007
+ InteractiveModeBase.prototype.handleCopyCommand = async function(options = {}) {
70008
+ if (options.preferSelection && this.getFullscreenCopyOnSelect() === false) {
70009
+ const selectionCopied = await this.copyActiveFullscreenSelection();
70010
+ if (selectionCopied !== undefined)
70011
+ return;
70012
+ }
69810
70013
  const text = this.session.getLastAssistantText();
69811
70014
  if (!text) {
69812
70015
  this.showError("No agent messages to copy yet.");
@@ -73860,6 +74063,8 @@ var init_rpc_extension_ui = __esm(() => {
73860
74063
  });
73861
74064
 
73862
74065
  // src/modes/rpc/rpc-session-binding.ts
74066
+ import { setCapabilityOverrides as setCapabilityOverrides6 } from "@earendil-works/pi-tui";
74067
+
73863
74068
  class RpcSessionBinding {
73864
74069
  session;
73865
74070
  unsubscribe;
@@ -73903,6 +74108,7 @@ class RpcSessionBinding {
73903
74108
  this.session = this.runtimeHost.session;
73904
74109
  this.disposeSubscriptions();
73905
74110
  const session = this.session;
74111
+ setCapabilityOverrides6(session.settingsManager.getTerminalCapabilityOverrides());
73906
74112
  this.renderService?.bindSession(session);
73907
74113
  this.footerDataProvider = new FooterDataProvider(session.sessionManager.getCwd());
73908
74114
  const models = session.scopedModels.length > 0 ? session.scopedModels.map((scoped) => scoped.model) : session.modelRuntime.getAvailableSnapshot();
@@ -74798,8 +75004,9 @@ var init_config_selector = __esm(() => {
74798
75004
  });
74799
75005
 
74800
75006
  // src/cli/config-selector.ts
74801
- import { ProcessTerminal as ProcessTerminal6, TuiMainScreen as TuiMainScreen8 } from "@earendil-works/pi-tui";
75007
+ import { ProcessTerminal as ProcessTerminal6, setCapabilityOverrides as setCapabilityOverrides7, TuiMainScreen as TuiMainScreen8 } from "@earendil-works/pi-tui";
74802
75008
  async function selectConfig(options) {
75009
+ setCapabilityOverrides7(options.settingsManager.getTerminalCapabilityOverrides());
74803
75010
  initTheme(options.settingsManager.getTheme(), true);
74804
75011
  return new Promise((resolve23) => {
74805
75012
  const ui = new TuiMainScreen8(new ProcessTerminal6, undefined, options.agentDir);
@@ -75652,6 +75859,7 @@ var init_package_manager_cli = __esm(() => {
75652
75859
  });
75653
75860
 
75654
75861
  // src/main.ts
75862
+ import { setCapabilityOverrides as setCapabilityOverrides8 } from "@earendil-works/pi-tui";
75655
75863
  import chalk15 from "chalk";
75656
75864
  function authCheckErrorMessage(error) {
75657
75865
  return error instanceof AuthCommandError ? error.message : "Failed to check provider readiness";
@@ -75886,6 +76094,7 @@ async function main(argv, options) {
75886
76094
  startupEarlyInputCapture = undefined;
75887
76095
  }
75888
76096
  const startupSettingsManager = SettingsManager.create(cwd, agentDir, { projectTrusted: startupProjectTrusted });
76097
+ setCapabilityOverrides8(startupSettingsManager.getTerminalCapabilityOverrides());
75889
76098
  const startupSettingsDiagnostics = collectSettingsDiagnostics(startupSettingsManager, "startup session lookup");
75890
76099
  if (appMode === "interactive" && parsed.useTheme !== undefined) {
75891
76100
  startupSettingsManager.applyOverrides({ theme: parsed.useTheme });
@@ -76020,6 +76229,8 @@ async function main(argv, options) {
76020
76229
  extensionFactories: isolateInteractiveHost ? undefined : extensionFactories
76021
76230
  }
76022
76231
  });
76232
+ if (isolateInteractiveHost)
76233
+ limitMandatoryIntercomToTool(services2.resourceLoader);
76023
76234
  const { settingsManager: settingsManager2, modelRuntime: modelRuntime2, resourceLoader: resourceLoader2 } = services2;
76024
76235
  const diagnostics = [
76025
76236
  ...services2.diagnostics,
@@ -76082,6 +76293,7 @@ async function main(argv, options) {
76082
76293
  endTimingSpan(runtimeCreationSpan);
76083
76294
  const { services, session, modelFallbackMessage } = runtime;
76084
76295
  const { settingsManager, modelRuntime, resourceLoader } = services;
76296
+ setCapabilityOverrides8(settingsManager.getTerminalCapabilityOverrides());
76085
76297
  applyHttpProxySettings(settingsManager.getGlobalSettings().httpProxy);
76086
76298
  configureHttpDispatcher(settingsManager.getHttpIdleTimeoutMs());
76087
76299
  if (parsed.help) {
@@ -76213,6 +76425,7 @@ var init_main = __esm(() => {
76213
76425
  init_auth_storage();
76214
76426
  init_builtin_packages();
76215
76427
  init_http_dispatcher();
76428
+ init_mandatory_resource_loader();
76216
76429
  init_model_resolver();
76217
76430
  init_model_runtime();
76218
76431
  init_output_guard();
@@ -93328,8 +93541,8 @@ class DbosDurableBackend {
93328
93541
  locallyRegistered = new Set;
93329
93542
  promptReservations;
93330
93543
  executorId;
93331
- writeQueue = Promise.resolve();
93332
- writeErrors = [];
93544
+ writeQueues = new Map;
93545
+ writeErrors = new Map;
93333
93546
  constructor(sdk, options) {
93334
93547
  this.sdk = sdk;
93335
93548
  this.executorId = options?.executorId ?? getAtomicExecutorId();
@@ -93337,7 +93550,7 @@ class DbosDurableBackend {
93337
93550
  pendingPrompts: (workflowId) => this.mem.getWorkflow(workflowId)?.pendingPrompts ?? 0,
93338
93551
  adjustPendingPrompts: (workflowId, delta) => this.mem.adjustPendingPrompts(workflowId, delta),
93339
93552
  persist: (workflowId, stepName, output) => {
93340
- this.enqueueWrite(() => this.sdk.recordStepOutput(workflowId, stepName, output));
93553
+ this.enqueueWrite(workflowId, () => this.sdk.recordStepOutput(workflowId, stepName, output));
93341
93554
  }
93342
93555
  });
93343
93556
  }
@@ -93350,14 +93563,14 @@ class DbosDurableBackend {
93350
93563
  this.locallyRegistered.add(handle.workflowId);
93351
93564
  const pendingPrompts2 = this.promptReservations.registerWorkflow(handle.workflowId, handle.pendingPrompts, this.mem.getWorkflow(handle.workflowId)?.pendingPrompts ?? 0);
93352
93565
  this.mem.registerWorkflow({ ...handle, pendingPrompts: pendingPrompts2 });
93353
- this.enqueueWrite(async () => {
93566
+ this.enqueueWrite(handle.workflowId, async () => {
93354
93567
  await this.sdk.startWorkflow(handle.workflowId, handle.name, handle.inputs);
93355
93568
  await this.writeMetadata(handle.workflowId);
93356
93569
  });
93357
93570
  }
93358
93571
  async persistPendingStageMessages(workflowId, messages2, logicalRunId = workflowId) {
93359
93572
  let persisted = false;
93360
- await this.enqueueWrite(async () => {
93573
+ await this.enqueueWrite(workflowId, async () => {
93361
93574
  if (!this.isWorkflowLoadable(workflowId))
93362
93575
  return;
93363
93576
  const handle = this.mem.getWorkflow(workflowId);
@@ -93382,7 +93595,7 @@ class DbosDurableBackend {
93382
93595
  if (!this.isWorkflowLoadable(checkpoint.workflowId))
93383
93596
  return;
93384
93597
  this.mem.recordCheckpoint(checkpoint);
93385
- this.enqueueWrite(() => this.persistCheckpoint(checkpoint));
93598
+ this.enqueueWrite(checkpoint.workflowId, () => this.persistCheckpoint(checkpoint));
93386
93599
  }
93387
93600
  async recordCheckpointAsync(checkpoint, options) {
93388
93601
  if (!this.isWorkflowLoadable(checkpoint.workflowId))
@@ -93390,7 +93603,7 @@ class DbosDurableBackend {
93390
93603
  const signal = options?.signal;
93391
93604
  if (signal?.aborted)
93392
93605
  throw abortSignalReason(signal);
93393
- await this.enqueueWrite(async () => {
93606
+ await this.enqueueWrite(checkpoint.workflowId, async () => {
93394
93607
  if (signal?.aborted || !this.isWorkflowLoadable(checkpoint.workflowId))
93395
93608
  return;
93396
93609
  const persist = (async () => {
@@ -93427,7 +93640,7 @@ class DbosDurableBackend {
93427
93640
  if (!this.isWorkflowLoadable(checkpoint.workflowId))
93428
93641
  return true;
93429
93642
  const encoded = encodeCheckpoint(checkpoint);
93430
- return await this.enqueueBestEffortWrite(async () => {
93643
+ return await this.enqueueBestEffortWrite(checkpoint.workflowId, async () => {
93431
93644
  if (!this.isWorkflowLoadable(checkpoint.workflowId))
93432
93645
  return;
93433
93646
  await this.sdk.recordStepOutput(checkpoint.workflowId, checkpoint.checkpointId, encoded);
@@ -93472,7 +93685,7 @@ class DbosDurableBackend {
93472
93685
  this.promptReservations.setBaseline(workflowId, pendingPrompts2);
93473
93686
  }
93474
93687
  this.mem.setWorkflowStatus(workflowId, status, pendingPrompts2, resumable, failure2);
93475
- this.enqueueWrite(async () => {
93688
+ this.enqueueWrite(workflowId, async () => {
93476
93689
  if (!this.isWorkflowLoadable(workflowId))
93477
93690
  return;
93478
93691
  if (status === "cancelled")
@@ -93486,14 +93699,14 @@ class DbosDurableBackend {
93486
93699
  return await transitionDbosWorkflowStatus({
93487
93700
  expectedStatuses: expected,
93488
93701
  status,
93489
- flush: () => this.flush(),
93702
+ flush: () => this.flush(workflowId),
93490
93703
  local: () => this.getLoadableWorkflow(workflowId),
93491
93704
  read: async () => classifyLatestMetadata(await this.sdk.listStepRecords(workflowId), workflowId),
93492
93705
  reconcile: (entry) => this.mem.setWorkflowStatus(workflowId, entry.status, undefined, entry.resumable),
93493
93706
  claim: (authoritative, generation) => this.claimStatusTransition(workflowId, authoritative, generation, status, pendingPrompts2, resumable),
93494
93707
  write: async () => {
93495
93708
  this.setWorkflowStatus(workflowId, status, pendingPrompts2, resumable);
93496
- await this.flush();
93709
+ await this.flush(workflowId);
93497
93710
  }
93498
93711
  });
93499
93712
  }
@@ -93555,13 +93768,13 @@ class DbosDurableBackend {
93555
93768
  this.locallyRegistered.delete(workflowId);
93556
93769
  this.promptReservations.delete(workflowId);
93557
93770
  await this.mem.deleteWorkflow(workflowId);
93558
- await this.enqueueWrite(async () => {
93771
+ await this.enqueueWrite(workflowId, async () => {
93559
93772
  await this.sdk.deleteWorkflowData(workflowId);
93560
93773
  await this.sdk.recordStepOutput(workflowId, DBOS_DELETION_STEP, encodeDbosDeletionTombstone(workflowId));
93561
93774
  });
93562
93775
  }
93563
93776
  async deleteWorkflowIfInactive(workflowId) {
93564
- await this.flush();
93777
+ await this.flush(workflowId);
93565
93778
  await this.hydrateWorkflow(workflowId);
93566
93779
  const handle = this.getLoadableWorkflow(workflowId);
93567
93780
  if (handle === undefined)
@@ -93572,7 +93785,7 @@ class DbosDurableBackend {
93572
93785
  if (!guarded)
93573
93786
  return { ok: false, reason: "running" };
93574
93787
  await this.deleteWorkflow(workflowId);
93575
- await this.flush();
93788
+ await this.flush(workflowId);
93576
93789
  return { ok: true };
93577
93790
  }
93578
93791
  isWorkflowLoadable(workflowId) {
@@ -93584,16 +93797,19 @@ class DbosDurableBackend {
93584
93797
  this.current.clear();
93585
93798
  this.locallyRegistered.clear();
93586
93799
  this.promptReservations.clear();
93587
- this.writeQueue = Promise.resolve();
93588
- this.writeErrors = [];
93589
- }
93590
- async flush() {
93591
- await this.writeQueue;
93592
- if (this.writeErrors.length === 0)
93593
- return;
93594
- const [first] = this.writeErrors;
93595
- this.writeErrors = [];
93596
- throw first;
93800
+ this.writeQueues.clear();
93801
+ this.writeErrors.clear();
93802
+ }
93803
+ async flush(workflowId) {
93804
+ const workflowIds = workflowId === undefined ? [...new Set([...this.writeQueues.keys(), ...this.writeErrors.keys()])] : [workflowId];
93805
+ await Promise.all(workflowIds.map(async (id) => await this.writeQueues.get(id)));
93806
+ for (const id of workflowIds) {
93807
+ const errors = this.writeErrors.get(id);
93808
+ if (errors === undefined || errors.length === 0)
93809
+ continue;
93810
+ this.writeErrors.delete(id);
93811
+ throw errors[0];
93812
+ }
93597
93813
  }
93598
93814
  async hydrateWorkflow(workflowId) {
93599
93815
  await this.hydrateWorkflowForInspection(workflowId);
@@ -93687,21 +93903,33 @@ class DbosDurableBackend {
93687
93903
  this.promptReservations.delete(workflowId);
93688
93904
  await this.mem.deleteWorkflow(workflowId);
93689
93905
  }
93690
- enqueueWrite(fn) {
93691
- const next = this.writeQueue.then(fn, fn);
93692
- this.writeQueue = next.catch((err) => {
93906
+ enqueueWrite(workflowId, fn) {
93907
+ const previous2 = this.writeQueues.get(workflowId) ?? Promise.resolve();
93908
+ const next = previous2.then(fn, fn);
93909
+ const tracked = next.catch((err) => {
93693
93910
  const error = err instanceof Error ? err : new Error(String(err));
93694
- this.writeErrors.push(error);
93911
+ const errors = this.writeErrors.get(workflowId) ?? [];
93912
+ errors.push(error);
93913
+ this.writeErrors.set(workflowId, errors);
93695
93914
  });
93915
+ this.trackWriteQueue(workflowId, tracked);
93696
93916
  return next;
93697
93917
  }
93698
- async enqueueBestEffortWrite(fn) {
93699
- const next = this.writeQueue.then(fn, fn);
93700
- this.writeQueue = next.catch(() => {
93918
+ async enqueueBestEffortWrite(workflowId, fn) {
93919
+ const previous2 = this.writeQueues.get(workflowId) ?? Promise.resolve();
93920
+ const next = previous2.then(fn, fn);
93921
+ this.trackWriteQueue(workflowId, next.catch(() => {
93701
93922
  return;
93702
- });
93923
+ }));
93703
93924
  return await next.then(() => true, () => false);
93704
93925
  }
93926
+ trackWriteQueue(workflowId, queue) {
93927
+ this.writeQueues.set(workflowId, queue);
93928
+ queue.finally(() => {
93929
+ if (this.writeQueues.get(workflowId) === queue)
93930
+ this.writeQueues.delete(workflowId);
93931
+ });
93932
+ }
93705
93933
  async writeMetadata(workflowId) {
93706
93934
  const value = this.mem.toMetadata(workflowId);
93707
93935
  if (value === undefined)
@@ -96705,7 +96933,7 @@ async function markDurableQuit(runId, run) {
96705
96933
  if (!transitioned)
96706
96934
  return "refused";
96707
96935
  recordRunTimingCheckpoint(backend, run);
96708
- await backend.flush();
96936
+ await backend.flush(runId);
96709
96937
  return "transitioned";
96710
96938
  }
96711
96939
  function discoverDurableQuitBackend(runId) {
@@ -96933,7 +97161,7 @@ async function markDurableResumed(runId) {
96933
97161
  const authoritative = getLoadableDurableWorkflow(backend, runId);
96934
97162
  return authoritative?.status === "running" ? "not_needed" : "refused";
96935
97163
  }
96936
- await backend.flush();
97164
+ await backend.flush(runId);
96937
97165
  pending.delete(runId);
96938
97166
  return "transitioned";
96939
97167
  } catch (error) {
@@ -105635,6 +105863,8 @@ import { extname as extname2, isAbsolute as isAbsolute20, join as join100, resol
105635
105863
  // dist/builtin/workflows/src/extension/workflow-module-loader.ts
105636
105864
  import { createJiti as createJiti2 } from "jiti/static";
105637
105865
  import * as typeboxModule from "typebox";
105866
+ import * as typeboxCompileModule from "typebox/compile";
105867
+ import * as typeboxValueModule from "typebox/value";
105638
105868
 
105639
105869
  // dist/builtin/workflows/src/sdk-surface.ts
105640
105870
  var exports_sdk_surface = {};
@@ -106973,8 +107203,8 @@ class ScopedDurableBackend {
106973
107203
  async recordAdditiveCheckpointBestEffort(checkpoint) {
106974
107204
  return await this.inner.recordAdditiveCheckpointBestEffort(this.remap(checkpoint));
106975
107205
  }
106976
- flush() {
106977
- return this.inner.flush();
107206
+ flush(workflowId) {
107207
+ return workflowId === undefined ? this.inner.flush() : this.inner.flush(this.scope.rootWorkflowId);
106978
107208
  }
106979
107209
  getToolOutput(_workflowId, argsHash) {
106980
107210
  return this.inner.getToolOutput(this.scope.rootWorkflowId, this.scopeKey(argsHash));
@@ -110328,17 +110558,7 @@ function resolveStageGroup(stageOptions, workflowGroup) {
110328
110558
  const trimmed = group.trim();
110329
110559
  return trimmed.length > 0 ? trimmed : undefined;
110330
110560
  }
110331
- function stageHasIntercomAccess(stageOptions) {
110332
- if (!stageOptions)
110333
- return true;
110334
- if (stageOptions.noTools === "all")
110335
- return false;
110336
- const tools = stageOptions.tools;
110337
- if (Array.isArray(tools) && !tools.includes("intercom"))
110338
- return false;
110339
- const excluded = stageOptions.excludedTools;
110340
- if (Array.isArray(excluded) && excluded.includes("intercom"))
110341
- return false;
110561
+ function stageHasIntercomAccess(_stageOptions) {
110342
110562
  return true;
110343
110563
  }
110344
110564
  function stageCanUseWorkflowPendingStageRoute(stageOptions, workflowGroup) {
@@ -110762,11 +110982,11 @@ function wrapUiWithDurable(base, deps) {
110762
110982
  };
110763
110983
  const releasePending = async (identity, token) => {
110764
110984
  releaseDurablePrompt(deps.backend, deps.workflowId, identity.hash, token);
110765
- await deps.backend.flush();
110985
+ await deps.backend.flush(deps.workflowId);
110766
110986
  };
110767
110987
  const beginPending = (identity) => {
110768
110988
  const token = reserveDurablePrompt(deps.backend, deps.workflowId, identity.hash);
110769
- const write = deps.backend.flush();
110989
+ const write = deps.backend.flush(deps.workflowId);
110770
110990
  return { token, write };
110771
110991
  };
110772
110992
  const waitForPendingWrite = async (identity, pending) => {
@@ -110777,7 +110997,7 @@ function wrapUiWithDurable(base, deps) {
110777
110997
  } catch (error) {
110778
110998
  releaseDurablePrompt(deps.backend, deps.workflowId, identity.hash, pending.token);
110779
110999
  try {
110780
- await deps.backend.flush();
111000
+ await deps.backend.flush(deps.workflowId);
110781
111001
  } catch {}
110782
111002
  throw error;
110783
111003
  }
@@ -111074,7 +111294,7 @@ async function admitDurableRootRun(args) {
111074
111294
  args.backend.setWorkflowStatus(args.runId, "running");
111075
111295
  }
111076
111296
  if (!args.isChildRun)
111077
- await args.backend.flush();
111297
+ await args.backend.flush(args.runId);
111078
111298
  }
111079
111299
 
111080
111300
  // dist/builtin/workflows/src/engine/run-durable-finalize.ts
@@ -111105,7 +111325,7 @@ async function finalizeDurableTerminalStatus(input2) {
111105
111325
  } : undefined;
111106
111326
  input2.durableBackend.setWorkflowStatus(input2.runId, durableStatus, undefined, input2.runSnapshot.resumable, failure2);
111107
111327
  }
111108
- await input2.durableBackend.flush();
111328
+ await input2.durableBackend.flush(input2.runId);
111109
111329
  }
111110
111330
  function toDurableStatus(status) {
111111
111331
  switch (status) {
@@ -111660,7 +111880,7 @@ async function resumeDurableWorkflow(workflowId, deps, catalog) {
111660
111880
  });
111661
111881
  } catch (error) {
111662
111882
  backend.setWorkflowStatus(resolved.workflowId, handle.status, handle.pendingPrompts, handle.resumable);
111663
- await backend.flush();
111883
+ await backend.flush(resolved.workflowId);
111664
111884
  return {
111665
111885
  ok: false,
111666
111886
  reason: "startup_failed",
@@ -111674,7 +111894,7 @@ async function resumeDurableWorkflow(workflowId, deps, catalog) {
111674
111894
  const error = workflowStartupFailureMessage(admission, snapshot2?.error, `Workflow ${resolved.workflowId} ended before startup admission`);
111675
111895
  deps.baseRunOpts.store?.removeRun(accepted2.runId);
111676
111896
  backend.setWorkflowStatus(resolved.workflowId, handle.status, handle.pendingPrompts, handle.resumable);
111677
- await backend.flush();
111897
+ await backend.flush(resolved.workflowId);
111678
111898
  return {
111679
111899
  ok: false,
111680
111900
  reason: "startup_failed",
@@ -117625,7 +117845,7 @@ async function run(def, inputs, opts = {}) {
117625
117845
  const result = normalizeWorkflowRunOutput(def.name, rawResult);
117626
117846
  assertWorkflowRunOutputs(def.name, result, def.outputs);
117627
117847
  assertWorkflowCreatedExecution(runSnapshot);
117628
- await durableBackend.flush();
117848
+ await durableBackend.flush(runId);
117629
117849
  const returned = classifyReturnedRunStatus(result, runSnapshot);
117630
117850
  const recorded = activeStore.recordRunEnd(runId, returned.status, result, returned.error, returned.metadata);
117631
117851
  appendRunEndWhenRecorded(opts.persistence, recorded, {
@@ -117641,7 +117861,7 @@ async function run(def, inputs, opts = {}) {
117641
117861
  if (opts.parentRun === undefined)
117642
117862
  recordRunTimingCheckpoint(durableBackend, runSnapshot);
117643
117863
  durableBackend.setWorkflowStatus(runId, returned.status, undefined, returned.metadata?.resumable);
117644
- await durableBackend.flush();
117864
+ await durableBackend.flush(runId);
117645
117865
  return reconcileTerminalRunResult(runId, runSnapshot, activeStore, { status: returned.status, result, error: returned.error }, opts.onRunEnd);
117646
117866
  } catch (err) {
117647
117867
  terminalEvents.selectFailure(err);
@@ -117798,10 +118018,21 @@ function createWorkflowVirtualModules(moduleSpecifier) {
117798
118018
  [`${builtinModuleSpecifier}/steering-context`]: exports_steering_context
117799
118019
  };
117800
118020
  }
118021
+ var TYPEBOX_COMPILE_MODULE = {
118022
+ ...typeboxCompileModule
118023
+ };
118024
+ var TYPEBOX_VALUE_MODULE = {
118025
+ ...typeboxValueModule
118026
+ };
117801
118027
  var WORKFLOWS_VIRTUAL_MODULES = {
117802
118028
  ...createWorkflowVirtualModules(WORKFLOWS_MODULE_SPECIFIER),
117803
118029
  ...createWorkflowVirtualModules(LEGACY_WORKFLOWS_MODULE_SPECIFIER),
117804
- [TYPEBOX_MODULE_SPECIFIER]: TYPEBOX_MODULE
118030
+ [TYPEBOX_MODULE_SPECIFIER]: TYPEBOX_MODULE,
118031
+ "typebox/compile": TYPEBOX_COMPILE_MODULE,
118032
+ "typebox/value": TYPEBOX_VALUE_MODULE,
118033
+ "@sinclair/typebox": TYPEBOX_MODULE,
118034
+ "@sinclair/typebox/compile": TYPEBOX_COMPILE_MODULE,
118035
+ "@sinclair/typebox/value": TYPEBOX_VALUE_MODULE
117805
118036
  };
117806
118037
  var workflowModuleLoader = createJiti2(import.meta.url, {
117807
118038
  moduleCache: false,
@@ -118178,7 +118409,7 @@ async function discardUnadmittedRun(runId, activeStore) {
118178
118409
  const handle = backend.getWorkflow(runId);
118179
118410
  if (handle?.status === "running") {
118180
118411
  backend.setWorkflowStatus(runId, "failed", handle.pendingPrompts, false);
118181
- await backend.flush();
118412
+ await backend.flush(runId);
118182
118413
  }
118183
118414
  const deleted = await backend.deleteWorkflowIfInactive(runId);
118184
118415
  if (!deleted.ok && deleted.reason !== "not_found") {
@@ -118341,7 +118572,7 @@ async function discardFailedActiveBlockedContinuation(backend, runId, store2) {
118341
118572
  const handle = backend.getWorkflow(runId);
118342
118573
  if (handle?.status === "running") {
118343
118574
  backend.setWorkflowStatus(runId, "failed", handle.pendingPrompts, false);
118344
- await backend.flush();
118575
+ await backend.flush(runId);
118345
118576
  }
118346
118577
  const deleted = await backend.deleteWorkflowIfInactive(runId);
118347
118578
  if (!deleted.ok && deleted.reason !== "not_found") {
@@ -124785,7 +125016,7 @@ var DEFAULT_PROMPT_GUIDANCE = [
124785
125016
  - Cyclic workflow graphs are unsupported. Workflow authors and coding agents MUST NOT create self-edges or dependency edges from the current frontier to an existing ancestor. Every materialized execution topology must remain a DAG. Redesign or stop before launch if a cycle cannot be removed.
124786
125017
  - Bounded loops must create distinct tracked work for every iteration; never reopen an ancestor below its downstream work. Stacked implementation slices are unrolled, not looped: each slice gets a fresh child boundary and distinct tracked nodes, and no slice may add an edge back to the current frontier, itself, or an ancestor. If a retained session receives follow-up without new dependency work, keep it as non-topological activity metadata rather than adding a back-edge. Before launch, sketch nodes and dependencies for every branch and loop and reject any proposed parent edge to the node itself or an ancestor.
124787
125018
  - Treat dynamic graph validation during execution, replay, and DBOS hydration as the authoritative cycle boundary. If runtime topology code changes, require incremental edge checks and DBOS hydration validation; prompt guidance and TypeScript types cannot replace those runtime checks.
124788
- - Every workflow invocation automatically receives one stable, non-default Intercom group named \`workflow:<rootRunId>\`. Intercom-capable stages inherit it, nested workflows keep the top-level invocation group, and subagents inherit their launching stage's group. Do not mint or thread group names through ordinary workflow definitions. Use an explicit \`group\` only for an intentional override: a named group or \`group: true\` creates a subgroup, while \`group: "default"\` opts into the shared default group. Stages without Intercom access receive no group, and \`contact_supervisor\` still crosses group boundaries for authorized escalation.
125019
+ - Every workflow invocation automatically receives one stable, non-default Intercom group named \`workflow:<rootRunId>\`. Every model stage inherits it because ordinary \`intercom\` is mandatory even under tool and extension restrictions; nested workflows keep the top-level invocation group, and subagents inherit their launching stage's group. Do not mint or thread group names through ordinary workflow definitions. Use an explicit \`group\` only for an intentional override: a named group or \`group: true\` creates a subgroup, while \`group: "default"\` opts into the shared default group. \`contact_supervisor\` still crosses group boundaries only for authorized subagent escalation.
124789
125020
  - Prefer \`ctx.tool(name, args, fn)\` for workflow-owned TypeScript operations with side effects, such as filesystem writes, network mutations, and external API actions. It creates a tracked, non-attachable durable graph node before invoking \`fn\`; it may be used before, between, after, or without model stages. A completed \`ctx.tool\` call is durably checkpointed with its serializable result, so resume replays that result without rerunning \`fn\`. For checks that may fail during a bounded repair loop, opt into \`failureMode: "return"\`, branch on the typed outcome, and pass only the needed error fields to the repair stage or artifact yourself; Atomic does not inject failure evidence into later prompts. Retries do not bound a hung callback, so every \`ctx.tool\` callback that starts a child process or performs network I/O MUST set an explicit positive finite \`timeoutMs\` and forward the supplied \`signal\` to cancellable work. A timeout applies per attempt, aborts that attempt's signal, and gives retries a fresh deadline and signal. Cancellation and storage faults still throw. Keep pure computation and side-effect-free transformations as ordinary TypeScript. Do not wrap agent-stage internals or every function call indiscriminately; this rule applies to side effects orchestrated directly by the workflow definition.
124790
125021
  - Pass large stage context through files/artifacts and \`reads\` with an explicit \`Read the file at <path>...\` prompt rather than large \`previous\` payloads or injected session history.
124791
125022
  - Wrap critical stage-prompt content in \`<keepContext>\` / \`</keepContext>\`. Tagged content survives compression verbatim regardless of the compression ratio, and every line of the span including the tag lines is protected. A long-running stage will be compacted, and compaction ranks lines individually: an objective is verbose and restated while the constraint that narrows it is usually one line, so the constraint is the cheaper deletion and what survives reads as broader permission than intended. Tag role constraints that bound a stage to part of the work, acceptance criteria and immutable contracts, explicit prohibitions, and identifiers a stage must not lose such as a target branch, worktree path, or run ID. Do not tag bulk context: protected lines count against the keep target rather than raising it, so a large protected span makes the surrounding transcript compress harder — tag the constraint, not the material it applies to.