@atlasharness/atlascode 0.1.77 → 0.1.79

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 (2) hide show
  1. package/dist/cli.js +531 -124
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -26844,24 +26844,47 @@ var init_params = __esm(() => {
26844
26844
  });
26845
26845
 
26846
26846
  // src/modelprovider/types.ts
26847
- var APIError2, APIConnectionError2, APIConnectionTimeoutError2;
26847
+ var APIError2, AuthenticationError2, NotFoundError2, APIConnectionError2, APIConnectionTimeoutError2, APIUserAbortError2;
26848
26848
  var init_types2 = __esm(() => {
26849
26849
  APIError2 = class APIError2 extends Error {
26850
26850
  status;
26851
+ code;
26852
+ headers;
26851
26853
  error;
26852
- constructor(message, status, error) {
26853
- super(message);
26854
+ constructor(message, statusOrOpts, error) {
26855
+ super(message ?? "API error");
26854
26856
  this.name = "APIError";
26855
- if (status !== undefined)
26856
- this.status = status;
26857
- if (error !== undefined)
26858
- this.error = error;
26857
+ if (typeof statusOrOpts === "number") {
26858
+ if (statusOrOpts !== undefined)
26859
+ this.status = statusOrOpts;
26860
+ if (error !== undefined)
26861
+ this.error = error;
26862
+ } else if (statusOrOpts) {
26863
+ if (statusOrOpts.status !== undefined)
26864
+ this.status = statusOrOpts.status;
26865
+ if (statusOrOpts.code !== undefined)
26866
+ this.code = statusOrOpts.code;
26867
+ if (statusOrOpts.headers !== undefined)
26868
+ this.headers = statusOrOpts.headers;
26869
+ if (statusOrOpts.error !== undefined)
26870
+ this.error = statusOrOpts.error;
26871
+ }
26872
+ }
26873
+ };
26874
+ AuthenticationError2 = class AuthenticationError2 extends APIError2 {
26875
+ constructor(message, opts) {
26876
+ super(message, opts);
26877
+ this.name = "AuthenticationError";
26859
26878
  }
26860
26879
  };
26880
+ NotFoundError2 = class NotFoundError2 extends APIError2 {
26881
+ };
26861
26882
  APIConnectionError2 = class APIConnectionError2 extends APIError2 {
26862
26883
  };
26863
26884
  APIConnectionTimeoutError2 = class APIConnectionTimeoutError2 extends APIConnectionError2 {
26864
26885
  };
26886
+ APIUserAbortError2 = class APIUserAbortError2 extends APIError2 {
26887
+ };
26865
26888
  });
26866
26889
 
26867
26890
  // src/modelprovider/errorUtils.ts
@@ -28846,7 +28869,9 @@ var init_hookEvents = __esm(() => {
28846
28869
  "CwdChanged",
28847
28870
  "FileChanged",
28848
28871
  "PreModelSwitch",
28849
- "PostModelSwitch"
28872
+ "PostModelSwitch",
28873
+ "DirectoryAdded",
28874
+ "MessageDisplay"
28850
28875
  ];
28851
28876
  });
28852
28877
 
@@ -28994,6 +29019,9 @@ async function getMatchingHooks(hookEvent, hookInput) {
28994
29019
  case "PostModelSwitch":
28995
29020
  matchQuery = hookInput.new_model;
28996
29021
  break;
29022
+ case "DirectoryAdded":
29023
+ matchQuery = hookInput.directory;
29024
+ break;
28997
29025
  default:
28998
29026
  break;
28999
29027
  }
@@ -29107,6 +29135,8 @@ function interpretHookOutput(p) {
29107
29135
  result.output = "";
29108
29136
  if (json.systemMessage)
29109
29137
  result.systemMessage = json.systemMessage;
29138
+ if (json.terminalSequence)
29139
+ result.terminalSequence = json.terminalSequence;
29110
29140
  } catch {}
29111
29141
  }
