@cydm/pie 2.6.10 → 2.6.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  createAskUserCapability
4
- } from "../../../chunks/chunk-DFWWHVJL.js";
4
+ } from "../../../chunks/chunk-ZVM234WE.js";
5
5
  import "../../../chunks/chunk-PAC62XU4.js";
6
6
  import "../../../chunks/chunk-7B4IIBVS.js";
7
7
  import "../../../chunks/chunk-XXGYUYXI.js";
@@ -7,7 +7,7 @@ import {
7
7
  isPlanModeSafeCommand,
8
8
  markCompletedPlanSteps,
9
9
  restoreExecutionState
10
- } from "../../../chunks/chunk-DFWWHVJL.js";
10
+ } from "../../../chunks/chunk-ZVM234WE.js";
11
11
  import "../../../chunks/chunk-PAC62XU4.js";
12
12
  import "../../../chunks/chunk-7B4IIBVS.js";
13
13
  import {
@@ -1,12 +1,12 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  createCliHostCapabilities
4
- } from "../../../chunks/chunk-YUVGEY6X.js";
4
+ } from "../../../chunks/chunk-MA4CHFN4.js";
5
5
  import {
6
6
  SUBAGENT_SESSION_RECORD_VERSION,
7
7
  createSharedFileSystemTools,
8
8
  createSubagentCapability
9
- } from "../../../chunks/chunk-DFWWHVJL.js";
9
+ } from "../../../chunks/chunk-ZVM234WE.js";
10
10
  import "../../../chunks/chunk-PAC62XU4.js";
11
11
  import "../../../chunks/chunk-7B4IIBVS.js";
12
12
  import "../../../chunks/chunk-5353DEEC.js";
@@ -8,7 +8,7 @@ import {
8
8
  executeManageTodoList,
9
9
  executionStateToTodos,
10
10
  restoreExecutionState
11
- } from "../../../chunks/chunk-DFWWHVJL.js";
11
+ } from "../../../chunks/chunk-ZVM234WE.js";
12
12
  import "../../../chunks/chunk-PAC62XU4.js";
13
13
  import "../../../chunks/chunk-7B4IIBVS.js";
14
14
  import "../../../chunks/chunk-XXGYUYXI.js";
@@ -8,7 +8,7 @@ import {
8
8
  createSharedWebSearchTool,
9
9
  interpretShellExit,
10
10
  requestInteraction
11
- } from "./chunk-DFWWHVJL.js";
11
+ } from "./chunk-ZVM234WE.js";
12
12
  import {
13
13
  getBuiltinDir,
14
14
  getConfigDir
@@ -491,6 +491,21 @@ function createBashTool(defaultCwd, options) {
491
491
  sandboxRoot: defaultCwd ?? workingDir
492
492
  });
