replicas-cli 0.3.218 → 0.3.220

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.cjs +65 -30
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -20178,6 +20178,15 @@ var init_preferences = __esm({
20178
20178
  }
20179
20179
  });
20180
20180
 
20181
+ // ../shared/src/default-skills/replicas-agent/index.ts
20182
+ var init_replicas_agent = __esm({
20183
+ "../shared/src/default-skills/replicas-agent/index.ts"() {
20184
+ "use strict";
20185
+ init_registry();
20186
+ init_registry();
20187
+ }
20188
+ });
20189
+
20181
20190
  // ../shared/src/prompts.ts
20182
20191
  function removeTag(text3, tag) {
20183
20192
  const regex = new RegExp(`<${tag}>[\\s\\S]*?</${tag}>`, "g");
@@ -20197,6 +20206,7 @@ var init_prompts = __esm({
20197
20206
  init_scout();
20198
20207
  init_preferences();
20199
20208
  init_registry();
20209
+ init_replicas_agent();
20200
20210
  init_slack_response_style();
20201
20211
  init_slack_response_style();
20202
20212
  REPLICAS_INSTRUCTIONS_TAG = "replicas_instructions";
@@ -29942,6 +29952,33 @@ function readClaudeUserPrompt(payload, content) {
29942
29952
  }
29943
29953
  function parseClaudeEvents(events, parentToolUseId) {
29944
29954
  const messages = [];
29955
+ const indexesById = /* @__PURE__ */ new Map();
29956
+ let indexedCount = 0;
29957
+ const indexesOf = (id) => {
29958
+ for (; indexedCount < messages.length; indexedCount++) {
29959
+ const indexes = indexesById.get(messages[indexedCount].id);
29960
+ if (indexes) indexes.push(indexedCount);
29961
+ else indexesById.set(messages[indexedCount].id, [indexedCount]);
29962
+ }
29963
+ return indexesById.get(id) ?? [];
29964
+ };
29965
+ const replaceMessage = (index, message2) => {
29966
+ const previousId = messages[index].id;
29967
+ messages[index] = message2;
29968
+ if (index >= indexedCount || previousId === message2.id) return;
29969
+ const previous = indexesById.get(previousId);
29970
+ if (!previous) throw new Error(`Chat message ${previousId} is missing from the id index`);
29971
+ previous.splice(previous.indexOf(index), 1);
29972
+ const next = indexesById.get(message2.id);
29973
+ if (!next) indexesById.set(message2.id, [index]);
29974
+ else next.splice(next.filter((other) => other < index).length, 0, index);
29975
+ };
29976
+ const upsertMessage = (message2) => {
29977
+ const [index] = indexesOf(message2.id);
29978
+ if (index === void 0) messages.push(message2);
29979
+ else replaceMessage(index, message2);
29980
+ return message2;
29981
+ };
29945
29982
  const filterValue = parentToolUseId !== void 0 ? parentToolUseId : null;
29946
29983
  const filteredEvents = events.filter((e) => {
29947
29984
  const eventParentToolUseId = e.payload.parent_tool_use_id ?? null;
@@ -29972,13 +30009,14 @@ function parseClaudeEvents(events, parentToolUseId) {
29972
30009
  const stampedUserMessages = /* @__PURE__ */ new Set();
29973
30010
  const findMatchingUserMessageIndex = (indexes, content, timestamp, messageId) => {
29974
30011
  if (typeof messageId === "string") {
29975
- const byId = messages.findIndex((message2, index) => message2.type === "user" && message2.id === messageId && !supersededUserMessageIndexes.has(index));
29976
- if (byId !== -1) return byId;
30012
+ const byId = indexesOf(messageId).find((index) => messages[index].type === "user" && !supersededUserMessageIndexes.has(index));
30013
+ if (byId !== void 0) return byId;
29977
30014
  }
29978
- return [...indexes].find((index) => {
30015
+ for (const index of indexes) {
29979
30016
  const message2 = messages[index];
29980
- return message2?.type === "user" && !(typeof messageId === "string" && stampedUserMessages.has(message2)) && areUserMessagesWithinMatchWindow(message2, { content, timestamp });
29981
- });
30017
+ if (message2?.type === "user" && !(typeof messageId === "string" && stampedUserMessages.has(message2)) && areUserMessagesWithinMatchWindow(message2, { content, timestamp })) return index;
30018
+ }
30019
+ return void 0;
29982
30020
  };
29983
30021
  const taskAccumulator = new TaskAccumulator();
29984
30022
  let nestedEventsByParent;
@@ -30007,7 +30045,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30007
30045
  if (canonicalIndex === void 0) {
30008
30046
  acceptedUserMessageIndexes.add(messages.push(message2) - 1);
30009
30047
  } else {
30010
- messages[canonicalIndex] = message2;
30048
+ replaceMessage(canonicalIndex, message2);
30011
30049
  canonicalUserMessageIndexes.delete(canonicalIndex);
30012
30050
  }
30013
30051
  if (typeof messageId === "string" || canonical && stampedUserMessages.has(canonical)) stampedUserMessages.add(message2);
@@ -30031,7 +30069,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30031
30069
  status: payload.status,
30032
30070
  timestamp: event.timestamp
30033
30071
  };
30034
- if (existing.reasoning !== void 0) messages[existing.reasoning] = reasoningMessage;
30072
+ if (existing.reasoning !== void 0) replaceMessage(existing.reasoning, reasoningMessage);
30035
30073
  else existing.reasoning = messages.push(reasoningMessage) - 1;
30036
30074
  }
30037
30075
  if (payload.text && !completedStreamIds.has(payload.streamId)) {
@@ -30041,7 +30079,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30041
30079
  content: payload.text,
30042
30080
  timestamp: event.timestamp
30043
30081
  };
30044
- if (existing.agent !== void 0) messages[existing.agent] = agentMessage;
30082
+ if (existing.agent !== void 0) replaceMessage(existing.agent, agentMessage);
30045
30083
  else existing.agent = messages.push(agentMessage) - 1;
30046
30084
  }
30047
30085
  if (payload.tool) streamingTools.set(payload.streamId, { tool: payload.tool, timestamp: event.timestamp });
@@ -30098,7 +30136,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30098
30136
  acceptedUserMessageIndexes.delete(acceptedIndex);
30099
30137
  canonicalUserMessageIndexes.add(messages.push(message2) - 1);
30100
30138
  } else {
30101
- messages[acceptedIndex] = message2;
30139
+ replaceMessage(acceptedIndex, message2);
30102
30140
  }
30103
30141
  if (typeof stampedId === "string" || accepted && stampedUserMessages.has(accepted)) stampedUserMessages.add(message2);
30104
30142
  }
@@ -30110,7 +30148,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30110
30148
  const localCommand = event.payload.local_command_run;
30111
30149
  const goalArgs = isRecord(localCommand) && localCommand.command === GOAL_TOOL_NAME && typeof localCommand.args === "string" ? localCommand.args.trim() : "";
30112
30150
  if (goalArgs) {
30113
- upsertDisplayMessage(messages, {
30151
+ upsertMessage({
30114
30152
  id: `goal-${messageKey}`,
30115
30153
  type: "tool_call",
30116
30154
  server: "claude",
@@ -30146,10 +30184,10 @@ function parseClaudeEvents(events, parentToolUseId) {
30146
30184
  timestamp: event.timestamp
30147
30185
  };
30148
30186
  if (streamRefs?.reasoning !== void 0) {
30149
- messages[streamRefs.reasoning] = reasoningMessage;
30187
+ replaceMessage(streamRefs.reasoning, reasoningMessage);
30150
30188
  streamRefs.reasoning = void 0;
30151
30189
  } else {
30152
- upsertDisplayMessage(messages, reasoningMessage);
30190
+ upsertMessage(reasoningMessage);
30153
30191
  }
30154
30192
  }
30155
30193
  contentBlocks.forEach((block) => {
@@ -30163,10 +30201,10 @@ function parseClaudeEvents(events, parentToolUseId) {
30163
30201
  timestamp: event.timestamp
30164
30202
  };
30165
30203
  if (streamRefs?.agent !== void 0) {
30166
- messages[streamRefs.agent] = agentMessage;
30204
+ replaceMessage(streamRefs.agent, agentMessage);
30167
30205
  streamRefs.agent = void 0;
30168
30206
  } else {
30169
- upsertDisplayMessage(messages, agentMessage);
30207
+ upsertMessage(agentMessage);
30170
30208
  }
30171
30209
  }
30172
30210
  if (block.type === "tool_use" && block.id) {
@@ -30260,7 +30298,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30260
30298
  if (event.type === "claude-result") {
30261
30299
  const payload = coerceClaudeResultPayload(event.payload);
30262
30300
  const last = messages.at(-1);
30263
- if (last?.type === "agent") messages[messages.length - 1] = { ...last, endsTurn: true };
30301
+ if (last?.type === "agent") replaceMessage(messages.length - 1, { ...last, endsTurn: true });
30264
30302
  if (isClaudeResultError(payload)) {
30265
30303
  const genuineErrors = stripAgentDiagnosticErrors(payload.errors ?? []);
30266
30304
  messages.push({
@@ -30303,7 +30341,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30303
30341
  nestedEvents: existingWorkflowAgent?.nestedEvents ?? collectNestedEvents(workflowAgent.agentId)
30304
30342
  }
30305
30343
  );
30306
- workflowAgentMessageMap.set(workflowAgent.agentId, upsertDisplayMessage(messages, nextWorkflowAgent));
30344
+ workflowAgentMessageMap.set(workflowAgent.agentId, upsertMessage(nextWorkflowAgent));
30307
30345
  }
30308
30346
  const existing = taskMessageMap.get(payload.taskId);
30309
30347
  const nextStatus = payload.subtype === "task_notification" ? normalizeBackgroundTaskStatus(payload.status) : payload.subtype === "task_updated" && payload.patch?.status !== void 0 ? normalizeBackgroundTaskStatus(payload.patch?.status) : existing?.status ?? "in_progress";
@@ -30327,7 +30365,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30327
30365
  notifiedAt: payload.subtype === "task_notification" ? event.timestamp : existing?.notifiedAt,
30328
30366
  timestamp: existing?.timestamp ?? event.timestamp
30329
30367
  };
30330
- taskMessageMap.set(payload.taskId, upsertDisplayMessage(messages, nextMessage));
30368
+ taskMessageMap.set(payload.taskId, upsertMessage(nextMessage));
30331
30369
  }
30332
30370
  }
30333
30371
  });
@@ -30396,7 +30434,7 @@ function parseClaudeEvents(events, parentToolUseId) {
30396
30434
  message2.outputOmitted = outputOmitted;
30397
30435
  message2.status = status;
30398
30436
  } else if (message2.type === "skill" && isError && message2.path) {
30399
- messages[toolInfo.messageIndex] = { id: message2.id, type: "tool_call", server: "claude", tool: toolInfo.toolName, input: toolInfo.input, output: resultContent, outputOmitted, status, timestamp: message2.timestamp };
30437
+ replaceMessage(toolInfo.messageIndex, { id: message2.id, type: "tool_call", server: "claude", tool: toolInfo.toolName, input: toolInfo.input, output: resultContent, outputOmitted, status, timestamp: message2.timestamp });
30400
30438
  } else if (message2.type === "skill") {
30401
30439
  message2.status = status;
30402
30440
  } else if (message2.type === "subagent") {
@@ -30470,9 +30508,15 @@ function parseDisplayMessages(events, agentType, options = {}) {
30470
30508
  return withoutReplacedMessages(excludeQueuedAcceptedEvents(events, []), (segment) => {
30471
30509
  const parsedEvents = parseProviderEvents(segment, agentType, options.parentToolUseId);
30472
30510
  const reconciledEvents = [];
30511
+ const firstIndexById = /* @__PURE__ */ new Map();
30473
30512
  for (const message2 of parsedEvents) {
30474
- if (message2.type === "user") upsertDisplayMessage(reconciledEvents, message2);
30475
- else reconciledEvents.push(message2);
30513
+ const index = message2.type === "user" ? firstIndexById.get(message2.id) : void 0;
30514
+ if (index !== void 0) {
30515
+ reconciledEvents[index] = message2;
30516
+ continue;
30517
+ }
30518
+ if (!firstIndexById.has(message2.id)) firstIndexById.set(message2.id, reconciledEvents.length);
30519
+ reconciledEvents.push(message2);
30476
30520
  }
30477
30521
  if (options.filter === false) return reconciledEvents;
30478
30522
  return applyEngineNotices(
@@ -31238,15 +31282,6 @@ var init_start_hooks = __esm({
31238
31282
  }
31239
31283
  });
31240
31284
 
31241
- // ../shared/src/default-skills/replicas-agent/index.ts
31242
- var init_replicas_agent = __esm({
31243
- "../shared/src/default-skills/replicas-agent/index.ts"() {
31244
- "use strict";
31245
- init_registry();
31246
- init_registry();
31247
- }
31248
- });
31249
-
31250
31285
  // ../shared/src/default-skills/index.ts
31251
31286
  var init_default_skills = __esm({
31252
31287
  "../shared/src/default-skills/index.ts"() {
@@ -31326,7 +31361,7 @@ var CLI_VERSION;
31326
31361
  var init_cli_version = __esm({
31327
31362
  "../shared/src/cli-version.ts"() {
31328
31363
  "use strict";
31329
- CLI_VERSION = "0.3.212";
31364
+ CLI_VERSION = "0.3.219";
31330
31365
  }
31331
31366
  });
31332
31367
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.3.218",
3
+ "version": "0.3.220",
4
4
  "description": "CLI for managing Replicas workspaces - SSH into cloud dev environments with automatic port forwarding",
5
5
  "main": "dist/index.cjs",
6
6
  "bin": {