@cydm/pie 2.7.10 → 2.7.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.
package/README.md CHANGED
@@ -240,7 +240,7 @@ Pie uses a hierarchical slash-command menu. The current built-in commands includ
240
240
  | `pie extensions list/enable/disable` | Inspect and toggle extensions non-interactively |
241
241
  | `/sessions/compact` | Summarize history and create a compact checkpoint |
242
242
  | `/sessions/new` | Start a new session |
243
- | `/sessions/resume` | Resume a different session |
243
+ | `/sessions/resume` | Resume a session (defaults to current-directory sessions; press `g` in the selector to show the full loaded recent list) |
244
244
  | `/sessions/tree` | Navigate the session tree |
245
245
  | `/sessions/info` | Show session information |
246
246
  | `/sessions/fork` | Fork from an earlier message |
@@ -363,7 +363,7 @@ Pie exposes one default model-visible web tool: `web_research`. Use it for publi
363
363
 
364
364
  ## Permissions
365
365
 
366
- Pie's default tools operate from the current workspace. File tools are workspace-scoped, `~/.pie` is allowlisted for Pie configuration/session support, and shell commands return structured timeout/truncation/error details. The canonical shell tool is still named `bash` for compatibility; on Windows `shell:auto` uses PowerShell, and callers can explicitly request `bash`, `powershell`, or `cmd`. High-risk shell commands require confirmation outside YOLO mode. `/settings/yolo` relaxes filesystem sandbox directory restrictions and should only be used in trusted workspaces. `pie permissions` prints the current policy-derived safety summary.
366
+ Pie's default tools operate from the current workspace. File tools are workspace-scoped, `~/.pie` is allowlisted for Pie configuration/session support, and shell commands return structured timeout/truncation/error details. The canonical shell tool is still named `bash` for compatibility; on Windows `shell:auto` uses PowerShell, and callers can explicitly request `bash`, `powershell`, or `cmd`. High-risk shell commands require confirmation outside YOLO mode; the confirmation dialog also offers a time-boxed `Yolo (5 min)` option that suppresses further high-risk prompts for five minutes without enabling full YOLO mode. `/settings/yolo` relaxes filesystem sandbox directory restrictions and should only be used in trusted workspaces. `pie permissions` prints the current policy-derived safety summary.
367
367
 
368
368
  In interactive Plan mode (`/tools/plan`), workspace editing tools are unavailable. The `bash` guard accepts simple read commands and read-only pipelines such as `rg 'TODO' . | head -20`; it blocks redirects, command substitution, and write-capable subcommands. Use `plan_scratch` to write, read, or list temporary text drafts in a directory dedicated to the current session. Shell redirection to `/tmp` remains blocked in Plan mode. When the plan is ready, the agent submits the ordered steps with `plan_submit` and you choose to execute immediately (progress is tracked through `[DONE:n]` markers in responses), keep planning, or refine the plan in a prefilled editor; a plan written as plain text under a `Plan:`/`计划:` heading is still detected as a fallback. Leave Plan mode before changing workspace files.
369
369
 
@@ -1,9 +1,9 @@
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-C4LXD56O.js";
5
- import "../../../chunks/chunk-JO6EDWHP.js";
6
- import "../../../chunks/chunk-2B6VS2NH.js";
4
+ } from "../../../chunks/chunk-XIRBNP2S.js";
5
+ import "../../../chunks/chunk-XVF6V6Q5.js";
6
+ import "../../../chunks/chunk-3VEIP2VY.js";
7
7
  import "../../../chunks/chunk-XXGYUYXI.js";
8
8
  import "../../../chunks/chunk-LZQXQOPJ.js";
9
9
 
@@ -6,9 +6,9 @@ import {
6
6
  extractPlanTodoItems,
7
7
  markCompletedPlanSteps,
8
8
  restoreExecutionState
9
- } from "../../../chunks/chunk-C4LXD56O.js";
10
- import "../../../chunks/chunk-JO6EDWHP.js";
11
- import "../../../chunks/chunk-2B6VS2NH.js";
9
+ } from "../../../chunks/chunk-XIRBNP2S.js";
10
+ import "../../../chunks/chunk-XVF6V6Q5.js";
11
+ import "../../../chunks/chunk-3VEIP2VY.js";
12
12
  import {
13
13
  Type
14
14
  } from "../../../chunks/chunk-XXGYUYXI.js";
@@ -4,15 +4,15 @@ import {
4
4
  formatTransportLifecycle,
5
5
  getConfigDir,
6
6
  logTransportLifecycle
7
- } from "../../../chunks/chunk-5GUPRFNP.js";
7
+ } from "../../../chunks/chunk-3NFKVBGY.js";
8
8
  import {
9
9
  SUBAGENT_SESSION_RECORD_VERSION,
10
10
  createPolicyEnforcedTools,
11
11
  createSharedFileSystemTools,
12
12
  createSubagentCapability
13
- } from "../../../chunks/chunk-C4LXD56O.js";
14
- import "../../../chunks/chunk-JO6EDWHP.js";
15
- import "../../../chunks/chunk-2B6VS2NH.js";
13
+ } from "../../../chunks/chunk-XIRBNP2S.js";
14
+ import "../../../chunks/chunk-XVF6V6Q5.js";
15
+ import "../../../chunks/chunk-3VEIP2VY.js";
16
16
  import "../../../chunks/chunk-XXGYUYXI.js";
17
17
  import "../../../chunks/chunk-LZQXQOPJ.js";
18
18
 
@@ -8,9 +8,9 @@ import {
8
8
  executeManageTodoList,
9
9
  executionStateToTodos,
10
10
  restoreExecutionState
11
- } from "../../../chunks/chunk-C4LXD56O.js";
12
- import "../../../chunks/chunk-JO6EDWHP.js";
13
- import "../../../chunks/chunk-2B6VS2NH.js";
11
+ } from "../../../chunks/chunk-XIRBNP2S.js";
12
+ import "../../../chunks/chunk-XVF6V6Q5.js";
13
+ import "../../../chunks/chunk-3VEIP2VY.js";
14
14
  import "../../../chunks/chunk-XXGYUYXI.js";
15
15
  import "../../../chunks/chunk-LZQXQOPJ.js";
16
16
 
