@atlasharness/atlascode 0.1.50 → 0.1.52

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 +986 -373
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -27939,7 +27939,14 @@ This tool's schema was not sent to the API — it was not in the discovered-tool
27939
27939
  }
27940
27940
 
27941
27941
  // src/engine/pipeline/toolExecution.ts
27942
- function mergeHookPermission(hookBehavior, gate) {
27942
+ function mergeHookPermission(hookBehavior, gate, hookReason) {
27943
+ if (hookBehavior === "defer") {
27944
+ return {
27945
+ allowed: false,
27946
+ deferred: true,
27947
+ reason: hookReason ?? "deferred by hook"
27948
+ };
27949
+ }
27943
27950
  if (hookBehavior === "deny") {
27944
27951
  return { allowed: false, reason: "blocked by hook" };
27945
27952
  }
@@ -28022,7 +28029,10 @@ async function executeToolUse(tu, assistantMsg, deps) {
28022
28029
  toolUseId: tu.id,
28023
28030
  assistantMessage: assistantMsg
28024
28031
  }) : { allowed: true };
28025
- const verdict = mergeHookPermission(preOutcome?.hookBehavior, gateVerdict);
28032
+ const verdict = mergeHookPermission(preOutcome?.hookBehavior, gateVerdict, preOutcome?.hookPermissionDecisionReason);
28033
+ if (verdict.deferred) {
28034
+ return { deferred: true, deferReason: verdict.reason, isError: false };
28035
+ }
28026
28036
  if (!verdict.allowed) {
28027
28037
  const content = verdict.ask ? `<tool_use_error>permission confirmation required (prompt 面残留守): ${verdict.reason ?? tu.name}</tool_use_error>` : `<tool_use_error>permission denied: ${verdict.reason ?? tu.name}</tool_use_error>`;
28028
28038
  return {
@@ -28087,8 +28097,13 @@ async function runToolBatch(toolUses, assistantMsg, deps) {
28087
28097
  name: tu.name,
28088
28098
  block: r.block,
28089
28099
  isError: r.isError,
28090
- toolUseResult: r.toolUseResult
28100
+ toolUseResult: r.toolUseResult,
28101
+ deferred: r.deferred,
28102
+ deferReason: r.deferReason
28091
28103
  });
28104
+ if (r.deferred) {
28105
+ return outcomes;
28106
+ }
28092
28107
  }
28093
28108
  }
28094
28109
  return outcomes;
@@ -28371,6 +28386,14 @@ function interpretHookOutput(p) {
28371
28386
  };
28372
28387
  } else if (specific?.permissionDecision === "ask") {
28373
28388
  result.permissionBehavior = "ask";
28389
+ if (specific.permissionDecisionReason) {
28390
+ result.permissionDecisionReason = specific.permissionDecisionReason;
28391
+ }
28392
+ } else if (specific?.permissionDecision === "defer") {
28393
+ result.permissionBehavior = "defer";
28394
+ if (specific.permissionDecisionReason) {
28395
+ result.permissionDecisionReason = specific.permissionDecisionReason;
28396
+ }
28374
28397
  }
28375
28398
  if (specific?.additionalContext)
28376
28399
  result.additionalContext = specific.additionalContext;
@@ -28410,6 +28433,7 @@ ${r.additionalContext}` : r.additionalContext;
28410
28433
  if (r.permissionBehavior) {
28411
28434
  if (!acc.permissionBehavior || PERMISSION_RANK[r.permissionBehavior] > PERMISSION_RANK[acc.permissionBehavior]) {
28412
28435
  acc.permissionBehavior = r.permissionBehavior;
28436
+ acc.permissionDecisionReason = r.permissionDecisionReason;
28413
28437
  }
28414
28438
  }
28415
28439
  }
@@ -28483,6 +28507,7 @@ var init_runHooks = __esm(() => {
28483
28507
  init_shouldSkipHookDueToTrust();
28484
28508
  HOOK_EXECUTION_TIMEOUT_MS = 10 * 60 * 1000;
28485
28509
  PERMISSION_RANK = {
28510
+ defer: 4,
28486
28511
  deny: 3,
28487
28512
  ask: 2,
28488
28513
  allow: 1,
@@ -28667,7 +28692,8 @@ var SettingsSchema = () => object({
28667
28692
  respectGitignore: boolean2().optional(),
28668
28693
  defaultShell: union([literal("bash"), literal("powershell")]).optional(),
28669
28694
  skipWebFetchPreflight: boolean2().optional(),
28670
- search: object({ tavilyApiKey: string2().optional() }).optional()
28695
+ search: object({ tavilyApiKey: string2().optional() }).optional(),
28696
+ tui: object({ fullscreen: boolean2().optional() }).optional()
28671
28697
  }).passthrough();
28672
28698
  var init_types3 = __esm(() => {
28673
28699
  init_zod();
@@ -28834,7 +28860,7 @@ var _provider3 = null;
28834
28860
 
28835
28861
  // src/permissions/filesystem.ts
28836
28862
  import { tmpdir } from "os";
28837
- import { join as join4, posix, sep } from "path";
28863
+ import { join as join4, posix, resolve as resolve2, sep } from "path";
28838
28864
  function expandPathLocal(path) {
28839
28865
  return expandPath(path, getPermissionsBootstrapEnv().getCwd());
28840
28866
  }
@@ -28968,11 +28994,36 @@ function checkPathSafetyForAutoEdit(path, precomputedPathsToCheck) {
28968
28994
  }
28969
28995
  return { safe: true };
28970
28996
  }
28997
+ function isActiveWorktreeCwd(cwd) {
28998
+ const cached = worktreeCwdProbeCache.get(cwd);
28999
+ if (cached !== undefined) {
29000
+ return cached;
29001
+ }
29002
+ let active = false;
29003
+ try {
29004
+ const content = getFsImplementation().readFileSync(join4(cwd, ".git"), { encoding: "utf8" });
29005
+ const gitdirMatch = content.match(/^gitdir:\s*(.+)$/m);
29006
+ if (gitdirMatch?.[1]) {
29007
+ const gitdir = resolve2(cwd, gitdirMatch[1].trim());
29008
+ active = gitdir.lastIndexOf(sep + ".git" + sep + "worktrees" + sep) > 0;
29009
+ }
29010
+ } catch {
29011
+ active = false;
29012
+ }
29013
+ worktreeCwdProbeCache.set(cwd, active);
29014
+ return active;
29015
+ }
28971
29016
  function allWorkingDirectories(context) {
28972
- return new Set([
28973
- getPermissionsBootstrapEnv().getOriginalCwd(),
29017
+ const originalCwd = getPermissionsBootstrapEnv().getOriginalCwd();
29018
+ const dirs = [
29019
+ originalCwd,
28974
29020
  ...context.additionalWorkingDirectories.keys()
28975
- ]);
29021
+ ];
29022
+ const cwd = getPermissionsBootstrapEnv().getCwd();
29023
+ if (cwd !== originalCwd && isActiveWorktreeCwd(cwd)) {
29024
+ dirs.push(cwd);
29025
+ }
29026
+ return new Set(dirs);
28976
29027
  }
28977
29028
  function getResolvedWorkingDirPaths(workingPath) {
28978
29029
  const cached = _resolvedWorkingDirCache.get(workingPath);
@@ -29197,7 +29248,7 @@ function checkWritePermissionForTool(tool, input, toolPermissionContext, precomp
29197
29248
  } : undefined
29198
29249
  };
29199
29250
  }
29200
- var DANGEROUS_FILES, DANGEROUS_DIRECTORIES, _atlasTempDir = null, _resolvedWorkingDirCache;
29251
+ var DANGEROUS_FILES, DANGEROUS_DIRECTORIES, _atlasTempDir = null, worktreeCwdProbeCache, _resolvedWorkingDirCache;
29201
29252
  var init_filesystem = __esm(() => {
29202
29253
  init_shared();
29203
29254
  DANGEROUS_FILES = [
@@ -29219,6 +29270,7 @@ var init_filesystem = __esm(() => {
29219
29270
  ".idea",
29220
29271
  getConfigDirName()
29221
29272
  ];
29273
+ worktreeCwdProbeCache = new Map;
29222
29274
  _resolvedWorkingDirCache = new Map;
29223
29275
  });
29224
29276
 
@@ -30132,7 +30184,7 @@ var init_permissionUpdateSchema = __esm(() => {
30132
30184
 
30133
30185
  // src/permissions/pathValidation.ts
30134
30186
  import { homedir as homedir3 } from "os";
30135
- import { dirname as dirname2, isAbsolute as isAbsolute2, resolve as resolve2 } from "path";
30187
+ import { dirname as dirname2, isAbsolute as isAbsolute2, resolve as resolve3 } from "path";
30136
30188
  function formatDirectoryList(directories) {
30137
30189
  const dirCount = directories.length;
30138
30190
  if (dirCount <= MAX_DIRS_TO_LIST) {
@@ -30261,7 +30313,7 @@ function isPathAllowed(resolvedPath, context, operationType, precomputedPathsToC
30261
30313
  }
30262
30314
  function validateGlobPattern(cleanPath, cwd, toolPermissionContext, operationType) {
30263
30315
  if (containsPathTraversal(cleanPath)) {
30264
- const absolutePath = isAbsolute2(cleanPath) ? cleanPath : resolve2(cwd, cleanPath);
30316
+ const absolutePath = isAbsolute2(cleanPath) ? cleanPath : resolve3(cwd, cleanPath);
30265
30317
  const { resolvedPath, isCanonical } = safeResolvePath2(absolutePath);
30266
30318
  const result = isPathAllowed(resolvedPath, toolPermissionContext, operationType, isCanonical ? [resolvedPath] : undefined);
30267
30319
  return {
@@ -30271,7 +30323,7 @@ function validateGlobPattern(cleanPath, cwd, toolPermissionContext, operationTyp
30271
30323
  };
30272
30324
  }
30273
30325
  const basePath = getGlobBaseDirectory(cleanPath);
30274
- const absoluteBasePath = isAbsolute2(basePath) ? basePath : resolve2(cwd, basePath);
30326
+ const absoluteBasePath = isAbsolute2(basePath) ? basePath : resolve3(cwd, basePath);
30275
30327
  const { resolvedPath, isCanonical } = safeResolvePath2(absoluteBasePath);
30276
30328
  const result = isPathAllowed(resolvedPath, toolPermissionContext, operationType, isCanonical ? [resolvedPath] : undefined);
30277
30329
  return {
@@ -30350,7 +30402,7 @@ function validatePath(path, cwd, toolPermissionContext, operationType) {
30350
30402
  }
30351
30403
  return validateGlobPattern(cleanPath, cwd, toolPermissionContext, operationType);
30352
30404
  }
30353
- const absolutePath = isAbsolute2(cleanPath) ? cleanPath : resolve2(cwd, cleanPath);
30405
+ const absolutePath = isAbsolute2(cleanPath) ? cleanPath : resolve3(cwd, cleanPath);
30354
30406
  const { resolvedPath, isCanonical } = safeResolvePath2(absolutePath);
30355
30407
  const result = isPathAllowed(resolvedPath, toolPermissionContext, operationType, isCanonical ? [resolvedPath] : undefined);
30356
30408
  return {
@@ -30939,7 +30991,7 @@ var init_validation = __esm(() => {
30939
30991
  });
30940
30992
 
30941
30993
  // src/engine/config/settings.ts
30942
- import { dirname as dirname3, join as join5, resolve as resolve3 } from "path";
30994
+ import { dirname as dirname3, join as join5, resolve as resolve4 } from "path";
30943
30995
  function getManagedSettingsFilePath() {
30944
30996
  return join5(getManagedSettingsDir(), "managed-settings.json");
30945
30997
  }
@@ -31025,14 +31077,14 @@ function parseSettingsFileUncached(path) {
31025
31077
  function getSettingsRootPathForSource(source) {
31026
31078
  switch (source) {
31027
31079
  case "userSettings":
31028
- return resolve3(getAtlasConfigHomeDir());
31080
+ return resolve4(getAtlasConfigHomeDir());
31029
31081
  case "policySettings":
31030
- return resolve3(getManagedSettingsDir());
31082
+ return resolve4(getManagedSettingsDir());
31031
31083
  case "projectSettings":
31032
31084
  case "localSettings":
31033
- return resolve3(process.cwd());
31085
+ return resolve4(process.cwd());
31034
31086
  case "flagSettings":
31035
- return resolve3(process.cwd());
31087
+ return resolve4(process.cwd());
31036
31088
  }
31037
31089
  }
31038
31090
  function getUserSettingsFilePath() {
@@ -31162,7 +31214,7 @@ function loadSettingsFromDisk() {
31162
31214
  }
31163
31215
  const filePath = getSettingsFilePathForSource(source);
31164
31216
  if (filePath) {
31165
- const resolvedPath = resolve3(filePath);
31217
+ const resolvedPath = resolve4(filePath);
31166
31218
  if (!seenFiles.has(resolvedPath)) {
31167
31219
  seenFiles.add(resolvedPath);
31168
31220
  const { settings, errors } = parseSettingsFile(filePath);
@@ -46017,12 +46069,22 @@ var init_bashCommandHelpers = __esm(() => {
46017
46069
  });
46018
46070
 
46019
46071
  // src/engine/tools/bash/bashReadOnly.ts
46020
- function isReadOnlyCommand(command) {
46072
+ function matchReadOnlyPrefix(command) {
46021
46073
  const trimmed = command.trim();
46022
46074
  if (trimmed.includes("&&") || trimmed.includes("||") || trimmed.includes(";") || trimmed.includes("|") || trimmed.includes("`") || trimmed.includes("$(") || trimmed.includes(">")) {
46023
- return false;
46075
+ return null;
46076
+ }
46077
+ let best = null;
46078
+ for (const p of READ_ONLY_PREFIXES) {
46079
+ if (trimmed === p || trimmed.startsWith(p + " ")) {
46080
+ if (best === null || p.length > best.length)
46081
+ best = p;
46082
+ }
46024
46083
  }
46025
- return READ_ONLY_PREFIXES.some((p) => trimmed === p || trimmed.startsWith(p + " "));
46084
+ return best;
46085
+ }
46086
+ function isReadOnlyCommand(command) {
46087
+ return matchReadOnlyPrefix(command) !== null;
46026
46088
  }
46027
46089
  var READ_ONLY_PREFIXES;