493
493
  if (risk.destructive && !options?.isYoloMode?.()) {
494
+ onUpdate?.({
495
+ content: [{
496
+ type: "text",
497
+ text: `\u23F8 Awaiting user confirmation (${risk.commandClass}): ${risk.riskWarnings.join("; ")}`
498
+ }],
499
+ details: {
500
+ exitCode: null,
501
+ signal: null,
502
+ timedOut: false,
503
+ shell: resolvedShell,
504
+ commandClass: risk.commandClass,
505
+ riskWarnings: risk.riskWarnings,
506
+ pendingConfirmation: true
507
+ }
508
+ });
494
509
  const approved = await (options?.confirm ?? requestHighRiskConfirmation)({
495
510
  command: effectiveCommand,
496
511
  shell: resolvedShell,
@@ -519,6 +534,18 @@ function createBashTool(defaultCwd, options) {
519
534
  isError: true
520
535
  };
521
536
  }
537
+ onUpdate?.({
538
+ content: [{ type: "text", text: "\u2713 Confirmed by user \u2014 running" }],
539
+ details: {
540
+ exitCode: null,
541
+ signal: null,
542
+ timedOut: false,
543
+ shell: resolvedShell,
544
+ commandClass: risk.commandClass,
545
+ riskWarnings: risk.riskWarnings,
546
+ pendingConfirmation: false
547
+ }
548
+ });
522
549
  }
523
550
  const timeoutPolicy = resolveTimeoutPolicy(timeout, risk.commandClass);
524
551
  const timeoutMs = timeoutPolicy.effectiveSeconds * 1e3;
@@ -1215,7 +1215,10 @@ var DESTRUCTIVE_PATTERNS = [
1215
1215
  { pattern: /\bgit\s+stash[ \t]+(drop|clear)\b/, warning: "may permanently remove stashed changes", commandClass: "git_destructive" },
1216
1216
  { pattern: /\bgit\s+branch\s+(-D[ \t]|--delete\s+--force|--force\s+--delete)\b/, warning: "may force-delete a branch", commandClass: "git_destructive" },
1217
1217
  { pattern: /\bgit\s+(commit|push|merge)\b[^;&|\n]*--no-verify\b/, warning: "may skip safety hooks", commandClass: "git_destructive" },
1218
- { pattern: /(^|[;&|\n]\s*)rm\s+-[a-zA-Z]*[rR][a-zA-Z]*f|(^|[;&|\n]\s*)rm\s+-[a-zA-Z]*f[a-zA-Z]*[rR]/, warning: "may recursively force-remove files", commandClass: "filesystem_write" },
1218
+ // `rm -rf` is NOT in this regex list: raw-text matching both missed split
1219
+ // flags (`rm -r -f`) and false-positived on quoted literals mentioning
1220
+ // `rm -rf` (grep patterns, echo, docs). It is detected semantically by
1221
+ // containsRecursiveForceRemove in classifyShellCommand instead.
1219
1222
  { pattern: /\bsudo\b|\bsu\s+-|\bchmod\s+777\b|\bchown\s+-R\b/, warning: "may require elevated privileges or weaken permissions", commandClass: "privilege_escalation" },
1220
1223
  { pattern: /\b(DROP|TRUNCATE)\s+(TABLE|DATABASE|SCHEMA)\b/i, warning: "may drop or truncate database objects", commandClass: "infra_destructive" },
1221
1224
  { pattern: /\bDELETE\s+FROM\s+\w+[ \t]*(;|"|'|\n|$)/i, warning: "may delete all rows from a database table", commandClass: "infra_destructive" },
@@ -1223,6 +1226,9 @@ var DESTRUCTIVE_PATTERNS = [
1223
1226
  { pattern: /\bterraform\s+destroy\b/, warning: "may destroy Terraform infrastructure", commandClass: "infra_destructive" }
1224
1227
  ];
1225
1228
  var RM_FORCE_RECURSIVE_WARNING = "may recursively force-remove files";
1229
+ var RM_RECURSIVE_WARNING = "may recursively remove files";
1230
+ var FIND_DELETE_WARNING = "may recursively delete matched files";
1231
+ var RSYNC_DELETE_WARNING = "may delete extraneous destination files";
1226
1232
  var SHELL_DYNAMIC_TOKEN = /[$`*?[\]{}~]/;
1227
1233
  var PROTECTED_POSIX_PATHS = /* @__PURE__ */ new Set([
1228
1234
  "/",
@@ -1276,7 +1282,45 @@ function classifyBashCommand(command, options) {
1276
1282
  return classifyShellCommand(command, "bash", options);
1277
1283
  }
1278
1284
  function splitShellSegments(command) {
1279
- return command.split(/&&|\|\||[;&|\n]/).map((part) => part.trim()).filter(Boolean);
1285
+ const segments = [];
1286
+ let current = "";
1287
+ let quote;
1288
+ for (let index = 0; index < command.length; index += 1) {
1289
+ const char = command[index];
1290
+ if (quote) {
1291
+ if (quote === '"' && char === "\\" && index + 1 < command.length) {
1292
+ current += char;
1293
+ current += command[index + 1];
1294
+ index += 1;
1295
+ continue;
1296
+ }
1297
+ current += char;
1298
+ if (char === quote) quote = void 0;
1299
+ continue;
1300
+ }
1301
+ if (char === "'" || char === '"') {
1302
+ quote = char;
1303
+ current += char;
1304
+ continue;
1305
+ }
1306
+ if (char === "\\" && index + 1 < command.length) {
1307
+ current += char;
1308
+ current += command[index + 1];
1309
+ index += 1;
1310
+ continue;
1311
+ }
1312
+ if (char === "&" || char === "|" || char === ";" || char === "\n") {
1313
+ if ((char === "&" || char === "|") && command[index + 1] === char) {
1314
+ index += 1;
1315
+ }
1316
+ segments.push(current);
1317
+ current = "";
1318
+ continue;
1319
+ }
1320
+ current += char;
1321
+ }
1322
+ segments.push(current);
1323
+ return segments.map((part) => part.trim()).filter(Boolean);
1280
1324
  }
1281
1325
  function splitShellWords(segment) {
1282
1326
  const words = [];
@@ -1348,7 +1392,7 @@ function isProtectedPosixPath(target) {
1348
1392
  function isStaticPathToken(token) {
1349
1393
  return Boolean(token) && !token.startsWith("-") && !token.includes("\0") && !SHELL_DYNAMIC_TOKEN.test(token);
1350
1394
  }
1351
- function parseRmForceRecursiveTargets(words) {
1395
+ function scanRmInvocation(words) {
1352
1396
  const executable = words[0] ?? "";
1353
1397
  if (executable !== "rm" && !executable.endsWith("/rm")) return void 0;
1354
1398
  let recursive = false;
@@ -1361,9 +1405,8 @@ function parseRmForceRecursiveTargets(words) {
1361
1405
  continue;
1362
1406
  }
1363
1407
  if (!endOfOptions && word.startsWith("--")) {
1364
- if (word === "--recursive" || word === "--dir") recursive = true;
1408
+ if (word === "--recursive") recursive = true;
1365
1409
  else if (word === "--force") force = true;
1366
- else return void 0;
1367
1410
  continue;
1368
1411
  }
1369
1412
  if (!endOfOptions && /^-[A-Za-z]+$/.test(word)) {
@@ -1373,7 +1416,37 @@ function parseRmForceRecursiveTargets(words) {
1373
1416
  }
1374
1417
  targets.push(word);
1375
1418
  }
1376
- return recursive && force && targets.length > 0 ? targets : void 0;
1419
+ return { recursive, force, targets };
1420
+ }
1421
+ var COMMAND_POSITION_RM_RECURSIVE_PATTERN = /^rm\s+-[a-zA-Z]*[rR]/;
1422
+ function recursiveRemoveWarnings(command) {
1423
+ const found = [];
1424
+ const warnings = [];
1425
+ for (const segment of splitShellSegments(command)) {
1426
+ const words = splitShellWords(segment);
1427
+ if (words) {
1428
+ const scan = scanRmInvocation(words);
1429
+ if (scan?.recursive) found.push({ scan });
1430
+ const xargsArgs = words[0] === "xargs" || words[0]?.endsWith("/xargs") ? words.slice(1) : void 0;
1431
+ const xargsScan = xargsArgs ? scanRmInvocation(xargsArgs) : void 0;
1432
+ if (xargsScan?.recursive) found.push({ scan: xargsScan });
1433
+ const executable = words[0] ?? "";
1434
+ if ((executable === "find" || executable.endsWith("/find")) && words.slice(1).some((word) => word === "-delete")) {
1435
+ warnings.push(FIND_DELETE_WARNING);
1436
+ }
1437
+ if ((executable === "rsync" || executable.endsWith("/rsync")) && words.slice(1).some((word) => word === "--delete" || word.startsWith("--delete-"))) {
1438
+ warnings.push(RSYNC_DELETE_WARNING);
1439
+ }
1440
+ continue;
1441
+ }
1442
+ if (COMMAND_POSITION_RM_RECURSIVE_PATTERN.test(segment)) {
1443
+ warnings.push(RM_RECURSIVE_WARNING);
1444
+ }
1445
+ }
1446
+ for (const { scan } of found) {
1447
+ warnings.push(scan.force ? RM_FORCE_RECURSIVE_WARNING : RM_RECURSIVE_WARNING);
1448
+ }
1449
+ return warnings;
1377
1450
  }
1378
1451
  function resolveStaticScopedTarget(target, cwd, root) {
1379
1452
  if (!isStaticPathToken(target)) return void 0;
@@ -1406,10 +1479,10 @@ function isStaticallyScopedRecursiveForceRemove(command, options) {
1406
1479
  currentCwd = next;
1407
1480
  continue;
1408
1481
  }
1409
- const targets = parseRmForceRecursiveTargets(words);
1410
- if (!targets) continue;
1482
+ const scan = scanRmInvocation(words);
1483
+ if (!scan?.recursive || scan.targets.length === 0) continue;
1411
1484
  sawRm = true;
1412
- if (!targets.every((target) => resolveStaticScopedTarget(target, currentCwd, normalizedRoot))) {
1485
+ if (!scan.targets.every((target) => resolveStaticScopedTarget(target, currentCwd, normalizedRoot))) {
1413
1486
  return false;
1414
1487
  }
1415
1488
  }
@@ -1420,12 +1493,18 @@ function classifyShellCommand(command, shell = "bash", options) {
1420
1493
  let commandClass = "unknown_shell";
1421
1494
  let destructive = false;
1422
1495
  const destructivePatterns = shell === "powershell" ? [...POWERSHELL_DESTRUCTIVE_PATTERNS, ...DESTRUCTIVE_PATTERNS] : shell === "cmd" ? [...CMD_DESTRUCTIVE_PATTERNS, ...DESTRUCTIVE_PATTERNS] : DESTRUCTIVE_PATTERNS;
1496
+ const removeWarnings = recursiveRemoveWarnings(command);
1497
+ if (removeWarnings.length > 0) {
1498
+ if (shell === "bash" && isStaticallyScopedRecursiveForceRemove(command, options)) {
1499
+ commandClass = "filesystem_write";
1500
+ } else {
1501
+ warnings.push(...removeWarnings);
1502
+ commandClass = "filesystem_write";
1503
+ destructive = true;
1504
+ }
1505
+ }
1423
1506
  for (const entry of destructivePatterns) {
1424
1507
  if (entry.pattern.test(command)) {
1425
- if (shell === "bash" && entry.commandClass === "filesystem_write" && entry.warning === RM_FORCE_RECURSIVE_WARNING && isStaticallyScopedRecursiveForceRemove(command, options)) {
1426
- commandClass = "filesystem_write";
1427
- continue;
1428
- }
1429
1508
  warnings.push(entry.warning);
1430
1509
  commandClass = entry.commandClass;
1431
1510
  destructive = true;
package/dist/cli.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  createCliWebResearchHealthStore,
8
8
  formatSize,
9
9
  truncateHeadTail
10
- } from "./chunks/chunk-YUVGEY6X.js";
10
+ } from "./chunks/chunk-MA4CHFN4.js";
11
11
  import {
12
12
  AGENTS_CONTEXT_FILE_NAME,
13
13
  AgentSessionController,
@@ -63,7 +63,7 @@ import {
63
63
  setExtensionEnabledInSettings,
64
64
  shouldPreserveExecutionStateForUserText,
65
65
  supersedeExecutionState
66
- } from "./chunks/chunk-DFWWHVJL.js";
66
+ } from "./chunks/chunk-ZVM234WE.js";
67
67
  import "./chunks/chunk-PAC62XU4.js";
68
68
  import {
69
69
  Deref,
@@ -63980,7 +63980,24 @@ var ProcessTerminal = class {
63980
63980
  process.stdout.write(sequence);
63981
63981
  }
63982
63982
  }
63983
+ /** Bounce the dock icon once (iTerm2's OSC 1337 extension; verified live
63984
+ * on iTerm2 — its docs list "Post a notification"-adjacent attention as
63985
+ * OSC 1337 ; RequestAttention). WezTerm documents OSC 1337 only for file
63986
+ * upload, not attention; other terminals ignore unknown OSC per the
63987
+ * xterm spec, so emitting unconditionally is safe and future-proof.
63988
+ * Value 1 bounces exactly once; 2 would bounce until the user activates
63989
+ * the app, which is too pushy for a per-turn attention signal. No
63990
+ * Notification Center permission is involved, so this works even when
63991
+ * the host app's notifications are muted — the banner channel's
63992
+ * fallback for "I just need a dot". */
63993
+ requestAttention() {
63994
+ if (!process.stdout.isTTY) return;
63995
+ process.stdout.write(buildDockAttentionSequence());
63996
+ }
63983
63997
  };
63998
+ function buildDockAttentionSequence() {
63999
+ return "\x1B]1337;RequestAttention=1\x07";
64000
+ }
63984
64001
  var NOTIFICATION_UNSAFE_CHARS = /[\x00-\x1f\x7f-\x9f;]/g;
63985
64002
  function sanitizeNotificationText(text) {
63986
64003
  return text.replace(NOTIFICATION_UNSAFE_CHARS, "");
@@ -78658,6 +78675,22 @@ function showStatus(host, message) {
78658
78675
  host.lastStatusText = text;
78659
78676
  host.ui.requestRender();
78660
78677
  }
78678
+ function clearStatusLine(host) {
78679
+ const spacer = host.lastStatusSpacer;
78680
+ const text = host.lastStatusText;
78681
+ host.lastStatusSpacer = void 0;
78682
+ host.lastStatusText = void 0;
78683
+ let removed = false;
78684
+ if (spacer && host.chatContainer.children.includes(spacer)) {
78685
+ host.chatContainer.removeChild(spacer);
78686
+ removed = true;
78687
+ }
78688
+ if (text && host.chatContainer.children.includes(text)) {
78689
+ host.chatContainer.removeChild(text);
78690
+ removed = true;
78691
+ }
78692
+ if (removed) host.ui.requestRender();
78693
+ }
78661
78694
  function showError(host, errorMessage4) {
78662
78695
  host.chatContainer.addChild(new Spacer(1));
78663
78696
  host.chatContainer.addChild(new Text(theme.fg("error", `Error: ${errorMessage4}`), 1, 0));
@@ -79382,6 +79415,7 @@ function sendDesktopNotification(reason, options = {}) {
79382
79415
  lastNotificationAtMs = atMs;
79383
79416
  const { title, body } = attentionMessage(reason);
79384
79417
  terminal.notify(title, body);
79418
+ terminal.requestAttention?.();
79385
79419
  return true;
79386
79420
  }
79387
79421
 
@@ -79567,13 +79601,17 @@ function installInteractiveInteractionHandler(host) {
79567
79601
  host.footer.setState({ lifecycleEvent: "\u25B6 resuming" });
79568
79602
  host.safeRequestRender();
79569
79603
  };
79570
- const withTimeout2 = async (promise) => {
79604
+ const withTimeout2 = async (createPromise) => {
79605
+ const controller = new AbortController();
79571
79606
  if (!("timeoutMs" in request) || !request.timeoutMs || request.timeoutMs <= 0) {
79572
- return { value: await promise, timedOut: false };
79607
+ return { value: await createPromise(controller.signal), timedOut: false };
79573
79608
  }
79574
79609
  return await new Promise((resolve7, reject) => {
79575
- const timer = setTimeout(() => resolve7({ timedOut: true }), request.timeoutMs);
79576
- promise.then((value) => {
79610
+ const timer = setTimeout(() => {
79611
+ controller.abort();
79612
+ resolve7({ timedOut: true });
79613
+ }, request.timeoutMs);
79614
+ createPromise(controller.signal).then((value) => {
79577
79615
  clearTimeout(timer);
79578
79616
  resolve7({ value, timedOut: false });
79579
79617
  }).catch((error) => {
@@ -79586,7 +79624,7 @@ function installInteractiveInteractionHandler(host) {
79586
79624
  beginWaitingForUser();
79587
79625
  let resolution = "cancelled";
79588
79626
  try {
79589
- const result = await withTimeout2(createPromise());
79627
+ const result = await withTimeout2(createPromise);
79590
79628
  resolution = interactionAttentionResolution(result);
79591
79629
  return result;
79592
79630
  } finally {
@@ -79609,7 +79647,8 @@ function installInteractiveInteractionHandler(host) {
79609
79647
  optionCount: request.options.length
79610
79648
  });
79611
79649
  const { value: selection, timedOut } = await waitForUser(
79612
- () => showExtensionSelector2(host, request.prompt, request.options, {
79650
+ (signal) => showExtensionSelector2(host, request.prompt, request.options, {
79651
+ signal,
79613
79652
  shortcuts: { left: request.leftShortcut, right: request.rightShortcut }
79614
79653
  })
79615
79654
  );
@@ -79628,7 +79667,7 @@ function installInteractiveInteractionHandler(host) {
79628
79667
  detail: request.detail
79629
79668
  });
79630
79669
  const { value: confirmed, timedOut } = await waitForUser(
79631
- () => showExtensionConfirm(host, request.prompt, request.detail ?? "")
79670
+ (signal) => showExtensionConfirm(host, request.prompt, request.detail ?? "", { signal })
79632
79671
  );
79633
79672
  host.logDebug("interaction:confirm:end", {
79634
79673
  id: request.id,
@@ -79644,7 +79683,7 @@ function installInteractiveInteractionHandler(host) {
79644
79683
  placeholder: request.placeholder
79645
79684
  });
79646
79685
  const { value, timedOut } = await waitForUser(
79647
- () => showExtensionInput(host, request.prompt, request.placeholder)
79686
+ (signal) => showExtensionInput(host, request.prompt, request.placeholder, { signal })
79648
79687
  );
79649
79688
  host.logDebug("interaction:text_input:end", {
79650
79689
  id: request.id,
@@ -79661,7 +79700,7 @@ function installInteractiveInteractionHandler(host) {
79661
79700
  prefillLength: request.prefill?.length ?? 0
79662
79701
  });
79663
79702
  const { value, timedOut } = await waitForUser(
79664
- () => showExtensionEditor(host, request.prompt, request.prefill)
79703
+ (signal) => showExtensionEditor(host, request.prompt, request.prefill, { signal })
79665
79704
  );
79666
79705
  host.logDebug("interaction:multiline_input:end", {
79667
79706
  id: request.id,
@@ -79682,12 +79721,24 @@ function showExtensionNotification(host, message, type = "info") {
79682
79721
  }
79683
79722
  function showExtensionSelector2(host, title, options, opts) {
79684
79723
  return new Promise((resolve7) => {
79685
- host.showStatus(`Waiting for selection: ${title}`);
79724
+ const promptLine = title.split("\n")[0].trim() || title.trim();
79725
+ host.showStatus(`Waiting for selection: ${promptLine}`);
79686
79726
  if (opts?.signal?.aborted) {
79727
+ host.clearStatusLine?.();
79687
79728
  resolve7(void 0);
79688
79729
  return;
79689
79730
  }
79731
+ const settle = (option) => {
79732
+ if (option === void 0) {
79733
+ host.clearStatusLine?.();
79734
+ } else {
79735
+ host.showStatus(`${promptLine} \u2192 ${option}`);
79736
+ }
79737
+ host.restoreEditor();
79738
+ resolve7(option);
79739
+ };
79690
79740
  const onAbort = () => {
79741
+ host.clearStatusLine?.();
79691
79742
  host.restoreEditor();
79692
79743
  resolve7(void 0);
79693
79744
  };
@@ -79697,13 +79748,11 @@ function showExtensionSelector2(host, title, options, opts) {
79697
79748
  options,
79698
79749
  (option) => {
79699
79750
  opts?.signal?.removeEventListener("abort", onAbort);
79700
- host.restoreEditor();
79701
- resolve7(option);
79751
+ settle(option);
79702
79752
  },
79703
79753
  () => {
79704
79754
  opts?.signal?.removeEventListener("abort", onAbort);
79705
- host.restoreEditor();
79706
- resolve7(void 0);
79755
+ settle(void 0);
79707
79756
  },
79708
79757
  opts?.shortcuts
79709
79758
  );
@@ -79723,26 +79772,27 @@ function showExtensionInput(host, title, placeholder, opts) {
79723
79772
  return new Promise((resolve7) => {
79724
79773
  host.showStatus(`Waiting for input: ${title}`);
79725
79774
  if (opts?.signal?.aborted) {
79775
+ host.clearStatusLine?.();
79726
79776
  resolve7(void 0);
79727
79777
  return;
79728
79778
  }
79729
- const onAbort = () => {
79779
+ const settle = (value) => {
79780
+ host.clearStatusLine?.();
79730
79781
  host.restoreEditor();
79731
- resolve7(void 0);
79782
+ resolve7(value);
79732
79783
  };
79784
+ const onAbort = () => settle(void 0);
79733
79785
  opts?.signal?.addEventListener("abort", onAbort, { once: true });
79734
79786
  const input = new ExtensionInputComponent(
79735
79787
  title,
79736
79788
  placeholder,
79737
79789
  (value) => {
79738
79790
  opts?.signal?.removeEventListener("abort", onAbort);
79739
- host.restoreEditor();
79740
- resolve7(value);
79791
+ settle(value);
79741
79792
  },
79742
79793
  () => {
79743
79794
  opts?.signal?.removeEventListener("abort", onAbort);
79744
- host.restoreEditor();
79745
- resolve7(void 0);
79795
+ settle(void 0);
79746
79796
  }
79747
79797
  );
79748
79798
  host.editorContainer.clear();
@@ -79752,9 +79802,20 @@ function showExtensionInput(host, title, placeholder, opts) {
79752
79802
  host.ui.requestRender();
79753
79803
  });
79754
79804
  }
79755
- function showExtensionEditor(host, title, prefill) {
79805
+ function showExtensionEditor(host, title, prefill, opts) {
79756
79806
  return new Promise((resolve7) => {
79757
79807
  host.showStatus(`Waiting for input: ${title}`);
79808
+ const settle = (value) => {
79809
+ host.clearStatusLine?.();
79810
+ host.restoreEditor();
79811
+ resolve7(value);
79812
+ };
79813
+ const onAbort = () => settle(void 0);
79814
+ opts?.signal?.addEventListener("abort", onAbort, { once: true });
79815
+ if (opts?.signal?.aborted) {
79816
+ onAbort();
79817
+ return;
79818
+ }
79758
79819
  const container = new Container();
79759
79820
  container.addChild(new Text(theme.bold(theme.fg("accent", title)), 0, 0));
79760
79821
  container.addChild(new Spacer(1));
@@ -79774,13 +79835,13 @@ function showExtensionEditor(host, title, prefill) {
79774
79835
  valueLength: value.length,
79775
79836
  preview: value.slice(0, 120)
79776
79837
  });
79777
- host.restoreEditor();
79778
- resolve7(value);
79838
+ opts?.signal?.removeEventListener("abort", onAbort);
79839
+ settle(value);
79779
79840
  };
79780
79841
  editor.onEscape = () => {
79781
79842
  host.logDebug("extension:editor:cancel", { title });
79782
- host.restoreEditor();
79783
- resolve7(void 0);
79843
+ opts?.signal?.removeEventListener("abort", onAbort);
79844
+ settle(void 0);
79784
79845
  };
79785
79846
  container.addChild(editor);
79786
79847
  container.addChild(new Spacer(1));
@@ -80909,6 +80970,9 @@ var InteractiveMode = class {
80909
80970
  showStatus(message) {
80910
80971
  return showStatus(this.uiHelperHost, message);
80911
80972
  }
80973
+ clearStatusLine() {
80974
+ return clearStatusLine(this.uiHelperHost);
80975
+ }
80912
80976
  showError(errorMessage4) {
80913
80977
  return showError(this.uiHelperHost, errorMessage4);
80914
80978
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "2.6.10",
3
+ "version": "2.6.11",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -19,7 +19,7 @@
19
19
  "pretest:offline": "npm run build --workspace @pie/agent-framework && npm run build --workspace @pie/shared-headless-capabilities && npm run build && npm run test:skill-regressions",
20
20
  "test:skill-regressions": "node --test --import tsx test/bash-lifecycle.test.ts test/skill-creator-runner.test.ts test/tui-use-contract.test.ts test/tui-use-runtime.test.ts test/browser-runtime.test.ts test/axi-stop-semantics.test.ts test/computer-evidence.test.ts test/interactive-lifecycle.test.ts",
21
21
  "posttest:offline": "node --test --import tsx test/remote-model-catalog.test.ts",
22
- "test:offline": "node --test --test-concurrency=4 --import tsx test/cli-attention.test.ts test/builtin-extensions.test.ts test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-provider.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/auto-compaction-ui.test.ts test/hierarchical-command-system.test.ts test/mcp-adapter.test.ts test/herdr-agent-state.test.ts test/extensions-enablement.test.ts test/extension-selector-shortcuts.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/subagent-session-store.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/tree-selector-pagination.test.ts test/session-control.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/plan-mode-extension.test.ts test/rendered-page-reader.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/bash-yolo.test.ts test/bash-process-group.test.ts test/bash-artifact-sink.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/ctrl-d-exit.test.ts test/session-display-title.test.ts test/calm-mode.test.ts test/stream-render-throttle.test.ts test/message-display-resync.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts test/cli-args.test.ts test/extensions-configured-paths.test.ts test/extensions-loader-path.test.ts test/file-picker.test.ts test/interrupt-recovery.test.ts test/mention-insert-regression.test.ts test/mention-picker-navigation.test.ts test/pie-unity-rpc-skill.test.ts test/skill-creator-scripts.test.ts",
22
+ "test:offline": "node --test --test-concurrency=4 --import tsx test/cli-attention.test.ts test/builtin-extensions.test.ts test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-provider.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/auto-compaction-ui.test.ts test/hierarchical-command-system.test.ts test/mcp-adapter.test.ts test/herdr-agent-state.test.ts test/extensions-enablement.test.ts test/extension-selector-shortcuts.test.ts test/skill-tool-enablement.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/subagent-session-store.test.ts test/runtime-mode-context.test.ts test/tool-policy.test.ts test/retry-policy.test.ts test/yolo-command.test.ts test/footer-lifecycle.test.ts test/files-utils.test.ts test/source-size-guard.test.ts test/runtime-logger.test.ts test/release-readiness.test.ts test/package-artifacts.test.ts test/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/skills-agents-discovery.test.ts test/skills-symlink.test.ts test/model-overrides.test.ts test/auth-storage.test.ts test/extension-register-provider.test.ts test/extension-reload.test.ts test/extension-terminal-input.test.ts test/extension-session-before-events.test.ts test/extension-widgets.test.ts test/extension-render-hint.test.ts test/extension-oauth-restore.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/session-selector.test.ts test/tree-selector-pagination.test.ts test/session-control.test.ts test/terminal-title.test.ts test/interactive-controller-title.test.ts test/todo-title.terminal.test.ts test/plan-mode-extension.test.ts test/rendered-page-reader.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/bash-yolo.test.ts test/bash-confirm-pending.test.ts test/interaction-status-lifecycle.test.ts test/bash-process-group.test.ts test/bash-artifact-sink.test.ts test/direct-bash.test.ts test/terminal-bell.test.ts test/ctrl-d-exit.test.ts test/session-display-title.test.ts test/calm-mode.test.ts test/stream-render-throttle.test.ts test/message-display-resync.test.ts test/project-root.test.ts test/guard-advisory-context.test.ts test/clear-command-usage.test.ts test/daily-agent-smoke.terminal.test.ts test/slash-menu-toggles.terminal.test.ts test/cli-args.test.ts test/extensions-configured-paths.test.ts test/extensions-loader-path.test.ts test/file-picker.test.ts test/interrupt-recovery.test.ts test/mention-insert-regression.test.ts test/mention-picker-navigation.test.ts test/pie-unity-rpc-skill.test.ts test/skill-creator-scripts.test.ts",
23
23
  "test:all": "npm run test:offline && npm run test:terminal:vitest",
24
24
  "test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/footer-plan-mode.test.ts test/viewport-position-final.test.ts test/resume-header.terminal.test.ts --no-file-parallelism",
25
25
  "test:todo-tui": "node ../../scripts/run-with-env.mjs PIE_REAL_TODO_TUI=1 -- --test --import tsx test/todo-closure.terminal.test.ts",