@cydm/pie 1.0.20 → 1.0.22

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.
Files changed (2) hide show
  1. package/dist/cli.js +165 -13
  2. package/package.json +2 -1
package/dist/cli.js CHANGED
@@ -45461,11 +45461,13 @@ async function probeModelsConfig(options) {
45461
45461
  };
45462
45462
  }
45463
45463
  function parseModelsCommandArgs(args) {
45464
- const parsed = { force: false, stdout: false };
45464
+ const parsed = { force: false, stdout: false, json: false };
45465
45465
  for (let i = 0; i < args.length; i += 1) {
45466
45466
  const arg = args[i];
45467
45467
  if (arg === "--force") {
45468
45468
  parsed.force = true;
45469
+ } else if (arg === "--json") {
45470
+ parsed.json = true;
45469
45471
  } else if (arg === "--stdout") {
45470
45472
  parsed.stdout = true;
45471
45473
  } else if (arg === "--probe" && args[i + 1]) {
@@ -45556,8 +45558,9 @@ async function listSessions(args) {
45556
45558
  }
45557
45559
  async function readSession(args) {
45558
45560
  const json = hasFlag(args, "--json");
45561
+ const includeMessage = hasFlag(args, "--raw") || hasFlag(args, "--include-message");
45559
45562
  const sessionId = positionalArgs(args, /* @__PURE__ */ new Set(["--limit", "--before"]))[0];
45560
- if (!sessionId) throw new Error("Usage: pie sessions read <sessionId> [--json] [--limit <n>] [--before <cursor>]");
45563
+ if (!sessionId) throw new Error("Usage: pie sessions read <sessionId> [--json] [--raw|--include-message] [--limit <n>] [--before <cursor>]");
45561
45564
  const limit = numericFlag(args, "--limit", 200);
45562
45565
  const before = stringFlag(args, "--before");
45563
45566
  const store = new FileSessionStore(getSessionsDir());
@@ -45572,7 +45575,7 @@ async function readSession(args) {
45572
45575
  session: sessionSummary(data.metadata),
45573
45576
  currentHead: data.metadata.activeEntryId,
45574
45577
  activeEntryId: data.metadata.activeEntryId,
45575
- events: page,
45578
+ events: json && !includeMessage ? page.map(stableTranscriptEvent) : page,
45576
45579
  hasMoreBefore: start > 0,
45577
45580
  nextBefore: start > 0 ? String(start) : void 0
45578
45581
  };
@@ -45694,7 +45697,7 @@ async function forkSession(args) {
45694
45697
  function printSessionsUsage() {
45695
45698
  console.log(`Usage:
45696
45699
  pie sessions list [--json] [--limit <n>] [--cursor <cursor>] [--cwd <path>]
45697
- pie sessions read <sessionId> [--json] [--limit <n>] [--before <cursor>]
45700
+ pie sessions read <sessionId> [--json] [--raw|--include-message] [--limit <n>] [--before <cursor>]
45698
45701
  pie sessions rename <sessionId> <name> [--json] [--cwd <path>]
45699
45702
  pie sessions rewind <sessionId> --to <entryId> [--json]
45700
45703
  pie sessions fork <sessionId> --from <entryId> --target <newSessionId> --name <name> [--cwd <path>] [--json]`);
@@ -45709,10 +45712,16 @@ function stringFlag(args, flag) {
45709
45712
  return value && !value.startsWith("-") ? value : void 0;
45710
45713
  }
45711
45714
  function numericFlag(args, flag, fallback) {
45712
- const value = stringFlag(args, flag);
45713
- if (!value) return fallback;
45715
+ const index = args.indexOf(flag);
45716
+ if (index < 0) return fallback;
45717
+ const value = args[index + 1];
45718
+ if (!value) throw new Error(`${flag} requires a value.`);
45714
45719
  const parsed = Number(value);
45715
- return Number.isFinite(parsed) && parsed >= 0 ? parsed : fallback;
45720
+ const max = 1e3;
45721
+ if (!Number.isInteger(parsed) || parsed <= 0 || parsed > max) {
45722
+ throw new Error(`${flag} must be a positive integer no greater than ${max}.`);
45723
+ }
45724
+ return parsed;
45716
45725
  }
45717
45726
  function positionalArgs(args, valueFlags) {
45718
45727
  const result = [];
@@ -45758,6 +45767,7 @@ function realpathOrInput(value) {
45758
45767
  function activeTranscriptEvents(entries) {
45759
45768
  return entries.map((entry, index) => {
45760
45769
  const role = isRecord2(entry.message) && typeof entry.message.role === "string" ? entry.message.role : void 0;
45770
+ const turnId = isRecord2(entry.message) && typeof entry.message.turnId === "string" ? entry.message.turnId : void 0;
45761
45771
  return {
45762
45772
  logicalSeq: index + 1,
45763
45773
  checkpointId: entry.id,
@@ -45767,11 +45777,26 @@ function activeTranscriptEvents(entries) {
45767
45777
  timestamp: entry.timestamp,
45768
45778
  occurredAt: entry.timestamp,
45769
45779
  role,
45780
+ turnId,
45770
45781
  content: textFromMessage(entry.message),
45771
45782
  message: entry.message ? cloneJson(entry.message) : void 0
45772
45783
  };
45773
45784
  });
45774
45785
  }
45786
+ function stableTranscriptEvent(event) {
45787
+ return {
45788
+ logicalSeq: event.logicalSeq,
45789
+ checkpointId: event.checkpointId,
45790
+ entryId: event.entryId,
45791
+ id: event.id,
45792
+ type: event.type,
45793
+ timestamp: event.timestamp,
45794
+ occurredAt: event.occurredAt,
45795
+ ...event.role ? { role: event.role } : {},
45796
+ ...event.turnId ? { turnId: event.turnId } : {},
45797
+ ...event.content ? { content: event.content } : {}
45798
+ };
45799
+ }
45775
45800
  function activePathEntries(data) {
45776
45801
  const activeEntryId = data.metadata.activeEntryId;
45777
45802
  if (!activeEntryId) return [];
@@ -59771,6 +59796,11 @@ var ToolExecutionComponent = class extends Container {
59771
59796
  const textBlocks = this.result.content?.filter((content) => content.type === "text") || [];
59772
59797
  return textBlocks.map((content) => (content.text || "").replace(/\r/g, "")).join("\n");
59773
59798
  }
59799
+ getExpandedOutputLineLimit(collapsedMaxLines) {
59800
+ if (!this.expanded) return collapsedMaxLines;
59801
+ const visibleOutputRows = Math.max(collapsedMaxLines, this.ui.terminal.rows - 15);
59802
+ return visibleOutputRows;
59803
+ }
59774
59804
  formatToolExecution() {
59775
59805
  let text = "";
59776
59806
  const invalidArg = theme.fg("error", "[invalid arg]");
@@ -60076,7 +60106,7 @@ ${theme.fg("warning", `[Truncated: ${warnings.join(", ")}]`)}`;
60076
60106
  const output = this.getTextOutput().trim();
60077
60107
  if (output) {
60078
60108
  const lines = output.split("\n");
60079
- const maxLines = this.expanded ? lines.length : 5;
60109
+ const maxLines = this.getExpandedOutputLineLimit(5);
60080
60110
  const displayLines = lines.slice(0, maxLines);
60081
60111
  const remaining = lines.length - maxLines;
60082
60112
  text += "\n\n" + displayLines.map((line) => theme.fg("toolOutput", line)).join("\n");
@@ -60327,7 +60357,10 @@ async function loadSession(host, sessionId) {
60327
60357
  host.ui.requestRender();
60328
60358
  }
60329
60359
  }
60330
- function updateTerminalTitle(host) {
60360
+ var TITLE_SPINNER_FRAMES = ["\u280B", "\u2819", "\u2839", "\u2838", "\u283C", "\u2834", "\u2826", "\u2827", "\u2807", "\u280F"];
60361
+ var TITLE_SPINNER_INTERVAL_MS = 80;
60362
+ var titleSpinnerTimers = /* @__PURE__ */ new WeakMap();
60363
+ function updateTerminalTitle(host, spinnerFrame) {
60331
60364
  const activeSession = host.sessionManager.getActiveSession();
60332
60365
  if (!activeSession) {
60333
60366
  host.ui.terminal.setTitle("Pie");
@@ -60338,14 +60371,41 @@ function updateTerminalTitle(host) {
60338
60371
  messages: host.sessionManager.getMessages()
60339
60372
  });
60340
60373
  const activityState = host.submitLock ? "busy" : "ready";
60341
- host.ui.terminal.setTitle(`Pie \xB7 ${sessionLabel} [ms:session=${activeSession.id};state=${activityState}]`);
60374
+ const prefix = spinnerFrame ? `${spinnerFrame} ` : "";
60375
+ host.ui.terminal.setTitle(`${prefix}Pie \xB7 ${sessionLabel} [ms:session=${activeSession.id};state=${activityState}]`);
60376
+ }
60377
+ function stopTitleSpinner(host) {
60378
+ const timer = titleSpinnerTimers.get(host);
60379
+ if (timer) {
60380
+ clearInterval(timer);
60381
+ titleSpinnerTimers.delete(host);
60382
+ }
60383
+ }
60384
+ function startTitleSpinner(host) {
60385
+ stopTitleSpinner(host);
60386
+ let frameIndex = 0;
60387
+ const timer = setInterval(() => {
60388
+ const frame = TITLE_SPINNER_FRAMES[frameIndex % TITLE_SPINNER_FRAMES.length];
60389
+ updateTerminalTitle(host, frame);
60390
+ frameIndex++;
60391
+ }, TITLE_SPINNER_INTERVAL_MS);
60392
+ if (typeof timer.unref === "function") {
60393
+ timer.unref();
60394
+ }
60395
+ titleSpinnerTimers.set(host, timer);
60396
+ updateTerminalTitle(host, TITLE_SPINNER_FRAMES[0]);
60342
60397
  }
60343
60398
  function setSubmitLock(host, locked) {
60344
60399
  if (host.submitLock === locked) {
60345
60400
  return;
60346
60401
  }
60347
60402
  host.submitLock = locked;
60348
- host.updateTerminalTitle();
60403
+ stopTitleSpinner(host);
60404
+ if (locked) {
60405
+ startTitleSpinner(host);
60406
+ } else {
60407
+ host.updateTerminalTitle();
60408
+ }
60349
60409
  }
60350
60410
  async function handleTreeCommand(host) {
60351
60411
  const entries = host.sessionManager.getEntries();
@@ -68379,6 +68439,9 @@ async function runJsonEventsMode(params) {
68379
68439
  let trace;
68380
68440
  let lastRetryEvent;
68381
68441
  let mockActiveEntryId;
68442
+ let thinkingLevel = "off";
68443
+ let defaultRuntime;
68444
+ let defaultModelState;
68382
68445
  const noProgressTimeoutMs = Number(process.env.PIE_JSON_EVENTS_NO_PROGRESS_MS || 6e5);
68383
68446
  const mockResponseDelayMs = Number(process.env.PIE_TEST_MOCK_RESPONSE_DELAY_MS || 0);
68384
68447
  writeEvent({ type: "agent.ready", sessionId });
@@ -68724,6 +68787,10 @@ async function runJsonEventsMode(params) {
68724
68787
  if (!runtime) {
68725
68788
  throw new Error("JSON events mode requires a CLI runtime");
68726
68789
  }
68790
+ if (defaultRuntime !== runtime) {
68791
+ defaultRuntime = runtime;
68792
+ defaultModelState = configuredDefaultModelState(runtime);
68793
+ }
68727
68794
  if (runtime.initialModel.unconfigured || controller) {
68728
68795
  return;
68729
68796
  }
@@ -68752,7 +68819,7 @@ async function runJsonEventsMode(params) {
68752
68819
  systemPrompt: baseSystemPrompt,
68753
68820
  model: runtime.model,
68754
68821
  tools,
68755
- thinkingLevel: "off"
68822
+ thinkingLevel
68756
68823
  },
68757
68824
  apiKey: runtime.apiKey,
68758
68825
  streamFn: params.streamFn
@@ -68805,6 +68872,77 @@ async function runJsonEventsMode(params) {
68805
68872
  controller.updateRuntimeContext({ tools: agent.state.tools });
68806
68873
  disposeSemanticSubscription = agent.subscribeSemantic(handleSemanticEvent);
68807
68874
  }
68875
+ function metadataSelection(metadata, key) {
68876
+ if (!metadata || !(key in metadata)) return void 0;
68877
+ const value = metadata[key];
68878
+ if (value === null) return null;
68879
+ if (typeof value !== "string") throw new Error(`${key} must be a string or null`);
68880
+ const normalized = value.trim();
68881
+ return normalized && normalized !== "default" ? normalized : null;
68882
+ }
68883
+ function configuredDefaultModelState(runtime2) {
68884
+ const model = runtime2.initialModel.model ?? runtime2.model;
68885
+ const apiKey = runtime2.initialModel.apiKey || runtime2.modelRegistry.getApiKey(model) || runtime2.apiKey;
68886
+ return {
68887
+ provider: runtime2.initialModel.provider || model.provider || runtime2.provider,
68888
+ modelId: runtime2.initialModel.modelId || model.id || runtime2.modelId,
68889
+ model,
68890
+ apiKey
68891
+ };
68892
+ }
68893
+ function parseRequestedModel(value) {
68894
+ const separator = value.indexOf("/");
68895
+ if (separator <= 0 || separator === value.length - 1) return void 0;
68896
+ return {
68897
+ provider: value.slice(0, separator),
68898
+ modelId: value.slice(separator + 1)
68899
+ };
68900
+ }
68901
+ function applyRuntimeSelection(message) {
68902
+ if (!runtime || !agent) return;
68903
+ const requestedModel = metadataSelection(message.metadata, "model");
68904
+ const requestedThinkingLevel = metadataSelection(message.metadata, "thinkingLevel");
68905
+ if (requestedModel !== void 0) {
68906
+ if (requestedModel === null) {
68907
+ const defaults = defaultModelState;
68908
+ if (defaults) {
68909
+ agent.setModel(defaults.model);
68910
+ agent.apiKey = defaults.apiKey;
68911
+ runtime.model = defaults.model;
68912
+ runtime.provider = defaults.provider;
68913
+ runtime.modelId = defaults.modelId;
68914
+ runtime.apiKey = defaults.apiKey;
68915
+ }
68916
+ } else {
68917
+ const parsed = parseRequestedModel(requestedModel);
68918
+ if (!parsed) throw new Error(`model must use profile/modelId format: ${requestedModel}`);
68919
+ const { provider, modelId } = parsed;
68920
+ const model = runtime.modelRegistry.find(provider, modelId);
68921
+ if (!model) throw new Error(`Model "${requestedModel}" not found`);
68922
+ const apiKey = runtime.modelRegistry.getApiKey(model);
68923
+ agent.setModel(model);
68924
+ agent.apiKey = apiKey;
68925
+ runtime.model = model;
68926
+ runtime.provider = provider;
68927
+ runtime.modelId = modelId;
68928
+ runtime.apiKey = apiKey;
68929
+ }
68930
+ }
68931
+ if (requestedThinkingLevel !== void 0) {
68932
+ const nextLevel = requestedThinkingLevel === null ? "off" : requestedThinkingLevel;
68933
+ if (!isThinkingLevel(nextLevel)) throw new Error(`Unsupported thinkingLevel: ${nextLevel}`);
68934
+ thinkingLevel = nextLevel;
68935
+ applyThinkingLevel({
68936
+ level: thinkingLevel,
68937
+ agent,
68938
+ settingsManager: runtime.settingsManager,
68939
+ sessionManager: runtime.sessionManager,
68940
+ model: runtime.model
68941
+ });
68942
+ } else {
68943
+ syncSessionModelMetadata(runtime.sessionManager, runtime.model, thinkingLevel);
68944
+ }
68945
+ }
68808
68946
  async function runTurn(message) {
68809
68947
  if (isSessionMismatch(message)) {
68810
68948
  writeEvent({
@@ -68887,6 +69025,14 @@ async function runJsonEventsMode(params) {
68887
69025
  if (activeTurn === turn) activeTurn = null;
68888
69026
  return;
68889
69027
  }
69028
+ try {
69029
+ applyRuntimeSelection(message);
69030
+ } catch (error) {
69031
+ finalize("failed", error instanceof Error ? error.message : String(error));
69032
+ if (activeTurn === turn) emitSettled(turn);
69033
+ if (activeTurn === turn) activeTurn = null;
69034
+ return;
69035
+ }
68890
69036
  const progressTimer = setInterval(() => {
68891
69037
  const turn2 = activeTurn;
68892
69038
  if (!turn2 || turn2.finalized) return;
@@ -69107,6 +69253,12 @@ async function runModelsCommand(args) {
69107
69253
  }
69108
69254
  if (subcommand === "validate") {
69109
69255
  const result = validateModelsConfig({ path: parsed.path });
69256
+ if (parsed.json) {
69257
+ const probe = result.ok && parsed.probe ? await probeModelsConfig({ path: parsed.path, probe: parsed.probe }) : void 0;
69258
+ console.log(JSON.stringify({ ...result, ...probe ? { probe } : {} }, null, 2));
69259
+ if (!result.ok || probe?.status === "failed") process.exitCode = 1;
69260
+ return;
69261
+ }
69110
69262
  if (!result.ok) {
69111
69263
  console.error(result.message);
69112
69264
  process.exitCode = 1;
@@ -69147,7 +69299,7 @@ async function runModelsCommand(args) {
69147
69299
  }
69148
69300
  console.log(`Usage:
69149
69301
  pie models init [--path <path>] [--force] [--stdout]
69150
- pie models validate [--path <path>] [--probe web_search]`);
69302
+ pie models validate [--path <path>] [--probe web_search] [--json]`);
69151
69303
  }
69152
69304
  function parseRepeatedFlag(args, flag) {
69153
69305
  const values = [];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "1.0.20",
3
+ "version": "1.0.22",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {
@@ -17,6 +17,7 @@
17
17
  "test": "npm run test:offline",
18
18
  "pretest:offline": "npm run build --workspace @pie/agent-framework && npm run build --workspace @pie/shared-headless-capabilities && npm run build",
19
19
  "test:offline": "node --test --import tsx test/core-services.test.ts test/cli.test.ts test/cli-auto-compaction.test.ts test/execution-state-manager.test.ts test/queued-steer-execution-state.test.ts test/architecture-boundaries.test.ts test/attachment-resolver.test.ts test/kimi-attachment-extension.test.ts test/document-attachment-extension.test.ts test/auto-compact-overflow.test.ts test/hierarchical-command-system.test.ts test/message-queue-unit.test.ts test/evals-harness.test.ts test/session-trace.test.ts test/runtime-mode-context.test.ts test/tool-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/code-intel-typescript-provider.test.ts test/init-extension-contract.test.ts test/skills-runtime.test.ts test/cross-host-parity.test.ts test/tool-name-rendering.test.ts test/tools-registry.test.ts test/system-prompt-contract.test.ts test/daily-agent-smoke.terminal.test.ts",
20
+ "test:all": "npm run test:offline && npm run test:terminal:vitest",
20
21
  "test:terminal:vitest": "vitest run test/mention-file-select.terminal.test.ts test/tool-partial-display.terminal.test.ts test/viewport-position-final.test.ts",
21
22
  "test:todo-tui": "PIE_REAL_TODO_TUI=1 node --test --import tsx test/todo-closure.terminal.test.ts",
22
23
  "test:daily-tui": "npm run test:daily-tui:quick",