@cydm/pie 2.7.6 → 2.7.7

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.
@@ -4,7 +4,7 @@ import {
4
4
  disposeModelTransports,
5
5
  streamSimple,
6
6
  validateToolArguments
7
- } from "./chunk-ZF5FHTES.js";
7
+ } from "./chunk-2FEDB5GR.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-5YWEUFLM.js";
10
- import "./chunk-ZF5FHTES.js";
9
+ } from "./chunk-W5B3OXHQ.js";
10
+ import "./chunk-2FEDB5GR.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-ZF5FHTES.js";
4
+ } from "./chunk-2FEDB5GR.js";
5
5
  import "./chunk-XXGYUYXI.js";
6
6
  import "./chunk-LZQXQOPJ.js";
7
7
 
@@ -94,6 +94,15 @@ function createTestStreamFnFromSequenceEnv(value = process.env.PIE_TEST_MOCK_STR
94
94
  return async (model, context, options) => {
95
95
  const step = steps[Math.min(callIndex, steps.length - 1)];
96
96
  assertSystemPromptIncludes(context.systemPrompt, callIndex);
97
+ const capturePath = process.env.PIE_TEST_MOCK_CAPTURE_CONTEXT;
98
+ if (capturePath) {
99
+ try {
100
+ const captured = context.messages.map((message) => ({ role: message.role, content: message.content }));
101
+ const fs = await import("node:fs");
102
+ fs.appendFileSync(capturePath, JSON.stringify({ callIndex, messages: captured }) + "\n");
103
+ } catch {
104
+ }
105
+ }
97
106
  callIndex += 1;
98
107
  const stream = new EventStream(
99
108
  (event) => event.type === "done" || event.type === "error",
package/dist/cli.js CHANGED
@@ -23,7 +23,7 @@ import {
23
23
  logTransportLifecycle,
24
24
  migrateConfigFromAgentDir,
25
25
  truncateHeadTail
26
- } from "./chunks/chunk-GAUIKMBA.js";
26
+ } from "./chunks/chunk-IU5L5DED.js";
27
27
  import {
28
28
  resolveCliProjectRoot
29
29
  } from "./chunks/chunk-WLFOBECN.js";
@@ -47,6 +47,7 @@ import {
47
47
  createEmptyExecutionState,
48
48
  createExecutionStateStore,
49
49
  createFileObservationState,
50
+ createHostEnvelopeProjectorRegistry,
50
51
  createPolicyEnforcedTools,
51
52
  createReadFileUnderstandingHandler,
52
53
  createSearchContextTool,
@@ -76,6 +77,7 @@ import {
76
77
  modalityForReadFileUnderstandingKind,
77
78
  pauseExecutionState,
78
79
  prepareSessionCompaction,
80
+ projectHostEnvelopes,
79
81
  registerInteractionHandler,
80
82
  requestInteraction,
81
83
  resolveExtensionIdentity,
@@ -85,8 +87,8 @@ import {
85
87
  shouldPreserveExecutionStateForUserText,
86
88
  supersedeExecutionState,
87
89
  verifyPreparedCompactionCommit
88
- } from "./chunks/chunk-YWWLRZSG.js";
89
- import "./chunks/chunk-5YWEUFLM.js";
90
+ } from "./chunks/chunk-UPGEXDEQ.js";
91
+ import "./chunks/chunk-W5B3OXHQ.js";
90
92
  import {
91
93
  Deref,
92
94
  EMPTY_ASSISTANT_CONTENT_ERROR,
@@ -111,7 +113,7 @@ import {
111
113
  sortToolModelCandidatesByCapability,
112
114
  streamSimple,
113
115
  type_exports
114
- } from "./chunks/chunk-ZF5FHTES.js";
116
+ } from "./chunks/chunk-2FEDB5GR.js";
115
117
  import {
116
118
  IsArray,
117
119
  IsBigInt,
@@ -53655,7 +53657,12 @@ var ModelRegistry = class {
53655
53657
  import * as fs4 from "fs";
53656
53658
  import * as path4 from "path";
53657
53659
  function getDisabledToolNames(settingsManager) {
53658
- return new Set(typeof settingsManager?.getDisabledTools === "function" ? settingsManager.getDisabledTools() : []);
53660
+ const disabled = new Set(typeof settingsManager?.getDisabledTools === "function" ? settingsManager.getDisabledTools() : []);
53661
+ if (disabled.has("bash") || disabled.has("shell")) {
53662
+ disabled.add("bash");
53663
+ disabled.add("shell");
53664
+ }
53665
+ return disabled;
53659
53666
  }
53660
53667
  function filterEnabledTools(tools, settingsManager) {
53661
53668
  const disabled = getDisabledToolNames(settingsManager);
@@ -53983,11 +53990,12 @@ var SettingsManager = class {
53983
53990
  }
53984
53991
  /** Whether a runtime tool is enabled; absent means "enabled". */
53985
53992
  isToolEnabled(name) {
53986
- return !this.getDisabledTools().includes(name);
53993
+ return !getDisabledToolNames(this).has(name);
53987
53994
  }
53988
53995
  /** Enable/disable a runtime tool by name (persisted in settings.json). */
53989
53996
  setToolEnabled(name, enabled) {
53990
- const disabled = this.getDisabledTools().filter((tool) => tool !== name);
53997
+ const isShell = name === "shell" || name === "bash";
53998
+ const disabled = this.getDisabledTools().filter((tool) => isShell ? tool !== "shell" && tool !== "bash" : tool !== name);
53991
53999
  if (!enabled) disabled.push(name);
53992
54000
  disabled.sort();
53993
54001
  const nextTools = { ...this.settings.tools ?? {} };
@@ -54427,8 +54435,8 @@ var MODE_RULES = {
54427
54435
  "File tools read and write inside the current workspace.",
54428
54436
  "~/.pie is allowlisted for Pie configuration and session support.",
54429
54437
  "Shell commands run from the workspace and return structured output, timeout, and truncation details.",
54430
- "web_research is read-only, uses provider-native web/search/fetch capabilities, and does not grant bash/curl web scraping permission.",
54431
- "Desktop control runs through the computer-use-axi skill CLI via bash: observation commands only read the screen, while act synthesizes real desktop input and goes through normal shell permission prompts.",
54438
+ "web_research is read-only, uses provider-native web/search/fetch capabilities, and does not grant shell/curl web scraping permission.",
54439
+ "Desktop control runs through the computer-use-axi skill CLI via the shell tool: observation commands only read the screen, while act synthesizes real desktop input and goes through normal shell permission prompts.",
54432
54440
  "Protected paths from extensions can block reads/writes even when tools are present."
54433
54441
  ],
54434
54442
  plan: [
@@ -54454,7 +54462,9 @@ var MODE_TITLES = {
54454
54462
  function buildPermissionsData() {
54455
54463
  return {
54456
54464
  modes: Object.fromEntries(Object.entries(MODE_RULES).map(([key, rules]) => [key, [...rules]])),
54457
- tools: Object.entries(BUILTIN_TOOL_CAPABILITY_METADATA).map(([name, meta]) => ({
54465
+ // The legacy bash policy key supports old history/settings; it is not a
54466
+ // second executable tool and must not be advertised as one here.
54467
+ tools: Object.entries(BUILTIN_TOOL_CAPABILITY_METADATA).filter(([name]) => name !== "bash").map(([name, meta]) => ({
54458
54468
  name,
54459
54469
  ...meta.riskClass ? { riskClass: meta.riskClass } : {},
54460
54470
  ...meta.permissionScope ? { permissionScope: meta.permissionScope } : {},
@@ -54478,7 +54488,7 @@ ${toolLines}
54478
54488
 
54479
54489
  Disable or narrow capabilities:
54480
54490
  - Start from a trusted cwd.
54481
- - Use selected tools or extension policy to omit write_file, edit_file, bash, or host-specific tools.
54491
+ - Use selected tools or extension policy to omit write_file, edit_file, the shell tool, or host-specific tools.
54482
54492
  - Keep API keys in environment variables or ~/.pie/models.json, not in prompts.`;
54483
54493
  }
54484
54494
 
@@ -72295,7 +72305,7 @@ ${displayLines.map((line) => theme.fg("toolOutput", line)).join("\n")}`;
72295
72305
  ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
72296
72306
  }
72297
72307
  }
72298
- } else if (this.toolName === "bash") {
72308
+ } else if (this.toolName === "bash" || this.toolName === "shell") {
72299
72309
  const command = str(this.args?.command);
72300
72310
  const timeout = this.args?.timeout;
72301
72311
  const timeoutSuffix = timeout ? theme.fg("muted", ` (timeout ${timeout}s)`) : "";
@@ -76118,14 +76128,15 @@ function handleHotkeysCommand(host) {
76118
76128
  "",
76119
76129
  theme.fg("muted", "Editor shortcuts:"),
76120
76130
  " Enter Submit message",
76121
- " Shift+Enter New line",
76131
+ " Shift+Enter New line (if ineffective, use Ctrl+J)",
76132
+ " Ctrl+J New line (fallback)",
76122
76133
  ` ${theme.fg("dim", kb.getKeys("steer").join(" / "))} ${theme.fg("muted", "Queue steering message for the active turn")}`,
76123
76134
  ` ${theme.fg("dim", kb.getKeys("dequeue").join(" / "))} ${theme.fg("muted", "Restore queued messages")}`,
76124
76135
  " / Show slash commands",
76125
76136
  " Esc Cancel autocomplete",
76126
76137
  "",
76127
76138
  theme.fg("muted", "Direct mode:"),
76128
- " !!command Execute bash command (bypasses AI)",
76139
+ " !!command Execute a shell command (bypasses AI)",
76129
76140
  "",
76130
76141
  theme.bold(theme.fg("accent", "Slash Commands")),
76131
76142
  "",
@@ -78884,9 +78895,7 @@ function queueMessage(host, text, mode, options = {}) {
78884
78895
  const clearEditor = options.clearEditor ?? true;
78885
78896
  host.sessionTrace.notePendingUserText(text);
78886
78897
  const runtimeBlock = host.runtimeModeBlockForNextMessage?.();
78887
- const content = runtimeBlock ? `${runtimeBlock}
78888
-
78889
- ${text}` : text;
78898
+ const content = runtimeBlock ? [runtimeBlock, { type: "text", text }] : [{ type: "text", text }];
78890
78899
  void host.agentSessionController.prompt(
78891
78900
  { role: "user", content, timestamp: Date.now() },
78892
78901
  {
@@ -79274,7 +79283,11 @@ When the user asks about Pie itself, its extensions, skills, TUI, model configur
79274
79283
  function buildCliSystemPrompt(options) {
79275
79284
  const tools = options.tools.map((tool) => ({
79276
79285
  name: tool.name,
79277
- description: ""
79286
+ description: "",
79287
+ // Metadata travels with the projection: the <tools> section resolves
79288
+ // policy from tool-carried metadata first, so a renamed tool cannot
79289
+ // silently disappear from the prompt.
79290
+ capabilityMetadata: tool.capabilityMetadata
79278
79291
  }));
79279
79292
  return [
79280
79293
  options.customPrompt?.trim() || "You are Pie, a helpful AI coding assistant.",
@@ -79580,10 +79593,7 @@ function estimateMessageTokens(msg) {
79580
79593
  return estimateTokens(msg);
79581
79594
  }
79582
79595
  function buildSystemPrompt(host) {
79583
- const tools = (host.agent?.state?.tools ?? host.options.tools ?? []).filter((tool) => typeof tool.name === "string").map((tool) => ({
79584
- name: tool.name,
79585
- description: tool.description
79586
- }));
79596
+ const tools = (host.agent?.state?.tools ?? host.options.tools ?? []).filter((tool) => typeof tool.name === "string");
79587
79597
  return buildCliSystemPrompt({
79588
79598
  cwd: host.options.cwd,
79589
79599
  tools,
@@ -79593,7 +79603,7 @@ function buildSystemPrompt(host) {
79593
79603
  }
79594
79604
  function getAllToolNames(host) {
79595
79605
  if (!host.agent?.state?.tools) {
79596
- return [...CLI_FILESYSTEM_TOOL_NAMES, "bash"];
79606
+ return [...CLI_FILESYSTEM_TOOL_NAMES, "shell"];
79597
79607
  }
79598
79608
  return host.agent.state.tools.map((tool) => tool.name);
79599
79609
  }
@@ -80595,26 +80605,66 @@ function createInteractiveAgentSessionController(host) {
80595
80605
  }
80596
80606
 
80597
80607
  // src/runtime/runtime-mode-context.ts
80608
+ var RUNTIME_MODE_ENVELOPE_KIND = "pie.runtimeMode";
80609
+ var RUNTIME_MODE_ENVELOPE_VERSION = 1;
80610
+ function runtimeModeEnvelopeRegistry() {
80611
+ return sharedRuntimeModeRegistry ??= createHostEnvelopeProjectorRegistry([{
80612
+ kind: RUNTIME_MODE_ENVELOPE_KIND,
80613
+ version: RUNTIME_MODE_ENVELOPE_VERSION,
80614
+ project: (data) => buildRuntimeModeContext(runtimeModeStateFromEnvelope(data))
80615
+ }]);
80616
+ }
80617
+ var sharedRuntimeModeRegistry;
80618
+ function runtimeModeStateFromEnvelope(data) {
80619
+ return {
80620
+ planMode: data.planMode === "planning" ? "planning" : "off",
80621
+ yoloMode: data.yoloMode === true,
80622
+ filesystemScope: data.filesystemScope === "all" ? "all" : "workspace",
80623
+ pendingTransition: typeof data.pendingTransition === "string" ? data.pendingTransition : void 0,
80624
+ activeToolNames: Array.isArray(data.activeToolNames) ? data.activeToolNames.filter((name) => typeof name === "string") : [],
80625
+ planDisabledToolNames: Array.isArray(data.planDisabledToolNames) ? data.planDisabledToolNames.filter((name) => typeof name === "string") : [],
80626
+ currentDate: typeof data.currentDate === "string" ? data.currentDate : void 0,
80627
+ timeZone: typeof data.timeZone === "string" ? data.timeZone : void 0
80628
+ };
80629
+ }
80630
+ function runtimeModeEnvelopeData(state) {
80631
+ return {
80632
+ planMode: state.planMode,
80633
+ yoloMode: state.yoloMode,
80634
+ filesystemScope: state.filesystemScope,
80635
+ ...state.pendingTransition ? { pendingTransition: state.pendingTransition } : {},
80636
+ activeToolNames: [...state.activeToolNames],
80637
+ planDisabledToolNames: [...state.planDisabledToolNames],
80638
+ ...state.currentDate ? { currentDate: state.currentDate } : {},
80639
+ ...state.timeZone ? { timeZone: state.timeZone } : {}
80640
+ };
80641
+ }
80642
+ function runtimeModeEnvelopeBlock(state) {
80643
+ return {
80644
+ type: "hostContext",
80645
+ kind: RUNTIME_MODE_ENVELOPE_KIND,
80646
+ version: RUNTIME_MODE_ENVELOPE_VERSION,
80647
+ data: runtimeModeEnvelopeData(state)
80648
+ };
80649
+ }
80598
80650
  function isAgentMessage(value) {
80599
80651
  return !!value && typeof value === "object" && "role" in value;
80600
80652
  }
80601
80653
  function prependRuntimeModeBlockToPrompt(input, block) {
80602
80654
  if (!block) return input;
80603
80655
  if (typeof input === "string") {
80604
- return input.trim() ? `${block}
80605
-
80606
- ${input}` : block;
80656
+ return [{ ...block }, { type: "text", text: input }];
80607
80657
  }
80608
80658
  if (Array.isArray(input)) {
80609
80659
  if (input.length > 0 && isAgentMessage(input[0])) {
80610
80660
  return prependBlockToMessages(input, block);
80611
80661
  }
80612
- return [{ type: "text", text: block }, ...input];
80662
+ return [block, ...input];
80613
80663
  }
80614
80664
  if (isAgentMessage(input)) {
80615
80665
  return prependBlockToMessages([input], block)[0];
80616
80666
  }
80617
- return [{ type: "text", text: block }, ...input];
80667
+ return [block, ...input];
80618
80668
  }
80619
80669
  function prependBlockToMessages(messages, block) {
80620
80670
  const next = [...messages];
@@ -80626,18 +80676,16 @@ function prependBlockToMessages(messages, block) {
80626
80676
  }
80627
80677
  }
80628
80678
  if (target < 0) {
80629
- next.push({ role: "user", content: block, timestamp: Date.now() });
80679
+ next.push({ role: "user", content: [block], timestamp: Date.now() });
80630
80680
  return next;
80631
80681
  }
80632
80682
  const message = next[target];
80633
- if (typeof message.content === "string") {
80634
- next[target] = { ...message, content: `${block}
80635
-
80636
- ${message.content}` };
80637
- } else if (Array.isArray(message.content)) {
80638
- next[target] = { ...message, content: [{ type: "text", text: block }, ...message.content] };
80683
+ if (Array.isArray(message.content)) {
80684
+ next[target] = { ...message, content: [block, ...message.content] };
80685
+ } else if (typeof message.content === "string") {
80686
+ next[target] = { ...message, content: [block, { type: "text", text: message.content }] };
80639
80687
  } else {
80640
- next.splice(target, 0, { role: "user", content: block, timestamp: Date.now() });
80688
+ next.splice(target, 0, { role: "user", content: [block], timestamp: Date.now() });
80641
80689
  }
80642
80690
  return next;
80643
80691
  }
@@ -80733,62 +80781,54 @@ function stripLeadingRuntimeBlock(text) {
80733
80781
  const leading = leadingRuntimeBlock(text);
80734
80782
  return leading ? { rest: leading.rest } : null;
80735
80783
  }
80736
- function leadingRuntimeBlockOfMessage(message) {
80737
- if (message.role !== "user") return null;
80738
- const content = message.content;
80739
- if (typeof content === "string") return leadingRuntimeBlock(content)?.block ?? null;
80740
- if (!Array.isArray(content)) return null;
80741
- const first = content[0];
80742
- if (first?.type !== "text" || typeof first.text !== "string") return null;
80743
- return leadingRuntimeBlock(first.text)?.block ?? null;
80744
- }
80745
- function lastUserMessageCarriesRuntimeBlock(messages, block) {
80784
+ function lastUserMessageCarriesEnvelopeBlock(messages, block) {
80746
80785
  for (let index = messages.length - 1; index >= 0; index -= 1) {
80747
80786
  const message = messages[index];
80748
80787
  if (message?.role !== "user") continue;
80749
- return leadingRuntimeBlockOfMessage(message) === block;
80788
+ const content = message.content;
80789
+ if (!Array.isArray(content) || content.length === 0) return false;
80790
+ const first = content[0];
80791
+ return first?.type === "hostContext" && first.kind === block.kind && first.version === block.version && JSON.stringify(first.data) === JSON.stringify(block.data);
80750
80792
  }
80751
80793
  return false;
80752
80794
  }
80753
- function applyRuntimeBlockToText(text, block) {
80754
- const split = stripLeadingRuntimeBlock(text);
80755
- const rest = split ? split.rest : text;
80756
- const next = rest.length > 0 ? `${block}
80757
-
80758
- ${rest}` : block;
80759
- return next === text ? text : next;
80760
- }
80761
- function applyRuntimeBlockToContentArray(content, block) {
80762
- const first = content[0];
80763
- if (first && typeof first === "object" && first.type === "text" && typeof first.text === "string") {
80764
- const text = first.text;
80765
- if (stripLeadingRuntimeBlock(text)) {
80766
- const nextText = applyRuntimeBlockToText(text, block);
80767
- if (nextText === text) return content;
80768
- const copy = [...content];
80769
- copy[0] = { ...first, text: nextText };
80770
- return copy;
80771
- }
80772
- }
80773
- return [{ type: "text", text: block }, ...content];
80774
- }
80775
80795
  function refreshRuntimeModeBlockOnLastUserMessage(messages, block) {
80776
80796
  for (let i = messages.length - 1; i >= 0; i--) {
80777
80797
  const message = messages[i];
80778
80798
  if (message?.role !== "user") continue;
80779
80799
  const content = message.content;
80780
80800
  if (typeof content === "string") {
80781
- const next = applyRuntimeBlockToText(content, block);
80782
- if (next === content) return messages;
80801
+ const stripped = stripLeadingRuntimeBlock(content);
80802
+ const rest = stripped ? stripped.rest : content;
80803
+ if (!rest) {
80804
+ const copy2 = [...messages];
80805
+ copy2[i] = { ...message, content: [block] };
80806
+ return copy2;
80807
+ }
80783
80808
  const copy = [...messages];
80784
- copy[i] = { ...message, content: next };
80809
+ copy[i] = { ...message, content: [block, { type: "text", text: rest }] };
80785
80810
  return copy;
80786
80811
  }
80787
80812
  if (Array.isArray(content)) {
80788
- const next = applyRuntimeBlockToContentArray(content, block);
80789
- if (next === content) return messages;
80813
+ const first = content[0];
80814
+ if (first?.type === "hostContext") {
80815
+ if (first === block) return messages;
80816
+ const copy2 = [...messages];
80817
+ const contentCopy = [...content];
80818
+ contentCopy[0] = block;
80819
+ copy2[i] = { ...message, content: contentCopy };
80820
+ return copy2;
80821
+ }
80822
+ let userBlocks = content;
80823
+ const firstText = content[0];
80824
+ if (firstText?.type === "text" && typeof firstText.text === "string") {
80825
+ const stripped = stripLeadingRuntimeBlock(firstText.text);
80826
+ if (stripped) {
80827
+ userBlocks = stripped.rest ? [{ type: "text", text: stripped.rest }, ...content.slice(1)] : content.slice(1);
80828
+ }
80829
+ }
80790
80830
  const copy = [...messages];
80791
- copy[i] = { ...message, content: next };
80831
+ copy[i] = { ...message, content: [block, ...userBlocks] };
80792
80832
  return copy;
80793
80833
  }
80794
80834
  return messages;
@@ -80801,7 +80841,7 @@ var RuntimeModeBlockInjector = class {
80801
80841
  }
80802
80842
  options;
80803
80843
  lastKey = null;
80804
- /** Exact frozen block, including its consumed one-shot transition. */
80844
+ /** Exact frozen envelope block, including its consumed one-shot transition. */
80805
80845
  lastFrozenBlock = null;
80806
80846
  /**
80807
80847
  * Request-view overlay. While active, the CURRENT block is re-derived on
@@ -80828,27 +80868,27 @@ var RuntimeModeBlockInjector = class {
80828
80868
  this.overlayActive = true;
80829
80869
  }
80830
80870
  /**
80831
- * Block to prepend to the next user message, or null when unchanged. Does
80832
- * NOT end the overlay: the block is only proof once the message carrying it
80833
- * reaches the request transform.
80871
+ * Envelope block to prepend to the next user message, or null when
80872
+ * unchanged. Does NOT end the overlay: the block is only proof once the
80873
+ * message carrying it reaches the request transform.
80834
80874
  */
80835
80875
  nextBlock() {
80836
80876
  return this.freshBlock();
80837
80877
  }
80838
80878
  /**
80839
- * Current block for a request that reuses existing history (overflow retry
80840
- * after compaction, manual-compact continue, or the tool rounds that follow
80841
- * a mid-turn mode change). Returns the same block for every request until
80842
- * the latest user message itself carries that block; then the overlay is
80843
- * retired and null is returned. Derivation is per request from the given
80844
- * snapshot; no message array is cached.
80879
+ * Current envelope block for a request that reuses existing history
80880
+ * (overflow retry after compaction, manual-compact continue, or the tool
80881
+ * rounds that follow a mid-turn mode change). Returns the same block for
80882
+ * every request until the latest user message itself carries that block;
80883
+ * then the overlay is retired and null is returned. Derivation is per
80884
+ * request from the given snapshot; no message array is cached.
80845
80885
  */
80846
80886
  consumeRetryRefreshBlock(messages) {
80847
80887
  if (!this.overlayActive) return null;
80848
80888
  const state = this.options.getState();
80849
- const block = buildRuntimeModeContext(state);
80889
+ const block = runtimeModeEnvelopeBlock(state);
80850
80890
  const frozenCurrent = this.lastKey === runtimeModeBlockKey(state) ? this.lastFrozenBlock : null;
80851
- if (messages && (lastUserMessageCarriesRuntimeBlock(messages, block) || frozenCurrent !== null && lastUserMessageCarriesRuntimeBlock(messages, frozenCurrent))) {
80891
+ if (messages && (lastUserMessageCarriesEnvelopeBlock(messages, block) || frozenCurrent !== null && lastUserMessageCarriesEnvelopeBlock(messages, frozenCurrent))) {
80852
80892
  this.overlayActive = false;
80853
80893
  return null;
80854
80894
  }
@@ -80860,7 +80900,7 @@ var RuntimeModeBlockInjector = class {
80860
80900
  this.lastKey = runtimeModeBlockKey(state);
80861
80901
  if (state.pendingTransition) this.options.consumeTransition();
80862
80902
  this.options.noteTrace(state);
80863
- this.lastFrozenBlock = buildRuntimeModeContext(state);
80903
+ this.lastFrozenBlock = runtimeModeEnvelopeBlock(state);
80864
80904
  return this.lastFrozenBlock;
80865
80905
  }
80866
80906
  };
@@ -81860,7 +81900,7 @@ var InteractiveMode = class {
81860
81900
  pendingYoloModeTransition = null;
81861
81901
  executionReminder = null;
81862
81902
  pendingRuntimeGuardAdvisory = null;
81863
- /** Freezes runtime mode blocks into user messages (cache-stable history). */
81903
+ /** Freezes runtime mode envelope blocks into user messages (cache-stable history). */
81864
81904
  runtimeModeBlocks = new RuntimeModeBlockInjector({
81865
81905
  getState: () => this.getRuntimeModeState(),
81866
81906
  consumeTransition: () => this.consumeRuntimeModeTransition(),
@@ -82037,7 +82077,7 @@ var InteractiveMode = class {
82037
82077
  });
82038
82078
  rebuildSkillAwareTools(sourceTools) {
82039
82079
  const preservedTools = sourceTools.filter(
82040
- (tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name) && tool.name !== "bash"
82080
+ (tool) => !CLI_FILESYSTEM_TOOL_NAMES.includes(tool.name) && tool.name !== "bash" && tool.name !== "shell"
82041
82081
  );
82042
82082
  const bashTool = createBashTool(this.options.cwd, { isYoloMode: () => this.yoloMode, getEnv: () => computerUseOwnerEnv(this.sessionManager.getActiveSessionId() || COMPUTER_USE_STANDALONE_OWNER, String(process.pid)) });
82043
82083
  const fileSystemToolOptions = (allowlistedDirs) => ({
@@ -82092,16 +82132,13 @@ var InteractiveMode = class {
82092
82132
  resetRuntimeModeBlocks() {
82093
82133
  this.runtimeModeBlocks.reset();
82094
82134
  }
82095
- /** Runtime mode block for the next user message; frozen into it (append-only history, cache-stable prefixes). */
82135
+ /** Runtime mode envelope block for the next user message; frozen into it (append-only history, cache-stable prefixes). */
82096
82136
  runtimeModeBlockForNextMessage() {
82097
82137
  return this.runtimeModeBlocks.nextBlock();
82098
82138
  }
82099
82139
  getPendingRuntimeModeTransition() {
82100
- if (this.pendingYoloModeTransition === "enter") return "entered_yolo";
82101
- if (this.pendingYoloModeTransition === "exit") return "exited_yolo";
82102
- if (this.pendingPlanModeTransition === "enter") return "entered_plan";
82103
- if (this.pendingPlanModeTransition === "exit") return "exited_plan";
82104
- return void 0;
82140
+ const yolo = this.pendingYoloModeTransition === "enter" ? "entered_yolo" : this.pendingYoloModeTransition === "exit" ? "exited_yolo" : void 0;
82141
+ return yolo ?? (this.pendingPlanModeTransition === "enter" ? "entered_plan" : this.pendingPlanModeTransition === "exit" ? "exited_plan" : void 0);
82105
82142
  }
82106
82143
  consumeRuntimeModeTransition() {
82107
82144
  this.pendingYoloModeTransition = null;
@@ -82190,7 +82227,7 @@ var InteractiveMode = class {
82190
82227
  async init() {
82191
82228
  const activeSession = this.sessionManager.getActiveSession();
82192
82229
  this.thinkingLevel = resolveInitialThinkingLevel({ session: activeSession, settingsManager: this.options.settingsManager });
82193
- const { Agent } = await import("./chunks/src-6WK5KYWQ.js");
82230
+ const { Agent } = await import("./chunks/src-C2CBPEUY.js");
82194
82231
  this.agent = new Agent({
82195
82232
  initialState: {
82196
82233
  systemPrompt: this.buildSystemPrompt(),
@@ -82201,14 +82238,21 @@ var InteractiveMode = class {
82201
82238
  apiKey: this.options.apiKey,
82202
82239
  sessionId: activeSession?.id,
82203
82240
  streamFn: createTransportDiagnosticsStreamFn(createCacheRetentionStreamFn(this.options.streamFn, () => this.options.settingsManager.getPromptCacheRetention()), createTraceTransportSink((type, meta) => this.sessionTrace.noteRuntimeEvent(type, meta))),
82204
- transformContext: async (messages) => applyRuntimeRequestTransform(messages, {
82205
- takeAdvisory: () => {
82206
- const advisory = this.pendingRuntimeGuardAdvisory;
82207
- this.pendingRuntimeGuardAdvisory = null;
82208
- return advisory;
82209
- },
82210
- takeRetryBlock: (snapshot) => this.runtimeModeBlocks.consumeRetryRefreshBlock(snapshot)
82211
- })
82241
+ transformContext: async (messages) => {
82242
+ const structured = applyRuntimeRequestTransform(messages, {
82243
+ takeAdvisory: () => {
82244
+ const advisory = this.pendingRuntimeGuardAdvisory;
82245
+ this.pendingRuntimeGuardAdvisory = null;
82246
+ return advisory;
82247
+ },
82248
+ takeRetryBlock: (snapshot) => this.runtimeModeBlocks.consumeRetryRefreshBlock(snapshot)
82249
+ });
82250
+ return projectHostEnvelopes(
82251
+ structured,
82252
+ runtimeModeEnvelopeRegistry(),
82253
+ (outcome) => this.sessionTrace.noteRuntimeEvent(outcome.degraded ? "host_envelope_degraded" : "host_envelope_projected", outcome.audit)
82254
+ );
82255
+ }
82212
82256
  });
82213
82257
  this.agentSessionController = createInteractiveAgentSessionController(this.controllerSetupHost);
82214
82258
  this.updateTerminalTitle();
@@ -83049,7 +83093,7 @@ async function runPrintMode(params) {
83049
83093
  `);
83050
83094
  console.log("Assistant: ");
83051
83095
  }
83052
- const { Agent: AgentClass } = await import("./chunks/src-6WK5KYWQ.js");
83096
+ const { Agent: AgentClass } = await import("./chunks/src-C2CBPEUY.js");
83053
83097
  let agent;
83054
83098
  const printModeExtensions = await loadPrintModeExtensions({
83055
83099
  cwd: runtime.cwd,
@@ -83082,7 +83126,7 @@ async function runPrintMode(params) {
83082
83126
  cwd: runtime.cwd,
83083
83127
  skillsSection: runtime.skillsSection,
83084
83128
  knowledgeSection: runtime.knowledgeSection,
83085
- tools: printModeTools.map((tool) => ({ name: tool.name, description: tool.description }))
83129
+ tools: printModeTools
83086
83130
  });
83087
83131
  const printThinkingLevel = resolveInitialThinkingLevel({ session: runtime.sessionManager.getActiveSession(), settingsManager: runtime.settingsManager });
83088
83132
  agent = new AgentClass({
@@ -83905,7 +83949,7 @@ async function runJsonEventsMode(params) {
83905
83949
  return;
83906
83950
  }
83907
83951
  const parent = agent;
83908
- const { Agent: AgentClass } = await import("./chunks/src-6WK5KYWQ.js");
83952
+ const { Agent: AgentClass } = await import("./chunks/src-C2CBPEUY.js");
83909
83953
  const sideAgent = new AgentClass({
83910
83954
  initialState: {
83911
83955
  systemPrompt: parent.state.systemPrompt,
@@ -84259,7 +84303,7 @@ async function runJsonEventsMode(params) {
84259
84303
  if (runtime.initialModel.unconfigured || controller) {
84260
84304
  return;
84261
84305
  }
84262
- const { Agent: AgentClass } = await import("./chunks/src-6WK5KYWQ.js");
84306
+ const { Agent: AgentClass } = await import("./chunks/src-C2CBPEUY.js");
84263
84307
  if (runtimeClosing) return;
84264
84308
  const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
84265
84309
  if (runtimeClosing) {
@@ -84286,7 +84330,7 @@ async function runJsonEventsMode(params) {
84286
84330
  skillsSection: runtime.skillsSection,
84287
84331
  knowledgeSection: runtime.knowledgeSection,
84288
84332
  appendSystemPrompt: params.developerInstructions,
84289
- tools: tools.map((tool) => ({ name: tool.name, description: tool.description }))
84333
+ tools
84290
84334
  });
84291
84335
  agent = new AgentClass({
84292
84336
  initialState: {
@@ -84797,6 +84841,8 @@ Commands:
84797
84841
 
84798
84842
  Interactive Mode Key Bindings:
84799
84843
  Enter Submit message
84844
+ Shift+Enter New line; if ineffective, use Ctrl+J
84845
+ Ctrl+J New line (fallback)
84800
84846
  \\ + Enter New line (fallback)
84801
84847
  Alt+Enter Queue steering message for the active turn
84802
84848
  Ctrl+C Exit
@@ -84866,7 +84912,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
84866
84912
  }
84867
84913
  async function createCliTestStreamFnFromEnv() {
84868
84914
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
84869
- return (await import("./chunks/test-stream-7EH7BGY6.js")).createTestStreamFnFromSequenceEnv();
84915
+ return (await import("./chunks/test-stream-LDVUVSUP.js")).createTestStreamFnFromSequenceEnv();
84870
84916
  }
84871
84917
  function resolveJsonEventsDetailFlag() {
84872
84918
  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.6",
3
+ "version": "2.7.7",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -16,10 +16,11 @@
16
16
  "init:models": "tsx scripts/init-models-config.ts",
17
17
  "validate:models": "tsx scripts/validate-models-config.ts",
18
18
  "test": "npm run test:offline",
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
- "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-use-axi.test.ts test/computer-evidence.test.ts test/interactive-lifecycle.test.ts",
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/todo-steering-ownership.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/json-events-sidechat-diagnostics.test.ts test/json-events-prewarm-shutdown.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/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/context-report.test.ts test/context-signals.test.ts test/plan-cache-stability.test.ts test/cache-invalidation-trace.test.ts test/cache-retention.test.ts test/trace-report.test.ts test/boot-report.test.ts test/compaction-diff.test.ts test/entry-body-and-usage.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 test/interactive-compact-command.test.ts test/computer-use-broker.test.ts test/computer-use-review-regressions.test.ts test/computer-use-safety.test.ts ../../scripts/node-test-diagnostics.test.js",
19
+ "test:offline:build": "node ../../scripts/build-unity-test-deps.mjs && npm run build",
20
+ "test:skill-regressions": "node --test --import tsx test/bash-lifecycle.test.ts test/bash-powershell-display.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-use-axi.test.ts test/computer-evidence.test.ts test/interactive-lifecycle.test.ts",
21
+ "test:offline:post": "node --test --import tsx test/remote-model-catalog.test.ts",
22
+ "test:offline": "node ../../scripts/run-cli-offline.mjs",
23
+ "test:offline:main": "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/todo-steering-ownership.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/json-events-sidechat-diagnostics.test.ts test/json-events-prewarm-shutdown.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/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/context-report.test.ts test/context-signals.test.ts test/plan-cache-stability.test.ts test/cache-invalidation-trace.test.ts test/cache-retention.test.ts test/trace-report.test.ts test/boot-report.test.ts test/compaction-diff.test.ts test/entry-body-and-usage.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/host-envelope-dogfood.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-contract.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 test/interactive-compact-command.test.ts test/computer-use-broker.test.ts test/computer-use-review-regressions.test.ts test/computer-use-safety.test.ts ../../scripts/node-test-diagnostics.test.js ../../scripts/offline-test-runner.test.js",
23
24
  "test:all": "npm run test:offline && npm run test:terminal:vitest",
24
25
  "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
26
  "test:todo-tui": "node ../../scripts/run-with-env.mjs PIE_REAL_TODO_TUI=1 -- --test --import tsx test/todo-closure.terminal.test.ts",