@@ -7,10 +7,10 @@ import {
7
7
  defaultShellKindForPlatform,
8
8
  interpretShellExit,
9
9
  requestInteraction
10
- } from "./chunk-C4LXD56O.js";
10
+ } from "./chunk-XIRBNP2S.js";
11
11
  import {
12
12
  getLogger
13
- } from "./chunk-2B6VS2NH.js";
13
+ } from "./chunk-3VEIP2VY.js";
14
14
  import {
15
15
  Type
16
16
  } from "./chunk-XXGYUYXI.js";
@@ -687,10 +687,28 @@ async function requestHighRiskConfirmation(request) {
687
687
  "",
688
688
  request.command
689
689
  ].join("\n"),
690
- timeoutMs: 12e4
690
+ timeoutMs: 12e4,
691
+ // An entry labeled Yolo (e.g. "Yolo (5 min)") is a time-boxed YOLO
692
+ // grant: hosts that understand it answer with yoloGrantMs so subsequent
693
+ // confirmations are bypassed for that window; hosts without support
694
+ // render the labels as plain options and a selection still confirms
695
+ // this one command.
696
+ options: ["Yes", "No", "Yolo (5 min)"]
691
697
  });
698
+ const yoloGrantMs = response.type === "confirm" ? response.yoloGrantMs : void 0;
699
+ if (yoloGrantMs && yoloGrantMs > 0) notifyYoloGrantAwarded(yoloGrantMs);
692
700
  return response.type === "confirm" && response.confirmed === true;
693
701
  }
702
+ var yoloGrantListener;
703
+ function setYoloGrantListener(listener) {
704
+ yoloGrantListener = listener;
705
+ }
706
+ function notifyYoloGrantAwarded(grantMs) {
707
+ try {
708
+ yoloGrantListener?.(grantMs);
709
+ } catch {
710
+ }
711
+ }
694
712
  function validateWorkingDirectory(cwd) {
695
713
  if (!existsSync2(cwd)) {
696
714
  throw new Error(`Invalid bash cwd: ${cwd} does not exist. Use the current workspace path or pass an existing directory in cwd.`);
@@ -1600,6 +1618,7 @@ export {
1600
1618
  createCliWebResearchHealthStore,
1601
1619
  truncateHeadTail,
1602
1620
  formatSize,
1621
+ setYoloGrantListener,
1603
1622
  cleanupBashOutputArtifacts,
1604
1623
  createBashTool,
1605
1624
  formatTransportLifecycle,
@@ -3074,11 +3074,17 @@ var FileSystemGateway = class {
3074
3074
  this.validatePath(destination, "copy");
3075
3075
  const platform = detectPlatform();
3076
3076
  const dir = this.dirname(destination);
3077
- this.mkdir(dir, { recursive: true });
3078
3077
  if (platform === "puerts" && typeof CS !== "undefined") {
3078
+ if (isPuertsReparsePoint(source) || isPuertsReparsePoint(destination) || containsPuertsReparsePoint(dir) || containsPuertsReparsePoint(this.dirname(source))) {
3079
+ throw new Error(
3080
+ `Refusing to copy through a reparse point (symlink/junction): '${source}' -> '${destination}'; resolve the link or copy inside it explicitly`
3081
+ );
3082
+ }
3083
+ this.mkdir(dir, { recursive: true });
3079
3084
  CS.System.IO.File.Copy(source, destination, true);
3080
3085
  return;
3081
3086
  }
3087
+ this.mkdir(dir, { recursive: true });
3082
3088
  const fs = nodeRequire("fs");
3083
3089
  fs.copyFileSync(source, destination);
3084
3090
  }
@@ -3093,14 +3099,39 @@ var FileSystemGateway = class {
3093
3099
  this.validatePath(destination, "rename");
3094
3100
  const platform = detectPlatform();
3095
3101
  const dir = this.dirname(destination);
3096
- this.mkdir(dir, { recursive: true });
3097
3102
  if (platform === "puerts" && typeof CS !== "undefined") {
3103
+ if (isPuertsReparsePoint(source) || isPuertsReparsePoint(destination) || containsPuertsReparsePoint(dir) || containsPuertsReparsePoint(this.dirname(source))) {
3104
+ throw new Error(
3105
+ `Refusing to rename through a reparse point (symlink/junction): '${source}' -> '${destination}'; resolve the link or move inside it explicitly`
3106
+ );
3107
+ }
3108
+ this.mkdir(dir, { recursive: true });
3109
+ if (!CS.System.IO.File.Exists(source)) {
3110
+ throw new Error(`File not found: ${source}`);
3111
+ }
3112
+ if (this.normalizePath(source) === this.normalizePath(destination)) {
3113
+ return;
3114
+ }
3098
3115
  if (CS.System.IO.File.Exists(destination)) {
3116
+ const staged = `${destination}.pie-replace-${Date.now()}.tmp`;
3117
+ CS.System.IO.File.Copy(source, staged, false);
3099
3118
  CS.System.IO.File.Delete(destination);
3119
+ try {
3120
+ CS.System.IO.File.Move(staged, destination);
3121
+ } catch (error) {
3122
+ try {
3123
+ CS.System.IO.File.Move(staged, destination);
3124
+ } catch {
3125
+ }
3126
+ throw error;
3127
+ }
3128
+ CS.System.IO.File.Delete(source);
3129
+ return;
3100
3130
  }
3101
3131
  CS.System.IO.File.Move(source, destination);
3102
3132
  return;
3103
3133
  }
3134
+ this.mkdir(dir, { recursive: true });
3104
3135
  const fs = nodeRequire("fs");
3105
3136
  fs.renameSync(source, destination);
3106
3137
  }
@@ -3352,7 +3383,7 @@ function isPuertsReparsePoint(path) {
3352
3383
  warnedMissingPuertsGetAttributes = true;
3353
3384
  try {
3354
3385
  console.warn(
3355
- "[platform] File.GetAttributes is unbound on this host; directory symlink checks are disabled (move/delete follow links)"
3386
+ "[platform] File.GetAttributes is unbound on this host; directory symlink checks are disabled (move/delete/copy follow links)"
3356
3387
  );
3357
3388
  } catch {
3358
3389
  }
@@ -3369,6 +3400,42 @@ function isPuertsReparsePoint(path) {
3369
3400
  return false;
3370
3401
  }
3371
3402
  }
3403
+ function containsPuertsReparsePoint(directory) {
3404
+ const slashed = directory.replace(/\\/g, "/");
3405
+ const trimmed = slashed.replace(/\/+$/, "");
3406
+ if (!trimmed || trimmed === "/") return false;
3407
+ const unc = /^\/\/([^/]+)\/([^/]+)/.exec(trimmed);
3408
+ let prefix;
3409
+ let rest;
3410
+ if (unc) {
3411
+ prefix = unc[0];
3412
+ rest = trimmed.slice(prefix.length);
3413
+ } else {
3414
+ const driveRoot = /^([a-zA-Z]:)\//.exec(trimmed);
3415
+ if (driveRoot) {
3416
+ prefix = `${driveRoot[1]}/`;
3417
+ rest = trimmed.slice(prefix.length);
3418
+ } else {
3419
+ const bareDrive = /^[a-zA-Z]:$/.test(trimmed);
3420
+ if (bareDrive) {
3421
+ return isPuertsReparsePoint(trimmed);
3422
+ }
3423
+ if (trimmed.startsWith("/")) {
3424
+ prefix = "/";
3425
+ rest = trimmed.slice(1);
3426
+ } else {
3427
+ prefix = "";
3428
+ rest = trimmed;
3429
+ }
3430
+ }
3431
+ }
3432
+ let current = prefix;
3433
+ for (const part of rest.split("/").filter((segment) => segment.length > 0 && segment !== ".")) {
3434
+ current = current ? current.endsWith("/") ? `${current}${part}` : `${current}/${part}` : part;
3435
+ if (isPuertsReparsePoint(current)) return true;
3436
+ }
3437
+ return false;
3438
+ }
3372
3439
  var warnedPuertsDeletionShells = false;
3373
3440
  function warnPuertsDeletionShellsOnce(path) {
3374
3441
  if (warnedPuertsDeletionShells) return;
@@ -2,7 +2,7 @@ import { createRequire as __createRequire } from "node:module"; const require =
2
2
  import {
3
3
  Agent,
4
4
  getToolCallerIdentity
5
- } from "./chunk-JO6EDWHP.js";
5
+ } from "./chunk-XVF6V6Q5.js";
6
6
  import {
7
7
  AssistantMessageEventStream,
8
8
  FileSystemGateway,
@@ -12,7 +12,7 @@ import {
12
12
  getPlatformConfig,
13
13
  hashText,
14
14
  streamSimple
15
- } from "./chunk-2B6VS2NH.js";
15
+ } from "./chunk-3VEIP2VY.js";
16
16
  import {
17
17
  Type
18
18
  } from "./chunk-XXGYUYXI.js";
@@ -1005,7 +1005,7 @@ var PLAN_POWERSHELL_READ_ALIASES = /* @__PURE__ */ new Set(["cat", "ls", "pwd",
1005
1005
  var PLAN_POWERSHELL_SAFE_PARAMETERS = /^(?:-(?:Raw|TotalCount|Head|Tail|First|Last|Wait|LiteralPath|Path|Name|Pattern|Recurse|Filter|Include|Exclude|SimpleMatch|CaseSensitive|Quiet|Word|Line|Character|Encoding|ErrorAction|WarningAction))$/i;
1006
1006
  var PLAN_POWERSHELL_SEPARATORS = /[;\n\r\t]|[<>]{1,2}|\||&&|\|\|/;
1007
1007
  var PLAN_POWERSHELL_NON_ASCII = /[^\x20-\x7E]/;
1008
- var PLAN_POWERSHELL_UNSAFE_TOKENS = /\$\(|`|%\{|[(){}\[\]]|\bsource\b|\.\s+[/~]|\b(bash|sh|zsh|pwsh|powershell|cmd|npm|npx|node|python3?|git)\b/i;
1008
+ var PLAN_POWERSHELL_UNSAFE_TOKENS = /\$\(|`|%\{|[(){}\[\]]|\bsource\b|\.\s+[/~]|\b(bash|sh|zsh|pwsh|powershell|cmd|npm|npx|node|python3?)\b/i;
1009
1009
  function isPlanModeSafePowerShellCommand(command) {
1010
1010
  const trimmed = command.trim();
1011
1011
  if (!trimmed) return false;
@@ -1015,6 +1015,18 @@ function isPlanModeSafePowerShellCommand(command) {
1015
1015
  const tokens = trimmed.split(/\s+/).filter(Boolean);
1016
1016
  const head = tokens[0].toLowerCase();
1017
1017
  if (!head) return false;
1018
+ if (head === "git" || head === "rg") {
1019
+ if (/["']/.test(trimmed)) return false;
1020
+ if (/[$@]/.test(trimmed)) return false;
1021
+ }
1022
+ if (head === "git") {
1023
+ const subcommand = tokens[1]?.toLowerCase() ?? "";
1024
+ if (!GIT_READ_SUBCOMMANDS.has(subcommand)) return false;
1025
+ return !tokens.slice(2).some((token) => UNSAFE_GIT_FLAGS.test(token) || token === "--no-pager" || token === "-c");
1026
+ }
1027
+ if (head === "rg") {
1028
+ return !tokens.slice(1).some((token) => UNSAFE_RG_FLAGS.test(token) || token === "--pre" || token === "--pre-glob");
1029
+ }
1018
1030
  if (!PLAN_POWERSHELL_READ_COMMANDS.has(head) && !PLAN_POWERSHELL_READ_ALIASES.has(head)) return false;
1019
1031
  for (const token of tokens.slice(1)) {
1020
1032
  if (token.startsWith("-") && !PLAN_POWERSHELL_SAFE_PARAMETERS.test(token)) return false;
@@ -8467,8 +8479,11 @@ var POWERSHELL_DESTRUCTIVE_PATTERNS = [
8467
8479
  // PowerShell resolves these aliases before execution. The classifier must
8468
8480
  // treat the aliases exactly like their canonical cmdlets; otherwise a
8469
8481
  // guarded shell can run `ri -Recurse -Force` without the confirmation that
8470
- // `Remove-Item -Recurse -Force` receives.
8471
- { pattern: /\b(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b[^;\n|]*(?:-Recurse|-Force)\b/i, warning: "may recursively or forcefully remove files", commandClass: "filesystem_write" },
8482
+ // `Remove-Item -Recurse -Force` receives. PowerShell parameters are
8483
+ // prefix-abbreviatable (`-r` == `-Recurse`, `-fo` == `-Force`), so the
8484
+ // parameter matcher below accepts any unambiguous-style abbreviation,
8485
+ // not just the full spellings.
8486
+ { pattern: buildPowerShellRemoveItemPattern(), warning: "may recursively or forcefully remove files", commandClass: "filesystem_write" },
8472
8487
  { pattern: /\b(?:Remove-Item|ri|rm|rmdir|del|erase|rd)\b[^;\n|]*(?:HKLM:|HKCU:|Registry::)/i, warning: "may remove registry entries", commandClass: "infra_destructive" },
8473
8488
  // These write aliases are not all destructive in the recursive-delete sense,
8474
8489
  // but they can overwrite or create arbitrary files. Keep them behind the
@@ -8482,7 +8497,10 @@ var POWERSHELL_DESTRUCTIVE_PATTERNS = [
8482
8497
  ];
8483
8498
  var CMD_DESTRUCTIVE_PATTERNS = [
8484
8499
  { pattern: /\b(del|erase)\b[^&|\n]*(\/s|\/q)/i, warning: "may recursively or quietly delete files", commandClass: "filesystem_write" },
8485
- { pattern: /\brmdir\b[^&|\n]*(\/s|\/q)/i, warning: "may recursively remove directories", commandClass: "filesystem_write" },
8500
+ // `rd` is cmd's documented synonym for rmdir and accepts the same /s /q
8501
+ // switches; classifying only `rmdir` let `rd /s /q C:\\anywhere` run as an
8502
+ // undetected recursive deletion.
8503
+ { pattern: /\b(?:rmdir|rd)\b[^&|\n]*(\/s|\/q)/i, warning: "may recursively remove directories", commandClass: "filesystem_write" },
8486
8504
  { pattern: /\bformat\s+[a-z]:/i, warning: "may format a drive", commandClass: "infra_destructive" },
8487
8505
  { pattern: /\b(takeown|icacls)\b[^&|\n]*(\/grant|\/reset|\/remove)/i, warning: "may alter ownership or permissions", commandClass: "privilege_escalation" },
8488
8506
  { pattern: /\bgit\s+reset\s+--hard\b/i, warning: "may discard uncommitted changes", commandClass: "git_destructive" },
@@ -8494,6 +8512,15 @@ function splitCommand(command) {
8494
8512
  function firstWord(command) {
8495
8513
  return command.trim().split(/\s+/)[0] || "";
8496
8514
  }
8515
+ function buildPowerShellRemoveItemPattern() {
8516
+ const removeVerb = "(?:Remove-Item|ri|rm|rmdir|del|erase|rd)";
8517
+ const recurseg = "-(?:r(?:e(?:c(?:u(?:r(?:s(?:e?)?)?)?)?)?)?)";
8518
+ const force = "-(?:f(?:o(?:r(?:c(?:e?)?)?)?)?)";
8519
+ return new RegExp(
8520
+ `\\b${removeVerb}\\b[^;\\n|]*(?:${recurseg}|${force})\\b`,
8521
+ "i"
8522
+ );
8523
+ }
8497
8524
  function lastPipelineCommand(command) {
8498
8525
  const segments = command.split("|").map((part) => part.trim()).filter(Boolean);
8499
8526
  return segments[segments.length - 1] || command;
@@ -4,7 +4,7 @@ import {
4
4
  disposeModelTransports,
5
5
  streamSimple,
6
6
  validateToolArguments
7
- } from "./chunk-2B6VS2NH.js";
7
+ } from "./chunk-3VEIP2VY.js";
8
8
 
9
9
  // ../../packages/agent-core/src/agent-loop.ts
10
10
  function createLoopErrorMessage(error, config, signal) {
@@ -6,8 +6,8 @@ import {
6
6
  bindToolCallerIdentity,
7
7
  createToolCallerIdentity,
8
8
  getToolCallerIdentity
9
- } from "./chunk-JO6EDWHP.js";
10
- import "./chunk-2B6VS2NH.js";
9
+ } from "./chunk-XVF6V6Q5.js";
10
+ import "./chunk-3VEIP2VY.js";
11
11
  import "./chunk-XXGYUYXI.js";
12
12
  import "./chunk-LZQXQOPJ.js";
13
13
  export {
@@ -1,7 +1,7 @@
1
1
  import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
2
2
  import {
3
3
  EventStream
4
- } from "./chunk-2B6VS2NH.js";
4
+ } from "./chunk-3VEIP2VY.js";
5
5
  import "./chunk-XXGYUYXI.js";
6
6
  import "./chunk-LZQXQOPJ.js";
7
7
 
package/dist/cli.js CHANGED
@@ -22,8 +22,9 @@ import {
22
22
  getThemesDir,
23
23
  logTransportLifecycle,
24
24
  migrateConfigFromAgentDir,
25
+ setYoloGrantListener,
25
26
  truncateHeadTail
26
- } from "./chunks/chunk-5GUPRFNP.js";
27
+ } from "./chunks/chunk-3NFKVBGY.js";
27
28
  import {
28
29
  resolveCliProjectRoot
29
30
  } from "./chunks/chunk-WLFOBECN.js";
@@ -88,8 +89,8 @@ import {
88
89
  shouldPreserveExecutionStateForUserText,
89
90
  supersedeExecutionState,
90
91
  verifyPreparedCompactionCommit
91
- } from "./chunks/chunk-C4LXD56O.js";
92
- import "./chunks/chunk-JO6EDWHP.js";
92
+ } from "./chunks/chunk-XIRBNP2S.js";
93
+ import "./chunks/chunk-XVF6V6Q5.js";
93
94
  import {
94
95
  Deref,
95
96
  EMPTY_ASSISTANT_CONTENT_ERROR,
@@ -114,7 +115,7 @@ import {
114
115
  sortToolModelCandidatesByCapability,
115
116
  streamSimple,
116
117
  type_exports
117
- } from "./chunks/chunk-2B6VS2NH.js";
118
+ } from "./chunks/chunk-3VEIP2VY.js";
118
119
  import {
119
120
  IsArray,
120
121
  IsBigInt,
@@ -59666,6 +59667,13 @@ var SelectList = class {
59666
59667
  this.filteredItems = this.items.filter((item) => item.value.toLowerCase().startsWith(filter.toLowerCase()));
59667
59668
  this.selectedIndex = 0;
59668
59669
  }
59670
+ /** Replace the item set (e.g. a scope toggle) and reset the cursor. */
59671
+ setItems(items) {
59672
+ this.items = items;
59673
+ this.filteredItems = items;
59674
+ this.selectedIndex = 0;
59675
+ if (items[0]) this.onSelectionChange?.(items[0]);
59676
+ }
59669
59677
  getVisibleRange() {
59670
59678
  const startIndex = Math.max(
59671
59679
  0,
@@ -70004,6 +70012,39 @@ function createCliFileSystemTools(cwd, options) {
70004
70012
  });
70005
70013
  }
70006
70014
 
70015
+ // src/runtime/yolo-grant.ts
70016
+ var YoloGrantTracker = class {
70017
+ untilMs = 0;
70018
+ isActive(now = Date.now()) {
70019
+ return this.untilMs > now;
70020
+ }
70021
+ award(grantMs, now = Date.now()) {
70022
+ this.untilMs = now + Math.max(0, grantMs);
70023
+ }
70024
+ expire() {
70025
+ this.untilMs = 0;
70026
+ }
70027
+ /** Expiry timestamp (0 when no grant is held); useful for display. */
70028
+ get until() {
70029
+ return this.untilMs;
70030
+ }
70031
+ };
70032
+ function renderYoloGrantBanner(grantMs, sink) {
70033
+ const minutes = Math.max(1, Math.round(grantMs / 6e4));
70034
+ sink.addChild(new Spacer(1));
70035
+ sink.addChild(
70036
+ new Text(theme.fg("warning", `\u26A0\uFE0F YOLO granted for ${minutes} min (high-risk commands skip confirmation)`), 1, 0)
70037
+ );
70038
+ sink.addChild(new Spacer(1));
70039
+ }
70040
+ function parseYoloGrantMs(options, selected) {
70041
+ const yoloOption = options.find((option) => /^\s*yolo(\s*\(|\s|$)/i.test(option));
70042
+ if (!yoloOption || selected !== yoloOption) return void 0;
70043
+ const minutesMatch = /\(\s*(\d+(?:\.\d+)?)\s*min/i.exec(yoloOption);
70044
+ const minutes = minutesMatch ? Number(minutesMatch[1]) : 5;
70045
+ return Math.round(minutes * 6e4);
70046
+ }
70047
+
70007
70048
  // src/execution/state-manager.ts
70008
70049
  function getTextFromMessageContent(content) {
70009
70050
  if (typeof content === "string") {
@@ -70502,6 +70543,14 @@ function normalizeForComparison(value, flavor) {
70502
70543
  const withoutTrailingSeparators = normalized.length > root.length ? normalized.replace(flavor === "windows" ? /[\\/]+$/ : /\/+$/, "") : normalized;
70503
70544
  return flavor === "windows" ? withoutTrailingSeparators.toLowerCase() : withoutTrailingSeparators;
70504
70545
  }
70546
+ function sessionBelongsToCwd(sessionCwd, currentCwd) {
70547
+ if (typeof sessionCwd !== "string" || sessionCwd.length === 0) return true;
70548
+ if (!currentCwd) return true;
70549
+ const sessionFlavor = getPathFlavor(sessionCwd, currentCwd);
70550
+ const currentFlavor = getPathFlavor(currentCwd, sessionCwd);
70551
+ if (sessionFlavor !== currentFlavor) return false;
70552
+ return normalizeForComparison(sessionCwd, sessionFlavor) === normalizeForComparison(currentCwd, currentFlavor);
70553
+ }
70505
70554
  function formatSessionCwdTag(sessionCwd, currentCwd, homeDir) {
70506
70555
  if (typeof sessionCwd !== "string" || sessionCwd.length === 0 || !currentCwd) return void 0;
70507
70556
  const sessionFlavor = getPathFlavor(sessionCwd, currentCwd);
@@ -70527,31 +70576,47 @@ var SessionSelectorComponent = class extends Container {
70527
70576
  callbacks;
70528
70577
  options;
70529
70578
  items;
70579
+ /** All sessions ever handed to the selector; the visible list is the current scope's filter. */
70580
+ allSessions;
70581
+ globalScope;
70530
70582
  refreshAttempted = /* @__PURE__ */ new Set();
70531
70583
  refreshInFlight = false;
70532
70584
  refreshQueue = [];
70533
70585
  refreshQueued = /* @__PURE__ */ new Set();
70534
70586
  refreshTimer;
70535
70587
  destroyed = false;
70588
+ titleText;
70589
+ hintText;
70536
70590
  constructor(sessions, callbacks, options = {}) {
70537
70591
  super();
70538
70592
  this.sessions = sessions;
70593
+ this.allSessions = sessions;
70594
+ this.globalScope = options.globalScope ?? false;
70539
70595
  this.callbacks = callbacks;
70540
70596
  this.options = options;
70541
- const truncated = options.totalCount !== void 0 && options.totalCount > sessions.length;
70542
- const title = truncated ? `Resume Session (recent ${sessions.length} of ${options.totalCount})` : "Resume Session";
70543
- this.addChild(new Text(theme.bold(theme.fg("accent", title)), 0, 0));
70597
+ const scoped = this.globalScope ? sessions : sessions.filter((session) => sessionBelongsToCwd(session.cwd, options.currentCwd));
70598
+ this.sessions = scoped;
70599
+ const title = this.isWindowTruncated() ? `Resume Session (recent ${scoped.length} of ${options.totalCount})` : "Resume Session";
70600
+ this.titleText = new Text(theme.bold(theme.fg("accent", title)), 0, 0);
70601
+ this.addChild(this.titleText);
70544
70602
  this.addChild(new Spacer(1));
70545
- this.items = sessions.map((session) => this.createItem(session));
70603
+ this.items = scoped.map((session) => this.createItem(session));
70546
70604
  this.selectList = new SelectList(
70547
70605
  this.items,
70548
- Math.min(this.items.length, 8),
70606
+ 8,
70549
70607
  {
70550
70608
  selectedPrefix: (text) => theme.fg("accent", text),
70551
70609
  selectedText: (text) => theme.fg("accent", text),
70552
70610
  description: (text) => theme.fg("muted", text),
70553
70611
  scrollInfo: (text) => theme.fg("dim", text),
70554
- noMatch: (text) => theme.fg("dim", text)
70612
+ // The noMatch hook carries the empty-directory-scope copy (SelectList
70613
+ // hardcodes "No matching commands", which is wrong for sessions).
70614
+ // When the loaded list is a truncated recent window, `g` cannot show
70615
+ // this directory's older sessions either — promise nothing it can't do.
70616
+ noMatch: () => theme.fg(
70617
+ "dim",
70618
+ this.options.totalCount !== void 0 && this.options.totalCount > this.allSessions.length ? " No recent sessions in this directory" : " No sessions in this directory \xB7 g shows all sessions"
70619
+ )
70555
70620
  }
70556
70621
  );
70557
70622
  this.selectList.onSelect = (item) => {
@@ -70569,14 +70634,49 @@ var SessionSelectorComponent = class extends Container {
70569
70634
  };
70570
70635
  this.addChild(this.selectList);
70571
70636
  this.addChild(new Spacer(1));
70572
- this.addChild(
70573
- new Text(theme.fg("dim", " \u2191\u2193 to navigate \xB7 \u2190\u2192 to page \xB7 Enter to select \xB7 Esc to cancel"), 0, 0)
70574
- );
70637
+ this.hintText = new Text(theme.fg("dim", this.buildHintLine()), 0, 0);
70638
+ this.addChild(this.hintText);
70575
70639
  this.scheduleVisibleRefreshes();
70576
70640
  }
70641
+ /** True when the visible list is the unfiltered window AND that window is
70642
+ * truncated vs the disk total (only then does "recent N of M" describe it). */
70643
+ isWindowTruncated() {
70644
+ return this.sessions.length === this.allSessions.length && this.options.totalCount !== void 0 && this.options.totalCount > this.allSessions.length;
70645
+ }
70646
+ /** Shared count expression so the title and the `g` hint never disagree. */
70647
+ scopeCountText(count) {
70648
+ return this.options.totalCount !== void 0 && this.options.totalCount > count ? `recent ${count} of ${this.options.totalCount}` : `all ${count}`;
70649
+ }
70650
+ buildHintLine() {
70651
+ const scopeNote = this.globalScope ? `${this.scopeCountText(this.allSessions.length)} sessions` : `${this.sessions.length} in this directory`;
70652
+ return ` \u2191\u2193 navigate \xB7 \u2190\u2192 page \xB7 g global (${scopeNote}) \xB7 Enter select \xB7 Esc cancel`;
70653
+ }
70577
70654
  handleInput(data) {
70655
+ if (this.destroyed) return;
70656
+ if (data === "g" || data === "G") {
70657
+ this.toggleScope();
70658
+ return;
70659
+ }
70578
70660
  this.selectList.handleInput(data);
70579
70661
  }
70662
+ /** Toggle between current-directory sessions and the full loaded recent list. */
70663
+ toggleScope() {
70664
+ if (this.destroyed) return;
70665
+ this.globalScope = !this.globalScope;
70666
+ this.sessions = this.globalScope ? this.allSessions : this.allSessions.filter((session) => sessionBelongsToCwd(session.cwd, this.options.currentCwd));
70667
+ this.items = this.sessions.map((session) => this.createItem(session));
70668
+ this.selectList.setItems(this.items);
70669
+ this.updateTitle();
70670
+ this.updateHint();
70671
+ this.scheduleVisibleRefreshes();
70672
+ }
70673
+ updateTitle() {
70674
+ const windowText = this.isWindowTruncated() ? ` (recent ${this.sessions.length} of ${this.options.totalCount})` : "";
70675
+ this.titleText.setText(theme.bold(theme.fg("accent", `Resume Session${windowText}`)));
70676
+ }
70677
+ updateHint() {
70678
+ this.hintText.setText(theme.fg("dim", this.buildHintLine()));
70679
+ }
70580
70680
  getSelectList() {
70581
70681
  return this.selectList;
70582
70682
  }
@@ -70584,10 +70684,11 @@ var SessionSelectorComponent = class extends Container {
70584
70684
  const cwdTag = formatSessionCwdTag(session.cwd, this.options.currentCwd, this.options.homeDir);
70585
70685
  const unknownTag = cwdTag === void 0 && this.options.currentCwd && !(typeof session.cwd === "string" && session.cwd.length > 0) ? "unknown path" : void 0;
70586
70686
  const tag = cwdTag ?? unknownTag;
70687
+ const meta = `${session.id} \xB7 ${session.messageCount} messages \xB7 ${formatDate(session.updatedAt)}`;
70587
70688
  return {
70588
70689
  value: session.id,
70589
70690
  label: session.name || `Session ${session.id.slice(0, 8)}`,
70590
- description: tag ? `${tag} \xB7 ${session.messageCount} messages \xB7 ${formatDate(session.updatedAt)}` : `${session.messageCount} messages \xB7 ${formatDate(session.updatedAt)}`
70691
+ description: tag ? `${tag} \xB7 ${meta}` : meta
70591
70692
  };
70592
70693
  }
70593
70694
  clearRefreshTimer() {
@@ -70634,6 +70735,8 @@ var SessionSelectorComponent = class extends Container {
70634
70735
  updateItem(metadata) {
70635
70736
  const sessionIndex = this.sessions.findIndex((session) => session.id === metadata.id);
70636
70737
  if (sessionIndex >= 0) this.sessions[sessionIndex] = metadata;
70738
+ const allIndex = this.allSessions.findIndex((session) => session.id === metadata.id);
70739
+ if (allIndex >= 0) this.allSessions[allIndex] = metadata;
70637
70740
  const itemIndex = this.items.findIndex((item2) => item2.value === metadata.id);
70638
70741
  if (itemIndex < 0) return;
70639
70742
  const nextItem = this.createItem(metadata);
@@ -72622,8 +72725,8 @@ async function handleResumeCommand(host) {
72622
72725
  host.showSelector((done) => {
72623
72726
  const selector = new SessionSelectorComponent(sessions, {
72624
72727
  onSelect: async (sessionId) => {
72625
- await host.loadSession(sessionId);
72626
72728
  done();
72729
+ await host.loadSession(sessionId);
72627
72730
  },
72628
72731
  onCancel: () => {
72629
72732
  done();
@@ -72635,7 +72738,7 @@ async function handleResumeCommand(host) {
72635
72738
  requestRender: () => host.ui.requestRender(),
72636
72739
  totalCount
72637
72740
  });
72638
- return { component: selector, focus: selector.getSelectList() };
72741
+ return { component: selector, focus: selector };
72639
72742
  });
72640
72743
  }
72641
72744
  async function loadSession(host, sessionId) {
@@ -76373,6 +76476,7 @@ function cleanupAndExit(host) {
76373
76476
  exitingHosts.add(host);
76374
76477
  console.log("\n[Cleanup] Stopping file status monitor...");
76375
76478
  const shutdown = shutdownInteractiveHost(host);
76479
+ const sessionId = host.sessionManager?.getActiveSessionId();
76376
76480
  void (async () => {
76377
76481
  try {
76378
76482
  await shutdown;
@@ -76380,7 +76484,7 @@ function cleanupAndExit(host) {
76380
76484
  console.error("Interactive shutdown failed:", error);
76381
76485
  process.exitCode = 1;
76382
76486
  }
76383
- console.log("[Cleanup] Goodbye!");
76487
+ console.log(`[Cleanup] Goodbye!${sessionId ? ` session: ${sessionId}` : ""}`);
76384
76488
  process.exit(process.exitCode || 0);
76385
76489
  })();
76386
76490
  }
@@ -80502,6 +80606,13 @@ function restoreEditor(host) {
80502
80606
  host.ui.invalidate();
80503
80607
  host.ui.requestRender();
80504
80608
  }
80609
+ function showMissingModelConfigurationNotice(host) {
80610
+ const message = "No model configured. Add one in ~/.pie/models.json, then use /settings/model.";
80611
+ host.chatContainer.addChild(new Spacer(1));
80612
+ host.chatContainer.addChild(new Text(theme.fg("warning", `\u26A0 ${message}`), 1, 0));
80613
+ host.chatContainer.addChild(new Spacer(1));
80614
+ host.showStatus(message);
80615
+ }
80505
80616
 
80506
80617
  // src/runtime/interactive-continuation.ts
80507
80618
  function getContinuationTimeoutMs() {
@@ -81266,7 +81377,7 @@ function createInteractiveExtensionUIContext(host) {
81266
81377
  return {
81267
81378
  notify: (message, type = "info", opts) => showExtensionNotification(host, message, type, opts),
81268
81379
  select: (title, options, opts) => interact(() => showExtensionSelector2(host, title, options, opts)),
81269
- confirm: async (title, message, opts) => await interact(() => showExtensionConfirm(host, title, message, opts)) === true,
81380
+ confirm: async (title, message, opts) => (await interact(() => showExtensionConfirm(host, title, message, opts)))?.confirmed === true,
81270
81381
  input: (title, placeholder, opts) => interact(() => showExtensionInput(host, title, placeholder, opts)),
81271
81382
  editor: (title, prefill) => interact(() => showExtensionEditor(host, title, prefill)),
81272
81383
  custom: (factory, options) => interact(() => showExtensionCustom(host, factory, options)),
@@ -81365,15 +81476,28 @@ function installInteractiveInteractionHandler(host) {
81365
81476
  prompt: request.prompt,
81366
81477
  detail: request.detail
81367
81478
  });
81368
- const { value: confirmed, timedOut } = await waitForUser(
81369
- (signal) => showExtensionConfirm(host, request.prompt, request.detail ?? "", { signal })
81479
+ const { value, timedOut } = await waitForUser(
81480
+ (signal) => showExtensionConfirm(host, request.prompt, request.detail ?? "", {
81481
+ signal,
81482
+ options: request.options
81483
+ })
81370
81484
  );
81485
+ const confirmed = value?.confirmed;
81486
+ const yoloGrantMs = value?.yoloGrantMs;
81371
81487
  host.logDebug("interaction:confirm:end", {
81372
81488
  id: request.id,
81373
81489
  confirmed,
81490
+ yoloGrantMs,
81374
81491
  timedOut
81375
81492
  });
81376
- return { type: "confirm", id: request.id, confirmed: confirmed === true, timedOut, skipped: timedOut || confirmed === void 0 };
81493
+ return {
81494
+ type: "confirm",
81495
+ id: request.id,
81496
+ confirmed: confirmed === true,
81497
+ timedOut,
81498
+ skipped: timedOut || confirmed === void 0,
81499
+ yoloGrantMs
81500
+ };
81377
81501
  }
81378
81502
  case "text_input": {
81379
81503
  host.logDebug("interaction:text_input:start", {
@@ -81467,9 +81591,15 @@ function showExtensionSelector2(host, title, options, opts) {
81467
81591
  });
81468
81592
  }
81469
81593
  async function showExtensionConfirm(host, title, message, opts) {
81594
+ const options = opts?.options?.length ? opts.options : ["Yes", "No"];
81470
81595
  const result = await showExtensionSelector2(host, `${title}
81471
- ${message}`, ["Yes", "No"], opts);
81472
- return result === void 0 ? void 0 : result === "Yes";
81596
+ ${message}`, options, opts);
81597
+ if (result === void 0) return void 0;
81598
+ const yoloGrantMs = parseYoloGrantMs(options, result);
81599
+ if (yoloGrantMs !== void 0) {
81600
+ return { confirmed: true, yoloGrantMs };
81601
+ }
81602
+ return { confirmed: result === "Yes" };
81473
81603
  }
81474
81604
  function showExtensionInput(host, title, placeholder, opts) {
81475
81605
  return new Promise((resolve7) => {
@@ -82017,6 +82147,8 @@ var InteractiveMode = class {
82017
82147
  mentionPickerOptions = [];
82018
82148
  attachmentResolver;
82019
82149
  yoloMode = false;
82150
+ yoloGrant = new YoloGrantTracker();
82151
+ // time-boxed confirm-dialog grant ("Yolo (5 min)")
82020
82152
  pristineTools = [];
82021
82153
  // Pristine (extension-unwrapped) tool assembly: the mode-rebuild source.
82022
82154
  /** Calm mode: render only questions and answers (display-only; persisted). */
@@ -82108,16 +82240,9 @@ var InteractiveMode = class {
82108
82240
  hasConfiguredModel() {
82109
82241
  return Boolean(this.options.apiKey) && this.options.model?.provider !== "unconfigured";
82110
82242
  }
82111
- showMissingModelConfigurationNotice() {
82112
- const message = "No model configured. Add one in ~/.pie/models.json, then use /settings/model.";
82113
- this.chatContainer.addChild(new Spacer(1));
82114
- this.chatContainer.addChild(new Text(theme.fg("warning", `\u26A0 ${message}`), 1, 0));
82115
- this.chatContainer.addChild(new Spacer(1));
82116
- this.showStatus(message);
82117
- }
82118
82243
  ensureAgentPromptReady() {
82119
82244
  if (this.hasConfiguredModel()) return true;
82120
- this.showMissingModelConfigurationNotice();
82245
+ showMissingModelConfigurationNotice(this.filePipelineHost);
82121
82246
  this.safeRequestRender();
82122
82247
  return false;
82123
82248
  }
@@ -82177,14 +82302,17 @@ var InteractiveMode = class {
82177
82302
  }
82178
82303
  getPolicyContext = () => ({
82179
82304
  mode: this.planModeEnabled ? "plan" : "normal",
82180
- yoloMode: this.yoloMode,
82305
+ yoloMode: this.yoloMode || this.yoloGrant.isActive(),
82181
82306
  confirmationPolicy: "allow"
82182
82307
  });
82183
82308
  rebuildSkillAwareTools(sourceTools) {
82184
82309
  const preservedTools = sourceTools.filter(
82185
82310
  (tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name) && tool.name !== "bash" && tool.name !== "shell"
82186
82311
  );
82187
- const bashTool = createBashTool(this.options.cwd, { isYoloMode: () => this.yoloMode, getEnv: () => computerUseOwnerEnv(this.sessionManager.getActiveSessionId() || COMPUTER_USE_STANDALONE_OWNER, String(process.pid)) });
82312
+ const bashTool = createBashTool(this.options.cwd, {
82313
+ isYoloMode: () => this.yoloMode || this.yoloGrant.isActive(),
82314
+ getEnv: () => computerUseOwnerEnv(this.sessionManager.getActiveSessionId() || COMPUTER_USE_STANDALONE_OWNER, String(process.pid))
82315
+ });
82188
82316
  const fileSystemToolOptions = (allowlistedDirs) => ({
82189
82317
  ...buildCliFileAccessOptions({
82190
82318
  cwd: this.options.cwd,
@@ -82332,7 +82460,7 @@ var InteractiveMode = class {
82332
82460
  async init() {
82333
82461
  const activeSession = this.sessionManager.getActiveSession();
82334
82462
  this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
82335
- const { Agent } = await import("./chunks/src-WFN4JWLE.js");
82463
+ const { Agent } = await import("./chunks/src-2RCV3I3P.js");
82336
82464
  this.agent = new Agent({
82337
82465
  initialState: {
82338
82466
  systemPrompt: this.buildSystemPrompt(),
@@ -82376,7 +82504,7 @@ var InteractiveMode = class {
82376
82504
  await this.initializeFileManager();
82377
82505
  this.syncSessionModelMetadata();
82378
82506
  if (!this.hasConfiguredModel()) {
82379
- this.showMissingModelConfigurationNotice();
82507
+ showMissingModelConfigurationNotice(this.filePipelineHost);
82380
82508
  }
82381
82509
  }
82382
82510
  createExtensionContextForCommands() {
@@ -82421,6 +82549,11 @@ var InteractiveMode = class {
82421
82549
  async loadExtensions() {
82422
82550
  this.extensionUIContext = createInteractiveExtensionUIContext(this);
82423
82551
  installInteractiveInteractionHandler(this);
82552
+ setYoloGrantListener((grantMs) => {
82553
+ this.yoloGrant.award(grantMs);
82554
+ renderYoloGrantBanner(grantMs, this.chatContainer);
82555
+ this.ui.requestRender();
82556
+ });
82424
82557
  await loadInteractiveExtensions(this.extensionLoaderHost);
82425
82558
  }
82426
82559
  /**
@@ -83210,7 +83343,7 @@ async function runPrintMode(params) {
83210
83343
  `);
83211
83344
  console.log("Assistant: ");
83212
83345
  }
83213
- const { Agent: AgentClass } = await import("./chunks/src-WFN4JWLE.js");
83346
+ const { Agent: AgentClass } = await import("./chunks/src-2RCV3I3P.js");
83214
83347
  let agent;
83215
83348
  const printModeExtensions = await loadPrintModeExtensions({
83216
83349
  cwd: runtime.cwd,
@@ -84099,7 +84232,7 @@ async function runJsonEventsMode(params) {
84099
84232
  return;
84100
84233
  }
84101
84234
  const parent = agent;
84102
- const { Agent: AgentClass } = await import("./chunks/src-WFN4JWLE.js");
84235
+ const { Agent: AgentClass } = await import("./chunks/src-2RCV3I3P.js");
84103
84236
  const sideAgent = new AgentClass({
84104
84237
  initialState: {
84105
84238
  systemPrompt: parent.state.systemPrompt,
@@ -84459,7 +84592,7 @@ async function runJsonEventsMode(params) {
84459
84592
  if (runtime.initialModel.unconfigured || controller) {
84460
84593
  return;
84461
84594
  }
84462
- const { Agent: AgentClass } = await import("./chunks/src-WFN4JWLE.js");
84595
+ const { Agent: AgentClass } = await import("./chunks/src-2RCV3I3P.js");
84463
84596
  if (runtimeClosing) return;
84464
84597
  const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
84465
84598
  if (runtimeClosing) {
@@ -85121,7 +85254,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
85121
85254
  }
85122
85255
  async function createCliTestStreamFnFromEnv() {
85123
85256
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
85124
- return (await import("./chunks/test-stream-GXZ7NT4H.js")).createTestStreamFnFromSequenceEnv();
85257
+ return (await import("./chunks/test-stream-Y2S3H7DK.js")).createTestStreamFnFromSequenceEnv();
85125
85258
  }
85126
85259
  function resolveJsonEventsDetailFlag() {
85127
85260
  for (let index = 0; index < process.argv.length; index += 1) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "2.7.10",
3
+ "version": "2.7.11",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {