replicas-cli 0.2.453 → 0.2.455

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/index.mjs +94 -70
  2. package/package.json +1 -1
package/dist/index.mjs CHANGED
@@ -10056,7 +10056,7 @@ function formatTurnElapsed(ms) {
10056
10056
  }
10057
10057
 
10058
10058
  // ../shared/src/cli-version.ts
10059
- var CLI_VERSION = "0.2.453";
10059
+ var CLI_VERSION = "0.2.455";
10060
10060
 
10061
10061
  // ../shared/src/version.ts
10062
10062
  function compareVersions(v1, v2) {
@@ -24930,6 +24930,15 @@ function normalizeBackgroundTaskStatus(status) {
24930
24930
  // ../shared/src/display-message/constants.ts
24931
24931
  var USER_MESSAGE_MATCH_GRACE_PERIOD_MS = 3e4;
24932
24932
 
24933
+ // ../shared/src/json.ts
24934
+ function safeJsonParse(str, fallback) {
24935
+ try {
24936
+ return JSON.parse(str);
24937
+ } catch {
24938
+ return fallback;
24939
+ }
24940
+ }
24941
+
24933
24942
  // ../shared/src/display-message/parsers/utils.ts
24934
24943
  var INTERRUPTED_MESSAGE_REGEX = /^\[Request interrupted by user.*\]$/;
24935
24944
  function userMessageImages(value) {
@@ -24946,6 +24955,32 @@ function stringifyDisplayValue(value) {
24946
24955
  return String(value);
24947
24956
  }
24948
24957
  }
24958
+ function upsertDisplayMessage(messages, message) {
24959
+ const index = messages.findIndex((candidate) => candidate.id === message.id);
24960
+ if (index === -1) messages.push(message);
24961
+ else messages[index] = message;
24962
+ }
24963
+ function parseSkillName(tool, input) {
24964
+ if (typeof tool !== "string") return null;
24965
+ const normalizedTool = tool.toLowerCase();
24966
+ if (normalizedTool.startsWith("skill.")) return tool.slice("skill.".length) || null;
24967
+ if (normalizedTool !== "skill") return null;
24968
+ const parsedInput = typeof input === "string" ? safeJsonParse(input, null) : input;
24969
+ if (!isRecord(parsedInput)) return null;
24970
+ const skillName = parsedInput.skill ?? parsedInput.name;
24971
+ return typeof skillName === "string" && skillName ? skillName : null;
24972
+ }
24973
+ function createCallDisplayMessage(message) {
24974
+ const skillName = message.server.toLowerCase() === "skills" ? message.tool : parseSkillName(message.tool, message.input);
24975
+ if (skillName === null) return { ...message, type: "tool_call" };
24976
+ return {
24977
+ id: message.id,
24978
+ type: "skill",
24979
+ skillName,
24980
+ status: message.status,
24981
+ timestamp: message.timestamp
24982
+ };
24983
+ }
24949
24984
 
24950
24985
  // ../shared/src/display-message/format.ts
24951
24986
  function formatStoppedAfter(durationMs) {
@@ -24962,15 +24997,6 @@ function areUserMessagesWithinMatchWindow(a, b) {
24962
24997
  return a.content === b.content && Math.abs(parseTimestampMs(a.timestamp) - parseTimestampMs(b.timestamp)) <= USER_MESSAGE_MATCH_GRACE_PERIOD_MS;
24963
24998
  }
24964
24999
 
24965
- // ../shared/src/json.ts
24966
- function safeJsonParse(str, fallback) {
24967
- try {
24968
- return JSON.parse(str);
24969
- } catch {
24970
- return fallback;
24971
- }
24972
- }
24973
-
24974
25000
  // ../shared/src/display-message/parsers/codex-parser.ts
24975
25001
  function getStatusFromExitCode(exitCode) {
24976
25002
  return exitCode === 0 ? "completed" : "failed";
@@ -25137,17 +25163,17 @@ function parseCodexEvents(events) {
25137
25163
  const operations = parsePatch(input);
25138
25164
  pendingPatches.set(callId, { input, status, timestamp: event.timestamp, operations });
25139
25165
  } else {
25140
- const msg = {
25141
- id: `toolcall-${callId || getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY) || `${event.timestamp}-${eventIndex}`}`,
25142
- type: "tool_call",
25166
+ const id = `toolcall-${callId || getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY) || `${event.timestamp}-${eventIndex}`}`;
25167
+ const msg = createCallDisplayMessage({
25168
+ id,
25143
25169
  server,
25144
25170
  tool: name,
25145
25171
  input,
25146
25172
  status,
25147
25173
  timestamp: event.timestamp
25148
- };
25174
+ });
25149
25175
  messages.push(msg);
25150
- if (callId) {
25176
+ if (callId && msg.type === "tool_call") {
25151
25177
  pendingToolCalls.set(callId, msg);
25152
25178
  }
25153
25179
  }
@@ -25231,10 +25257,10 @@ function getCursorThinkingText(event) {
25231
25257
  function isTerminalStatus(status) {
25232
25258
  return status === "FINISHED" || status === "ERROR" || status === "CANCELLED" || status === "EXPIRED";
25233
25259
  }
25234
- function finalizeOpenTools(messages, toolIndexes, status) {
25235
- for (const index of toolIndexes.values()) {
25260
+ function finalizeOpenCalls(messages, callIndexes, status) {
25261
+ for (const index of callIndexes.values()) {
25236
25262
  const message = messages[index];
25237
- if (message?.type === "tool_call" && message.status === "in_progress") {
25263
+ if ((message?.type === "tool_call" || message?.type === "skill") && message.status === "in_progress") {
25238
25264
  messages[index] = {
25239
25265
  ...message,
25240
25266
  status
@@ -25244,7 +25270,7 @@ function finalizeOpenTools(messages, toolIndexes, status) {
25244
25270
  }
25245
25271
  function parseCursorEvents(events) {
25246
25272
  const messages = [];
25247
- const toolIndexes = /* @__PURE__ */ new Map();
25273
+ const callIndexes = /* @__PURE__ */ new Map();
25248
25274
  const runAssistantSegments = /* @__PURE__ */ new Map();
25249
25275
  const runThinkingSegments = /* @__PURE__ */ new Map();
25250
25276
  let activeAssistant = null;
@@ -25336,21 +25362,20 @@ function parseCursorEvents(events) {
25336
25362
  const tool = typeof event.payload.name === "string" ? event.payload.name : "tool";
25337
25363
  const status = cursorStatusToDisplayStatus(event.payload.status);
25338
25364
  const input = isRecord(event.payload.args) ? event.payload.args : typeof event.payload.args === "string" ? event.payload.args : void 0;
25339
- const existing = toolIndexes.get(callId);
25340
- const next = {
25365
+ const existing = callIndexes.get(callId);
25366
+ const next = createCallDisplayMessage({
25341
25367
  id: callId,
25342
- type: "tool_call",
25343
25368
  server: "cursor",
25344
25369
  tool,
25345
25370
  ...input !== void 0 ? { input } : {},
25346
25371
  output: stringifyDisplayValue(event.payload.result),
25347
25372
  status,
25348
25373
  timestamp: event.timestamp
25349
- };
25374
+ });
25350
25375
  if (existing === void 0) {
25351
- toolIndexes.set(callId, messages.push(next) - 1);
25376
+ callIndexes.set(callId, messages.push(next) - 1);
25352
25377
  } else {
25353
- messages[existing] = { ...messages[existing], ...next };
25378
+ messages[existing] = next;
25354
25379
  }
25355
25380
  continue;
25356
25381
  }
@@ -25372,7 +25397,7 @@ function parseCursorEvents(events) {
25372
25397
  if (isTerminalStatus(status)) {
25373
25398
  const displayStatus = cursorStatusToDisplayStatus(status);
25374
25399
  finalizeActiveThinking(displayStatus);
25375
- finalizeOpenTools(messages, toolIndexes, displayStatus);
25400
+ finalizeOpenCalls(messages, callIndexes, displayStatus);
25376
25401
  activeThinking = null;
25377
25402
  activeAssistant = null;
25378
25403
  }
@@ -25380,7 +25405,7 @@ function parseCursorEvents(events) {
25380
25405
  }
25381
25406
  if (event.type === "cursor-error") {
25382
25407
  finalizeActiveThinking("failed");
25383
- finalizeOpenTools(messages, toolIndexes, "failed");
25408
+ finalizeOpenCalls(messages, callIndexes, "failed");
25384
25409
  activeAssistant = null;
25385
25410
  activeThinking = null;
25386
25411
  const message = typeof event.payload.message === "string" ? event.payload.message : "Cursor run failed";
@@ -25405,14 +25430,6 @@ function partFromEvent(event) {
25405
25430
  function toolStatus(status) {
25406
25431
  return status === "completed" ? "completed" : status === "error" ? "failed" : "in_progress";
25407
25432
  }
25408
- function setById(messages, id, next) {
25409
- const index = messages.findIndex((message) => message.id === id);
25410
- if (index === -1) {
25411
- messages.push(next);
25412
- } else {
25413
- messages[index] = next;
25414
- }
25415
- }
25416
25433
  function assistantError(info) {
25417
25434
  if (!isRecord(info) || !isRecord(info.error)) return null;
25418
25435
  const data = isRecord(info.error.data) ? info.error.data : null;
@@ -25457,15 +25474,32 @@ function parseOpencodeEvents(events) {
25457
25474
  });
25458
25475
  continue;
25459
25476
  }
25477
+ if (event.type === "opencode-session.next.tool.called") {
25478
+ const tool = typeof event.payload.tool === "string" ? event.payload.tool : "tool";
25479
+ const input = event.payload.input ?? event.payload.arguments;
25480
+ const callId = typeof event.payload.callID === "string" ? event.payload.callID : null;
25481
+ const id2 = callId ? `opencode-${callId}` : `opencode-${event.timestamp}-${messages.length}`;
25482
+ upsertDisplayMessage(messages, createCallDisplayMessage({
25483
+ id: id2,
25484
+ server: "opencode",
25485
+ tool,
25486
+ input: isRecord(input) ? input : stringifyDisplayValue(input),
25487
+ status: "in_progress",
25488
+ timestamp: event.timestamp
25489
+ }));
25490
+ continue;
25491
+ }
25460
25492
  const part = partFromEvent(event);
25461
25493
  if (!part) continue;
25462
- const id = typeof part.id === "string" ? `opencode-${part.id}` : `opencode-${event.timestamp}-${messages.length}`;
25494
+ let id = `opencode-${event.timestamp}-${messages.length}`;
25495
+ if (typeof part.callID === "string") id = `opencode-${part.callID}`;
25496
+ else if (typeof part.id === "string") id = `opencode-${part.id}`;
25463
25497
  const time3 = isRecord(part.time) ? part.time : null;
25464
25498
  const timestamp = timestampFromMs(time3?.start, event.timestamp);
25465
25499
  if (part.type === "text") {
25466
25500
  const text = typeof part.text === "string" ? part.text : "";
25467
25501
  if (text.trim()) {
25468
- setById(messages, id, {
25502
+ upsertDisplayMessage(messages, {
25469
25503
  id,
25470
25504
  type: "agent",
25471
25505
  content: text,
@@ -25477,7 +25511,7 @@ function parseOpencodeEvents(events) {
25477
25511
  if (part.type === "reasoning") {
25478
25512
  const text = typeof part.text === "string" ? part.text : "";
25479
25513
  if (text.trim()) {
25480
- setById(messages, id, {
25514
+ upsertDisplayMessage(messages, {
25481
25515
  id,
25482
25516
  type: "reasoning",
25483
25517
  content: text,
@@ -25490,23 +25524,24 @@ function parseOpencodeEvents(events) {
25490
25524
  if (part.type === "tool" && isRecord(part.state)) {
25491
25525
  const state = part.state;
25492
25526
  const status = toolStatus(state.status);
25527
+ const tool = typeof part.tool === "string" ? part.tool : "tool";
25528
+ const input = state.input;
25493
25529
  const output = state.status === "completed" ? stringifyDisplayValue(state.output) : state.status === "error" ? stringifyDisplayValue(state.error) : void 0;
25494
- setById(messages, id, {
25530
+ upsertDisplayMessage(messages, createCallDisplayMessage({
25495
25531
  id,
25496
- type: "tool_call",
25497
25532
  server: "opencode",
25498
- tool: typeof part.tool === "string" ? part.tool : "tool",
25499
- input: isRecord(state.input) ? state.input : stringifyDisplayValue(state.input),
25533
+ tool,
25534
+ input: isRecord(input) ? input : stringifyDisplayValue(input),
25500
25535
  output,
25501
25536
  status,
25502
25537
  timestamp
25503
- });
25538
+ }));
25504
25539
  continue;
25505
25540
  }
25506
25541
  if (part.type === "patch") {
25507
25542
  const files = Array.isArray(part.files) ? part.files.filter((file2) => typeof file2 === "string") : [];
25508
25543
  if (files.length > 0) {
25509
- setById(messages, id, {
25544
+ upsertDisplayMessage(messages, {
25510
25545
  id,
25511
25546
  type: "file_change",
25512
25547
  changes: files.map((path6) => ({ path: path6, kind: "update" })),
@@ -25523,11 +25558,6 @@ function parseOpencodeEvents(events) {
25523
25558
  function nestedPayload(event) {
25524
25559
  return isRecord(event.payload.assistantMessageEvent) ? event.payload.assistantMessageEvent : event.payload;
25525
25560
  }
25526
- function setById2(messages, id, message) {
25527
- const index = messages.findIndex((candidate) => candidate.id === id);
25528
- if (index === -1) messages.push(message);
25529
- else messages[index] = message;
25530
- }
25531
25561
  function toolStatus2(value) {
25532
25562
  return value === "completed" || value === "success" ? "completed" : value === "error" ? "failed" : "in_progress";
25533
25563
  }
@@ -25563,8 +25593,8 @@ function parsePiEvents(events) {
25563
25593
  if (payload.type === "thinking_delta" && typeof payload.delta === "string") thinking.set(id, `${thinking.get(id) ?? ""}${payload.delta}`);
25564
25594
  const textContent = text.get(id);
25565
25595
  const thinkingContent = thinking.get(id);
25566
- if (textContent !== void 0) setById2(messages, `pi-${id}`, { id: `pi-${id}`, type: "agent", content: textContent, timestamp: event.timestamp });
25567
- if (thinkingContent !== void 0) setById2(messages, `pi-thinking-${id}`, { id: `pi-thinking-${id}`, type: "reasoning", content: thinkingContent, status: "in_progress", timestamp: event.timestamp });
25596
+ if (textContent !== void 0) upsertDisplayMessage(messages, { id: `pi-${id}`, type: "agent", content: textContent, timestamp: event.timestamp });
25597
+ if (thinkingContent !== void 0) upsertDisplayMessage(messages, { id: `pi-thinking-${id}`, type: "reasoning", content: thinkingContent, status: "in_progress", timestamp: event.timestamp });
25568
25598
  continue;
25569
25599
  }
25570
25600
  if (event.type === "pi-message_start") {
@@ -25576,16 +25606,18 @@ function parsePiEvents(events) {
25576
25606
  const payload = event.payload;
25577
25607
  const input = payload.args ?? payload.input;
25578
25608
  const id = typeof payload.toolCallId === "string" ? payload.toolCallId : typeof payload.id === "string" ? payload.id : `tool-${event.timestamp}`;
25579
- setById2(messages, `pi-tool-${id}`, {
25580
- id: `pi-tool-${id}`,
25581
- type: "tool_call",
25609
+ const tool = typeof payload.toolName === "string" ? payload.toolName : "tool";
25610
+ const messageId = `pi-tool-${id}`;
25611
+ const status = event.type === "pi-tool_execution_end" ? toolStatus2(payload.isError ? "error" : "completed") : "in_progress";
25612
+ upsertDisplayMessage(messages, createCallDisplayMessage({
25613
+ id: messageId,
25582
25614
  server: "pi",
25583
- tool: typeof payload.toolName === "string" ? payload.toolName : "tool",
25615
+ tool,
25584
25616
  input: isRecord(input) ? input : stringifyDisplayValue(input),
25585
25617
  output: event.type === "pi-tool_execution_end" ? stringifyDisplayValue(payload.result ?? payload.error) : void 0,
25586
- status: event.type === "pi-tool_execution_end" ? toolStatus2(payload.isError ? "error" : "completed") : "in_progress",
25618
+ status,
25587
25619
  timestamp: event.timestamp
25588
- });
25620
+ }));
25589
25621
  }
25590
25622
  }
25591
25623
  return messages;
@@ -25751,14 +25783,6 @@ function isClaudeResultError(payload) {
25751
25783
  if (payload.errors?.length && stripAgentDiagnosticErrors(payload.errors).length === 0) return false;
25752
25784
  return Boolean(payload.is_error) || payload.subtype !== "success";
25753
25785
  }
25754
- function upsertDisplayMessage(messages, message) {
25755
- const index = messages.findIndex((existing) => existing.id === message.id);
25756
- if (index === -1) {
25757
- messages.push(message);
25758
- } else {
25759
- messages[index] = message;
25760
- }
25761
- }
25762
25786
  var LOCAL_COMMAND_ECHO_REGEX = /^<(?:command-name|command-message|local-command-stdout|local-command-stderr)>/;
25763
25787
  function parseClaudeEvents(events, parentToolUseId) {
25764
25788
  const messages = [];
@@ -26041,7 +26065,7 @@ function parseClaudeEvents(events, parentToolUseId) {
26041
26065
  } else if (toolName === "Skill") {
26042
26066
  const inputObj = typeof toolInput === "string" ? safeJsonParse(toolInput, {}) : toolInput;
26043
26067
  messages.push({
26044
- id: `skill-${event.timestamp}-${messages.length}`,
26068
+ id: `skill-${toolUseId}`,
26045
26069
  type: "skill",
26046
26070
  skillName: inputObj.skill || "unknown",
26047
26071
  args: inputObj.args,
@@ -26316,16 +26340,15 @@ function messageForItem(item) {
26316
26340
  };
26317
26341
  }
26318
26342
  if (item.type === "toolCall") {
26319
- return {
26343
+ return createCallDisplayMessage({
26320
26344
  id: `toolcall-${item.id}`,
26321
- type: "tool_call",
26322
26345
  server: item.server,
26323
26346
  tool: item.tool,
26324
26347
  input: inputForDisplay(item.input),
26325
26348
  output: item.output,
26326
26349
  status: normalizeCodexAspTranscriptStatus(item.status),
26327
26350
  timestamp: item.timestamp
26328
- };
26351
+ });
26329
26352
  }
26330
26353
  if (item.type === "subagent") {
26331
26354
  return {
@@ -26458,7 +26481,8 @@ function parseAgentEvents(events, agentType) {
26458
26481
  }
26459
26482
  function parseDisplayMessages(events, agentType, codexAspTranscript, options = {}) {
26460
26483
  const shouldFilter = options.filter ?? true;
26461
- const legacyMessages = shouldFilter ? filterDisplayMessages(parseAgentEvents(events, agentType), agentType) : parseAgentEvents(events, agentType);
26484
+ const parsedEvents = agentType === "claude" || agentType === "relay" ? parseClaudeEvents(events, options.parentToolUseId) : parseAgentEvents(events, agentType);
26485
+ const legacyMessages = shouldFilter ? filterDisplayMessages(parsedEvents, agentType) : parsedEvents;
26462
26486
  if (agentType !== "codex" || !codexAspTranscript) {
26463
26487
  return shouldFilter ? applyInterruptions(legacyMessages, events) : legacyMessages;
26464
26488
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.453",
3
+ "version": "0.2.455",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.mjs",
6
6
  "bin": {