@cnwenf/occ 2.1.336 → 2.1.338

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env bun
2
- globalThis.MACRO={"VERSION":"2.1.336","BINARY_NAME":"occ","BUILD_TIME":"2026-09-15T19:40:03.023Z","FEEDBACK_CHANNEL":"","ISSUES_EXPLAINER":"","NATIVE_PACKAGE_URL":"","PACKAGE_URL":"@cnwenf/occ","VERSION_CHANGELOG":""};
2
+ globalThis.MACRO={"VERSION":"2.1.338","BINARY_NAME":"occ","BUILD_TIME":"2026-09-16T23:15:11.887Z","FEEDBACK_CHANNEL":"","ISSUES_EXPLAINER":"","NATIVE_PACKAGE_URL":"","PACKAGE_URL":"@cnwenf/occ","VERSION_CHANGELOG":""};
3
3
  // @bun
4
4
  var __create = Object.create;
5
5
  var __getProtoOf = Object.getPrototypeOf;
@@ -101874,6 +101874,62 @@ var init_model = __esm(() => {
101874
101874
  ];
101875
101875
  });
101876
101876
 
101877
+ // src/utils/agentSwarmsEnabled.ts
101878
+ function isAgentTeamsFlagSet() {
101879
+ return process.argv.includes("--agent-teams");
101880
+ }
101881
+ function isAgentSwarmsEnabled() {
101882
+ if (process.env.USER_TYPE === "ant") {
101883
+ return true;
101884
+ }
101885
+ if (!isEnvTruthy(process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS) && !isAgentTeamsFlagSet()) {
101886
+ return false;
101887
+ }
101888
+ if (!getFeatureValue_CACHED_MAY_BE_STALE("tengu_amber_flint", true)) {
101889
+ return false;
101890
+ }
101891
+ return true;
101892
+ }
101893
+ var init_agentSwarmsEnabled = __esm(() => {
101894
+ init_growthbook();
101895
+ init_envUtils();
101896
+ });
101897
+
101898
+ // src/utils/agentContext.ts
101899
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
101900
+ function getAgentContext() {
101901
+ return agentContextStorage.getStore();
101902
+ }
101903
+ function runWithAgentContext(context, fn) {
101904
+ return agentContextStorage.run(context, fn);
101905
+ }
101906
+ function isSubagentContext(context) {
101907
+ return context?.agentType === "subagent";
101908
+ }
101909
+ function getSubagentLogName() {
101910
+ const context = getAgentContext();
101911
+ if (!isSubagentContext(context) || !context.subagentName) {
101912
+ return;
101913
+ }
101914
+ return context.isBuiltIn ? context.subagentName : "user-defined";
101915
+ }
101916
+ function consumeInvokingRequestId() {
101917
+ const context = getAgentContext();
101918
+ if (!context?.invokingRequestId || context.invocationEmitted) {
101919
+ return;
101920
+ }
101921
+ context.invocationEmitted = true;
101922
+ return {
101923
+ invokingRequestId: context.invokingRequestId,
101924
+ invocationKind: context.invocationKind
101925
+ };
101926
+ }
101927
+ var agentContextStorage;
101928
+ var init_agentContext = __esm(() => {
101929
+ init_agentSwarmsEnabled();
101930
+ agentContextStorage = new AsyncLocalStorage2;
101931
+ });
101932
+
101877
101933
  // src/services/api/bedrockContentTypeGuard.ts
101878
101934
  function assertBedrockStreamingContentType(response, requestUrl, provider3) {
101879
101935
  if (provider3 !== "bedrock")
@@ -101909,6 +101965,160 @@ var init_bedrockContentTypeGuard = __esm(() => {
101909
101965
  };
101910
101966
  });
101911
101967
 
101968
+ // src/services/api/gatewayHints.ts
101969
+ function isFirstPartyAnthropicGateway() {
101970
+ return getAPIProvider() === "firstParty" && isFirstPartyAnthropicBaseUrl();
101971
+ }
101972
+ function isGatewayHintHeadersEnabled() {
101973
+ const envOverride = parseTriBool(process.env.CLAUDE_CODE_GATEWAY_HINT_HEADERS);
101974
+ if (envOverride !== undefined) {
101975
+ return envOverride;
101976
+ }
101977
+ if (isFirstPartyAnthropicGateway()) {
101978
+ return true;
101979
+ }
101980
+ if (getAPIProvider() !== "firstParty") {
101981
+ return false;
101982
+ }
101983
+ return false;
101984
+ }
101985
+ function parseTriBool(value) {
101986
+ if (value === undefined) {
101987
+ return;
101988
+ }
101989
+ if (isEnvTruthy(value)) {
101990
+ return true;
101991
+ }
101992
+ if (isEnvDefinedFalsy(value)) {
101993
+ return false;
101994
+ }
101995
+ return;
101996
+ }
101997
+ function toWellFormedString(value) {
101998
+ if (typeof String.prototype.toWellFormed === "function") {
101999
+ return value.toWellFormed();
102000
+ }
102001
+ return value.replace(LONE_SURROGATE_RE, "\uFFFD");
102002
+ }
102003
+ function sanitizeToolNameForHeader(toolName) {
102004
+ return toWellFormedString(toolName).replace(/%|[;=, ]|[^\x20-\x7e]/gu, encodeURIComponent);
102005
+ }
102006
+ function sanitizeHeaderValue(value) {
102007
+ return value.replace(/%|[^\x20-\x7e]/gu, encodeURIComponent);
102008
+ }
102009
+ function buildPrevToolDurationsHeader(entries) {
102010
+ const parts = [];
102011
+ let length = 0;
102012
+ for (const { toolName, durationMs } of entries) {
102013
+ if (parts.length >= MAX_TOOL_DURATION_ENTRIES) {
102014
+ break;
102015
+ }
102016
+ if (!Number.isFinite(durationMs)) {
102017
+ continue;
102018
+ }
102019
+ const ms = Math.max(0, Math.round(durationMs));
102020
+ const entry = `${sanitizeToolNameForHeader(toolName)}=${ms}`;
102021
+ const separatorLength = parts.length > 0 ? 1 : 0;
102022
+ if (length + separatorLength + entry.length > MAX_TOOL_DURATION_HEADER_BYTES) {
102023
+ break;
102024
+ }
102025
+ length += separatorLength + entry.length;
102026
+ parts.push(entry);
102027
+ }
102028
+ return parts.length > 0 ? parts.join(";") : undefined;
102029
+ }
102030
+ function classifyQuerySource(querySource) {
102031
+ if (querySource === undefined) {
102032
+ return;
102033
+ }
102034
+ if (querySource.startsWith("repl_main_thread") || querySource === "sdk") {
102035
+ return "main";
102036
+ }
102037
+ if (querySource.startsWith("agent:") || querySource === "hook_agent") {
102038
+ return "subagent";
102039
+ }
102040
+ return "auxiliary";
102041
+ }
102042
+ function isMainThreadQuerySource(querySource) {
102043
+ return querySource === undefined || classifyQuerySource(querySource) === "main";
102044
+ }
102045
+ function shouldSendContextCompactedHeader(querySource, agentId) {
102046
+ return agentId === undefined && isMainThreadQuerySource(querySource);
102047
+ }
102048
+ function getRequestClassHeader(querySource, agentContext) {
102049
+ if (querySource === undefined) {
102050
+ return;
102051
+ }
102052
+ if (querySource === "compact") {
102053
+ return "compaction";
102054
+ }
102055
+ const querySourceClass = classifyQuerySource(querySource);
102056
+ if (querySourceClass === "subagent" && agentContext?.agentType === "subagent" && agentContext.workflowRunId) {
102057
+ return "workflow";
102058
+ }
102059
+ return querySourceClass;
102060
+ }
102061
+ function getAgentTypeHeader(querySource, agentContext) {
102062
+ if (querySource === undefined || !querySource.startsWith("agent:")) {
102063
+ return;
102064
+ }
102065
+ if (agentContext?.agentType === "teammate") {
102066
+ return "teammate";
102067
+ }
102068
+ if (querySource.startsWith(BUILTIN_AGENT_QUERY_SOURCE_PREFIX)) {
102069
+ return querySource.slice(BUILTIN_AGENT_QUERY_SOURCE_PREFIX.length) || undefined;
102070
+ }
102071
+ if (querySource.startsWith("agent:custom")) {
102072
+ return "custom";
102073
+ }
102074
+ return;
102075
+ }
102076
+ function getCompactionKind(trigger, definednessProbe) {
102077
+ return trigger === "manual" ? "manual" : definednessProbe !== undefined ? "auto" : "reactive";
102078
+ }
102079
+ function armPendingContextCompacted(kind) {
102080
+ pendingContextCompacted = kind;
102081
+ }
102082
+ function consumePendingContextCompacted() {
102083
+ const kind = pendingContextCompacted;
102084
+ pendingContextCompacted = undefined;
102085
+ return kind;
102086
+ }
102087
+ function applyContextCompactedHeaders(headers, contextCompactedKind, compactionRequestKind) {
102088
+ if (contextCompactedKind === undefined && compactionRequestKind === undefined) {
102089
+ return;
102090
+ }
102091
+ const firstPartyGateway = isFirstPartyAnthropicGateway();
102092
+ const hintsEnabled = isGatewayHintHeadersEnabled();
102093
+ if (contextCompactedKind !== undefined) {
102094
+ if (firstPartyGateway) {
102095
+ headers[CONTEXT_COMPACTED_GATEWAY_HEADER] = contextCompactedKind;
102096
+ }
102097
+ if (hintsEnabled) {
102098
+ headers[CONTEXT_COMPACTED_HEADER] = contextCompactedKind;
102099
+ }
102100
+ }
102101
+ if (compactionRequestKind !== undefined) {
102102
+ if (firstPartyGateway) {
102103
+ headers[COMPACTION_REQUEST_GATEWAY_HEADER] = compactionRequestKind;
102104
+ }
102105
+ if (hintsEnabled) {
102106
+ headers[COMPACTION_HEADER] = compactionRequestKind;
102107
+ }
102108
+ }
102109
+ }
102110
+ function applyPrevToolDurationsHeader(headers, prevToolDurationsHeader) {
102111
+ if (prevToolDurationsHeader !== undefined && isGatewayHintHeadersEnabled()) {
102112
+ headers[PREV_TOOL_DURATIONS_HEADER] = prevToolDurationsHeader;
102113
+ }
102114
+ }
102115
+ var CONTEXT_COMPACTED_GATEWAY_HEADER = "x-cc-context-compacted", COMPACTION_REQUEST_GATEWAY_HEADER = "x-cc-compaction-request", COMPACTION_HEADER = "x-claude-code-compaction", CONTEXT_COMPACTED_HEADER = "x-claude-code-context-compacted", PREV_TOOL_DURATIONS_HEADER = "x-claude-code-prev-tool-durations", REQUEST_CLASS_HEADER = "x-claude-code-request-class", AGENT_TYPE_HEADER = "x-claude-code-agent-type", MAX_TOOL_DURATION_ENTRIES = 32, MAX_TOOL_DURATION_HEADER_BYTES = 4096, BUILTIN_AGENT_QUERY_SOURCE_PREFIX = "agent:builtin:", LONE_SURROGATE_RE, pendingContextCompacted;
102116
+ var init_gatewayHints = __esm(() => {
102117
+ init_envUtils();
102118
+ init_providers();
102119
+ LONE_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
102120
+ });
102121
+
101912
102122
  // node_modules/.bun/tslib@1.14.1/node_modules/tslib/tslib.js