29112
29142
  if (!p.aborted && p.code === 2 && !jsonParsed && !result.blockingError) {
@@ -29118,8 +29148,14 @@ function interpretHookOutput(p) {
29118
29148
  return result;
29119
29149
  }
29120
29150
  function mergeAggregated(acc, r) {
29121
- if (r.blockingError && !acc.blockingError)
29151
+ if (r.terminalSequence) {
29152
+ acc.terminalSequence = (acc.terminalSequence ?? "") + r.terminalSequence;
29153
+ }
29154
+ if (r.blockingError && !acc.blockingError) {
29122
29155
  acc.blockingError = r.blockingError;
29156
+ if (r.continueOnBlock)
29157
+ acc.continueOnBlock = true;
29158
+ }
29123
29159
  if (r.preventContinuation)
29124
29160
  acc.preventContinuation = true;
29125
29161
  if (r.stopReason && !acc.stopReason)
@@ -29142,13 +29178,19 @@ ${r.additionalContext}` : r.additionalContext;
29142
29178
  function runOneHook(m, port, env, signal, options) {
29143
29179
  const cmd = m.hook;
29144
29180
  const timeoutMs = cmd.timeoutMs ?? options.timeoutMs ?? HOOK_EXECUTION_TIMEOUT_MS;
29145
- return port.runCommand(cmd.command, env, signal, timeoutMs).then((exec) => interpretHookOutput({
29146
- command: cmd.command,
29147
- stdout: exec.stdout,
29148
- stderr: exec.stderr,
29149
- code: exec.code,
29150
- aborted: exec.aborted
29151
- }), (e) => ({
29181
+ return port.runCommand(cmd.command, env, signal, timeoutMs).then((exec) => {
29182
+ const result = interpretHookOutput({
29183
+ command: cmd.command,
29184
+ stdout: exec.stdout,
29185
+ stderr: exec.stderr,
29186
+ code: exec.code,
29187
+ aborted: exec.aborted
29188
+ });
29189
+ if (result.blockingError && cmd.continueOnBlock === true) {
29190
+ result.continueOnBlock = true;
29191
+ }
29192
+ return result;
29193
+ }, (e) => ({
29152
29194
  command: cmd.command,
29153
29195
  status: -1,
29154
29196
  succeeded: false,
@@ -29172,6 +29214,11 @@ async function runHooks(hookEvent, hookInput, options = {}) {
29172
29214
  results.push(result);
29173
29215
  mergeAggregated(aggregated, result);
29174
29216
  }
29217
+ if (aggregated.terminalSequence) {
29218
+ try {
29219
+ process.stdout.write(aggregated.terminalSequence);
29220
+ } catch {}
29221
+ }
29175
29222
  return aggregated;
29176
29223
  }
29177
29224
  async function runPreToolUseHooks(toolName, toolInput, toolUseID, options = {}) {
@@ -29319,6 +29366,7 @@ var init_hooksSchema = __esm(() => {
29319
29366
  once: boolean2().optional(),
29320
29367
  async: boolean2().optional(),
29321
29368
  asyncRewake: boolean2().optional(),
29369
+ continueOnBlock: boolean2().optional(),
29322
29370
  if: string2().optional()
29323
29371
  }).passthrough();
29324
29372
  PromptHookSchema = object({
@@ -29395,18 +29443,53 @@ var SettingsSchema = () => object({
29395
29443
  defaultShell: union([literal("bash"), literal("powershell")]).optional(),
29396
29444
  skipWebFetchPreflight: boolean2().optional(),
29397
29445
  search: object({ tavilyApiKey: string2().optional() }).optional(),
29398
- tui: object({ fullscreen: boolean2().optional() }).optional()
29446
+ tui: object({ fullscreen: boolean2().optional() }).optional(),
29447
+ skillOverrides: union([
29448
+ literal("off"),
29449
+ literal("user-invocable-only"),
29450
+ literal("name-only")
29451
+ ]).optional()
29399
29452
  }).passthrough();
29400
29453
  var init_types3 = __esm(() => {
29401
29454
  init_zod();
29402
29455
  init_hooksSchema();
29403
29456
  });
29404
29457
 
29458
+ // src/engine/config/restrictedMode.ts
29459
+ function isRestrictedMode() {
29460
+ return restrictedOverride ?? isEnvTruthy(process.env.ATLAS_RESTRICTED);
29461
+ }
29462
+ function setRestrictedMode(enabled) {
29463
+ restrictedOverride = enabled;
29464
+ }
29465
+ function resetRestrictedMode() {
29466
+ restrictedOverride = undefined;
29467
+ }
29468
+ function isSettingsSourceIgnoredInRestricted(source) {
29469
+ if (!isRestrictedMode())
29470
+ return false;
29471
+ return source === "userSettings" || source === "projectSettings" || source === "localSettings";
29472
+ }
29473
+ function restrictedBypassError(opts) {
29474
+ if (!isRestrictedMode())
29475
+ return null;
29476
+ if (opts.permissionMode === "bypassPermissions" || opts.allowDangerouslySkipPermissions === true || opts.dangerouslySkipPermissions === true) {
29477
+ return "--restricted mode does not allow bypassPermissions or --dangerously-skip-permissions for security reasons";
29478
+ }
29479
+ return null;
29480
+ }
29481
+ var restrictedOverride;
29482
+ var init_restrictedMode = __esm(() => {
29483
+ init_shared();
29484
+ });
29485
+
29405
29486
  // src/engine/config/constants.ts
29406
29487
  function getEnabledSettingSources() {
29407
29488
  const result = new Set(ALLOWED_SETTING_SOURCES);
29408
29489
  result.add("policySettings");
29409
29490
  result.add("flagSettings");
29491
+ if (isRestrictedMode())
29492
+ result.delete("userSettings");
29410
29493
  return Array.from(result);
29411
29494
  }
29412
29495
  function isSettingSourceEnabled(source) {
@@ -29415,6 +29498,7 @@ function isSettingSourceEnabled(source) {
29415
29498
  }
29416
29499
  var SETTING_SOURCES, ALLOWED_SETTING_SOURCES;
29417
29500
  var init_constants3 = __esm(() => {
29501
+ init_restrictedMode();
29418
29502
  SETTING_SOURCES = [
29419
29503
  "userSettings",
29420
29504
  "projectSettings",
@@ -30058,11 +30142,9 @@ var init_permissionRuleParser = __esm(() => {
30058
30142
 
30059
30143
  // src/permissions/mcpRuleNames.ts
30060
30144
  function normalizeNameForMCP(name) {
30061
- let normalized = name.replace(/[^a-zA-Z0-9_-]/g, "_");
30062
- if (name.startsWith(CLAUDEAI_SERVER_PREFIX)) {
30063
- normalized = normalized.replace(/_+/g, "_").replace(/^_|_$/g, "");
30064
- }
30065
- return normalized;
30145
+ const folded = name.replace(/[^a-zA-Z0-9_-]/g, "_");
30146
+ const normalized = folded.replace(/_+/g, "_").replace(/^_|_$/g, "");
30147
+ return normalized === "" ? folded : normalized;
30066
30148
  }
30067
30149
  function mcpInfoFromString(toolString) {
30068
30150
  const parts = toolString.split("__");
@@ -30082,7 +30164,6 @@ function buildMcpToolName(serverName, toolName) {
30082
30164
  function getToolNameForPermissionCheck(tool) {
30083
30165
  return tool.mcpInfo ? buildMcpToolName(tool.mcpInfo.serverName, tool.mcpInfo.toolName) : tool.name;
30084
30166
  }
30085
- var CLAUDEAI_SERVER_PREFIX = "claude.ai ";
30086
30167
 
30087
30168
  // src/permissions/ruleMatching.ts
30088
30169
  function permissionRuleSourceDisplayString(source) {
@@ -31913,6 +31994,8 @@ function getSettingsForSource(source) {
31913
31994
  return result;
31914
31995
  }
31915
31996
  function getSettingsForSourceUncached(source) {
31997
+ if (isSettingsSourceIgnoredInRestricted(source))
31998
+ return null;
31916
31999
  if (source === "policySettings") {
31917
32000
  return loadManagedFileSettings().settings;
31918
32001
  }
@@ -31925,6 +32008,11 @@ function getPolicySettingsOrigin() {
31925
32008
  return settings ? "file" : null;
31926
32009
  }
31927
32010
  function updateSettingsForSource(source, settings) {
32011
+ if (isSettingsSourceIgnoredInRestricted(source)) {
32012
+ return {
32013
+ error: new Error(`Settings source ${source} is ignored in restricted mode (--restricted / ATLAS_RESTRICTED)`)
32014
+ };
32015
+ }
31928
32016
  if (source === "policySettings" || source === "flagSettings") {
31929
32017
  return { error: null };
31930
32018
  }
@@ -32087,6 +32175,7 @@ var init_settings = __esm(() => {
32087
32175
  init_zod();
32088
32176
  init_configRoot();
32089
32177
  init_constants3();
32178
+ init_restrictedMode();
32090
32179
  init_managedPath();
32091
32180
  init_settingsCache();
32092
32181
  init_types3();
@@ -32291,6 +32380,7 @@ var init_autoCompactOverrides = __esm(() => {
32291
32380
  var init_config = __esm(() => {
32292
32381
  init_types3();
32293
32382
  init_constants3();
32383
+ init_restrictedMode();
32294
32384
  init_settingsCache();
32295
32385
  init_managedPath();
32296
32386
  init_configRoot();
@@ -36515,11 +36605,9 @@ var init_killShellTasks = __esm(() => {
36515
36605
 
36516
36606
  // src/engine/tools/mcp.ts
36517
36607
  function normalizeNameForMCP2(name) {
36518
- let normalized = name.replace(/[^a-zA-Z0-9_-]/g, "_");
36519
- if (name.startsWith(CLAUDEAI_SERVER_PREFIX2)) {
36520
- normalized = normalized.replace(/_+/g, "_").replace(/^_|_$/g, "");
36521
- }
36522
- return normalized;
36608
+ const folded = name.replace(/[^a-zA-Z0-9_-]/g, "_");
36609
+ const normalized = folded.replace(/_+/g, "_").replace(/^_|_$/g, "");
36610
+ return normalized === "" ? folded : normalized;
36523
36611
  }
36524
36612
  function mcpInfoFromString2(toolString) {
36525
36613
  const parts = toolString.split("__");
@@ -36601,7 +36689,7 @@ function buildMcpTool(conn, d) {
36601
36689
  }
36602
36690
  };
36603
36691
  }
36604
- var CLAUDEAI_SERVER_PREFIX2 = "claude.ai ", MCP_MAX_RESULT_SIZE_CHARS = 1e5, PERMISSIVE_INPUT_SCHEMA;
36692
+ var MCP_MAX_RESULT_SIZE_CHARS = 1e5, PERMISSIVE_INPUT_SCHEMA;
36605
36693
  var init_mcp = __esm(() => {
36606
36694
  PERMISSIVE_INPUT_SCHEMA = {
36607
36695
  type: "object",
@@ -37120,14 +37208,24 @@ function isAscendToolsEnabled(env = process.env) {
37120
37208
  }
37121
37209
  function getAllBaseTools(deps = {}) {
37122
37210
  const env = deps.env ?? process.env;
37211
+ const restricted = isRestrictedMode();
37123
37212
  const pool = [AgentTool];
37124
37213
  if (deps.baseTools)
37125
37214
  pool.push(...deps.baseTools);
37126
- if (deps.ascendTools && isAscendToolsEnabled(env))
37215
+ if (deps.ascendTools && isAscendToolsEnabled(env) && !restricted) {
37127
37216
  pool.push(...deps.ascendTools);
37217
+ }
37128
37218
  if (deps.mcpTools)
37129
37219
  pool.push(...deps.mcpTools);
37130
- return uniqByName(pool);
37220
+ const assembled = uniqByName(pool);
37221
+ if (!restricted)
37222
+ return assembled;
37223
+ const stripped = new Set([
37224
+ ...SHELL_TOOL_NAMES,
37225
+ WEB_FETCH_TOOL_NAME,
37226
+ AGENT_TOOL_NAME
37227
+ ]);
37228
+ return assembled.filter((t) => !stripped.has(t.name));
37131
37229
  }
37132
37230
  function uniqByName(tools) {
37133
37231
  const seen = new Set;
@@ -37159,7 +37257,9 @@ function parseToolPreset(preset) {
37159
37257
  var TOOL_PRESETS;
37160
37258
  var init_toolRegistry = __esm(() => {
37161
37259
  init_permissions3();
37260
+ init_config();
37162
37261
  init_AgentTool();
37262
+ init_toolNames();
37163
37263
  TOOL_PRESETS = ["default"];
37164
37264
  });
37165
37265
 
@@ -78386,6 +78486,21 @@ var init_mcpFetch = __esm(() => {
78386
78486
  function getConnectionTimeoutMs() {
78387
78487
  return parseInt(process.env.MCP_TIMEOUT || "", 10) || 30000;
78388
78488
  }
78489
+ function getMcpConnectBackoffMs(env = process.env) {
78490
+ const raw = env.ATLAS_MCP_CONNECT_BACKOFF_MS;
78491
+ if (raw === undefined || raw === "")
78492
+ return DEFAULT_MCP_CONNECT_BACKOFF_MS;
78493
+ const parsed = Number(raw);
78494
+ if (!Number.isFinite(parsed))
78495
+ return DEFAULT_MCP_CONNECT_BACKOFF_MS;
78496
+ return Math.max(0, parsed);
78497
+ }
78498
+ function mcpConnectBackoffDelayMs(failureCount, baseMs = getMcpConnectBackoffMs()) {
78499
+ if (failureCount <= 0 || baseMs <= 0)
78500
+ return 0;
78501
+ const raw = baseMs * 2 ** (failureCount - 1);
78502
+ return Math.min(raw, MAX_MCP_CONNECT_BACKOFF_MS);
78503
+ }
78389
78504
  function isTerminalConnectionError(msg) {
78390
78505
  return msg.includes("ECONNRESET") || msg.includes("ETIMEDOUT") || msg.includes("EPIPE") || msg.includes("EHOSTUNREACH") || msg.includes("ECONNREFUSED") || msg.includes("Body Timeout Error") || msg.includes("terminated") || msg.includes("SSE stream disconnected") || msg.includes("Failed to reconnect SSE stream");
78391
78506
  }
@@ -78434,6 +78549,7 @@ async function terminateChild(name, child) {
78434
78549
  function createMcpConnectionManager() {
78435
78550
  const connections = new Map;
78436
78551
  const pending = new Set;
78552
+ const connectFailures = new Map;
78437
78553
  function fail(name, config, error, authFailure = false) {
78438
78554
  const conn = {
78439
78555
  name,
@@ -78538,6 +78654,7 @@ function createMcpConnectionManager() {
78538
78654
  }
78539
78655
  };
78540
78656
  connections.set(name, connection);
78657
+ connectFailures.delete(name);
78541
78658
  return connection;
78542
78659
  } catch (e) {
78543
78660
  stderr.off("data", stderrHandler);
@@ -78548,6 +78665,8 @@ function createMcpConnectionManager() {
78548
78665
  stderrOutput = "";
78549
78666
  }
78550
78667
  const message = e instanceof McpJsonRpcError || e instanceof Error ? e.message : String(e);
78668
+ const prev = connectFailures.get(name);
78669
+ connectFailures.set(name, { count: (prev?.count ?? 0) + 1, lastFailedAt: Date.now() });
78551
78670
  return fail(name, config, message);
78552
78671
  }
78553
78672
  }
@@ -78555,6 +78674,14 @@ function createMcpConnectionManager() {
78555
78674
  const existing = connections.get(name);
78556
78675
  if (existing?.type === "connected")
78557
78676
  return existing;
78677
+ const record = connectFailures.get(name);
78678
+ const backoffDelayMs = record ? mcpConnectBackoffDelayMs(record.count) : 0;
78679
+ if (record !== undefined && backoffDelayMs > 0) {
78680
+ const sinceLastFailure = Date.now() - record.lastFailedAt;
78681
+ if (sinceLastFailure < backoffDelayMs) {
78682
+ return fail(name, config, `MCP server "${name}" connect deferred (backoff): ${record.count} consecutive failure(s), retry in ~${Math.ceil((backoffDelayMs - sinceLastFailure) / 1000)}s (set ATLAS_MCP_CONNECT_BACKOFF_MS=0 to disable)`);
78683
+ }
78684
+ }
78558
78685
  pending.add(name);
78559
78686
  try {
78560
78687
  const t = config.type;
@@ -78592,7 +78719,7 @@ function createMcpConnectionManager() {
78592
78719
  function getMcpConnectionManager() {
78593
78720
  return singleton ??= createMcpConnectionManager();
78594
78721
  }
78595
- var MAX_ERRORS_BEFORE_RECONNECT = 3, FORWARD_SEAM_MESSAGE = "MCP transport = 前向接缝登记(§8.68 R2:非 stdio 传输真实现待 MCP 标准远程传输(M6 波)(#200 波);G-3 ⑩ D3 型面 8→4 后 4 型 config,仅 stdio 连接支 live)", singleton;
78722
+ var DEFAULT_MCP_CONNECT_BACKOFF_MS = 1000, MAX_MCP_CONNECT_BACKOFF_MS = 30000, MAX_ERRORS_BEFORE_RECONNECT = 3, FORWARD_SEAM_MESSAGE = "MCP transport = 前向接缝登记(§8.68 R2:非 stdio 传输真实现待 MCP 标准远程传输(M6 波)(#200 波);G-3 ⑩ D3 型面 8→4 后 4 型 config,仅 stdio 连接支 live)", singleton;
78596
78723
  var init_mcpConnectionManager = __esm(() => {
78597
78724
  init_shared();
78598
78725
  init_bootstrap();
@@ -78704,6 +78831,85 @@ function buildSchemaNotSentHint(tool, discoveredToolNames) {
78704
78831
  This tool's schema was not sent to the API — it was not in the discovered-tool set derived from message history. ` + `Without the schema in your prompt, typed parameters (arrays, numbers, booleans) get emitted as strings and the client-side parser rejects them. ` + `Re-issue the call with correctly-typed parameters (arrays/numbers/booleans, not their string forms).`;
78705
78832
  }
78706
78833
 
78834
+ // src/engine/pipeline/mcpAutoBackground.ts
78835
+ function getMcpAutoBackgroundMs(env = process.env) {
78836
+ const raw = env.ATLAS_MCP_AUTO_BACKGROUND_MS;
78837
+ if (!raw)
78838
+ return DEFAULT_MCP_AUTO_BACKGROUND_MS;
78839
+ const parsed = Number(raw);
78840
+ if (!Number.isFinite(parsed))
78841
+ return DEFAULT_MCP_AUTO_BACKGROUND_MS;
78842
+ return Math.max(MIN_MCP_AUTO_BACKGROUND_MS, parsed);
78843
+ }
78844
+ async function callWithMcpAutoBackground(opts, fn) {
78845
+ let settled = false;
78846
+ return new Promise((resolve, reject) => {
78847
+ const pending = fn();
78848
+ const timer = setTimeout(() => {
78849
+ if (settled)
78850
+ return;
78851
+ settled = true;
78852
+ resolve({ backgrounded: true });
78853
+ pending.then((data) => {
78854
+ opts.onBackgrounded({
78855
+ toolUseId: opts.toolUseId,
78856
+ toolName: opts.toolName,
78857
+ outcome: { ok: true, data }
78858
+ });
78859
+ }).catch((error) => {
78860
+ opts.onBackgrounded({
78861
+ toolUseId: opts.toolUseId,
78862
+ toolName: opts.toolName,
78863
+ outcome: { ok: false, error: String(error?.message ?? error) }
78864
+ });
78865
+ });
78866
+ }, opts.backgroundAfterMs);
78867
+ timer.unref?.();
78868
+ pending.then((result) => {
78869
+ if (settled)
78870
+ return;
78871
+ settled = true;
78872
+ clearTimeout(timer);
78873
+ resolve({ backgrounded: false, result });
78874
+ }, (error) => {
78875
+ if (settled)
78876
+ return;
78877
+ settled = true;
78878
+ clearTimeout(timer);
78879
+ reject(error);
78880
+ });
78881
+ });
78882
+ }
78883
+ var DEFAULT_MCP_AUTO_BACKGROUND_MS = 120000, MIN_MCP_AUTO_BACKGROUND_MS = 1000;
78884
+
78885
+ // src/engine/pipeline/toolHeartbeat.ts
78886
+ function getToolHeartbeatIntervalMs(env = process.env) {
78887
+ const raw = env.ATLAS_TOOL_HEARTBEAT_MS;
78888
+ if (!raw)
78889
+ return DEFAULT_TOOL_HEARTBEAT_INTERVAL_MS;
78890
+ const parsed = Number(raw);
78891
+ if (!Number.isFinite(parsed))
78892
+ return DEFAULT_TOOL_HEARTBEAT_INTERVAL_MS;
78893
+ return Math.max(MIN_TOOL_HEARTBEAT_INTERVAL_MS, parsed);
78894
+ }
78895
+ async function runWithToolHeartbeat(opts, fn) {
78896
+ const start = Date.now();
78897
+ const timer = setInterval(() => {
78898
+ opts.onHeartbeat({
78899
+ toolUseId: opts.toolUseId,
78900
+ toolName: opts.toolName,
78901
+ elapsedMs: Date.now() - start
78902
+ });
78903
+ }, opts.intervalMs);
78904
+ timer.unref?.();
78905
+ try {
78906
+ return await fn();
78907
+ } finally {
78908
+ clearInterval(timer);
78909
+ }
78910
+ }
78911
+ var DEFAULT_TOOL_HEARTBEAT_INTERVAL_MS = 30000, MIN_TOOL_HEARTBEAT_INTERVAL_MS = 100;
78912
+
78707
78913
  // src/engine/pipeline/toolExecution.ts
78708
78914
  function mergeHookPermission(hookBehavior, gate, hookReason) {
78709
78915
  if (hookBehavior === "defer") {
@@ -78815,8 +79021,40 @@ async function executeToolUse(tu, assistantMsg, deps) {
78815
79021
  let block;
78816
79022
  let isError = false;
78817
79023
  let toolUseResult;
79024
+ const mcpAutoBackgroundArmed = deps.onMcpToolBackgrounded !== undefined && tool.isMcp === true;
78818
79025
  try {
78819
- const res = await tool.call(callInput, toolCallContext, undefined, assistantMsg);
79026
+ const callTool = () => tool.call(callInput, toolCallContext, undefined, assistantMsg);
79027
+ const withHeartbeat = () => deps.onToolHeartbeat ? runWithToolHeartbeat({
79028
+ toolUseId: tu.id,
79029
+ toolName: tool.name,
79030
+ intervalMs: getToolHeartbeatIntervalMs(),
79031
+ onHeartbeat: deps.onToolHeartbeat
79032
+ }, callTool) : callTool();
79033
+ let res;
79034
+ if (mcpAutoBackgroundArmed) {
79035
+ const raced = await callWithMcpAutoBackground({
79036
+ toolUseId: tu.id,
79037
+ toolName: tool.name,
79038
+ backgroundAfterMs: deps.mcpAutoBackgroundMs ?? getMcpAutoBackgroundMs(),
79039
+ onBackgrounded: deps.onMcpToolBackgrounded
79040
+ }, withHeartbeat);
79041
+ if (raced.backgrounded === true) {
79042
+ const backgroundedContent = `[mcp tool ${tool.name} is still running after exceeding the auto-background threshold; ` + "it has been moved to the background and will keep running. " + "The result will be delivered later as a task notification — do not call this tool again for the same purpose.";
79043
+ return {
79044
+ block: {
79045
+ type: "tool_result",
79046
+ tool_use_id: tu.id,
79047
+ content: backgroundedContent,
79048
+ is_error: false
79049
+ },
79050
+ isError: false,
79051
+ toolUseResult: backgroundedContent
79052
+ };
79053
+ }
79054
+ res = raced.result;
79055
+ } else {
79056
+ res = await withHeartbeat();
79057
+ }
78820
79058
  block = tool.mapToolResultToToolResultBlockParam(res.data, tu.id);
78821
79059
  toolUseResult = res.data;
78822
79060
  } catch (error) {
@@ -78835,6 +79073,17 @@ async function executeToolUse(tu, assistantMsg, deps) {
78835
79073
  block = { ...block, content: postOutcome.updatedToolOutput };
78836
79074
  toolUseResult = postOutcome.updatedToolOutput;
78837
79075
  }
79076
+ if (postOutcome?.blockingError !== undefined) {
79077
+ const hookDenyText = `<tool_use_error>blocked by PostToolUse hook: ${postOutcome.blockingError}</tool_use_error>`;
79078
+ block = {
79079
+ type: "tool_result",
79080
+ tool_use_id: tu.id,
79081
+ content: hookDenyText,
79082
+ is_error: true
79083
+ };
79084
+ isError = true;
79085
+ toolUseResult = hookDenyText;
79086
+ }
78838
79087
  return { block, isError, toolUseResult };
78839
79088
  }
78840
79089
  var init_toolExecution = () => {};
@@ -82349,7 +82598,9 @@ async function queryOneRound(deps, tools, messages) {
82349
82598
  signal: deps.signal,
82350
82599
  checkPermission: deps.checkPermission,
82351
82600
  hooks: deps.hooks?.toolHooks,
82352
- toolContext: deps.toolContext
82601
+ toolContext: deps.toolContext,
82602
+ onToolHeartbeat: deps.emit ? (info) => deps.emit({ type: "tool_heartbeat", ...info }) : undefined,
82603
+ onMcpToolBackgrounded: deps.onMcpToolBackgrounded
82353
82604
  });
82354
82605
  const deferredOutcome = outcomes.find((o) => o.deferred);
82355
82606
  const deferredPayload = deferredOutcome ? {
@@ -82664,7 +82915,8 @@ function createToolHooks(opts = {}) {
82664
82915
  const r = await runPostToolUseHooks(tool.name, input, block, toolUseId, { ...base, toolUseID: toolUseId });
82665
82916
  const outcome = {
82666
82917
  additionalContext: r.additionalContext,
82667
- updatedToolOutput: r.updatedToolOutput
82918
+ updatedToolOutput: r.updatedToolOutput,
82919
+ blockingError: r.blockingError && r.continueOnBlock ? r.blockingError.blockingError : undefined
82668
82920
  };
82669
82921
  return outcome;
82670
82922
  }
@@ -85348,6 +85600,15 @@ To attach: tmux attach -t ${tmuxSessionName}
85348
85600
  if (!bare) {
85349
85601
  getCommands(getProjectRoot()).catch(() => {});
85350
85602
  }
85603
+ const restrictedBypassErr = restrictedBypassError({
85604
+ permissionMode: options.permissionMode,
85605
+ allowDangerouslySkipPermissions: options.allowDangerouslySkipPermissions === true
85606
+ });
85607
+ if (restrictedBypassErr) {
85608
+ process.stderr.write(`Error: ${restrictedBypassErr}
85609
+ `);
85610
+ process.exit(1);
85611
+ }
85351
85612
  if (options.permissionMode === "bypassPermissions" || options.allowDangerouslySkipPermissions) {
85352
85613
  if (process.platform !== "win32" && typeof process.getuid === "function" && process.getuid() === 0 && process.env.IS_SANDBOX !== "1" && !isEnvTruthy(process.env.ATLAS_BUBBLEWRAP)) {
85353
85614
  process.stderr.write(`--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons
@@ -88352,6 +88613,19 @@ function buildHeadlessOptions(options) {
88352
88613
  };
88353
88614
  }
88354
88615
  async function mainActionSeam(prompt, options) {
88616
+ if (options.restricted === true) {
88617
+ setRestrictedMode(true);
88618
+ const bypassErr = restrictedBypassError({
88619
+ permissionMode: options.permissionMode,
88620
+ allowDangerouslySkipPermissions: options.allowDangerouslySkipPermissions === true,
88621
+ dangerouslySkipPermissions: options.dangerouslySkipPermissions === true
88622
+ });
88623
+ if (bypassErr) {
88624
+ process.stderr.write(`Error: ${bypassErr}
88625
+ `);
88626
+ process.exit(1);
88627
+ }
88628
+ }
88355
88629
  if (options.initOnly) {
88356
88630
  await runCliSetup({
88357
88631
  permissionMode: options.permissionMode,
@@ -88416,7 +88690,7 @@ function buildProgram() {
88416
88690
  throw new Error("--task-budget must be a positive integer");
88417
88691
  }
88418
88692
  return tokens;
88419
- }).hideHelp()).option("--replay-user-messages", "Re-emit user messages from stdin back on stdout for acknowledgment (only works with --input-format=stream-json and --output-format=stream-json)", () => true).addOption(new Option("--enable-auth-status", "Enable auth status messages in SDK mode").default(false).hideHelp()).option("--allowedTools, --allowed-tools <tools...>", 'Comma or space-separated list of tool names to allow (e.g. "Bash(git:*) Edit")').option("--tools <tools...>", 'Specify the list of available tools from the built-in set. Use "" to disable all tools, "default" to use all tools, or specify tool names (e.g. "Bash,Edit,Read").').option("--disallowedTools, --disallowed-tools <tools...>", 'Comma or space-separated list of tool names to deny (e.g. "Bash(git:*) Edit")').option("--mcp-config <configs...>", "Load MCP servers from JSON files or strings (space-separated)").addOption(new Option("--permission-prompt-tool <tool>", "MCP tool to use for permission prompts (only works with --print)").argParser(String).hideHelp()).addOption(new Option("--system-prompt <prompt>", "System prompt to use for the session").argParser(String)).addOption(new Option("--system-prompt-file <file>", "Read system prompt from a file").argParser(String).hideHelp()).addOption(new Option("--append-system-prompt <prompt>", "Append a system prompt to the default system prompt").argParser(String)).addOption(new Option("--append-system-prompt-file <file>", "Read system prompt from a file and append to the default system prompt").argParser(String).hideHelp()).addOption(new Option("--permission-mode <mode>", "Permission mode to use for the session").argParser(String).choices(PERMISSION_MODES)).addOption(new Option("--permission-prompts <mode>", "Permission prompt policy; 'none' auto-denies prompts that would otherwise ask").argParser(String).choices(["none"])).option("-c, --continue", "Continue the most recent conversation in the current directory", () => true).option("-r, --resume [value]", "Resume a conversation by session ID, or open interactive picker with optional search term", (value) => value || true).option("--fork-session", "When resuming, create a new session ID instead of reusing the original (use with --resume or --continue)", () => true).addOption(new Option("--prefill <text>", "Pre-fill the prompt input with text without submitting it").hideHelp()).addOption(new Option("--deep-link-origin", "Signal that this session was launched from a deep link").hideHelp()).addOption(new Option("--deep-link-repo <slug>", "Repo slug the deep link ?repo= parameter resolved to the current cwd").hideHelp()).addOption(new Option("--deep-link-last-fetch <ms>", "FETCH_HEAD mtime in epoch ms, precomputed by the deep link trampoline").argParser((v) => {
88693
+ }).hideHelp()).option("--replay-user-messages", "Re-emit user messages from stdin back on stdout for acknowledgment (only works with --input-format=stream-json and --output-format=stream-json)", () => true).addOption(new Option("--enable-auth-status", "Enable auth status messages in SDK mode").default(false).hideHelp()).option("--allowedTools, --allowed-tools <tools...>", 'Comma or space-separated list of tool names to allow (e.g. "Bash(git:*) Edit")').option("--tools <tools...>", 'Specify the list of available tools from the built-in set. Use "" to disable all tools, "default" to use all tools, or specify tool names (e.g. "Bash,Edit,Read").').option("--disallowedTools, --disallowed-tools <tools...>", 'Comma or space-separated list of tool names to deny (e.g. "Bash(git:*) Edit")').option("--restricted", "Run in restricted mode: strips command-execution tools (Bash/PowerShell), WebFetch, and Agent; rejects bypassPermissions and --dangerously-skip-permissions; ignores user/project/local settings (env: ATLAS_RESTRICTED)").option("--mcp-config <configs...>", "Load MCP servers from JSON files or strings (space-separated)").addOption(new Option("--permission-prompt-tool <tool>", "MCP tool to use for permission prompts (only works with --print)").argParser(String).hideHelp()).addOption(new Option("--system-prompt <prompt>", "System prompt to use for the session").argParser(String)).addOption(new Option("--system-prompt-file <file>", "Read system prompt from a file").argParser(String).hideHelp()).addOption(new Option("--append-system-prompt <prompt>", "Append a system prompt to the default system prompt").argParser(String)).addOption(new Option("--append-system-prompt-file <file>", "Read system prompt from a file and append to the default system prompt").argParser(String).hideHelp()).addOption(new Option("--permission-mode <mode>", "Permission mode to use for the session").argParser(String).choices(PERMISSION_MODES)).addOption(new Option("--permission-prompts <mode>", "Permission prompt policy; 'none' auto-denies prompts that would otherwise ask").argParser(String).choices(["none"])).option("-c, --continue", "Continue the most recent conversation in the current directory", () => true).option("-r, --resume [value]", "Resume a conversation by session ID, or open interactive picker with optional search term", (value) => value || true).option("--fork-session", "When resuming, create a new session ID instead of reusing the original (use with --resume or --continue)", () => true).addOption(new Option("--prefill <text>", "Pre-fill the prompt input with text without submitting it").hideHelp()).addOption(new Option("--deep-link-origin", "Signal that this session was launched from a deep link").hideHelp()).addOption(new Option("--deep-link-repo <slug>", "Repo slug the deep link ?repo= parameter resolved to the current cwd").hideHelp()).addOption(new Option("--deep-link-last-fetch <ms>", "FETCH_HEAD mtime in epoch ms, precomputed by the deep link trampoline").argParser((v) => {
88420
88694
  const n = Number(v);
88421
88695
  return Number.isFinite(n) ? n : undefined;
88422
88696
  }).hideHelp()).option("--from-pr [value]", "Resume a session linked to a PR by PR number/URL, or open interactive picker with optional search term", (value) => value || true).option("--no-session-persistence", "Disable session persistence - sessions will not be saved to disk and cannot be resumed (only works with --print)").addOption(new Option("--resume-session-at <message id>", "When resuming, only messages up to and including the assistant message with <message.id> (use with --resume in print mode)").argParser(String).hideHelp()).addOption(new Option("--rewind-files <user-message-id>", "Restore files to state at the specified user message and exit (requires --resume)").hideHelp()).option("--model <model>", "Model for the current session. Provide a role alias (e.g. 'small' or 'premium') or a provider/model reference (e.g. 'bailian/qwen38-27b').").addOption(new Option("--effort <level>", "Effort level for the current session (low, medium, high, xhigh, max)").argParser((rawValue) => {
@@ -88522,6 +88796,7 @@ async function runCli() {
88522
88796
  var init_parse4 = __esm(() => {
88523
88797
  init_extra_typings();
88524
88798
  init_bootstrap();
88799
+ init_engine();
88525
88800
  init_permissions3();
88526
88801
  init_shared();
88527
88802
  init_remote();
@@ -96700,34 +96975,8 @@ var init_envUtils2 = __esm(() => {
96700
96975
  });
96701
96976
 
96702
96977
  // src/tui/types/atlas.ts
96703
- var APIError3, AuthenticationError2, NotFoundError2, APIConnectionError3, APIUserAbortError3;
96704
96978
  var init_atlas = __esm(() => {
96705
- APIError3 = class APIError3 extends Error {
96706
- status;
96707
- code;
96708
- headers;
96709
- constructor(message, opts) {
96710
- super(message ?? "API error");
96711
- this.name = "APIError";
96712
- if (opts) {
96713
- this.status = opts.status;
96714
- this.code = opts.code;
96715
- this.headers = opts.headers;
96716
- }
96717
- }
96718
- };
96719
- AuthenticationError2 = class AuthenticationError2 extends APIError3 {
96720
- constructor(message, opts) {
96721
- super(message, opts);
96722
- this.name = "AuthenticationError";
96723
- }
96724
- };
96725
- NotFoundError2 = class NotFoundError2 extends APIError3 {
96726
- };
96727
- APIConnectionError3 = class APIConnectionError3 extends APIError3 {
96728
- };
96729
- APIUserAbortError3 = class APIUserAbortError3 extends APIError3 {
96730
- };
96979
+ init_types2();
96731
96980
  });
96732
96981
 
96733
96982
  // src/tui/utils/errors.ts
@@ -124113,7 +124362,12 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
124113
124362
  xaaIdp: any().optional(),
124114
124363
  agent: any().optional(),
124115
124364
  local: any().optional(),
124116
- worktree: any().optional()
124365
+ worktree: any().optional(),
124366
+ skillOverrides: union([
124367
+ literal("off"),
124368
+ literal("user-invocable-only"),
124369
+ literal("name-only")
124370
+ ]).optional()
124117
124371
  }).passthrough(), CUSTOMIZATION_SURFACES;
124118
124372
  var init_types7 = __esm(() => {
124119
124373
  init_zod();
@@ -124241,13 +124495,10 @@ var init_stringUtils2 = __esm(() => {
124241
124495
 
124242
124496
  // src/tui/services/mcp/normalization.ts
124243
124497
  function normalizeNameForMCP3(name) {
124244
- let normalized = name.replace(/[^a-zA-Z0-9_-]/g, "_");
124245
- if (name.startsWith(CLAUDEAI_SERVER_PREFIX3)) {
124246
- normalized = normalized.replace(/_+/g, "_").replace(/^_|_$/g, "");
124247
- }
124248
- return normalized;
124498
+ const folded = name.replace(/[^a-zA-Z0-9_-]/g, "_");
124499
+ const normalized = folded.replace(/_+/g, "_").replace(/^_|_$/g, "");
124500
+ return normalized === "" ? folded : normalized;
124249
124501
  }
124250
- var CLAUDEAI_SERVER_PREFIX3 = "claude.ai ";
124251
124502
 
124252
124503
  // src/tui/services/mcp/mcpStringUtils.ts
124253
124504
  function mcpInfoFromString3(toolString) {
@@ -133082,7 +133333,7 @@ function getEnvironmentKind() {
133082
133333
  }
133083
133334
  return null;
133084
133335
  }
133085
- var WIRE_ENVIRONMENT_KIND_CLOUD = "anthropic_cloud";
133336
+ var WIRE_ENVIRONMENT_KIND_CLOUD = "cloud";
133086
133337
  var init_outputsScanner = __esm(() => {
133087
133338
  init_debug();
133088
133339
  });
@@ -151040,28 +151291,28 @@ function getEventPriority(eventType) {
151040
151291
  case "focus":
151041
151292
  case "blur":
151042
151293
  case "paste":
151043
- return import_constants53.DiscreteEventPriority;
151294
+ return import_constants54.DiscreteEventPriority;
151044
151295
  case "resize":
151045
151296
  case "scroll":
151046
151297
  case "mousemove":
151047
- return import_constants53.ContinuousEventPriority;
151298
+ return import_constants54.ContinuousEventPriority;
151048
151299
  default:
151049
- return import_constants53.DefaultEventPriority;
151300
+ return import_constants54.DefaultEventPriority;
151050
151301
  }
151051
151302
  }
151052
151303
 
151053
151304
  class Dispatcher {
151054
151305
  currentEvent = null;
151055
- currentUpdatePriority = import_constants53.DefaultEventPriority;
151306
+ currentUpdatePriority = import_constants54.DefaultEventPriority;
151056
151307
  discreteUpdates = null;
151057
151308
  resolveEventPriority() {
151058
- if (this.currentUpdatePriority !== import_constants53.NoEventPriority) {
151309
+ if (this.currentUpdatePriority !== import_constants54.NoEventPriority) {
151059
151310
  return this.currentUpdatePriority;
151060
151311
  }
151061
151312
  if (this.currentEvent) {
151062
151313
  return getEventPriority(this.currentEvent.type);
151063
151314
  }
151064
- return import_constants53.DefaultEventPriority;
151315
+ return import_constants54.DefaultEventPriority;
151065
151316
  }
151066
151317
  dispatch(target, event) {
151067
151318
  const previousEvent = this.currentEvent;
@@ -151086,18 +151337,18 @@ class Dispatcher {
151086
151337
  dispatchContinuous(target, event) {
151087
151338
  const previousPriority = this.currentUpdatePriority;
151088
151339
  try {
151089
- this.currentUpdatePriority = import_constants53.ContinuousEventPriority;
151340
+ this.currentUpdatePriority = import_constants54.ContinuousEventPriority;
151090
151341
  return this.dispatch(target, event);
151091
151342
  } finally {
151092
151343
  this.currentUpdatePriority = previousPriority;
151093
151344
  }
151094
151345
  }
151095
151346
  }
151096
- var import_constants53;
151347
+ var import_constants54;
151097
151348
  var init_dispatcher = __esm(() => {
151098
151349
  init_log5();
151099
151350
  init_event_handlers();
151100
- import_constants53 = __toESM(require_constants2(), 1);
151351
+ import_constants54 = __toESM(require_constants2(), 1);
151101
151352
  });
151102
151353
 
151103
151354
  // src/tui/ink/events/terminal-event.ts
@@ -159904,7 +160155,7 @@ function applyPositionedHighlight(screen, stylePool, positions, rowOffset, curre
159904
160155
  }
159905
160156
  return true;
159906
160157
  }
159907
- var import_constants55, timing;
160158
+ var import_constants56, timing;
159908
160159
  var init_render_to_screen = __esm(() => {
159909
160160
  init_debug();
159910
160161
  init_dom();
@@ -159913,7 +160164,7 @@ var init_render_to_screen = __esm(() => {
159913
160164
  init_reconciler();
159914
160165
  init_render_node_to_output();
159915
160166
  init_screen();
159916
- import_constants55 = __toESM(require_constants2(), 1);
160167
+ import_constants56 = __toESM(require_constants2(), 1);
159917
160168
  timing = { reconcile: 0, yoga: 0, paint: 0, scan: 0, calls: 0 };
159918
160169
  });
159919
160170
 
@@ -160219,7 +160470,7 @@ class Ink {
160219
160470
  };
160220
160471
  }
160221
160472
  };
160222
- this.container = reconciler_default.createContainer(this.rootNode, import_constants56.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
160473
+ this.container = reconciler_default.createContainer(this.rootNode, import_constants57.ConcurrentRoot, null, false, null, "id", noop_default, noop_default, noop_default, noop_default);
160223
160474
  if (false) {}
160224
160475
  }
160225
160476
  handleResume = () => {
@@ -161032,7 +161283,7 @@ function drainStdin(stdin = process.stdin) {
161032
161283
  }
161033
161284
  }
161034
161285
  }
161035
- var import_constants56, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
161286
+ var import_constants57, jsx_dev_runtime8, ALT_SCREEN_ANCHOR_CURSOR, CURSOR_HOME_PATCH, ERASE_THEN_HOME_PATCH, CONSOLE_STDOUT_METHODS, CONSOLE_STDERR_METHODS;
161036
161287
  var init_ink = __esm(() => {
161037
161288
  init_noop();
161038
161289
  init_throttle2();
@@ -161065,7 +161316,7 @@ var init_ink = __esm(() => {
161065
161316
  init_dec();
161066
161317
  init_osc();
161067
161318
  init_useTerminalNotification();
161068
- import_constants56 = __toESM(require_constants2(), 1);
161319
+ import_constants57 = __toESM(require_constants2(), 1);
161069
161320
  jsx_dev_runtime8 = __toESM(require_jsx_dev_runtime(), 1);
161070
161321
  ALT_SCREEN_ANCHOR_CURSOR = Object.freeze({
161071
161322
  x: 0,
@@ -166828,7 +167079,7 @@ var init_addDirPluginSettings = __esm(() => {
166828
167079
  });
166829
167080
 
166830
167081
  // src/tui/entrypoints/sdk/coreSchemas.ts
166831
- var ModelUsageSchema, OutputFormatTypeSchema, BaseOutputFormatSchema, JsonSchemaOutputFormatSchema, OutputFormatSchema, ApiKeySourceSchema, ConfigScopeSchema2, SdkBetaSchema, ThinkingAdaptiveSchema, ThinkingEnabledSchema, ThinkingDisabledSchema, ThinkingConfigSchema, McpStdioServerConfigSchema2, McpSSEServerConfigSchema2, McpHttpServerConfigSchema, McpSdkServerConfigSchema, McpServerConfigForProcessTransportSchema, McpServerStatusConfigSchema, McpServerStatusSchema, McpSetServersResultSchema, PermissionUpdateDestinationSchema, PermissionBehaviorSchema, PreToolUsePermissionDecisionSchema, PermissionRuleValueSchema, PermissionUpdateSchema, PermissionDecisionClassificationSchema, PermissionResultSchema, PermissionModeSchema2, HOOK_EVENTS2, HookEventSchema, BaseHookInputSchema, PreToolUseHookInputSchema, PermissionRequestHookInputSchema, PostToolUseHookInputSchema, PostToolUseFailureHookInputSchema, PermissionDeniedHookInputSchema, NotificationHookInputSchema, UserPromptSubmitHookInputSchema, SessionStartHookInputSchema, PreModelSwitchHookInputSchema, PostModelSwitchHookInputSchema, SetupHookInputSchema, StopHookInputSchema, StopFailureHookInputSchema, SubagentStartHookInputSchema, SubagentStopHookInputSchema, PreCompactHookInputSchema, PostCompactHookInputSchema, TeammateIdleHookInputSchema, TaskCreatedHookInputSchema, TaskCompletedHookInputSchema, ElicitationHookInputSchema, ElicitationResultHookInputSchema, CONFIG_CHANGE_SOURCES, ConfigChangeHookInputSchema, INSTRUCTIONS_LOAD_REASONS, INSTRUCTIONS_MEMORY_TYPES, InstructionsLoadedHookInputSchema, WorktreeCreateHookInputSchema, WorktreeRemoveHookInputSchema, CwdChangedHookInputSchema, FileChangedHookInputSchema, EXIT_REASONS, ExitReasonSchema, SessionEndHookInputSchema, HookInputSchema, AsyncHookJSONOutputSchema, PreToolUseHookSpecificOutputSchema, UserPromptSubmitHookSpecificOutputSchema, SessionStartHookSpecificOutputSchema, SetupHookSpecificOutputSchema, SubagentStartHookSpecificOutputSchema, PostToolUseHookSpecificOutputSchema, PostToolUseFailureHookSpecificOutputSchema, PermissionDeniedHookSpecificOutputSchema, NotificationHookSpecificOutputSchema, PermissionRequestHookSpecificOutputSchema, CwdChangedHookSpecificOutputSchema, FileChangedHookSpecificOutputSchema, SyncHookJSONOutputSchema, ElicitationHookSpecificOutputSchema, ElicitationResultHookSpecificOutputSchema, WorktreeCreateHookSpecificOutputSchema, HookJSONOutputSchema, PromptRequestOptionSchema, PromptRequestSchema, PromptResponseSchema, SlashCommandSchema, AgentInfoSchema, ModelInfoSchema, AccountInfoSchema, AgentMcpServerSpecSchema, AgentDefinitionSchema, SettingSourceSchema, SdkPluginConfigSchema, RewindFilesResultSchema, APIUserMessagePlaceholder, APIAssistantMessagePlaceholder, RawMessageStreamEventPlaceholder, UUIDPlaceholder, NonNullableUsagePlaceholder, SDKAssistantMessageErrorSchema, SDKStatusSchema, SDKUserMessageContentSchema, SDKUserMessageSchema, SDKUserMessageReplaySchema, SDKRateLimitInfoSchema, SDKAssistantMessageSchema, SDKRateLimitEventSchema, SDKStreamlinedTextMessageSchema, SDKStreamlinedToolUseSummaryMessageSchema, SDKPermissionDenialSchema, SDKResultSuccessSchema, SDKResultErrorSchema, SDKResultMessageSchema, SDKSystemMessageSchema, SDKPartialAssistantMessageSchema, SDKCompactBoundaryMessageSchema, SDKStatusMessageSchema, SDKPostTurnSummaryMessageSchema, SDKAPIRetryMessageSchema, SDKLocalCommandOutputMessageSchema, SDKHookStartedMessageSchema, SDKHookProgressMessageSchema, SDKHookResponseMessageSchema, SDKToolProgressMessageSchema, SDKAuthStatusMessageSchema, SDKFilesPersistedEventSchema, SDKTaskNotificationMessageSchema, SDKTaskStartedMessageSchema, SDKSessionStateChangedMessageSchema, SDKTaskProgressMessageSchema, SDKToolUseSummaryMessageSchema, SDKElicitationCompleteMessageSchema, SDKPromptSuggestionMessageSchema, SDKSessionInfoSchema, SDKMessageSchema, FastModeStateSchema;
167082
+ var ModelUsageSchema, OutputFormatTypeSchema, BaseOutputFormatSchema, JsonSchemaOutputFormatSchema, OutputFormatSchema, ApiKeySourceSchema, ConfigScopeSchema2, SdkBetaSchema, ThinkingAdaptiveSchema, ThinkingEnabledSchema, ThinkingDisabledSchema, ThinkingConfigSchema, McpStdioServerConfigSchema2, McpSSEServerConfigSchema2, McpHttpServerConfigSchema, McpSdkServerConfigSchema, McpServerConfigForProcessTransportSchema, McpServerStatusConfigSchema, McpServerStatusSchema, McpSetServersResultSchema, PermissionUpdateDestinationSchema, PermissionBehaviorSchema, PreToolUsePermissionDecisionSchema, PermissionRuleValueSchema, PermissionUpdateSchema, PermissionDecisionClassificationSchema, PermissionResultSchema, PermissionModeSchema2, HOOK_EVENTS2, HookEventSchema, BaseHookInputSchema, PreToolUseHookInputSchema, PermissionRequestHookInputSchema, PostToolUseHookInputSchema, PostToolUseFailureHookInputSchema, PermissionDeniedHookInputSchema, NotificationHookInputSchema, UserPromptSubmitHookInputSchema, SessionStartHookInputSchema, PreModelSwitchHookInputSchema, PostModelSwitchHookInputSchema, DirectoryAddedHookInputSchema, MessageDisplayHookInputSchema, SetupHookInputSchema, StopHookInputSchema, StopFailureHookInputSchema, SubagentStartHookInputSchema, SubagentStopHookInputSchema, PreCompactHookInputSchema, PostCompactHookInputSchema, TeammateIdleHookInputSchema, TaskCreatedHookInputSchema, TaskCompletedHookInputSchema, ElicitationHookInputSchema, ElicitationResultHookInputSchema, CONFIG_CHANGE_SOURCES, ConfigChangeHookInputSchema, INSTRUCTIONS_LOAD_REASONS, INSTRUCTIONS_MEMORY_TYPES, InstructionsLoadedHookInputSchema, WorktreeCreateHookInputSchema, WorktreeRemoveHookInputSchema, CwdChangedHookInputSchema, FileChangedHookInputSchema, EXIT_REASONS, ExitReasonSchema, SessionEndHookInputSchema, HookInputSchema, AsyncHookJSONOutputSchema, PreToolUseHookSpecificOutputSchema, UserPromptSubmitHookSpecificOutputSchema, SessionStartHookSpecificOutputSchema, SetupHookSpecificOutputSchema, SubagentStartHookSpecificOutputSchema, PostToolUseHookSpecificOutputSchema, PostToolUseFailureHookSpecificOutputSchema, PermissionDeniedHookSpecificOutputSchema, NotificationHookSpecificOutputSchema, PermissionRequestHookSpecificOutputSchema, CwdChangedHookSpecificOutputSchema, FileChangedHookSpecificOutputSchema, SyncHookJSONOutputSchema, ElicitationHookSpecificOutputSchema, ElicitationResultHookSpecificOutputSchema, WorktreeCreateHookSpecificOutputSchema, HookJSONOutputSchema, PromptRequestOptionSchema, PromptRequestSchema, PromptResponseSchema, SlashCommandSchema, AgentInfoSchema, ModelInfoSchema, AccountInfoSchema, AgentMcpServerSpecSchema, AgentDefinitionSchema, SettingSourceSchema, SdkPluginConfigSchema, RewindFilesResultSchema, APIUserMessagePlaceholder, APIAssistantMessagePlaceholder, RawMessageStreamEventPlaceholder, UUIDPlaceholder, NonNullableUsagePlaceholder, SDKAssistantMessageErrorSchema, SDKStatusSchema, SDKUserMessageContentSchema, SDKUserMessageSchema, SDKUserMessageReplaySchema, SDKRateLimitInfoSchema, SDKAssistantMessageSchema, SDKRateLimitEventSchema, SDKStreamlinedTextMessageSchema, SDKStreamlinedToolUseSummaryMessageSchema, SDKPermissionDenialSchema, SDKResultSuccessSchema, SDKResultErrorSchema, SDKResultMessageSchema, SDKSystemMessageSchema, SDKPartialAssistantMessageSchema, SDKCompactBoundaryMessageSchema, SDKStatusMessageSchema, SDKPostTurnSummaryMessageSchema, SDKAPIRetryMessageSchema, SDKLocalCommandOutputMessageSchema, SDKHookStartedMessageSchema, SDKHookProgressMessageSchema, SDKHookResponseMessageSchema, SDKToolProgressMessageSchema, SDKAuthStatusMessageSchema, SDKFilesPersistedEventSchema, SDKTaskNotificationMessageSchema, SDKTaskStartedMessageSchema, SDKSessionStateChangedMessageSchema, SDKTaskProgressMessageSchema, SDKToolUseSummaryMessageSchema, SDKElicitationCompleteMessageSchema, SDKPromptSuggestionMessageSchema, SDKSessionInfoSchema, SDKMessageSchema, FastModeStateSchema;
166832
167083
  var init_coreSchemas = __esm(() => {
166833
167084
  init_v4();
166834
167085
  ModelUsageSchema = lazySchema2(() => object({
@@ -167017,7 +167268,9 @@ var init_coreSchemas = __esm(() => {
167017
167268
  "CwdChanged",
167018
167269
  "FileChanged",
167019
167270
  "PreModelSwitch",
167020
- "PostModelSwitch"
167271
+ "PostModelSwitch",
167272
+ "DirectoryAdded",
167273
+ "MessageDisplay"
167021
167274
  ];
167022
167275
  HookEventSchema = lazySchema2(() => _enum(HOOK_EVENTS2));
167023
167276
  BaseHookInputSchema = lazySchema2(() => object({
@@ -167090,6 +167343,15 @@ var init_coreSchemas = __esm(() => {
167090
167343
  new_model: string2(),
167091
167344
  source: string2()
167092
167345
  })));
167346
+ DirectoryAddedHookInputSchema = lazySchema2(() => BaseHookInputSchema().and(object({
167347
+ hook_event_name: literal("DirectoryAdded"),
167348
+ directory: string2(),
167349
+ source: string2()
167350
+ })));
167351
+ MessageDisplayHookInputSchema = lazySchema2(() => BaseHookInputSchema().and(object({
167352
+ hook_event_name: literal("MessageDisplay"),
167353
+ message: string2()
167354
+ })));
167093
167355
  SetupHookInputSchema = lazySchema2(() => BaseHookInputSchema().and(object({
167094
167356
  hook_event_name: literal("Setup"),
167095
167357
  trigger: _enum(["init", "maintenance"])
@@ -167506,7 +167768,7 @@ var init_coreSchemas = __esm(() => {
167506
167768
  ]).optional(),
167507
167769
  isUsingOverage: boolean2().optional(),
167508
167770
  surpassedThreshold: number2().optional()
167509
- }).describe("Rate limit information for claude.ai subscription users."));
167771
+ }).describe("Rate limit information."));
167510
167772
  SDKAssistantMessageSchema = lazySchema2(() => object({
167511
167773
  type: literal("assistant"),
167512
167774
  message: APIAssistantMessagePlaceholder(),
@@ -180728,6 +180990,7 @@ __export(exports_engineCompat, {
180728
180990
  getLastSummarizedMessageId: () => getLastSummarizedMessageId,
180729
180991
  getManagedSettingsDir: () => getManagedSettingsDir,
180730
180992
  getManagedSettingsDropInDir: () => getManagedSettingsDropInDir,
180993
+ getMcpAutoBackgroundMs: () => getMcpAutoBackgroundMs,
180731
180994
  getMcpClientRegistry: () => getMcpClientRegistry,
180732
180995
  getMcpPrefix: () => getMcpPrefix2,
180733
180996
  getMcpSkillCommands: () => getMcpSkillCommands,
@@ -180847,11 +181110,13 @@ __export(exports_engineCompat, {
180847
181110
  isReactiveCompactRecoverableError: () => isReactiveCompactRecoverableError,
180848
181111
  isReactiveOnlyMode: () => isReactiveOnlyMode,
180849
181112
  isRecurringTaskAged: () => isRecurringTaskAged,
181113
+ isRestrictedMode: () => isRestrictedMode,
180850
181114
  isSafeRefName: () => isSafeRefName,
180851
181115
  isSandboxPermissionRequest: () => isSandboxPermissionRequest,
180852
181116
  isSandboxPermissionResponse: () => isSandboxPermissionResponse,
180853
181117
  isSessionMemoryInitialized: () => isSessionMemoryInitialized,
180854
181118
  isSettingSourceEnabled: () => isSettingSourceEnabled,
181119
+ isSettingsSourceIgnoredInRestricted: () => isSettingsSourceIgnoredInRestricted,
180855
181120
  isShutdownApproved: () => isShutdownApproved,
180856
181121
  isShutdownRejected: () => isShutdownRejected,
180857
181122
  isShutdownRequest: () => isShutdownRequest,
@@ -180997,6 +181262,7 @@ __export(exports_engineCompat, {
180997
181262
  resetPendingNotifications: () => resetPendingNotifications,
180998
181263
  resetProjectFlushStateForTesting: () => resetProjectFlushStateForTesting,
180999
181264
  resetProjectForTesting: () => resetProjectForTesting,
181265
+ resetRestrictedMode: () => resetRestrictedMode,
181000
181266
  resetSchedulerEnv: () => resetSchedulerEnv,
181001
181267
  resetSdkEventQueueForTesting: () => resetSdkEventQueueForTesting,
181002
181268
  resetSessionContextPort: () => resetSessionContextPort,
@@ -181019,6 +181285,7 @@ __export(exports_engineCompat, {
181019
181285
  restoreGoalState: () => restoreGoalState,
181020
181286
  restoreSessionMetadata: () => restoreSessionMetadata,
181021
181287
  restoreWorktreeSession: () => restoreWorktreeSession,
181288
+ restrictedBypassError: () => restrictedBypassError,
181022
181289
  resumeGoal: () => resumeGoal,
181023
181290
  roughTokenCountEstimation: () => roughTokenCountEstimation2,
181024
181291
  roughTokenCountEstimationForContent: () => roughTokenCountEstimationForContent,
@@ -181055,6 +181322,7 @@ __export(exports_engineCompat, {
181055
181322
  setPartialCompactPort: () => setPartialCompactPort,
181056
181323
  setPluginSettingsBase: () => setPluginSettingsBase,
181057
181324
  setReactiveCompactPort: () => setReactiveCompactPort,
181325
+ setRestrictedMode: () => setRestrictedMode,
181058
181326
  setSchedulerEnv: () => setSchedulerEnv,
181059
181327
  setSessionContextPort: () => setSessionContextPort,
181060
181328
  setSessionEnv: () => setSessionEnv,
@@ -194533,8 +194801,6 @@ function describeMcpConfigFilePath2(scope) {
194533
194801
  return "Dynamically configured";
194534
194802
  case "enterprise":
194535
194803
  return getEnterpriseMcpFilePath();
194536
- case "claudeai":
194537
- return "claude.ai";
194538
194804
  default:
194539
194805
  return scope;
194540
194806
  }
@@ -194551,8 +194817,6 @@ function getScopeLabel2(scope) {
194551
194817
  return "Dynamic config (from command line)";
194552
194818
  case "enterprise":
194553
194819
  return "Enterprise config (managed by your organization)";
194554
- case "claudeai":
194555
- return "claude.ai config";
194556
194820
  default:
194557
194821
  return scope;
194558
194822
  }
@@ -256442,6 +256706,8 @@ async function* queryEngineLoopStream(params) {
256442
256706
  pending.push(event.messages[0]);
256443
256707
  } else if (event.type === "stream_delta") {
256444
256708
  pending.push(event);
256709
+ } else if (event.type === "tool_heartbeat") {
256710
+ pending.push(event);
256445
256711
  }
256446
256712
  notify();
256447
256713
  }
@@ -274462,7 +274728,7 @@ var init_apiErrors = __esm(() => {
274462
274728
  });
274463
274729
  },
274464
274730
  resolveAuthErrorMessaging: (error, _model) => {
274465
- if (error instanceof APIError3 && error.status === 400 && error.message.toLowerCase().includes("organization has been disabled")) {
274731
+ if (error instanceof APIError2 && error.status === 400 && error.message.toLowerCase().includes("organization has been disabled")) {
274466
274732
  const { source } = getAtlasApiKeyWithSource();
274467
274733
  if (source === "OPENAI_API_KEY" && process.env.OPENAI_API_KEY) {
274468
274734
  const hasStoredOAuth = getOAuthTokens()?.accessToken != null;
@@ -274487,13 +274753,13 @@ var init_apiErrors = __esm(() => {
274487
274753
  content: isExternalSource ? INVALID_API_KEY_ERROR_MESSAGE_EXTERNAL : INVALID_API_KEY_ERROR_MESSAGE
274488
274754
  });
274489
274755
  }
274490
- if (error instanceof APIError3 && error.status === 403 && error.message.includes("OAuth token has been revoked")) {
274756
+ if (error instanceof APIError2 && error.status === 403 && error.message.includes("OAuth token has been revoked")) {
274491
274757
  return createAssistantAPIErrorMessage2({
274492
274758
  error: "authentication_failed",
274493
274759
  content: getTokenRevokedErrorMessage()
274494
274760
  });
274495
274761
  }
274496
- if (error instanceof APIError3 && (error.status === 401 || error.status === 403) && error.message.includes("OAuth authentication is currently not allowed for this organization")) {
274762
+ if (error instanceof APIError2 && (error.status === 401 || error.status === 403) && error.message.includes("OAuth authentication is currently not allowed for this organization")) {
274497
274763
  return createAssistantAPIErrorMessage2({
274498
274764
  error: "authentication_failed",
274499
274765
  content: getOauthOrgNotAllowedErrorMessage()
@@ -274513,7 +274779,7 @@ var init_apiErrors = __esm(() => {
274513
274779
  content: getIsNonInteractiveSession() ? `${API_ERROR_MESSAGE_PREFIX}: provider quota exhausted (403). Top up your provider quota, or switch provider/model via --model, then retry.` : `${API_ERROR_MESSAGE_PREFIX}: provider quota exhausted (403). Top up your provider quota, or run /model to switch provider/model, then retry.`
274514
274780
  });
274515
274781
  }
274516
- if (error instanceof APIError3 && (error.status === 401 || error.status === 403)) {
274782
+ if (error instanceof APIError2 && (error.status === 401 || error.status === 403)) {
274517
274783
  if (isCCRMode()) {
274518
274784
  return createAssistantAPIErrorMessage2({
274519
274785
  error: "authentication_failed",
@@ -299536,14 +299802,14 @@ function handleValidationError(error, modelName) {
299536
299802
  error: `Model '${modelName}' not found`
299537
299803
  };
299538
299804
  }
299539
- if (error instanceof APIError3) {
299805
+ if (error instanceof APIError2) {
299540
299806
  if (error instanceof AuthenticationError2) {
299541
299807
  return {
299542
299808
  valid: false,
299543
299809
  error: "Authentication failed. Please check your API credentials."
299544
299810
  };
299545
299811
  }
299546
- if (error instanceof APIConnectionError3) {
299812
+ if (error instanceof APIConnectionError2) {
299547
299813
  return {
299548
299814
  valid: false,
299549
299815
  error: "Network error. Please check your internet connection."
@@ -308902,7 +309168,7 @@ async function executeAsyncClassifierCheck2(pendingCheck, signal, isNonInteracti
308902
309168
  try {
308903
309169
  classifierResult = speculativeResult ? await speculativeResult : await classifyBashCommand2(command, cwd, descriptions, "allow", signal, isNonInteractiveSession);
308904
309170
  } catch (error) {
308905
- if (error instanceof APIUserAbortError3 || error instanceof AbortError2) {
309171
+ if (error instanceof APIUserAbortError2 || error instanceof AbortError2) {
308906
309172
  callbacks.onComplete?.();
308907
309173
  return;
308908
309174
  }
@@ -320944,7 +321210,7 @@ var init_tools3 = __esm(() => {
320944
321210
  });
320945
321211
 
320946
321212
  // src/tui/utils/model/providers.ts
320947
- function isFirstPartyGatewayUrl() {
321213
+ function isDefaultGateway() {
320948
321214
  return !process.env.OPENAI_BASE_URL;
320949
321215
  }
320950
321216
 
@@ -321005,7 +321271,7 @@ async function toolToAPISchema(tool, options) {
321005
321271
  if (strictToolsEnabled && tool.strict === true && options.model && modelSupportsStructuredOutputs(options.model)) {
321006
321272
  base.strict = true;
321007
321273
  }
321008
- if (isFirstPartyGatewayUrl() && (getFeatureValue_CACHED_MAY_BE_STALE("atlas_fgts", false) || isEnvTruthy2(process.env.ATLAS_ENABLE_FINE_GRAINED_TOOL_STREAMING))) {
321274
+ if (isDefaultGateway() && (getFeatureValue_CACHED_MAY_BE_STALE("atlas_fgts", false) || isEnvTruthy2(process.env.ATLAS_ENABLE_FINE_GRAINED_TOOL_STREAMING))) {
321009
321275
  base.eager_input_streaming = true;
321010
321276
  }
321011
321277
  cache.set(cacheKey, base);
@@ -326019,7 +326285,7 @@ function isToolSearchEnabledOptimistic2() {
326019
326285
  }
326020
326286
  return false;
326021
326287
  }
326022
- if (!process.env.ENABLE_TOOL_SEARCH && !isFirstPartyGatewayUrl()) {
326288
+ if (!process.env.ENABLE_TOOL_SEARCH && !isDefaultGateway()) {
326023
326289
  if (!loggedOptimistic2) {
326024
326290
  loggedOptimistic2 = true;
326025
326291
  logForDebugging3(`[ToolSearch:optimistic] disabled: OPENAI_BASE_URL=${process.env.OPENAI_BASE_URL} is not a first-party host. Set ENABLE_TOOL_SEARCH=true (or auto / auto:N) if your proxy forwards tool_reference blocks.`);
@@ -335389,6 +335655,22 @@ ${EXPLANATORY_FEATURE_PROMPT}`
335389
335655
  });
335390
335656
  });
335391
335657
 
335658
+ // src/tui/utils/messageDisplayHooks.ts
335659
+ function fireMessageDisplayHooks(message) {
335660
+ (async () => {
335661
+ try {
335662
+ for await (const _hookResult of executeMessageDisplayHooks(message, undefined, MESSAGE_DISPLAY_HOOK_TIMEOUT_MS)) {}
335663
+ } catch (e) {
335664
+ logForDebugging3(`MessageDisplay hook execution failed: ${e instanceof Error ? e.message : String(e)}`);
335665
+ }
335666
+ })();
335667
+ }
335668
+ var MESSAGE_DISPLAY_HOOK_TIMEOUT_MS = 15000;
335669
+ var init_messageDisplayHooks = __esm(() => {
335670
+ init_debug();
335671
+ init_hooks7();
335672
+ });
335673
+
335392
335674
  // src/tui/utils/messages.ts
335393
335675
  import { randomUUID as randomUUID36 } from "crypto";
335394
335676
  function isFeatureOn(name) {
@@ -336805,8 +337087,8 @@ function getContentText(content) {
336805
337087
  }
336806
337088
  return null;
336807
337089
  }
336808
- function handleMessageFromStream(message, onMessage, onUpdateLength, onSetStreamMode, onStreamingToolUses, onTombstone, onStreamingThinking, onApiMetrics, onStreamingText) {
336809
- if (message.type !== "stream_event" && message.type !== "stream_request_start" && message.type !== "stream_delta") {
337090
+ function handleMessageFromStream(message, onMessage, onUpdateLength, onSetStreamMode, onStreamingToolUses, onTombstone, onStreamingThinking, onApiMetrics, onStreamingText, onToolHeartbeat) {
337091
+ if (message.type !== "stream_event" && message.type !== "stream_request_start" && message.type !== "stream_delta" && message.type !== "tool_heartbeat") {
336810
337092
  if (message.type === "tombstone") {
336811
337093
  onTombstone?.(message.message);
336812
337094
  return;
@@ -336823,6 +337105,9 @@ function handleMessageFromStream(message, onMessage, onUpdateLength, onSetStream
336823
337105
  streamingEndedAt: Date.now()
336824
337106
  }));
336825
337107
  }
337108
+ const displayText = getContentText(message.message.content);
337109
+ if (displayText)
337110
+ fireMessageDisplayHooks(displayText);
336826
337111
  }
336827
337112
  onStreamingText?.(() => null);
336828
337113
  onMessage(message);
@@ -336832,6 +337117,10 @@ function handleMessageFromStream(message, onMessage, onUpdateLength, onSetStream
336832
337117
  onSetStreamMode("requesting");
336833
337118
  return;
336834
337119
  }
337120
+ if (message.type === "tool_heartbeat") {
337121
+ onToolHeartbeat?.({ toolName: message.toolName, elapsedMs: message.elapsedMs });
337122
+ return;
337123
+ }
336835
337124
  if (message.type === "stream_delta") {
336836
337125
  if (message.delta.type === "text_delta") {
336837
337126
  onSetStreamMode("responding");
@@ -338287,6 +338576,7 @@ var init_messages3 = __esm(() => {
338287
338576
  init_shared();
338288
338577
  init_last();
338289
338578
  init_outputStyles();
338579
+ init_messageDisplayHooks();
338290
338580
  init_paths3();
338291
338581
  init_growthbook();
338292
338582
  init_modelprovider2();
@@ -339528,7 +339818,7 @@ async function checkRuleBasedPermissions(tool, input, context) {
339528
339818
  const parsedInput = tool.inputSchema.parse(input);
339529
339819
  toolPermissionResult = await tool.checkPermissions(parsedInput, context);
339530
339820
  } catch (e) {
339531
- if (e instanceof AbortError2 || e instanceof APIUserAbortError3) {
339821
+ if (e instanceof AbortError2 || e instanceof APIUserAbortError2) {
339532
339822
  throw e;
339533
339823
  }
339534
339824
  logError3(e);
@@ -339582,7 +339872,7 @@ async function hasPermissionsToUseToolInner(tool, input, context) {
339582
339872
  const parsedInput = tool.inputSchema.parse(input);
339583
339873
  toolPermissionResult = await tool.checkPermissions(parsedInput, context);
339584
339874
  } catch (e) {
339585
- if (e instanceof AbortError2 || e instanceof APIUserAbortError3) {
339875
+ if (e instanceof AbortError2 || e instanceof APIUserAbortError2) {
339586
339876
  throw e;
339587
339877
  }
339588
339878
  logError3(e);
@@ -339816,7 +340106,7 @@ var classifierDecisionModule, autoModeStateModule3, CLASSIFIER_FAIL_CLOSED_REFRE
339816
340106
  };
339817
340107
  }
339818
340108
  } catch (e) {
339819
- if (e instanceof AbortError2 || e instanceof APIUserAbortError3) {
340109
+ if (e instanceof AbortError2 || e instanceof APIUserAbortError2) {
339820
340110
  throw e;
339821
340111
  }
339822
340112
  }
@@ -345051,6 +345341,22 @@ var init_AddWorkspaceDirectory = __esm(() => {
345051
345341
  }];
345052
345342
  });
345053
345343
 
345344
+ // src/tui/utils/directoryAddedHooks.ts
345345
+ function fireDirectoryAddedHooks(directory, source) {
345346
+ (async () => {
345347
+ try {
345348
+ for await (const _hookResult of executeDirectoryAddedHooks(directory, source, undefined, DIRECTORY_ADDED_HOOK_TIMEOUT_MS)) {}
345349
+ } catch (e) {
345350
+ logForDebugging3(`DirectoryAdded hook execution failed: ${e instanceof Error ? e.message : String(e)}`);
345351
+ }
345352
+ })();
345353
+ }
345354
+ var DIRECTORY_ADDED_HOOK_TIMEOUT_MS = 15000;
345355
+ var init_directoryAddedHooks = __esm(() => {
345356
+ init_debug();
345357
+ init_hooks7();
345358
+ });
345359
+
345054
345360
  // src/tui/commands/add-dir/add-dir.tsx
345055
345361
  var exports_add_dir = {};
345056
345362
  __export(exports_add_dir, {
@@ -345156,6 +345462,7 @@ async function call2(onDone, context, args) {
345156
345462
  message = `Added ${source_default.bold(path)} as a working directory for this session`;
345157
345463
  }
345158
345464
  const messageWithHint = `${message} ${source_default.dim("· /permissions to manage")}`;
345465
+ fireDirectoryAddedHooks(path, destination);
345159
345466
  onDone(messageWithHint);
345160
345467
  };
345161
345468
  if (!directoryPath) {
@@ -345196,6 +345503,7 @@ var init_add_dir = __esm(() => {
345196
345503
  init_PermissionUpdate();
345197
345504
  init_sandboxCompat();
345198
345505
  init_validation4();
345506
+ init_directoryAddedHooks();
345199
345507
  import_compiler_runtime110 = __toESM(require_compiler_runtime(), 1);
345200
345508
  import_react77 = __toESM(require_react(), 1);
345201
345509
  jsx_dev_runtime132 = __toESM(require_jsx_dev_runtime(), 1);
@@ -352148,11 +352456,11 @@ function buildAccountProperties() {
352148
352456
  }
352149
352457
  function buildAPIProviderProperties() {
352150
352458
  const properties = [];
352151
- const anthropicBaseUrl = process.env.OPENAI_BASE_URL;
352152
- if (anthropicBaseUrl) {
352459
+ const baseUrl = process.env.OPENAI_BASE_URL;
352460
+ if (baseUrl) {
352153
352461
  properties.push({
352154
352462
  label: "API base URL",
352155
- value: anthropicBaseUrl
352463
+ value: baseUrl
352156
352464
  });
352157
352465
  }
352158
352466
  const proxyUrl = getProxyUrl();
@@ -398943,7 +399251,7 @@ function GenerateStep() {
398943
399251
  });
398944
399252
  goToStep(6);
398945
399253
  } catch (err) {
398946
- if (err instanceof APIUserAbortError3) {} else if (err instanceof Error && !err.message.includes("No assistant message found")) {
399254
+ if (err instanceof APIUserAbortError2) {} else if (err instanceof Error && !err.message.includes("No assistant message found")) {
398947
399255
  setError(err.message || "Failed to generate agent");
398948
399256
  }
398949
399257
  updateWizardData({
@@ -420990,7 +421298,7 @@ function meetsAvailabilityRequirement2(cmd) {
420990
421298
  case "claude-ai":
420991
421299
  break;
420992
421300
  case "console":
420993
- if (isFirstPartyGatewayUrl())
421301
+ if (isDefaultGateway())
420994
421302
  return true;
420995
421303
  break;
420996
421304
  case "vendor":
@@ -427457,6 +427765,7 @@ var init_hooks6 = __esm(() => {
427457
427765
  decision: _enum(["approve", "block"]).optional(),
427458
427766
  reason: string2().describe("Explanation for the decision").optional(),
427459
427767
  systemMessage: string2().describe("Warning message shown to the user").optional(),
427768
+ terminalSequence: string2().optional(),
427460
427769
  hookSpecificOutput: union([
427461
427770
  object({
427462
427771
  hookEventName: literal("PreToolUse"),
@@ -428465,6 +428774,9 @@ function processHookJSONOutput({
428465
428774
  if (json.systemMessage) {
428466
428775
  result.systemMessage = json.systemMessage;
428467
428776
  }
428777
+ if (json.terminalSequence) {
428778
+ result.terminalSequence = json.terminalSequence;
428779
+ }
428468
428780
  if (json.hookSpecificOutput?.hookEventName === "PreToolUse" && json.hookSpecificOutput.permissionDecision) {
428469
428781
  switch (json.hookSpecificOutput.permissionDecision) {
428470
428782
  case "allow":
@@ -429105,6 +429417,9 @@ async function getMatchingHooks2(appState, sessionId, hookEvent, hookInput, tool
429105
429417
  case "PostModelSwitch":
429106
429418
  matchQuery = hookInput.new_model;
429107
429419
  break;
429420
+ case "DirectoryAdded":
429421
+ matchQuery = hookInput.directory;
429422
+ break;
429108
429423
  default:
429109
429424
  break;
429110
429425
  }
@@ -429782,6 +430097,11 @@ async function* executeHooks({
429782
430097
  let permissionBehavior;
429783
430098
  for await (const result of all2(hookPromises)) {
429784
430099
  outcomes[result.outcome]++;
430100
+ if (result.terminalSequence) {
430101
+ try {
430102
+ process.stdout.write(result.terminalSequence);
430103
+ } catch {}
430104
+ }
429785
430105
  if (result.preventContinuation) {
429786
430106
  logForDebugging3(`Hook ${hookEvent} (${getHookDisplayText(result.hook)}) requested preventContinuation`);
429787
430107
  yield {
@@ -430277,6 +430597,35 @@ async function* executePostModelSwitchHooks(oldModel, newModel, source, signal,
430277
430597
  timeoutMs
430278
430598
  });
430279
430599
  }
430600
+ async function* executeDirectoryAddedHooks(directory, source, signal, timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS) {
430601
+ const hookInput = {
430602
+ ...createBaseHookInput2(undefined),
430603
+ hook_event_name: "DirectoryAdded",
430604
+ directory,
430605
+ source
430606
+ };
430607
+ yield* executeHooks({
430608
+ hookInput,
430609
+ toolUseID: randomUUID43(),
430610
+ matchQuery: directory,
430611
+ signal,
430612
+ timeoutMs
430613
+ });
430614
+ }
430615
+ async function* executeMessageDisplayHooks(message, signal, timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS) {
430616
+ const hookInput = {
430617
+ ...createBaseHookInput2(undefined),
430618
+ hook_event_name: "MessageDisplay",
430619
+ message
430620
+ };
430621
+ yield* executeHooks({
430622
+ hookInput,
430623
+ toolUseID: randomUUID43(),
430624
+ matchQuery: undefined,
430625
+ signal,
430626
+ timeoutMs
430627
+ });
430628
+ }
430280
430629
  async function* executeSetupHooks(trigger, signal, timeoutMs = TOOL_HOOK_EXECUTION_TIMEOUT_MS, forceSyncExecution) {
430281
430630
  const hookInput = {
430282
430631
  ...createBaseHookInput2(undefined),
@@ -431940,7 +432289,7 @@ async function streamCompactSummary({
431940
432289
  }
431941
432290
  if (attempt < maxAttempts) {
431942
432291
  await sleep9(getRetryDelay(attempt), context.abortController.signal, {
431943
- abortError: () => new APIUserAbortError3
432292
+ abortError: () => new APIUserAbortError2
431944
432293
  });
431945
432294
  continue;
431946
432295
  }
@@ -433192,13 +433541,17 @@ function truncateEntrypointContent(raw) {
433192
433541
  const byteCount = trimmed.length;
433193
433542
  const wasLineTruncated = lineCount > MAX_ENTRYPOINT_LINES;
433194
433543
  const wasByteTruncated = byteCount > MAX_ENTRYPOINT_BYTES;
433544
+ const nearLimit = (lineCount >= NEAR_LIMIT_LINES || byteCount >= NEAR_LIMIT_BYTES) && !wasLineTruncated && !wasByteTruncated;
433195
433545
  if (!wasLineTruncated && !wasByteTruncated) {
433196
433546
  return {
433197
- content: trimmed,
433547
+ content: nearLimit ? trimmed + `
433548
+
433549
+ > NOTE: ${ENTRYPOINT_NAME} is close to the read limit (${lineCount} lines / ${formatFileSize3(byteCount)}; limits: ${MAX_ENTRYPOINT_LINES} lines / ${formatFileSize3(MAX_ENTRYPOINT_BYTES)}). ${COMPACT_NOW_DIRECTIVE}` : trimmed,
433198
433550
  lineCount,
433199
433551
  byteCount,
433200
433552
  wasLineTruncated,
433201
- wasByteTruncated
433553
+ wasByteTruncated,
433554
+ nearLimit
433202
433555
  };
433203
433556
  }
433204
433557
  let truncated = wasLineTruncated ? contentLines.slice(0, MAX_ENTRYPOINT_LINES).join(`
@@ -433212,11 +433565,12 @@ function truncateEntrypointContent(raw) {
433212
433565
  return {
433213
433566
  content: truncated + `
433214
433567
 
433215
- > WARNING: ${ENTRYPOINT_NAME} is ${reason}. Only part of it was loaded. Keep index entries to one line under ~200 chars; move detail into topic files.`,
433568
+ > WARNING: ${ENTRYPOINT_NAME} is ${reason}. Only part of it was loaded. Keep index entries to one line under ~200 chars; move detail into topic files. ${COMPACT_NOW_DIRECTIVE}`,
433216
433569
  lineCount,
433217
433570
  byteCount,
433218
433571
  wasLineTruncated,
433219
- wasByteTruncated
433572
+ wasByteTruncated,
433573
+ nearLimit: true
433220
433574
  };
433221
433575
  }
433222
433576
  async function ensureMemoryDirExists(memoryDir, store) {
@@ -433360,7 +433714,7 @@ async function loadMemoryPrompt(store) {
433360
433714
  if (getFeatureValue_CACHED_MAY_BE_STALE("atlas_herring_clock", false)) {}
433361
433715
  return null;
433362
433716
  }
433363
- var teamMemPaths5, ENTRYPOINT_NAME = "MEMORY.md", MAX_ENTRYPOINT_LINES = 200, MAX_ENTRYPOINT_BYTES = 25000, teamMemPrompts, DIR_EXISTS_GUIDANCE = "This directory already exists — write to it directly with the Write tool (do not run mkdir or check for its existence).", DIRS_EXIST_GUIDANCE = "Both directories already exist — write to them directly with the Write tool (do not run mkdir or check for their existence).";
433717
+ var teamMemPaths5, ENTRYPOINT_NAME = "MEMORY.md", MAX_ENTRYPOINT_LINES = 200, MAX_ENTRYPOINT_BYTES = 25000, NEAR_LIMIT_FRACTION = 0.8, NEAR_LIMIT_LINES, NEAR_LIMIT_BYTES, COMPACT_NOW_DIRECTIVE = "Compact it now: merge duplicate entries and prune stale ones before adding new lines.", teamMemPrompts, DIR_EXISTS_GUIDANCE = "This directory already exists — write to it directly with the Write tool (do not run mkdir or check for its existence).", DIRS_EXIST_GUIDANCE = "Both directories already exist — write to them directly with the Write tool (do not run mkdir or check for their existence).";
433364
433718
  var init_memdir = __esm(() => {
433365
433719
  init_shared();
433366
433720
  init_memory();
@@ -433378,6 +433732,8 @@ var init_memdir = __esm(() => {
433378
433732
  init_sessionStorage();
433379
433733
  init_memoryTypes2();
433380
433734
  teamMemPaths5 = feature("TEAMMEM") ? (init_teamMemPaths(), __toCommonJS(exports_teamMemPaths)) : null;
433735
+ NEAR_LIMIT_LINES = Math.floor(MAX_ENTRYPOINT_LINES * NEAR_LIMIT_FRACTION);
433736
+ NEAR_LIMIT_BYTES = Math.floor(MAX_ENTRYPOINT_BYTES * NEAR_LIMIT_FRACTION);
433381
433737
  teamMemPrompts = feature("TEAMMEM") ? (init_teamMemPrompts(), __toCommonJS(exports_teamMemPrompts)) : null;
433382
433738
  });
433383
433739
 
@@ -468563,7 +468919,7 @@ function useCanUseTool(setToolUseConfirmQueue, setToolPermissionContext) {
468563
468919
  }
468564
468920
  }
468565
468921
  }).catch((error) => {
468566
- if (error instanceof AbortError2 || error instanceof APIUserAbortError3) {
468922
+ if (error instanceof AbortError2 || error instanceof APIUserAbortError2) {
468567
468923
  logForDebugging3(`Permission check threw ${error.constructor.name} for tool=${tool.name}: ${error.message}`);
468568
468924
  ctx.logCancelled();
468569
468925
  resolve(ctx.cancelAndAbort(undefined, true));
@@ -471825,7 +472181,7 @@ async function generateAwaySummary(messages, signal) {
471825
472181
  });
471826
472182
  return getAssistantMessageText2(response);
471827
472183
  } catch (err) {
471828
- if (err instanceof APIUserAbortError3 || signal.aborted) {
472184
+ if (err instanceof APIUserAbortError2 || signal.aborted) {
471829
472185
  return null;
471830
472186
  }
471831
472187
  logForDebugging3(`[awaySummary] generation failed: ${err}`);
@@ -479465,6 +479821,9 @@ Error: sandbox required but unavailable: ${reason}
479465
479821
  onBackgroundQuery: handleBackgroundQuery
479466
479822
  });
479467
479823
  const onQueryEvent = import_react282.useCallback((event) => {
479824
+ if (event.type === "stream_request_start") {
479825
+ setAppState((prev) => ({ ...prev, spinnerTip: undefined }));
479826
+ }
479468
479827
  handleMessageFromStream(event, (newMessage) => {
479469
479828
  if (isCompactBoundaryMessage2(newMessage)) {
479470
479829
  if (isFullscreenEnvEnabled()) {
@@ -479503,8 +479862,13 @@ Error: sandbox required but unavailable: ${reason}
479503
479862
  responseLengthBaseline: baseline,
479504
479863
  endResponseLength: baseline
479505
479864
  });
479506
- }, onStreamingText);
479507
- }, [setMessages, setResponseLength, setStreamMode, setStreamingToolUses, setStreamingThinking, onStreamingText]);
479865
+ }, onStreamingText, (info) => {
479866
+ setAppState((prev) => ({
479867
+ ...prev,
479868
+ spinnerTip: `${info.toolName} 仍在运行 · ${Math.round(info.elapsedMs / 1000)}s`
479869
+ }));
479870
+ });
479871
+ }, [setMessages, setResponseLength, setStreamMode, setStreamingToolUses, setStreamingThinking, onStreamingText, setAppState]);
479508
479872
  const onQueryImpl = import_react282.useCallback(async (messagesIncludingNewMessages, newMessages, abortController, shouldQuery, additionalAllowedTools, mainLoopModelParam, effort) => {
479509
479873
  if (shouldQuery) {
479510
479874
  const freshClients = mergeClients(initialMcpClients, store.getState().mcp.clients);
@@ -479620,8 +479984,30 @@ Error: sandbox required but unavailable: ${reason}
479620
479984
  toolUseContext,
479621
479985
  querySource: getQuerySourceForREPL()
479622
479986
  });
479987
+ const controller = abortController;
479988
+ const handleMcpToolBackgrounded = (info) => {
479989
+ if (controller.signal.aborted)
479990
+ return;
479991
+ let text;
479992
+ if (info.outcome.ok === true) {
479993
+ let serialized;
479994
+ try {
479995
+ serialized = typeof info.outcome.data === "string" ? info.outcome.data : JSON.stringify(info.outcome.data, null, 2);
479996
+ } catch {
479997
+ serialized = String(info.outcome.data);
479998
+ }
479999
+ if (serialized.length > 1e4)
480000
+ serialized = `${serialized.slice(0, 1e4)}
480001
+ …(结果过长已截断)`;
480002
+ text = `【后台 MCP 工具完成】${info.toolName}(后台运行)已完成,结果如下:
480003
+ ${serialized}`;
480004
+ } else {
480005
+ text = `【后台 MCP 工具失败】${info.toolName}(后台运行)失败:${info.outcome.error}`;
480006
+ }
480007
+ enqueuePendingNotification2({ value: text, mode: "task-notification" });
480008
+ };
479623
480009
  const loopGen = queryEngineLoopStream({
479624
- deps: loopDeps,
480010
+ deps: { ...loopDeps, onMcpToolBackgrounded: handleMcpToolBackgrounded },
479625
480011
  args: loopArgs
479626
480012
  });
479627
480013
  let loopResult;
@@ -488986,6 +489372,14 @@ To attach: ${source_default.bold(`tmux attach -t ${tmuxSessionName}`)}`));
488986
489372
  await getRecentActivity();
488987
489373
  }
488988
489374
  }
489375
+ const restrictedBypassErr = restrictedBypassError({
489376
+ permissionMode,
489377
+ allowDangerouslySkipPermissions
489378
+ });
489379
+ if (restrictedBypassErr) {
489380
+ console.error(`Error: ${restrictedBypassErr}`);
489381
+ process.exit(1);
489382
+ }
488989
489383
  if (permissionMode === "bypassPermissions" || allowDangerouslySkipPermissions) {
488990
489384
  if (process.platform !== "win32" && typeof process.getuid === "function" && process.getuid() === 0 && process.env.IS_SANDBOX !== "1" && !isEnvTruthy2(process.env.ATLAS_BUBBLEWRAP)) {
488991
489385
  console.error(`--dangerously-skip-permissions cannot be used with root/sudo privileges for security reasons`);
@@ -489004,6 +489398,7 @@ var init_setup4 = __esm(() => {
489004
489398
  init_Shell2();
489005
489399
  init_sinks();
489006
489400
  init_bootstrap();
489401
+ init_engine();
489007
489402
  init_commands5();
489008
489403
  init_sessionMemory2();
489009
489404
  init_ids();
@@ -492590,7 +492985,7 @@ async function run() {
492590
492985
  throw new Error("--task-budget must be a positive integer");
492591
492986
  }
492592
492987
  return tokens;
492593
- }).hideHelp()).option("--replay-user-messages", "Re-emit user messages from stdin back on stdout for acknowledgment (only works with --input-format=stream-json and --output-format=stream-json)", () => true).addOption(new Option("--enable-auth-status", "Enable auth status messages in SDK mode").default(false).hideHelp()).option("--allowedTools, --allowed-tools <tools...>", 'Comma or space-separated list of tool names to allow (e.g. "Bash(git:*) Edit")').option("--tools <tools...>", 'Specify the list of available tools from the built-in set. Use "" to disable all tools, "default" to use all tools, or specify tool names (e.g. "Bash,Edit,Read").').option("--disallowedTools, --disallowed-tools <tools...>", 'Comma or space-separated list of tool names to deny (e.g. "Bash(git:*) Edit")').option("--mcp-config <configs...>", "Load MCP servers from JSON files or strings (space-separated)").addOption(new Option("--permission-prompt-tool <tool>", "MCP tool to use for permission prompts (only works with --print)").argParser(String).hideHelp()).addOption(new Option("--system-prompt <prompt>", "System prompt to use for the session").argParser(String)).addOption(new Option("--system-prompt-file <file>", "Read system prompt from a file").argParser(String).hideHelp()).addOption(new Option("--append-system-prompt <prompt>", "Append a system prompt to the default system prompt").argParser(String)).addOption(new Option("--append-system-prompt-file <file>", "Read system prompt from a file and append to the default system prompt").argParser(String).hideHelp()).addOption(new Option("--permission-mode <mode>", "Permission mode to use for the session").argParser(String).choices(PERMISSION_MODES2)).addOption(new Option("--permission-prompts <mode>", "Permission prompt policy; 'none' auto-denies prompts that would otherwise ask").argParser(String).choices(["none"])).option("-c, --continue", "Continue the most recent conversation in the current directory", () => true).option("-r, --resume [value]", "Resume a conversation by session ID, or open interactive picker with optional search term", (value) => value || true).option("--fork-session", "When resuming, create a new session ID instead of reusing the original (use with --resume or --continue)", () => true).addOption(new Option("--prefill <text>", "Pre-fill the prompt input with text without submitting it").hideHelp()).addOption(new Option("--deep-link-origin", "Signal that this session was launched from a deep link").hideHelp()).addOption(new Option("--deep-link-repo <slug>", "Repo slug the deep link ?repo= parameter resolved to the current cwd").hideHelp()).addOption(new Option("--deep-link-last-fetch <ms>", "FETCH_HEAD mtime in epoch ms, precomputed by the deep link trampoline").argParser((v) => {
492988
+ }).hideHelp()).option("--replay-user-messages", "Re-emit user messages from stdin back on stdout for acknowledgment (only works with --input-format=stream-json and --output-format=stream-json)", () => true).addOption(new Option("--enable-auth-status", "Enable auth status messages in SDK mode").default(false).hideHelp()).option("--allowedTools, --allowed-tools <tools...>", 'Comma or space-separated list of tool names to allow (e.g. "Bash(git:*) Edit")').option("--tools <tools...>", 'Specify the list of available tools from the built-in set. Use "" to disable all tools, "default" to use all tools, or specify tool names (e.g. "Bash,Edit,Read").').option("--disallowedTools, --disallowed-tools <tools...>", 'Comma or space-separated list of tool names to deny (e.g. "Bash(git:*) Edit")').option("--mcp-config <configs...>", "Load MCP servers from JSON files or strings (space-separated)").addOption(new Option("--permission-prompt-tool <tool>", "MCP tool to use for permission prompts (only works with --print)").argParser(String).hideHelp()).addOption(new Option("--system-prompt <prompt>", "System prompt to use for the session").argParser(String)).addOption(new Option("--system-prompt-file <file>", "Read system prompt from a file").argParser(String).hideHelp()).addOption(new Option("--append-system-prompt <prompt>", "Append a system prompt to the default system prompt").argParser(String)).addOption(new Option("--append-system-prompt-file <file>", "Read system prompt from a file and append to the default system prompt").argParser(String).hideHelp()).addOption(new Option("--permission-mode <mode>", "Permission mode to use for the session").argParser(String).choices(PERMISSION_MODES2)).addOption(new Option("--permission-prompts <mode>", "Permission prompt policy; 'none' auto-denies prompts that would otherwise ask").argParser(String).choices(["none"])).option("--restricted", "Run in restricted mode: strips command-execution tools (Bash/PowerShell), WebFetch, and Agent; rejects bypassPermissions and --dangerously-skip-permissions; ignores user/project/local settings (env: ATLAS_RESTRICTED)", () => true).option("-c, --continue", "Continue the most recent conversation in the current directory", () => true).option("-r, --resume [value]", "Resume a conversation by session ID, or open interactive picker with optional search term", (value) => value || true).option("--fork-session", "When resuming, create a new session ID instead of reusing the original (use with --resume or --continue)", () => true).addOption(new Option("--prefill <text>", "Pre-fill the prompt input with text without submitting it").hideHelp()).addOption(new Option("--deep-link-origin", "Signal that this session was launched from a deep link").hideHelp()).addOption(new Option("--deep-link-repo <slug>", "Repo slug the deep link ?repo= parameter resolved to the current cwd").hideHelp()).addOption(new Option("--deep-link-last-fetch <ms>", "FETCH_HEAD mtime in epoch ms, precomputed by the deep link trampoline").argParser((v) => {
492594
492989
  const n = Number(v);
492595
492990
  return Number.isFinite(n) ? n : undefined;
492596
492991
  }).hideHelp()).option("--from-pr [value]", "Resume a session linked to a PR by PR number/URL, or open interactive picker with optional search term", (value) => value || true).option("--no-session-persistence", "Disable session persistence - sessions will not be saved to disk and cannot be resumed (only works with --print)").addOption(new Option("--resume-session-at <message id>", "When resuming, only messages up to and including the assistant message with <message.id> (use with --resume in print mode)").argParser(String).hideHelp()).addOption(new Option("--rewind-files <user-message-id>", "Restore files to state at the specified user message and exit (requires --resume)").hideHelp()).option("--model <model>", `Model for the current session. Provide a role alias (e.g. 'small' or 'premium') or a provider/model reference (e.g. 'bailian/qwen38-27b').`).addOption(new Option("--effort <level>", `Effort level for the current session (low, medium, high, xhigh, max)`).argParser((rawValue) => {
@@ -492630,6 +493025,18 @@ async function run() {
492630
493025
  includePartialMessages
492631
493026
  } = options;
492632
493027
  const permissionModeCli = permissionModeCliRaw ?? (permissionPrompts === "none" ? "dontAsk" : undefined);
493028
+ if (options.restricted === true) {
493029
+ setRestrictedMode(true);
493030
+ const restrictedBypassErr = restrictedBypassError({
493031
+ permissionMode: permissionModeCliRaw,
493032
+ allowDangerouslySkipPermissions,
493033
+ dangerouslySkipPermissions
493034
+ });
493035
+ if (restrictedBypassErr) {
493036
+ console.error(`Error: ${restrictedBypassErr}`);
493037
+ process.exit(1);
493038
+ }
493039
+ }
492633
493040
  if (options.prefill) {
492634
493041
  seedEarlyInput(options.prefill);
492635
493042
  }