@cydm/pie 1.0.35 → 1.0.36

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.
@@ -5,6 +5,28 @@ import {
5
5
  import "./chunk-TG2EQLX2.js";
6
6
 
7
7
  // src/app/test-stream.ts
8
+ function parseSystemPromptExpectations(value) {
9
+ if (!value) return [];
10
+ const parsed = JSON.parse(value);
11
+ const normalize = (item) => {
12
+ if (typeof item === "string") return [item];
13
+ if (Array.isArray(item) && item.every((entry) => typeof entry === "string")) return item;
14
+ throw new Error("PIE_TEST_EXPECT_SYSTEM_PROMPT_INCLUDES entries must be strings");
15
+ };
16
+ if (typeof parsed === "string" || Array.isArray(parsed) && parsed.every((entry) => typeof entry === "string")) {
17
+ return [normalize(parsed)];
18
+ }
19
+ if (!Array.isArray(parsed)) throw new Error("PIE_TEST_EXPECT_SYSTEM_PROMPT_INCLUDES must be JSON");
20
+ return parsed.map(normalize);
21
+ }
22
+ function assertSystemPromptIncludes(systemPrompt, callIndex) {
23
+ const expectations = parseSystemPromptExpectations(process.env.PIE_TEST_EXPECT_SYSTEM_PROMPT_INCLUDES);
24
+ for (const expected of expectations[Math.min(callIndex, Math.max(0, expectations.length - 1))] ?? []) {
25
+ if (!systemPrompt.includes(expected)) {
26
+ throw new Error(`Expected system prompt to include ${JSON.stringify(expected)}`);
27
+ }
28
+ }
29
+ }
8
30
  function createAssistantMessage(model, text, stopReason = "stop", errorMessage) {
9
31
  return {
10
32
  role: "assistant",
@@ -68,8 +90,9 @@ function createTestStreamFnFromSequenceEnv(value = process.env.PIE_TEST_MOCK_STR
68
90
  }
69
91
  const steps = parseMockStreamSequence(value);
70
92
  let callIndex = 0;
71
- return async (model) => {
93
+ return async (model, context) => {
72
94
  const step = steps[Math.min(callIndex, steps.length - 1)];
95
+ assertSystemPromptIncludes(context.systemPrompt, callIndex);
73
96
  callIndex += 1;
74
97
  const stream = new EventStream(
75
98
  (event) => event.type === "done" || event.type === "error",
package/dist/cli.js CHANGED
@@ -985,15 +985,15 @@ var require_route = __commonJS({
985
985
  };
986
986
  }
987
987
  function wrapConversion(toModel, graph) {
988
- const path30 = [graph[toModel].parent, toModel];
988
+ const path31 = [graph[toModel].parent, toModel];
989
989
  let fn = conversions[graph[toModel].parent][toModel];
990
990
  let cur = graph[toModel].parent;
991
991
  while (graph[cur].parent) {
992
- path30.unshift(graph[cur].parent);
992
+ path31.unshift(graph[cur].parent);
993
993
  fn = link(conversions[graph[cur].parent][cur], fn);
994
994
  cur = graph[cur].parent;
995
995
  }
996
- fn.conversion = path30;
996
+ fn.conversion = path31;
997
997
  return fn;
998
998
  }
999
999
  module.exports = function(fromModel) {
@@ -43957,11 +43957,11 @@ var require_dist = __commonJS({
43957
43957
  });
43958
43958
 
43959
43959
  // src/cli.ts
43960
- import * as fs26 from "fs";
43961
- import * as path29 from "path";
43960
+ import * as fs27 from "fs";
43961
+ import * as path30 from "path";
43962
43962
 
43963
43963
  // src/cli-args.ts
43964
- var FLAGS_WITH_VALUES = /* @__PURE__ */ new Set(["--session-id", "--extension-path"]);
43964
+ var FLAGS_WITH_VALUES = /* @__PURE__ */ new Set(["--session-id", "--extension-path", "--developer-instructions", "--developer-instructions-file"]);
43965
43965
  var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["--raw-output", "--json-output", "--json-events", "--resume-required"]);
43966
43966
  var HELP_FLAGS = /* @__PURE__ */ new Set(["help", "--help", "-h"]);
43967
43967
  var COMMANDS = /* @__PURE__ */ new Set(["chat", "help"]);
@@ -44561,7 +44561,7 @@ async function acquireRemoteRefreshLock(modelsPath) {
44561
44561
  throw lockError;
44562
44562
  }
44563
44563
  if (Date.now() >= deadline) throw new Error(`timed out waiting for remote catalog refresh lock: ${lockPath}`);
44564
- await new Promise((resolve5) => setTimeout(resolve5, 25));
44564
+ await new Promise((resolve6) => setTimeout(resolve6, 25));
44565
44565
  }
44566
44566
  }
44567
44567
  }
@@ -46881,15 +46881,15 @@ function activePathEntries(data) {
46881
46881
  }
46882
46882
  function pathToEntry(data, entryId) {
46883
46883
  const byId = new Map(data.entries.map((entry) => [entry.id, entry]));
46884
- const path30 = [];
46884
+ const path31 = [];
46885
46885
  let current = entryId;
46886
46886
  while (current) {
46887
46887
  const entry = byId.get(current);
46888
46888
  if (!entry) return [];
46889
- path30.unshift(entry);
46889
+ path31.unshift(entry);
46890
46890
  current = entry.parentId;
46891
46891
  }
46892
- return path30;
46892
+ return path31;
46893
46893
  }
46894
46894
  function resolveBeforeCursor(events, cursor) {
46895
46895
  if (!cursor) return events.length;
@@ -46952,19 +46952,19 @@ var CommandTree = class {
46952
46952
  * register(["session", "new"], { description, handler })
46953
46953
  * register(["tools", "subagent", "spawn", "local"], { description, handler })
46954
46954
  */
46955
- register(path30, info) {
46956
- if (path30.length === 0) {
46955
+ register(path31, info) {
46956
+ if (path31.length === 0) {
46957
46957
  throw new Error("Command path cannot be empty");
46958
46958
  }
46959
46959
  let current = this.root;
46960
46960
  const fullPath = [];
46961
- for (let i = 0; i < path30.length; i++) {
46962
- const segment = path30[i];
46961
+ for (let i = 0; i < path31.length; i++) {
46962
+ const segment = path31[i];
46963
46963
  fullPath.push(segment);
46964
46964
  if (!current.children) {
46965
46965
  current.children = [];
46966
46966
  }
46967
- const isLast = i === path30.length - 1;
46967
+ const isLast = i === path31.length - 1;
46968
46968
  let node = current.children.find((n) => n.name === segment);
46969
46969
  if (!node) {
46970
46970
  node = {
@@ -46994,31 +46994,31 @@ var CommandTree = class {
46994
46994
  /**
46995
46995
  * Find a node by path
46996
46996
  */
46997
- find(path30) {
46998
- if (path30.length === 0) {
46997
+ find(path31) {
46998
+ if (path31.length === 0) {
46999
46999
  return this.root;
47000
47000
  }
47001
- const key = path30.join("/");
47001
+ const key = path31.join("/");
47002
47002
  return this.pathCache.get(key) || null;
47003
47003
  }
47004
47004
  /**
47005
47005
  * Get children of a path
47006
47006
  */
47007
- getChildren(path30) {
47008
- const node = this.find(path30);
47007
+ getChildren(path31) {
47008
+ const node = this.find(path31);
47009
47009
  return (node?.children || []).filter((child) => !child.hidden);
47010
47010
  }
47011
47011
  /**
47012
47012
  * Check if a path exists (as category or command)
47013
47013
  */
47014
- exists(path30) {
47015
- return this.find(path30) !== null;
47014
+ exists(path31) {
47015
+ return this.find(path31) !== null;
47016
47016
  }
47017
47017
  /**
47018
47018
  * Check if path is a category (has children)
47019
47019
  */
47020
- isCategory(path30) {
47021
- const node = this.find(path30);
47020
+ isCategory(path31) {
47021
+ const node = this.find(path31);
47022
47022
  return node?.isCategory || false;
47023
47023
  }
47024
47024
  /**
@@ -47097,8 +47097,8 @@ var CommandTree = class {
47097
47097
  * Supports dot notation: "tools.subagent.spawn.local"
47098
47098
  */
47099
47099
  registerFromPath(pathStr, info) {
47100
- const path30 = pathStr.split(/[./]/).filter(Boolean);
47101
- this.register(path30, info);
47100
+ const path31 = pathStr.split(/[./]/).filter(Boolean);
47101
+ this.register(path31, info);
47102
47102
  }
47103
47103
  };
47104
47104
  var commandTree = new CommandTree();
@@ -54388,7 +54388,7 @@ var ProcessTerminal = class {
54388
54388
  const timeLeft = endTime - now;
54389
54389
  if (timeLeft <= 0) break;
54390
54390
  if (now - lastDataTime >= idleMs) break;
54391
- await new Promise((resolve5) => setTimeout(resolve5, Math.min(idleMs, timeLeft)));
54391
+ await new Promise((resolve6) => setTimeout(resolve6, Math.min(idleMs, timeLeft)));
54392
54392
  }
54393
54393
  } finally {
54394
54394
  process.stdin.removeListener("data", onData);
@@ -54922,10 +54922,10 @@ var KeybindingsManager = class _KeybindingsManager {
54922
54922
  static inMemory(config = {}) {
54923
54923
  return new _KeybindingsManager(config);
54924
54924
  }
54925
- static loadFromFile(path30) {
54926
- if (!existsSync7(path30)) return {};
54925
+ static loadFromFile(path31) {
54926
+ if (!existsSync7(path31)) return {};
54927
54927
  try {
54928
- return JSON.parse(readFileSync6(path30, "utf-8"));
54928
+ return JSON.parse(readFileSync6(path31, "utf-8"));
54929
54929
  } catch {
54930
54930
  return {};
54931
54931
  }
@@ -57635,11 +57635,11 @@ var FileCache = class _FileCache {
57635
57635
  // Hash Computation
57636
57636
  // ============================================================================
57637
57637
  async computeHash(filePath) {
57638
- return new Promise((resolve5, reject) => {
57638
+ return new Promise((resolve6, reject) => {
57639
57639
  const hash = crypto.createHash("sha256");
57640
57640
  const stream = fs16.createReadStream(filePath);
57641
57641
  stream.on("data", (chunk) => hash.update(chunk));
57642
- stream.on("end", () => resolve5(hash.digest("hex")));
57642
+ stream.on("end", () => resolve6(hash.digest("hex")));
57643
57643
  stream.on("error", reject);
57644
57644
  });
57645
57645
  }
@@ -58349,17 +58349,17 @@ var FFmpegProcessor = class {
58349
58349
  // Detection
58350
58350
  // ============================================================================
58351
58351
  async checkAvailability() {
58352
- return new Promise((resolve5) => {
58352
+ return new Promise((resolve6) => {
58353
58353
  const proc = spawn(this.ffmpegPath, ["-version"]);
58354
- proc.on("error", () => resolve5(false));
58355
- proc.on("exit", (code) => resolve5(code === 0));
58354
+ proc.on("error", () => resolve6(false));
58355
+ proc.on("exit", (code) => resolve6(code === 0));
58356
58356
  });
58357
58357
  }
58358
58358
  // ============================================================================
58359
58359
  // Video Analysis
58360
58360
  // ============================================================================
58361
58361
  async analyzeVideo(videoPath) {
58362
- return new Promise((resolve5, reject) => {
58362
+ return new Promise((resolve6, reject) => {
58363
58363
  const args = [
58364
58364
  "-v",
58365
58365
  "error",
@@ -58388,7 +58388,7 @@ var FFmpegProcessor = class {
58388
58388
  }
58389
58389
  try {
58390
58390
  const info = this.parseProbeOutput(stdout, videoPath);
58391
- resolve5(info);
58391
+ resolve6(info);
58392
58392
  } catch (err) {
58393
58393
  reject(err);
58394
58394
  }
@@ -58583,7 +58583,7 @@ var FFmpegProcessor = class {
58583
58583
  // FFmpeg Execution
58584
58584
  // ============================================================================
58585
58585
  runFFmpeg(args) {
58586
- return new Promise((resolve5, reject) => {
58586
+ return new Promise((resolve6, reject) => {
58587
58587
  const proc = spawn(this.ffmpegPath, args);
58588
58588
  let stderr = "";
58589
58589
  proc.stderr.on("data", (data) => {
@@ -58598,7 +58598,7 @@ var FFmpegProcessor = class {
58598
58598
  )
58599
58599
  );
58600
58600
  } else {
58601
- resolve5();
58601
+ resolve6();
58602
58602
  }
58603
58603
  });
58604
58604
  proc.on("error", (err) => {
@@ -58615,7 +58615,7 @@ var FFmpegProcessor = class {
58615
58615
  // Progress Monitoring (for future use)
58616
58616
  // ============================================================================
58617
58617
  async runWithProgress(args, onProgress) {
58618
- return new Promise((resolve5, reject) => {
58618
+ return new Promise((resolve6, reject) => {
58619
58619
  const progressArgs = [
58620
58620
  ...args,
58621
58621
  "-progress",
@@ -58645,7 +58645,7 @@ var FFmpegProcessor = class {
58645
58645
  )
58646
58646
  );
58647
58647
  } else {
58648
- resolve5();
58648
+ resolve6();
58649
58649
  }
58650
58650
  });
58651
58651
  });
@@ -59635,7 +59635,7 @@ async function waitForReady(params) {
59635
59635
  if (status.status === "error" || status.status === "expired") {
59636
59636
  throw new Error(`Uploaded file is not ready: ${status.status}${status.error ? ` (${status.error})` : ""}`);
59637
59637
  }
59638
- await new Promise((resolve5) => setTimeout(resolve5, 1500));
59638
+ await new Promise((resolve6) => setTimeout(resolve6, 1500));
59639
59639
  }
59640
59640
  throw new Error("Timed out waiting for uploaded file to become ready");
59641
59641
  }
@@ -59731,8 +59731,8 @@ function createIsolatedRegexSession(pattern, ignoreCase) {
59731
59731
  let initError;
59732
59732
  let readyResolve;
59733
59733
  let readyReject;
59734
- const ready = new Promise((resolve5, reject) => {
59735
- readyResolve = resolve5;
59734
+ const ready = new Promise((resolve6, reject) => {
59735
+ readyResolve = resolve6;
59736
59736
  readyReject = reject;
59737
59737
  });
59738
59738
  void ready.catch(() => void 0);
@@ -59754,7 +59754,7 @@ function createIsolatedRegexSession(pattern, ignoreCase) {
59754
59754
  if (initError) throw initError;
59755
59755
  if (signal?.aborted) throw new Error("Operation aborted");
59756
59756
  const id = nextId++;
59757
- return new Promise((resolve5, reject) => {
59757
+ return new Promise((resolve6, reject) => {
59758
59758
  let settled = false;
59759
59759
  const finish = (error, matches) => {
59760
59760
  if (settled) return;
@@ -59764,7 +59764,7 @@ function createIsolatedRegexSession(pattern, ignoreCase) {
59764
59764
  worker.off("message", onMessage);
59765
59765
  worker.off("error", onWorkerError);
59766
59766
  if (error) reject(error);
59767
- else resolve5(matches ?? []);
59767
+ else resolve6(matches ?? []);
59768
59768
  };
59769
59769
  const terminate = (error) => {
59770
59770
  disposed = true;
@@ -60992,7 +60992,7 @@ async function handleCacheTest(host) {
60992
60992
  host.chatContainer.addChild(new Text(theme.fg("dim", ` ${summarizeUsage(result1.usage)}`), 1, 0));
60993
60993
  host.chatContainer.addChild(new Text(theme.fg("dim", " Waiting 2s before replaying identical request..."), 1, 0));
60994
60994
  host.ui.requestRender();
60995
- await new Promise((resolve5) => setTimeout(resolve5, 2e3));
60995
+ await new Promise((resolve6) => setTimeout(resolve6, 2e3));
60996
60996
  host.chatContainer.addChild(new Text(theme.fg("accent", "Request 2/2: replaying identical request..."), 1, 0));
60997
60997
  host.ui.requestRender();
60998
60998
  result2 = await completeSimple(model, context, options);
@@ -61982,16 +61982,16 @@ var Diff = class {
61982
61982
  }
61983
61983
  }
61984
61984
  }
61985
- addToPath(path30, added, removed, oldPosInc, options) {
61986
- const last = path30.lastComponent;
61985
+ addToPath(path31, added, removed, oldPosInc, options) {
61986
+ const last = path31.lastComponent;
61987
61987
  if (last && !options.oneChangePerToken && last.added === added && last.removed === removed) {
61988
61988
  return {
61989
- oldPos: path30.oldPos + oldPosInc,
61989
+ oldPos: path31.oldPos + oldPosInc,
61990
61990
  lastComponent: { count: last.count + 1, added, removed, previousComponent: last.previousComponent }
61991
61991
  };
61992
61992
  } else {
61993
61993
  return {
61994
- oldPos: path30.oldPos + oldPosInc,
61994
+ oldPos: path31.oldPos + oldPosInc,
61995
61995
  lastComponent: { count: 1, added, removed, previousComponent: last }
61996
61996
  };
61997
61997
  }
@@ -62439,13 +62439,13 @@ function formatSize2(bytes) {
62439
62439
  }
62440
62440
  var DEFAULT_MAX_BYTES = 102400;
62441
62441
  var DEFAULT_MAX_LINES = 100;
62442
- function shortenPath(path30) {
62443
- if (typeof path30 !== "string") return "";
62442
+ function shortenPath(path31) {
62443
+ if (typeof path31 !== "string") return "";
62444
62444
  const home = os4.homedir();
62445
- if (path30.startsWith(home)) {
62446
- return `~${path30.slice(home.length)}`;
62445
+ if (path31.startsWith(home)) {
62446
+ return `~${path31.slice(home.length)}`;
62447
62447
  }
62448
- return path30;
62448
+ return path31;
62449
62449
  }
62450
62450
  function replaceTabs(text) {
62451
62451
  return text.replace(/\t/g, " ");
@@ -62526,14 +62526,14 @@ ${renderManageTodoListResult(this.result, { expanded: this.expanded }, theme)}`;
62526
62526
  }
62527
62527
  } else if (this.toolName === "read_file") {
62528
62528
  const rawPath = str(this.args?.file_path ?? this.args?.path);
62529
- const path30 = rawPath !== null ? shortenPath(rawPath) : null;
62529
+ const path31 = rawPath !== null ? shortenPath(rawPath) : null;
62530
62530
  const offset = typeof this.args?.offset === "number" ? this.args.offset : void 0;
62531
62531
  const limit = typeof this.args?.limit === "number" ? this.args.limit : void 0;
62532
62532
  let pathDisplay;
62533
- if (path30 === null) {
62533
+ if (path31 === null) {
62534
62534
  pathDisplay = invalidArg;
62535
- } else if (path30) {
62536
- pathDisplay = theme.fg("accent", path30);
62535
+ } else if (path31) {
62536
+ pathDisplay = theme.fg("accent", path31);
62537
62537
  } else {
62538
62538
  const partialPath = partialStr(this.args?.file_path ?? this.args?.path);
62539
62539
  pathDisplay = theme.fg("toolOutput", partialPath);
@@ -62580,12 +62580,12 @@ ${renderManageTodoListResult(this.result, { expanded: this.expanded }, theme)}`;
62580
62580
  } else if (this.toolName === "write_file") {
62581
62581
  const rawPath = str(this.args?.file_path ?? this.args?.path);
62582
62582
  const fileContent = str(this.args?.content);
62583
- const path30 = rawPath !== null ? shortenPath(rawPath) : null;
62583
+ const path31 = rawPath !== null ? shortenPath(rawPath) : null;
62584
62584
  let pathDisplay;
62585
- if (path30 === null) {
62585
+ if (path31 === null) {
62586
62586
  pathDisplay = invalidArg;
62587
- } else if (path30) {
62588
- pathDisplay = theme.fg("accent", path30);
62587
+ } else if (path31) {
62588
+ pathDisplay = theme.fg("accent", path31);
62589
62589
  } else {
62590
62590
  const partialPath = partialStr(this.args?.file_path ?? this.args?.path);
62591
62591
  pathDisplay = theme.fg("toolOutput", partialPath);
@@ -62622,12 +62622,12 @@ ${theme.fg("error", errorText)}`;
62622
62622
  }
62623
62623
  } else if (this.toolName === "edit_file") {
62624
62624
  const rawPath = str(this.args?.file_path ?? this.args?.path);
62625
- const path30 = rawPath !== null ? shortenPath(rawPath) : null;
62625
+ const path31 = rawPath !== null ? shortenPath(rawPath) : null;
62626
62626
  let pathDisplay;
62627
- if (path30 === null) {
62627
+ if (path31 === null) {
62628
62628
  pathDisplay = invalidArg;
62629
- } else if (path30) {
62630
- pathDisplay = theme.fg("accent", path30);
62629
+ } else if (path31) {
62630
+ pathDisplay = theme.fg("accent", path31);
62631
62631
  } else {
62632
62632
  const partialPath = partialStr(this.args?.file_path ?? this.args?.path);
62633
62633
  pathDisplay = theme.fg("toolOutput", partialPath);
@@ -62652,7 +62652,7 @@ ${theme.fg("error", errorText)}`;
62652
62652
  const diff = this.result.details.diff;
62653
62653
  const firstChangedLine = this.result.details.firstChangedLine;
62654
62654
  if (firstChangedLine) {
62655
- text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent", path30 || rawPath)}${theme.fg("warning", `:${firstChangedLine}`)}`;
62655
+ text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent", path31 || rawPath)}${theme.fg("warning", `:${firstChangedLine}`)}`;
62656
62656
  }
62657
62657
  const lines = diff.split("\n");
62658
62658
  const maxLines = this.expanded ? lines.length : 15;
@@ -62672,7 +62672,7 @@ ${theme.fg("error", errorText)}`;
62672
62672
  const diff = generateEditDiff(oldText, newText, rawPath);
62673
62673
  const firstChangedLine = findFirstChangedLine(oldText, newText);
62674
62674
  if (firstChangedLine) {
62675
- text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent", path30 || rawPath)}${theme.fg("warning", `:${firstChangedLine}`)}`;
62675
+ text = `${theme.fg("toolTitle", theme.bold("edit_file"))} ${theme.fg("accent", path31 || rawPath)}${theme.fg("warning", `:${firstChangedLine}`)}`;
62676
62676
  }
62677
62677
  const lines = diff.split("\n");
62678
62678
  const maxLines = this.expanded ? lines.length : 15;
@@ -62691,9 +62691,9 @@ ${theme.fg("error", errorText)}`;
62691
62691
  }
62692
62692
  } else if (this.toolName === "list_dir") {
62693
62693
  const rawPath = str(this.args?.path);
62694
- const path30 = rawPath !== null ? shortenPath(rawPath || ".") : null;
62694
+ const path31 = rawPath !== null ? shortenPath(rawPath || ".") : null;
62695
62695
  const limit = this.args?.limit;
62696
- text = `${theme.fg("toolTitle", theme.bold("list_dir"))} ${path30 === null ? invalidArg : theme.fg("accent", path30)}`;
62696
+ text = `${theme.fg("toolTitle", theme.bold("list_dir"))} ${path31 === null ? invalidArg : theme.fg("accent", path31)}`;
62697
62697
  if (limit !== void 0) {
62698
62698
  text += theme.fg("toolOutput", ` (limit ${limit})`);
62699
62699
  }
@@ -62729,9 +62729,9 @@ ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
62729
62729
  } else if (this.toolName === "find_files") {
62730
62730
  const pattern = str(this.args?.pattern);
62731
62731
  const rawPath = str(this.args?.path);
62732
- const path30 = rawPath !== null ? shortenPath(rawPath || ".") : null;
62732
+ const path31 = rawPath !== null ? shortenPath(rawPath || ".") : null;
62733
62733
  const limit = this.args?.limit;
62734
- text = theme.fg("toolTitle", theme.bold("find_files")) + " " + (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) + theme.fg("toolOutput", ` in ${path30 === null ? invalidArg : path30}`);
62734
+ text = theme.fg("toolTitle", theme.bold("find_files")) + " " + (pattern === null ? invalidArg : theme.fg("accent", pattern || "")) + theme.fg("toolOutput", ` in ${path31 === null ? invalidArg : path31}`);
62735
62735
  if (limit !== void 0) {
62736
62736
  text += theme.fg("toolOutput", ` (limit ${limit})`);
62737
62737
  }
@@ -62767,10 +62767,10 @@ ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
62767
62767
  } else if (this.toolName === "grep_text") {
62768
62768
  const pattern = str(this.args?.pattern);
62769
62769
  const rawPath = str(this.args?.path);
62770
- const path30 = rawPath !== null ? shortenPath(rawPath || ".") : null;
62770
+ const path31 = rawPath !== null ? shortenPath(rawPath || ".") : null;
62771
62771
  const glob = str(this.args?.glob);
62772
62772
  const limit = this.args?.limit;
62773
- text = theme.fg("toolTitle", theme.bold("grep_text")) + " " + (pattern === null ? invalidArg : theme.fg("accent", `/${pattern || ""}/`)) + theme.fg("toolOutput", ` in ${path30 === null ? invalidArg : path30}`);
62773
+ text = theme.fg("toolTitle", theme.bold("grep_text")) + " " + (pattern === null ? invalidArg : theme.fg("accent", `/${pattern || ""}/`)) + theme.fg("toolOutput", ` in ${path31 === null ? invalidArg : path31}`);
62774
62774
  if (glob) {
62775
62775
  text += theme.fg("toolOutput", ` (${glob})`);
62776
62776
  }
@@ -63224,8 +63224,8 @@ async function forkAtEntry(host, entryId) {
63224
63224
  host.showError("Failed to branch at entry");
63225
63225
  return;
63226
63226
  }
63227
- const path30 = host.sessionManager.getPathToEntry(entryId);
63228
- const pathNames = path30.map((e) => e.message?.role || "entry").join(" \u2192 ");
63227
+ const path31 = host.sessionManager.getPathToEntry(entryId);
63228
+ const pathNames = path31.map((e) => e.message?.role || "entry").join(" \u2192 ");
63229
63229
  const messages = host.sessionManager.getMessages();
63230
63230
  host.syncAgentFromActiveSession(messages);
63231
63231
  await host.syncSessionScopedState(messages);
@@ -63238,7 +63238,7 @@ async function forkAtEntry(host, entryId) {
63238
63238
  host.updatePendingMessagesDisplay();
63239
63239
  host.renderMessageHistory(messages);
63240
63240
  await host.sessionManager.save();
63241
- host.showStatus(`Branched at: ${pathNames} (${path30.length} messages). Continue to add to this branch.`);
63241
+ host.showStatus(`Branched at: ${pathNames} (${path31.length} messages). Continue to add to this branch.`);
63242
63242
  } catch (error) {
63243
63243
  host.showError(
63244
63244
  `Failed to branch: ${error instanceof Error ? error.message : String(error)}`
@@ -63266,10 +63266,10 @@ async function navigateToEntry(host, entryId) {
63266
63266
  host.sessionManager.save().catch((err) => {
63267
63267
  console.error("[Session] Save after navigation failed:", err);
63268
63268
  });
63269
- const path30 = host.sessionManager.getPathToEntry(entryId);
63269
+ const path31 = host.sessionManager.getPathToEntry(entryId);
63270
63270
  const entry = host.sessionManager.getEntry(entryId);
63271
63271
  const role = entry?.message?.role || "entry";
63272
- host.showStatus(`Switched to branch: ${role} (${path30.length} messages in path)`);
63272
+ host.showStatus(`Switched to branch: ${role} (${path31.length} messages in path)`);
63273
63273
  } catch (error) {
63274
63274
  host.showError(
63275
63275
  `Failed to navigate: ${error instanceof Error ? error.message : String(error)}`
@@ -65059,7 +65059,7 @@ function setupInteractiveEditorSubmitHandler(host) {
65059
65059
  host.chatContainer.addChild(userMsg);
65060
65060
  host.editor.setText("");
65061
65061
  host.ui.requestRender();
65062
- await new Promise((resolve5) => setImmediate(resolve5));
65062
+ await new Promise((resolve6) => setImmediate(resolve6));
65063
65063
  let finalContent = messageContent;
65064
65064
  const reminderPrefix = host.executionReminder;
65065
65065
  const combinedPrefix = [reminderPrefix].filter((value) => Boolean(value)).join("");
@@ -67713,11 +67713,11 @@ var HierarchicalSelectorComponent = class extends Container {
67713
67713
  // src/runtime/interactive-ui-helpers.ts
67714
67714
  function showHierarchicalMenu(host, initialPath = []) {
67715
67715
  const basePath = [...initialPath];
67716
- const showAtPath = (path30) => {
67716
+ const showAtPath = (path31) => {
67717
67717
  host.showSelector((done) => {
67718
67718
  const selector = new HierarchicalSelectorComponent({
67719
67719
  tree: commandTree,
67720
- path: path30,
67720
+ path: path31,
67721
67721
  basePath,
67722
67722
  onNavigate: (newPath) => {
67723
67723
  done();
@@ -67725,7 +67725,7 @@ function showHierarchicalMenu(host, initialPath = []) {
67725
67725
  },
67726
67726
  onSelect: async (selectedPath, node, searchArgs) => {
67727
67727
  if (node.handler) {
67728
- const args = searchArgs || (selectedPath.length > path30.length ? selectedPath.slice(path30.length).join(" ") : void 0);
67728
+ const args = searchArgs || (selectedPath.length > path31.length ? selectedPath.slice(path31.length).join(" ") : void 0);
67729
67729
  const commandPath = "/" + selectedPath.join("/");
67730
67730
  if (!args && host.isInteractiveCommand(commandPath)) {
67731
67731
  done();
@@ -68404,7 +68404,7 @@ async function handleDirectBash(host, command) {
68404
68404
  child.stderr.on("data", (data) => {
68405
68405
  output.append(data.toString());
68406
68406
  });
68407
- return new Promise((resolve5) => {
68407
+ return new Promise((resolve6) => {
68408
68408
  let settled = false;
68409
68409
  const finish = (code) => {
68410
68410
  if (settled) return;
@@ -68417,7 +68417,7 @@ async function handleDirectBash(host, command) {
68417
68417
  }
68418
68418
  host.chatContainer.addChild(new Spacer(1));
68419
68419
  host.ui.requestRender();
68420
- resolve5();
68420
+ resolve6();
68421
68421
  };
68422
68422
  child.on("error", (error) => {
68423
68423
  output.append(error.message);
@@ -68460,11 +68460,11 @@ function installInteractiveInteractionHandler(host) {
68460
68460
  if (!("timeoutMs" in request) || !request.timeoutMs || request.timeoutMs <= 0) {
68461
68461
  return { value: await promise, timedOut: false };
68462
68462
  }
68463
- return await new Promise((resolve5, reject) => {
68464
- const timer = setTimeout(() => resolve5({ timedOut: true }), request.timeoutMs);
68463
+ return await new Promise((resolve6, reject) => {
68464
+ const timer = setTimeout(() => resolve6({ timedOut: true }), request.timeoutMs);
68465
68465
  promise.then((value) => {
68466
68466
  clearTimeout(timer);
68467
- resolve5({ value, timedOut: false });
68467
+ resolve6({ value, timedOut: false });
68468
68468
  }).catch((error) => {
68469
68469
  clearTimeout(timer);
68470
68470
  reject(error);
@@ -68564,15 +68564,15 @@ function showExtensionNotification(host, message, type = "info") {
68564
68564
  host.ui.requestRender();
68565
68565
  }
68566
68566
  function showExtensionSelector2(host, title, options, opts) {
68567
- return new Promise((resolve5) => {
68567
+ return new Promise((resolve6) => {
68568
68568
  host.showStatus(`Waiting for selection: ${title}`);
68569
68569
  if (opts?.signal?.aborted) {
68570
- resolve5(void 0);
68570
+ resolve6(void 0);
68571
68571
  return;
68572
68572
  }
68573
68573
  const onAbort = () => {
68574
68574
  host.restoreEditor();
68575
- resolve5(void 0);
68575
+ resolve6(void 0);
68576
68576
  };
68577
68577
  opts?.signal?.addEventListener("abort", onAbort, { once: true });
68578
68578
  const selector = new ExtensionSelectorComponent(
@@ -68581,12 +68581,12 @@ function showExtensionSelector2(host, title, options, opts) {
68581
68581
  (option) => {
68582
68582
  opts?.signal?.removeEventListener("abort", onAbort);
68583
68583
  host.restoreEditor();
68584
- resolve5(option);
68584
+ resolve6(option);
68585
68585
  },
68586
68586
  () => {
68587
68587
  opts?.signal?.removeEventListener("abort", onAbort);
68588
68588
  host.restoreEditor();
68589
- resolve5(void 0);
68589
+ resolve6(void 0);
68590
68590
  }
68591
68591
  );
68592
68592
  host.editorContainer.clear();
@@ -68602,15 +68602,15 @@ ${message}`, ["Yes", "No"], opts);
68602
68602
  return result === "Yes";
68603
68603
  }
68604
68604
  function showExtensionInput(host, title, placeholder, opts) {
68605
- return new Promise((resolve5) => {
68605
+ return new Promise((resolve6) => {
68606
68606
  host.showStatus(`Waiting for input: ${title}`);
68607
68607
  if (opts?.signal?.aborted) {
68608
- resolve5(void 0);
68608
+ resolve6(void 0);
68609
68609
  return;
68610
68610
  }
68611
68611
  const onAbort = () => {
68612
68612
  host.restoreEditor();
68613
- resolve5(void 0);
68613
+ resolve6(void 0);
68614
68614
  };
68615
68615
  opts?.signal?.addEventListener("abort", onAbort, { once: true });
68616
68616
  const input = new ExtensionInputComponent(
@@ -68619,12 +68619,12 @@ function showExtensionInput(host, title, placeholder, opts) {
68619
68619
  (value) => {
68620
68620
  opts?.signal?.removeEventListener("abort", onAbort);
68621
68621
  host.restoreEditor();
68622
- resolve5(value);
68622
+ resolve6(value);
68623
68623
  },
68624
68624
  () => {
68625
68625
  opts?.signal?.removeEventListener("abort", onAbort);
68626
68626
  host.restoreEditor();
68627
- resolve5(void 0);
68627
+ resolve6(void 0);
68628
68628
  }
68629
68629
  );
68630
68630
  host.editorContainer.clear();
@@ -68635,7 +68635,7 @@ function showExtensionInput(host, title, placeholder, opts) {
68635
68635
  });
68636
68636
  }
68637
68637
  function showExtensionEditor(host, title, prefill) {
68638
- return new Promise((resolve5) => {
68638
+ return new Promise((resolve6) => {
68639
68639
  host.showStatus(`Waiting for input: ${title}`);
68640
68640
  const container = new Container();
68641
68641
  container.addChild(new Text(theme.bold(theme.fg("accent", title)), 0, 0));
@@ -68657,12 +68657,12 @@ function showExtensionEditor(host, title, prefill) {
68657
68657
  preview: value.slice(0, 120)
68658
68658
  });
68659
68659
  host.restoreEditor();
68660
- resolve5(value);
68660
+ resolve6(value);
68661
68661
  };
68662
68662
  editor.onEscape = () => {
68663
68663
  host.logDebug("extension:editor:cancel", { title });
68664
68664
  host.restoreEditor();
68665
- resolve5(void 0);
68665
+ resolve6(void 0);
68666
68666
  };
68667
68667
  container.addChild(editor);
68668
68668
  container.addChild(new Spacer(1));
@@ -68676,14 +68676,14 @@ function showExtensionEditor(host, title, prefill) {
68676
68676
  }
68677
68677
  function showExtensionCustom(host, factory, options) {
68678
68678
  const savedText = host.editor.getText();
68679
- return new Promise((resolve5, reject) => {
68679
+ return new Promise((resolve6, reject) => {
68680
68680
  let closed = false;
68681
68681
  const close = (result) => {
68682
68682
  if (closed) return;
68683
68683
  closed = true;
68684
68684
  host.restoreEditor();
68685
68685
  host.editor.setText(savedText);
68686
- resolve5(result);
68686
+ resolve6(result);
68687
68687
  };
68688
68688
  Promise.resolve(factory(host.ui, theme, close)).then((component) => {
68689
68689
  if (closed) return;
@@ -68895,8 +68895,8 @@ async function loadInteractiveExtensions(host) {
68895
68895
  );
68896
68896
  host.extensionRunner.setUIContext(host.extensionUIContext);
68897
68897
  if (process.env.PIE_VERBOSE) {
68898
- for (const { path: path30, error } of errors) {
68899
- console.error(`[Extension] Failed to load ${path30}: ${error}`);
68898
+ for (const { path: path31, error } of errors) {
68899
+ console.error(`[Extension] Failed to load ${path31}: ${error}`);
68900
68900
  }
68901
68901
  }
68902
68902
  const extensionTools = convertExtensionTools(extensions);
@@ -70396,7 +70396,7 @@ async function runJsonEventsMode(params) {
70396
70396
  return typeof message.sessionId === "string" && message.sessionId !== sessionId;
70397
70397
  }
70398
70398
  function delay(ms) {
70399
- return new Promise((resolve5) => setTimeout(resolve5, Math.max(0, ms)));
70399
+ return new Promise((resolve6) => setTimeout(resolve6, Math.max(0, ms)));
70400
70400
  }
70401
70401
  async function waitForActiveController(timeoutMs = 1e3) {
70402
70402
  const deadline = Date.now() + timeoutMs;
@@ -70783,6 +70783,7 @@ async function runJsonEventsMode(params) {
70783
70783
  cwd: runtime.cwd,
70784
70784
  skillsSection: runtime.skillsSection,
70785
70785
  knowledgeSection: runtime.knowledgeSection,
70786
+ appendSystemPrompt: params.developerInstructions,
70786
70787
  tools: tools.map((tool) => ({ name: tool.name, description: tool.description }))
70787
70788
  });
70788
70789
  agent = new AgentClass({
@@ -71189,20 +71190,44 @@ async function runJsonEventsMode(params) {
71189
71190
  await disposeRuntime();
71190
71191
  }
71191
71192
 
71192
- // src/cli.ts
71193
- enableEarlyLogBuffer();
71194
- var logError = (msg, err) => {
71195
- const logPath = getRuntimeLogPath();
71196
- const timestamp = (/* @__PURE__ */ new Date()).toISOString();
71197
- const stack = err instanceof Error ? err.stack || "" : "";
71198
- fs26.mkdirSync(path29.dirname(logPath), { recursive: true });
71199
- fs26.appendFileSync(logPath, `[${timestamp}] ${msg}
71200
- ${stack}
71193
+ // src/developer-instructions.ts
71194
+ import * as fs26 from "fs";
71195
+ import * as path29 from "path";
71196
+ var MAX_DEVELOPER_INSTRUCTIONS_CHARS = 64e3;
71197
+ function readTextFileBounded(filePath) {
71198
+ const resolved = path29.resolve(filePath);
71199
+ const stat2 = fs26.statSync(resolved);
71200
+ if (!stat2.isFile()) {
71201
+ throw new Error(`Developer instructions file is not a regular file: ${filePath}`);
71202
+ }
71203
+ if (stat2.size > MAX_DEVELOPER_INSTRUCTIONS_CHARS * 4) {
71204
+ throw new Error(`Developer instructions file is too large: ${filePath}`);
71205
+ }
71206
+ return fs26.readFileSync(resolved, "utf8");
71207
+ }
71208
+ function collectFlagValues(args, flag) {
71209
+ const values = [];
71210
+ for (let i = 0; i < args.length; i += 1) {
71211
+ if (args[i] === flag && args[i + 1]) {
71212
+ values.push(args[i + 1]);
71213
+ i += 1;
71214
+ }
71215
+ }
71216
+ return values;
71217
+ }
71218
+ function resolveDeveloperInstructionsFromArgs(args) {
71219
+ const direct = collectFlagValues(args, "--developer-instructions");
71220
+ const files = collectFlagValues(args, "--developer-instructions-file").map(readTextFileBounded);
71221
+ const parts = [...direct, ...files].map((part) => part.trim()).filter(Boolean);
71222
+ if (parts.length === 0) return void 0;
71223
+ const combined = parts.join("\n\n");
71224
+ if (combined.length > MAX_DEVELOPER_INSTRUCTIONS_CHARS) {
71225
+ throw new Error(`Developer instructions exceed ${MAX_DEVELOPER_INSTRUCTIONS_CHARS} characters`);
71226
+ }
71227
+ return combined;
71228
+ }
71201
71229
 
71202
- `);
71203
- };
71204
- setupGlobalErrorHandlers(logError);
71205
- migrateConfigFromAgentDir();
71230
+ // src/cli-help.ts
71206
71231
  function showHelp() {
71207
71232
  console.log(`
71208
71233
  Pie AI Agent CLI
@@ -71242,11 +71267,36 @@ Print Mode Options:
71242
71267
  --json-events Run JSONL protocol mode over stdin/stdout
71243
71268
  --session-id Reuse or create a specific session in non-interactive mode
71244
71269
  --resume-required In JSON-events mode, fail if --session-id cannot be resumed
71270
+ --developer-instructions <text> Append stable host/developer instructions in JSON-events mode
71271
+ --developer-instructions-file <path> Read stable host/developer instructions from a file
71245
71272
  --extension-path Add an extra extension search directory (repeatable)
71246
71273
  --no-builtin-extensions Skip built-in extensions (keep user/project ones)
71247
71274
  --no-extensions Skip all discovered extensions (keeps --extension-path)
71248
71275
  `);
71249
71276
  }
71277
+
71278
+ // src/cli.ts
71279
+ enableEarlyLogBuffer();
71280
+ var logError = (msg, err) => {
71281
+ const logPath = getRuntimeLogPath();
71282
+ const timestamp = (/* @__PURE__ */ new Date()).toISOString();
71283
+ const stack = err instanceof Error ? err.stack || "" : "";
71284
+ fs27.mkdirSync(path30.dirname(logPath), { recursive: true });
71285
+ fs27.appendFileSync(logPath, `[${timestamp}] ${msg}
71286
+ ${stack}
71287
+
71288
+ `);
71289
+ };
71290
+ setupGlobalErrorHandlers(logError);
71291
+ migrateConfigFromAgentDir();
71292
+ var STABLE_CLI_COMMANDS = {
71293
+ chat: "chat",
71294
+ doctor: "doctor",
71295
+ models: "models",
71296
+ sessions: "sessions",
71297
+ extensions: "extensions",
71298
+ permissions: "permissions"
71299
+ };
71250
71300
  async function runDoctorCommand(args) {
71251
71301
  const json = args.includes("--json");
71252
71302
  const report = await runDoctor();
@@ -71339,7 +71389,7 @@ async function runWithJsonEventsConsoleIsolation(fn) {
71339
71389
  }
71340
71390
  async function createCliTestStreamFnFromEnv() {
71341
71391
  if (!process.env.PIE_TEST_MOCK_STREAM_SEQUENCE) return void 0;
71342
- return (await import("./chunks/test-stream-A7JSM2UM.js")).createTestStreamFnFromSequenceEnv();
71392
+ return (await import("./chunks/test-stream-L4PUYWQQ.js")).createTestStreamFnFromSequenceEnv();
71343
71393
  }
71344
71394
  async function startChat(initialPrompt, testCommand) {
71345
71395
  const rawOutput = process.argv.includes("--raw-output");
@@ -71351,11 +71401,19 @@ async function startChat(initialPrompt, testCommand) {
71351
71401
  const extensionPaths = parseRepeatedFlag(process.argv, "--extension-path");
71352
71402
  const extensionFlags = parseExtensionFlags(process.argv);
71353
71403
  if (jsonEvents) {
71404
+ let developerInstructions;
71405
+ try {
71406
+ developerInstructions = resolveDeveloperInstructionsFromArgs(process.argv);
71407
+ } catch (error) {
71408
+ console.error(error instanceof Error ? `Error: ${error.message}` : String(error));
71409
+ process.exit(1);
71410
+ }
71354
71411
  await runWithJsonEventsConsoleIsolation(async () => {
71355
71412
  if (process.env.PIE_TEST_MOCK_RESPONSE !== void 0) {
71356
71413
  await runJsonEventsMode({
71357
71414
  explicitSessionId,
71358
71415
  resumeRequired,
71416
+ developerInstructions,
71359
71417
  mockResponse: process.env.PIE_TEST_MOCK_RESPONSE
71360
71418
  });
71361
71419
  return;
@@ -71363,6 +71421,7 @@ async function startChat(initialPrompt, testCommand) {
71363
71421
  await runJsonEventsMode({
71364
71422
  explicitSessionId,
71365
71423
  resumeRequired,
71424
+ developerInstructions,
71366
71425
  streamFn: await createCliTestStreamFnFromEnv(),
71367
71426
  createRuntime: async ({ cwd, sessionId }) => composeCliRuntime({
71368
71427
  explicitSessionId: explicitSessionId ?? sessionId,
@@ -71425,9 +71484,9 @@ async function startChat(initialPrompt, testCommand) {
71425
71484
  flushEarlyLogs();
71426
71485
  if (testCommand) {
71427
71486
  console.log(`[TEST] Auto-executing command: ${testCommand}`);
71428
- await new Promise((resolve5) => setTimeout(resolve5, 500));
71487
+ await new Promise((resolve6) => setTimeout(resolve6, 500));
71429
71488
  await interactive.executeCommand(testCommand);
71430
- await new Promise((resolve5) => setTimeout(resolve5, 2e3));
71489
+ await new Promise((resolve6) => setTimeout(resolve6, 2e3));
71431
71490
  console.log("[TEST] Command executed, exiting...");
71432
71491
  process.exit(0);
71433
71492
  return;
@@ -71448,11 +71507,11 @@ async function main() {
71448
71507
  console.log(VERSION);
71449
71508
  return;
71450
71509
  }
71451
- if (args[0] === "doctor") {
71510
+ if (args[0] === STABLE_CLI_COMMANDS.doctor) {
71452
71511
  await runDoctorCommand(args.slice(1));
71453
71512
  return;
71454
71513
  }
71455
- if (args[0] === "models") {
71514
+ if (args[0] === STABLE_CLI_COMMANDS.models) {
71456
71515
  try {
71457
71516
  await runModelsCommand(args.slice(1));
71458
71517
  } catch (error) {
@@ -71461,15 +71520,15 @@ async function main() {
71461
71520
  }
71462
71521
  return;
71463
71522
  }
71464
- if (args[0] === "sessions") {
71523
+ if (args[0] === STABLE_CLI_COMMANDS.sessions) {
71465
71524
  await runSessionsCommand(args.slice(1));
71466
71525
  return;
71467
71526
  }
71468
- if (args[0] === "extensions") {
71527
+ if (args[0] === STABLE_CLI_COMMANDS.extensions) {
71469
71528
  await runExtensionsCommand(args.slice(1));
71470
71529
  return;
71471
71530
  }
71472
- if (args[0] === "permissions") {
71531
+ if (args[0] === STABLE_CLI_COMMANDS.permissions) {
71473
71532
  console.log(formatPermissionsHelp());
71474
71533
  return;
71475
71534
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "1.0.35",
3
+ "version": "1.0.36",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {