@integrity-labs/agt-cli 0.27.74 → 0.27.76

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/bin/agt.js CHANGED
@@ -28,7 +28,7 @@ import {
28
28
  success,
29
29
  table,
30
30
  warn
31
- } from "../chunk-CADO5HXF.js";
31
+ } from "../chunk-NANSSDFG.js";
32
32
  import {
33
33
  CHANNEL_REGISTRY,
34
34
  DEPLOYMENT_TEMPLATES,
@@ -4930,7 +4930,7 @@ import { execFileSync, execSync } from "child_process";
4930
4930
  import { existsSync as existsSync10, realpathSync as realpathSync2 } from "fs";
4931
4931
  import chalk18 from "chalk";
4932
4932
  import ora16 from "ora";
4933
- var cliVersion = true ? "0.27.74" : "dev";
4933
+ var cliVersion = true ? "0.27.76" : "dev";
4934
4934
  async function fetchLatestVersion() {
4935
4935
  const host2 = getHost();
4936
4936
  if (!host2) return null;
@@ -5853,7 +5853,7 @@ function handleError(err) {
5853
5853
  }
5854
5854
 
5855
5855
  // src/bin/agt.ts
5856
- var cliVersion2 = true ? "0.27.74" : "dev";
5856
+ var cliVersion2 = true ? "0.27.76" : "dev";
5857
5857
  var program = new Command();
5858
5858
  program.name("agt").description("Augmented CLI \u2014 agent provisioning and management").version(cliVersion2).option("--json", "Emit machine-readable JSON output (suppress spinners and colors)").option("--skip-update-check", "Skip the automatic update check on startup");
5859
5859
  program.hook("preAction", async (thisCommand, actionCommand) => {
@@ -7,7 +7,7 @@ import {
7
7
  } from "./chunk-XWVM4KPK.js";
8
8
 
9
9
  // src/lib/persistent-session.ts
10
- import { spawn, execSync, execFileSync as execFileSync2 } from "child_process";
10
+ import { spawn, execSync, execFileSync as execFileSync3 } from "child_process";
11
11
  import { join as join2, dirname } from "path";
12
12
  import { homedir as homedir2, platform, userInfo } from "os";
13
13
  import { existsSync as existsSync3, readFileSync as readFileSync4, readdirSync, writeFileSync as writeFileSync3, appendFileSync, mkdirSync as mkdirSync2, chmodSync, copyFileSync, rmSync } from "fs";
@@ -279,6 +279,226 @@ function probeClaudeProcessInTmux(tmuxSession) {
279
279
  }
280
280
  }
281
281
 
282
+ // src/lib/claude-dialogs.ts
283
+ import { execFileSync as execFileSync2 } from "child_process";
284
+ function isLoginPickerVisible(screen) {
285
+ return screen.includes("Select login method") || screen.includes("Claude account with subscription") && screen.includes("Anthropic Console account");
286
+ }
287
+ function isResumeModeDialogVisible(screen) {
288
+ return screen.includes("Resume from summary") && screen.includes("Don't ask me again");
289
+ }
290
+ function isSessionFeedbackDialogVisible(screen) {
291
+ return screen.includes("How is Claude doing this session") && screen.includes("0: Dismiss");
292
+ }
293
+ function sweepDialogs(screen) {
294
+ if (screen.includes("Choose the text style") || screen.includes("Dark mode") && screen.includes("Light mode")) {
295
+ return {
296
+ kind: "theme-picker",
297
+ keys: ["Enter"],
298
+ interKeyDelayMs: 0,
299
+ logMessage: "Auto-accepted theme picker"
300
+ };
301
+ }
302
+ if (screen.includes("Yes, I trust this folder")) {
303
+ return {
304
+ kind: "folder-trust",
305
+ keys: ["Enter"],
306
+ interKeyDelayMs: 0,
307
+ logMessage: "Auto-accepted folder trust"
308
+ };
309
+ }
310
+ if (isResumeModeDialogVisible(screen)) {
311
+ return {
312
+ kind: "resume-mode",
313
+ keys: ["3", "Enter"],
314
+ interKeyDelayMs: 300,
315
+ logMessage: "Auto-dismissed resume-mode dialog (picked 'Don't ask me again')"
316
+ };
317
+ }
318
+ if (screen.includes("I am using this for local development")) {
319
+ return {
320
+ kind: "dev-channels",
321
+ keys: ["Enter"],
322
+ interKeyDelayMs: 0,
323
+ logMessage: "Auto-accepted dev channels"
324
+ };
325
+ }
326
+ if (screen.includes("Enter to confirm") && screen.includes("MCP")) {
327
+ return {
328
+ kind: "mcp-servers",
329
+ keys: ["Enter"],
330
+ interKeyDelayMs: 0,
331
+ logMessage: "Auto-accepted MCP servers"
332
+ };
333
+ }
334
+ if (screen.includes("Yes, I accept") && screen.includes("Bypass Permissions")) {
335
+ return {
336
+ kind: "bypass-permissions",
337
+ keys: ["2", "Enter"],
338
+ interKeyDelayMs: 300,
339
+ logMessage: "Auto-accepted bypass permissions"
340
+ };
341
+ }
342
+ if (isSessionFeedbackDialogVisible(screen)) {
343
+ return {
344
+ kind: "session-feedback",
345
+ keys: ["0"],
346
+ interKeyDelayMs: 0,
347
+ logMessage: "Auto-dismissed session-feedback dialog"
348
+ };
349
+ }
350
+ return null;
351
+ }
352
+ async function sendDialogKeys(tmuxSession, action) {
353
+ for (let i = 0; i < action.keys.length; i++) {
354
+ if (i > 0 && action.interKeyDelayMs > 0) {
355
+ await new Promise((r) => setTimeout(r, action.interKeyDelayMs));
356
+ }
357
+ execFileSync2("tmux", ["send-keys", "-t", tmuxSession, action.keys[i]], {
358
+ stdio: "ignore"
359
+ });
360
+ }
361
+ }
362
+ function simpleTextHash(s) {
363
+ let h = 0;
364
+ for (let i = 0; i < s.length; i++) {
365
+ h = (h << 5) - h + s.charCodeAt(i) | 0;
366
+ }
367
+ return h.toString(16);
368
+ }
369
+
370
+ // src/lib/channel-input-watchdog.ts
371
+ var STUCK_THRESHOLD_MS = 5e3;
372
+ var MAX_ENTER_FIRES = 3;
373
+ var ATTACHED_STUCK_THRESHOLD_MS = 15e3;
374
+ var INPUT_BOX_DIVIDER = /^[─━]{10,}/;
375
+ var PROMPT_PREFIX = "\u276F ";
376
+ function decide(pane, prev, now, config = {}) {
377
+ const threshold = config.stuckThresholdMs ?? STUCK_THRESHOLD_MS;
378
+ const maxFires = config.maxEnterFires ?? MAX_ENTER_FIRES;
379
+ const dialogAction = sweepDialogs(pane);
380
+ if (dialogAction) {
381
+ return { fire: false, dialog: dialogAction, next: prev };
382
+ }
383
+ const inputText = extractInputBoxText(pane);
384
+ if (!inputText) {
385
+ return { fire: false, next: void 0 };
386
+ }
387
+ if (isActivelyProcessing(pane)) {
388
+ return { fire: false, next: prev };
389
+ }
390
+ const hash = simpleTextHash(inputText);
391
+ if (!prev || prev.lastInputHash !== hash) {
392
+ return {
393
+ fire: false,
394
+ next: { lastInputHash: hash, firstSeenAt: now, fires: 0, lastFireAt: 0, gaveUpLogged: false }
395
+ };
396
+ }
397
+ if (prev.fires >= maxFires) {
398
+ if (!prev.gaveUpLogged) {
399
+ return { fire: false, gaveUp: true, next: { ...prev, gaveUpLogged: true } };
400
+ }
401
+ return { fire: false, next: prev };
402
+ }
403
+ const sinceLastAttempt = prev.fires === 0 ? now - prev.firstSeenAt : now - prev.lastFireAt;
404
+ if (sinceLastAttempt < threshold) return { fire: false, next: prev };
405
+ return {
406
+ fire: true,
407
+ next: { ...prev, fires: prev.fires + 1, lastFireAt: now }
408
+ };
409
+ }
410
+ function extractInputBoxText(pane) {
411
+ const lines = pane.split("\n");
412
+ for (let i = 1; i < lines.length; i++) {
413
+ const line = lines[i] ?? "";
414
+ if (!line.startsWith(PROMPT_PREFIX)) continue;
415
+ let j = i - 1;
416
+ while (j >= 0 && (lines[j] ?? "").trim() === "") j--;
417
+ if (j < 0) continue;
418
+ if (!INPUT_BOX_DIVIDER.test((lines[j] ?? "").trim())) continue;
419
+ const text = line.slice(PROMPT_PREFIX.length).trim();
420
+ return text.length > 0 ? text : null;
421
+ }
422
+ return null;
423
+ }
424
+ function isActivelyProcessing(pane) {
425
+ const lines = pane.split("\n");
426
+ for (let i = lines.length - 1; i >= 0; i--) {
427
+ const line = (lines[i] ?? "").trim();
428
+ if (!line.startsWith("\u273B")) continue;
429
+ if (/\bfor\s+\d+s\s*$/.test(line)) return false;
430
+ if (/\b\w+ing[…\.]{0,3}\s*$/i.test(line)) return true;
431
+ return false;
432
+ }
433
+ return false;
434
+ }
435
+ function checkChannelInputs(codeNames, io, config = {}, states = sharedStates) {
436
+ const live = new Set(codeNames);
437
+ for (const codeName of codeNames) {
438
+ try {
439
+ checkOne(codeName, io, config, states);
440
+ } catch (err) {
441
+ io.log(`[channel-input-watchdog] '${codeName}': ${err.message}`);
442
+ }
443
+ }
444
+ for (const key of [...states.keys()]) {
445
+ if (!live.has(key)) states.delete(key);
446
+ }
447
+ for (const key of [...giveUpCounts.keys()]) {
448
+ if (!live.has(key)) giveUpCounts.delete(key);
449
+ }
450
+ }
451
+ function checkOne(codeName, io, config, states) {
452
+ const pane = io.capturePane(codeName);
453
+ if (!pane) {
454
+ states.delete(codeName);
455
+ return;
456
+ }
457
+ const attached = io.isClientAttached(codeName);
458
+ const effectiveConfig = attached ? {
459
+ ...config,
460
+ stuckThresholdMs: config.attachedStuckThresholdMs ?? ATTACHED_STUCK_THRESHOLD_MS
461
+ } : config;
462
+ const prev = states.get(codeName);
463
+ const { fire, dialog, gaveUp, next } = decide(pane, prev, io.now(), effectiveConfig);
464
+ if (next === void 0) {
465
+ states.delete(codeName);
466
+ } else {
467
+ states.set(codeName, next);
468
+ }
469
+ if (dialog) {
470
+ io.log(
471
+ `[channel-input-watchdog] '${codeName}': ${dialog.logMessage} (dialog was blocking the input box)`
472
+ );
473
+ io.sendKeys(codeName, dialog.keys, dialog.interKeyDelayMs);
474
+ return;
475
+ }
476
+ const text = extractInputBoxText(pane) ?? "";
477
+ const hash = next?.lastInputHash ?? simpleTextHash(text);
478
+ if (gaveUp) {
479
+ const maxFires = effectiveConfig.maxEnterFires ?? MAX_ENTER_FIRES;
480
+ io.log(
481
+ `[channel-input-watchdog] '${codeName}': GIVING UP after ${maxFires} Enter attempts \u2014 input remains unsubmitted (input_hash=${hash}, len=${text.length})`
482
+ );
483
+ giveUpCounts.set(codeName, (giveUpCounts.get(codeName) ?? 0) + 1);
484
+ return;
485
+ }
486
+ if (fire) {
487
+ const maxFires = effectiveConfig.maxEnterFires ?? MAX_ENTER_FIRES;
488
+ io.log(
489
+ `[channel-input-watchdog] '${codeName}': stuck channel input \u2014 firing Enter (attempt ${next?.fires ?? 1}/${maxFires}, input_hash=${hash}, len=${text.length})`
490
+ );
491
+ io.sendEnter(codeName);
492
+ }
493
+ }
494
+ var sharedStates = /* @__PURE__ */ new Map();
495
+ var giveUpCounts = /* @__PURE__ */ new Map();
496
+ function takeWatchdogGiveUpCount(codeName) {
497
+ const count = giveUpCounts.get(codeName) ?? 0;
498
+ giveUpCounts.delete(codeName);
499
+ return count;
500
+ }
501
+
282
502
  // src/lib/persistent-session.ts
283
503
  function syncClaudeCredsToRoot() {
284
504
  if (platform() !== "linux") return true;
@@ -405,7 +625,7 @@ function getAcpxBin() {
405
625
  }
406
626
  function defaultAcpxSessionProbe(acpxBin, projectDir) {
407
627
  try {
408
- execFileSync2(acpxBin, ["claude", "list-sessions"], {
628
+ execFileSync3(acpxBin, ["claude", "list-sessions"], {
409
629
  cwd: projectDir,
410
630
  timeout: 5e3,
411
631
  stdio: "ignore"
@@ -655,12 +875,6 @@ function spawnSession(config, session) {
655
875
  session.restartCount++;
656
876
  }
657
877
  }
658
- function isLoginPickerVisible(screen) {
659
- return screen.includes("Select login method") || screen.includes("Claude account with subscription") && screen.includes("Anthropic Console account");
660
- }
661
- function isResumeModeDialogVisible(screen) {
662
- return screen.includes("Resume from summary") && screen.includes("Don't ask me again");
663
- }
664
878
  function hasMcpChildren(tmuxSession) {
665
879
  try {
666
880
  const claudePidOut = execSync(
@@ -710,40 +924,10 @@ async function acceptDialogs(tmuxSession, codeName, log, primaryModel = null, se
710
924
  continue;
711
925
  }
712
926
  dialogIterations++;
713
- if (screen.includes("Choose the text style") || screen.includes("Dark mode") && screen.includes("Light mode")) {
714
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
715
- log(`[persistent-session] Auto-accepted theme picker for '${codeName}'`);
716
- continue;
717
- }
718
- if (screen.includes("Yes, I trust this folder")) {
719
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
720
- log(`[persistent-session] Auto-accepted workspace trust for '${codeName}'`);
721
- continue;
722
- }
723
- if (isResumeModeDialogVisible(screen)) {
724
- execFileSync2("tmux", ["send-keys", "-t", tmuxSession, "3"], { stdio: "ignore" });
725
- await new Promise((r) => setTimeout(r, 300));
726
- execFileSync2("tmux", ["send-keys", "-t", tmuxSession, "Enter"], { stdio: "ignore" });
727
- log(
728
- `[persistent-session] Auto-dismissed resume-mode dialog for '${codeName}' (picked 'Don't ask me again')`
729
- );
730
- continue;
731
- }
732
- if (screen.includes("I am using this for local development")) {
733
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
734
- log(`[persistent-session] Auto-accepted dev channels for '${codeName}'`);
735
- continue;
736
- }
737
- if (screen.includes("Enter to confirm") && screen.includes("MCP")) {
738
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
739
- log(`[persistent-session] Auto-accepted MCP servers for '${codeName}'`);
740
- continue;
741
- }
742
- if (screen.includes("Yes, I accept") && screen.includes("Bypass Permissions")) {
743
- execSync(`tmux send-keys -t ${tmuxSession} 2`, { stdio: "ignore" });
744
- await new Promise((r) => setTimeout(r, 300));
745
- execSync(`tmux send-keys -t ${tmuxSession} Enter`, { stdio: "ignore" });
746
- log(`[persistent-session] Auto-accepted bypass permissions for '${codeName}'`);
927
+ const dialogAction = sweepDialogs(screen);
928
+ if (dialogAction) {
929
+ await sendDialogKeys(tmuxSession, dialogAction);
930
+ log(`[persistent-session] ${dialogAction.logMessage} for '${codeName}'`);
747
931
  continue;
748
932
  }
749
933
  if (screen.includes("\u276F") && !screen.includes("Enter to confirm")) {
@@ -794,7 +978,7 @@ async function waitForPromptReady(tmuxSession) {
794
978
  const deadline = Date.now() + 1e4;
795
979
  while (Date.now() < deadline) {
796
980
  try {
797
- const screen = execFileSync2(
981
+ const screen = execFileSync3(
798
982
  "tmux",
799
983
  ["capture-pane", "-t", tmuxSession, "-p"],
800
984
  { encoding: "utf-8", stdio: ["ignore", "pipe", "ignore"] }
@@ -813,11 +997,11 @@ function sleepBlockingMs(ms) {
813
997
  }
814
998
  function defaultArmSender(tmuxSession, command) {
815
999
  try {
816
- execFileSync2("tmux", ["send-keys", "-t", tmuxSession, "-l", command], {
1000
+ execFileSync3("tmux", ["send-keys", "-t", tmuxSession, "-l", command], {
817
1001
  stdio: ["ignore", "ignore", "pipe"]
818
1002
  });
819
1003
  sleepBlockingMs(SEND_KEYS_ENTER_DELAY_MS);
820
- execFileSync2("tmux", ["send-keys", "-t", tmuxSession, "Enter"], {
1004
+ execFileSync3("tmux", ["send-keys", "-t", tmuxSession, "Enter"], {
821
1005
  stdio: ["ignore", "ignore", "pipe"]
822
1006
  });
823
1007
  return true;
@@ -826,6 +1010,50 @@ function defaultArmSender(tmuxSession, command) {
826
1010
  }
827
1011
  }
828
1012
  var armSender = defaultArmSender;
1013
+ function defaultPaneCapture(tmuxSession) {
1014
+ try {
1015
+ return execFileSync3("tmux", ["capture-pane", "-t", tmuxSession, "-p"], {
1016
+ encoding: "utf-8",
1017
+ stdio: ["ignore", "pipe", "ignore"],
1018
+ timeout: 2e3
1019
+ });
1020
+ } catch {
1021
+ return null;
1022
+ }
1023
+ }
1024
+ var paneCapture = defaultPaneCapture;
1025
+ var defaultHygieneKeySender = async (tmuxSession, keys, interKeyDelayMs) => {
1026
+ for (let i = 0; i < keys.length; i++) {
1027
+ if (i > 0 && interKeyDelayMs > 0) {
1028
+ await new Promise((r) => setTimeout(r, interKeyDelayMs));
1029
+ }
1030
+ execFileSync3("tmux", ["send-keys", "-t", tmuxSession, keys[i]], {
1031
+ stdio: "ignore"
1032
+ });
1033
+ }
1034
+ };
1035
+ var hygieneKeySender = defaultHygieneKeySender;
1036
+ async function preSendPaneHygiene(tmuxSession, codeName, log) {
1037
+ try {
1038
+ let screen = paneCapture(tmuxSession);
1039
+ if (screen === null) return;
1040
+ const action = sweepDialogs(screen);
1041
+ if (action) {
1042
+ await hygieneKeySender(tmuxSession, action.keys, action.interKeyDelayMs);
1043
+ log(`[inject] ${action.logMessage} for '${codeName}' before injection`);
1044
+ await new Promise((r) => setTimeout(r, 300));
1045
+ screen = paneCapture(tmuxSession) ?? "";
1046
+ }
1047
+ const orphan = extractInputBoxText(screen);
1048
+ if (orphan) {
1049
+ log(
1050
+ `[inject] clearing orphaned input for '${codeName}' before injection (input_hash=${simpleTextHash(orphan)}, len=${orphan.length})`
1051
+ );
1052
+ await hygieneKeySender(tmuxSession, ["C-u"], 0);
1053
+ }
1054
+ } catch {
1055
+ }
1056
+ }
829
1057
  function sendToAgent(tmuxSession, command) {
830
1058
  return armSender(tmuxSession, command);
831
1059
  }
@@ -848,6 +1076,17 @@ var _internals = {
848
1076
  __setArmSender(fn) {
849
1077
  armSender = fn ?? defaultArmSender;
850
1078
  },
1079
+ // ENG-6017 test seam: swap the pane capture used by the inject-time
1080
+ // hygiene so unit tests can simulate dialog overlays / orphaned input
1081
+ // without a tmux server. null restores the real capture.
1082
+ __setPaneCapture(fn) {
1083
+ paneCapture = fn ?? defaultPaneCapture;
1084
+ },
1085
+ // ENG-6017 test seam: swap the hygiene key sender (dialog dismissal +
1086
+ // C-u clear) so unit tests can assert keystrokes without tmux.
1087
+ __setHygieneKeySender(fn) {
1088
+ hygieneKeySender = fn ?? defaultHygieneKeySender;
1089
+ },
851
1090
  // ENG-5758 test seam: swap the acpx session probe so unit tests can
852
1091
  // simulate "session present" / "no session" without spawning acpx.
853
1092
  __setAcpxSessionProbe(fn) {
@@ -922,6 +1161,7 @@ async function injectMessageWithStatus(codeName, type, content, meta, log) {
922
1161
  _log(`[inject] acpx binary not found \u2014 falling back to tmux send-keys`);
923
1162
  }
924
1163
  const singleLineText = text.replace(/\s*\n+\s*/g, " ").trim();
1164
+ await preSendPaneHygiene(`agt-${codeName}`, codeName, _log);
925
1165
  const sent = sendToAgent(`agt-${codeName}`, singleLineText);
926
1166
  if (sent) {
927
1167
  _log(`[inject] tmux send-keys sent for '${codeName}' \u2014 unverified (delivered=false, fallbackUsed=true)`);
@@ -942,7 +1182,7 @@ function stopPersistentSession(codeName, log) {
942
1182
  try {
943
1183
  const acpx = getAcpxBin();
944
1184
  if (acpx) {
945
- execFileSync2(acpx, ["claude", "sessions", "close", `agt-${codeName}`], {
1185
+ execFileSync3(acpx, ["claude", "sessions", "close", `agt-${codeName}`], {
946
1186
  cwd: getProjectDir(codeName),
947
1187
  timeout: 5e3,
948
1188
  stdio: "ignore"
@@ -1019,7 +1259,7 @@ function isSessionHealthy(codeName) {
1019
1259
  if (!claudeAlive) {
1020
1260
  const paneTail = readPaneLogTail(codeName);
1021
1261
  try {
1022
- execFileSync2("tmux", ["kill-session", "-t", tmuxSession], { stdio: "ignore" });
1262
+ execFileSync3("tmux", ["kill-session", "-t", tmuxSession], { stdio: "ignore" });
1023
1263
  } catch {
1024
1264
  }
1025
1265
  session.status = "crashed";
@@ -1059,13 +1299,13 @@ function collectDiagnostics(codeNames) {
1059
1299
  let launchArgs = null;
1060
1300
  let channelStatus = null;
1061
1301
  try {
1062
- execFileSync2("tmux", ["has-session", "-t", tmuxSession], { stdio: "ignore" });
1302
+ execFileSync3("tmux", ["has-session", "-t", tmuxSession], { stdio: "ignore" });
1063
1303
  tmuxAlive = true;
1064
1304
  } catch {
1065
1305
  }
1066
1306
  if (tmuxAlive) {
1067
1307
  try {
1068
- screenCapture = execFileSync2("tmux", ["capture-pane", "-t", tmuxSession, "-p", "-S", "-30"], {
1308
+ screenCapture = execFileSync3("tmux", ["capture-pane", "-t", tmuxSession, "-p", "-S", "-30"], {
1069
1309
  encoding: "utf-8",
1070
1310
  timeout: 3e3
1071
1311
  }).trim();
@@ -1073,7 +1313,7 @@ function collectDiagnostics(codeNames) {
1073
1313
  }
1074
1314
  }
1075
1315
  try {
1076
- const psOutput = execFileSync2("ps", ["aux"], { encoding: "utf-8", timeout: 3e3 });
1316
+ const psOutput = execFileSync3("ps", ["aux"], { encoding: "utf-8", timeout: 3e3 });
1077
1317
  const line = psOutput.split("\n").find((l) => l.includes(`agt-${codeName}`) && !l.includes("grep"));
1078
1318
  if (line) {
1079
1319
  const match = line.match(/claude\s+.*/);
@@ -1187,6 +1427,8 @@ export {
1187
1427
  isAgentIdle,
1188
1428
  isStaleForToday,
1189
1429
  peekCurrentSession,
1430
+ checkChannelInputs,
1431
+ takeWatchdogGiveUpCount,
1190
1432
  resolveClaudeBinary,
1191
1433
  writePersistentClaudeWrapper,
1192
1434
  paneLogPath,
@@ -1210,4 +1452,4 @@ export {
1210
1452
  stopAllSessionsAndWait,
1211
1453
  getProjectDir
1212
1454
  };
1213
- //# sourceMappingURL=chunk-7YM2F3DG.js.map
1455
+ //# sourceMappingURL=chunk-FAR2FJBQ.js.map