101913
102123
  var require_tslib2 = __commonJS((exports, module) => {
101914
102124
  /*! *****************************************************************************
@@ -139857,6 +140067,17 @@ async function getAnthropicClient({
139857
140067
  ...remoteSessionId ? { "x-claude-remote-session-id": remoteSessionId } : {},
139858
140068
  ...clientApp ? { "x-client-app": clientApp } : {}
139859
140069
  };
140070
+ if (isGatewayHintHeadersEnabled()) {
140071
+ const agentContext = getAgentContext();
140072
+ const requestClass = getRequestClassHeader(source, agentContext);
140073
+ if (requestClass) {
140074
+ defaultHeaders[REQUEST_CLASS_HEADER] = requestClass;
140075
+ }
140076
+ const agentType = getAgentTypeHeader(source, agentContext);
140077
+ if (agentType) {
140078
+ defaultHeaders[AGENT_TYPE_HEADER] = sanitizeHeaderValue(agentType);
140079
+ }
140080
+ }
139860
140081
  logForDebugging(`[API:request] Creating client, ANTHROPIC_CUSTOM_HEADERS present: ${!!process.env.ANTHROPIC_CUSTOM_HEADERS}, has Authorization header: ${!!customHeaders["Authorization"]}`);
139861
140082
  const additionalProtectionEnabled = isEnvTruthy(process.env.CLAUDE_CODE_ADDITIONAL_PROTECTION);
139862
140083
  if (additionalProtectionEnabled) {
@@ -140064,7 +140285,9 @@ var init_client9 = __esm(() => {
140064
140285
  init_oauth();
140065
140286
  init_debug();
140066
140287
  init_envUtils();
140288
+ init_agentContext();
140067
140289
  init_bedrockContentTypeGuard();
140290
+ init_gatewayHints();
140068
140291
  });
140069
140292
 
140070
140293
  // src/utils/model/modelCapabilities.ts
@@ -143744,7 +143967,7 @@ function getClaudeCodeUserAgent() {
143744
143967
  }
143745
143968
 
143746
143969
  // src/utils/workloadContext.ts
143747
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
143970
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
143748
143971
  function getWorkload() {
143749
143972
  return workloadStorage.getStore()?.workload;
143750
143973
  }
@@ -143753,7 +143976,7 @@ function runWithWorkload(workload, fn) {
143753
143976
  }
143754
143977
  var WORKLOAD_CRON = "cron", workloadStorage;
143755
143978
  var init_workloadContext = __esm(() => {
143756
- workloadStorage = new AsyncLocalStorage2;
143979
+ workloadStorage = new AsyncLocalStorage3;
143757
143980
  });
143758
143981
 
143759
143982
  // src/utils/http.ts
@@ -150712,62 +150935,6 @@ var init_officialRegistry = __esm(() => {
150712
150935
  init_errors();
150713
150936
  });
150714
150937
 
150715
- // src/utils/agentSwarmsEnabled.ts
150716
- function isAgentTeamsFlagSet() {
150717
- return process.argv.includes("--agent-teams");
150718
- }
150719
- function isAgentSwarmsEnabled() {
150720
- if (process.env.USER_TYPE === "ant") {
150721
- return true;
150722
- }
150723
- if (!isEnvTruthy(process.env.CLAUDE_CODE_EXPERIMENTAL_AGENT_TEAMS) && !isAgentTeamsFlagSet()) {
150724
- return false;
150725
- }
150726
- if (!getFeatureValue_CACHED_MAY_BE_STALE("tengu_amber_flint", true)) {
150727
- return false;
150728
- }
150729
- return true;
150730
- }
150731
- var init_agentSwarmsEnabled = __esm(() => {
150732
- init_growthbook();
150733
- init_envUtils();
150734
- });
150735
-
150736
- // src/utils/agentContext.ts
150737
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
150738
- function getAgentContext() {
150739
- return agentContextStorage.getStore();
150740
- }
150741
- function runWithAgentContext(context4, fn) {
150742
- return agentContextStorage.run(context4, fn);
150743
- }
150744
- function isSubagentContext(context4) {
150745
- return context4?.agentType === "subagent";
150746
- }
150747
- function getSubagentLogName() {
150748
- const context4 = getAgentContext();
150749
- if (!isSubagentContext(context4) || !context4.subagentName) {
150750
- return;
150751
- }
150752
- return context4.isBuiltIn ? context4.subagentName : "user-defined";
150753
- }
150754
- function consumeInvokingRequestId() {
150755
- const context4 = getAgentContext();
150756
- if (!context4?.invokingRequestId || context4.invocationEmitted) {
150757
- return;
150758
- }
150759
- context4.invocationEmitted = true;
150760
- return {
150761
- invokingRequestId: context4.invokingRequestId,
150762
- invocationKind: context4.invocationKind
150763
- };
150764
- }
150765
- var agentContextStorage;
150766
- var init_agentContext = __esm(() => {
150767
- init_agentSwarmsEnabled();
150768
- agentContextStorage = new AsyncLocalStorage3;
150769
- });
150770
-
150771
150938
  // src/utils/teammateContext.ts
150772
150939
  import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
150773
150940
  function getTeammateContext() {
@@ -232750,6 +232917,7 @@ function parseAgentFromJson(name3, definition, source = "flagSettings") {
232750
232917
  ...parsed.skills && parsed.skills.length > 0 ? { skills: parsed.skills } : {},
232751
232918
  ...parsed.initialPrompt ? { initialPrompt: parsed.initialPrompt } : {},
232752
232919
  ...parsed.background ? { background: parsed.background } : {},
232920
+ ...parsed.omitClaudeMd ? { omitClaudeMd: parsed.omitClaudeMd } : {},
232753
232921
  ...parsed.memory ? { memory: parsed.memory } : {},
232754
232922
  ...parsed.isolation ? { isolation: parsed.isolation } : {}
232755
232923
  };
@@ -232809,6 +232977,8 @@ function parseAgentFromMarkdown(filePath, baseDir, frontmatter, content, source)
232809
232977
  logForDebugging(`Agent file ${filePath} has invalid background value '${backgroundRaw}'. Must be 'true', 'false', or omitted.`);
232810
232978
  }
232811
232979
  const background = backgroundRaw === "true" || backgroundRaw === true ? true : undefined;
232980
+ const omitClaudeMdRaw = frontmatter["omitClaudeMd"];
232981
+ const omitClaudeMd = omitClaudeMdRaw === "true" || omitClaudeMdRaw === true ? true : undefined;
232812
232982
  const VALID_MEMORY_SCOPES2 = ["user", "project", "local"];
232813
232983
  const memoryRaw = frontmatter["memory"];
232814
232984
  let memory;
@@ -232906,6 +233076,7 @@ function parseAgentFromMarkdown(filePath, baseDir, frontmatter, content, source)
232906
233076
  ...isValidPermissionMode ? { permissionMode: permissionModeRaw } : {},
232907
233077
  ...maxTurns !== undefined ? { maxTurns } : {},
232908
233078
  ...background ? { background } : {},
233079
+ ...omitClaudeMd ? { omitClaudeMd } : {},
232909
233080
  ...memory ? { memory } : {},
232910
233081
  ...isolation ? { isolation } : {},
232911
233082
  ...cacheTtl !== undefined ? { cacheTtl } : {}
@@ -232964,6 +233135,7 @@ var init_loadAgentsDir = __esm(() => {
232964
233135
  initialPrompt: exports_external.string().optional(),
232965
233136
  memory: exports_external.enum(["user", "project", "local"]).optional(),
232966
233137
  background: exports_external.boolean().optional(),
233138
+ omitClaudeMd: exports_external.boolean().optional(),
232967
233139
  isolation: (process.env.USER_TYPE === "ant" ? exports_external.enum(["worktree", "remote"]) : exports_external.enum(["worktree"])).optional()
232968
233140
  }));
232969
233141
  AgentsJsonSchema = lazySchema(() => exports_external.record(exports_external.string(), AgentJsonSchema()));
@@ -266498,29 +266670,39 @@ async function* withRetry(getClient2, operation, options) {
266498
266670
  } catch (error52) {
266499
266671
  lastError = error52;
266500
266672
  logForDebugging(`API error (attempt ${attempt}/${maxRetries + 1}): ${error52 instanceof APIError ? `${error52.status} ${error52.message}` : errorMessage(error52)}`, { level: "error" });
266673
+ const watchdogRetryEnabled = isRetryWatchdogEnabled();
266501
266674
  if (wasFastModeActive && !isPersistentRetryEnabled() && error52 instanceof APIError && (error52.status === 429 || is529Error(error52))) {
266502
266675
  const overageReason = error52.headers?.get("anthropic-ratelimit-unified-overage-disabled-reason");
266503
266676
  if (overageReason !== null && overageReason !== undefined) {
266504
266677
  handleFastModeOverageRejection(overageReason);
266505
266678
  retryContext.fastMode = false;
266679
+ if (watchdogRetryEnabled && attempt >= maxRetries)
266680
+ attempt = maxRetries;
266506
266681
  continue;
266507
266682
  }
266508
266683
  const retryAfterMs = getRetryAfterMs(error52);
266509
- if (retryAfterMs !== null && retryAfterMs < SHORT_RETRY_THRESHOLD_MS) {
266684
+ const isShortRetry = retryAfterMs !== null && retryAfterMs < SHORT_RETRY_THRESHOLD_MS;
266685
+ if (isShortRetry && !watchdogRetryEnabled) {
266510
266686
  await sleep2(retryAfterMs, options.signal, { abortError });
266511
266687
  continue;
266512
266688
  }
266513
- const cooldownMs = Math.max(retryAfterMs ?? DEFAULT_FAST_MODE_FALLBACK_HOLD_MS, MIN_COOLDOWN_MS);
266514
- const cooldownReason = is529Error(error52) ? "overloaded" : "rate_limit";
266515
- triggerFastModeCooldown(Date.now() + cooldownMs, cooldownReason);
266516
- if (isFastModeEnabled()) {
266517
- retryContext.fastMode = false;
266689
+ if (!isShortRetry) {
266690
+ const cooldownMs = Math.max(retryAfterMs ?? DEFAULT_FAST_MODE_FALLBACK_HOLD_MS, MIN_COOLDOWN_MS);
266691
+ const cooldownReason = is529Error(error52) ? "overloaded" : "rate_limit";
266692
+ triggerFastModeCooldown(Date.now() + cooldownMs, cooldownReason);
266693
+ if (isFastModeEnabled()) {
266694
+ retryContext.fastMode = false;
266695
+ }
266696
+ if (watchdogRetryEnabled && attempt >= maxRetries)
266697
+ attempt = maxRetries;
266698
+ continue;
266518
266699
  }
266519
- continue;
266520
266700
  }
266521
266701
  if (wasFastModeActive && isFastModeNotEnabledError(error52)) {
266522
266702
  handleFastModeRejectedByAPI();
266523
266703
  retryContext.fastMode = false;
266704
+ if (watchdogRetryEnabled && attempt >= maxRetries)
266705
+ attempt = maxRetries;
266524
266706
  continue;
266525
266707
  }
266526
266708
  if (is529Error(error52) && !shouldRetry529(options.querySource) && !isRetryWatchdogEnabled()) {
@@ -361041,10 +361223,17 @@ function collectCommands(node, commands7, varScope) {
361041
361223
  const arg = walkArgument(child, commands7, varScope);
361042
361224
  if (typeof arg !== "string")
361043
361225
  return arg;
361044
- if ((argv[0] === "declare" || argv[0] === "typeset" || argv[0] === "local") && /^-[a-zA-Z]*[niaA]/.test(arg)) {
361226
+ if ((argv[0] === "declare" || argv[0] === "typeset" || argv[0] === "local") && /^[+-].*[nialuAEFLRZ]/.test(arg)) {
361227
+ return {
361228
+ kind: "too-complex",
361229
+ reason: `declare flag ${arg} changes assignment semantics (nameref/integer/float/array/width-truncation/case-conversion)`,
361230
+ nodeType: "declaration_command"
361231
+ };
361232
+ }
361233
+ if ((argv[0] === "export" || argv[0] === "readonly") && /^[+-].*[iluEFLRZ]/.test(arg)) {
361045
361234
  return {
361046
361235
  kind: "too-complex",
361047
- reason: `declare flag ${arg} changes assignment semantics (nameref/integer/array)`,
361236
+ reason: `${argv[0]} flag ${arg} \u2014 zsh bin_typeset mathevals (-i/-E/-F), width-truncates (-L/-R/-Z), or case-converts (-l/-u) the assigned value`,
361048
361237
  nodeType: "declaration_command"
361049
361238
  };
361050
361239
  }
@@ -380838,10 +381027,32 @@ function parsePatternCommand(args, flagsWithArgs, defaults2 = []) {
380838
381027
  }
380839
381028
  return paths2.length > 0 ? paths2 : defaults2;
380840
381029
  }
381030
+ function globCharIndex(arg) {
381031
+ for (let i6 = 0;i6 < arg.length; i6++) {
381032
+ const c9 = arg[i6];
381033
+ if (c9 === "*" || c9 === "?")
381034
+ return i6;
381035
+ if (c9 === "[" && arg.indexOf("]", i6 + 1) !== -1)
381036
+ return i6;
381037
+ }
381038
+ return -1;
381039
+ }
381040
+ function collectUnextractedGlobArgs(args, extractedPaths) {
381041
+ const seen = new Set(extractedPaths);
381042
+ const out = [];
381043
+ for (const arg of args) {
381044
+ if (globCharIndex(arg) !== -1 && !seen.has(arg)) {
381045
+ seen.add(arg);
381046
+ out.push(arg);
381047
+ }
381048
+ }
381049
+ return out;
381050
+ }
380841
381051
  function validateCommandPaths(command4, args, cwd2, toolPermissionContext, compoundCommandHasCd, operationTypeOverride) {
380842
381052
  const extractor = PATH_EXTRACTORS[command4];
380843
- const paths2 = extractor(args);
381053
+ const extractedPaths = extractor(args);
380844
381054
  const operationType = operationTypeOverride ?? COMMAND_OPERATION_TYPE[command4];
381055
+ const paths2 = operationType === "read" ? [...extractedPaths, ...collectUnextractedGlobArgs(args, extractedPaths)] : extractedPaths;
380845
381056
  const validator = COMMAND_VALIDATOR[command4];
380846
381057
  if (validator && !validator(args)) {
380847
381058
  return {
@@ -385036,8 +385247,8 @@ function findCatastrophicSubstitutionBlock(command4) {
385036
385247
  }
385037
385248
  return null;
385038
385249
  }
385039
- for (const body of [command4, ...subs]) {
385040
- let c9 = body.trim();
385250
+ const analyzeText = (text2) => {
385251
+ let c9 = text2.trim();
385041
385252
  if (c9.startsWith("{") && /;?\s*\}$/.test(c9) || c9.startsWith("(") && c9.endsWith(")")) {
385042
385253
  c9 = c9.slice(1).replace(/;?\s*[)}]$/, "").trim();
385043
385254
  }
@@ -385054,6 +385265,18 @@ function findCatastrophicSubstitutionBlock(command4) {
385054
385265
  reason: "rm -rf targeting the root or home directory detected inside command substitution"
385055
385266
  };
385056
385267
  }
385268
+ return null;
385269
+ };
385270
+ for (const body of [command4, ...subs]) {
385271
+ for (const text2 of [body, ...splitCommand_DEPRECATED(body)]) {
385272
+ if (text2.trim() === "") {
385273
+ continue;
385274
+ }
385275
+ const block = analyzeText(text2);
385276
+ if (block !== null) {
385277
+ return block;
385278
+ }
385279
+ }
385057
385280
  }
385058
385281
  return null;
385059
385282
  }
@@ -453731,9 +453954,13 @@ function computeTodoLabel(todo) {
453731
453954
  function computeSpinnerVerbWidth(columns) {
453732
453955
  return Math.max(40, columns - 8);
453733
453956
  }
453734
- var THINKING_AMBER_DELAY_MS = 1e4, THINKING_AMBER_RAMP_MS = 1e4, RGB_CACHE;
453957
+ function appendSpinnerEllipsis(verb) {
453958
+ return SPINNER_ELLIPSIS_RE.test(verb) ? verb : verb + "\u2026";
453959
+ }
453960
+ var THINKING_AMBER_DELAY_MS = 1e4, THINKING_AMBER_RAMP_MS = 1e4, RGB_CACHE, SPINNER_ELLIPSIS_RE;
453735
453961
  var init_utils10 = __esm(() => {
453736
453962
  RGB_CACHE = new Map;
453963
+ SPINNER_ELLIPSIS_RE = /(\u2026|\.\.\.)$/;
453737
453964
  });
453738
453965
 
453739
453966
  // src/components/Spinner/FlashingChar.tsx
@@ -460536,7 +460763,7 @@ function SpinnerWithVerbInner({
460536
460763
  const leaderTodoLabel = currentTodo ? computeTodoLabel(currentTodo) : undefined;
460537
460764
  const leaderVerb = overrideMessage ?? (leaderTodoLabel === undefined ? undefined : truncateToWidthNoEllipsis(leaderTodoLabel, computeSpinnerVerbWidth(columns))) ?? randomVerb;
460538
460765
  const effectiveVerb = foregroundedTeammate && !foregroundedTeammate.isIdle ? foregroundedTeammate.spinnerVerb ?? randomVerb : leaderVerb;
460539
- const message = effectiveVerb + "\u2026";
460766
+ const message = appendSpinnerEllipsis(effectiveVerb);
460540
460767
  import_react64.useEffect(() => {
460541
460768
  const operationId = "spinner-" + mode;
460542
460769
  activityManager.startCLIActivity(operationId);
@@ -584823,10 +585050,117 @@ ${output2.json}`
584823
585050
  var exports_MonitorTool = {};
584824
585051
  __export(exports_MonitorTool, {
584825
585052
  stopMonitor: () => stopMonitor,
585053
+ normalizeMonitorInput: () => normalizeMonitorInput,
585054
+ monitorExpiredNotice: () => monitorExpiredNotice,
585055
+ fireMonitorDeadline: () => fireMonitorDeadline,
584826
585056
  MonitorTool: () => MonitorTool,
584827
585057
  MONITOR_TOOL_NAME: () => MONITOR_TOOL_NAME
584828
585058
  });
584829
585059
  import { randomUUID as randomUUID22 } from "crypto";
585060
+ function monitorDeadlineCap() {
585061
+ return getIsNonInteractiveSession() ? MONITOR_DEADLINE_CAP_PRINT_MS : MONITOR_DEADLINE_CAP_MS;
585062
+ }
585063
+ function formatMonitorMinutes(ms) {
585064
+ return `${Math.round(ms / 60000)} minutes`;
585065
+ }
585066
+ function normalizeMonitorInput(input2) {
585067
+ return {
585068
+ timeoutMs: Math.min(input2.timeout_ms ?? DEFAULT_TIMEOUT_MS2, monitorDeadlineCap()),
585069
+ persistent: false
585070
+ };
585071
+ }
585072
+ function monitorExpiredNotice(timeoutMs, eventCount) {
585073
+ const duration3 = formatDuration(timeoutMs, { hideTrailingZeros: true });
585074
+ if (eventCount === 0) {
585075
+ return `[Monitor expired after ${duration3} with no events delivered. Re-arm it if you still need the watch \u2014 and widen the filter if silence was unexpected.]`;
585076
+ }
585077
+ return `[Monitor expired after ${duration3} with ${eventCount} ${pluralize2(eventCount, "event")} delivered. Re-arm it if you still need the watch.]`;
585078
+ }
585079
+ function deadlineSection() {
585080
+ return `Every monitor expires after \`timeout_ms\` (default ${formatMonitorMinutes(DEFAULT_TIMEOUT_MS2)}, at most ${formatMonitorMinutes(monitorDeadlineCap())}): it is killed and you get one notice with the event count. Re-arm it if you still need the watch; for a long watch (PR monitoring, log tails) set \`timeout_ms\` to the maximum and re-arm on each expiry, and widen the filter if an expiry with no events was unexpected.`;
585081
+ }
585082
+ function buildDescription2() {
585083
+ return `**OCC build note (event delivery not yet wired):** in this build, Monitor events and the expiry notice are recorded internally but are NOT delivered to the chat \u2014 the notification consumer is a tracked follow-up (occ127). The deadline itself IS enforced: every monitor is killed and deregistered at \`timeout_ms\`. Until delivery lands, use Bash \`run_in_background\` when you need a delivered completion notification, and read the delivery-dependent statements below ("notifications arrive in the chat", the expiry notice) as describing not-yet-available behavior.
585084
+
585085
+ Start a background monitor that streams events from a long-running script. Each stdout line is an event \u2014 you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you're waiting for the user to answer a question.
585086
+
585087
+ Pick by how many notifications you need:
585088
+ - **One** ("tell me when the server is ready / the build finishes") \u2192 use **Bash with \`run_in_background\`** and a command that exits when the condition is true, e.g. \`until grep -q "Ready in" dev.log; do sleep 0.5; done\`. You get a single completion notification when it exits.
585089
+ - **One per occurrence, indefinitely** ("tell me every time an ERROR line appears") \u2192 Monitor with an unbounded command (\`tail -f\`, \`inotifywait -m\`, \`while true\`).
585090
+ - **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") \u2192 Monitor with a command that emits lines and then exits.
585091
+
585092
+ Your script's stdout is the event stream. Each line becomes a notification. Exit ends the watch.
585093
+
585094
+ # Each matching log line is an event
585095
+ tail -f /var/log/app.log | grep --line-buffered "ERROR"
585096
+
585097
+ # Each file change is an event
585098
+ inotifywait -m --format '%e %f' /watched/dir
585099
+
585100
+ # Poll GitHub for new PR comments and emit one line per new comment
585101
+ last=$(date -u +%Y-%m-%dT%H:%M:%SZ)
585102
+ while true; do
585103
+ now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
585104
+ gh api "repos/owner/repo/issues/123/comments?since=$last" --jq '.[] | "\\(.user.login): \\(.body)"'
585105
+ last=$now; sleep 30
585106
+ done
585107
+
585108
+ # Node script that emits events as they arrive (e.g. WebSocket listener)
585109
+ node watch-for-events.js
585110
+
585111
+ # Per-occurrence with a natural end: emit each CI check as it lands, exit when the run completes
585112
+ prev=""
585113
+ while true; do
585114
+ s=$(gh pr checks 123 --json name,bucket)
585115
+ cur=$(jq -r '.[] | select(.bucket!="pending") | "\\(.name): \\(.bucket)"' <<<"$s" | sort)
585116
+ comm -13 <(echo "$prev") <(echo "$cur")
585117
+ prev=$cur
585118
+ jq -e 'all(.bucket!="pending")' <<<"$s" >/dev/null && break
585119
+ sleep 30
585120
+ done
585121
+
585122
+ **Don't use an unbounded command for a single notification.** \`tail -f\`, \`inotifywait -m\`, and \`while true\` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash \`run_in_background\` with an \`until\` loop instead (one notification, ends in seconds). Note that \`tail -f log | grep -m 1 ...\` does *not* fix this: if the log goes quiet after the match, \`tail\` never receives SIGPIPE and the pipeline hangs anyway.
585123
+
585124
+ **Script quality:**
585125
+ - Every pipe stage must flush per line or matches sit in its buffer unseen: \`grep\` needs \`--line-buffered\`, \`awk\` needs \`fflush()\`. \`head\` cannot flush at all \u2014 \`| head -N\` delivers nothing until N matches accumulate, then ends the stream.
585126
+ - In poll loops, handle transient failures (\`curl ... || true\`) \u2014 one failed request shouldn't kill the monitor.
585127
+ - Poll intervals: 30s+ for remote APIs (rate limits), 0.5-1s for local checks.
585128
+ - Write a specific \`description\` \u2014 it appears in every notification ("errors in deploy.log" not "watching logs").
585129
+ - Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications \u2014 for a command you run directly (e.g. \`python train.py 2>&1 | grep --line-buffered ...\`), merge stderr with \`2>&1\` so its failures reach your filter. (No effect on \`tail -f\` of an existing log \u2014 that file only contains what its writer redirected.)
585130
+
585131
+ **Coverage \u2014 silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit \u2014 and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.
585132
+
585133
+ # Wrong \u2014 silent on crash, hang, or any non-success exit
585134
+ tail -f run.log | grep --line-buffered "elapsed_steps="
585135
+
585136
+ # Right \u2014 one alternation covering progress + the failure signatures you'd act on
585137
+ tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"
585138
+
585139
+ For poll loops checking job state, emit on every terminal status (\`succeeded|failed|cancelled|timeout\`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it \u2014 some extra noise is better than missing a crashloop.
585140
+
585141
+ **Output volume**: Every stdout line is a conversation message, so the filter should be selective \u2014 but selective means "the lines you'd act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.
585142
+
585143
+ Stdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.
585144
+
585145
+ The script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). ${deadlineSection()} Use TaskStop to cancel early.
585146
+ **ws source** \u2014 open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.
585147
+ Monitor({
585148
+ ws: {url: 'wss://events.example.com/stream', protocols: ['v1']},
585149
+ description: 'deploy events',
585150
+ })
585151
+ Each text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as \`[binary frame, N bytes]\` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash \u2014 a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.
585152
+ Prefer this over \`command: 'websocat wss://\u2026'\` \u2014 it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.`;
585153
+ }
585154
+ function fireMonitorDeadline(deps) {
585155
+ const registry2 = deps.registry ?? activeMonitors;
585156
+ const h5 = registry2.get(deps.taskId);
585157
+ if (!h5)
585158
+ return false;
585159
+ deps.emit(monitorExpiredNotice(deps.timeoutMs, deps.eventCount));
585160
+ h5.kill();
585161
+ registry2.delete(deps.taskId);
585162
+ return true;
585163
+ }
584830
585164
  function shellPath() {
584831
585165
  return process.env.SHELL || "/bin/sh";
584832
585166
  }
@@ -584919,77 +585253,13 @@ function stopMonitor(taskId) {
584919
585253
  activeMonitors.delete(taskId);
584920
585254
  return true;
584921
585255
  }
584922
- var MONITOR_TOOL_NAME = "Monitor", DEFAULT_TIMEOUT_MS2 = 300000, MAX_TIMEOUT_MS2 = 3600000, COMMAND_DESC = "Shell command or script. Each stdout line is an event; exit ends the watch.", DESCRIPTION19 = `Start a background monitor that streams events from a long-running script. Each stdout line is an event \u2014 you keep working and notifications arrive in the chat. Events arrive on their own schedule and are not replies from the user, even if one lands while you're waiting for the user to answer a question.
584923
-
584924
- Pick by how many notifications you need:
584925
- - **One** ("tell me when the server is ready / the build finishes") \u2192 use **Bash with \`run_in_background\`** and a command that exits when the condition is true, e.g. \`until grep -q "Ready in" dev.log; do sleep 0.5; done\`. You get a single completion notification when it exits.
584926
- - **One per occurrence, indefinitely** ("tell me every time an ERROR line appears") \u2192 Monitor with an unbounded command (\`tail -f\`, \`inotifywait -m\`, \`while true\`).
584927
- - **One per occurrence, until a known end** ("emit each CI step result, stop when the run completes") \u2192 Monitor with a command that emits lines and then exits.
584928
-
584929
- Your script's stdout is the event stream. Each line becomes a notification. Exit ends the watch.
584930
-
584931
- # Each matching log line is an event
584932
- tail -f /var/log/app.log | grep --line-buffered "ERROR"
584933
-
584934
- # Each file change is an event
584935
- inotifywait -m --format '%e %f' /watched/dir
584936
-
584937
- # Poll GitHub for new PR comments and emit one line per new comment
584938
- last=$(date -u +%Y-%m-%dT%H:%M:%SZ)
584939
- while true; do
584940
- now=$(date -u +%Y-%m-%dT%H:%M:%SZ)
584941
- gh api "repos/owner/repo/issues/123/comments?since=$last" --jq '.[] | "\\(.user.login): \\(.body)"'
584942
- last=$now; sleep 30
584943
- done
584944
-
584945
- # Node script that emits events as they arrive (e.g. WebSocket listener)
584946
- node watch-for-events.js
584947
-
584948
- # Per-occurrence with a natural end: emit each CI check as it lands, exit when the run completes
584949
- prev=""
584950
- while true; do
584951
- s=$(gh pr checks 123 --json name,bucket)
584952
- cur=$(jq -r '.[] | select(.bucket!="pending") | "\\(.name): \\(.bucket)"' <<<"$s" | sort)
584953
- comm -13 <(echo "$prev") <(echo "$cur")
584954
- prev=$cur
584955
- jq -e 'all(.bucket!="pending")' <<<"$s" >/dev/null && break
584956
- sleep 30
584957
- done
584958
-
584959
- **Don't use an unbounded command for a single notification.** \`tail -f\`, \`inotifywait -m\`, and \`while true\` never exit on their own, so the monitor stays armed until timeout even after the event has fired. For "tell me when X is ready," use Bash \`run_in_background\` with an \`until\` loop instead (one notification, ends in seconds). Note that \`tail -f log | grep -m 1 ...\` does *not* fix this: if the log goes quiet after the match, \`tail\` never receives SIGPIPE and the pipeline hangs anyway.
584960
-
584961
- **Script quality:**
584962
- - Every pipe stage must flush per line or matches sit in its buffer unseen: \`grep\` needs \`--line-buffered\`, \`awk\` needs \`fflush()\`. \`head\` cannot flush at all \u2014 \`| head -N\` delivers nothing until N matches accumulate, then ends the stream.
584963
- - In poll loops, handle transient failures (\`curl ... || true\`) \u2014 one failed request shouldn't kill the monitor.
584964
- - Poll intervals: 30s+ for remote APIs (rate limits), 0.5-1s for local checks.
584965
- - Write a specific \`description\` \u2014 it appears in every notification ("errors in deploy.log" not "watching logs").
584966
- - Only stdout is the event stream. Stderr goes to the output file (readable via Read) but does not trigger notifications \u2014 for a command you run directly (e.g. \`python train.py 2>&1 | grep --line-buffered ...\`), merge stderr with \`2>&1\` so its failures reach your filter. (No effect on \`tail -f\` of an existing log \u2014 that file only contains what its writer redirected.)
584967
-
584968
- **Coverage \u2014 silence is not success.** When watching a job or process for an outcome, your filter must match every terminal state, not just the happy path. A monitor that greps only for the success marker stays silent through a crashloop, a hung process, or an unexpected exit \u2014 and silence looks identical to "still running." Before arming, ask: *if this process crashed right now, would my filter emit anything?* If not, widen it.
584969
-
584970
- # Wrong \u2014 silent on crash, hang, or any non-success exit
584971
- tail -f run.log | grep --line-buffered "elapsed_steps="
584972
-
584973
- # Right \u2014 one alternation covering progress + the failure signatures you'd act on
584974
- tail -f run.log | grep -E --line-buffered "elapsed_steps=|Traceback|Error|FAILED|assert|Killed|OOM"
584975
-
584976
- For poll loops checking job state, emit on every terminal status (\`succeeded|failed|cancelled|timeout\`), not just success. If you cannot confidently enumerate the failure signatures, broaden the grep alternation rather than narrow it \u2014 some extra noise is better than missing a crashloop.
584977
-
584978
- **Output volume**: Every stdout line is a conversation message, so the filter should be selective \u2014 but selective means "the lines you'd act on," not "only good news." Never pipe raw logs; filter to exactly the success and failure signals you care about. Monitors that produce too many events are automatically stopped; restart with a tighter filter if this happens.
584979
-
584980
- Stdout lines within 200ms are batched into a single notification, so multiline output from a single event groups naturally.
584981
-
584982
- The script runs in the same shell environment as Bash. Exit ends the watch (exit code is reported). Timeout \u2192 killed. Set \`persistent: true\` for session-length watches (PR monitoring, log tails) \u2014 the monitor runs until you call TaskStop or the session ends. Use TaskStop to cancel early.
584983
- **ws source** \u2014 open a WebSocket and stream each incoming text frame as an event. No shell, no polling: the server pushes, you get notified.
584984
- Monitor({
584985
- ws: {url: 'wss://events.example.com/stream', protocols: ['v1']},
584986
- description: 'deploy events',
584987
- })
584988
- Each text frame becomes one notification (multiline frames stay as one event). Binary frames are reported as \`[binary frame, N bytes]\` rather than passed through. Socket close ends the watch with the close code surfaced; errors are surfaced before close. Same rate limiting as bash \u2014 a firehose will be suppressed and eventually stopped, so subscribe to a filtered feed where one exists.
584989
- Prefer this over \`command: 'websocat wss://\u2026'\` \u2014 it avoids the extra process and line-buffering pitfalls. Use bash when you need to transform or filter frames with shell tools before they become events.`, inputSchema38, outputSchema35, activeMonitors, MonitorTool;
585256
+ var MONITOR_TOOL_NAME = "Monitor", DEFAULT_TIMEOUT_MS2 = 300000, MAX_TIMEOUT_MS2 = 3600000, MONITOR_DEADLINE_CAP_MS = 1800000, MONITOR_DEADLINE_CAP_PRINT_MS = 600000, COMMAND_DESC = "Shell command or script. Each stdout line is an event; exit ends the watch.", inputSchema38, outputSchema35, activeMonitors, MonitorTool;
584990
585257
  var init_MonitorTool = __esm(() => {
584991
585258
  init_v4();
584992
585259
  init_Tool();
585260
+ init_state();
585261
+ init_format();
585262
+ init_oauthLoginExpiry();
584993
585263
  inputSchema38 = lazySchema(() => exports_external.strictObject({
584994
585264
  command: exports_external.string().min(1).describe(COMMAND_DESC).optional(),
584995
585265
  ws: exports_external.object({
@@ -585013,10 +585283,10 @@ var init_MonitorTool = __esm(() => {
585013
585283
  maxResultSizeChars: 1e5,
585014
585284
  shouldDefer: true,
585015
585285
  async description() {
585016
- return DESCRIPTION19;
585286
+ return buildDescription2();
585017
585287
  },
585018
585288
  async prompt() {
585019
- return DESCRIPTION19;
585289
+ return buildDescription2();
585020
585290
  },
585021
585291
  get inputSchema() {
585022
585292
  return inputSchema38();
@@ -585038,8 +585308,7 @@ var init_MonitorTool = __esm(() => {
585038
585308
  },
585039
585309
  async call(input2, _context) {
585040
585310
  const taskId = `monitor-${randomUUID22()}`;
585041
- const persistent = input2.persistent ?? false;
585042
- const timeoutMs = persistent ? 0 : input2.timeout_ms ?? DEFAULT_TIMEOUT_MS2;
585311
+ const { timeoutMs, persistent } = normalizeMonitorInput(input2);
585043
585312
  const events2 = [];
585044
585313
  const emit2 = (line) => {
585045
585314
  events2.push(line);
@@ -585049,17 +585318,16 @@ var init_MonitorTool = __esm(() => {
585049
585318
  } else if (input2.ws) {
585050
585319
  streamWs(input2.ws.url, input2.ws.protocols, taskId, emit2).catch(() => {});
585051
585320
  }
585052
- if (timeoutMs > 0) {
585053
- const timer2 = setTimeout(() => {
585054
- const h5 = activeMonitors.get(taskId);
585055
- if (h5) {
585056
- h5.kill();
585057
- activeMonitors.delete(taskId);
585058
- }
585059
- }, timeoutMs);
585060
- if (typeof timer2 === "object" && timer2 && "unref" in timer2) {
585061
- timer2.unref();
585062
- }
585321
+ const timer2 = setTimeout(() => {
585322
+ fireMonitorDeadline({
585323
+ taskId,
585324
+ timeoutMs,
585325
+ eventCount: events2.length,
585326
+ emit: emit2
585327
+ });
585328
+ }, timeoutMs);
585329
+ if (typeof timer2 === "object" && timer2 && "unref" in timer2) {
585330
+ timer2.unref();
585063
585331
  }
585064
585332
  return {
585065
585333
  data: {
@@ -585099,7 +585367,7 @@ function isPushDisabled() {
585099
585367
  return true;
585100
585368
  }
585101
585369
  }
585102
- var PUSH_NOTIFICATION_TOOL_NAME = "PushNotification", DESCRIPTION20 = "Send a notification to the user via their terminal and, when Remote Control is connected, also push to their mobile device", inputSchema39, outputSchema36, noopTerminal, PushNotificationTool;
585370
+ var PUSH_NOTIFICATION_TOOL_NAME = "PushNotification", DESCRIPTION19 = "Send a notification to the user via their terminal and, when Remote Control is connected, also push to their mobile device", inputSchema39, outputSchema36, noopTerminal, PushNotificationTool;
585103
585371
  var init_PushNotificationTool = __esm(() => {
585104
585372
  init_v4();
585105
585373
  init_Tool();
@@ -585127,10 +585395,10 @@ var init_PushNotificationTool = __esm(() => {
585127
585395
  maxResultSizeChars: 1000,
585128
585396
  shouldDefer: true,
585129
585397
  async description() {
585130
- return DESCRIPTION20;
585398
+ return DESCRIPTION19;
585131
585399
  },
585132
585400
  async prompt() {
585133
- return DESCRIPTION20;
585401
+ return DESCRIPTION19;
585134
585402
  },
585135
585403
  get inputSchema() {
585136
585404
  return inputSchema39();
@@ -585451,7 +585719,7 @@ If you receive a JSON message with \`type: "shutdown_request"\` or \`type: "plan
585451
585719
  Approving shutdown terminates your process. Rejecting plan sends the teammate back to revise. Don't originate \`shutdown_request\` unless asked. Don't send structured JSON status messages \u2014 use TaskUpdate.
585452
585720
  `.trim();
585453
585721
  }
585454
- var DESCRIPTION21 = "Send a message to another agent";
585722
+ var DESCRIPTION20 = "Send a message to another agent";
585455
585723
  var init_prompt24 = __esm(() => {
585456
585724
  init_featureFlags();
585457
585725
  });
@@ -585972,7 +586240,7 @@ var init_SendMessageTool = __esm(() => {
585972
586240
  return { result: true };
585973
586241
  },
585974
586242
  async description() {
585975
- return DESCRIPTION21;
586243
+ return DESCRIPTION20;
585976
586244
  },
585977
586245
  async prompt() {
585978
586246
  return getPrompt6();
@@ -586220,7 +586488,7 @@ async function listCloudSessions() {
586220
586488
  async function listRemoteBridgeSessions() {
586221
586489
  return [];
586222
586490
  }
586223
- var LIST_AGENTS_TOOL_NAME = "ListAgents", DESCRIPTION22 = `Lists agents you can SendMessage to \u2014 in-process subagents you spawned, other local Claude sessions on this machine, your Claude sessions running in the cloud (when this session has cloud access), and (when Remote Control is connected) remote bridge sessions, which you can only reply to. Names are the address: send with \`SendMessage({to: "<name>", message: "..."})\`, copying the name exactly as a row prints it. Append a row's \` [ref]\` only when the bare name is not enough \u2014 two rows share it, or an error asks you to disambiguate.`, inputSchema41, AgentTypeSchema, outputSchema37, ListPeersTool;
586491
+ var LIST_AGENTS_TOOL_NAME = "ListAgents", DESCRIPTION21 = `Lists agents you can SendMessage to \u2014 in-process subagents you spawned, other local Claude sessions on this machine, your Claude sessions running in the cloud (when this session has cloud access), and (when Remote Control is connected) remote bridge sessions, which you can only reply to. Names are the address: send with \`SendMessage({to: "<name>", message: "..."})\`, copying the name exactly as a row prints it. Append a row's \` [ref]\` only when the bare name is not enough \u2014 two rows share it, or an error asks you to disambiguate.`, inputSchema41, AgentTypeSchema, outputSchema37, ListPeersTool;
586224
586492
  var init_ListPeersTool = __esm(() => {
586225
586493
  init_v4();
586226
586494
  init_Tool();
@@ -586246,10 +586514,10 @@ var init_ListPeersTool = __esm(() => {
586246
586514
  maxResultSizeChars: 50000,
586247
586515
  shouldDefer: true,
586248
586516
  async description() {
586249
- return DESCRIPTION22;
586517
+ return DESCRIPTION21;
586250
586518
  },
586251
586519
  async prompt() {
586252
- return DESCRIPTION22;
586520
+ return DESCRIPTION21;
586253
586521
  },
586254
586522
  get inputSchema() {
586255
586523
  return inputSchema41();
@@ -587070,9 +587338,20 @@ You MUST call the ${SYNTHETIC_OUTPUT_TOOL_NAME} tool exactly once at the end of
587070
587338
  model: agentModel,
587071
587339
  startTime: agentStartTime
587072
587340
  });
587341
+ const workflowAgentContext = {
587342
+ agentId,
587343
+ parentSessionId: getParentSessionId2(),
587344
+ agentType: "subagent",
587345
+ subagentName: agentDef.agentType,
587346
+ isBuiltIn: isBuiltInAgent(agentDef),
587347
+ workflowRunId: ctx.runId,
587348
+ workflowName: ctx.workflowName,
587349
+ invocationKind: "spawn",
587350
+ invocationEmitted: false
587351
+ };
587073
587352
  let messages;
587074
587353
  try {
587075
- messages = await drainGenerator(gen);
587354
+ messages = await runWithAgentContext(workflowAgentContext, () => drainGenerator(gen));
587076
587355
  } catch (e4) {
587077
587356
  const msg = `Agent "${opts.label ?? prompt.slice(0, 40)}" failed: ${e4.message}`;
587078
587357
  ctx.counters.failures.push(msg);
@@ -587358,6 +587637,9 @@ var WORKFLOW_AGENT_LIFETIME_CAP = 1000, WORKFLOW_PARALLEL_MAX_ITEMS = 4096, WORK
587358
587637
  var init_primitives = __esm(() => {
587359
587638
  init_runAgent();
587360
587639
  init_generalPurposeAgent();
587640
+ init_loadAgentsDir();
587641
+ init_agentContext();
587642
+ init_teammate();
587361
587643
  init_worktree();
587362
587644
  init_messages3();
587363
587645
  init_tokens();
@@ -588030,7 +588312,7 @@ function buildWorkflowProgressHandler(runId, seedPhases, emit2, onAgentEvent) {
588030
588312
  });
588031
588313
  };
588032
588314
  }
588033
- var import_react86, inputSchema42, outputSchema38, DESCRIPTION23 = `Run a multi-step workflow from a self-contained JavaScript script. The script runs in a sandboxed vm with access to primitives: agent(prompt, opts?) to spawn a subagent, parallel(items) for concurrent execution (max 4096 items, ~10 concurrent), pipeline(items, ...stages) for streaming, phase(title, fn?) to group agents (optional callback form: phase('title', async () => { ...parallel/agent... }) runs fn within the phase and returns its result), log(...args) for workflow-scoped logging, budget {total, remaining(), spent()} for token caps, and workflow(nameOrRef) / resolveWorkflow(name) for sub-workflows. Scripts are deterministic for resume (no Date/Math.random/import). Use the Workflow tool on substantive multi-agent tasks.
588315
+ var import_react86, inputSchema42, outputSchema38, DESCRIPTION22 = `Run a multi-step workflow from a self-contained JavaScript script. The script runs in a sandboxed vm with access to primitives: agent(prompt, opts?) to spawn a subagent, parallel(items) for concurrent execution (max 4096 items, ~10 concurrent), pipeline(items, ...stages) for streaming, phase(title, fn?) to group agents (optional callback form: phase('title', async () => { ...parallel/agent... }) runs fn within the phase and returns its result), log(...args) for workflow-scoped logging, budget {total, remaining(), spent()} for token caps, and workflow(nameOrRef) / resolveWorkflow(name) for sub-workflows. Scripts are deterministic for resume (no Date/Math.random/import). Use the Workflow tool on substantive multi-agent tasks.
588034
588316
 
588035
588317
  - Ultracode is on for the session (a system-reminder confirms it) \u2014 see **Ultracode** below.
588036
588318
 
@@ -588089,10 +588371,10 @@ var init_WorkflowTool = __esm(() => {
588089
588371
  async description() {
588090
588372
  const size = getInitialSettings()?.dynamicWorkflowSize ?? "medium";
588091
588373
  const sizeHint = size === "small" ? "When creating a dynamic workflow, prefer a small number of agents (~3)." : size === "large" ? "When creating a dynamic workflow, prefer a large number of agents (~12)." : "When creating a dynamic workflow, prefer a medium number of agents (~6).";
588092
- return `${DESCRIPTION23} ${sizeHint} (Per the dynamicWorkflowSize setting \u2014 advisory, not a cap.)`;
588374
+ return `${DESCRIPTION22} ${sizeHint} (Per the dynamicWorkflowSize setting \u2014 advisory, not a cap.)`;
588093
588375
  },
588094
588376
  async prompt() {
588095
- return `${DESCRIPTION23}
588377
+ return `${DESCRIPTION22}
588096
588378
 
588097
588379
  Use this tool to run a workflow script. The script must start with \`export const meta = { name, description, phases }\` and export a default async function: \`export default async ({ agent, parallel, pipeline, phase, log, budget, workflow, resolveWorkflow, args }) => { ... }\`.`;
588098
588380
  },
@@ -596448,7 +596730,8 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input2, toolUseConte
596448
596730
  contextModifier: toolContextModifier ? {
596449
596731
  toolUseID,
596450
596732
  modifyContext: toolContextModifier
596451
- } : undefined
596733
+ } : undefined,
596734
+ toolDuration: { toolName: tool.name, durationMs }
596452
596735
  });
596453
596736
  }
596454
596737
  if (!isMcpTool(tool)) {
@@ -596615,7 +596898,8 @@ async function checkPermissionsAndCallTool(tool, toolUseID, input2, toolUseConte
596615
596898
  toolUseResult: `Error: ${content}`,
596616
596899
  mcpMeta: toolUseContext.agentId ? undefined : error52 instanceof McpToolCallError_I_VERIFIED_THIS_IS_NOT_CODE_OR_FILEPATHS ? error52.mcpMeta : undefined,
596617
596900
  sourceToolAssistantUUID: assistantMessage.uuid
596618
- })
596901
+ }),
596902
+ toolDuration: { toolName: tool.name, durationMs }
596619
596903
  },
596620
596904
  ...hookMessages
596621
596905
  ];
@@ -596876,6 +597160,9 @@ class StreamingToolExecutor {
596876
597160
  if (update.contextModifier) {
596877
597161
  contextModifiers.push(update.contextModifier.modifyContext);
596878
597162
  }
597163
+ if (update.toolDuration) {
597164
+ tool.toolDuration = update.toolDuration;
597165
+ }
596879
597166
  }
596880
597167
  tool.results = messages;
596881
597168
  tool.contextModifiers = contextModifiers;
@@ -596907,8 +597194,10 @@ class StreamingToolExecutor {
596907
597194
  }
596908
597195
  if (tool.status === "completed" && tool.results) {
596909
597196
  tool.status = "yielded";
597197
+ let toolDuration = tool.toolDuration;
596910
597198
  for (const message of tool.results) {
596911
- yield { message, newContext: this.toolUseContext };
597199
+ yield { message, newContext: this.toolUseContext, toolDuration };
597200
+ toolDuration = undefined;
596912
597201
  }
596913
597202
  markToolUseAsComplete(this.toolUseContext, tool.id);
596914
597203
  } else if (tool.status === "executing" && !tool.isConcurrencySafe) {
@@ -597168,7 +597457,8 @@ async function* runTools(toolUseMessages, assistantMessages, canUseTool, toolUse
597168
597457
  }
597169
597458
  yield {
597170
597459
  message: update.message,
597171
- newContext: currentContext
597460
+ newContext: currentContext,
597461
+ ...update.toolDuration && { toolDuration: update.toolDuration }
597172
597462
  };
597173
597463
  }
597174
597464
  for (const block of blocks) {
@@ -597188,7 +597478,8 @@ async function* runTools(toolUseMessages, assistantMessages, canUseTool, toolUse
597188
597478
  }
597189
597479
  yield {
597190
597480
  message: update.message,
597191
- newContext: currentContext
597481
+ newContext: currentContext,
597482
+ ...update.toolDuration && { toolDuration: update.toolDuration }
597192
597483
  };
597193
597484
  }
597194
597485
  }
@@ -597223,7 +597514,8 @@ async function* runToolsSerially(toolUseMessages, assistantMessages, canUseTool,
597223
597514
  }
597224
597515
  yield {
597225
597516
  message: update.message,
597226
- newContext: currentContext
597517
+ newContext: currentContext,
597518
+ ...update.toolDuration && { toolDuration: update.toolDuration }
597227
597519
  };
597228
597520
  }
597229
597521
  markToolUseAsComplete2(toolUseContext, toolUse.id);
@@ -599744,7 +600036,8 @@ async function* queryLoop(params, consumedCommandUuids) {
599744
600036
  querySource,
599745
600037
  maxTurns,
599746
600038
  skipCacheWrite,
599747
- agentCacheTtlOverride
600039
+ agentCacheTtlOverride,
600040
+ compactionRequestKind
599748
600041
  } = params;
599749
600042
  const deps = params.deps ?? productionDeps();
599750
600043
  let state3 = {
@@ -599762,6 +600055,7 @@ async function* queryLoop(params, consumedCommandUuids) {
599762
600055
  };
599763
600056
  const budgetTracker = feature("TOKEN_BUDGET") ? createBudgetTracker() : null;
599764
600057
  let taskBudgetRemaining;
600058
+ let prevToolDurations;
599765
600059
  const config7 = buildQueryConfig();
599766
600060
  const pendingMemoryPrefetch = startRelevantMemoryPrefetch(state3.messages, state3.toolUseContext);
599767
600061
  while (true) {
@@ -599878,6 +600172,7 @@ async function* queryLoop(params, consumedCommandUuids) {
599878
600172
  const toolResults = [];
599879
600173
  const toolUseBlocks = [];
599880
600174
  let needsFollowUp = false;
600175
+ const toolDurations = [];
599881
600176
  queryCheckpoint("query_setup_start");
599882
600177
  const useStreamingToolExecution = config7.gates.streamingToolExecution;
599883
600178
  let streamingToolExecutor = useStreamingToolExecution ? new StreamingToolExecutor(toolUseContext.options.tools, canUseTool, toolUseContext) : null;
@@ -599960,6 +600255,10 @@ async function* queryLoop(params, consumedCommandUuids) {
599960
600255
  agentCacheTtlOverride,
599961
600256
  agentId: toolUseContext.agentId,
599962
600257
  addNotification: toolUseContext.addNotification,
600258
+ ...prevToolDurations !== undefined && { prevToolDurations },
600259
+ ...compactionRequestKind !== undefined && {
600260
+ compactionRequestKind
600261
+ },
599963
600262
  ...params.taskBudget && {
599964
600263
  taskBudget: {
599965
600264
  total: params.taskBudget.total,
@@ -600050,6 +600349,9 @@ async function* queryLoop(params, consumedCommandUuids) {
600050
600349
  }
600051
600350
  if (streamingToolExecutor && !toolUseContext.abortController.signal.aborted) {
600052
600351
  for (const result of streamingToolExecutor.getCompletedResults()) {
600352
+ if (result.toolDuration) {
600353
+ toolDurations.push(result.toolDuration);
600354
+ }
600053
600355
  if (result.message) {
600054
600356
  yield result.message;
600055
600357
  toolResults.push(...normalizeMessagesForAPI([result.message], toolUseContext.options.tools).filter((_4) => _4.type === "user"));
@@ -600397,6 +600699,9 @@ ${stopHookAdditionalContexts.join(`
600397
600699
  }
600398
600700
  const toolUpdates = streamingToolExecutor ? streamingToolExecutor.getRemainingResults() : runTools(toolUseBlocks, assistantMessages, canUseTool, toolUseContext);
600399
600701
  for await (const update of toolUpdates) {
600702
+ if (update.toolDuration) {
600703
+ toolDurations.push(update.toolDuration);
600704
+ }
600400
600705
  if (update.message) {
600401
600706
  yield update.message;
600402
600707
  if (update.message.type === "attachment" && update.message.attachment.type === "hook_stopped_continuation") {
@@ -600412,6 +600717,7 @@ ${stopHookAdditionalContexts.join(`
600412
600717
  }
600413
600718
  }
600414
600719
  queryCheckpoint("query_tool_execution_end");
600720
+ prevToolDurations = toolDurations.length > 0 ? [...toolDurations] : undefined;
600415
600721
  let nextPendingToolUseSummary;
600416
600722
  if (config7.gates.emitToolUseSummaries && toolUseBlocks.length > 0 && !toolUseContext.abortController.signal.aborted && !toolUseContext.agentId) {
600417
600723
  const lastAssistantMessage = assistantMessages.at(-1);
@@ -601418,7 +601724,8 @@ async function runForkedAgent({
601418
601724
  maxTurns,
601419
601725
  onMessage: onMessage2,
601420
601726
  skipTranscript,
601421
- skipCacheWrite
601727
+ skipCacheWrite,
601728
+ compactionRequestKind
601422
601729
  }) {
601423
601730
  const startTime2 = Date.now();
601424
601731
  const outputMessages = [];
@@ -601451,7 +601758,8 @@ async function runForkedAgent({
601451
601758
  maxOutputTokensOverride: maxOutputTokens,
601452
601759
  maxTurns,
601453
601760
  skipCacheWrite,
601454
- agentCacheTtlOverride
601761
+ agentCacheTtlOverride,
601762
+ compactionRequestKind
601455
601763
  })) {
601456
601764
  if (message.type === "stream_event") {
601457
601765
  if ("event" in message && message.event?.type === "message_delta" && message.event.usage) {
@@ -606471,7 +606779,8 @@ function mergeHookInstructions(userInstructions, hookInstructions) {
606471
606779
 
606472
606780
  ${hookInstructions}`;
606473
606781
  }
606474
- async function compactConversation(messages, context7, cacheSafeParams, suppressFollowUpQuestions, customInstructions, isAutoCompact = false, recompactionInfo) {
606782
+ async function compactConversation(messages, context7, cacheSafeParams, suppressFollowUpQuestions, customInstructions, isAutoCompact = false, recompactionInfo, thresholdSource) {
606783
+ const compactionRequestKind = getCompactionKind(isAutoCompact ? "auto" : "manual", thresholdSource);
606475
606784
  try {
606476
606785
  if (messages.length === 0) {
606477
606786
  throw new Error(ERROR_MESSAGE_NOT_ENOUGH_MESSAGES);
@@ -606513,7 +606822,8 @@ async function compactConversation(messages, context7, cacheSafeParams, suppress
606513
606822
  appState,
606514
606823
  context: context7,
606515
606824
  preCompactTokenCount,
606516
- cacheSafeParams: retryCacheSafeParams
606825
+ cacheSafeParams: retryCacheSafeParams,
606826
+ compactionRequestKind
606517
606827
  });
606518
606828
  summary = getAssistantMessageText(summaryResponse);
606519
606829
  if (!summary?.startsWith(PROMPT_TOO_LONG_ERROR_MESSAGE))
@@ -606670,6 +606980,9 @@ async function compactConversation(messages, context7, cacheSafeParams, suppress
606670
606980
  postCompactHookResult.userDisplayMessage
606671
606981
  ].filter(Boolean).join(`
606672
606982
  `);
606983
+ if (shouldSendContextCompactedHeader(recompactionInfo?.querySource ?? context7.options.querySource, context7.agentId)) {
606984
+ armPendingContextCompacted(getCompactionKind(isAutoCompact ? "auto" : "manual", getLastMainRequestId()));
606985
+ }
606673
606986
  return {
606674
606987
  boundaryMarker,
606675
606988
  summaryMessages,
@@ -606927,7 +607240,8 @@ async function streamCompactSummary({
606927
607240
  appState,
606928
607241
  context: context7,
606929
607242
  preCompactTokenCount,
606930
- cacheSafeParams
607243
+ cacheSafeParams,
607244
+ compactionRequestKind
606931
607245
  }) {
606932
607246
  const promptCacheSharingEnabled = getFeatureValue_CACHED_MAY_BE_STALE("tengu_compact_cache_prefix", true);
606933
607247
  const activityInterval = isSessionActivityTrackingActive() ? setInterval((statusSetter) => {
@@ -606945,7 +607259,8 @@ async function streamCompactSummary({
606945
607259
  forkLabel: "compact",
606946
607260
  maxTurns: 1,
606947
607261
  skipCacheWrite: true,
606948
- overrides: { abortController: context7.abortController }
607262
+ overrides: { abortController: context7.abortController },
607263
+ ...compactionRequestKind !== undefined && { compactionRequestKind }
606949
607264
  });
606950
607265
  const assistantMsg = getLastAssistantMessage(result.messages);
606951
607266
  const assistantText = assistantMsg ? getAssistantMessageText(assistantMsg) : null;
@@ -607008,6 +607323,7 @@ async function streamCompactSummary({
607008
607323
  hasAppendSystemPrompt: !!context7.options.appendSystemPrompt,
607009
607324
  maxOutputTokensOverride: Math.min(COMPACT_MAX_OUTPUT_TOKENS, getMaxOutputTokensForModel(context7.options.mainLoopModel)),
607010
607325
  querySource: "compact",
607326
+ ...compactionRequestKind !== undefined && { compactionRequestKind },
607011
607327
  agents: context7.options.agentDefinitions.activeAgents,
607012
607328
  mcpTools: [],
607013
607329
  effortValue: appState.effortValue
@@ -607219,6 +607535,7 @@ var init_compact = __esm(() => {
607219
607535
  init_uniqBy();
607220
607536
  init_sdk();
607221
607537
  init_state();
607538
+ init_gatewayHints();
607222
607539
  init_state();
607223
607540
  init_FileReadTool();
607224
607541
  init_prompt3();
@@ -607954,7 +608271,7 @@ async function autoCompactIfNeeded(messages, toolUseContext, cacheSafeParams, qu
607954
608271
  };
607955
608272
  }
607956
608273
  try {
607957
- const compactionResult = await compactConversation(messages, toolUseContext, cacheSafeParams, true, undefined, true, recompactionInfo);
608274
+ const compactionResult = await compactConversation(messages, toolUseContext, cacheSafeParams, true, undefined, true, recompactionInfo, "auto-compact-threshold");
607958
608275
  setLastSummarizedMessageId(undefined);
607959
608276
  runPostCompactCleanup(querySource);
607960
608277
  return {
@@ -624080,7 +624397,7 @@ var init_p_map = __esm(() => {
624080
624397
  });
624081
624398
 
624082
624399
  // src/tools/MCPTool/prompt.ts
624083
- var PROMPT10 = "", DESCRIPTION24 = "";
624400
+ var PROMPT10 = "", DESCRIPTION23 = "";
624084
624401
 
624085
624402
  // src/components/design-system/ProgressBar.tsx
624086
624403
  function ProgressBar(t0) {
@@ -624749,7 +625066,7 @@ var init_MCPTool = __esm(() => {
624749
625066
  name: "mcp",
624750
625067
  maxResultSizeChars: 1e5,
624751
625068
  async description() {
624752
- return DESCRIPTION24;
625069
+ return DESCRIPTION23;
624753
625070
  },
624754
625071
  async prompt() {
624755
625072
  return PROMPT10;
@@ -633798,7 +634115,7 @@ function getCacheControl({
633798
634115
  function querySourceMatchesPatterns(querySource, patterns) {
633799
634116
  return querySource !== undefined && patterns.some((pattern) => pattern.endsWith("*") ? querySource.startsWith(pattern.slice(0, -1)) : querySource === pattern);
633800
634117
  }
633801
- function isMainThreadQuerySource(querySource) {
634118
+ function isMainThreadQuerySource2(querySource) {
633802
634119
  return querySourceMatchesPatterns(querySource, MAIN_THREAD_QUERY_SOURCES);
633803
634120
  }
633804
634121
  function parsePromptCacheTtlEnv(value) {
@@ -633808,7 +634125,7 @@ function resolvePromptCacheTtlOverride(querySource, agentCacheTtlOverride, isUsi
633808
634125
  if (isEnvTruthy(process.env.FORCE_PROMPT_CACHING_5M)) {
633809
634126
  return { ttl: "5m", reason: "force_5m_env" };
633810
634127
  }
633811
- const isMainThread = isMainThreadQuerySource(querySource);
634128
+ const isMainThread = isMainThreadQuerySource2(querySource);
633812
634129
  const envTtl = parsePromptCacheTtlEnv(isMainThread ? process.env.CLAUDE_CODE_PROMPT_CACHE_TTL : process.env.CLAUDE_CODE_SUBAGENT_PROMPT_CACHE_TTL);
633813
634130
  if (envTtl !== undefined)
633814
634131
  return { ttl: envTtl, reason: "env" };
@@ -634065,7 +634382,7 @@ function getApiForceIdleTimeout() {
634065
634382
  const ms = parseInt(raw, 10);
634066
634383
  return Number.isFinite(ms) && ms > 0 ? ms : undefined;
634067
634384
  }
634068
- async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFromContext, onAttempt, captureRequest, originatingRequestId) {
634385
+ async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFromContext, onAttempt, captureRequest, originatingRequestId, gatewayHintWireValues) {
634069
634386
  const fallbackTimeoutMs = getNonstreamingFallbackTimeoutMs();
634070
634387
  const generator = withRetry(() => getAnthropicClient({
634071
634388
  maxRetries: 0,
@@ -634079,12 +634396,16 @@ async function* executeNonStreamingRequest(clientOptions, retryOptions, paramsFr
634079
634396
  onAttempt(attempt, start, retryParams.max_tokens);
634080
634397
  const adjustedParams = adjustParamsForNonStreaming(retryParams, MAX_NON_STREAMING_TOKENS);
634081
634398
  try {
634399
+ const hintHeaders = {};
634400
+ applyContextCompactedHeaders(hintHeaders, gatewayHintWireValues?.contextCompactedKindForWire, gatewayHintWireValues?.compactionRequestKindForWire);
634401
+ applyPrevToolDurationsHeader(hintHeaders, gatewayHintWireValues?.prevToolDurationsForWire);
634082
634402
  return await anthropic.beta.messages.create({
634083
634403
  ...adjustedParams,
634084
634404
  model: normalizeModelStringForAPI(adjustedParams.model)
634085
634405
  }, {
634086
634406
  signal: retryOptions.signal,
634087
- timeout: fallbackTimeoutMs
634407
+ timeout: fallbackTimeoutMs,
634408
+ ...Object.keys(hintHeaders).length > 0 ? { headers: hintHeaders } : {}
634088
634409
  });
634089
634410
  } catch (err2) {
634090
634411
  if (err2 instanceof APIUserAbortError)
@@ -634587,6 +634908,9 @@ ${deferredToolList}
634587
634908
  let research;
634588
634909
  let isFastModeRequest = isFastMode;
634589
634910
  let isAdvisorInProgress = false;
634911
+ const contextCompactedKindForWire = classifyQuerySource(options.querySource) === "main" && options.agentId === undefined ? consumePendingContextCompacted() : undefined;
634912
+ const compactionRequestKindForWire = options.compactionRequestKind;
634913
+ const prevToolDurationsForWire = options.prevToolDurations !== undefined ? buildPrevToolDurationsHeader(options.prevToolDurations) : undefined;
634590
634914
  try {
634591
634915
  let clearStreamIdleTimers = function() {
634592
634916
  if (streamIdleWarningTimer !== null) {
@@ -634643,20 +634967,23 @@ ${deferredToolList}
634643
634967
  }
634644
634968
  clientRequestId = getAPIProvider() === "firstParty" && isFirstPartyAnthropicBaseUrl() ? randomUUID33() : undefined;
634645
634969
  const incomingTrace = shouldPropagateTraceparent() ? getIncomingTraceContext() : undefined;
634970
+ const attemptHeaders = {
634971
+ ...clientRequestId && {
634972
+ [CLIENT_REQUEST_ID_HEADER]: clientRequestId
634973
+ },
634974
+ ...incomingTrace?.traceparent && {
634975
+ traceparent: incomingTrace.traceparent
634976
+ },
634977
+ ...incomingTrace?.tracestate && {
634978
+ tracestate: incomingTrace.tracestate
634979
+ }
634980
+ };
634981
+ applyContextCompactedHeaders(attemptHeaders, contextCompactedKindForWire, compactionRequestKindForWire);
634982
+ applyPrevToolDurationsHeader(attemptHeaders, prevToolDurationsForWire);
634646
634983
  const result = await anthropic.beta.messages.create({ ...params, stream: true }, {
634647
634984
  signal,
634648
634985
  ...getApiForceIdleTimeout() !== undefined ? { timeout: false } : {},
634649
- headers: {
634650
- ...clientRequestId && {
634651
- [CLIENT_REQUEST_ID_HEADER]: clientRequestId
634652
- },
634653
- ...incomingTrace?.traceparent && {
634654
- traceparent: incomingTrace.traceparent
634655
- },
634656
- ...incomingTrace?.tracestate && {
634657
- tracestate: incomingTrace.tracestate
634658
- }
634659
- }
634986
+ headers: attemptHeaders
634660
634987
  }).withResponse();
634661
634988
  queryCheckpoint("query_response_headers_received");
634662
634989
  streamRequestId = result.request_id;
@@ -635110,7 +635437,11 @@ ${deferredToolList}
635110
635437
  }, paramsFromContext, (attempt, _startTime, tokens) => {
635111
635438
  attemptNumber = attempt;
635112
635439
  maxOutputTokens = tokens;
635113
- }, (params) => captureAPIRequest(params, options.querySource), streamRequestId);
635440
+ }, (params) => captureAPIRequest(params, options.querySource), streamRequestId, {
635441
+ contextCompactedKindForWire,
635442
+ compactionRequestKindForWire,
635443
+ prevToolDurationsForWire
635444
+ });
635114
635445
  const m5 = {
635115
635446
  message: {
635116
635447
  ...result,
@@ -635167,7 +635498,11 @@ ${deferredToolList}
635167
635498
  }, paramsFromContext, (attempt, _startTime, tokens) => {
635168
635499
  attemptNumber = attempt;
635169
635500
  maxOutputTokens = tokens;
635170
- }, (params) => captureAPIRequest(params, options.querySource), failedRequestId);
635501
+ }, (params) => captureAPIRequest(params, options.querySource), failedRequestId, {
635502
+ contextCompactedKindForWire,
635503
+ compactionRequestKindForWire,
635504
+ prevToolDurationsForWire
635505
+ });
635171
635506
  const m5 = {
635172
635507
  message: {
635173
635508
  ...result,
@@ -635658,6 +635993,7 @@ var init_claude = __esm(() => {
635658
635993
  init_utils9();
635659
635994
  init_vcr();
635660
635995
  init_client9();
635996
+ init_gatewayHints();
635661
635997
  init_errors10();
635662
635998
  init_logging2();
635663
635999
  init_rawApiBodies();
@@ -638903,6 +639239,9 @@ function getValueFromInput(input2) {
638903
639239
  function isInputModeCharacter(input2) {
638904
639240
  return input2 === "!";
638905
639241
  }
639242
+ function shouldTriggerModeSwitch(keystroke, isAtStart, currentMode) {
639243
+ return currentMode !== undefined && isAtStart && isInputModeCharacter(keystroke) && currentMode !== getModeFromInput(keystroke);
639244
+ }
638906
639245
 
638907
639246
  // src/projectOnboardingState.ts
638908
639247
  import { join as join128 } from "path";
@@ -641087,7 +641426,8 @@ function useTextInput({
641087
641426
  onOffsetChange,
641088
641427
  inputFilter,
641089
641428
  inlineGhostText,
641090
- dim: dim2
641429
+ dim: dim2,
641430
+ getInputMode
641091
641431
  }) {
641092
641432
  if (env4.terminal === "Apple_Terminal") {
641093
641433
  prewarmModifiers();
@@ -641347,7 +641687,7 @@ function useTextInput({
641347
641687
  if (echo !== null)
641348
641688
  pushScreenReaderAnnouncement(echo);
641349
641689
  }
641350
- if (cursor.isAtStart() && isInputModeCharacter(input2)) {
641690
+ if (shouldTriggerModeSwitch(input2, cursor.isAtStart(), getInputMode?.())) {
641351
641691
  return cursor.insert(text2).left();
641352
641692
  }
641353
641693
  return cursor.insert(text2);
@@ -642114,6 +642454,7 @@ function TextInput(props) {
642114
642454
  onOffsetChange: props.onChangeCursorOffset,
642115
642455
  inputFilter: props.inputFilter,
642116
642456
  inlineGhostText: props.inlineGhostText,
642457
+ getInputMode: props.getInputMode,
642117
642458
  dim: source_default.dim
642118
642459
  });
642119
642460
  return /* @__PURE__ */ jsx_runtime167.jsx(ThemedBox_default, {
@@ -709120,7 +709461,7 @@ function _temp148(s4) {
709120
709461
  }
709121
709462
  async function handleFastModeShortcut(enable2, getAppState, setAppState) {
709122
709463
  const unavailableReason = getFastModeUnavailableReason();
709123
- if (unavailableReason) {
709464
+ if (enable2 && unavailableReason) {
709124
709465
  return `Fast mode unavailable: ${unavailableReason}`;
709125
709466
  }
709126
709467
  if (enable2) {
@@ -730529,7 +730870,7 @@ function urlMatchesPattern2(url3, pattern) {
730529
730870
  const regexStr = escaped.replace(/\*/g, ".*");
730530
730871
  return new RegExp(`^${regexStr}$`).test(url3);
730531
730872
  }
730532
- function sanitizeHeaderValue(value) {
730873
+ function sanitizeHeaderValue2(value) {
730533
730874
  return value.replace(/[\r\n\x00]/g, "");
730534
730875
  }
730535
730876
  function interpolateEnvVars(value, allowedEnvVars) {
@@ -730541,7 +730882,7 @@ function interpolateEnvVars(value, allowedEnvVars) {
730541
730882
  }
730542
730883
  return process.env[varName] ?? "";
730543
730884
  });
730544
- return sanitizeHeaderValue(interpolated);
730885
+ return sanitizeHeaderValue2(interpolated);
730545
730886
  }
730546
730887
  async function execHttpHook(hook, _hookEvent, jsonInput, signal) {
730547
730888
  const policy = getHttpHookPolicy();
@@ -776925,7 +777266,7 @@ var init_PromptInputStashNotice = __esm(() => {
776925
777266
  function stripLoneSurrogates2(text2) {
776926
777267
  if (isWellFormed && isWellFormed(text2))
776927
777268
  return text2;
776928
- return text2.replace(LONE_SURROGATE_RE, "");
777269
+ return text2.replace(LONE_SURROGATE_RE2, "");
776929
777270
  }
776930
777271
  function stripAnsiSequences(text2) {
776931
777272
  let result = text2;
@@ -776949,11 +777290,11 @@ function clampBannerTextWidth(maxWidth) {
776949
777290
  function sanitizeAndClampBannerText(text2, maxWidth) {
776950
777291
  return truncateToWidth(sanitizeBannerText(text2), clampBannerTextWidth(maxWidth));
776951
777292
  }
776952
- var BANNER_TEXT_MAX_WIDTH = 24, ANSI_STRIP_PASSES = 4, ANSI_SEQUENCE_RE, LONE_SURROGATE_RE, CONTROL_FORMAT_RE, isWellFormed;
777293
+ var BANNER_TEXT_MAX_WIDTH = 24, ANSI_STRIP_PASSES = 4, ANSI_SEQUENCE_RE, LONE_SURROGATE_RE2, CONTROL_FORMAT_RE, isWellFormed;
776953
777294
  var init_sanitizeBannerText = __esm(() => {
776954
777295
  init_truncate();
776955
777296
  ANSI_SEQUENCE_RE = /\x1b\[[\x30-\x3f]*[\x20-\x2f]*[\x40-\x7e]|\x1b[\]PX^_][^\x1b\x07]*(?:\x07|\x1b\\)/g;
776956
- LONE_SURROGATE_RE = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
777297
+ LONE_SURROGATE_RE2 = /[\uD800-\uDBFF](?![\uDC00-\uDFFF])|(?<![\uD800-\uDBFF])[\uDC00-\uDFFF]/g;
776957
777298
  CONTROL_FORMAT_RE = /[\p{Cc}\p{Cf}\u2028\u2029]+/gu;
776958
777299
  isWellFormed = typeof String.prototype.isWellFormed === "function" ? Function.prototype.call.bind(String.prototype.isWellFormed) : undefined;
776959
777300
  });
@@ -777919,14 +778260,14 @@ function PromptInput({
777919
778260
  abortSpeculation(setAppState);
777920
778261
  const isSingleCharInsertion = value.length === input2.length + 1;
777921
778262
  const insertedAtStart = cursorOffset === 0;
777922
- const mode2 = getModeFromInput(value);
777923
- if (insertedAtStart && mode2 !== "prompt") {
778263
+ const detectedMode = getModeFromInput(value);
778264
+ if (insertedAtStart && detectedMode !== "prompt" && detectedMode !== mode) {
777924
778265
  if (isSingleCharInsertion) {
777925
- onModeChange(mode2);
778266
+ onModeChange(detectedMode);
777926
778267
  return;
777927
778268
  }
777928
778269
  if (input2.length === 0) {
777929
- onModeChange(mode2);
778270
+ onModeChange(detectedMode);
777930
778271
  const valueWithoutMode = getValueFromInput(value).replaceAll("\t", " ");
777931
778272
  pushToBuffer(input2, cursorOffset, pastedContents);
777932
778273
  trackAndSetInput(valueWithoutMode);
@@ -777943,7 +778284,7 @@ function PromptInput({
777943
778284
  footerSelection: null
777944
778285
  });
777945
778286
  trackAndSetInput(processedValue);
777946
- }, [trackAndSetInput, onModeChange, input2, cursorOffset, pushToBuffer, pastedContents, dismissStashHint, setAppState]);
778287
+ }, [trackAndSetInput, onModeChange, input2, cursorOffset, mode, pushToBuffer, pastedContents, dismissStashHint, setAppState]);
777947
778288
  const {
777948
778289
  resetHistory,
777949
778290
  onHistoryUp,
@@ -779041,7 +779382,8 @@ function PromptInput({
779041
779382
  } : undefined,
779042
779383
  highlights: combinedHighlights,
779043
779384
  inlineGhostText,
779044
- inputFilter: lazySpaceInputFilter
779385
+ inputFilter: lazySpaceInputFilter,
779386
+ getInputMode: () => mode
779045
779387
  };
779046
779388
  const getBorderColor = () => {
779047
779389
  const modeColors = {
@@ -816520,7 +816862,7 @@ var init_verifyContent = __esm(() => {
816520
816862
  function registerVerifySkill() {
816521
816863
  registerBundledSkill({
816522
816864
  name: "verify",
816523
- description: DESCRIPTION25,
816865
+ description: DESCRIPTION24,
816524
816866
  userInvocable: true,
816525
816867
  files: SKILL_FILES,
816526
816868
  async getPromptForCommand(args) {
@@ -816536,13 +816878,13 @@ ${args}`);
816536
816878
  }
816537
816879
  });
816538
816880
  }
816539
- var frontmatter, SKILL_BODY, DESCRIPTION25;
816881
+ var frontmatter, SKILL_BODY, DESCRIPTION24;
816540
816882
  var init_verify = __esm(() => {
816541
816883
  init_frontmatterParser();
816542
816884
  init_bundledSkills();
816543
816885
  init_verifyContent();
816544
816886
  ({ frontmatter, content: SKILL_BODY } = parseFrontmatter(SKILL_MD));
816545
- DESCRIPTION25 = typeof frontmatter.description === "string" ? frontmatter.description : "Verify a code change does what it should by running the app.";
816887
+ DESCRIPTION24 = typeof frontmatter.description === "string" ? frontmatter.description : "Verify a code change does what it should by running the app.";
816546
816888
  });
816547
816889
 
816548
816890
  // src/skills/bundled/dream.js
@@ -831528,7 +831870,7 @@ var _FEATURE_ALLOWLIST = new Set([
831528
831870
  var feature2 = (name3) => _FEATURE_ALLOWLIST.has(name3);
831529
831871
  if (typeof globalThis.MACRO === "undefined") {
831530
831872
  globalThis.MACRO = {
831531
- VERSION: "2.1.270",
831873
+ VERSION: "2.1.273",
831532
831874
  BINARY_NAME: "occ",
831533
831875
  BUILD_TIME: new Date().toISOString(),
831534
831876
  FEEDBACK_CHANNEL: "",