@meistrari/remy-cli 1.8.0 → 1.9.0

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 (3) hide show
  1. package/README.md +2 -0
  2. package/dist/remy.js +262 -39
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -44,6 +44,8 @@ Use `Tab` while writing the request to complete a local file path. Remy attaches
44
44
 
45
45
  Use Up/Down to select a session in the dashboard, Left/Right to load the adjacent page, and `Enter` to open it. After the dashboard list or repository-review list has focus, Vim keys work too: `j`/`k` move, `h`/`l` go to the previous/next dashboard page (or clear/mark a repository), `G` goes to the last row, and `gg` goes to the first row. Press `Shift+L` in the dashboard to start a logout confirmation. In a session, type a follow-up and press `Enter` to send it.
46
46
 
47
+ The **Live reasoning preview** shows the newest main-agent summary as it arrives. It is a short, best-effort preview—not private chain-of-thought. Long previews show **Preview shortened.** Opening or reconnecting partway through a summary may show no preview; the final summary still appears in activity history. Disconnecting or finishing the item clears the live preview.
48
+
47
49
  Published files and Tela Pages appear in the timeline. A Tela Page row includes its title and canonical URL so you can open it directly from the terminal.
48
50
 
49
51
  When Remy creates a plan, the session shows its checklist in the timeline and keeps `Plan <done>/<total>` with the current item pinned above the composer. Updates change the same checklist instead of producing repeated rows, and an unfinished plan remains visible after reconnecting or between turns. The collapsed timeline shows up to five plan items; press `Ctrl+O` for the complete checklist and activity detail.
