@cydm/pie 1.0.13 → 1.0.14

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 +577 -1
  2. package/package.json +1 -1
package/dist/cli.js CHANGED
@@ -43943,7 +43943,7 @@ import * as path26 from "path";
43943
43943
 
43944
43944
  // src/cli-args.ts
43945
43945
  var FLAGS_WITH_VALUES = /* @__PURE__ */ new Set(["--session-id", "--extension-path"]);
43946
- var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["--raw-output", "--json-output"]);
43946
+ var BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["--raw-output", "--json-output", "--json-events"]);
43947
43947
  var HELP_FLAGS = /* @__PURE__ */ new Set(["help", "--help", "-h"]);
43948
43948
  var COMMANDS = /* @__PURE__ */ new Set(["chat", "help"]);
43949
43949
  function parseCliInvocation(args) {
@@ -67520,6 +67520,538 @@ async function runPrintMode(params) {
67520
67520
  sessionTrace.flush();
67521
67521
  }
67522
67522
 
67523
+ // src/app/json-events-mode.ts
67524
+ import readline from "node:readline";
67525
+ var MAX_EVENT_OBJECT_KEYS = 50;
67526
+ var MAX_EVENT_ARRAY_ITEMS = 50;
67527
+ var MAX_EVENT_VALUE_DEPTH = 4;
67528
+ var MAX_EVENT_STRING_LENGTH = 4e3;
67529
+ function createNoOpExtensionUIContext2() {
67530
+ return {
67531
+ notify: () => {
67532
+ },
67533
+ select: async () => void 0,
67534
+ confirm: async () => false,
67535
+ input: async () => void 0,
67536
+ editor: async () => void 0,
67537
+ custom: async () => void 0
67538
+ };
67539
+ }
67540
+ function writeEvent(event) {
67541
+ process.stdout.write(`${JSON.stringify(event)}
67542
+ `);
67543
+ }
67544
+ function toJsonValue(value, depth = 0) {
67545
+ if (value === null) return null;
67546
+ if (typeof value === "string") {
67547
+ return value.length > MAX_EVENT_STRING_LENGTH ? `${value.slice(0, MAX_EVENT_STRING_LENGTH)}...` : value;
67548
+ }
67549
+ if (typeof value === "number") return Number.isFinite(value) ? value : String(value);
67550
+ if (typeof value === "boolean") return value;
67551
+ if (typeof value === "bigint") return value.toString();
67552
+ if (typeof value !== "object") return void 0;
67553
+ if (depth >= MAX_EVENT_VALUE_DEPTH) return "[truncated]";
67554
+ if (Array.isArray(value)) {
67555
+ return value.slice(0, MAX_EVENT_ARRAY_ITEMS).map((item) => toJsonValue(item, depth + 1) ?? null);
67556
+ }
67557
+ const result = {};
67558
+ for (const [key, item] of Object.entries(value).slice(0, MAX_EVENT_OBJECT_KEYS)) {
67559
+ result[key] = toJsonValue(item, depth + 1);
67560
+ }
67561
+ return result;
67562
+ }
67563
+ function isRecord3(value) {
67564
+ return !!value && typeof value === "object" && !Array.isArray(value);
67565
+ }
67566
+ function parseInput(line) {
67567
+ let parsed;
67568
+ try {
67569
+ parsed = JSON.parse(line);
67570
+ } catch {
67571
+ return null;
67572
+ }
67573
+ if (!isRecord3(parsed) || typeof parsed.type !== "string") return null;
67574
+ if (parsed.type === "shutdown") {
67575
+ return { type: "shutdown", reason: typeof parsed.reason === "string" ? parsed.reason : void 0 };
67576
+ }
67577
+ if (parsed.type === "turn.interrupt") {
67578
+ return {
67579
+ type: "turn.interrupt",
67580
+ sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
67581
+ turnId: typeof parsed.turnId === "string" ? parsed.turnId : void 0,
67582
+ reason: typeof parsed.reason === "string" ? parsed.reason : void 0
67583
+ };
67584
+ }
67585
+ if (parsed.type === "turn.request" && typeof parsed.turnId === "string" && typeof parsed.prompt === "string") {
67586
+ return {
67587
+ type: "turn.request",
67588
+ sessionId: typeof parsed.sessionId === "string" ? parsed.sessionId : void 0,
67589
+ turnId: parsed.turnId,
67590
+ prompt: parsed.prompt,
67591
+ cwd: typeof parsed.cwd === "string" ? parsed.cwd : void 0,
67592
+ metadata: isRecord3(parsed.metadata) ? parsed.metadata : void 0
67593
+ };
67594
+ }
67595
+ return null;
67596
+ }
67597
+ function assistantTextFromAgent(agent) {
67598
+ const messages = agent?.state.messages ?? [];
67599
+ const lastMessage = messages[messages.length - 1];
67600
+ if (lastMessage?.role !== "assistant") return "";
67601
+ let text = "";
67602
+ for (const content of lastMessage.content) {
67603
+ if (content.type === "text") {
67604
+ text += content.text;
67605
+ }
67606
+ }
67607
+ return text;
67608
+ }
67609
+ function readProgressText(value) {
67610
+ return typeof value === "string" ? value : "";
67611
+ }
67612
+ function extractJsonEventsToolProgressText(partialResult) {
67613
+ const plainText = readProgressText(partialResult).trim();
67614
+ if (plainText) return plainText;
67615
+ if (!isRecord3(partialResult)) return "";
67616
+ const content = partialResult.content;
67617
+ if (Array.isArray(content)) {
67618
+ return content.map((block) => isRecord3(block) && block.type === "text" ? readProgressText(block.text) : "").filter(Boolean).join("\n").trim();
67619
+ }
67620
+ const directText = readProgressText(partialResult.text) || readProgressText(partialResult.message);
67621
+ if (directText) return directText.trim();
67622
+ const details = partialResult.details;
67623
+ if (isRecord3(details)) {
67624
+ return (readProgressText(details.text) || readProgressText(details.message)).trim();
67625
+ }
67626
+ return "";
67627
+ }
67628
+ async function loadJsonModeExtensions(params) {
67629
+ const uiContext = createNoOpExtensionUIContext2();
67630
+ const executionState = new ExecutionStateManager();
67631
+ const activeSession = params.runtime.sessionManager.getActiveSession();
67632
+ executionState.restoreFromMetadata(activeSession?.metadata?.executionState);
67633
+ const actions = {
67634
+ setActiveTools: (toolNames) => {
67635
+ const agent = params.getAgent();
67636
+ if (!agent) return;
67637
+ agent.state.tools = agent.state.tools.filter((tool) => toolNames.includes(tool.name));
67638
+ },
67639
+ getActiveTools: () => params.getAgent()?.state.tools.map((tool) => tool.name) ?? [],
67640
+ sendUserMessage: () => {
67641
+ },
67642
+ setPlanMode: () => {
67643
+ },
67644
+ setExecutionReminder: (text) => {
67645
+ const session = params.runtime.sessionManager.getActiveSession();
67646
+ if (!session) return;
67647
+ if (text) {
67648
+ session.metadata.executionReminder = text;
67649
+ } else {
67650
+ delete session.metadata.executionReminder;
67651
+ }
67652
+ },
67653
+ getExecutionState: () => executionState.read(),
67654
+ setExecutionState: (state) => {
67655
+ const nextState = executionState.replace(state);
67656
+ const session = params.runtime.sessionManager.getActiveSession();
67657
+ if (session) {
67658
+ session.metadata.executionState = executionState.createMetadata();
67659
+ }
67660
+ return nextState;
67661
+ },
67662
+ cwd: params.runtime.cwd,
67663
+ apiKey: params.runtime.apiKey,
67664
+ model: params.runtime.model,
67665
+ skills: params.runtime.skills,
67666
+ getAllTools: () => params.getAgent()?.state.tools.map((tool) => ({
67667
+ name: tool.name,
67668
+ description: tool.description,
67669
+ parameters: tool.parameters
67670
+ })) ?? [],
67671
+ getRuntimeTools: () => params.getAgent()?.state.tools ?? [],
67672
+ resolveModelClass: (modelClass) => params.runtime.modelRegistry.resolveModelClass(modelClass),
67673
+ getMessages: () => params.getAgent()?.state.messages ?? [],
67674
+ getSessionMetadata: () => ({ ...params.runtime.sessionManager.getActiveSession()?.metadata ?? {} }),
67675
+ setSessionMetadata: (key, value) => {
67676
+ const session = params.runtime.sessionManager.getActiveSession();
67677
+ if (!session) return;
67678
+ session.metadata[key] = value;
67679
+ },
67680
+ yoloMode: false
67681
+ };
67682
+ const { extensions } = await loadExtensions(
67683
+ params.runtime.extensionPaths,
67684
+ params.runtime.cwd,
67685
+ uiContext,
67686
+ () => params.getAgent()?.abort(),
67687
+ () => true,
67688
+ false,
67689
+ actions
67690
+ );
67691
+ const runner = new ExtensionRunner(
67692
+ extensions,
67693
+ actions,
67694
+ {
67695
+ isIdle: () => true,
67696
+ abort: () => params.getAgent()?.abort()
67697
+ },
67698
+ false
67699
+ );
67700
+ runner.setUIContext(uiContext);
67701
+ return {
67702
+ runner,
67703
+ extensionTools: convertExtensionTools(extensions),
67704
+ extensionCount: extensions.length
67705
+ };
67706
+ }
67707
+ async function runJsonEventsMode(params) {
67708
+ const sessionId = params.explicitSessionId || params.runtime?.sessionManager.getActiveSession()?.id || `pie-json-${Date.now()}`;
67709
+ let activeTurn = null;
67710
+ let agent;
67711
+ let controller;
67712
+ let disposeAgentSubscription;
67713
+ let disposeSemanticSubscription;
67714
+ let trace;
67715
+ const noProgressTimeoutMs = Number(process.env.PIE_JSON_EVENTS_NO_PROGRESS_MS || 6e5);
67716
+ const mockResponseDelayMs = Number(process.env.PIE_TEST_MOCK_RESPONSE_DELAY_MS || 0);
67717
+ writeEvent({ type: "agent.ready", sessionId });
67718
+ function sessionMismatchError(requestedSessionId) {
67719
+ return `session mismatch: JSON events process is bound to ${sessionId}, received ${requestedSessionId}`;
67720
+ }
67721
+ function isSessionMismatch(message) {
67722
+ return typeof message.sessionId === "string" && message.sessionId !== sessionId;
67723
+ }
67724
+ function delay(ms) {
67725
+ return new Promise((resolve4) => setTimeout(resolve4, Math.max(0, ms)));
67726
+ }
67727
+ function touch() {
67728
+ if (activeTurn) {
67729
+ activeTurn.lastActivityAt = Date.now();
67730
+ }
67731
+ }
67732
+ function display(chunk) {
67733
+ if (!activeTurn || !chunk) return;
67734
+ activeTurn.summary += chunk;
67735
+ touch();
67736
+ writeEvent({
67737
+ type: "display.output",
67738
+ sessionId: activeTurn.sessionId,
67739
+ turnId: activeTurn.turnId,
67740
+ stream: "terminal",
67741
+ chunk
67742
+ });
67743
+ }
67744
+ function finalize(kind, detail) {
67745
+ const turn = activeTurn;
67746
+ if (!turn || turn.finalized) return;
67747
+ turn.finalized = true;
67748
+ switch (kind) {
67749
+ case "completed":
67750
+ writeEvent({ type: "turn.completed", sessionId: turn.sessionId, turnId: turn.turnId, summary: turn.summary.trim() });
67751
+ break;
67752
+ case "failed":
67753
+ writeEvent({ type: "turn.failed", sessionId: turn.sessionId, turnId: turn.turnId, error: detail || "turn failed" });
67754
+ break;
67755
+ case "cancelled":
67756
+ writeEvent({ type: "turn.cancelled", sessionId: turn.sessionId, turnId: turn.turnId, reason: detail || "interrupted" });
67757
+ break;
67758
+ case "stalled":
67759
+ writeEvent({ type: "turn.stalled", sessionId: turn.sessionId, turnId: turn.turnId, reason: detail || "no_progress_timeout" });
67760
+ break;
67761
+ }
67762
+ }
67763
+ function handleSemanticEvent(event) {
67764
+ if (!activeTurn || activeTurn.finalized) return;
67765
+ switch (event.type) {
67766
+ case "assistant_response_delta":
67767
+ display(event.delta);
67768
+ break;
67769
+ case "tool_started":
67770
+ touch();
67771
+ writeEvent({
67772
+ type: "tool.started",
67773
+ sessionId: activeTurn.sessionId,
67774
+ turnId: activeTurn.turnId,
67775
+ toolCallId: event.toolCallId,
67776
+ name: event.toolName,
67777
+ data: toJsonValue({ args: event.args })
67778
+ });
67779
+ break;
67780
+ case "tool_progressed":
67781
+ touch();
67782
+ {
67783
+ const progressText = extractJsonEventsToolProgressText(event.partialResult);
67784
+ if (progressText) {
67785
+ display(progressText.endsWith("\n") ? progressText : `${progressText}
67786
+ `);
67787
+ }
67788
+ }
67789
+ break;
67790
+ case "tool_finished":
67791
+ touch();
67792
+ writeEvent({
67793
+ type: "tool.completed",
67794
+ sessionId: activeTurn.sessionId,
67795
+ turnId: activeTurn.turnId,
67796
+ toolCallId: event.toolCallId,
67797
+ name: event.toolName,
67798
+ status: event.isError ? "error" : "ok",
67799
+ data: toJsonValue({
67800
+ resultText: extractJsonEventsToolProgressText(event.result),
67801
+ isError: event.isError
67802
+ })
67803
+ });
67804
+ break;
67805
+ }
67806
+ }
67807
+ async function ensureRuntime() {
67808
+ if (params.mockResponse !== void 0 || controller) return;
67809
+ const runtime = params.runtime;
67810
+ if (!runtime) {
67811
+ throw new Error("JSON events mode requires a CLI runtime");
67812
+ }
67813
+ if (runtime.initialModel.unconfigured) {
67814
+ return;
67815
+ }
67816
+ const { Agent: AgentClass } = await import("./chunks/src-LZC56DRG.js");
67817
+ const jsonModeExtensions = await loadJsonModeExtensions({ runtime, getAgent: () => agent });
67818
+ const tools = [...runtime.tools, ...jsonModeExtensions.extensionTools];
67819
+ recordCliCompositionStep(runtime.compositionTrace, {
67820
+ id: "extensions_tool_wrapping",
67821
+ inputSummary: `baseTools=${runtime.tools.length} extensionPaths=${runtime.extensionPaths.length}`,
67822
+ outputSummary: `extensions=${jsonModeExtensions.extensionCount}`,
67823
+ toolCount: tools.length,
67824
+ extensionWrapping: {
67825
+ extensionCount: jsonModeExtensions.extensionCount,
67826
+ extensionToolCount: jsonModeExtensions.extensionTools.length,
67827
+ wrappedToolCount: tools.length
67828
+ }
67829
+ });
67830
+ const baseSystemPrompt = buildCliSystemPrompt({
67831
+ cwd: runtime.cwd,
67832
+ skillsSection: runtime.skillsSection,
67833
+ knowledgeSection: runtime.knowledgeSection,
67834
+ tools: tools.map((tool) => ({ name: tool.name, description: tool.description }))
67835
+ });
67836
+ agent = new AgentClass({
67837
+ initialState: {
67838
+ systemPrompt: baseSystemPrompt,
67839
+ model: runtime.model,
67840
+ tools,
67841
+ thinkingLevel: "off"
67842
+ },
67843
+ apiKey: runtime.apiKey
67844
+ });
67845
+ controller = new AgentSessionController({
67846
+ agent,
67847
+ sessionManager: runtime.sessionManager,
67848
+ cwd: runtime.cwd,
67849
+ baseSystemPrompt,
67850
+ prepareTurn: async (context) => {
67851
+ const result = await jsonModeExtensions.runner.emitBeforeAgentStart({
67852
+ type: "before_agent_start",
67853
+ messages: context.messages,
67854
+ baseSystemPrompt: context.baseSystemPrompt ?? baseSystemPrompt,
67855
+ source: context.source
67856
+ });
67857
+ return {
67858
+ systemPrompt: result?.systemPrompt ?? context.baseSystemPrompt ?? baseSystemPrompt,
67859
+ messages: result?.messages?.length ? [...context.messages, ...result.messages] : context.messages
67860
+ };
67861
+ }
67862
+ });
67863
+ trace = new SessionTraceWriter(runtime.paths.sessionsDir, runtime.sessionManager);
67864
+ attachAgentEventsToSessionTrace({ agent, trace });
67865
+ agent.setTools(wrapToolsWithExtensions(agent.state.tools, jsonModeExtensions.runner));
67866
+ controller.updateRuntimeContext({ tools: agent.state.tools });
67867
+ disposeSemanticSubscription = agent.subscribeSemantic(handleSemanticEvent);
67868
+ }
67869
+ async function runTurn(message) {
67870
+ if (isSessionMismatch(message)) {
67871
+ writeEvent({
67872
+ type: "turn.failed",
67873
+ sessionId,
67874
+ turnId: message.turnId,
67875
+ error: sessionMismatchError(message.sessionId)
67876
+ });
67877
+ return;
67878
+ }
67879
+ if (activeTurn && !activeTurn.finalized) {
67880
+ writeEvent({
67881
+ type: "turn.failed",
67882
+ sessionId,
67883
+ turnId: message.turnId,
67884
+ error: "another turn is already running"
67885
+ });
67886
+ return;
67887
+ }
67888
+ activeTurn = {
67889
+ sessionId,
67890
+ turnId: message.turnId,
67891
+ prompt: message.prompt,
67892
+ startedAt: Date.now(),
67893
+ lastActivityAt: Date.now(),
67894
+ interrupted: false,
67895
+ stalled: false,
67896
+ finalized: false,
67897
+ summary: ""
67898
+ };
67899
+ const turn = activeTurn;
67900
+ writeEvent({ type: "turn.started", sessionId: activeTurn.sessionId, turnId: activeTurn.turnId });
67901
+ if (params.mockResponse !== void 0) {
67902
+ if (mockResponseDelayMs > 0) {
67903
+ await delay(mockResponseDelayMs);
67904
+ }
67905
+ if (activeTurn !== turn || turn.finalized) {
67906
+ return;
67907
+ }
67908
+ display(params.mockResponse);
67909
+ finalize("completed");
67910
+ if (activeTurn === turn) activeTurn = null;
67911
+ return;
67912
+ }
67913
+ if (params.startupError) {
67914
+ finalize("failed", params.startupError);
67915
+ if (activeTurn === turn) activeTurn = null;
67916
+ return;
67917
+ }
67918
+ try {
67919
+ await ensureRuntime();
67920
+ } catch (error) {
67921
+ finalize("failed", error instanceof Error ? error.message : String(error));
67922
+ if (activeTurn === turn) activeTurn = null;
67923
+ return;
67924
+ }
67925
+ const runtime = params.runtime;
67926
+ if (runtime?.initialModel.unconfigured) {
67927
+ finalize("failed", runtime.initialModel.warning || "No models are configured.");
67928
+ if (activeTurn === turn) activeTurn = null;
67929
+ return;
67930
+ }
67931
+ if (!controller || !agent) {
67932
+ finalize("failed", "JSON events runtime was not initialized");
67933
+ if (activeTurn === turn) activeTurn = null;
67934
+ return;
67935
+ }
67936
+ const progressTimer = setInterval(() => {
67937
+ const turn2 = activeTurn;
67938
+ if (!turn2 || turn2.finalized) return;
67939
+ if (Date.now() - turn2.lastActivityAt >= noProgressTimeoutMs) {
67940
+ turn2.stalled = true;
67941
+ agent?.abort();
67942
+ finalize("stalled", "no_progress_timeout");
67943
+ }
67944
+ }, Math.max(1e3, Math.min(noProgressTimeoutMs, 1e4)));
67945
+ progressTimer.unref?.();
67946
+ try {
67947
+ trace?.notePendingUserText(message.prompt);
67948
+ trace?.noteDispatchStart({ mode: "json-events" });
67949
+ await controller.prompt(message.prompt, { source: "json-events" });
67950
+ trace?.noteDispatchSettled({ mode: "json-events" });
67951
+ trace?.noteWaitForIdleStart({ mode: "json-events" });
67952
+ await controller.waitForIdle();
67953
+ trace?.noteWaitForIdleSettled({ mode: "json-events" });
67954
+ if (!activeTurn?.finalized) {
67955
+ const text = activeTurn?.summary.trim() || assistantTextFromAgent(agent);
67956
+ if (!activeTurn?.summary && text) {
67957
+ display(text);
67958
+ }
67959
+ finalize(activeTurn?.interrupted ? "cancelled" : "completed", activeTurn?.interrupted ? "user_interrupt" : void 0);
67960
+ }
67961
+ } catch (error) {
67962
+ const messageText = error instanceof Error ? error.message : String(error);
67963
+ trace?.noteStalled(messageText, { mode: "json-events" });
67964
+ if (!activeTurn?.finalized) {
67965
+ finalize(activeTurn?.interrupted ? "cancelled" : "failed", activeTurn?.interrupted ? "user_interrupt" : messageText);
67966
+ }
67967
+ } finally {
67968
+ clearInterval(progressTimer);
67969
+ trace?.flush();
67970
+ await runtime?.sessionManager.save();
67971
+ if (activeTurn === turn) activeTurn = null;
67972
+ }
67973
+ }
67974
+ async function interrupt(message) {
67975
+ if (isSessionMismatch(message)) {
67976
+ writeEvent({
67977
+ type: "turn.cancelled",
67978
+ sessionId,
67979
+ turnId: message.turnId || "no-active-turn",
67980
+ reason: sessionMismatchError(message.sessionId)
67981
+ });
67982
+ return;
67983
+ }
67984
+ if (!activeTurn || activeTurn.finalized) {
67985
+ writeEvent({
67986
+ type: "turn.cancelled",
67987
+ sessionId,
67988
+ turnId: message.turnId || "no-active-turn",
67989
+ reason: message.reason || "no_active_turn"
67990
+ });
67991
+ return;
67992
+ }
67993
+ if (message.turnId && message.turnId !== activeTurn.turnId) {
67994
+ writeEvent({
67995
+ type: "turn.cancelled",
67996
+ sessionId,
67997
+ turnId: message.turnId,
67998
+ reason: `turn mismatch: active turn is ${activeTurn.turnId}`
67999
+ });
68000
+ return;
68001
+ }
68002
+ activeTurn.interrupted = true;
68003
+ agent?.abort();
68004
+ if (params.mockResponse !== void 0) {
68005
+ finalize("cancelled", message.reason || "user_interrupt");
68006
+ activeTurn = null;
68007
+ }
68008
+ }
68009
+ const input = readline.createInterface({ input: process.stdin });
68010
+ let activeTurnPromise = null;
68011
+ for await (const line of input) {
68012
+ if (!line.trim()) continue;
68013
+ const message = parseInput(line);
68014
+ if (!message) {
68015
+ writeEvent({ type: "turn.failed", sessionId, turnId: `invalid-${Date.now()}`, error: "invalid JSON events input" });
68016
+ continue;
68017
+ }
68018
+ if (message.type === "shutdown") {
68019
+ if (activeTurn && !activeTurn.finalized) {
68020
+ activeTurn.interrupted = true;
68021
+ agent?.abort();
68022
+ finalize("cancelled", message.reason || "shutdown");
68023
+ }
68024
+ break;
68025
+ }
68026
+ if (message.type === "turn.interrupt") {
68027
+ await interrupt(message);
68028
+ continue;
68029
+ }
68030
+ const shouldTrackTurn = !activeTurn || activeTurn.finalized;
68031
+ const turnPromise = runTurn(message).catch((error) => {
68032
+ writeEvent({
68033
+ type: "turn.failed",
68034
+ sessionId,
68035
+ turnId: message.turnId,
68036
+ error: error instanceof Error ? error.message : String(error)
68037
+ });
68038
+ }).finally(() => {
68039
+ if (activeTurnPromise === turnPromise) {
68040
+ activeTurnPromise = null;
68041
+ }
68042
+ });
68043
+ if (shouldTrackTurn) {
68044
+ activeTurnPromise = turnPromise;
68045
+ }
68046
+ }
68047
+ await activeTurnPromise;
68048
+ disposeAgentSubscription?.();
68049
+ disposeSemanticSubscription?.();
68050
+ controller?.dispose();
68051
+ await params.runtime?.sessionManager.save();
68052
+ trace?.flush();
68053
+ }
68054
+
67523
68055
  // src/cli.ts
67524
68056
  enableEarlyLogBuffer();
67525
68057
  var logError = (msg, err) => {
@@ -67567,6 +68099,7 @@ Config Files:
67567
68099
  Print Mode Options:
67568
68100
  --raw-output Print assistant text only in non-interactive mode
67569
68101
  --json-output Print structured JSON in non-interactive mode
68102
+ --json-events Run JSONL protocol mode over stdin/stdout
67570
68103
  --session-id Reuse or create a specific session in non-interactive mode
67571
68104
  --extension-path Add an extra extension search directory (repeatable)
67572
68105
  `);
@@ -67649,12 +68182,55 @@ function parseRepeatedFlag(args, flag) {
67649
68182
  }
67650
68183
  return values;
67651
68184
  }
68185
+ async function runWithJsonEventsConsoleIsolation(fn) {
68186
+ const originalLog = console.log;
68187
+ const originalInfo = console.info;
68188
+ const originalDebug = console.debug;
68189
+ const redirectToStderr = (...args) => console.error(...args);
68190
+ console.log = redirectToStderr;
68191
+ console.info = redirectToStderr;
68192
+ console.debug = redirectToStderr;
68193
+ try {
68194
+ await fn();
68195
+ } finally {
68196
+ console.log = originalLog;
68197
+ console.info = originalInfo;
68198
+ console.debug = originalDebug;
68199
+ }
68200
+ }
67652
68201
  async function startChat(initialPrompt, testCommand) {
67653
68202
  const rawOutput = process.argv.includes("--raw-output");
67654
68203
  const jsonOutput = process.argv.includes("--json-output");
68204
+ const jsonEvents = process.argv.includes("--json-events");
67655
68205
  const sessionIdFlagIndex = process.argv.indexOf("--session-id");
67656
68206
  const explicitSessionId = sessionIdFlagIndex >= 0 ? process.argv[sessionIdFlagIndex + 1] : void 0;
67657
68207
  const extensionPaths = parseRepeatedFlag(process.argv, "--extension-path");
68208
+ if (jsonEvents) {
68209
+ await runWithJsonEventsConsoleIsolation(async () => {
68210
+ if (process.env.PIE_TEST_MOCK_RESPONSE !== void 0) {
68211
+ await runJsonEventsMode({
68212
+ explicitSessionId,
68213
+ mockResponse: process.env.PIE_TEST_MOCK_RESPONSE
68214
+ });
68215
+ return;
68216
+ }
68217
+ let runtime2;
68218
+ try {
68219
+ runtime2 = await composeCliRuntime({ explicitSessionId, extensionPaths });
68220
+ } catch (error) {
68221
+ if (error instanceof CliMissingApiKeyError) {
68222
+ await runJsonEventsMode({
68223
+ explicitSessionId,
68224
+ startupError: error.message
68225
+ });
68226
+ return;
68227
+ }
68228
+ throw error;
68229
+ }
68230
+ await runJsonEventsMode({ runtime: runtime2, explicitSessionId });
68231
+ });
68232
+ return;
68233
+ }
67658
68234
  if (initialPrompt && process.env.PIE_TEST_MOCK_RESPONSE !== void 0) {
67659
68235
  const text = process.env.PIE_TEST_MOCK_RESPONSE;
67660
68236
  if (jsonOutput) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cydm/pie",
3
- "version": "1.0.13",
3
+ "version": "1.0.14",
4
4
  "description": "Pie AI Agent CLI",
5
5
  "type": "module",
6
6
  "bin": {