46028
46090
  var init_bashReadOnly = __esm(() => {
@@ -46458,9 +46520,9 @@ var init_permissionPersist = __esm(() => {
46458
46520
 
46459
46521
  // src/engine/tools/bash/pathHelpers.ts
46460
46522
  import { statSync as statSync2 } from "fs";
46461
- import { dirname as dirname7, isAbsolute as isAbsolute3, resolve as resolve4 } from "path";
46523
+ import { dirname as dirname7, isAbsolute as isAbsolute3, resolve as resolve5 } from "path";
46462
46524
  function getDirectoryForPath(path) {
46463
- const absolutePath = isAbsolute3(path) ? path : resolve4(getCwd(), path);
46525
+ const absolutePath = isAbsolute3(path) ? path : resolve5(getCwd(), path);
46464
46526
  if (absolutePath.startsWith("\\\\") || absolutePath.startsWith("//")) {
46465
46527
  return dirname7(absolutePath);
46466
46528
  }
@@ -46478,13 +46540,13 @@ var init_pathHelpers = __esm(() => {
46478
46540
 
46479
46541
  // src/engine/tools/bash/pathValidation.ts
46480
46542
  import { homedir as homedir6 } from "os";
46481
- import { isAbsolute as isAbsolute4, resolve as resolve5 } from "path";
46543
+ import { isAbsolute as isAbsolute4, resolve as resolve6 } from "path";
46482
46544
  function checkDangerousRemovalPaths(command, args, cwd) {
46483
46545
  const extractor = PATH_EXTRACTORS[command];
46484
46546
  const paths = extractor(args);
46485
46547
  for (const path of paths) {
46486
46548
  const cleanPath = expandTilde(path.replace(/^['"]|['"]$/g, ""));
46487
- const absolutePath = isAbsolute4(cleanPath) ? cleanPath : resolve5(cwd, cleanPath);
46549
+ const absolutePath = isAbsolute4(cleanPath) ? cleanPath : resolve6(cwd, cleanPath);
46488
46550
  if (isDangerousRemovalPath(absolutePath)) {
46489
46551
  return {
46490
46552
  behavior: "ask",
@@ -49627,7 +49689,7 @@ var init_shellProvider = () => {};
49627
49689
  // src/executor/shell/Shell.ts
49628
49690
  import { execFileSync, spawn } from "child_process";
49629
49691
  import { accessSync, constants as fsConstants2 } from "fs";
49630
- import { dirname as dirname8, isAbsolute as isAbsolute5, join as join13, resolve as resolve6 } from "path";
49692
+ import { dirname as dirname8, isAbsolute as isAbsolute5, join as join13, resolve as resolve7 } from "path";
49631
49693
  function isExecutable(shellPath) {
49632
49694
  try {
49633
49695
  accessSync(shellPath, fsConstants2.X_OK);
@@ -49781,7 +49843,7 @@ async function exec(command, abortSignal, options) {
49781
49843
  function setCwd(path, relativeTo) {
49782
49844
  const bootstrap = getBootstrapStatePort();
49783
49845
  const fsOps = getFsImplementation();
49784
- const resolved = isAbsolute5(path) ? path : resolve6(relativeTo || bootstrap.getCwd(), path);
49846
+ const resolved = isAbsolute5(path) ? path : resolve7(relativeTo || bootstrap.getCwd(), path);
49785
49847
  let physicalPath;
49786
49848
  try {
49787
49849
  physicalPath = fsOps.realpathSync(resolved);
@@ -51879,7 +51941,7 @@ var init_config3 = __esm(() => {
51879
51941
  });
51880
51942
 
51881
51943
  // src/engine/permissions/permissionSetup.ts
51882
- import { resolve as resolve7 } from "path";
51944
+ import { resolve as resolve8 } from "path";
51883
51945
  function parseBaseToolsFromCLI(baseTools, deps = {}) {
51884
51946
  const joinedInput = baseTools.join(" ").trim();
51885
51947
  const preset = parseToolPreset(joinedInput);
@@ -51893,7 +51955,7 @@ function isSymlinkTo({
51893
51955
  originalCwd
51894
51956
  }) {
51895
51957
  const { resolvedPath: resolvedProcessPwd, isSymlink: isProcessPwdSymlink } = safeResolvePath(getFsImplementation(), processPwd);
51896
- return isProcessPwdSymlink ? resolvedProcessPwd === resolve7(originalCwd) : false;
51958
+ return isProcessPwdSymlink ? resolvedProcessPwd === resolve8(originalCwd) : false;
51897
51959
  }
51898
51960
  function initialPermissionModeFromCLI({
51899
51961
  permissionModeCli,
@@ -54352,7 +54414,7 @@ import {
54352
54414
  join as join15,
54353
54415
  normalize,
54354
54416
  relative,
54355
- resolve as resolve8,
54417
+ resolve as resolve9,
54356
54418
  sep as sep2
54357
54419
  } from "path";
54358
54420
  function getFileModificationTime(filePath) {
@@ -54480,7 +54542,7 @@ function writeFileSyncAndFlush_DEPRECATED(filePath, content, options = { encodin
54480
54542
  let targetPath = filePath;
54481
54543
  try {
54482
54544
  const linkTarget = fs.readlinkSync(filePath);
54483
- targetPath = isAbsolute6(linkTarget) ? linkTarget : resolve8(dirname9(filePath), linkTarget);
54545
+ targetPath = isAbsolute6(linkTarget) ? linkTarget : resolve9(dirname9(filePath), linkTarget);
54484
54546
  logForDebugging(`Writing through symlink: ${filePath} -> ${targetPath}`);
54485
54547
  } catch {}
54486
54548
  const tempPath = `${targetPath}.tmp.${process.pid}.${Date.now()}`;
@@ -55298,7 +55360,7 @@ var init_sandbox_backend = __esm(() => {
55298
55360
  // src/sandbox/createSandboxManager.ts
55299
55361
  import { rmSync, statSync as statSync3 } from "fs";
55300
55362
  import { readFile as readFile3 } from "fs/promises";
55301
- import { join as join16, resolve as resolve10, sep as sep3 } from "path";
55363
+ import { join as join16, resolve as resolve11, sep as sep3 } from "path";
55302
55364
  function memoizeNoArg2(fn) {
55303
55365
  let cached = false;
55304
55366
  let value;
@@ -55341,18 +55403,18 @@ function createSandboxManager(deps, backend) {
55341
55403
  const cwd = deps.getCwd();
55342
55404
  const originalCwd = deps.getOriginalCwd();
55343
55405
  if (cwd !== originalCwd) {
55344
- denyWrite.push(resolve10(cwd, deps.getConfigDirName(), "settings.json"));
55345
- denyWrite.push(resolve10(cwd, deps.getConfigDirName(), "settings.local.json"));
55406
+ denyWrite.push(resolve11(cwd, deps.getConfigDirName(), "settings.json"));
55407
+ denyWrite.push(resolve11(cwd, deps.getConfigDirName(), "settings.local.json"));
55346
55408
  }
55347
- denyWrite.push(resolve10(originalCwd, deps.getConfigDirName(), "skills"));
55409
+ denyWrite.push(resolve11(originalCwd, deps.getConfigDirName(), "skills"));
55348
55410
  if (cwd !== originalCwd) {
55349
- denyWrite.push(resolve10(cwd, deps.getConfigDirName(), "skills"));
55411
+ denyWrite.push(resolve11(cwd, deps.getConfigDirName(), "skills"));
55350
55412
  }
55351
55413
  bareGitRepoScrubPaths.length = 0;
55352
55414
  const bareGitRepoFiles = ["HEAD", "objects", "refs", "hooks", "config"];
55353
55415
  for (const dir of cwd === originalCwd ? [originalCwd] : [originalCwd, cwd]) {
55354
55416
  for (const gitFile of bareGitRepoFiles) {
55355
- const p = resolve10(dir, gitFile);
55417
+ const p = resolve11(dir, gitFile);
55356
55418
  try {
55357
55419
  statSync3(p);
55358
55420
  denyWrite.push(p);
@@ -55421,7 +55483,7 @@ function createSandboxManager(deps, backend) {
55421
55483
  if (!gitdirMatch?.[1]) {
55422
55484
  return null;
55423
55485
  }
55424
- const gitdir = resolve10(cwd, gitdirMatch[1].trim());
55486
+ const gitdir = resolve11(cwd, gitdirMatch[1].trim());
55425
55487
  const marker = sep3 + ".git" + sep3 + "worktrees" + sep3;
55426
55488
  const markerIndex = gitdir.lastIndexOf(marker);
55427
55489
  if (markerIndex > 0) {
@@ -68278,7 +68340,7 @@ var init_mcp2 = __esm(() => {
68278
68340
  var PROMPT = `Completely replaces the contents of a specific cell in a Jupyter notebook (.ipynb file) with new source. Jupyter notebooks are interactive documents that combine code, text, and visualizations, commonly used for data analysis and scientific computing. The notebook_path parameter must be an absolute path, not a relative path. The cell_number is 0-indexed. Use edit_mode=insert to add a new cell at the index specified by cell_number. Use edit_mode=delete to delete the cell at the index specified by cell_number.`;
68279
68341
 
68280
68342
  // src/engine/tools/notebook/notebookEditTool.ts
68281
- import { extname as extname4, isAbsolute as isAbsolute9, resolve as resolve11 } from "path";
68343
+ import { extname as extname4, isAbsolute as isAbsolute9, resolve as resolve12 } from "path";
68282
68344
  var NOTEBOOK_EDIT_TOOL_INPUT_SCHEMA, NotebookEditTool;
68283
68345
  var init_notebookEditTool = __esm(() => {
68284
68346
  init_shared();
@@ -68394,7 +68456,7 @@ var init_notebookEditTool = __esm(() => {
68394
68456
  edit_mode = "replace"
68395
68457
  } = input;
68396
68458
  const ctx = context;
68397
- const fullPath = isAbsolute9(notebook_path) ? notebook_path : resolve11(getCwd(), notebook_path);
68459
+ const fullPath = isAbsolute9(notebook_path) ? notebook_path : resolve12(getCwd(), notebook_path);
68398
68460
  if (fullPath.startsWith("\\\\") || fullPath.startsWith("//")) {
68399
68461
  return { result: true };
68400
68462
  }
@@ -68498,7 +68560,7 @@ var init_notebookEditTool = __esm(() => {
68498
68560
  } = args ?? {};
68499
68561
  let cell_type = inputCellType;
68500
68562
  const { readFileState } = context;
68501
- const fullPath = isAbsolute9(notebook_path) ? notebook_path : resolve11(getCwd(), notebook_path);
68563
+ const fullPath = isAbsolute9(notebook_path) ? notebook_path : resolve12(getCwd(), notebook_path);
68502
68564
  try {
68503
68565
  const { content, encoding, lineEndings } = readFileSyncWithMetadata(fullPath);
68504
68566
  let notebook;
@@ -74913,7 +74975,7 @@ var init_skillModel = __esm(() => {
74913
74975
  import { execFile as execFile5 } from "child_process";
74914
74976
  import { readFileSync as readFileSync8, realpathSync as realpathSync4, statSync as statSync4 } from "fs";
74915
74977
  import { readFile as readFile9, stat as stat6 } from "fs/promises";
74916
- import { basename as basename6, dirname as dirname15, join as join29, resolve as resolve12, sep as sep6 } from "path";
74978
+ import { basename as basename6, dirname as dirname15, join as join29, resolve as resolve13, sep as sep6 } from "path";
74917
74979
  function getErrorMessage(code, signal) {
74918
74980
  if (signal)
74919
74981
  return signal;
@@ -74975,7 +75037,7 @@ function gitExe() {
74975
75037
  function findGitRootImpl(startPath) {
74976
75038
  if (typeof startPath !== "string")
74977
75039
  startPath = String(startPath || "/tmp");
74978
- let current = resolve12(startPath);
75040
+ let current = resolve13(startPath);
74979
75041
  const root = current.substring(0, current.indexOf(sep6) + 1) || sep6;
74980
75042
  while (current !== root) {
74981
75043
  try {
@@ -75014,9 +75076,9 @@ function resolveCanonicalRoot(gitRoot) {
75014
75076
  if (!gitContent.startsWith("gitdir:")) {
75015
75077
  return gitRoot;
75016
75078
  }
75017
- const worktreeGitDir = resolve12(gitRoot, gitContent.slice("gitdir:".length).trim());
75018
- const commonDir = resolve12(worktreeGitDir, readFileSync8(join29(worktreeGitDir, "commondir"), "utf-8").trim());
75019
- if (resolve12(dirname15(worktreeGitDir)) !== join29(commonDir, "worktrees")) {
75079
+ const worktreeGitDir = resolve13(gitRoot, gitContent.slice("gitdir:".length).trim());
75080
+ const commonDir = resolve13(worktreeGitDir, readFileSync8(join29(worktreeGitDir, "commondir"), "utf-8").trim());
75081
+ if (resolve13(dirname15(worktreeGitDir)) !== join29(commonDir, "worktrees")) {
75020
75082
  return gitRoot;
75021
75083
  }
75022
75084
  const backlink = realpathSync4(readFileSync8(join29(worktreeGitDir, "gitdir"), "utf-8").trim());
@@ -75045,7 +75107,7 @@ function findCanonicalGitRoot(startPath) {
75045
75107
  return resolved;
75046
75108
  }
75047
75109
  async function resolveGitDir(startPath) {
75048
- const cwd = resolve12(startPath ?? process.cwd());
75110
+ const cwd = resolve13(startPath ?? process.cwd());
75049
75111
  const cached = resolveGitDirCache.get(cwd);
75050
75112
  if (cached !== undefined) {
75051
75113
  return cached;
@@ -75062,7 +75124,7 @@ async function resolveGitDir(startPath) {
75062
75124
  const content = (await readFile9(gitPath, "utf-8")).trim();
75063
75125
  if (content.startsWith("gitdir:")) {
75064
75126
  const rawDir = content.slice("gitdir:".length).trim();
75065
- const resolved = resolve12(root, rawDir);
75127
+ const resolved = resolve13(root, rawDir);
75066
75128
  resolveGitDirCache.set(cwd, resolved);
75067
75129
  return resolved;
75068
75130
  }
@@ -75166,7 +75228,7 @@ async function resolveRefInDir(dir, ref) {
75166
75228
  async function getCommonDir(gitDir) {
75167
75229
  try {
75168
75230
  const content = (await readFile9(join29(gitDir, "commondir"), "utf-8")).trim();
75169
- return resolve12(gitDir, content);
75231
+ return resolve13(gitDir, content);
75170
75232
  } catch {
75171
75233
  return null;
75172
75234
  }
@@ -75178,7 +75240,7 @@ async function readWorktreeHeadSha(worktreePath) {
75178
75240
  if (!ptr.startsWith("gitdir:")) {
75179
75241
  return null;
75180
75242
  }
75181
- gitDir = resolve12(worktreePath, ptr.slice("gitdir:".length).trim());
75243
+ gitDir = resolve13(worktreePath, ptr.slice("gitdir:".length).trim());
75182
75244
  } catch {
75183
75245
  return null;
75184
75246
  }
@@ -75191,6 +75253,42 @@ async function readWorktreeHeadSha(worktreePath) {
75191
75253
  }
75192
75254
  return head.sha;
75193
75255
  }
75256
+ function parseWorktreeListPorcelain(out) {
75257
+ const entries = [];
75258
+ let current = null;
75259
+ for (const line of out.split(`
75260
+ `)) {
75261
+ const trimmed = line.trim();
75262
+ if (trimmed.startsWith("worktree ")) {
75263
+ if (current)
75264
+ entries.push(current);
75265
+ current = { worktreePath: trimmed.slice("worktree ".length), branch: null };
75266
+ continue;
75267
+ }
75268
+ if (!current || trimmed === "")
75269
+ continue;
75270
+ if (trimmed.startsWith("branch ")) {
75271
+ let ref = trimmed.slice("branch ".length);
75272
+ if (ref.startsWith("refs/heads/"))
75273
+ ref = ref.slice("refs/heads/".length);
75274
+ current.branch = ref;
75275
+ }
75276
+ }
75277
+ if (current)
75278
+ entries.push(current);
75279
+ return entries;
75280
+ }
75281
+ async function listWorktrees(repoRoot) {
75282
+ const { code, stdout, stderr } = await execFileNoThrowWithCwd(gitExe(), ["worktree", "list", "--porcelain"], {
75283
+ cwd: repoRoot,
75284
+ stdin: "ignore",
75285
+ env: { ...process.env, ...GIT_NO_PROMPT_ENV }
75286
+ });
75287
+ if (code !== 0) {
75288
+ throw new Error(`git worktree list failed (code ${code}): ${stderr.trim()}`);
75289
+ }
75290
+ return parseWorktreeListPorcelain(stdout);
75291
+ }
75194
75292
  async function readRawSymref(gitDir, refPath, branchPrefix) {
75195
75293
  try {
75196
75294
  const content = (await readFile9(join29(gitDir, refPath), "utf-8")).trim();
@@ -75407,8 +75505,12 @@ function resetWorktreeGitCaches() {
75407
75505
  resolveGitDirCache.clear();
75408
75506
  _gitExe = null;
75409
75507
  }
75410
- var MS_IN_SECOND2 = 1000, SECONDS_IN_MINUTE2 = 60, _gitExe = null, GIT_ROOT_NOT_FOUND, findGitRootCache, canonicalRootCache, resolveGitDirCache;
75508
+ var MS_IN_SECOND2 = 1000, SECONDS_IN_MINUTE2 = 60, _gitExe = null, GIT_NO_PROMPT_ENV, GIT_ROOT_NOT_FOUND, findGitRootCache, canonicalRootCache, resolveGitDirCache;
75411
75509
  var init_git = __esm(() => {
75510
+ GIT_NO_PROMPT_ENV = {
75511
+ GIT_TERMINAL_PROMPT: "0",
75512
+ GIT_ASKPASS: ""
75513
+ };
75412
75514
  GIT_ROOT_NOT_FOUND = Symbol("git-root-not-found");
75413
75515
  findGitRootCache = new Map;
75414
75516
  canonicalRootCache = new Map;
@@ -75416,8 +75518,16 @@ var init_git = __esm(() => {
75416
75518
  });
75417
75519
 
75418
75520
  // src/engine/worktree/worktree.ts
75419
- import { copyFile, mkdir as mkdir10, readdir as readdir4, stat as stat7, symlink as symlink2, utimes } from "fs/promises";
75420
- import { basename as basename7, dirname as dirname16, join as join30 } from "path";
75521
+ import {
75522
+ copyFile,
75523
+ mkdir as mkdir10,
75524
+ readdir as readdir4,
75525
+ realpath as realpath2,
75526
+ stat as stat7,
75527
+ symlink as symlink2,
75528
+ utimes
75529
+ } from "fs/promises";
75530
+ import { basename as basename7, dirname as dirname16, join as join30, resolve as resolve14 } from "path";
75421
75531
  function validateWorktreeSlug(slug) {
75422
75532
  if (slug.length > MAX_WORKTREE_SLUG_LENGTH) {
75423
75533
  throw new Error(`Invalid worktree name: must be ${MAX_WORKTREE_SLUG_LENGTH} characters or fewer (got ${slug.length})`);
@@ -75684,6 +75794,53 @@ async function createWorktreeForSession(sessionId, slug, tmuxSessionName, option
75684
75794
  };
75685
75795
  return currentWorktreeSession;
75686
75796
  }
75797
+ async function enterExistingWorktreeForSession(sessionId, requestedPath, tmuxSessionName) {
75798
+ const originalCwd = process.cwd();
75799
+ const gitRoot = findGitRoot(process.cwd());
75800
+ if (!gitRoot) {
75801
+ throw new Error("Cannot enter a worktree: not in a git repository. " + "Worktree isolation requires a git repository.");
75802
+ }
75803
+ const entries = await listWorktrees(gitRoot);
75804
+ const resolved = resolve14(requestedPath);
75805
+ const norm = async (p) => {
75806
+ try {
75807
+ return await realpath2(p);
75808
+ } catch {
75809
+ return p;
75810
+ }
75811
+ };
75812
+ const resolvedNorm = await norm(resolved);
75813
+ const entryNorms = await Promise.all(entries.map((e) => norm(e.worktreePath)));
75814
+ const matchIdx = entryNorms.indexOf(resolvedNorm);
75815
+ const match = matchIdx >= 0 ? entries[matchIdx] : undefined;
75816
+ if (!match) {
75817
+ let exists = false;
75818
+ try {
75819
+ await stat7(resolved);
75820
+ exists = true;
75821
+ } catch {
75822
+ exists = false;
75823
+ }
75824
+ if (!exists) {
75825
+ throw new Error(`Path does not exist: ${requestedPath}. ` + 'EnterWorktree "path" must point to an existing git worktree of this ' + 'repository. Use the "name" argument to create a new worktree instead.');
75826
+ }
75827
+ throw new Error(`${requestedPath} is not a registered worktree of this repository. ` + `Registered worktrees: ${entries.map((e) => e.worktreePath).join(", ")}. ` + 'Use the "name" argument to create a new worktree instead.');
75828
+ }
75829
+ const originalBranch = await getBranch();
75830
+ const headCommit = await readWorktreeHeadSha(match.worktreePath);
75831
+ currentWorktreeSession = {
75832
+ originalCwd,
75833
+ worktreePath: match.worktreePath,
75834
+ worktreeName: basename7(match.worktreePath),
75835
+ worktreeBranch: match.branch ?? undefined,
75836
+ originalBranch,
75837
+ originalHeadCommit: headCommit ?? undefined,
75838
+ sessionId,
75839
+ tmuxSessionName,
75840
+ usedSparsePaths: (getWorktreeSettings().sparsePaths?.length ?? 0) > 0
75841
+ };
75842
+ return currentWorktreeSession;
75843
+ }
75687
75844
  async function keepWorktree() {
75688
75845
  if (!currentWorktreeSession) {
75689
75846
  return;
@@ -75736,13 +75893,15 @@ async function cleanupWorktree() {
75736
75893
  });
75737
75894
  }
75738
75895
  }
75739
- async function createAgentWorktree(slug) {
75896
+ async function createAgentWorktree(slug, options) {
75740
75897
  validateWorktreeSlug(slug);
75898
+ const effectiveSlug = options?.sessionId ? `${slug}-${options.sessionId.slice(0, 8)}` : slug;
75899
+ validateWorktreeSlug(effectiveSlug);
75741
75900
  const gitRoot = findCanonicalGitRoot(process.cwd());
75742
75901
  if (!gitRoot) {
75743
75902
  throw new Error("Cannot create agent worktree: not in a git repository. " + "Worktree isolation requires a git repository (new repo has no WorktreeCreate " + "hook 面; that forward seam lands with the tool-body / E-wave-end wave).");
75744
75903
  }
75745
- const { worktreePath, worktreeBranch, headCommit, existed } = await getOrCreateWorktree(gitRoot, slug);
75904
+ const { worktreePath, worktreeBranch, headCommit, existed } = await getOrCreateWorktree(gitRoot, effectiveSlug);
75746
75905
  if (!existed) {
75747
75906
  logForDebugging(`Created agent worktree at: ${worktreePath} on branch: ${worktreeBranch}`);
75748
75907
  await performPostCreationSetup(gitRoot, worktreePath);
@@ -75833,16 +75992,12 @@ async function cleanupStaleAgentWorktrees(cutoffDate) {
75833
75992
  }
75834
75993
  return removed;
75835
75994
  }
75836
- var VALID_WORKTREE_SLUG_SEGMENT, MAX_WORKTREE_SLUG_LENGTH = 64, GIT_NO_PROMPT_ENV, currentWorktreeSession = null, sleep7 = (ms) => new Promise((r) => setTimeout(r, ms)), EPHEMERAL_WORKTREE_PATTERNS;
75995
+ var VALID_WORKTREE_SLUG_SEGMENT, MAX_WORKTREE_SLUG_LENGTH = 64, currentWorktreeSession = null, sleep7 = (ms) => new Promise((r) => setTimeout(r, ms)), EPHEMERAL_WORKTREE_PATTERNS;
75837
75996
  var init_worktree = __esm(() => {
75838
75997
  init_shared();
75839
75998
  init_config();
75840
75999
  init_git();
75841
76000
  VALID_WORKTREE_SLUG_SEGMENT = /^[a-zA-Z0-9._-]+$/;
75842
- GIT_NO_PROMPT_ENV = {
75843
- GIT_TERMINAL_PROMPT: "0",
75844
- GIT_ASKPASS: ""
75845
- };
75846
76001
  EPHEMERAL_WORKTREE_PATTERNS = [
75847
76002
  /^agent-a[0-9a-f]{7}$/,
75848
76003
  /^wf_[0-9a-f]{8}-[0-9a-f]{3}-\d+$/,
@@ -75876,9 +76031,9 @@ function memoize2(fn, resolver) {
75876
76031
 
75877
76032
  // src/engine/skill/markdownLoader.ts
75878
76033
  import { statSync as statSync5 } from "fs";
75879
- import { lstat, readdir as readdir5, readFile as readFile10, stat as stat8, realpath as realpath2 } from "fs/promises";
76034
+ import { lstat, readdir as readdir5, readFile as readFile10, stat as stat8, realpath as realpath3 } from "fs/promises";
75880
76035
  import { homedir as homedir12 } from "os";
75881
- import { dirname as dirname17, join as join31, resolve as resolve13 } from "path";
76036
+ import { dirname as dirname17, join as join31, resolve as resolve15 } from "path";
75882
76037
  function extractDescriptionFromMarkdown(content, defaultDescription = "Custom item") {
75883
76038
  const lines = content.split(`
75884
76039
  `);
@@ -75936,9 +76091,9 @@ function resolveStopBoundary(cwd) {
75936
76091
  return findGitRoot(cwd);
75937
76092
  }
75938
76093
  function getProjectDirsUpToHome(subdir, cwd) {
75939
- const home = resolve13(homedir12()).normalize("NFC");
76094
+ const home = resolve15(homedir12()).normalize("NFC");
75940
76095
  const gitRoot = resolveStopBoundary(cwd);
75941
- let current = resolve13(cwd);
76096
+ let current = resolve15(cwd);
75942
76097
  const dirs = [];
75943
76098
  while (true) {
75944
76099
  if (normalizePathForComparison(current) === normalizePathForComparison(home)) {
@@ -75973,7 +76128,7 @@ async function findMarkdownFilesNative(dir, signal) {
75973
76128
  try {
75974
76129
  const stats = await stat8(currentDir, { bigint: true });
75975
76130
  if (stats.isDirectory()) {
75976
- const dirKey = stats.dev !== undefined && stats.ino !== undefined ? `${stats.dev}:${stats.ino}` : await realpath2(currentDir);
76131
+ const dirKey = stats.dev !== undefined && stats.ino !== undefined ? `${stats.dev}:${stats.ino}` : await realpath3(currentDir);
75977
76132
  if (visitedDirs.has(dirKey)) {
75978
76133
  logForDebugging(`Skipping already visited directory (circular symlink): ${currentDir}`);
75979
76134
  return;
@@ -76350,7 +76505,7 @@ var init_gitignore = __esm(() => {
76350
76505
  init_worktree2();
76351
76506
  });
76352
76507
  // src/engine/skill/loadSkillsDir.ts
76353
- import { realpath as realpath3 } from "fs/promises";
76508
+ import { realpath as realpath4 } from "fs/promises";
76354
76509
  import {
76355
76510
  basename as basename8,
76356
76511
  dirname as dirname18,
@@ -76361,7 +76516,7 @@ import {
76361
76516
  } from "path";
76362
76517
  async function getFileIdentity2(filePath) {
76363
76518
  try {
76364
- return await realpath3(filePath);
76519
+ return await realpath4(filePath);
76365
76520
  } catch {
76366
76521
  return null;
76367
76522
  }
@@ -78478,6 +78633,10 @@ var init_enterWorktreeTool = __esm(() => {
78478
78633
  name: {
78479
78634
  type: "string",
78480
78635
  description: 'Optional name for the worktree. Each "/"-separated segment may contain only letters, digits, dots, underscores, and dashes; max 64 chars total. A random name is generated if not provided.'
78636
+ },
78637
+ path: {
78638
+ type: "string",
78639
+ description: "Optional path to an EXISTING git worktree of the current repository to enter without creating a new one (probed via `git worktree list`). If the path does not exist or is not a registered worktree of this repository, the call fails with an actionable error. When both name and path are given, name wins."
78481
78640
  }
78482
78641
  }
78483
78642
  };
@@ -78492,7 +78651,10 @@ var init_enterWorktreeTool = __esm(() => {
78492
78651
  isConcurrencySafe: () => false,
78493
78652
  isReadOnly: () => false,
78494
78653
  isDestructive: () => false,
78495
- toAutoClassifierInput: (input) => input.name ?? "",
78654
+ toAutoClassifierInput: (input) => {
78655
+ const i = input;
78656
+ return i.name ?? i.path ?? "";
78657
+ },
78496
78658
  userFacingName: () => "Creating worktree",
78497
78659
  checkPermissions: async (input) => ({
78498
78660
  behavior: "allow",
@@ -78500,14 +78662,20 @@ var init_enterWorktreeTool = __esm(() => {
78500
78662
  }),
78501
78663
  description: async () => ENTER_WORKTREE_PROMPT,
78502
78664
  async validateInput(input) {
78503
- const { name } = input;
78504
- if (name === undefined) {
78505
- return { result: true };
78665
+ const { name, path } = input;
78666
+ if (name !== undefined) {
78667
+ try {
78668
+ validateWorktreeSlug(name);
78669
+ } catch (e) {
78670
+ return { result: false, errorCode: 1, message: e.message };
78671
+ }
78506
78672
  }
78507
- try {
78508
- validateWorktreeSlug(name);
78509
- } catch (e) {
78510
- return { result: false, errorCode: 1, message: e.message };
78673
+ if (path !== undefined && (typeof path !== "string" || path.length === 0)) {
78674
+ return {
78675
+ result: false,
78676
+ errorCode: 1,
78677
+ message: "`path` must be a non-empty string (an existing git worktree path of this repository)"
78678
+ };
78511
78679
  }
78512
78680
  return { result: true };
78513
78681
  },
@@ -78521,6 +78689,20 @@ var init_enterWorktreeTool = __esm(() => {
78521
78689
  process.chdir(mainRepoRoot);
78522
78690
  setCwd(mainRepoRoot);
78523
78691
  }
78692
+ if (input.path !== undefined) {
78693
+ const entered = await enterExistingWorktreeForSession(getSessionId(), input.path);
78694
+ process.chdir(entered.worktreePath);
78695
+ setCwd(entered.worktreePath);
78696
+ setOriginalCwd(getCwdState());
78697
+ const enteredBranchInfo = entered.worktreeBranch ? ` on branch ${entered.worktreeBranch}` : "";
78698
+ return {
78699
+ data: {
78700
+ worktreePath: entered.worktreePath,
78701
+ worktreeBranch: entered.worktreeBranch,
78702
+ message: `Entered existing worktree at ${entered.worktreePath}${enteredBranchInfo}. The session is now working in the worktree. Use ExitWorktree to leave mid-session, or exit the session to be prompted.`
78703
+ }
78704
+ };
78705
+ }
78524
78706
  const slug = input.name ?? randomUUID15();
78525
78707
  const worktreeSession = await createWorktreeForSession(getSessionId(), slug);
78526
78708
  process.chdir(worktreeSession.worktreePath);
@@ -81279,6 +81461,19 @@ var init_reactiveCompactError = __esm(() => {
81279
81461
 
81280
81462
  // src/engine/query/loop.ts
81281
81463
  import { randomUUID as randomUUID18 } from "crypto";
81464
+ function makeDeferredToolUseMarker(payload) {
81465
+ return {
81466
+ type: "system",
81467
+ subtype: "deferred_tool_use",
81468
+ role: "system",
81469
+ tool_use_id: payload.toolUseId,
81470
+ tool_name: payload.toolName,
81471
+ defer_reason: payload.deferReason,
81472
+ isMeta: false,
81473
+ uuid: randomUUID18(),
81474
+ timestamp: new Date().toISOString()
81475
+ };
81476
+ }
81282
81477
  async function queryOneRound(deps, tools, messages) {
81283
81478
  const chatArgs = {
81284
81479
  messages,
@@ -81338,13 +81533,20 @@ async function queryOneRound(deps, tools, messages) {
81338
81533
  hooks: deps.hooks?.toolHooks,
81339
81534
  toolContext: deps.toolContext
81340
81535
  });
81341
- const toolResults = outcomes.map((o) => ({
81536
+ const deferredOutcome = outcomes.find((o) => o.deferred);
81537
+ const deferredPayload = deferredOutcome ? {
81538
+ toolUseId: deferredOutcome.toolUseId,
81539
+ toolName: deferredOutcome.name,
81540
+ deferReason: deferredOutcome.deferReason
81541
+ } : undefined;
81542
+ const marker = deferredPayload ? makeDeferredToolUseMarker(deferredPayload) : undefined;
81543
+ const toolResults = outcomes.filter((o) => !o.deferred).map((o) => ({
81342
81544
  toolUseId: o.toolUseId,
81343
81545
  name: o.name,
81344
81546
  block: o.block
81345
81547
  }));
81346
81548
  const now = new Date().toISOString();
81347
- const resultMessages = outcomes.map((o) => ({
81549
+ const resultMessages = outcomes.filter((o) => !o.deferred).map((o) => ({
81348
81550
  type: "user",
81349
81551
  role: "user",
81350
81552
  uuid: randomUUID18(),
@@ -81352,15 +81554,17 @@ async function queryOneRound(deps, tools, messages) {
81352
81554
  message: { role: "user", content: [o.block] },
81353
81555
  toolUseResult: o.toolUseResult
81354
81556
  }));
81557
+ const roundMessages = marker ? [...messages, assistantMsg, ...resultMessages, marker] : [...messages, assistantMsg, ...resultMessages];
81355
81558
  if (deps.transcript) {
81356
- deps.transcript.record([...messages, assistantMsg, ...resultMessages]);
81559
+ deps.transcript.record(roundMessages);
81357
81560
  }
81358
81561
  return {
81359
- messages: [...messages, assistantMsg, ...resultMessages],
81562
+ messages: roundMessages,
81360
81563
  toolResults,
81361
81564
  assistantContent,
81362
81565
  stopReason: resp.message.stop_reason,
81363
- empty
81566
+ empty,
81567
+ deferred: deferredPayload
81364
81568
  };
81365
81569
  }
81366
81570
  async function queryAgentLoop(deps, args) {
@@ -81375,6 +81579,7 @@ async function queryAgentLoop(deps, args) {
81375
81579
  let turns = 0;
81376
81580
  let terminated = false;
81377
81581
  let lastRound;
81582
+ let deferredToolUse;
81378
81583
  if (deps.transcript) {
81379
81584
  await deps.transcript.record(messages);
81380
81585
  }
@@ -81449,6 +81654,10 @@ async function queryAgentLoop(deps, args) {
81449
81654
  });
81450
81655
  break;
81451
81656
  }
81657
+ if (lastRound.deferred) {
81658
+ deferredToolUse = lastRound.deferred;
81659
+ break;
81660
+ }
81452
81661
  if (lastRound.toolResults.length === 0) {
81453
81662
  const stop = deps.hooks?.stopHooks;
81454
81663
  const preventStop = stop ? (await stop(deps.signal)).preventContinuation : false;
@@ -81468,7 +81677,8 @@ async function queryAgentLoop(deps, args) {
81468
81677
  terminated,
81469
81678
  tracking,
81470
81679
  lastRound,
81471
- emptyTerminated
81680
+ emptyTerminated,
81681
+ deferred: deferredToolUse
81472
81682
  };
81473
81683
  deps.emit?.({ type: "loop_end", result });
81474
81684
  return result;
@@ -81526,6 +81736,7 @@ function createToolHooks(opts = {}) {
81526
81736
  blockingError: r.blockingError?.blockingError,
81527
81737
  updatedInput: r.updatedInput,
81528
81738
  hookBehavior: r.permissionBehavior,
81739
+ hookPermissionDecisionReason: r.permissionDecisionReason,
81529
81740
  preventContinuation: r.preventContinuation,
81530
81741
  stopReason: r.stopReason
81531
81742
  };
@@ -81715,6 +81926,7 @@ var init_engine = __esm(() => {
81715
81926
  init_tools();
81716
81927
  init_tools();
81717
81928
  init_tools();
81929
+ init_tools();
81718
81930
  init_skill();
81719
81931
  init_skill();
81720
81932
  init_skill();
@@ -85154,7 +85366,7 @@ var init_hooksWiring = __esm(() => {
85154
85366
  // src/cli/print.ts
85155
85367
  import { randomUUID as randomUUID21 } from "crypto";
85156
85368
  import { readFile as readFile12 } from "node:fs/promises";
85157
- import { join as join37, resolve as resolve14 } from "path";
85369
+ import { join as join37, resolve as resolve16 } from "path";
85158
85370
  function bridgeMcpToolClientLocal(client) {
85159
85371
  return {
85160
85372
  async callTool(toolName, args, _signal) {
@@ -85226,7 +85438,7 @@ async function parseMcpConfigItemsLocal(items) {
85226
85438
  object = JSON.parse(trimmed);
85227
85439
  } catch {
85228
85440
  try {
85229
- const raw = await readFile12(resolve14(trimmed), "utf8");
85441
+ const raw = await readFile12(resolve16(trimmed), "utf8");
85230
85442
  object = JSON.parse(raw);
85231
85443
  } catch {
85232
85444
  object = null;
@@ -85368,6 +85580,98 @@ function extractFinalAssistantText(loopResult) {
85368
85580
  }
85369
85581
  return "";
85370
85582
  }
85583
+ function findDeferredToolUseState(conversation) {
85584
+ let markerIdx = -1;
85585
+ let marker;
85586
+ for (let i = conversation.length - 1;i >= 0; i--) {
85587
+ const m = conversation[i];
85588
+ if (m.type === "system" && m.subtype === "deferred_tool_use") {
85589
+ markerIdx = i;
85590
+ marker = m;
85591
+ break;
85592
+ }
85593
+ }
85594
+ if (!marker)
85595
+ return;
85596
+ const toolUseId = marker.tool_use_id;
85597
+ const toolName = marker.tool_name;
85598
+ if (typeof toolUseId !== "string" || typeof toolName !== "string") {
85599
+ return;
85600
+ }
85601
+ const deferReason = typeof marker.defer_reason === "string" ? marker.defer_reason : undefined;
85602
+ const resolved = conversation.slice(markerIdx + 1).some((m) => {
85603
+ const content = m.message?.content;
85604
+ return Array.isArray(content) && content.some((b) => b?.type === "tool_result" && b?.tool_use_id === toolUseId);
85605
+ });
85606
+ if (resolved)
85607
+ return;
85608
+ return { toolUseId, toolName, deferReason };
85609
+ }
85610
+ async function reEvaluateDeferredToolCalls(params) {
85611
+ const { conversation, toolUseId, tools, toolHooks, checkPermission } = params;
85612
+ let tu;
85613
+ let assistantMsg;
85614
+ for (let i = conversation.length - 1;i >= 0; i--) {
85615
+ const m = conversation[i];
85616
+ if (m.role !== "assistant")
85617
+ continue;
85618
+ const content = m.message?.content;
85619
+ if (!Array.isArray(content))
85620
+ continue;
85621
+ const block = content.find((b) => b?.type === "tool_use" && b?.id === toolUseId);
85622
+ if (block) {
85623
+ tu = block;
85624
+ assistantMsg = m;
85625
+ break;
85626
+ }
85627
+ }
85628
+ if (!tu) {
85629
+ const marker = conversation.find((m) => m.type === "system" && m.subtype === "deferred_tool_use" && m.tool_use_id === toolUseId);
85630
+ tu = {
85631
+ type: "tool_use",
85632
+ id: toolUseId,
85633
+ name: typeof marker?.tool_name === "string" ? marker?.tool_name : "unknown",
85634
+ input: {}
85635
+ };
85636
+ }
85637
+ if (!assistantMsg) {
85638
+ assistantMsg = {
85639
+ type: "assistant",
85640
+ role: "assistant",
85641
+ uuid: randomUUID21(),
85642
+ timestamp: new Date().toISOString(),
85643
+ message: { role: "assistant", content: [tu] }
85644
+ };
85645
+ }
85646
+ const outcome = await executeToolUse(tu, assistantMsg, {
85647
+ tools,
85648
+ hooks: toolHooks,
85649
+ checkPermission
85650
+ });
85651
+ if (outcome.deferred) {
85652
+ const payload = {
85653
+ toolUseId,
85654
+ toolName: tu.name,
85655
+ deferReason: outcome.deferReason
85656
+ };
85657
+ const marker = makeDeferredToolUseMarker(payload);
85658
+ return {
85659
+ suspended: true,
85660
+ deferred: payload,
85661
+ messages: [...conversation, marker]
85662
+ };
85663
+ }
85664
+ const now = new Date().toISOString();
85665
+ const resultMsg = {
85666
+ type: "user",
85667
+ role: "user",
85668
+ uuid: randomUUID21(),
85669
+ timestamp: now,
85670
+ message: { role: "user", content: [outcome.block] },
85671
+ toolUseResult: outcome.toolUseResult
85672
+ };
85673
+ return { suspended: false, messages: [...conversation, resultMsg] };
85674
+ }
85371
85675
  function resolveHeadlessTpc(tpc) {
85372
85676
  if (tpc)
85373
85677
  return tpc;
@@ -85593,6 +85897,34 @@ async function runHeadless(inputPrompt, options) {
85593
85897
  await writeMessage(resultMessage);
85594
85898
  return resultMessage;
85595
85899
  };
85900
+ const writeDeferredSuspendResult = async (p, numTurns, conversationMessages) => {
85901
+ await drainToOutput();
85902
+ for (const m of conversationMessages) {
85903
+ if (m.role !== "assistant")
85904
+ continue;
85905
+ const content = m.message?.content;
85906
+ if (!content || content.length === 0)
85907
+ continue;
85908
+ await writeMessage({
85909
+ type: "assistant",
85910
+ session_id: sessionId,
85911
+ message: { role: "assistant", content },
85912
+ uuid: randomUUID21()
85913
+ });
85914
+ }
85915
+ await drainToOutput();
85916
+ const resultMessage = {
85917
+ type: "result",
85918
+ subtype: "deferred",
85919
+ session_id: sessionId,
85920
+ is_error: false,
85921
+ num_turns: numTurns,
85922
+ result: `Deferred tool call ${p.toolName} (${p.toolUseId}) by PreToolUse hook` + (p.deferReason ? `: ${p.deferReason}` : "") + `. Session suspended — resume with: atlas -p --resume ${sessionId}`,
85923
+ uuid: randomUUID21()
85924
+ };
85925
+ await writeMessage(resultMessage);
85926
+ return resultMessage;
85927
+ };
85596
85928
  const queuedUserTurns = [];
85597
85929
  let stdinClosed = false;
85598
85930
  const drainPump = (async () => {
@@ -85625,38 +85957,90 @@ async function runHeadless(inputPrompt, options) {
85625
85957
  });
85626
85958
  cronScheduler.start();
85627
85959
  try {
85628
- let loopResult = await runTurn(conversation);
85629
- conversation = loopResult.messages;
85630
- const firstResult = await writeTurnOutputs(loopResult);
85631
- switch (options.outputFormat) {
85632
- case "json": {
85633
- if (options.verbose) {
85634
- process.stdout.write(JSON.stringify(conversation) + `
85635
- `);
85636
- } else {
85637
- process.stdout.write(JSON.stringify(firstResult) + `
85638
- `);
85639
- }
85640
- break;
85960
+ const deferredState = findDeferredToolUseState(conversation);
85961
+ let reSuspended = false;
85962
+ if (deferredState) {
85963
+ const re = await reEvaluateDeferredToolCalls({
85964
+ conversation,
85965
+ toolUseId: deferredState.toolUseId,
85966
+ tools,
85967
+ toolHooks: loopDeps.hooks?.toolHooks,
85968
+ checkPermission
85969
+ });
85970
+ conversation = re.messages;
85971
+ if (loopDeps.transcript) {
85972
+ loopDeps.transcript.record(conversation);
85641
85973
  }
85642
- case "stream-json":
85643
- break;
85644
- default: {
85645
- const result = firstResult;
85646
- switch (result.subtype) {
85647
- case "success":
85648
- process.stdout.write(result.result?.endsWith(`
85649
- `) ? result.result : (result.result ?? "") + `
85974
+ if (re.suspended && re.deferred) {
85975
+ await writeDeferredSuspendResult(re.deferred, 0, conversation);
85976
+ reSuspended = true;
85977
+ }
85978
+ }
85979
+ let loopResult;
85980
+ if (reSuspended) {
85981
+ queuedUserTurns.length = 0;
85982
+ stdinClosed = true;
85983
+ cronScheduler.stop();
85984
+ await drainToOutput();
85985
+ } else {
85986
+ loopResult = await runTurn(conversation);
85987
+ conversation = loopResult.messages;
85988
+ if (loopResult.deferred) {
85989
+ const firstResult = await writeDeferredSuspendResult(loopResult.deferred, loopResult.turns, conversation);
85990
+ switch (options.outputFormat) {
85991
+ case "json": {
85992
+ if (options.verbose) {
85993
+ process.stdout.write(JSON.stringify(conversation) + `
85650
85994
  `);
85995
+ } else {
85996
+ process.stdout.write(JSON.stringify(firstResult) + `
85997
+ `);
85998
+ }
85651
85999
  break;
85652
- case "error_during_execution":
85653
- process.stdout.write(`Execution error`);
86000
+ }
86001
+ case "stream-json":
85654
86002
  break;
85655
- case "error_max_turns":
85656
- process.stdout.write(`Error: Reached max turns (${String(options.maxTurns)})`);
86003
+ default: {
86004
+ process.stdout.write(String(firstResult.result ?? "") + `
86005
+ `);
85657
86006
  break;
85658
- default:
86007
+ }
86008
+ }
86009
+ queuedUserTurns.length = 0;
86010
+ stdinClosed = true;
86011
+ } else {
86012
+ const firstResult = await writeTurnOutputs(loopResult);
86013
+ switch (options.outputFormat) {
86014
+ case "json": {
86015
+ if (options.verbose) {
86016
+ process.stdout.write(JSON.stringify(conversation) + `
86017
+ `);
86018
+ } else {
86019
+ process.stdout.write(JSON.stringify(firstResult) + `
86020
+ `);
86021
+ }
85659
86022
  break;
86023
+ }
86024
+ case "stream-json":
86025
+ break;
86026
+ default: {
86027
+ const result = firstResult;
86028
+ switch (result.subtype) {
86029
+ case "success":
86030
+ process.stdout.write(result.result?.endsWith(`
86031
+ `) ? result.result : (result.result ?? "") + `
86032
+ `);
86033
+ break;
86034
+ case "error_during_execution":
86035
+ process.stdout.write(`Execution error`);
86036
+ break;
86037
+ case "error_max_turns":
86038
+ process.stdout.write(`Error: Reached max turns (${String(options.maxTurns)})`);
86039
+ break;
86040
+ default:
86041
+ break;
86042
+ }
86043
+ }
85660
86044
  }
85661
86045
  }
85662
86046
  }
@@ -86709,7 +87093,7 @@ var init_autoMode2 = __esm(() => {
86709
87093
 
86710
87094
  // src/cli/parse.ts
86711
87095
  import { existsSync as existsSync8, readFileSync as readFileSync11, realpathSync as realpathSync6 } from "fs";
86712
- import { dirname as dirname21, join as join40, resolve as resolve15 } from "path";
87096
+ import { dirname as dirname21, join as join40, resolve as resolve17 } from "path";
86713
87097
  function resolveCliVersion(startDir) {
86714
87098
  let dir;
86715
87099
  try {
@@ -86752,11 +87136,11 @@ function readPromptFileInline(inline, file, label) {
86752
87136
  process.exit(1);
86753
87137
  }
86754
87138
  try {
86755
- return readFileSync11(resolve15(file), "utf8");
87139
+ return readFileSync11(resolve17(file), "utf8");
86756
87140
  } catch (error) {
86757
87141
  const code = error.code;
86758
87142
  if (code === "ENOENT") {
86759
- process.stderr.write(`Error: ${label} file not found: ${resolve15(file)}
87143
+ process.stderr.write(`Error: ${label} file not found: ${resolve17(file)}
86760
87144
  `);
86761
87145
  } else {
86762
87146
  process.stderr.write(`Error reading ${label} file: ${error.message}
@@ -98331,12 +98715,12 @@ var init_gitConfigParser = () => {};
98331
98715
  // src/tui/utils/git/gitFilesystem.ts
98332
98716
  import { unwatchFile, watchFile } from "fs";
98333
98717
  import { readdir as readdir7, readFile as readFile16, stat as stat13 } from "fs/promises";
98334
- import { join as join47, resolve as resolve16 } from "path";
98718
+ import { join as join47, resolve as resolve18 } from "path";
98335
98719
  function clearResolveGitDirCache() {
98336
98720
  resolveGitDirCache2.clear();
98337
98721
  }
98338
98722
  async function resolveGitDir2(startPath) {
98339
- const cwd = resolve16(startPath ?? getCwd());
98723
+ const cwd = resolve18(startPath ?? getCwd());
98340
98724
  const cached = resolveGitDirCache2.get(cwd);
98341
98725
  if (cached !== undefined) {
98342
98726
  return cached;
@@ -98353,7 +98737,7 @@ async function resolveGitDir2(startPath) {
98353
98737
  const content = (await readFile16(gitPath, "utf-8")).trim();
98354
98738
  if (content.startsWith("gitdir:")) {
98355
98739
  const rawDir = content.slice("gitdir:".length).trim();
98356
- const resolved = resolve16(root, rawDir);
98740
+ const resolved = resolve18(root, rawDir);
98357
98741
  resolveGitDirCache2.set(cwd, resolved);
98358
98742
  return resolved;
98359
98743
  }
@@ -98457,7 +98841,7 @@ async function resolveRefInDir2(dir, ref) {
98457
98841
  async function getCommonDir2(gitDir) {
98458
98842
  try {
98459
98843
  const content = (await readFile16(join47(gitDir, "commondir"), "utf-8")).trim();
98460
- return resolve16(gitDir, content);
98844
+ return resolve18(gitDir, content);
98461
98845
  } catch {
98462
98846
  return null;
98463
98847
  }
@@ -98677,7 +99061,7 @@ async function readWorktreeHeadSha2(worktreePath) {
98677
99061
  if (!ptr.startsWith("gitdir:")) {
98678
99062
  return null;
98679
99063
  }
98680
- gitDir = resolve16(worktreePath, ptr.slice("gitdir:".length).trim());
99064
+ gitDir = resolve18(worktreePath, ptr.slice("gitdir:".length).trim());
98681
99065
  } catch {
98682
99066
  return null;
98683
99067
  }
@@ -99530,7 +99914,7 @@ var init_gitAvailability = __esm(() => {
99530
99914
 
99531
99915
  // src/tui/utils/git.ts
99532
99916
  import { readFileSync as readFileSync14, realpathSync as realpathSync7, statSync as statSync7 } from "fs";
99533
- import { basename as basename9, dirname as dirname25, join as join49, resolve as resolve17, sep as sep7 } from "path";
99917
+ import { basename as basename9, dirname as dirname25, join as join49, resolve as resolve19, sep as sep7 } from "path";
99534
99918
  function createFindGitRoot() {
99535
99919
  function wrapper(startPath) {
99536
99920
  const result = findGitRootImpl2(startPath);
@@ -99666,7 +100050,7 @@ var init_git2 = __esm(() => {
99666
100050
  logForDiagnosticsNoPII("info", "find_git_root_started");
99667
100051
  if (typeof startPath !== "string")
99668
100052
  startPath = String(startPath || "/tmp");
99669
- let current = resolve17(startPath);
100053
+ let current = resolve19(startPath);
99670
100054
  const root = current.substring(0, current.indexOf(sep7) + 1) || sep7;
99671
100055
  let statCount = 0;
99672
100056
  while (current !== root) {
@@ -99716,9 +100100,9 @@ var init_git2 = __esm(() => {
99716
100100
  if (!gitContent.startsWith("gitdir:")) {
99717
100101
  return gitRoot;
99718
100102
  }
99719
- const worktreeGitDir = resolve17(gitRoot, gitContent.slice("gitdir:".length).trim());
99720
- const commonDir = resolve17(worktreeGitDir, readFileSync14(join49(worktreeGitDir, "commondir"), "utf-8").trim());
99721
- if (resolve17(dirname25(worktreeGitDir)) !== join49(commonDir, "worktrees")) {
100103
+ const worktreeGitDir = resolve19(gitRoot, gitContent.slice("gitdir:".length).trim());
100104
+ const commonDir = resolve19(worktreeGitDir, readFileSync14(join49(worktreeGitDir, "commondir"), "utf-8").trim());
100105
+ if (resolve19(dirname25(worktreeGitDir)) !== join49(commonDir, "worktrees")) {
99722
100106
  return gitRoot;
99723
100107
  }
99724
100108
  const backlink = realpathSync7(readFileSync14(join49(worktreeGitDir, "gitdir"), "utf-8").trim());
@@ -99948,7 +100332,7 @@ var init_getWorktreePathsPortable = __esm(() => {
99948
100332
  });
99949
100333
 
99950
100334
  // src/tui/utils/sessionStoragePortable.ts
99951
- import { open as fsOpen2, readdir as readdir9, realpath as realpath4, stat as stat14 } from "fs/promises";
100335
+ import { open as fsOpen2, readdir as readdir9, realpath as realpath5, stat as stat14 } from "fs/promises";
99952
100336
  function validateUuid(maybeUuid) {
99953
100337
  if (typeof maybeUuid !== "string")
99954
100338
  return null;
@@ -100260,7 +100644,7 @@ var init_sessionStoragePortable = __esm(() => {
100260
100644
 
100261
100645
  // src/tui/utils/path.ts
100262
100646
  import { homedir as homedir17 } from "os";
100263
- import { dirname as dirname27, isAbsolute as isAbsolute11, join as join51, normalize as normalize3, relative as relative5, resolve as resolve19 } from "path";
100647
+ import { dirname as dirname27, isAbsolute as isAbsolute11, join as join51, normalize as normalize3, relative as relative5, resolve as resolve21 } from "path";
100264
100648
  function expandPath2(path, baseDir) {
100265
100649
  const actualBaseDir = baseDir ?? getCwd() ?? getFsImplementation2().cwd();
100266
100650
  if (typeof path !== "string") {
@@ -100293,7 +100677,7 @@ function expandPath2(path, baseDir) {
100293
100677
  if (isAbsolute11(processedPath)) {
100294
100678
  return normalize3(processedPath).normalize("NFC");
100295
100679
  }
100296
- return resolve19(actualBaseDir, processedPath).normalize("NFC");
100680
+ return resolve21(actualBaseDir, processedPath).normalize("NFC");
100297
100681
  }
100298
100682
  function toRelativePath2(absolutePath) {
100299
100683
  const relativePath = relative5(getCwd(), absolutePath);
@@ -121026,7 +121410,7 @@ __export(exports_teamMemPaths, {
121026
121410
  isTeamMemPath: () => isTeamMemPath,
121027
121411
  isTeamMemoryEnabled: () => isTeamMemoryEnabled
121028
121412
  });
121029
- import { dirname as dirname28, join as join55, resolve as resolve20, sep as sep10 } from "path";
121413
+ import { dirname as dirname28, join as join55, resolve as resolve22, sep as sep10 } from "path";
121030
121414
  function isTeamMemoryEnabled() {
121031
121415
  if (!isAutoMemoryEnabled2()) {
121032
121416
  return false;
@@ -121040,7 +121424,7 @@ function getTeamMemEntrypoint() {
121040
121424
  return join55(getAutoMemPath2(), "team", "MEMORY.md");
121041
121425
  }
121042
121426
  function isTeamMemPath(filePath) {
121043
- const resolvedPath = resolve20(filePath);
121427
+ const resolvedPath = resolve22(filePath);
121044
121428
  const teamDir = getTeamMemPath();
121045
121429
  return resolvedPath.startsWith(teamDir);
121046
121430
  }
@@ -121056,7 +121440,7 @@ var init_teamMemPaths = __esm(() => {
121056
121440
  // src/tui/utils/config.ts
121057
121441
  import { randomBytes as randomBytes5 } from "crypto";
121058
121442
  import { unwatchFile as unwatchFile2, watchFile as watchFile2 } from "fs";
121059
- import { basename as basename10, dirname as dirname29, join as join56, resolve as resolve21 } from "path";
121443
+ import { basename as basename10, dirname as dirname29, join as join56, resolve as resolve23 } from "path";
121060
121444
  function createDefaultGlobalConfig() {
121061
121445
  return {
121062
121446
  numStartups: 0,
@@ -121115,7 +121499,7 @@ function computeTrustDialogAccepted() {
121115
121499
  if (pathConfig?.hasTrustDialogAccepted) {
121116
121500
  return true;
121117
121501
  }
121118
- const parentPath = normalizePathForConfigKey(resolve21(currentPath, ".."));
121502
+ const parentPath = normalizePathForConfigKey(resolve23(currentPath, ".."));
121119
121503
  if (parentPath === currentPath) {
121120
121504
  break;
121121
121505
  }
@@ -121740,7 +122124,7 @@ var init_config6 = __esm(() => {
121740
122124
  if (gitRoot) {
121741
122125
  return normalizePathForConfigKey(gitRoot);
121742
122126
  }
121743
- return normalizePathForConfigKey(resolve21(originalCwd));
122127
+ return normalizePathForConfigKey(resolve23(originalCwd));
121744
122128
  });
121745
122129
  });
121746
122130
 
@@ -121978,7 +122362,7 @@ var init_fileReadCache2 = __esm(() => {
121978
122362
 
121979
122363
  // src/tui/utils/file.ts
121980
122364
  import { chmodSync as chmodSync2, writeFileSync as fsWriteFileSync2 } from "fs";
121981
- import { realpath as realpath5, stat as stat16 } from "fs/promises";
122365
+ import { realpath as realpath6, stat as stat16 } from "fs/promises";
121982
122366
  import { homedir as homedir20 } from "os";
121983
122367
  import {
121984
122368
  basename as basename11,
@@ -121988,7 +122372,7 @@ import {
121988
122372
  join as join57,
121989
122373
  normalize as normalize5,
121990
122374
  relative as relative6,
121991
- resolve as resolve22,
122375
+ resolve as resolve24,
121992
122376
  sep as sep11
121993
122377
  } from "path";
121994
122378
  async function pathExists2(path) {
@@ -122088,7 +122472,7 @@ async function suggestPathUnderCwd2(requestedPath) {
122088
122472
  const cwdParent = dirname30(cwd);
122089
122473
  let resolvedPath = requestedPath;
122090
122474
  try {
122091
- const resolvedDir = await realpath5(dirname30(requestedPath));
122475
+ const resolvedDir = await realpath6(dirname30(requestedPath));
122092
122476
  resolvedPath = join57(resolvedDir, basename11(requestedPath));
122093
122477
  } catch {}
122094
122478
  const cwdParentPrefix = cwdParent === sep11 ? sep11 : cwdParent + sep11;
@@ -122148,7 +122532,7 @@ function writeFileSyncAndFlush_DEPRECATED2(filePath, content, options = { encodi
122148
122532
  let targetPath = filePath;
122149
122533
  try {
122150
122534
  const linkTarget = fs.readlinkSync(filePath);
122151
- targetPath = isAbsolute13(linkTarget) ? linkTarget : resolve22(dirname30(filePath), linkTarget);
122535
+ targetPath = isAbsolute13(linkTarget) ? linkTarget : resolve24(dirname30(filePath), linkTarget);
122152
122536
  logForDebugging3(`Writing through symlink: ${filePath} -> ${targetPath}`);
122153
122537
  } catch {}
122154
122538
  const tempPath = `${targetPath}.tmp.${process.pid}.${Date.now()}`;
@@ -122522,6 +122906,7 @@ var isMcpServerCommandEntry = () => ({}), isMcpServerNameEntry = () => ({}), isM
122522
122906
  outputStyle: string2().optional(),
122523
122907
  language: string2().optional(),
122524
122908
  theme: string2().optional(),
122909
+ tui: object({ fullscreen: boolean2().optional() }).optional(),
122525
122910
  autoCompactWindow: discriminatedUnion("kind", [
122526
122911
  object({ kind: literal("auto") }),
122527
122912
  object({ kind: literal("off") }),
@@ -123538,7 +123923,7 @@ var init_settingsCache2 = __esm(() => {
123538
123923
  });
123539
123924
 
123540
123925
  // src/tui/utils/settings/settings.ts
123541
- import { dirname as dirname32, join as join60, resolve as resolve23 } from "path";
123926
+ import { dirname as dirname32, join as join60, resolve as resolve25 } from "path";
123542
123927
  function getManagedSettingsFilePath2() {
123543
123928
  return join60(getManagedFilePath(), "managed-settings.json");
123544
123929
  }
@@ -123626,15 +124011,15 @@ function parseSettingsFileUncached2(path) {
123626
124011
  function getSettingsRootPathForSource2(source) {
123627
124012
  switch (source) {
123628
124013
  case "userSettings":
123629
- return resolve23(getAtlasConfigHomeDir3());
124014
+ return resolve25(getAtlasConfigHomeDir3());
123630
124015
  case "policySettings":
123631
124016
  case "projectSettings":
123632
124017
  case "localSettings": {
123633
- return resolve23(getOriginalCwd());
124018
+ return resolve25(getOriginalCwd());
123634
124019
  }
123635
124020
  case "flagSettings": {
123636
124021
  const path = getFlagSettingsPath();
123637
- return path ? dirname32(resolve23(path)) : resolve23(getOriginalCwd());
124022
+ return path ? dirname32(resolve25(path)) : resolve25(getOriginalCwd());
123638
124023
  }
123639
124024
  }
123640
124025
  }
@@ -123915,7 +124300,7 @@ function loadSettingsFromDisk2() {
123915
124300
  }
123916
124301
  const filePath = getSettingsFilePathForSource2(source);
123917
124302
  if (filePath) {
123918
- const resolvedPath = resolve23(filePath);
124303
+ const resolvedPath = resolve25(filePath);
123919
124304
  if (!seenFiles.has(resolvedPath)) {
123920
124305
  seenFiles.add(resolvedPath);
123921
124306
  const { settings, errors } = parseSettingsFile2(filePath);
@@ -135484,6 +135869,12 @@ var init_earlyInput = __esm(() => {
135484
135869
 
135485
135870
  // src/tui/utils/fullscreen.ts
135486
135871
  import { spawnSync as spawnSync2 } from "child_process";
135872
+ function setFullscreenRuntimeOverride(value) {
135873
+ fullscreenRuntimeOverride = value;
135874
+ }
135875
+ function getFullscreenRuntimeOverride() {
135876
+ return fullscreenRuntimeOverride;
135877
+ }
135487
135878
  function isTmuxControlModeEnvHeuristic() {
135488
135879
  if (!process.env.TMUX)
135489
135880
  return false;
@@ -135516,6 +135907,9 @@ function isTmuxControlMode() {
135516
135907
  return tmuxControlModeProbed ?? false;
135517
135908
  }
135518
135909
  function isFullscreenEnvEnabled() {
135910
+ if (fullscreenRuntimeOverride !== undefined) {
135911
+ return fullscreenRuntimeOverride;
135912
+ }
135519
135913
  if (isEnvDefinedFalsy2(process.env.ATLAS_NO_FLICKER))
135520
135914
  return false;
135521
135915
  if (isEnvTruthy2(process.env.ATLAS_NO_FLICKER))
@@ -135553,7 +135947,7 @@ async function maybeGetTmuxMouseHint() {
135553
135947
  return null;
135554
135948
  return "tmux detected · scroll with PgUp/PgDn · or add 'set -g mouse on' to ~/.tmux.conf for wheel scroll";
135555
135949
  }
135556
- var loggedTmuxCcDisable = false, checkedTmuxMouseHint = false, tmuxControlModeProbed;
135950
+ var loggedTmuxCcDisable = false, checkedTmuxMouseHint = false, tmuxControlModeProbed, fullscreenRuntimeOverride;
135557
135951
  var init_fullscreen = __esm(() => {
135558
135952
  init_bootstrap();
135559
135953
  init_debug();
@@ -162097,14 +162491,14 @@ var init_MessageResponse = __esm(() => {
162097
162491
 
162098
162492
  // src/tui/commands/add-dir/validation.ts
162099
162493
  import { stat as stat17 } from "fs/promises";
162100
- import { dirname as dirname36, resolve as resolve25 } from "path";
162494
+ import { dirname as dirname36, resolve as resolve27 } from "path";
162101
162495
  async function validateDirectoryForWorkspace(directoryPath, permissionContext) {
162102
162496
  if (!directoryPath) {
162103
162497
  return {
162104
162498
  resultType: "emptyPath"
162105
162499
  };
162106
162500
  }
162107
- const absolutePath = resolve25(expandPath2(directoryPath));
162501
+ const absolutePath = resolve27(expandPath2(directoryPath));
162108
162502
  try {
162109
162503
  const stats = await stat17(absolutePath);
162110
162504
  if (!stats.isDirectory()) {
@@ -162356,7 +162750,7 @@ var init_mailbox3 = __esm(() => {
162356
162750
  });
162357
162751
 
162358
162752
  // node_modules/readdirp/index.js
162359
- import { lstat as lstat2, readdir as readdir10, realpath as realpath6, stat as stat18 } from "node:fs/promises";
162753
+ import { lstat as lstat2, readdir as readdir10, realpath as realpath7, stat as stat18 } from "node:fs/promises";
162360
162754
  import { join as pjoin, resolve as presolve, sep as psep } from "node:path";
162361
162755
  import { Readable as Readable6 } from "node:stream";
162362
162756
  function readdirp(root, options = {}) {
@@ -162579,7 +162973,7 @@ var init_readdirp = __esm(() => {
162579
162973
  async _getSymlinkEntryType(entry) {
162580
162974
  const full = entry.fullPath;
162581
162975
  try {
162582
- const entryRealPath = await realpath6(full);
162976
+ const entryRealPath = await realpath7(full);
162583
162977
  const entryRealPathStats = await lstat2(entryRealPath);
162584
162978
  if (entryRealPathStats.isFile()) {
162585
162979
  return "file";
@@ -164559,9 +164953,9 @@ var init_pluginOnlyPolicy = __esm(() => {
164559
164953
 
164560
164954
  // src/tui/utils/markdownConfigLoader.ts
164561
164955
  import { statSync as statSync9 } from "fs";
164562
- import { lstat as lstat4, readdir as readdir12, readFile as readFile20, realpath as realpath7, stat as stat22 } from "fs/promises";
164956
+ import { lstat as lstat4, readdir as readdir12, readFile as readFile20, realpath as realpath8, stat as stat22 } from "fs/promises";
164563
164957
  import { homedir as homedir23 } from "os";
164564
- import { dirname as dirname40, join as join67, resolve as resolve28, sep as sep14 } from "path";
164958
+ import { dirname as dirname40, join as join67, resolve as resolve30, sep as sep14 } from "path";
164565
164959
  function extractDescriptionFromMarkdown2(content, defaultDescription = "Custom item") {
164566
164960
  const lines = content.split(`
164567
164961
  `);
@@ -164643,9 +165037,9 @@ function resolveStopBoundary2(cwd) {
164643
165037
  return cwdGitRoot;
164644
165038
  }
164645
165039
  function getProjectDirsUpToHome2(subdir, cwd) {
164646
- const home = resolve28(homedir23()).normalize("NFC");
165040
+ const home = resolve30(homedir23()).normalize("NFC");
164647
165041
  const gitRoot = resolveStopBoundary2(cwd);
164648
- let current = resolve28(cwd);
165042
+ let current = resolve30(cwd);
164649
165043
  const dirs = [];
164650
165044
  while (true) {
164651
165045
  if (normalizePathForComparison2(current) === normalizePathForComparison2(home)) {
@@ -164680,7 +165074,7 @@ async function findMarkdownFilesNative2(dir, signal) {
164680
165074
  try {
164681
165075
  const stats = await stat22(currentDir, { bigint: true });
164682
165076
  if (stats.isDirectory()) {
164683
- const dirKey = stats.dev !== undefined && stats.ino !== undefined ? `${stats.dev}:${stats.ino}` : await realpath7(currentDir);
165077
+ const dirKey = stats.dev !== undefined && stats.ino !== undefined ? `${stats.dev}:${stats.ino}` : await realpath8(currentDir);
164684
165078
  if (visitedDirs.has(dirKey)) {
164685
165079
  logForDebugging3(`Skipping already visited directory (circular symlink): ${currentDir}`);
164686
165080
  return;
@@ -165031,7 +165425,7 @@ var init_addDirPluginSettings = __esm(() => {
165031
165425
  });
165032
165426
 
165033
165427
  // src/tui/entrypoints/sdk/coreSchemas.ts
165034
- var ModelUsageSchema, OutputFormatTypeSchema, BaseOutputFormatSchema, JsonSchemaOutputFormatSchema, OutputFormatSchema, ApiKeySourceSchema, ConfigScopeSchema2, SdkBetaSchema, ThinkingAdaptiveSchema, ThinkingEnabledSchema, ThinkingDisabledSchema, ThinkingConfigSchema, McpStdioServerConfigSchema2, McpSSEServerConfigSchema2, McpHttpServerConfigSchema, McpSdkServerConfigSchema, McpServerConfigForProcessTransportSchema, McpClaudeAIProxyServerConfigSchema, McpServerStatusConfigSchema, McpServerStatusSchema, McpSetServersResultSchema, PermissionUpdateDestinationSchema, PermissionBehaviorSchema, PermissionRuleValueSchema, PermissionUpdateSchema, PermissionDecisionClassificationSchema, PermissionResultSchema, PermissionModeSchema2, HOOK_EVENTS2, HookEventSchema, BaseHookInputSchema, PreToolUseHookInputSchema, PermissionRequestHookInputSchema, PostToolUseHookInputSchema, PostToolUseFailureHookInputSchema, PermissionDeniedHookInputSchema, NotificationHookInputSchema, UserPromptSubmitHookInputSchema, SessionStartHookInputSchema, 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;
165428
+ var ModelUsageSchema, OutputFormatTypeSchema, BaseOutputFormatSchema, JsonSchemaOutputFormatSchema, OutputFormatSchema, ApiKeySourceSchema, ConfigScopeSchema2, SdkBetaSchema, ThinkingAdaptiveSchema, ThinkingEnabledSchema, ThinkingDisabledSchema, ThinkingConfigSchema, McpStdioServerConfigSchema2, McpSSEServerConfigSchema2, McpHttpServerConfigSchema, McpSdkServerConfigSchema, McpServerConfigForProcessTransportSchema, McpClaudeAIProxyServerConfigSchema, McpServerStatusConfigSchema, McpServerStatusSchema, McpSetServersResultSchema, PermissionUpdateDestinationSchema, PermissionBehaviorSchema, PreToolUsePermissionDecisionSchema, PermissionRuleValueSchema, PermissionUpdateSchema, PermissionDecisionClassificationSchema, PermissionResultSchema, PermissionModeSchema2, HOOK_EVENTS2, HookEventSchema, BaseHookInputSchema, PreToolUseHookInputSchema, PermissionRequestHookInputSchema, PostToolUseHookInputSchema, PostToolUseFailureHookInputSchema, PermissionDeniedHookInputSchema, NotificationHookInputSchema, UserPromptSubmitHookInputSchema, SessionStartHookInputSchema, 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;
165035
165429
  var init_coreSchemas = __esm(() => {
165036
165430
  init_v4();
165037
165431
  ModelUsageSchema = lazySchema2(() => object({
@@ -165141,6 +165535,7 @@ var init_coreSchemas = __esm(() => {
165141
165535
  "cliArg"
165142
165536
  ]));
165143
165537
  PermissionBehaviorSchema = lazySchema2(() => _enum(["allow", "deny", "ask"]));
165538
+ PreToolUsePermissionDecisionSchema = lazySchema2(() => _enum(["allow", "deny", "ask", "defer"]));
165144
165539
  PermissionRuleValueSchema = lazySchema2(() => object({
165145
165540
  toolName: string2(),
165146
165541
  ruleContent: string2().optional()
@@ -165462,7 +165857,7 @@ var init_coreSchemas = __esm(() => {
165462
165857
  }));
165463
165858
  PreToolUseHookSpecificOutputSchema = lazySchema2(() => object({
165464
165859
  hookEventName: literal("PreToolUse"),
165465
- permissionDecision: PermissionBehaviorSchema().optional(),
165860
+ permissionDecision: PreToolUsePermissionDecisionSchema().optional(),
165466
165861
  permissionDecisionReason: string2().optional(),
165467
165862
  updatedInput: record(string2(), unknown()).optional(),
165468
165863
  additionalContext: string2().optional()
@@ -167832,7 +168227,7 @@ var init_readOnlyCommandValidation2 = __esm(() => {
167832
168227
 
167833
168228
  // src/tui/utils/permissions/pathValidation.ts
167834
168229
  import { homedir as homedir24 } from "os";
167835
- import { dirname as dirname41, isAbsolute as isAbsolute16, resolve as resolve29 } from "path";
168230
+ import { dirname as dirname41, isAbsolute as isAbsolute16, resolve as resolve31 } from "path";
167836
168231
  function expandTilde2(path) {
167837
168232
  if (path === "~" || path.startsWith("~/") || process.platform === "win32" && path.startsWith("~\\")) {
167838
168233
  return homedir24() + path.slice(1);
@@ -178848,6 +179243,7 @@ __export(exports_engineCompat, {
178848
179243
  FORK_DIRECTIVE_PREFIX: () => FORK_DIRECTIVE_PREFIX,
178849
179244
  FORK_SUBAGENT_TYPE: () => FORK_SUBAGENT_TYPE,
178850
179245
  GENERAL_PURPOSE_AGENT: () => GENERAL_PURPOSE_AGENT,
179246
+ GIT_NO_PROMPT_ENV: () => GIT_NO_PROMPT_ENV,
178851
179247
  GLOB_TOOL_NAME: () => GLOB_TOOL_NAME,
178852
179248
  GREP_TOOL_NAME: () => GREP_TOOL_NAME,
178853
179249
  GlobTool: () => GlobTool,
@@ -179039,6 +179435,7 @@ __export(exports_engineCompat, {
179039
179435
  enqueuePendingNotification: () => enqueuePendingNotification,
179040
179436
  enqueueSdkEvent: () => enqueueSdkEvent,
179041
179437
  enqueueTaskNotification: () => enqueueTaskNotification,
179438
+ enterExistingWorktreeForSession: () => enterExistingWorktreeForSession,
179042
179439
  estimateMessageTokens: () => estimateMessageTokens,
179043
179440
  evaluateTimeBasedTrigger: () => evaluateTimeBasedTrigger,
179044
179441
  evictTerminalTask: () => evictTerminalTask,
@@ -179261,6 +179658,7 @@ __export(exports_engineCompat, {
179261
179658
  killTmuxSession: () => killTmuxSession,
179262
179659
  listAllCronTasks: () => listAllCronTasks,
179263
179660
  listTasks: () => listTasks,
179661
+ listWorktrees: () => listWorktrees,
179264
179662
  loadAgentDefinitions: () => loadAgentDefinitions,
179265
179663
  loadAllPermissionRulesFromDisk: () => loadAllPermissionRulesFromDisk,
179266
179664
  loadManagedFileSettings: () => loadManagedFileSettings,
@@ -179269,6 +179667,7 @@ __export(exports_engineCompat, {
179269
179667
  lock: () => lock,
179270
179668
  lockSync: () => lockSync,
179271
179669
  looksLikePrompt: () => looksLikePrompt,
179670
+ makeDeferredToolUseMarker: () => makeDeferredToolUseMarker,
179272
179671
  markAgentsNotified: () => markAgentsNotified,
179273
179672
  markCronTasksFired: () => markCronTasksFired,
179274
179673
  markExtractionCompleted: () => markExtractionCompleted,
@@ -179278,6 +179677,7 @@ __export(exports_engineCompat, {
179278
179677
  markMessagesAsReadByPredicate: () => markMessagesAsReadByPredicate,
179279
179678
  markSessionMemoryInitialized: () => markSessionMemoryInitialized,
179280
179679
  markTaskNotified: () => markTaskNotified,
179680
+ matchReadOnlyPrefix: () => matchReadOnlyPrefix,
179281
179681
  matchSessionMode: () => matchSessionMode,
179282
179682
  mcpInfoFromString: () => mcpInfoFromString2,
179283
179683
  mergeAutoCompactOverrides: () => mergeAutoCompactOverrides,
@@ -179309,6 +179709,7 @@ __export(exports_engineCompat, {
179309
179709
  parseSettingsFile: () => parseSettingsFile,
179310
179710
  parseToolListFromCLI: () => parseToolListFromCLI,
179311
179711
  parseToolPreset: () => parseToolPreset,
179712
+ parseWorktreeListPorcelain: () => parseWorktreeListPorcelain,
179312
179713
  partialCompactConversation: () => partialCompactConversation,
179313
179714
  partitionToolCalls: () => partitionToolCalls,
179314
179715
  peek: () => peek,
@@ -197646,7 +198047,7 @@ var init_IdeOnboardingDialog = __esm(() => {
197646
198047
 
197647
198048
  // src/tui/utils/ide.ts
197648
198049
  import { createConnection } from "net";
197649
- import { basename as basename19, join as join84, sep as pathSeparator, resolve as resolve30 } from "path";
198050
+ import { basename as basename19, join as join84, sep as pathSeparator, resolve as resolve32 } from "path";
197650
198051
  function isProcessRunning3(pid) {
197651
198052
  try {
197652
198053
  process.kill(pid, 0);
@@ -197788,7 +198189,7 @@ async function getIdeLockfilesPaths() {
197788
198189
  if (windowsHome) {
197789
198190
  const converter = new WindowsToWSLConverter(process.env.WSL_DISTRO_NAME);
197790
198191
  const wslPath = converter.toLocalPath(windowsHome);
197791
- paths.push(resolve30(wslPath, getConfigDirName2(), "ide"));
198192
+ paths.push(resolve32(wslPath, getConfigDirName2(), "ide"));
197792
198193
  }
197793
198194
  try {
197794
198195
  const usersDir = "/mnt/c/Users";
@@ -197930,14 +198331,14 @@ async function detectIDEs(includeInvalid) {
197930
198331
  if (!checkWSLDistroMatch(idePath, process.env.WSL_DISTRO_NAME)) {
197931
198332
  return false;
197932
198333
  }
197933
- const resolvedOriginal = resolve30(localPath).normalize("NFC");
198334
+ const resolvedOriginal = resolve32(localPath).normalize("NFC");
197934
198335
  if (cwd === resolvedOriginal || cwd.startsWith(resolvedOriginal + pathSeparator)) {
197935
198336
  return true;
197936
198337
  }
197937
198338
  const converter = new WindowsToWSLConverter(process.env.WSL_DISTRO_NAME);
197938
198339
  localPath = converter.toLocalPath(idePath);
197939
198340
  }
197940
- const resolvedPath = resolve30(localPath).normalize("NFC");
198341
+ const resolvedPath = resolve32(localPath).normalize("NFC");
197941
198342
  if (getPlatform3() === "windows") {
197942
198343
  const normalizedCwd = cwd.replace(/^[a-zA-Z]:/, (match) => match.toUpperCase());
197943
198344
  const normalizedResolvedPath = resolvedPath.replace(/^[a-zA-Z]:/, (match) => match.toUpperCase());
@@ -209738,12 +210139,12 @@ var init_LSPDiagnosticRegistry = __esm(() => {
209738
210139
 
209739
210140
  // src/tui/utils/plugins/lspPluginIntegration.ts
209740
210141
  import { readFile as readFile26 } from "fs/promises";
209741
- import { join as join89, relative as relative10, resolve as resolve31 } from "path";
210142
+ import { join as join89, relative as relative10, resolve as resolve33 } from "path";
209742
210143
  function validatePathWithinPlugin(pluginPath, relativePath) {
209743
- const resolvedPluginPath = resolve31(pluginPath);
209744
- const resolvedFilePath = resolve31(pluginPath, relativePath);
210144
+ const resolvedPluginPath = resolve33(pluginPath);
210145
+ const resolvedFilePath = resolve33(pluginPath, relativePath);
209745
210146
  const rel = relative10(resolvedPluginPath, resolvedFilePath);
209746
- if (rel.startsWith("..") || resolve31(rel) === rel) {
210147
+ if (rel.startsWith("..") || resolve33(rel) === rel) {
209747
210148
  return null;
209748
210149
  }
209749
210150
  return resolvedFilePath;
@@ -216004,6 +216405,7 @@ var init_memoryTypes2 = __esm(() => {
216004
216405
  "- If the memory names a file path: check the file exists.",
216005
216406
  "- If the memory names a function or flag: grep for it.",
216006
216407
  "- If the user is about to act on your recommendation (not just asking about history), verify first.",
216408
+ "- User-profile memories (who the user is, how they like to collaborate) are context, not instructions — when in doubt, trust observed behavior over the recalled preference, and ask rather than assume.",
216007
216409
  "",
216008
216410
  '"The memory says X exists" is not the same as "X exists now."',
216009
216411
  "",
@@ -251378,7 +251780,7 @@ var init_readEditContext = __esm(() => {
251378
251780
  });
251379
251781
 
251380
251782
  // src/tui/tools/FileWriteTool/UI.tsx
251381
- import { isAbsolute as isAbsolute20, relative as relative14, resolve as resolve33 } from "path";
251783
+ import { isAbsolute as isAbsolute20, relative as relative14, resolve as resolve35 } from "path";
251382
251784
  function countLines(content) {
251383
251785
  const parts = content.split(EOL);
251384
251786
  return content.endsWith(EOL) ? parts.length - 1 : parts.length;
@@ -251702,7 +252104,7 @@ function WriteRejectionBody(t0) {
251702
252104
  }
251703
252105
  async function loadRejectionDiff(filePath, content) {
251704
252106
  try {
251705
- const fullFilePath = isAbsolute20(filePath) ? filePath : resolve33(getCwd(), filePath);
252107
+ const fullFilePath = isAbsolute20(filePath) ? filePath : resolve35(getCwd(), filePath);
251706
252108
  const handle = await openForScan(fullFilePath);
251707
252109
  if (handle === null)
251708
252110
  return {
@@ -257508,7 +257910,7 @@ var init_bashProvider = __esm(() => {
257508
257910
  });
257509
257911
 
257510
257912
  // src/tui/utils/shell/powershellDetection.ts
257511
- import { realpath as realpath8, stat as stat32 } from "fs/promises";
257913
+ import { realpath as realpath9, stat as stat32 } from "fs/promises";
257512
257914
  async function probePath(p) {
257513
257915
  try {
257514
257916
  return (await stat32(p)).isFile() ? p : null;
@@ -257520,11 +257922,11 @@ async function findPowerShell() {
257520
257922
  const pwshPath = await which("pwsh");
257521
257923
  if (pwshPath) {
257522
257924
  if (getPlatform3() === "linux") {
257523
- const resolved = await realpath8(pwshPath).catch(() => pwshPath);
257925
+ const resolved = await realpath9(pwshPath).catch(() => pwshPath);
257524
257926
  if (pwshPath.startsWith("/snap/") || resolved.startsWith("/snap/")) {
257525
257927
  const direct = await probePath("/opt/microsoft/powershell/7/pwsh") ?? await probePath("/usr/bin/pwsh");
257526
257928
  if (direct) {
257527
- const directResolved = await realpath8(direct).catch(() => direct);
257929
+ const directResolved = await realpath9(direct).catch(() => direct);
257528
257930
  if (!direct.startsWith("/snap/") && !directResolved.startsWith("/snap/")) {
257529
257931
  return direct;
257530
257932
  }
@@ -257615,8 +258017,8 @@ var init_powershellProvider = __esm(() => {
257615
258017
  // src/tui/utils/Shell.ts
257616
258018
  import { execFileSync as execFileSync4, spawn as spawn9 } from "child_process";
257617
258019
  import { constants as fsConstants5, readFileSync as readFileSync19, unlinkSync as unlinkSync3 } from "fs";
257618
- import { mkdir as mkdir27, open as open12, realpath as realpath9 } from "fs/promises";
257619
- import { isAbsolute as isAbsolute25, resolve as resolve34 } from "path";
258020
+ import { mkdir as mkdir27, open as open12, realpath as realpath10 } from "fs/promises";
258021
+ import { isAbsolute as isAbsolute25, resolve as resolve36 } from "path";
257620
258022
  import { join as posixJoin3 } from "path/posix";
257621
258023
  import { accessSync as accessSync2 } from "fs";
257622
258024
  function isExecutable2(shellPath) {
@@ -257701,12 +258103,12 @@ async function exec3(command, abortSignal, shellType, options) {
257701
258103
  let commandString = builtCommand;
257702
258104
  let cwd = pwd();
257703
258105
  try {
257704
- await realpath9(cwd);
258106
+ await realpath10(cwd);
257705
258107
  } catch {
257706
258108
  const fallback = getOriginalCwd();
257707
258109
  logForDebugging3(`Shell CWD "${cwd}" no longer exists, recovering to "${fallback}"`);
257708
258110
  try {
257709
- await realpath9(fallback);
258111
+ await realpath10(fallback);
257710
258112
  setCwdState(fallback);
257711
258113
  cwd = fallback;
257712
258114
  } catch {
@@ -257805,7 +258207,7 @@ async function exec3(command, abortSignal, shellType, options) {
257805
258207
  }
257806
258208
  }
257807
258209
  function setCwd2(path, relativeTo) {
257808
- const resolved = isAbsolute25(path) ? path : resolve34(relativeTo || getFsImplementation2().cwd(), path);
258210
+ const resolved = isAbsolute25(path) ? path : resolve36(relativeTo || getFsImplementation2().cwd(), path);
257809
258211
  let physicalPath;
257810
258212
  try {
257811
258213
  physicalPath = getFsImplementation2().realpathSync(resolved);
@@ -258406,7 +258808,7 @@ var init_UI8 = __esm(() => {
258406
258808
  });
258407
258809
 
258408
258810
  // src/tui/tools/NotebookEditTool/NotebookEditTool.ts
258409
- import { extname as extname13, isAbsolute as isAbsolute26, resolve as resolve35 } from "path";
258811
+ import { extname as extname13, isAbsolute as isAbsolute26, resolve as resolve37 } from "path";
258410
258812
  var inputSchema12, outputSchema10, NotebookEditTool2;
258411
258813
  var init_NotebookEditTool = __esm(() => {
258412
258814
  init_shared();
@@ -258520,7 +258922,7 @@ var init_NotebookEditTool = __esm(() => {
258520
258922
  renderToolUseErrorMessage: renderToolUseErrorMessage5,
258521
258923
  renderToolResultMessage: renderToolResultMessage8,
258522
258924
  async validateInput({ notebook_path, cell_type, cell_id, edit_mode = "replace" }, toolUseContext) {
258523
- const fullPath = isAbsolute26(notebook_path) ? notebook_path : resolve35(getCwd(), notebook_path);
258925
+ const fullPath = isAbsolute26(notebook_path) ? notebook_path : resolve37(getCwd(), notebook_path);
258524
258926
  if (fullPath.startsWith("\\\\") || fullPath.startsWith("//")) {
258525
258927
  return { result: true };
258526
258928
  }
@@ -258619,7 +259021,7 @@ var init_NotebookEditTool = __esm(() => {
258619
259021
  cell_type,
258620
259022
  edit_mode: originalEditMode
258621
259023
  }, { readFileState, updateFileHistoryState }, _, parentMessage) {
258622
- const fullPath = isAbsolute26(notebook_path) ? notebook_path : resolve35(getCwd(), notebook_path);
259024
+ const fullPath = isAbsolute26(notebook_path) ? notebook_path : resolve37(getCwd(), notebook_path);
258623
259025
  if (fileHistoryEnabled()) {
258624
259026
  await fileHistoryTrackEdit(updateFileHistoryState, fullPath, parentMessage.uuid);
258625
259027
  }
@@ -260536,7 +260938,7 @@ var init_fileStateCache = __esm(() => {
260536
260938
  });
260537
260939
 
260538
260940
  // src/tui/utils/hooks/hooksSettings.ts
260539
- import { resolve as resolve36 } from "path";
260941
+ import { resolve as resolve38 } from "path";
260540
260942
  function isHookEqual(a, b) {
260541
260943
  if (a.type !== b.type)
260542
260944
  return false;
@@ -260587,7 +260989,7 @@ function getAllHooks(appState) {
260587
260989
  for (const source of sources) {
260588
260990
  const filePath = getSettingsFilePathForSource2(source);
260589
260991
  if (filePath) {
260590
- const resolvedPath = resolve36(filePath);
260992
+ const resolvedPath = resolve38(filePath);
260591
260993
  if (seenFiles.has(resolvedPath)) {
260592
260994
  continue;
260593
260995
  }
@@ -300982,10 +301384,11 @@ var init_InProcessTeammateTask = __esm(() => {
300982
301384
  });
300983
301385
 
300984
301386
  // src/tui/utils/permissions/PermissionRule.ts
300985
- var permissionBehaviorSchema2, permissionRuleValueSchema2;
301387
+ var permissionBehaviorSchema2, preToolUsePermissionDecisionSchema, permissionRuleValueSchema2;
300986
301388
  var init_PermissionRule2 = __esm(() => {
300987
301389
  init_v4();
300988
301390
  permissionBehaviorSchema2 = lazySchema2(() => _enum(["allow", "deny", "ask"]));
301391
+ preToolUsePermissionDecisionSchema = lazySchema2(() => _enum(["allow", "deny", "ask", "defer"]));
300989
301392
  permissionRuleValueSchema2 = lazySchema2(() => object({
300990
301393
  toolName: string2(),
300991
301394
  ruleContent: string2().optional()
@@ -314163,7 +314566,7 @@ var init_parser7 = __esm(() => {
314163
314566
  });
314164
314567
 
314165
314568
  // src/tui/tools/PowerShellTool/gitSafety.ts
314166
- import { basename as basename29, posix as posix7, resolve as resolve37, sep as sep23 } from "path";
314569
+ import { basename as basename29, posix as posix7, resolve as resolve39, sep as sep23 } from "path";
314167
314570
  function resolveCwdReentry(normalized) {
314168
314571
  if (!normalized.startsWith("../"))
314169
314572
  return normalized;
@@ -314211,7 +314614,7 @@ function normalizeGitPathArg(arg) {
314211
314614
  }
314212
314615
  function resolveEscapingPathToCwdRelative(n) {
314213
314616
  const cwd = getCwd();
314214
- const abs = resolve37(cwd, n);
314617
+ const abs = resolve39(cwd, n);
314215
314618
  const cwdWithSep = cwd.endsWith(sep23) ? cwd : cwd + sep23;
314216
314619
  const absLower = abs.toLowerCase();
314217
314620
  const cwdLower = cwd.toLowerCase();
@@ -315451,7 +315854,7 @@ var init_modeValidation3 = __esm(() => {
315451
315854
 
315452
315855
  // src/tui/tools/PowerShellTool/pathValidation.ts
315453
315856
  import { homedir as homedir29 } from "os";
315454
- import { isAbsolute as isAbsolute27, resolve as resolve38 } from "path";
315857
+ import { isAbsolute as isAbsolute27, resolve as resolve40 } from "path";
315455
315858
  function matchesParam(paramLower, paramList) {
315456
315859
  for (const p of paramList) {
315457
315860
  if (p === paramLower || paramLower.length > 1 && p.startsWith(paramLower)) {
@@ -315559,7 +315962,7 @@ function checkDenyRuleForGuessedPath(strippedPath, cwd, toolPermissionContext, o
315559
315962
  if (!strippedPath || strippedPath.includes("\x00"))
315560
315963
  return null;
315561
315964
  const tildeExpanded = expandTilde3(strippedPath);
315562
- const abs = isAbsolute27(tildeExpanded) ? tildeExpanded : resolve38(cwd, tildeExpanded);
315965
+ const abs = isAbsolute27(tildeExpanded) ? tildeExpanded : resolve40(cwd, tildeExpanded);
315563
315966
  const { resolvedPath } = safeResolvePath3(getFsImplementation2(), abs);
315564
315967
  const permissionType = operationType === "read" ? "read" : "edit";
315565
315968
  const denyRule = matchingRuleForInput2(resolvedPath, toolPermissionContext, permissionType, "deny");
@@ -315649,7 +316052,7 @@ function validatePath3(filePath, cwd, toolPermissionContext, operationType) {
315649
316052
  };
315650
316053
  }
315651
316054
  if (containsPathTraversal2(normalizedPath)) {
315652
- const absolutePath = isAbsolute27(normalizedPath) ? normalizedPath : resolve38(cwd, normalizedPath);
316055
+ const absolutePath = isAbsolute27(normalizedPath) ? normalizedPath : resolve40(cwd, normalizedPath);
315653
316056
  const { resolvedPath, isCanonical } = safeResolvePath3(getFsImplementation2(), absolutePath);
315654
316057
  const result = isPathAllowed2(resolvedPath, toolPermissionContext, operationType, isCanonical ? [resolvedPath] : undefined);
315655
316058
  return {
@@ -315659,7 +316062,7 @@ function validatePath3(filePath, cwd, toolPermissionContext, operationType) {
315659
316062
  };
315660
316063
  }
315661
316064
  const basePath = getGlobBaseDirectory2(normalizedPath);
315662
- const absoluteBasePath = isAbsolute27(basePath) ? basePath : resolve38(cwd, basePath);
316065
+ const absoluteBasePath = isAbsolute27(basePath) ? basePath : resolve40(cwd, basePath);
315663
316066
  const { resolvedPath } = safeResolvePath3(getFsImplementation2(), absoluteBasePath);
315664
316067
  const permissionType = operationType === "read" ? "read" : "edit";
315665
316068
  const denyRule = matchingRuleForInput2(resolvedPath, toolPermissionContext, permissionType, "deny");
@@ -315679,7 +316082,7 @@ function validatePath3(filePath, cwd, toolPermissionContext, operationType) {
315679
316082
  }
315680
316083
  };
315681
316084
  }
315682
- const absolutePath = isAbsolute27(normalizedPath) ? normalizedPath : resolve38(cwd, normalizedPath);
316085
+ const absolutePath = isAbsolute27(normalizedPath) ? normalizedPath : resolve40(cwd, normalizedPath);
315683
316086
  const { resolvedPath, isCanonical } = safeResolvePath3(getFsImplementation2(), absolutePath);
315684
316087
  const result = isPathAllowed2(resolvedPath, toolPermissionContext, operationType, isCanonical ? [resolvedPath] : undefined);
315685
316088
  return {
@@ -317593,7 +317996,7 @@ var init_powershellSecurity = __esm(() => {
317593
317996
  });
317594
317997
 
317595
317998
  // src/tui/tools/PowerShellTool/powershellPermissions.ts
317596
- import { resolve as resolve39 } from "path";
317999
+ import { resolve as resolve41 } from "path";
317597
318000
  async function extractCommandName(command) {
317598
318001
  const trimmed = command.trim();
317599
318002
  if (!trimmed) {
@@ -318206,7 +318609,7 @@ async function powershellToolHasPermission(input, context) {
318206
318609
  const canonical = resolveToCanonical(element.name);
318207
318610
  if (canonical === "set-location" && element.args.length > 0) {
318208
318611
  const target = element.args.find((a) => a.length === 0 || !PS_TOKENIZER_DASH_CHARS.has(a[0]));
318209
- if (target && resolve39(getCwd(), target) === getCwd()) {
318612
+ if (target && resolve41(getCwd(), target) === getCwd()) {
318210
318613
  return false;
318211
318614
  }
318212
318615
  }
@@ -323222,7 +323625,7 @@ function registerMCPSkillBuilders(b) {
323222
323625
  var builders = null;
323223
323626
 
323224
323627
  // src/tui/skills/loadSkillsDir.ts
323225
- import { realpath as realpath10 } from "fs/promises";
323628
+ import { realpath as realpath11 } from "fs/promises";
323226
323629
  import {
323227
323630
  basename as basename30,
323228
323631
  dirname as dirname56,
@@ -323251,7 +323654,7 @@ function estimateSkillFrontmatterTokens2(skill) {
323251
323654
  }
323252
323655
  async function getFileIdentity4(filePath) {
323253
323656
  try {
323254
- return await realpath10(filePath);
323657
+ return await realpath11(filePath);
323255
323658
  } catch {
323256
323659
  return null;
323257
323660
  }
@@ -326600,7 +327003,7 @@ var init_findRelevantMemories = __esm(() => {
326600
327003
 
326601
327004
  // src/tui/utils/attachments.ts
326602
327005
  import { readdir as readdir21, stat as stat37 } from "fs/promises";
326603
- import { dirname as dirname58, parse as parse12, relative as relative21, resolve as resolve40 } from "path";
327006
+ import { dirname as dirname58, parse as parse12, relative as relative21, resolve as resolve42 } from "path";
326604
327007
  import { randomUUID as randomUUID35 } from "crypto";
326605
327008
  async function getAttachments(input, toolUseContext, ideSelection, queuedCommands, messages, querySource, options) {
326606
327009
  if (isEnvTruthy2(process.env.ATLAS_DISABLE_ATTACHMENTS) || isEnvTruthy2(process.env.ATLAS_SIMPLE)) {
@@ -327021,7 +327424,7 @@ async function getSelectedLinesFromIDE(ideSelection, toolUseContext) {
327021
327424
  ];
327022
327425
  }
327023
327426
  function getDirectoriesToProcess(targetPath, originalCwd) {
327024
- const targetDir = dirname58(resolve40(targetPath));
327427
+ const targetDir = dirname58(resolve42(targetPath));
327025
327428
  const nestedDirs = [];
327026
327429
  let currentDir = targetDir;
327027
327430
  while (currentDir !== originalCwd && currentDir !== parse12(currentDir).root) {
@@ -327320,7 +327723,7 @@ async function getDynamicSkillAttachments(toolUseContext) {
327320
327723
  const candidates = entries.filter((e) => e.isDirectory() || e.isSymbolicLink()).map((e) => e.name);
327321
327724
  const checked = await Promise.all(candidates.map(async (name) => {
327322
327725
  try {
327323
- await stat37(resolve40(skillDir, name, "SKILL.md"));
327726
+ await stat37(resolve42(skillDir, name, "SKILL.md"));
327324
327727
  return name;
327325
327728
  } catch {
327326
327729
  return null;
@@ -329372,10 +329775,10 @@ var init_marketplaceHelpers = __esm(() => {
329372
329775
 
329373
329776
  // src/tui/utils/plugins/officialMarketplaceGcs.ts
329374
329777
  import { chmod as chmod5, mkdir as mkdir36, readFile as readFile41, rename as rename4, rm as rm7, writeFile as writeFile27 } from "fs/promises";
329375
- import { dirname as dirname61, join as join116, resolve as resolve41, sep as sep24 } from "path";
329778
+ import { dirname as dirname61, join as join116, resolve as resolve43, sep as sep24 } from "path";
329376
329779
  async function fetchOfficialMarketplaceFromGcs(installLocation, marketplacesCacheDir) {
329377
- const cacheDir = resolve41(marketplacesCacheDir);
329378
- const resolvedLoc = resolve41(installLocation);
329780
+ const cacheDir = resolve43(marketplacesCacheDir);
329781
+ const resolvedLoc = resolve43(installLocation);
329379
329782
  if (resolvedLoc !== cacheDir && !resolvedLoc.startsWith(cacheDir + sep24)) {
329380
329783
  logForDebugging3(`fetchOfficialMarketplaceFromGcs: refusing path outside cache dir: ${installLocation}`, { level: "error" });
329381
329784
  return null;
@@ -329509,7 +329912,7 @@ var init_ascendMarketplace = __esm(() => {
329509
329912
  });
329510
329913
 
329511
329914
  // src/tui/utils/plugins/orphanScanner.ts
329512
- import { join as join117, resolve as resolve42, sep as sep25 } from "path";
329915
+ import { join as join117, resolve as resolve44, sep as sep25 } from "path";
329513
329916
  function normalizeRepoRef(ref) {
329514
329917
  let u = ref.trim();
329515
329918
  const ssh = u.match(/^git@([^:]+):(.+)$/);
@@ -329553,7 +329956,7 @@ async function readOrphanManifestName(dirPath) {
329553
329956
  }
329554
329957
  async function scanOrphanedMarketplaces() {
329555
329958
  const fs = getFsImplementation2();
329556
- const cacheDir = resolve42(getMarketplacesCacheDir());
329959
+ const cacheDir = resolve44(getMarketplacesCacheDir());
329557
329960
  let entries;
329558
329961
  try {
329559
329962
  entries = await fs.readdir(cacheDir);
@@ -329561,8 +329964,8 @@ async function scanOrphanedMarketplaces() {
329561
329964
  return [];
329562
329965
  }
329563
329966
  const config = await loadKnownMarketplacesConfigSafe();
329564
- const registered = new Set(Object.values(config).map((e) => resolve42(e.installLocation)));
329565
- const seedDirs = getPluginSeedDirs().map((d) => resolve42(d));
329967
+ const registered = new Set(Object.values(config).map((e) => resolve44(e.installLocation)));
329968
+ const seedDirs = getPluginSeedDirs().map((d) => resolve44(d));
329566
329969
  const orphans = [];
329567
329970
  for (const entry of entries) {
329568
329971
  if (!entry.isDirectory())
@@ -329600,7 +330003,7 @@ var init_orphanScanner = __esm(() => {
329600
330003
 
329601
330004
  // src/tui/utils/plugins/marketplaceManager.ts
329602
330005
  import { writeFile as writeFile28 } from "fs/promises";
329603
- import { basename as basename35, dirname as dirname62, isAbsolute as isAbsolute31, join as join118, resolve as resolve43, sep as sep26 } from "path";
330006
+ import { basename as basename35, dirname as dirname62, isAbsolute as isAbsolute31, join as join118, resolve as resolve45, sep as sep26 } from "path";
329604
330007
  function getKnownMarketplacesFile() {
329605
330008
  return join118(getPluginsDirectory(), "known_marketplaces.json");
329606
330009
  }
@@ -330100,6 +330503,18 @@ async function cacheMarketplaceFromGit(gitUrl, cachePath, ref, sparsePaths, onPr
330100
330503
  logPluginFetch("marketplace_pull", gitUrl, pullResult.code === 0 ? "success" : "failure", performance.now() - pullStarted, pullResult.code === 0 ? undefined : classifyFetchError(pullResult.stderr));
330101
330504
  if (pullResult.code === 0)
330102
330505
  return;
330506
+ if (isEnvTruthy2(process.env.ATLAS_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE)) {
330507
+ let cacheExists = false;
330508
+ try {
330509
+ await fs.stat(cachePath);
330510
+ cacheExists = true;
330511
+ } catch {}
330512
+ if (cacheExists) {
330513
+ logForDebugging3(`ATLAS_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE set: keeping stale marketplace cache at ${cachePath} after failed pull (${pullResult.stderr}); skipping re-clone`, { level: "warn" });
330514
+ safeCallProgress(onProgress, "Marketplace update failed; keeping existing cache (ATLAS_PLUGIN_KEEP_MARKETPLACE_ON_FAILURE).");
330515
+ return;
330516
+ }
330517
+ }
330103
330518
  logForDebugging3(`git pull failed, will re-clone: ${pullResult.stderr}`, {
330104
330519
  level: "warn"
330105
330520
  });
@@ -330386,14 +330801,14 @@ async function loadAndCacheMarketplace(source, onProgress) {
330386
330801
  break;
330387
330802
  }
330388
330803
  case "file": {
330389
- const absPath = resolve43(source.path);
330804
+ const absPath = resolve45(source.path);
330390
330805
  marketplacePath = absPath;
330391
330806
  temporaryCachePath = dirname62(dirname62(absPath));
330392
330807
  cleanupNeeded = false;
330393
330808
  break;
330394
330809
  }
330395
330810
  case "directory": {
330396
- const absPath = resolve43(source.path);
330811
+ const absPath = resolve45(source.path);
330397
330812
  marketplacePath = findManifestInDir(absPath, "marketplace.json");
330398
330813
  temporaryCachePath = absPath;
330399
330814
  cleanupNeeded = false;
@@ -330425,8 +330840,8 @@ async function loadAndCacheMarketplace(source, onProgress) {
330425
330840
  throw new Error(`Failed to parse marketplace file at ${marketplacePath}: ${errorMessage2(e)}`);
330426
330841
  }
330427
330842
  const finalCachePath = join118(cacheDir, marketplace.name);
330428
- const resolvedFinal = resolve43(finalCachePath);
330429
- const resolvedCacheDir = resolve43(cacheDir);
330843
+ const resolvedFinal = resolve45(finalCachePath);
330844
+ const resolvedCacheDir = resolve45(cacheDir);
330430
330845
  if (!resolvedFinal.startsWith(resolvedCacheDir + sep26)) {
330431
330846
  throw new Error(`Marketplace name '${marketplace.name}' resolves to a path outside the cache directory`);
330432
330847
  }
@@ -330475,7 +330890,7 @@ async function captureResolvedSha(source, cachePath) {
330475
330890
  async function addMarketplaceSource(source, onProgress) {
330476
330891
  let resolvedSource = source;
330477
330892
  if (isLocalMarketplaceSource(source) && !isAbsolute31(source.path)) {
330478
- resolvedSource = { ...source, path: resolve43(source.path) };
330893
+ resolvedSource = { ...source, path: resolve45(source.path) };
330479
330894
  }
330480
330895
  if (!isSourceAllowedByPolicy(resolvedSource)) {
330481
330896
  if (isSourceInBlocklist(resolvedSource)) {
@@ -330524,9 +330939,9 @@ Tip: The shorthand "${resolvedSource.repo}" assumes github.com. ` + `For interna
330524
330939
  }
330525
330940
  logForDebugging3(`Marketplace '${marketplace.name}' exists with different source — overwriting`);
330526
330941
  if (!isLocalMarketplaceSource(oldEntry.source)) {
330527
- const cacheDir = resolve43(getMarketplacesCacheDir());
330528
- const resolvedOld = resolve43(oldEntry.installLocation);
330529
- const resolvedNew = resolve43(cachePath);
330942
+ const cacheDir = resolve45(getMarketplacesCacheDir());
330943
+ const resolvedOld = resolve45(oldEntry.installLocation);
330944
+ const resolvedNew = resolve45(cachePath);
330530
330945
  if (resolvedOld === resolvedNew) {} else if (resolvedOld === cacheDir || resolvedOld.startsWith(cacheDir + sep26)) {
330531
330946
  const fs = getFsImplementation2();
330532
330947
  await fs.rm(oldEntry.installLocation, { recursive: true, force: true });
@@ -330548,7 +330963,7 @@ Tip: The shorthand "${resolvedSource.repo}" assumes github.com. ` + `For interna
330548
330963
  }
330549
330964
  async function adoptOrphanMarketplace(dirName, overrideName) {
330550
330965
  const fs = getFsImplementation2();
330551
- const cacheDir = resolve43(getMarketplacesCacheDir());
330966
+ const cacheDir = resolve45(getMarketplacesCacheDir());
330552
330967
  const dirPath = join118(cacheDir, dirName);
330553
330968
  if (!fs.existsSync(dirPath) || !fs.statSync(dirPath).isDirectory()) {
330554
330969
  throw new Error(`No marketplace directory named '${dirName}' in ${cacheDir}. ` + `Run \`plugin marketplace list\` to see unregistered directories.`);
@@ -330578,7 +330993,7 @@ async function adoptOrphanMarketplace(dirName, overrideName) {
330578
330993
  await updateKnownMarketplacesConfig((existing) => {
330579
330994
  const prior = existing[name];
330580
330995
  if (prior) {
330581
- if (resolve43(prior.installLocation) === resolve43(dirPath)) {
330996
+ if (resolve45(prior.installLocation) === resolve45(dirPath)) {
330582
330997
  return;
330583
330998
  }
330584
330999
  throw new Error(`Marketplace name '${name}' is already registered at ` + `${prior.installLocation}. Remove it first ` + `(\`plugin marketplace remove ${name}\`) or adopt under a different name.`);
@@ -330809,8 +331224,8 @@ async function refreshMarketplace(name, onProgress, options) {
330809
331224
  throw new Error(`Marketplace '${name}' is seed-managed (${seedDir}) and its content is ` + `controlled by the seed image. To update: ask your admin to update the seed.`);
330810
331225
  }
330811
331226
  if (!isLocalMarketplaceSource(source)) {
330812
- const cacheDir = resolve43(getMarketplacesCacheDir());
330813
- const resolvedLoc = resolve43(installLocation);
331227
+ const cacheDir = resolve45(getMarketplacesCacheDir());
331228
+ const resolvedLoc = resolve45(installLocation);
330814
331229
  if (resolvedLoc !== cacheDir && !resolvedLoc.startsWith(cacheDir + sep26)) {
330815
331230
  throw new Error(`Marketplace '${name}' has a corrupted installLocation ` + `(${installLocation}) — expected a path inside ${cacheDir}. ` + `This can happen after cross-platform path writes or manual edits ` + `to known_marketplaces.json. ` + `Run: claude plugin marketplace remove "${name}" and re-add it.`);
330816
331231
  }
@@ -331814,14 +332229,14 @@ var init_pluginVersioning = __esm(() => {
331814
332229
  // src/tui/utils/plugins/pluginInstallationHelpers.ts
331815
332230
  import { randomBytes as randomBytes16 } from "crypto";
331816
332231
  import { rename as rename6, rm as rm8 } from "fs/promises";
331817
- import { dirname as dirname64, join as join121, resolve as resolve44, sep as sep27 } from "path";
332232
+ import { dirname as dirname64, join as join121, resolve as resolve46, sep as sep27 } from "path";
331818
332233
  function getCurrentTimestamp() {
331819
332234
  return new Date().toISOString();
331820
332235
  }
331821
332236
  function validatePathWithinBase(basePath, relativePath) {
331822
- const resolvedPath = resolve44(basePath, relativePath);
331823
- const normalizedBase = resolve44(basePath) + sep27;
331824
- if (!resolvedPath.startsWith(normalizedBase) && resolvedPath !== resolve44(basePath)) {
332237
+ const resolvedPath = resolve46(basePath, relativePath);
332238
+ const normalizedBase = resolve46(basePath) + sep27;
332239
+ if (!resolvedPath.startsWith(normalizedBase) && resolvedPath !== resolve46(basePath)) {
331825
332240
  throw new Error(`Path traversal detected: "${relativePath}" would escape the base directory`);
331826
332241
  }
331827
332242
  return resolvedPath;
@@ -332055,14 +332470,14 @@ import {
332055
332470
  readdir as readdir24,
332056
332471
  readFile as readFile43,
332057
332472
  readlink,
332058
- realpath as realpath11,
332473
+ realpath as realpath12,
332059
332474
  rename as rename7,
332060
332475
  rm as rm9,
332061
332476
  rmdir,
332062
332477
  stat as stat40,
332063
332478
  symlink as symlink5
332064
332479
  } from "fs/promises";
332065
- import { basename as basename36, dirname as dirname65, join as join122, relative as relative22, resolve as resolve45, sep as sep28 } from "path";
332480
+ import { basename as basename36, dirname as dirname65, join as join122, relative as relative22, resolve as resolve47, sep as sep28 } from "path";
332066
332481
  function getPluginCachePath() {
332067
332482
  return join122(getPluginsDirectory(), "cache");
332068
332483
  }
@@ -332119,14 +332534,14 @@ async function copyDir(src, dest) {
332119
332534
  const linkTarget = await readlink(srcPath);
332120
332535
  let resolvedTarget;
332121
332536
  try {
332122
- resolvedTarget = await realpath11(srcPath);
332537
+ resolvedTarget = await realpath12(srcPath);
332123
332538
  } catch {
332124
332539
  await symlink5(linkTarget, destPath);
332125
332540
  continue;
332126
332541
  }
332127
332542
  let resolvedSrc;
332128
332543
  try {
332129
- resolvedSrc = await realpath11(src);
332544
+ resolvedSrc = await realpath12(src);
332130
332545
  } catch {
332131
332546
  resolvedSrc = src;
332132
332547
  }
@@ -332740,7 +333155,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332740
333155
  try {
332741
333156
  mergedHooks = await loadPluginHooks2(standardHooksPath, manifest.name);
332742
333157
  try {
332743
- loadedHookPaths.add(await realpath11(standardHooksPath));
333158
+ loadedHookPaths.add(await realpath12(standardHooksPath));
332744
333159
  } catch {
332745
333160
  loadedHookPaths.add(standardHooksPath);
332746
333161
  }
@@ -332779,7 +333194,7 @@ async function createPluginFromPath(pluginPath, source, enabled, fallbackName, s
332779
333194
  }
332780
333195
  let normalizedPath;
332781
333196
  try {
332782
- normalizedPath = await realpath11(hookFilePath);
333197
+ normalizedPath = await realpath12(hookFilePath);
332783
333198
  } catch {
332784
333199
  normalizedPath = hookFilePath;
332785
333200
  }
@@ -333416,7 +333831,7 @@ async function loadSessionOnlyPlugins(sessionPluginPaths) {
333416
333831
  const errors = [];
333417
333832
  for (const [index, pluginPath] of sessionPluginPaths.entries()) {
333418
333833
  try {
333419
- const resolvedPath = resolve45(pluginPath);
333834
+ const resolvedPath = resolve47(pluginPath);
333420
333835
  if (!await pathExists2(resolvedPath)) {
333421
333836
  logForDebugging3(`Plugin path does not exist: ${resolvedPath}, skipping`, { level: "warn" });
333422
333837
  errors.push({
@@ -338495,7 +338910,7 @@ __export(exports_permissionSetup, {
338495
338910
  verifyAutoModeGateAccess: () => verifyAutoModeGateAccess
338496
338911
  });
338497
338912
  import { relative as relative23 } from "path";
338498
- import { resolve as resolve46 } from "path";
338913
+ import { resolve as resolve48 } from "path";
338499
338914
  function isDangerousBashPermission(toolName, ruleContent) {
338500
338915
  if (toolName !== BASH_TOOL_NAME2) {
338501
338916
  return false;
@@ -338767,7 +339182,7 @@ function isSymlinkTo2({
338767
339182
  originalCwd
338768
339183
  }) {
338769
339184
  const { resolvedPath: resolvedProcessPwd, isSymlink: isProcessPwdSymlink } = safeResolvePath3(getFsImplementation2(), processPwd);
338770
- return isProcessPwdSymlink ? resolvedProcessPwd === resolve46(originalCwd) : false;
339185
+ return isProcessPwdSymlink ? resolvedProcessPwd === resolve48(originalCwd) : false;
338771
339186
  }
338772
339187
  function initialPermissionModeFromCLI2({
338773
339188
  permissionModeCli,
@@ -346388,6 +346803,65 @@ var init_color3 = __esm(() => {
346388
346803
  color_default = color2;
346389
346804
  });
346390
346805
 
346806
+ // src/tui/commands/tui/tui.ts
346807
+ var exports_tui = {};
346808
+ __export(exports_tui, {
346809
+ call: () => call7
346810
+ });
346811
+ var ON_ALIASES, OFF_ALIASES, USAGE = "Usage: /tui fullscreen|off (no argument = status)", call7 = (onDone, context, args) => {
346812
+ const arg = (args ?? "").trim().toLowerCase();
346813
+ if (arg === "") {
346814
+ const active = getFullscreenRuntimeOverride() ?? isFullscreenEnvEnabled();
346815
+ onDone(`Fullscreen rendering: ${active ? "on" : "off"} (this session) · ${USAGE}`, { display: "system" });
346816
+ return Promise.resolve(null);
346817
+ }
346818
+ let target;
346819
+ if (ON_ALIASES.includes(arg)) {
346820
+ target = true;
346821
+ } else if (OFF_ALIASES.includes(arg)) {
346822
+ target = false;
346823
+ } else {
346824
+ onDone(`Invalid /tui argument "${arg}". ${USAGE}`, { display: "system" });
346825
+ return Promise.resolve(null);
346826
+ }
346827
+ const { error } = updateSettingsForSource2("userSettings", {
346828
+ tui: { fullscreen: target }
346829
+ });
346830
+ if (error) {
346831
+ onDone(`Failed to persist fullscreen setting: ${error.message}`, {
346832
+ display: "system"
346833
+ });
346834
+ return Promise.resolve(null);
346835
+ }
346836
+ setFullscreenRuntimeOverride(target);
346837
+ context.setAppState((prev) => ({
346838
+ ...prev,
346839
+ settings: { ...prev.settings, tui: { fullscreen: target } }
346840
+ }));
346841
+ onDone(target ? "Fullscreen rendering enabled for this session (in-session switch, no restart). Persisted to user settings." : "Fullscreen rendering disabled for this session (in-session switch, no restart). Persisted to user settings.", { display: "system" });
346842
+ return Promise.resolve(null);
346843
+ };
346844
+ var init_tui = __esm(() => {
346845
+ init_fullscreen();
346846
+ init_settings3();
346847
+ ON_ALIASES = ["fullscreen", "on", "true", "1"];
346848
+ OFF_ALIASES = ["off", "default", "reset", "false", "0"];
346849
+ });
346850
+
346851
+ // src/tui/commands/tui/index.ts
346852
+ var tui, tui_default;
346853
+ var init_tui2 = __esm(() => {
346854
+ tui = {
346855
+ type: "local-jsx",
346856
+ name: "tui",
346857
+ description: "Toggle fullscreen rendering for this session (no restart): /tui fullscreen|off, no argument = status",
346858
+ immediate: true,
346859
+ argumentHint: "<fullscreen|off>",
346860
+ load: () => Promise.resolve().then(() => (init_tui(), exports_tui))
346861
+ };
346862
+ tui_default = tui;
346863
+ });
346864
+
346391
346865
  // src/tui/commands/commit.ts
346392
346866
  function getPromptContent() {
346393
346867
  const { commit: commitAttribution } = getAttributionTexts();
@@ -346473,7 +346947,7 @@ var init_commit = __esm(() => {
346473
346947
  // src/tui/commands/copy/copy.tsx
346474
346948
  var exports_copy = {};
346475
346949
  __export(exports_copy, {
346476
- call: () => call7,
346950
+ call: () => call8,
346477
346951
  collectRecentAssistantTexts: () => collectRecentAssistantTexts,
346478
346952
  fileExtension: () => fileExtension2
346479
346953
  });
@@ -346801,7 +347275,7 @@ function _temp46(block, index) {
346801
347275
  description: [block.lang, blockLines > 1 ? `${blockLines} lines` : undefined].filter(Boolean).join(", ") || undefined
346802
347276
  };
346803
347277
  }
346804
- var import_compiler_runtime113, import_react81, jsx_dev_runtime138, COPY_DIR, RESPONSE_FILENAME = "response.md", MAX_LOOKBACK = 20, call7 = async (onDone, context, args) => {
347278
+ var import_compiler_runtime113, import_react81, jsx_dev_runtime138, COPY_DIR, RESPONSE_FILENAME = "response.md", MAX_LOOKBACK = 20, call8 = async (onDone, context, args) => {
346805
347279
  const texts = collectRecentAssistantTexts(context.messages);
346806
347280
  if (texts.length === 0) {
346807
347281
  onDone("No assistant message to copy");
@@ -347442,7 +347916,7 @@ var init_CustomSelect = __esm(() => {
347442
347916
  // src/tui/commands/autocompact/autocompact.tsx
347443
347917
  var exports_autocompact = {};
347444
347918
  __export(exports_autocompact, {
347445
- call: () => call8
347919
+ call: () => call9
347446
347920
  });
347447
347921
  function currentToOptionValue(setting) {
347448
347922
  if (!setting || setting.kind === "auto")
@@ -347586,7 +348060,7 @@ function AutoCompactCommand({ onDone }) {
347586
348060
  ]
347587
348061
  }, undefined, true, undefined, this);
347588
348062
  }
347589
- var React41, jsx_dev_runtime140, PRESET_TIERS, call8 = async (onDone, _context, args) => {
348063
+ var React41, jsx_dev_runtime140, PRESET_TIERS, call9 = async (onDone, _context, args) => {
347590
348064
  const raw = (args ?? "").trim();
347591
348065
  if (raw === "") {
347592
348066
  return /* @__PURE__ */ jsx_dev_runtime140.jsxDEV(AutoCompactCommand, {
@@ -347711,7 +348185,7 @@ var init_sessionMemoryUtils = __esm(() => {
347711
348185
  // src/tui/commands/compact/compact.ts
347712
348186
  var exports_compact = {};
347713
348187
  __export(exports_compact, {
347714
- call: () => call9
348188
+ call: () => call10
347715
348189
  });
347716
348190
  async function compactViaReactive(messages, context, customInstructions, reactive) {
347717
348191
  context.onCompactProgress?.({
@@ -347802,7 +348276,7 @@ async function getCacheSharingParams(context, forkContextMessages) {
347802
348276
  forkContextMessages
347803
348277
  };
347804
348278
  }
347805
- var reactiveCompact, call9 = async (args, context) => {
348279
+ var reactiveCompact, call10 = async (args, context) => {
347806
348280
  const { abortController } = context;
347807
348281
  let { messages } = context;
347808
348282
  messages = getMessagesAfterCompactBoundary(messages);
@@ -348886,7 +349360,7 @@ var init_packageManagers = __esm(() => {
348886
349360
  });
348887
349361
 
348888
349362
  // src/tui/utils/doctorDiagnostic.ts
348889
- import { readFile as readFile49, realpath as realpath12 } from "fs/promises";
349363
+ import { readFile as readFile49, realpath as realpath13 } from "fs/promises";
348890
349364
  import { homedir as homedir33 } from "os";
348891
349365
  import { delimiter as delimiter2, join as join134, posix as posix8, win32 as win322 } from "path";
348892
349366
  function getNormalizedPaths() {
@@ -348942,7 +349416,7 @@ async function getInstallationPath() {
348942
349416
  }
348943
349417
  if (isInBundledMode2()) {
348944
349418
  try {
348945
- return await realpath12(process.execPath);
349419
+ return await realpath13(process.execPath);
348946
349420
  } catch {}
348947
349421
  try {
348948
349422
  const path = await which("atlas");
@@ -349001,7 +349475,7 @@ async function detectMultipleInstallations() {
349001
349475
  if (globalBinExists) {
349002
349476
  let isCurrentHomebrewInstallation = false;
349003
349477
  try {
349004
- const realPath = await realpath12(globalBinPath);
349478
+ const realPath = await realpath13(globalBinPath);
349005
349479
  if (realPath.includes("/Caskroom/")) {
349006
349480
  isCurrentHomebrewInstallation = detectHomebrew();
349007
349481
  }
@@ -349545,7 +350019,7 @@ import {
349545
350019
  mkdir as mkdir40,
349546
350020
  readdir as readdir26,
349547
350021
  readlink as readlink2,
349548
- realpath as realpath13,
350022
+ realpath as realpath14,
349549
350023
  rename as rename8,
349550
350024
  rm as rm10,
349551
350025
  rmdir as rmdir2,
@@ -349555,7 +350029,7 @@ import {
349555
350029
  writeFile as writeFile36
349556
350030
  } from "fs/promises";
349557
350031
  import { homedir as homedir34 } from "os";
349558
- import { basename as basename42, delimiter as delimiter3, dirname as dirname69, join as join137, resolve as resolve47 } from "path";
350032
+ import { basename as basename42, delimiter as delimiter3, dirname as dirname69, join as join137, resolve as resolve49 } from "path";
349559
350033
  function getPlatform4() {
349560
350034
  const os = env5.platform;
349561
350035
  const arch = process.arch === "x64" ? "x64" : process.arch === "arm64" ? "arm64" : null;
@@ -349903,8 +350377,8 @@ async function updateSymlink(symlinkPath, targetPath) {
349903
350377
  if (symlinkExists) {
349904
350378
  try {
349905
350379
  const currentTarget = await readlink2(symlinkPath);
349906
- const resolvedCurrentTarget = resolve47(dirname69(symlinkPath), currentTarget);
349907
- const resolvedTargetPath = resolve47(targetPath);
350380
+ const resolvedCurrentTarget = resolve49(dirname69(symlinkPath), currentTarget);
350381
+ const resolvedTargetPath = resolve49(targetPath);
349908
350382
  if (resolvedCurrentTarget === resolvedTargetPath) {
349909
350383
  return false;
349910
350384
  }
@@ -349944,7 +350418,7 @@ async function checkInstall(force = false) {
349944
350418
  const dirs = getBaseDirectories();
349945
350419
  const messages = [];
349946
350420
  const localBinDir = dirname69(dirs.executable);
349947
- const resolvedLocalBinPath = resolve47(localBinDir);
350421
+ const resolvedLocalBinPath = resolve49(localBinDir);
349948
350422
  const platform = getPlatform4();
349949
350423
  const isWindows = platform.startsWith("win32");
349950
350424
  try {
@@ -349967,7 +350441,7 @@ async function checkInstall(force = false) {
349967
350441
  } else {
349968
350442
  try {
349969
350443
  const target = await readlink2(dirs.executable);
349970
- const absoluteTarget = resolve47(dirname69(dirs.executable), target);
350444
+ const absoluteTarget = resolve49(dirname69(dirs.executable), target);
349971
350445
  if (!await isPossibleClaudeBinary(absoluteTarget)) {
349972
350446
  messages.push({
349973
350447
  message: `AtlasCode symlink points to missing or invalid binary: ${target}`,
@@ -349995,7 +350469,7 @@ async function checkInstall(force = false) {
349995
350469
  }
349996
350470
  const isInCurrentPath = (process.env.PATH || "").split(delimiter3).some((entry) => {
349997
350471
  try {
349998
- const resolvedEntry = resolve47(entry);
350472
+ const resolvedEntry = resolve49(entry);
349999
350473
  if (isWindows) {
350000
350474
  return resolvedEntry.toLowerCase() === resolvedLocalBinPath.toLowerCase();
350001
350475
  }
@@ -350074,7 +350548,7 @@ async function installLatestImpl(channelOrVersion, forceReinstall = false) {
350074
350548
  async function getVersionFromSymlink(symlinkPath) {
350075
350549
  try {
350076
350550
  const target = await readlink2(symlinkPath);
350077
- const absoluteTarget = resolve47(dirname69(symlinkPath), target);
350551
+ const absoluteTarget = resolve49(dirname69(symlinkPath), target);
350078
350552
  if (await isPossibleClaudeBinary(absoluteTarget)) {
350079
350553
  return absoluteTarget;
350080
350554
  }
@@ -350090,7 +350564,7 @@ async function lockCurrentVersion() {
350090
350564
  if (!process.execPath.includes(dirs.versions)) {
350091
350565
  return;
350092
350566
  }
350093
- const versionPath = resolve47(process.execPath);
350567
+ const versionPath = resolve49(process.execPath);
350094
350568
  try {
350095
350569
  const lockfilePath = getLockFilePathFromVersionPath(dirs, versionPath);
350096
350570
  await mkdir40(dirs.locks, { recursive: true });
@@ -350236,7 +350710,7 @@ async function cleanupOldVersions() {
350236
350710
  versionFiles.push({
350237
350711
  name: entry,
350238
350712
  path: entryPath,
350239
- resolvedPath: resolve47(entryPath),
350713
+ resolvedPath: resolve49(entryPath),
350240
350714
  mtime: stats.mtime
350241
350715
  });
350242
350716
  } catch {}
@@ -350251,7 +350725,7 @@ async function cleanupOldVersions() {
350251
350725
  const currentBinaryPath = process.execPath;
350252
350726
  const protectedVersions = new Set;
350253
350727
  if (currentBinaryPath && currentBinaryPath.includes(dirs.versions)) {
350254
- protectedVersions.add(resolve47(currentBinaryPath));
350728
+ protectedVersions.add(resolve49(currentBinaryPath));
350255
350729
  }
350256
350730
  const currentSymlinkVersion = await getVersionFromSymlink(dirs.executable);
350257
350731
  if (currentSymlinkVersion) {
@@ -350313,7 +350787,7 @@ async function isNpmSymlink(executablePath) {
350313
350787
  let targetPath = executablePath;
350314
350788
  const stats = await lstat6(executablePath);
350315
350789
  if (stats.isSymbolicLink()) {
350316
- targetPath = await realpath13(executablePath);
350790
+ targetPath = await realpath14(executablePath);
350317
350791
  }
350318
350792
  return targetPath.endsWith(".js") || targetPath.includes("node_modules");
350319
350793
  }
@@ -354893,9 +355367,9 @@ var init_Settings = __esm(() => {
354893
355367
  // src/tui/commands/config/config.tsx
354894
355368
  var exports_config = {};
354895
355369
  __export(exports_config, {
354896
- call: () => call10
355370
+ call: () => call11
354897
355371
  });
354898
- var jsx_dev_runtime153, call10 = async (onDone, context) => {
355372
+ var jsx_dev_runtime153, call11 = async (onDone, context) => {
354899
355373
  return /* @__PURE__ */ jsx_dev_runtime153.jsxDEV(Settings, {
354900
355374
  onClose: onDone,
354901
355375
  context,
@@ -356131,7 +356605,7 @@ var projectView = () => ({});
356131
356605
  // src/tui/commands/context/context.tsx
356132
356606
  var exports_context = {};
356133
356607
  __export(exports_context, {
356134
- call: () => call11
356608
+ call: () => call12
356135
356609
  });
356136
356610
  function toApiView(messages) {
356137
356611
  let view = getMessagesAfterCompactBoundary(messages);
@@ -356141,7 +356615,7 @@ function toApiView(messages) {
356141
356615
  }
356142
356616
  return view;
356143
356617
  }
356144
- async function call11(onDone, context) {
356618
+ async function call12(onDone, context) {
356145
356619
  const {
356146
356620
  messages,
356147
356621
  getAppState,
@@ -356177,7 +356651,7 @@ var init_context3 = __esm(() => {
356177
356651
  // src/tui/commands/context/context-noninteractive.ts
356178
356652
  var exports_context_noninteractive = {};
356179
356653
  __export(exports_context_noninteractive, {
356180
- call: () => call12,
356654
+ call: () => call13,
356181
356655
  collectContextData: () => collectContextData
356182
356656
  });
356183
356657
  async function collectContextData(context) {
@@ -356201,7 +356675,7 @@ async function collectContextData(context) {
356201
356675
  const appState = getAppState();
356202
356676
  return analyzeContextUsage(compactedMessages, mainLoopModel, async () => appState.toolPermissionContext, tools, agentDefinitions, undefined, { options: { customSystemPrompt, appendSystemPrompt } }, undefined, apiView);
356203
356677
  }
356204
- async function call12(_args, context) {
356678
+ async function call13(_args, context) {
356205
356679
  const data = await collectContextData(context);
356206
356680
  return {
356207
356681
  type: "text",
@@ -356496,9 +356970,9 @@ var init_context4 = __esm(() => {
356496
356970
  // src/tui/commands/cost/cost.ts
356497
356971
  var exports_cost = {};
356498
356972
  __export(exports_cost, {
356499
- call: () => call13
356973
+ call: () => call14
356500
356974
  });
356501
- var call13 = async () => {
356975
+ var call14 = async () => {
356502
356976
  return { type: "text", value: formatTotalCost() };
356503
356977
  };
356504
356978
  var init_cost = __esm(() => {
@@ -356721,7 +357195,7 @@ var init_useTurnDiffs = __esm(() => {
356721
357195
  });
356722
357196
 
356723
357197
  // src/tui/components/diff/DiffDetailView.tsx
356724
- import { resolve as resolve48 } from "path";
357198
+ import { resolve as resolve50 } from "path";
356725
357199
  function DiffDetailView(t0) {
356726
357200
  const $ = import_compiler_runtime130.c(53);
356727
357201
  const {
@@ -356754,7 +357228,7 @@ function DiffDetailView(t0) {
356754
357228
  let content;
356755
357229
  let t2;
356756
357230
  if ($[1] !== filePath) {
356757
- const fullPath = resolve48(getCwd(), filePath);
357231
+ const fullPath = resolve50(getCwd(), filePath);
356758
357232
  content = readFileSafe2(fullPath);
356759
357233
  t2 = content?.split(`
356760
357234
  `)[0] ?? null;
@@ -357974,9 +358448,9 @@ var init_DiffDialog = __esm(() => {
357974
358448
  // src/tui/commands/diff/diff.tsx
357975
358449
  var exports_diff = {};
357976
358450
  __export(exports_diff, {
357977
- call: () => call14
358451
+ call: () => call15
357978
358452
  });
357979
- var jsx_dev_runtime162, call14 = async (onDone, context) => {
358453
+ var jsx_dev_runtime162, call15 = async (onDone, context) => {
357980
358454
  await Promise.resolve().then(() => init_DiffDialog());
357981
358455
  return /* @__PURE__ */ jsx_dev_runtime162.jsxDEV(DiffDialog, {
357982
358456
  messages: context.messages,
@@ -360174,9 +360648,9 @@ var init_Doctor = __esm(() => {
360174
360648
  // src/tui/commands/doctor/doctor.tsx
360175
360649
  var exports_doctor = {};
360176
360650
  __export(exports_doctor, {
360177
- call: () => call15
360651
+ call: () => call16
360178
360652
  });
360179
- var jsx_dev_runtime169, call15 = (onDone, _context, _args) => {
360653
+ var jsx_dev_runtime169, call16 = (onDone, _context, _args) => {
360180
360654
  return Promise.resolve(/* @__PURE__ */ jsx_dev_runtime169.jsxDEV(Doctor, {
360181
360655
  onDone
360182
360656
  }, undefined, false, undefined, this));
@@ -360949,7 +361423,7 @@ var init_promptEditor = __esm(() => {
360949
361423
  // src/tui/commands/memory/memory.tsx
360950
361424
  var exports_memory = {};
360951
361425
  __export(exports_memory, {
360952
- call: () => call16
361426
+ call: () => call17
360953
361427
  });
360954
361428
  import { mkdir as mkdir42, writeFile as writeFile37 } from "fs/promises";
360955
361429
  function MemoryCommand({
@@ -361029,7 +361503,7 @@ ${editorHint}`, {
361029
361503
  }, undefined, true, undefined, this)
361030
361504
  }, undefined, false, undefined, this);
361031
361505
  }
361032
- var React48, jsx_dev_runtime171, call16 = async (onDone) => {
361506
+ var React48, jsx_dev_runtime171, call17 = async (onDone) => {
361033
361507
  clearMemoryFileCaches();
361034
361508
  await getMemoryFiles();
361035
361509
  return /* @__PURE__ */ jsx_dev_runtime171.jsxDEV(MemoryCommand, {
@@ -361985,9 +362459,9 @@ var init_HelpV2 = __esm(() => {
361985
362459
  // src/tui/commands/help/help.tsx
361986
362460
  var exports_help = {};
361987
362461
  __export(exports_help, {
361988
- call: () => call17
362462
+ call: () => call18
361989
362463
  });
361990
- var jsx_dev_runtime176, call17 = async (onDone, {
362464
+ var jsx_dev_runtime176, call18 = async (onDone, {
361991
362465
  options: {
361992
362466
  commands
361993
362467
  }
@@ -362194,7 +362668,7 @@ var init_IdeAutoConnectDialog = __esm(() => {
362194
362668
  // src/tui/commands/ide/ide.tsx
362195
362669
  var exports_ide = {};
362196
362670
  __export(exports_ide, {
362197
- call: () => call18,
362671
+ call: () => call19,
362198
362672
  formatWorkspaceFolders: () => formatWorkspaceFolders
362199
362673
  });
362200
362674
  import * as path22 from "path";
@@ -362673,7 +363147,7 @@ function InstallOnMount(t0) {
362673
363147
  import_react99.useEffect(t1, t2);
362674
363148
  return null;
362675
363149
  }
362676
- async function call18(onDone, context, args) {
363150
+ async function call19(onDone, context, args) {
362677
363151
  const {
362678
363152
  options: {
362679
363153
  dynamicMcpConfig
@@ -363453,11 +363927,11 @@ var init_template2 = __esm(() => {
363453
363927
  // src/tui/commands/keybindings/keybindings.ts
363454
363928
  var exports_keybindings = {};
363455
363929
  __export(exports_keybindings, {
363456
- call: () => call19
363930
+ call: () => call20
363457
363931
  });
363458
363932
  import { mkdir as mkdir43, writeFile as writeFile38 } from "fs/promises";
363459
363933
  import { dirname as dirname70 } from "path";
363460
- async function call19() {
363934
+ async function call20() {
363461
363935
  if (!isKeybindingCustomizationEnabled()) {
363462
363936
  return {
363463
363937
  type: "text",
@@ -363746,9 +364220,9 @@ var init_user = __esm(() => {
363746
364220
  var exports_login = {};
363747
364221
  __export(exports_login, {
363748
364222
  Login: () => Login,
363749
- call: () => call20
364223
+ call: () => call21
363750
364224
  });
363751
- async function call20(onDone, context) {
364225
+ async function call21(onDone, context) {
363752
364226
  return /* @__PURE__ */ jsx_dev_runtime180.jsxDEV(Login, {
363753
364227
  onDone: async (success) => {
363754
364228
  context.onChangeAPIKey();
@@ -363870,7 +364344,7 @@ var init_login2 = __esm(() => {
363870
364344
  // src/tui/commands/logout/logout.tsx
363871
364345
  var exports_logout = {};
363872
364346
  __export(exports_logout, {
363873
- call: () => call21,
364347
+ call: () => call22,
363874
364348
  clearAuthRelatedCaches: () => clearAuthRelatedCaches,
363875
364349
  performLogout: () => performLogout
363876
364350
  });
@@ -363907,7 +364381,7 @@ async function clearAuthRelatedCaches() {
363907
364381
  resetUserCache();
363908
364382
  refreshGrowthBookAfterAuthChange();
363909
364383
  }
363910
- async function call21() {
364384
+ async function call22() {
363911
364385
  await performLogout({
363912
364386
  clearOnboarding: true
363913
364387
  });
@@ -370079,7 +370553,7 @@ var init_mcp5 = __esm(() => {
370079
370553
  // src/tui/commands/mcp/mcp.tsx
370080
370554
  var exports_mcp = {};
370081
370555
  __export(exports_mcp, {
370082
- call: () => call22
370556
+ call: () => call23
370083
370557
  });
370084
370558
  function MCPToggle(t0) {
370085
370559
  const $ = import_compiler_runtime161.c(7);
@@ -370132,7 +370606,7 @@ function _temp235(c) {
370132
370606
  function _temp89(s) {
370133
370607
  return s.mcp.clients;
370134
370608
  }
370135
- async function call22(onDone, _context, args) {
370609
+ async function call23(onDone, _context, args) {
370136
370610
  if (args) {
370137
370611
  const parts = args.trim().split(/\s+/);
370138
370612
  if (parts[0] === "no-redirect") {
@@ -370338,7 +370812,7 @@ var init_releaseNotes = __esm(() => {
370338
370812
  // src/tui/commands/release-notes/release-notes.ts
370339
370813
  var exports_release_notes = {};
370340
370814
  __export(exports_release_notes, {
370341
- call: () => call23
370815
+ call: () => call24
370342
370816
  });
370343
370817
  function formatReleaseNotes(notes) {
370344
370818
  return notes.map(([version, notes]) => {
@@ -370351,7 +370825,7 @@ ${bulletPoints}`;
370351
370825
 
370352
370826
  `);
370353
370827
  }
370354
- async function call23() {
370828
+ async function call24() {
370355
370829
  let freshNotes = [];
370356
370830
  try {
370357
370831
  const timeoutPromise = new Promise((_, reject) => {
@@ -370542,9 +371016,9 @@ var init_generateSessionName = __esm(() => {
370542
371016
  // src/tui/commands/rename/rename.ts
370543
371017
  var exports_rename = {};
370544
371018
  __export(exports_rename, {
370545
- call: () => call24
371019
+ call: () => call25
370546
371020
  });
370547
- async function call24(onDone, context, args) {
371021
+ async function call25(onDone, context, args) {
370548
371022
  if (isTeammate2()) {
370549
371023
  onDone("Cannot rename: This session is a swarm teammate. Teammate names are set by the team leader.", { display: "system" });
370550
371024
  return null;
@@ -378511,7 +378985,7 @@ var init_crossProjectResume = __esm(() => {
378511
378985
  // src/tui/commands/resume/resume.tsx
378512
378986
  var exports_resume = {};
378513
378987
  __export(exports_resume, {
378514
- call: () => call25,
378988
+ call: () => call26,
378515
378989
  filterResumableSessions: () => filterResumableSessions
378516
378990
  });
378517
378991
  function resumeHelpMessage(result) {
@@ -378697,7 +379171,7 @@ function ResumeCommand({
378697
379171
  function filterResumableSessions(logs, currentSessionId) {
378698
379172
  return logs.filter((l) => !l.isSidechain && getSessionIdFromLog(l) !== currentSessionId);
378699
379173
  }
378700
- var import_compiler_runtime179, React69, jsx_dev_runtime221, call25 = async (onDone, context, args) => {
379174
+ var import_compiler_runtime179, React69, jsx_dev_runtime221, call26 = async (onDone, context, args) => {
378701
379175
  const onResume = async (sessionId, log, entrypoint) => {
378702
379176
  try {
378703
379177
  await context.resume?.(sessionId, log, entrypoint);
@@ -383095,7 +383569,7 @@ var init_server = __esm(() => {
383095
383569
  // src/tui/commands/session/session.tsx
383096
383570
  var exports_session = {};
383097
383571
  __export(exports_session, {
383098
- call: () => call26
383572
+ call: () => call27
383099
383573
  });
383100
383574
  function SessionInfo(t0) {
383101
383575
  const $ = import_compiler_runtime180.c(19);
@@ -383285,7 +383759,7 @@ function _temp241(e) {
383285
383759
  function _temp105(s) {
383286
383760
  return s.remoteSessionUrl;
383287
383761
  }
383288
- var import_compiler_runtime180, import_react131, jsx_dev_runtime222, call26 = async (onDone) => {
383762
+ var import_compiler_runtime180, import_react131, jsx_dev_runtime222, call27 = async (onDone) => {
383289
383763
  return /* @__PURE__ */ jsx_dev_runtime222.jsxDEV(SessionInfo, {
383290
383764
  onDone
383291
383765
  }, undefined, false, undefined, this);
@@ -383641,9 +384115,9 @@ var init_SkillsMenu = __esm(() => {
383641
384115
  // src/tui/commands/skills/skills.tsx
383642
384116
  var exports_skills = {};
383643
384117
  __export(exports_skills, {
383644
- call: () => call27
384118
+ call: () => call28
383645
384119
  });
383646
- async function call27(onDone, context) {
384120
+ async function call28(onDone, context) {
383647
384121
  return /* @__PURE__ */ jsx_dev_runtime224.jsxDEV(SkillsMenu, {
383648
384122
  onExit: onDone,
383649
384123
  commands: context.options.commands
@@ -383670,9 +384144,9 @@ var init_skills3 = __esm(() => {
383670
384144
  // src/tui/commands/status/status.tsx
383671
384145
  var exports_status = {};
383672
384146
  __export(exports_status, {
383673
- call: () => call28
384147
+ call: () => call29
383674
384148
  });
383675
- async function call28(onDone, context) {
384149
+ async function call29(onDone, context) {
383676
384150
  return /* @__PURE__ */ jsx_dev_runtime225.jsxDEV(Settings, {
383677
384151
  onClose: onDone,
383678
384152
  context,
@@ -386868,9 +387342,9 @@ var init_BackgroundTasksDialog = __esm(() => {
386868
387342
  // src/tui/commands/tasks/tasks.tsx
386869
387343
  var exports_tasks = {};
386870
387344
  __export(exports_tasks, {
386871
- call: () => call29
387345
+ call: () => call30
386872
387346
  });
386873
- async function call29(onDone, context) {
387347
+ async function call30(onDone, context) {
386874
387348
  return /* @__PURE__ */ jsx_dev_runtime234.jsxDEV(BackgroundTasksDialog, {
386875
387349
  toolUseContext: context,
386876
387350
  onDone
@@ -387317,9 +387791,9 @@ var init_FileTaskDialog = __esm(() => {
387317
387791
  // src/tui/commands/tasklist/tasklist.tsx
387318
387792
  var exports_tasklist = {};
387319
387793
  __export(exports_tasklist, {
387320
- call: () => call30
387794
+ call: () => call31
387321
387795
  });
387322
- async function call30(onDone, _context) {
387796
+ async function call31(onDone, _context) {
387323
387797
  return /* @__PURE__ */ jsx_dev_runtime236.jsxDEV(FileTaskDialog, {
387324
387798
  onDone
387325
387799
  }, undefined, false, undefined, this);
@@ -387366,9 +387840,9 @@ var init_terminalSetup2 = __esm(() => {
387366
387840
  // src/tui/commands/usage/usage.tsx
387367
387841
  var exports_usage2 = {};
387368
387842
  __export(exports_usage2, {
387369
- call: () => call31
387843
+ call: () => call32
387370
387844
  });
387371
- var jsx_dev_runtime237, call31 = async (onDone, context) => {
387845
+ var jsx_dev_runtime237, call32 = async (onDone, context) => {
387372
387846
  return /* @__PURE__ */ jsx_dev_runtime237.jsxDEV(Settings, {
387373
387847
  onClose: onDone,
387374
387848
  context,
@@ -387395,7 +387869,7 @@ var init_usage4 = __esm(() => {
387395
387869
  // src/tui/commands/theme/theme.tsx
387396
387870
  var exports_theme = {};
387397
387871
  __export(exports_theme, {
387398
- call: () => call32
387872
+ call: () => call33
387399
387873
  });
387400
387874
  function ThemePickerCommand(t0) {
387401
387875
  const $ = import_compiler_runtime189.c(8);
@@ -387445,7 +387919,7 @@ function ThemePickerCommand(t0) {
387445
387919
  }
387446
387920
  return t3;
387447
387921
  }
387448
- var import_compiler_runtime189, jsx_dev_runtime238, call32 = async (onDone, _context) => {
387922
+ var import_compiler_runtime189, jsx_dev_runtime238, call33 = async (onDone, _context) => {
387449
387923
  return /* @__PURE__ */ jsx_dev_runtime238.jsxDEV(ThemePickerCommand, {
387450
387924
  onDone
387451
387925
  }, undefined, false, undefined, this);
@@ -387473,9 +387947,9 @@ var init_theme3 = __esm(() => {
387473
387947
  // src/tui/commands/vim/vim.ts
387474
387948
  var exports_vim = {};
387475
387949
  __export(exports_vim, {
387476
- call: () => call33
387950
+ call: () => call34
387477
387951
  });
387478
- var call33 = async () => {
387952
+ var call34 = async () => {
387479
387953
  const config = getGlobalConfig();
387480
387954
  let currentMode = config.editorMode || "normal";
387481
387955
  if (currentMode === "emacs") {
@@ -388187,7 +388661,7 @@ var init_pluginOperations = __esm(() => {
388187
388661
  // src/tui/commands/thinkback/thinkback.tsx
388188
388662
  var exports_thinkback = {};
388189
388663
  __export(exports_thinkback, {
388190
- call: () => call34,
388664
+ call: () => call35,
388191
388665
  playAnimation: () => playAnimation
388192
388666
  });
388193
388667
  import { readFile as readFile51 } from "fs/promises";
@@ -388725,7 +389199,7 @@ function ThinkbackFlow(t0) {
388725
389199
  }
388726
389200
  return t8;
388727
389201
  }
388728
- async function call34(onDone) {
389202
+ async function call35(onDone) {
388729
389203
  return /* @__PURE__ */ jsx_dev_runtime239.jsxDEV(ThinkbackFlow, {
388730
389204
  onDone
388731
389205
  }, undefined, false, undefined, this);
@@ -388773,13 +389247,13 @@ var init_thinkback2 = __esm(() => {
388773
389247
  // src/tui/commands/thinkback-play/thinkback-play.ts
388774
389248
  var exports_thinkback_play = {};
388775
389249
  __export(exports_thinkback_play, {
388776
- call: () => call35
389250
+ call: () => call36
388777
389251
  });
388778
389252
  import { join as join144 } from "path";
388779
389253
  function getPluginId2() {
388780
389254
  return `thinkback@${OFFICIAL_MARKETPLACE_NAME}`;
388781
389255
  }
388782
- async function call35() {
389256
+ async function call36() {
388783
389257
  const v2Data = loadInstalledPluginsV2();
388784
389258
  const pluginId = getPluginId2();
388785
389259
  const installations = v2Data.plugins[pluginId];
@@ -391281,9 +391755,9 @@ var init_PermissionRuleList = __esm(() => {
391281
391755
  // src/tui/commands/permissions/permissions.tsx
391282
391756
  var exports_permissions2 = {};
391283
391757
  __export(exports_permissions2, {
391284
- call: () => call36
391758
+ call: () => call37
391285
391759
  });
391286
- var jsx_dev_runtime247, call36 = async (onDone, context) => {
391760
+ var jsx_dev_runtime247, call37 = async (onDone, context) => {
391287
391761
  return /* @__PURE__ */ jsx_dev_runtime247.jsxDEV(PermissionRuleList, {
391288
391762
  onExit: onDone,
391289
391763
  onRetryDenials: (commands) => {
@@ -391313,7 +391787,7 @@ var init_permissions8 = __esm(() => {
391313
391787
  // src/tui/commands/plan/plan.tsx
391314
391788
  var exports_plan = {};
391315
391789
  __export(exports_plan, {
391316
- call: () => call37
391790
+ call: () => call38
391317
391791
  });
391318
391792
  function PlanDisplay(t0) {
391319
391793
  const $ = import_compiler_runtime198.c(11);
@@ -391401,7 +391875,7 @@ function PlanDisplay(t0) {
391401
391875
  }
391402
391876
  return t5;
391403
391877
  }
391404
- async function call37(onDone, context, args) {
391878
+ async function call38(onDone, context, args) {
391405
391879
  const {
391406
391880
  getAppState,
391407
391881
  setAppState
@@ -393239,9 +393713,9 @@ var init_HooksConfigMenu = __esm(() => {
393239
393713
  // src/tui/commands/hooks/hooks.tsx
393240
393714
  var exports_hooks = {};
393241
393715
  __export(exports_hooks, {
393242
- call: () => call38
393716
+ call: () => call39
393243
393717
  });
393244
- var jsx_dev_runtime254, call38 = async (onDone, context) => {
393718
+ var jsx_dev_runtime254, call39 = async (onDone, context) => {
393245
393719
  const appState = context.getAppState();
393246
393720
  const permissionContext = appState.toolPermissionContext;
393247
393721
  const toolNames = getTools2(permissionContext).map((tool) => tool.name);
@@ -393272,10 +393746,10 @@ var init_hooks5 = __esm(() => {
393272
393746
  // src/tui/commands/files/files.ts
393273
393747
  var exports_files4 = {};
393274
393748
  __export(exports_files4, {
393275
- call: () => call39
393749
+ call: () => call40
393276
393750
  });
393277
393751
  import { relative as relative27 } from "path";
393278
- async function call39(_args, context) {
393752
+ async function call40(_args, context) {
393279
393753
  const files = context.readFileState ? cacheKeys(context.readFileState) : [];
393280
393754
  if (files.length === 0) {
393281
393755
  return { type: "text", value: "No files in context" };
@@ -393307,7 +393781,7 @@ var init_files8 = __esm(() => {
393307
393781
  // src/tui/commands/branch/branch.ts
393308
393782
  var exports_branch = {};
393309
393783
  __export(exports_branch, {
393310
- call: () => call40,
393784
+ call: () => call41,
393311
393785
  createFork: () => createFork,
393312
393786
  deriveFirstPrompt: () => deriveFirstPrompt,
393313
393787
  getUniqueForkName: () => getUniqueForkName
@@ -393416,7 +393890,7 @@ async function getUniqueForkName(baseName) {
393416
393890
  }
393417
393891
  return `${baseName} (Branch ${nextNumber})`;
393418
393892
  }
393419
- async function call40(onDone, context, args) {
393893
+ async function call41(onDone, context, args) {
393420
393894
  const customTitle = args?.trim() || undefined;
393421
393895
  const originalSessionId = getSessionId();
393422
393896
  try {
@@ -399460,9 +399934,9 @@ var init_AgentsMenu = __esm(() => {
399460
399934
  // src/tui/commands/agents/agents.tsx
399461
399935
  var exports_agents2 = {};
399462
399936
  __export(exports_agents2, {
399463
- call: () => call41
399937
+ call: () => call42
399464
399938
  });
399465
- async function call41(onDone, context) {
399939
+ async function call42(onDone, context) {
399466
399940
  const appState = context.getAppState();
399467
399941
  const permissionContext = appState.toolPermissionContext;
399468
399942
  const tools = getTools2(permissionContext);
@@ -399625,7 +400099,7 @@ var init_refresh = __esm(() => {
399625
400099
 
399626
400100
  // src/tui/utils/plugins/parseMarketplaceInput.ts
399627
400101
  import { homedir as homedir37 } from "os";
399628
- import { resolve as resolve49 } from "path";
400102
+ import { resolve as resolve51 } from "path";
399629
400103
  function matchKnownGitHost(hostname) {
399630
400104
  const host = hostname.toLowerCase();
399631
400105
  for (const known of KNOWN_GIT_HOSTS) {
@@ -399677,7 +400151,7 @@ async function parseMarketplaceInput(input) {
399677
400151
  const isWindows = process.platform === "win32";
399678
400152
  const isWindowsPath = isWindows && (trimmed.startsWith(".\\") || trimmed.startsWith("..\\") || /^[a-zA-Z]:[/\\]/.test(trimmed));
399679
400153
  if (trimmed.startsWith("./") || trimmed.startsWith("../") || trimmed.startsWith("/") || trimmed.startsWith("~") || isWindowsPath) {
399680
- const resolvedPath = resolve49(trimmed.startsWith("~") ? trimmed.replace(/^~/, homedir37()) : trimmed);
400154
+ const resolvedPath = resolve51(trimmed.startsWith("~") ? trimmed.replace(/^~/, homedir37()) : trimmed);
399681
400155
  let stats;
399682
400156
  try {
399683
400157
  stats = await fs.stat(resolvedPath);
@@ -409603,9 +410077,9 @@ var init_PluginSettings = __esm(() => {
409603
410077
  // src/tui/commands/plugin/plugin.tsx
409604
410078
  var exports_plugin = {};
409605
410079
  __export(exports_plugin, {
409606
- call: () => call42
410080
+ call: () => call43
409607
410081
  });
409608
- async function call42(onDone, _context, args) {
410082
+ async function call43(onDone, _context, args) {
409609
410083
  return /* @__PURE__ */ jsx_dev_runtime294.jsxDEV(PluginSettings, {
409610
410084
  onComplete: onDone,
409611
410085
  args
@@ -409634,12 +410108,12 @@ var init_plugin3 = __esm(() => {
409634
410108
  // src/tui/commands/reload-plugins/reload-plugins.ts
409635
410109
  var exports_reload_plugins = {};
409636
410110
  __export(exports_reload_plugins, {
409637
- call: () => call43
410111
+ call: () => call44
409638
410112
  });
409639
410113
  function n2(count, noun) {
409640
410114
  return `${count} ${plural2(count, noun)}`;
409641
410115
  }
409642
- var call43 = async (_args, context) => {
410116
+ var call44 = async (_args, context) => {
409643
410117
  const r = await refreshActivePlugins(context.setAppState);
409644
410118
  const parts = [
409645
410119
  n2(r.enabled_count, "plugin"),
@@ -409677,9 +410151,9 @@ var init_reload_plugins2 = __esm(() => {
409677
410151
  // src/tui/commands/rewind/rewind.ts
409678
410152
  var exports_rewind = {};
409679
410153
  __export(exports_rewind, {
409680
- call: () => call44
410154
+ call: () => call45
409681
410155
  });
409682
- async function call44(_args, context) {
410156
+ async function call45(_args, context) {
409683
410157
  if (context.openMessageSelector) {
409684
410158
  context.openMessageSelector();
409685
410159
  }
@@ -409852,9 +410326,9 @@ var init_heapDumpService = __esm(() => {
409852
410326
  // src/tui/commands/heapdump/heapdump.ts
409853
410327
  var exports_heapdump = {};
409854
410328
  __export(exports_heapdump, {
409855
- call: () => call45
410329
+ call: () => call46
409856
410330
  });
409857
- async function call45() {
410331
+ async function call46() {
409858
410332
  const result = await performHeapDump();
409859
410333
  if (!result.success) {
409860
410334
  return {
@@ -409887,7 +410361,7 @@ var init_heapdump2 = __esm(() => {
409887
410361
  });
409888
410362
 
409889
410363
  // src/tui/commands/version.ts
409890
- var call46 = async () => {
410364
+ var call47 = async () => {
409891
410365
  return {
409892
410366
  type: "text",
409893
410367
  value: MACRO.BUILD_TIME ? `${MACRO.VERSION} (built ${MACRO.BUILD_TIME})` : MACRO.VERSION
@@ -409900,7 +410374,7 @@ var init_version = __esm(() => {
409900
410374
  description: "Print the version this session is running (not what autoupdate downloaded)",
409901
410375
  isEnabled: () => true,
409902
410376
  supportsNonInteractive: true,
409903
- load: () => Promise.resolve({ call: call46 })
410377
+ load: () => Promise.resolve({ call: call47 })
409904
410378
  };
409905
410379
  version_default = version2;
409906
410380
  });
@@ -411006,10 +411480,10 @@ var init_SandboxSettings = __esm(() => {
411006
411480
  // src/tui/commands/sandbox-toggle/sandbox-toggle.tsx
411007
411481
  var exports_sandbox_toggle = {};
411008
411482
  __export(exports_sandbox_toggle, {
411009
- call: () => call47
411483
+ call: () => call48
411010
411484
  });
411011
411485
  import { relative as relative28 } from "path";
411012
- async function call47(onDone, _context, args) {
411486
+ async function call48(onDone, _context, args) {
411013
411487
  const settings = getSettings_DEPRECATED();
411014
411488
  const themeName = settings.theme || "light";
411015
411489
  const platform = getPlatform3();
@@ -411116,9 +411590,9 @@ var init_sandbox_toggle2 = __esm(() => {
411116
411590
  // src/tui/commands/stickers/stickers.ts
411117
411591
  var exports_stickers = {};
411118
411592
  __export(exports_stickers, {
411119
- call: () => call48
411593
+ call: () => call49
411120
411594
  });
411121
- async function call48() {
411595
+ async function call49() {
411122
411596
  const url = "https://www.stickermule.com/claudecode";
411123
411597
  const success = await openBrowser(url);
411124
411598
  if (success) {
@@ -411652,13 +412126,13 @@ var init_concurrentSessions2 = __esm(() => {
411652
412126
  // src/tui/commands/exit/exit.tsx
411653
412127
  var exports_exit = {};
411654
412128
  __export(exports_exit, {
411655
- call: () => call49
412129
+ call: () => call50
411656
412130
  });
411657
412131
  import { spawnSync as spawnSync5 } from "child_process";
411658
412132
  function getRandomGoodbyeMessage2() {
411659
412133
  return sample_default(GOODBYE_MESSAGES2) ?? "Goodbye!";
411660
412134
  }
411661
- async function call49(onDone) {
412135
+ async function call50(onDone) {
411662
412136
  if (feature("BG_SESSIONS") && isBgSession2()) {
411663
412137
  onDone();
411664
412138
  spawnSync5("tmux", ["detach-client"], {
@@ -411957,7 +412431,7 @@ var init_exportRenderer = __esm(() => {
411957
412431
  // src/tui/commands/export/export.tsx
411958
412432
  var exports_export = {};
411959
412433
  __export(exports_export, {
411960
- call: () => call50,
412434
+ call: () => call51,
411961
412435
  extractFirstPrompt: () => extractFirstPrompt2,
411962
412436
  sanitizeFilename: () => sanitizeFilename
411963
412437
  });
@@ -412000,7 +412474,7 @@ async function exportWithReactRenderer(context) {
412000
412474
  const tools = context.options.tools || [];
412001
412475
  return renderMessagesToPlainText(context.messages, tools);
412002
412476
  }
412003
- async function call50(onDone, context, args) {
412477
+ async function call51(onDone, context, args) {
412004
412478
  const content = await exportWithReactRenderer(context);
412005
412479
  const filename = args.trim();
412006
412480
  if (filename) {
@@ -412065,7 +412539,7 @@ function shouldInferenceConfigCommandBeImmediate() {
412065
412539
  // src/tui/commands/model/model.tsx
412066
412540
  var exports_model = {};
412067
412541
  __export(exports_model, {
412068
- call: () => call51
412542
+ call: () => call52
412069
412543
  });
412070
412544
  function ModelPickerWrapper(t0) {
412071
412545
  const $ = import_compiler_runtime237.c(17);
@@ -412241,7 +412715,7 @@ function renderModelLabel(model) {
412241
412715
  const rendered = renderDefaultModelSetting(model ?? getDefaultMainLoopModelSetting());
412242
412716
  return model === null ? `${rendered} (default)` : rendered;
412243
412717
  }
412244
- var import_compiler_runtime237, React90, jsx_dev_runtime306, call51 = async (onDone, _context, args) => {
412718
+ var import_compiler_runtime237, React90, jsx_dev_runtime306, call52 = async (onDone, _context, args) => {
412245
412719
  args = args?.trim() || "";
412246
412720
  if (COMMON_INFO_ARGS.includes(args)) {
412247
412721
  return /* @__PURE__ */ jsx_dev_runtime306.jsxDEV(ShowModelAndClose, {
@@ -412300,7 +412774,7 @@ var init_model3 = __esm(() => {
412300
412774
  // src/tui/commands/tag/tag.tsx
412301
412775
  var exports_tag = {};
412302
412776
  __export(exports_tag, {
412303
- call: () => call52
412777
+ call: () => call53
412304
412778
  });
412305
412779
  function ConfirmRemoveTag(t0) {
412306
412780
  const $ = import_compiler_runtime238.c(11);
@@ -412518,7 +412992,7 @@ Examples:
412518
412992
  React91.useEffect(t1, t2);
412519
412993
  return null;
412520
412994
  }
412521
- async function call52(onDone, _context, args) {
412995
+ async function call53(onDone, _context, args) {
412522
412996
  args = args?.trim() || "";
412523
412997
  if (COMMON_INFO_ARGS.includes(args) || COMMON_HELP_ARGS.includes(args)) {
412524
412998
  return /* @__PURE__ */ jsx_dev_runtime307.jsxDEV(ShowHelp, {
@@ -412590,7 +413064,7 @@ var init_sessionlist = __esm(() => {
412590
413064
  // src/tui/commands/effort/effort.tsx
412591
413065
  var exports_effort = {};
412592
413066
  __export(exports_effort, {
412593
- call: () => call53,
413067
+ call: () => call54,
412594
413068
  executeEffort: () => executeEffort,
412595
413069
  showCurrentEffort: () => showCurrentEffort
412596
413070
  });
@@ -412739,7 +413213,7 @@ function ApplyEffortAndClose(t0) {
412739
413213
  React92.useEffect(t1, t2);
412740
413214
  return null;
412741
413215
  }
412742
- async function call53(onDone, _context, args) {
413216
+ async function call54(onDone, _context, args) {
412743
413217
  args = args?.trim() || "";
412744
413218
  if (COMMON_HELP_ARGS2.includes(args)) {
412745
413219
  onDone(`Usage: /effort [low|medium|high|xhigh|max|auto]
@@ -415763,9 +416237,9 @@ var init_Stats = __esm(() => {
415763
416237
  // src/tui/commands/stats/stats.tsx
415764
416238
  var exports_stats = {};
415765
416239
  __export(exports_stats, {
415766
- call: () => call54
416240
+ call: () => call55
415767
416241
  });
415768
- var jsx_dev_runtime310, call54 = async (onDone) => {
416242
+ var jsx_dev_runtime310, call55 = async (onDone) => {
415769
416243
  return /* @__PURE__ */ jsx_dev_runtime310.jsxDEV(Stats2, {
415770
416244
  onClose: onDone
415771
416245
  }, undefined, false, undefined, this);
@@ -416517,9 +416991,9 @@ var init_useVoice = __esm(() => {
416517
416991
  // src/tui/commands/voice/voice.ts
416518
416992
  var exports_voice3 = {};
416519
416993
  __export(exports_voice3, {
416520
- call: () => call55
416994
+ call: () => call56
416521
416995
  });
416522
- var LANG_HINT_MAX_SHOWS = 2, call55 = async () => {
416996
+ var LANG_HINT_MAX_SHOWS = 2, call56 = async () => {
416523
416997
  if (!isVoiceModeEnabled()) {
416524
416998
  return {
416525
416999
  type: "text",
@@ -418856,6 +419330,7 @@ var init_commands5 = __esm(() => {
418856
419330
  init_feedback2();
418857
419331
  init_clear2();
418858
419332
  init_color3();
419333
+ init_tui2();
418859
419334
  init_commit();
418860
419335
  init_copy2();
418861
419336
  init_commit_push_pr();
@@ -418989,6 +419464,7 @@ var init_commands5 = __esm(() => {
418989
419464
  stickers_default,
418990
419465
  tag_default,
418991
419466
  theme_default,
419467
+ tui_default,
418992
419468
  feedback_default,
418993
419469
  review_default,
418994
419470
  rewind_default,
@@ -421707,7 +422183,7 @@ var init_sessionStorage = __esm(() => {
421707
422183
  // src/tui/utils/plans.ts
421708
422184
  import { randomUUID as randomUUID40 } from "crypto";
421709
422185
  import { copyFile as copyFile9, writeFile as writeFile47 } from "fs/promises";
421710
- import { join as join160, resolve as resolve51, sep as sep34 } from "path";
422186
+ import { join as join160, resolve as resolve53, sep as sep34 } from "path";
421711
422187
  function getPlanSlug2(sessionId) {
421712
422188
  const id = sessionId ?? getSessionId();
421713
422189
  const cache = getPlanSlugCache();
@@ -421917,7 +422393,7 @@ var init_plans = __esm(() => {
421917
422393
  let plansPath;
421918
422394
  if (settingsDir) {
421919
422395
  const cwd = getCwd();
421920
- const resolved = resolve51(cwd, settingsDir);
422396
+ const resolved = resolve53(cwd, settingsDir);
421921
422397
  if (!resolved.startsWith(cwd + sep34) && resolved !== cwd) {
421922
422398
  logError3(new Error(`plansDirectory must be within project root: ${settingsDir}`));
421923
422399
  plansPath = join160(getAtlasConfigHomeDir3(), "plans");
@@ -421939,7 +422415,7 @@ var init_plans = __esm(() => {
421939
422415
  // src/tui/utils/permissions/filesystem.ts
421940
422416
  import { randomBytes as randomBytes21 } from "crypto";
421941
422417
  import { homedir as homedir38, tmpdir as tmpdir11 } from "os";
421942
- import { join as join161, normalize as normalize15, posix as posix9, sep as sep35 } from "path";
422418
+ import { join as join161, normalize as normalize15, posix as posix9, resolve as resolve54, sep as sep35 } from "path";
421943
422419
  function normalizeCaseForComparison2(path) {
421944
422420
  return path.toLowerCase();
421945
422421
  }
@@ -422155,11 +422631,38 @@ function checkPathSafetyForAutoEdit2(path, precomputedPathsToCheck) {
422155
422631
  }
422156
422632
  return { safe: true };
422157
422633
  }
422634
+ function isActiveWorktreeCwd2(cwd) {
422635
+ const cached = worktreeCwdProbeCache2.get(cwd);
422636
+ if (cached !== undefined) {
422637
+ return cached;
422638
+ }
422639
+ let active = false;
422640
+ try {
422641
+ const content = getFsImplementation2().readFileSync(join161(cwd, ".git"), {
422642
+ encoding: "utf8"
422643
+ });
422644
+ const gitdirMatch = content.match(/^gitdir:\s*(.+)$/m);
422645
+ if (gitdirMatch?.[1]) {
422646
+ const gitdir = resolve54(cwd, gitdirMatch[1].trim());
422647
+ active = gitdir.lastIndexOf(sep35 + ".git" + sep35 + "worktrees" + sep35) > 0;
422648
+ }
422649
+ } catch {
422650
+ active = false;
422651
+ }
422652
+ worktreeCwdProbeCache2.set(cwd, active);
422653
+ return active;
422654
+ }
422158
422655
  function allWorkingDirectories2(context) {
422159
- return new Set([
422160
- getOriginalCwd(),
422656
+ const originalCwd = getOriginalCwd();
422657
+ const dirs = [
422658
+ originalCwd,
422161
422659
  ...context.additionalWorkingDirectories.keys()
422162
- ]);
422660
+ ];
422661
+ const cwd = getCwd();
422662
+ if (cwd !== originalCwd && isActiveWorktreeCwd2(cwd)) {
422663
+ dirs.push(cwd);
422664
+ }
422665
+ return new Set(dirs);
422163
422666
  }
422164
422667
  function pathInAllowedWorkingPath2(path, toolPermissionContext, precomputedPathsToCheck) {
422165
422668
  const pathsToCheck = precomputedPathsToCheck ?? getPathsForPermissionCheck2(path);
@@ -422782,7 +423285,7 @@ function checkReadableInternalPath2(absolutePath, input) {
422782
423285
  }
422783
423286
  return { behavior: "passthrough", message: "" };
422784
423287
  }
422785
- var import_ignore4, DANGEROUS_FILES2, DANGEROUS_DIRECTORIES2, DIR_SEP2, getAtlasTempDir2, getBundledSkillsRoot2, getResolvedWorkingDirPaths2;
423288
+ var import_ignore4, DANGEROUS_FILES2, DANGEROUS_DIRECTORIES2, DIR_SEP2, getAtlasTempDir2, getBundledSkillsRoot2, worktreeCwdProbeCache2, getResolvedWorkingDirPaths2;
422786
423289
  var init_filesystem2 = __esm(() => {
422787
423290
  init_shared();
422788
423291
  init_configDir();
@@ -422841,6 +423344,7 @@ var init_filesystem2 = __esm(() => {
422841
423344
  const nonce = randomBytes21(16).toString("hex");
422842
423345
  return join161(getAtlasTempDir2(), "bundled-skills", MACRO.VERSION, nonce);
422843
423346
  });
423347
+ worktreeCwdProbeCache2 = new Map;
422844
423348
  getResolvedWorkingDirPaths2 = memoize_default(getPathsForPermissionCheck2);
422845
423349
  });
422846
423350
 
@@ -425207,7 +425711,7 @@ var init_hooks6 = __esm(() => {
425207
425711
  hookSpecificOutput: union([
425208
425712
  object({
425209
425713
  hookEventName: literal("PreToolUse"),
425210
- permissionDecision: permissionBehaviorSchema2().optional(),
425714
+ permissionDecision: preToolUsePermissionDecisionSchema().optional(),
425211
425715
  permissionDecisionReason: string2().optional(),
425212
425716
  updatedInput: record(string2(), unknown()).optional(),
425213
425717
  additionalContext: string2().optional()
@@ -426121,11 +426625,11 @@ ${jsonStringify5({
426121
426625
  decision: '"approve" | "block" (optional)',
426122
426626
  reason: "string (optional)",
426123
426627
  systemMessage: "string (optional)",
426124
- permissionDecision: '"allow" | "deny" | "ask" (optional)',
426628
+ permissionDecision: '"allow" | "deny" | "ask" | "defer" (optional; defer = 挂起重评, TUI 车道确认等价)',
426125
426629
  hookSpecificOutput: {
426126
426630
  "for PreToolUse": {
426127
426631
  hookEventName: '"PreToolUse"',
426128
- permissionDecision: '"allow" | "deny" | "ask" (optional)',
426632
+ permissionDecision: '"allow" | "deny" | "ask" | "defer" (optional; defer = 挂起重评, TUI 车道确认等价)',
426129
426633
  permissionDecisionReason: "string (optional)",
426130
426634
  updatedInput: "object (optional) - Modified tool input to use"
426131
426635
  },
@@ -426227,8 +426731,11 @@ function processHookJSONOutput({
426227
426731
  case "ask":
426228
426732
  result.permissionBehavior = "ask";
426229
426733
  break;
426734
+ case "defer":
426735
+ result.permissionBehavior = "ask";
426736
+ break;
426230
426737
  default:
426231
- throw new Error(`Unknown hook permissionDecision type: ${json.hookSpecificOutput.permissionDecision}. Valid types are: allow, deny, ask`);
426738
+ throw new Error(`Unknown hook permissionDecision type: ${json.hookSpecificOutput.permissionDecision}. Valid types are: allow, deny, ask, defer`);
426232
426739
  }
426233
426740
  }
426234
426741
  if (result.permissionBehavior !== undefined && json.reason !== undefined) {
@@ -426255,6 +426762,9 @@ function processHookJSONOutput({
426255
426762
  case "ask":
426256
426763
  result.permissionBehavior = "ask";
426257
426764
  break;
426765
+ case "defer":
426766
+ result.permissionBehavior = "ask";
426767
+ break;
426258
426768
  }
426259
426769
  }
426260
426770
  result.hookPermissionDecisionReason = json.hookSpecificOutput.permissionDecisionReason;
@@ -469472,7 +469982,7 @@ import {
469472
469982
  rm as rm11,
469473
469983
  writeFile as writeFile49
469474
469984
  } from "fs/promises";
469475
- import { join as join173, resolve as resolve54, sep as sep41 } from "path";
469985
+ import { join as join173, resolve as resolve57, sep as sep41 } from "path";
469476
469986
  function getBuiltinSnapshotRoot() {
469477
469987
  return join173(getMarketplacesCacheDir(), "builtin-snapshots");
469478
469988
  }
@@ -469484,7 +469994,7 @@ function isBuiltinSnapshotEntry(entry) {
469484
469994
  return false;
469485
469995
  if (entry.source.source !== "directory")
469486
469996
  return false;
469487
- const root = resolve54(getBuiltinSnapshotRoot()) + sep41;
469997
+ const root = resolve57(getBuiltinSnapshotRoot()) + sep41;
469488
469998
  return entry.installLocation.startsWith(root);
469489
469999
  }
469490
470000
  async function installBuiltinSnapshotFallback(marketplaceName) {
@@ -472005,7 +472515,7 @@ var init_usePluginAutoupdateNotification = __esm(() => {
472005
472515
  });
472006
472516
 
472007
472517
  // src/tui/utils/plugins/reconciler.ts
472008
- import { isAbsolute as isAbsolute34, resolve as resolve55 } from "path";
472518
+ import { isAbsolute as isAbsolute34, resolve as resolve58 } from "path";
472009
472519
  function diffMarketplaces(declared, materialized, opts) {
472010
472520
  const missing = [];
472011
472521
  const sourceChanged = [];
@@ -472118,7 +472628,7 @@ function normalizeSource(source, projectRoot) {
472118
472628
  const canonicalRoot = findCanonicalGitRoot2(base);
472119
472629
  return {
472120
472630
  ...source,
472121
- path: resolve55(canonicalRoot ?? base, source.path)
472631
+ path: resolve58(canonicalRoot ?? base, source.path)
472122
472632
  };
472123
472633
  }
472124
472634
  return source;
@@ -476082,6 +476592,10 @@ function REPL({
476082
476592
  });
476083
476593
  }
476084
476594
  }, [autoUpdaterResult, addNotification]);
476595
+ const tuiFullscreenSeed = useAppState((s) => s.settings.tui?.fullscreen);
476596
+ import_react280.useEffect(() => {
476597
+ setFullscreenRuntimeOverride(tuiFullscreenSeed);
476598
+ }, [tuiFullscreenSeed]);
476085
476599
  import_react280.useEffect(() => {
476086
476600
  if (isFullscreenEnvEnabled()) {
476087
476601
  maybeGetTmuxMouseHint().then((hint) => {
@@ -479581,7 +480095,7 @@ class FpsTracker {
479581
480095
  }
479582
480096
 
479583
480097
  // src/tui/utils/githubRepoPathMapping.ts
479584
- import { realpath as realpath14 } from "fs/promises";
480098
+ import { realpath as realpath15 } from "fs/promises";
479585
480099
  async function updateGithubRepoPathMapping() {
479586
480100
  try {
479587
480101
  const repo = await detectCurrentRepository();
@@ -479594,7 +480108,7 @@ async function updateGithubRepoPathMapping() {
479594
480108
  const basePath = gitRoot ?? cwd;
479595
480109
  let currentPath;
479596
480110
  try {
479597
- currentPath = (await realpath14(basePath)).normalize("NFC");
480111
+ currentPath = (await realpath15(basePath)).normalize("NFC");
479598
480112
  } catch {
479599
480113
  currentPath = basePath;
479600
480114
  }
@@ -483782,6 +484296,103 @@ var init_keybindings3 = __esm(() => {
483782
484296
  `);
483783
484297
  });
483784
484298
 
484299
+ // src/tui/skills/bundled/lessPermissionPrompts.ts
484300
+ function extractToolCallFrequencies(messages) {
484301
+ const counts = new Map;
484302
+ for (const msg of messages) {
484303
+ const content = msg?.message?.content ?? msg?.content;
484304
+ if (!Array.isArray(content))
484305
+ continue;
484306
+ for (const block of content) {
484307
+ if (!block || typeof block !== "object")
484308
+ continue;
484309
+ const b = block;
484310
+ if (b.type !== "tool_use" || typeof b.name !== "string")
484311
+ continue;
484312
+ if (b.name === "Bash") {
484313
+ const command = b.input?.command;
484314
+ if (typeof command !== "string")
484315
+ continue;
484316
+ const prefix = matchReadOnlyPrefix(command);
484317
+ if (prefix === null)
484318
+ continue;
484319
+ const key = `Bash|${prefix}`;
484320
+ const entry = counts.get(key) ?? { toolName: "Bash", ruleContent: `${prefix}:*`, frequency: 0 };
484321
+ entry.frequency++;
484322
+ counts.set(key, entry);
484323
+ } else if (READONLY_BUILTIN_TOOLS.has(b.name) || b.name.startsWith("mcp__")) {
484324
+ const entry = counts.get(b.name) ?? { toolName: b.name, frequency: 0 };
484325
+ entry.frequency++;
484326
+ counts.set(b.name, entry);
484327
+ }
484328
+ }
484329
+ }
484330
+ return counts;
484331
+ }
484332
+ function buildAllowlistProposal(messages, limit = DEFAULT_LIMIT) {
484333
+ const sorted = [...extractToolCallFrequencies(messages).values()].sort((a, b) => b.frequency - a.frequency || (a.toolName + (a.ruleContent ?? "")).localeCompare(b.toolName + (b.ruleContent ?? ""))).slice(0, Math.max(1, limit));
484334
+ return sorted;
484335
+ }
484336
+ function writeAllowlistToSettings(candidates) {
484337
+ if (candidates.length === 0)
484338
+ return true;
484339
+ const ruleValues = candidates.map((c) => c.ruleContent ? { toolName: c.toolName, ruleContent: c.ruleContent } : { toolName: c.toolName });
484340
+ return addPermissionRulesToSettings2({ ruleValues, ruleBehavior: "allow" }, "userSettings");
484341
+ }
484342
+ function ruleString(c) {
484343
+ return c.ruleContent ? `${c.toolName}(${c.ruleContent})` : c.toolName;
484344
+ }
484345
+ async function runLessPermissionPrompts(args, context) {
484346
+ const parsed = args.trim() === "" ? NaN : parseInt(args.trim(), 10);
484347
+ const limit = Number.isFinite(parsed) && parsed > 0 ? parsed : DEFAULT_LIMIT;
484348
+ const candidates = buildAllowlistProposal(context?.messages ?? [], limit);
484349
+ if (candidates.length === 0) {
484350
+ return [{ type: "text", text: NO_CANDIDATES_MESSAGE }];
484351
+ }
484352
+ const written = writeAllowlistToSettings(candidates);
484353
+ const lines = candidates.map((c) => ` - \`${ruleString(c)}\` — seen ${c.frequency}× this session`);
484354
+ const head = written ? `Added ${candidates.length} allowlist rule(s) to user settings (permissions.allow):
484355
+ ${lines.join(`
484356
+ `)}
484357
+
484358
+ These read-only calls will no longer prompt. To revoke, remove the entries from \`permissions.allow\` in user settings.json.` : `Found ${candidates.length} allowlist candidate(s) but the write was rejected (managed permission rules policy is active):
484359
+ ${lines.join(`
484360
+ `)}
484361
+
484362
+ Ask your admin to add these rules, or re-run without the managed-policy override.`;
484363
+ return [
484364
+ {
484365
+ type: "text",
484366
+ text: `${head}
484367
+
484368
+ Report this summary to the user in one short message (no extra commentary).`
484369
+ }
484370
+ ];
484371
+ }
484372
+ function registerLessPermissionPromptsSkill() {
484373
+ registerBundledSkill2({
484374
+ name: "less-permission-prompts",
484375
+ description: "Scan this session for frequent read-only tool calls and add matching allowlist rules to user settings so they stop prompting.",
484376
+ whenToUse: "Use when the user is tired of repeated permission prompts for the same read-only commands/tools (git status, ls, MCP read tools, …) and wants to allowlist them in one step.",
484377
+ argumentHint: "[max-rules]",
484378
+ userInvocable: true,
484379
+ disableModelInvocation: true,
484380
+ getPromptForCommand: runLessPermissionPrompts
484381
+ });
484382
+ }
484383
+ var READONLY_BUILTIN_TOOLS, DEFAULT_LIMIT = 10, NO_CANDIDATES_MESSAGE = "No read-only tool-call patterns were found in this session transcript to allowlist. Read-only Bash calls (e.g. `git status`, `ls`) and read-only built-in/MCP tools would appear here; write-class commands are never allowlisted by this skill. Try it in a session where you were prompted for the same read-only commands repeatedly.";
484384
+ var init_lessPermissionPrompts = __esm(() => {
484385
+ init_bundledSkills2();
484386
+ init_engine();
484387
+ init_permissionsLoader();
484388
+ READONLY_BUILTIN_TOOLS = new Set([
484389
+ "Read",
484390
+ "Glob",
484391
+ "Grep",
484392
+ "NotebookRead"
484393
+ ]);
484394
+ });
484395
+
483785
484396
  // src/tui/skills/bundled/loremIpsum.ts
483786
484397
  function registerLoremIpsumSkill() {}
483787
484398
 
@@ -484837,6 +485448,7 @@ function initBundledSkills() {
484837
485448
  registerSimplifySkill();
484838
485449
  registerBatchSkill();
484839
485450
  registerStuckSkill();
485451
+ registerLessPermissionPromptsSkill();
484840
485452
  registerAscendGenerateSkill();
484841
485453
  registerAscendDebugSkill();
484842
485454
  registerAscendOptimizeSkill();
@@ -484860,6 +485472,7 @@ var init_bundled = __esm(() => {
484860
485472
  init_batch();
484861
485473
  init_debug2();
484862
485474
  init_keybindings3();
485475
+ init_lessPermissionPrompts();
484863
485476
  init_simplify();
484864
485477
  init_updateConfig();
484865
485478
  init_ascendGenerate();
@@ -487748,7 +488361,7 @@ import {
487748
488361
  dirname as dirname87,
487749
488362
  join as join184,
487750
488363
  relative as relative38,
487751
- resolve as resolve56,
488364
+ resolve as resolve59,
487752
488365
  sep as sep43
487753
488366
  } from "path";
487754
488367
  function git(marketplaceDir, args, timeoutMs = 2 * 60 * 1000) {
@@ -487761,8 +488374,8 @@ function gitFailureMessage(res) {
487761
488374
  return (res.stderr || res.error || `exit code ${res.code}`).trim();
487762
488375
  }
487763
488376
  async function publishPluginToMarketplace(opts) {
487764
- const pluginDir = resolve56(opts.pluginDir);
487765
- const marketplaceDir = resolve56(opts.marketplaceDir);
488377
+ const pluginDir = resolve59(opts.pluginDir);
488378
+ const marketplaceDir = resolve59(opts.marketplaceDir);
487766
488379
  const notes = [];
487767
488380
  if (pluginDir === marketplaceDir || pluginDir.startsWith(marketplaceDir + sep43)) {
487768
488381
  throw new Error(`Cannot publish "${pluginDir}": the plugin directory must not live inside the target marketplace (${marketplaceDir})`);
@@ -487893,9 +488506,9 @@ var init_marketplacePublish = __esm(() => {
487893
488506
  import { userInfo as userInfo2 } from "os";
487894
488507
  import { existsSync as existsSync15 } from "fs";
487895
488508
  import { mkdir as mkdir57, writeFile as writeFile54 } from "fs/promises";
487896
- import { dirname as dirname88, join as join185, resolve as resolve57 } from "path";
488509
+ import { dirname as dirname88, join as join185, resolve as resolve60 } from "path";
487897
488510
  async function scaffoldMarketplace(opts) {
487898
- const targetDir = resolve57(opts.targetDir);
488511
+ const targetDir = resolve60(opts.targetDir);
487899
488512
  const name = opts.name.trim();
487900
488513
  const manifestDirName = getPluginManifestDirs()[0];
487901
488514
  const marketplaceManifestPath = join185(targetDir, manifestDirName, "marketplace.json");
@@ -487981,7 +488594,7 @@ var init_marketplaceScaffold = __esm(() => {
487981
488594
  });
487982
488595
 
487983
488596
  // src/tui/cli/handlers/plugins.ts
487984
- import { basename as basename65, dirname as dirname89, resolve as resolve58 } from "path";
488597
+ import { basename as basename65, dirname as dirname89, resolve as resolve61 } from "path";
487985
488598
  function handleMarketplaceError(error, action) {
487986
488599
  logError3(error);
487987
488600
  cliError2(`${figures_default.cross} Failed to ${action}: ${errorMessage2(error)}`);
@@ -488333,7 +488946,7 @@ async function marketplaceUpdateHandler(name, options) {
488333
488946
  async function marketplaceScaffoldHandler(options) {
488334
488947
  if (options.cowork)
488335
488948
  setUseCoworkPlugins(true);
488336
- const targetDir = resolve58(options.target ?? process.cwd());
488949
+ const targetDir = resolve61(options.target ?? process.cwd());
488337
488950
  try {
488338
488951
  const result = await scaffoldMarketplace({
488339
488952
  name: options.name,
@@ -488358,8 +488971,8 @@ async function marketplacePublishHandler(options) {
488358
488971
  setUseCoworkPlugins(true);
488359
488972
  try {
488360
488973
  const result = await publishPluginToMarketplace({
488361
- pluginDir: resolve58(options.plugin),
488362
- marketplaceDir: resolve58(options.marketplace),
488974
+ pluginDir: resolve61(options.plugin),
488975
+ marketplaceDir: resolve61(options.marketplace),
488363
488976
  version: options.version,
488364
488977
  push: options.push
488365
488978
  });
@@ -489575,7 +490188,7 @@ var init_update2 = __esm(() => {
489575
490188
 
489576
490189
  // src/tui/main.tsx
489577
490190
  import { readFileSync as readFileSync25 } from "fs";
489578
- import { resolve as resolve59 } from "path";
490191
+ import { resolve as resolve62 } from "path";
489579
490192
  function logManagedSettings() {
489580
490193
  try {
489581
490194
  const policySettings = getSettingsForSource2("policySettings");
@@ -490142,12 +490755,12 @@ ${getTmuxInstallInstructions3()}
490142
490755
  process.exit(1);
490143
490756
  }
490144
490757
  try {
490145
- const filePath = resolve59(options.systemPromptFile);
490758
+ const filePath = resolve62(options.systemPromptFile);
490146
490759
  systemPrompt = readFileSync25(filePath, "utf8");
490147
490760
  } catch (error) {
490148
490761
  const code = getErrnoCode2(error);
490149
490762
  if (code === "ENOENT") {
490150
- process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve59(options.systemPromptFile)}
490763
+ process.stderr.write(source_default.red(`Error: System prompt file not found: ${resolve62(options.systemPromptFile)}
490151
490764
  `));
490152
490765
  process.exit(1);
490153
490766
  }
@@ -490164,12 +490777,12 @@ ${getTmuxInstallInstructions3()}
490164
490777
  process.exit(1);
490165
490778
  }
490166
490779
  try {
490167
- const filePath = resolve59(options.appendSystemPromptFile);
490780
+ const filePath = resolve62(options.appendSystemPromptFile);
490168
490781
  appendSystemPrompt = readFileSync25(filePath, "utf8");
490169
490782
  } catch (error) {
490170
490783
  const code = getErrnoCode2(error);
490171
490784
  if (code === "ENOENT") {
490172
- process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve59(options.appendSystemPromptFile)}
490785
+ process.stderr.write(source_default.red(`Error: Append system prompt file not found: ${resolve62(options.appendSystemPromptFile)}
490173
490786
  `));
490174
490787
  process.exit(1);
490175
490788
  }
@@ -490219,7 +490832,7 @@ ${addendum}` : addendum;
490219
490832
  errors = result.errors;
490220
490833
  }
490221
490834
  } else {
490222
- const configPath = resolve59(configItem);
490835
+ const configPath = resolve62(configItem);
490223
490836
  const result = parseMcpConfigFromFilePath({
490224
490837
  filePath: configPath,
490225
490838
  expandVars: true,