package/dist/remy.js CHANGED
@@ -32991,7 +32991,8 @@ async function* streamSessionEvents({
32991
32991
  sessionId,
32992
32992
  lastRetainedEventId,
32993
32993
  maxReconnects = 0,
32994
- signal
32994
+ signal,
32995
+ onSynchronized
32995
32996
  }) {
32996
32997
  let retainedCursor = lastRetainedEventId;
32997
32998
  let reconnects = 0;
@@ -33005,7 +33006,7 @@ async function* streamSessionEvents({
33005
33006
  });
33006
33007
  if (!response.body)
33007
33008
  throw new CodingAgentProtocolError("Session event stream response did not include a readable body.");
33008
- for await (const frame of parseSessionEventStream(response.body)) {
33009
+ for await (const frame of parseSessionEventStream(response.body, { onSynchronized })) {
33009
33010
  if (frame.kind === "retained")
33010
33011
  retainedCursor = frame.id;
33011
33012
  yield frame;
@@ -33015,21 +33016,33 @@ async function* streamSessionEvents({
33015
33016
  reconnects += 1;
33016
33017
  }
33017
33018
  }
33018
- async function* parseSessionEventStream(stream) {
33019
- for await (const message of parseServerSentEvents(stream)) {
33019
+ async function* parseSessionEventStream(stream, { onSynchronized } = {}) {
33020
+ for await (const message of parseServerSentEvents(stream, { onSynchronized })) {
33020
33021
  if (message.event !== undefined && message.event !== "session-event")
33021
33022
  continue;
33022
33023
  yield parseSessionEventMessage(message);
33023
33024
  }
33024
33025
  }
33025
- async function* parseServerSentEvents(stream) {
33026
+ async function* parseServerSentEvents(stream, { onSynchronized }) {
33026
33027
  const decoder2 = new TextDecoder;
33027
33028
  const reader = stream.getReader();
33028
33029
  let buffer = "";
33029
33030
  let messageId;
33030
33031
  let eventName;
33031
33032
  let dataLines = [];
33032
- function dispatch() {
33033
+ let frameLineCount = 0;
33034
+ let hasSynchronizationComment = false;
33035
+ let synchronized = false;
33036
+ function dispatch(completeFrame) {
33037
+ const isSynchronizationFrame = completeFrame && frameLineCount === 1 && hasSynchronizationComment;
33038
+ frameLineCount = 0;
33039
+ hasSynchronizationComment = false;
33040
+ if (isSynchronizationFrame) {
33041
+ if (synchronized)
33042
+ throw new CodingAgentProtocolError("Session event stream contained more than one synchronization marker.");
33043
+ synchronized = true;
33044
+ onSynchronized?.();
33045
+ }
33033
33046
  if (dataLines.length === 0) {
33034
33047
  messageId = undefined;
33035
33048
  eventName = undefined;
@@ -33048,7 +33061,10 @@ async function* parseServerSentEvents(stream) {
33048
33061
  }
33049
33062
  function applyLine(line) {
33050
33063
  if (line === "")
33051
- return dispatch();
33064
+ return dispatch(true);
33065
+ frameLineCount += 1;
33066
+ if (line === ": synchronized")
33067
+ hasSynchronizationComment = true;
33052
33068
  if (line.startsWith(":"))
33053
33069
  return null;
33054
33070
  const separatorIndex = line.indexOf(":");
@@ -33086,7 +33102,7 @@ async function* parseServerSentEvents(stream) {
33086
33102
  if (message)
33087
33103
  yield message;
33088
33104
  }
33089
- const finalMessage = dispatch();
33105
+ const finalMessage = dispatch(false);
33090
33106
  if (finalMessage)
33091
33107
  yield finalMessage;
33092
33108
  } finally {
@@ -33860,10 +33876,6 @@ var agentMessageDeltaEventSchema = exports_external2.object({
33860
33876
  type: exports_external2.literal("agent.message.delta"),
33861
33877
  payload: exports_external2.object({ role: exports_external2.string(), delta: exports_external2.string() }).passthrough()
33862
33878
  }).passthrough();
33863
- var agentReasoningSummaryDeltaEventSchema = exports_external2.object({
33864
- type: exports_external2.literal("agent.reasoning.summary.delta"),
33865
- payload: exports_external2.object({ text: exports_external2.string() }).passthrough()
33866
- }).passthrough();
33867
33879
  var publicMessageContentSegmentSchema = exports_external2.discriminatedUnion("type", [
33868
33880
  exports_external2.strictObject({ type: exports_external2.literal("text"), text: exports_external2.string() }),
33869
33881
  exports_external2.strictObject({
@@ -33966,13 +33978,6 @@ function projectEphemeralEvent({ state, event }) {
33966
33978
  previews: { ...state.previews, assistantText: state.previews.assistantText + messageDelta.data.payload.delta }
33967
33979
  };
33968
33980
  }
33969
- const reasoningDelta = agentReasoningSummaryDeltaEventSchema.safeParse(event);
33970
- if (reasoningDelta.success) {
33971
- return {
33972
- ...state,
33973
- previews: { ...state.previews, reasoningText: state.previews.reasoningText + reasoningDelta.data.payload.text }
33974
- };
33975
- }
33976
33981
  return state;
33977
33982
  }
33978
33983
  function projectRetainedEvent({
@@ -34120,8 +34125,7 @@ function projectDurableAgentEvent({ state, event, occurredAt, retainedEventId })
34120
34125
  retainedTurnStarts: { ...state.retainedTurnStarts, [agentEvent.turnId]: { actorType: agentEvent.actor.type, startedAt: occurredAt } },
34121
34126
  messageTurns: Object.fromEntries(Object.entries(state.messageTurns).map(([messageId, turn]) => [messageId, turn.turnId === agentEvent.turnId ? { ...turn, startedAt: occurredAt } : turn]))
34122
34127
  } : state;
34123
- const stateWithCompletedReasoning = agentEvent.type === "agent.reasoning.ended" ? { ...stateWithTurnStart, previews: { ...stateWithTurnStart.previews, reasoningText: "" } } : stateWithTurnStart;
34124
- return appendActivity({ state: stateWithCompletedReasoning, retainedEventId, occurredAt, card: toAgentActivityCard(agentEvent) });
34128
+ return appendActivity({ state: stateWithTurnStart, retainedEventId, occurredAt, card: toAgentActivityCard(agentEvent) });
34125
34129
  }
34126
34130
  function projectAgentWorkObserved({
34127
34131
  state,
@@ -34311,6 +34315,16 @@ var terminalControlPattern = /[\u0000-\u0008\u000B-\u001F\u007F-\u009F]/g;
34311
34315
  function stripAnsi(value) {
34312
34316
  return value.replace(ansiEscapePattern, "").replace(terminalControlPattern, "");
34313
34317
  }
34318
+ function formatReasoningPreview(item) {
34319
+ if (item.status === "absent")
34320
+ return "";
34321
+ const preview = stripAnsi(item.text).trim();
34322
+ if (!item.truncated)
34323
+ return preview;
34324
+ return preview.length > 0 ? `${preview}
34325
+
34326
+ Preview shortened.` : "Preview shortened.";
34327
+ }
34314
34328
  function providerText(raw, fallback) {
34315
34329
  const cleaned = stripAnsi(raw ?? "").trim();
34316
34330
  return cleaned.length > 0 ? cleaned : fallback;
@@ -34328,6 +34342,127 @@ function toSessionPullRequest(detail) {
34328
34342
  return pullRequest ? { number: pullRequest.number, status: pullRequest.status, draft: pullRequest.draft } : null;
34329
34343
  }
34330
34344
 
34345
+ // src/sessions/reasoning-preview.ts
34346
+ var maximumPrefixLength = 2000;
34347
+ var absentItem = { status: "absent" };
34348
+ function initialReasoningPreviewState() {
34349
+ return {
34350
+ synchronized: false,
34351
+ sequenceFloor: -1,
34352
+ runtime: "active",
34353
+ lastSessionStartedEventId: null,
34354
+ item: absentItem
34355
+ };
34356
+ }
34357
+ function reduceReasoningPreview(state, input) {
34358
+ if (input.type === "synchronized")
34359
+ return state.synchronized ? state : { ...state, synchronized: true };
34360
+ const event = input.event;
34361
+ if (event.type === "agent.session.started") {
34362
+ if (event.eventId === state.lastSessionStartedEventId)
34363
+ return state;
34364
+ return {
34365
+ ...state,
34366
+ sequenceFloor: event.sequence,
34367
+ runtime: "active",
34368
+ lastSessionStartedEventId: event.eventId,
34369
+ item: absentItem
34370
+ };
34371
+ }
34372
+ if (event.type === "agent.session.ended") {
34373
+ return {
34374
+ ...state,
34375
+ sequenceFloor: Math.max(state.sequenceFloor, event.sequence),
34376
+ runtime: "ended",
34377
+ item: absentItem
34378
+ };
34379
+ }
34380
+ if (!isMainReasoningOrTurnEvent(event) || state.runtime === "ended")
34381
+ return state;
34382
+ const matchingRetainedEnd = state.item.status === "active" && state.item.turnId === event.turnId && (event.type === "agent.turn.ended" || event.type === "agent.reasoning.ended" && state.item.reasoningId === event.payload.reasoningId);
34383
+ if (event.sequence <= state.sequenceFloor && !matchingRetainedEnd)
34384
+ return state;
34385
+ const advancedState = { ...state, sequenceFloor: Math.max(state.sequenceFloor, event.sequence) };
34386
+ switch (event.type) {
34387
+ case "agent.reasoning.started": {
34388
+ if (!state.synchronized)
34389
+ return advancedState;
34390
+ if (state.item.status === "active" && sameReasoningItem({ item: state.item, turnId: event.turnId, reasoningId: event.payload.reasoningId })) {
34391
+ return advancedState;
34392
+ }
34393
+ return {
34394
+ ...advancedState,
34395
+ item: {
34396
+ status: "active",
34397
+ turnId: event.turnId,
34398
+ reasoningId: event.payload.reasoningId,
34399
+ text: "",
34400
+ truncated: false
34401
+ }
34402
+ };
34403
+ }
34404
+ case "agent.reasoning.summary.delta": {
34405
+ if (state.item.status !== "active" || !sameReasoningItem({ item: state.item, turnId: event.turnId, reasoningId: event.payload.reasoningId })) {
34406
+ return advancedState;
34407
+ }
34408
+ return {
34409
+ ...advancedState,
34410
+ item: appendBoundedPrefix(state.item, event.payload.text)
34411
+ };
34412
+ }
34413
+ case "agent.reasoning.ended": {
34414
+ if (state.item.status !== "active" || !sameReasoningItem({ item: state.item, turnId: event.turnId, reasoningId: event.payload.reasoningId })) {
34415
+ return advancedState;
34416
+ }
34417
+ return { ...advancedState, item: absentItem };
34418
+ }
34419
+ case "agent.turn.started": {
34420
+ if (state.item.status === "active" && state.item.turnId !== event.turnId)
34421
+ return { ...advancedState, item: absentItem };
34422
+ return advancedState;
34423
+ }
34424
+ case "agent.turn.ended": {
34425
+ if (state.item.status === "active" && state.item.turnId === event.turnId)
34426
+ return { ...advancedState, item: absentItem };
34427
+ return advancedState;
34428
+ }
34429
+ }
34430
+ }
34431
+ function isMainReasoningOrTurnEvent(event) {
34432
+ if (event.type !== "agent.reasoning.started" && event.type !== "agent.reasoning.summary.delta" && event.type !== "agent.reasoning.ended" && event.type !== "agent.turn.started" && event.type !== "agent.turn.ended") {
34433
+ return false;
34434
+ }
34435
+ return event.actor.type === "main";
34436
+ }
34437
+ function sameReasoningItem({
34438
+ item,
34439
+ turnId,
34440
+ reasoningId
34441
+ }) {
34442
+ return item.turnId === turnId && item.reasoningId === reasoningId;
34443
+ }
34444
+ function appendBoundedPrefix(item, text) {
34445
+ if (item.truncated)
34446
+ return item;
34447
+ const availableLength = maximumPrefixLength - item.text.length;
34448
+ let retainedLength = Math.min(availableLength, text.length);
34449
+ const reachesSizeBound = item.text.length + retainedLength === maximumPrefixLength;
34450
+ if (reachesSizeBound && retainedLength > 0 && isHighSurrogate(text.charCodeAt(retainedLength - 1)))
34451
+ retainedLength -= 1;
34452
+ const discardedInput = retainedLength < text.length;
34453
+ if (retainedLength === 0) {
34454
+ return discardedInput && !item.truncated ? { ...item, truncated: true } : item;
34455
+ }
34456
+ return {
34457
+ ...item,
34458
+ text: item.text + text.slice(0, retainedLength),
34459
+ truncated: item.truncated || discardedInput
34460
+ };
34461
+ }
34462
+ function isHighSurrogate(codeUnit) {
34463
+ return codeUnit >= 55296 && codeUnit <= 56319;
34464
+ }
34465
+
34331
34466
  // src/sessions/session-controller.ts
34332
34467
  var remoteSessionReconnectPolicy = {
34333
34468
  initialBackoffMs: 1000,
@@ -34366,6 +34501,9 @@ function createRemoteSessionController(dependencies) {
34366
34501
  let stopped = false;
34367
34502
  let state;
34368
34503
  let cachedLastRetainedEventId;
34504
+ let reasoningPreviewState = initialReasoningPreviewState();
34505
+ let reasoningConnectionGeneration = 0;
34506
+ let reasoningHistorySequenceFloor = -1;
34369
34507
  async function start(input) {
34370
34508
  stopped = false;
34371
34509
  ready = new Promise((resolve) => {
@@ -34379,14 +34517,17 @@ function createRemoteSessionController(dependencies) {
34379
34517
  });
34380
34518
  resolveReady();
34381
34519
  publishState();
34382
- if (input.mode === "cold-resume")
34383
- await hydrateRetainedHistoryFromBeginning();
34520
+ if (input.mode === "cold-resume") {
34521
+ const hydrationGeneration = beginReasoningAttempt();
34522
+ await hydrateRetainedHistoryFromBeginning(hydrationGeneration);
34523
+ }
34384
34524
  await streamWithControllerReconnects();
34385
34525
  }
34386
34526
  function stop() {
34387
34527
  if (stopped)
34388
34528
  return;
34389
34529
  stopped = true;
34530
+ invalidateReasoningAttempt({ publish: true });
34390
34531
  abortController.abort(new Error("Remote session controller stopped."));
34391
34532
  }
34392
34533
  function subscribe(listener) {
@@ -34421,10 +34562,14 @@ function createRemoteSessionController(dependencies) {
34421
34562
  publishState();
34422
34563
  }
34423
34564
  function updateDetail(detail) {
34565
+ if (detail.status !== "open")
34566
+ invalidateReasoningAttempt({ publish: false });
34424
34567
  state = updateSessionDetail({ state: getState(), detail });
34568
+ if (detail.status !== "open")
34569
+ state = withoutReasoningPreview(state);
34425
34570
  publishState();
34426
34571
  }
34427
- async function hydrateRetainedHistoryFromBeginning() {
34572
+ async function hydrateRetainedHistoryFromBeginning(generation) {
34428
34573
  let after;
34429
34574
  while (true) {
34430
34575
  if (stopped)
@@ -34436,10 +34581,13 @@ function createRemoteSessionController(dependencies) {
34436
34581
  });
34437
34582
  for (const item of page.data) {
34438
34583
  await reduceFrameAndPersist({
34439
- kind: "retained",
34440
- id: String(item.history_sequence),
34441
- event: "session-event",
34442
- data: item
34584
+ frame: {
34585
+ kind: "retained",
34586
+ id: String(item.history_sequence),
34587
+ event: "session-event",
34588
+ data: item
34589
+ },
34590
+ generation
34443
34591
  });
34444
34592
  }
34445
34593
  if (!page.has_more || !page.next_cursor)
@@ -34453,27 +34601,33 @@ function createRemoteSessionController(dependencies) {
34453
34601
  while (true) {
34454
34602
  if (stopped)
34455
34603
  return;
34604
+ const generation = beginReasoningAttempt();
34456
34605
  state = markSessionConnected(getState());
34457
34606
  publishState();
34458
34607
  try {
34459
34608
  const stream = await dependencies.openEventStream({
34460
34609
  sessionId: dependencies.sessionId,
34461
34610
  lastRetainedEventId: cachedLastRetainedEventId,
34462
- signal: abortController.signal
34611
+ signal: abortController.signal,
34612
+ onSynchronized: () => synchronizeReasoningAttempt(generation)
34463
34613
  });
34464
34614
  for await (const frame of stream) {
34465
34615
  if (stopped)
34466
34616
  return;
34467
- await reduceFrameAndPersist(frame);
34617
+ await reduceFrameAndPersist({ frame, generation });
34468
34618
  }
34619
+ endReasoningAttempt(generation);
34469
34620
  } catch (error93) {
34621
+ endReasoningAttempt(generation);
34470
34622
  if (stopped)
34471
34623
  return;
34472
34624
  if (error93 instanceof Error && error93.name === "SessionProjectionProtocolError")
34473
34625
  throw error93;
34626
+ const refreshGeneration = reasoningConnectionGeneration;
34474
34627
  const detail = await dependencies.getSession({ sessionId: dependencies.sessionId });
34475
- state = updateSessionDetail({ state: getState(), detail });
34476
- publishState();
34628
+ if (stopped || refreshGeneration !== reasoningConnectionGeneration)
34629
+ return;
34630
+ updateDetail(detail);
34477
34631
  }
34478
34632
  if (stopped)
34479
34633
  return;
@@ -34499,17 +34653,86 @@ function createRemoteSessionController(dependencies) {
34499
34653
  backoffMs = Math.min(backoffMs * 2, reconnectPolicy.maxBackoffMs);
34500
34654
  }
34501
34655
  }
34502
- async function reduceFrameAndPersist(frame) {
34503
- const nextState = projectRemoteSessionEvent({ state: getState(), frame });
34656
+ async function reduceFrameAndPersist({ frame, generation }) {
34657
+ const previousState = getState();
34658
+ const projectedState = projectRemoteSessionEvent({ state: previousState, frame });
34659
+ state = projectReasoningPreview({ previousState, projectedState, frame, generation });
34504
34660
  if (frame.kind === "retained") {
34505
- state = nextState;
34506
34661
  await writeCache();
34507
- cachedLastRetainedEventId = nextState.lastRetainedEventId;
34662
+ cachedLastRetainedEventId = projectedState.lastRetainedEventId;
34508
34663
  }
34509
- state = nextState;
34510
34664
  resolveCompletedWaiters();
34665
+ if (stopped)
34666
+ return;
34511
34667
  publishState(frame);
34512
34668
  }
34669
+ function projectReasoningPreview({
34670
+ previousState,
34671
+ projectedState,
34672
+ frame,
34673
+ generation
34674
+ }) {
34675
+ if (generation !== reasoningConnectionGeneration || projectedState.aggregateStatus !== "open")
34676
+ return withoutReasoningPreview(projectedState);
34677
+ if (frame.kind === "retained") {
34678
+ if (previousState.seenRetainedEventIds[frame.id])
34679
+ return projectedState;
34680
+ if (frame.data.history_sequence <= reasoningHistorySequenceFloor)
34681
+ return projectedState;
34682
+ reasoningHistorySequenceFloor = frame.data.history_sequence;
34683
+ } else if (frame.data.event.type !== "agent.reasoning.summary.delta") {
34684
+ return projectedState;
34685
+ }
34686
+ if (frame.data.event.type === "agent.message.ended")
34687
+ return projectedState;
34688
+ const parsed = wrappedAgentEventSchema.safeParse(frame.data.event);
34689
+ if (!parsed.success)
34690
+ return projectedState;
34691
+ reasoningPreviewState = reduceReasoningPreview(reasoningPreviewState, { type: "event", event: parsed.data });
34692
+ return {
34693
+ ...projectedState,
34694
+ previews: {
34695
+ ...projectedState.previews,
34696
+ reasoningText: formatReasoningPreview(reasoningPreviewState.item)
34697
+ }
34698
+ };
34699
+ }
34700
+ function beginReasoningAttempt() {
34701
+ reasoningConnectionGeneration += 1;
34702
+ reasoningPreviewState = initialReasoningPreviewState();
34703
+ reasoningHistorySequenceFloor = -1;
34704
+ if (state)
34705
+ state = withoutReasoningPreview(state);
34706
+ return reasoningConnectionGeneration;
34707
+ }
34708
+ function synchronizeReasoningAttempt(generation) {
34709
+ if (stopped || generation !== reasoningConnectionGeneration || getState().aggregateStatus !== "open")
34710
+ return;
34711
+ reasoningPreviewState = reduceReasoningPreview(reasoningPreviewState, { type: "synchronized" });
34712
+ }
34713
+ function endReasoningAttempt(generation) {
34714
+ if (generation !== reasoningConnectionGeneration)
34715
+ return;
34716
+ invalidateReasoningAttempt({ publish: true });
34717
+ }
34718
+ function invalidateReasoningAttempt({ publish }) {
34719
+ reasoningConnectionGeneration += 1;
34720
+ reasoningPreviewState = initialReasoningPreviewState();
34721
+ reasoningHistorySequenceFloor = -1;
34722
+ if (!state || state.previews.reasoningText.length === 0)
34723
+ return;
34724
+ state = withoutReasoningPreview(state);
34725
+ if (publish)
34726
+ publishState();
34727
+ }
34728
+ function withoutReasoningPreview(currentState) {
34729
+ if (currentState.previews.reasoningText.length === 0)
34730
+ return currentState;
34731
+ return {
34732
+ ...currentState,
34733
+ previews: { ...currentState.previews, reasoningText: "" }
34734
+ };
34735
+ }
34513
34736
  async function writeCache() {
34514
34737
  const currentState = getState();
34515
34738
  const cache = {
@@ -37545,7 +37768,7 @@ var compactMarkRows = 9;
37545
37768
  var compactMinWidth = 48;
37546
37769
  var compactMinHeight = 20;
37547
37770
  var markBrightnessGain = 4.2;
37548
- var remyCliVersion = "1.8.0";
37771
+ var remyCliVersion = "1.9.0";
37549
37772
  async function showRemySplash({
37550
37773
  createRenderer = createRemyRenderer,
37551
37774
  durationMs = splashDurationMs,
@@ -38798,7 +39021,7 @@ async function runAttachedSession({
38798
39021
  environment: dependencies.environment,
38799
39022
  getSession: async ({ sessionId: id }) => await operations.getSession({ client: operations.client, sessionId: id }),
38800
39023
  listSessionEvents: async ({ sessionId: id, limit, after }) => await operations.listSessionEvents({ client: operations.client, sessionId: id, limit, after }),
38801
- openEventStream: ({ sessionId: id, lastRetainedEventId, signal }) => operations.streamSessionEvents({ client: operations.client, sessionId: id, lastRetainedEventId, signal })
39024
+ openEventStream: ({ sessionId: id, lastRetainedEventId, signal, onSynchronized }) => operations.streamSessionEvents({ client: operations.client, sessionId: id, lastRetainedEventId, signal, onSynchronized })
38802
39025
  });
38803
39026
  const interactive = !noTui && !json3 && isInteractiveTerminal(dependencies);
38804
39027
  const shouldPrintJson = !interactive || json3;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@meistrari/remy-cli",
3
- "version": "1.8.0",
3
+ "version": "1.9.0",
4
4
  "description": "Remy, the Coding Agent terminal client.",
5
5
  "type": "module",
6
6
  "bin": {