replicas-cli 0.2.699 → 0.2.701

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 +278 -297
  2. package/package.json +1 -1
package/dist/index.cjs CHANGED
@@ -22917,6 +22917,9 @@ var QUEUED_MESSAGE_REMOVED_EVENT_TYPE = "replicas-queued-message-removed";
22917
22917
  var REMOVED_MESSAGE_IDS_PAYLOAD_KEY = "removedMessageIds";
22918
22918
  var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
22919
22919
  var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
22920
+ var CODEX_ITEM_EVENT_TYPE = "codex-item";
22921
+ var CODEX_ITEM_PARTIAL_EVENT_TYPE = "codex-item-partial";
22922
+ var CODEX_TURN_EVENT_TYPE = "codex-turn";
22920
22923
  var CODEX_QUOTA_STATUS_EVENT_TYPE = "codex-quota-status";
22921
22924
  var CHAT_INTERRUPTED_EVENT_TYPE = "replicas-interrupted";
22922
22925
  var AUTH_FALLBACK_EVENT_TYPE = "auth-fallback";
@@ -23030,6 +23033,38 @@ function getCodexAspTurnResponse(turn) {
23030
23033
  if (normalizeCodexAspTranscriptStatus(turn.status) === "in_progress") return null;
23031
23034
  return turn.items.findLast((item) => item.type === "agentMessage") ?? null;
23032
23035
  }
23036
+ function isTranscriptItemStatus(value) {
23037
+ return value === "in_progress" || value === "completed" || value === "failed";
23038
+ }
23039
+ var CODEX_ITEM_FIELD_CHECKS = {
23040
+ userMessage: (item) => typeof item.content === "string",
23041
+ agentMessage: (item) => typeof item.text === "string",
23042
+ reasoning: (item) => typeof item.text === "string" && isTranscriptItemStatus(item.status),
23043
+ commandExecution: (item) => typeof item.command === "string" && isTranscriptItemStatus(item.status),
23044
+ fileChange: (item) => Array.isArray(item.operations) && isTranscriptItemStatus(item.status),
23045
+ toolCall: (item) => typeof item.server === "string" && typeof item.tool === "string" && isTranscriptItemStatus(item.status),
23046
+ subagent: (item) => typeof item.description === "string" && typeof item.prompt === "string" && typeof item.subagentType === "string" && isTranscriptItemStatus(item.status),
23047
+ webSearch: (item) => typeof item.query === "string" && isTranscriptItemStatus(item.status),
23048
+ plan: (item) => typeof item.text === "string" && isTranscriptItemStatus(item.status),
23049
+ contextCompaction: (item) => isTranscriptItemStatus(item.status),
23050
+ error: (item) => typeof item.message === "string"
23051
+ };
23052
+ function isCodexAspTranscriptItem(value) {
23053
+ if (!isRecord(value) || typeof value.id !== "string" || typeof value.timestamp !== "string") return false;
23054
+ if (value.sequence !== void 0 && typeof value.sequence !== "number") return false;
23055
+ if (typeof value.type !== "string" || !Object.hasOwn(CODEX_ITEM_FIELD_CHECKS, value.type)) return false;
23056
+ return CODEX_ITEM_FIELD_CHECKS[value.type](value);
23057
+ }
23058
+ function codexItemFromEvent(event) {
23059
+ if (event.type !== CODEX_ITEM_EVENT_TYPE && event.type !== CODEX_ITEM_PARTIAL_EVENT_TYPE) return null;
23060
+ const { turnId, item } = event.payload;
23061
+ return typeof turnId === "string" && isCodexAspTranscriptItem(item) ? { turnId, item } : null;
23062
+ }
23063
+ function codexTurnFromEvent(event) {
23064
+ if (event.type !== CODEX_TURN_EVENT_TYPE) return null;
23065
+ const { turnId, status, error: error51 } = event.payload;
23066
+ return typeof turnId === "string" && typeof status === "string" ? { turnId, status, ...typeof error51 === "string" ? { error: error51 } : {} } : null;
23067
+ }
23033
23068
 
23034
23069
  // ../shared/src/display-message/types.ts
23035
23070
  var BACKGROUND_TASK_SUBTYPES = /* @__PURE__ */ new Set([
@@ -25008,6 +25043,201 @@ function removeReplicasInstructions(text) {
25008
25043
  return removeTag(text, REPLICAS_INSTRUCTIONS_TAG);
25009
25044
  }
25010
25045
 
25046
+ // ../shared/src/display-message/parsers/codex-asp-parser.ts
25047
+ function collectCodexTurns(events) {
25048
+ const turns = /* @__PURE__ */ new Map();
25049
+ const turnFor = (id) => {
25050
+ const existing = turns.get(id);
25051
+ if (existing) return existing;
25052
+ const turn = { id, status: "inProgress", items: [] };
25053
+ turns.set(id, turn);
25054
+ return turn;
25055
+ };
25056
+ for (const event of events) {
25057
+ const item = codexItemFromEvent(event);
25058
+ if (item) {
25059
+ const turn = turnFor(item.turnId);
25060
+ const index = turn.items.findIndex((candidate) => candidate.id === item.item.id);
25061
+ if (index === -1) turn.items.push(item.item);
25062
+ else turn.items[index] = item.item;
25063
+ continue;
25064
+ }
25065
+ const turnEvent = codexTurnFromEvent(event);
25066
+ if (turnEvent) {
25067
+ const turn = turnFor(turnEvent.turnId);
25068
+ turn.status = turnEvent.status;
25069
+ turn.completedAt = event.timestamp;
25070
+ turn.error = turnEvent.error;
25071
+ }
25072
+ }
25073
+ return turns;
25074
+ }
25075
+ function messagesForCodexTurn(turn) {
25076
+ const items = turn.items.map((item, index) => ({ item, index })).sort((a, b) => parseTimestampMs(a.item.timestamp) - parseTimestampMs(b.item.timestamp) || a.index - b.index).map(({ item }) => item);
25077
+ const reasoning = items.filter(
25078
+ (item) => item.type === "reasoning" && item.text.trim().length > 0
25079
+ );
25080
+ const firstReasoningIndex = items.findIndex((item) => item.type === "reasoning");
25081
+ const coalesced = items.flatMap((item, index) => {
25082
+ if (item.type !== "reasoning") return [item];
25083
+ if (index !== firstReasoningIndex || reasoning.length === 0) return [];
25084
+ return [{
25085
+ type: "reasoning",
25086
+ id: turn.id,
25087
+ text: reasoning.map(({ text }) => text.trim()).join("\n\n"),
25088
+ timestamp: reasoning[0].timestamp,
25089
+ status: reasoning.at(-1)?.status ?? "completed"
25090
+ }];
25091
+ });
25092
+ const response = getCodexAspTurnResponse({ status: turn.status, items: coalesced });
25093
+ const reasoningIndex = coalesced.findIndex((item) => item.type === "reasoning");
25094
+ const responseIndex = response ? coalesced.indexOf(response) : -1;
25095
+ if (responseIndex !== -1 && reasoningIndex > responseIndex) {
25096
+ coalesced.splice(responseIndex, 0, ...coalesced.splice(reasoningIndex, 1));
25097
+ }
25098
+ const messages = coalesced.flatMap((item) => {
25099
+ const message = messageForItem(item);
25100
+ return [...message ? [message] : [], ...skillMessagesForItem(item)];
25101
+ });
25102
+ if (turn.error) {
25103
+ messages.push({
25104
+ id: `error-${turn.id}`,
25105
+ type: "error",
25106
+ message: turn.error,
25107
+ timestamp: turn.completedAt ?? items.at(-1)?.timestamp ?? (/* @__PURE__ */ new Date(0)).toISOString()
25108
+ });
25109
+ }
25110
+ return messages;
25111
+ }
25112
+ function inputForDisplay(input) {
25113
+ if (input === void 0 || input === null) return void 0;
25114
+ if (typeof input === "string") return input;
25115
+ if (isRecord(input)) return input;
25116
+ return String(input);
25117
+ }
25118
+ function isInternalUserMessage(content) {
25119
+ const trimmed = content.trim();
25120
+ return trimmed.startsWith("<environment_context>") || trimmed.startsWith("<goal_context>");
25121
+ }
25122
+ function messageForItem(item) {
25123
+ if (item.type === "userMessage") {
25124
+ if (isInternalUserMessage(item.content)) return null;
25125
+ return {
25126
+ id: `user-${item.id}`,
25127
+ type: "user",
25128
+ content: item.content,
25129
+ images: item.images,
25130
+ timestamp: item.timestamp
25131
+ };
25132
+ }
25133
+ if (item.type === "agentMessage" || item.type === "plan") {
25134
+ if (!item.text) return null;
25135
+ return {
25136
+ id: `agent-${item.id}`,
25137
+ type: "agent",
25138
+ content: item.text,
25139
+ timestamp: item.timestamp,
25140
+ ...item.type === "plan" ? { isPlan: true } : {}
25141
+ };
25142
+ }
25143
+ if (item.type === "reasoning") {
25144
+ if (!item.text) return null;
25145
+ return {
25146
+ id: `reasoning-${item.id}`,
25147
+ type: "reasoning",
25148
+ content: item.text,
25149
+ status: normalizeCodexAspTranscriptStatus(item.status),
25150
+ timestamp: item.timestamp,
25151
+ ...item.sourceTimestamp ? { sourceTimestamp: item.sourceTimestamp } : {}
25152
+ };
25153
+ }
25154
+ if (item.type === "commandExecution") {
25155
+ const skillNames = skillNamesFromCommand(item.command);
25156
+ return {
25157
+ id: `command-${item.id}`,
25158
+ type: "command",
25159
+ command: item.command,
25160
+ ...skillNames.length > 0 ? { skillNames } : {},
25161
+ output: item.output,
25162
+ exitCode: item.exitCode ?? void 0,
25163
+ status: normalizeCodexAspTranscriptStatus(item.status),
25164
+ timestamp: item.timestamp
25165
+ };
25166
+ }
25167
+ if (item.type === "fileChange") {
25168
+ return {
25169
+ id: `patch-${item.id}`,
25170
+ type: "patch",
25171
+ operations: item.operations,
25172
+ output: item.output,
25173
+ exitCode: item.exitCode ?? void 0,
25174
+ status: normalizeCodexAspTranscriptStatus(item.status),
25175
+ timestamp: item.timestamp
25176
+ };
25177
+ }
25178
+ if (item.type === "toolCall") {
25179
+ return createCallDisplayMessage({
25180
+ id: `toolcall-${item.id}`,
25181
+ server: item.server,
25182
+ tool: item.tool,
25183
+ input: inputForDisplay(item.input),
25184
+ output: item.output,
25185
+ status: normalizeCodexAspTranscriptStatus(item.status),
25186
+ timestamp: item.timestamp
25187
+ });
25188
+ }
25189
+ if (item.type === "subagent") {
25190
+ return {
25191
+ id: `subagent-${item.id}`,
25192
+ type: "subagent",
25193
+ toolUseId: item.id,
25194
+ description: item.description,
25195
+ prompt: item.prompt,
25196
+ subagentType: item.subagentType,
25197
+ ...item.receiverThreadIds ? { receiverThreadIds: item.receiverThreadIds } : {},
25198
+ ...item.model ? { model: item.model } : {},
25199
+ status: normalizeCodexAspTranscriptStatus(item.status),
25200
+ ...item.output ? { output: item.output } : {},
25201
+ nestedEvents: [],
25202
+ timestamp: item.timestamp
25203
+ };
25204
+ }
25205
+ if (item.type === "webSearch") {
25206
+ return {
25207
+ id: `web-search-${item.id}`,
25208
+ type: "web_search",
25209
+ query: item.query,
25210
+ status: normalizeCodexAspTranscriptStatus(item.status),
25211
+ timestamp: item.timestamp
25212
+ };
25213
+ }
25214
+ if (item.type === "contextCompaction") {
25215
+ return {
25216
+ id: `reasoning-${item.id}`,
25217
+ type: "reasoning",
25218
+ content: "Context compacted",
25219
+ status: normalizeCodexAspTranscriptStatus(item.status),
25220
+ timestamp: item.timestamp
25221
+ };
25222
+ }
25223
+ return {
25224
+ id: `error-${item.id}`,
25225
+ type: "error",
25226
+ message: item.message,
25227
+ timestamp: item.timestamp
25228
+ };
25229
+ }
25230
+ function skillMessagesForItem(item) {
25231
+ if (item.type !== "userMessage" || !item.skillNames) return [];
25232
+ return item.skillNames.filter((skillName) => skillName.trim().length > 0).map((skillName, index) => ({
25233
+ id: `skill-${item.id}-${index}`,
25234
+ type: "skill",
25235
+ skillName,
25236
+ status: "completed",
25237
+ timestamp: item.timestamp
25238
+ }));
25239
+ }
25240
+
25011
25241
  // ../shared/src/display-message/parsers/codex-parser.ts
25012
25242
  function getStatusFromExitCode(exitCode) {
25013
25243
  return exitCode === 0 ? "completed" : "failed";
@@ -25082,10 +25312,31 @@ function parsePatch(input) {
25082
25312
  }
25083
25313
  function parseCodexEvents(events) {
25084
25314
  const messages = [];
25315
+ const turns = collectCodexTurns(events);
25316
+ const turnInsertions = [];
25085
25317
  const pendingCommands = /* @__PURE__ */ new Map();
25086
25318
  const pendingToolCalls = /* @__PURE__ */ new Map();
25087
25319
  const pendingPatches = /* @__PURE__ */ new Map();
25088
25320
  events.forEach((event, eventIndex) => {
25321
+ const turnId = codexItemFromEvent(event)?.turnId ?? codexTurnFromEvent(event)?.turnId;
25322
+ if (turnId !== void 0) {
25323
+ if (!turnInsertions.some((insertion) => insertion.turnId === turnId)) {
25324
+ turnInsertions.push({ index: messages.length, turnId });
25325
+ }
25326
+ return;
25327
+ }
25328
+ if (event.type === "codex-asp-error") {
25329
+ const failedTurnId = getPayloadString(event, CODEX_ASP_ITEM_ID_PAYLOAD_KEY);
25330
+ if (!(failedTurnId && turns.has(failedTurnId))) {
25331
+ messages.push({
25332
+ id: displayId(event, eventIndex, "error"),
25333
+ type: "error",
25334
+ message: getPayloadString(event, "message") ?? "Codex run failed",
25335
+ timestamp: event.timestamp
25336
+ });
25337
+ }
25338
+ return;
25339
+ }
25089
25340
  if (event.type === CODEX_QUOTA_STATUS_EVENT_TYPE) {
25090
25341
  const state = event.payload?.state;
25091
25342
  if (state) {
@@ -25242,6 +25493,25 @@ function parseCodexEvents(events) {
25242
25493
  }
25243
25494
  }
25244
25495
  });
25496
+ const claimedPrompts = /* @__PURE__ */ new Set();
25497
+ for (const { index, turnId } of turnInsertions.reverse()) {
25498
+ const turn = turns.get(turnId);
25499
+ if (!turn) continue;
25500
+ const kept = [];
25501
+ for (const message of messagesForCodexTurn(turn)) {
25502
+ const recordedIndex = message.type === "user" ? messages.findLastIndex((candidate, candidateIndex) => candidateIndex < index && candidate.type === "user" && candidate.content === message.content && !claimedPrompts.has(candidateIndex)) : -1;
25503
+ if (recordedIndex === -1) {
25504
+ kept.push(message);
25505
+ continue;
25506
+ }
25507
+ claimedPrompts.add(recordedIndex);
25508
+ const recorded = messages[recordedIndex];
25509
+ if (recorded.type === "user" && message.type === "user" && !recorded.images && message.images) {
25510
+ messages[recordedIndex] = { ...recorded, images: message.images };
25511
+ }
25512
+ }
25513
+ messages.splice(index, 0, ...kept);
25514
+ }
25245
25515
  return messages;
25246
25516
  }
25247
25517
 
@@ -26785,292 +27055,6 @@ function parseClaudeEvents(events, parentToolUseId) {
26785
27055
  return messages.filter((_2, index) => !staleIndexes.has(index));
26786
27056
  }
26787
27057
 
26788
- // ../shared/src/display-message/parsers/codex-asp-parser.ts
26789
- var DUPLICATE_WINDOW_MS = 5 * 60 * 1e3;
26790
- function nearTimestamp(a, b) {
26791
- return Math.abs(parseTimestampMs(a) - parseTimestampMs(b)) <= DUPLICATE_WINDOW_MS;
26792
- }
26793
- function inputForDisplay(input) {
26794
- if (input === void 0 || input === null) return void 0;
26795
- if (typeof input === "string") return input;
26796
- if (isRecord(input)) return input;
26797
- return String(input);
26798
- }
26799
- function isInternalUserMessage(content) {
26800
- const trimmed = content.trim();
26801
- return trimmed.startsWith("<environment_context>") || trimmed.startsWith("<goal_context>");
26802
- }
26803
- function messageForItem(item) {
26804
- if (item.type === "userMessage") {
26805
- if (isInternalUserMessage(item.content)) return null;
26806
- return {
26807
- id: `user-${item.id}`,
26808
- type: "user",
26809
- content: item.content,
26810
- images: item.images,
26811
- timestamp: item.timestamp
26812
- };
26813
- }
26814
- if (item.type === "agentMessage" || item.type === "plan") {
26815
- if (!item.text) return null;
26816
- return {
26817
- id: `agent-${item.id}`,
26818
- type: "agent",
26819
- content: item.text,
26820
- timestamp: item.timestamp,
26821
- ...item.type === "plan" ? { isPlan: true } : {}
26822
- };
26823
- }
26824
- if (item.type === "reasoning") {
26825
- if (!item.text) return null;
26826
- return {
26827
- id: `reasoning-${item.id}`,
26828
- type: "reasoning",
26829
- content: item.text,
26830
- status: normalizeCodexAspTranscriptStatus(item.status),
26831
- timestamp: item.timestamp,
26832
- ...item.sourceTimestamp ? { sourceTimestamp: item.sourceTimestamp } : {}
26833
- };
26834
- }
26835
- if (item.type === "commandExecution") {
26836
- const skillNames = skillNamesFromCommand(item.command);
26837
- return {
26838
- id: `command-${item.id}`,
26839
- type: "command",
26840
- command: item.command,
26841
- ...skillNames.length > 0 ? { skillNames } : {},
26842
- output: item.output,
26843
- exitCode: item.exitCode ?? void 0,
26844
- status: normalizeCodexAspTranscriptStatus(item.status),
26845
- timestamp: item.timestamp
26846
- };
26847
- }
26848
- if (item.type === "fileChange") {
26849
- return {
26850
- id: `patch-${item.id}`,
26851
- type: "patch",
26852
- operations: item.operations,
26853
- output: item.output,
26854
- exitCode: item.exitCode ?? void 0,
26855
- status: normalizeCodexAspTranscriptStatus(item.status),
26856
- timestamp: item.timestamp
26857
- };
26858
- }
26859
- if (item.type === "toolCall") {
26860
- return createCallDisplayMessage({
26861
- id: `toolcall-${item.id}`,
26862
- server: item.server,
26863
- tool: item.tool,
26864
- input: inputForDisplay(item.input),
26865
- output: item.output,
26866
- status: normalizeCodexAspTranscriptStatus(item.status),
26867
- timestamp: item.timestamp
26868
- });
26869
- }
26870
- if (item.type === "subagent") {
26871
- return {
26872
- id: `subagent-${item.id}`,
26873
- type: "subagent",
26874
- toolUseId: item.id,
26875
- description: item.description,
26876
- prompt: item.prompt,
26877
- subagentType: item.subagentType,
26878
- ...item.receiverThreadIds ? { receiverThreadIds: item.receiverThreadIds } : {},
26879
- ...item.model ? { model: item.model } : {},
26880
- status: normalizeCodexAspTranscriptStatus(item.status),
26881
- ...item.output ? { output: item.output } : {},
26882
- nestedEvents: [],
26883
- timestamp: item.timestamp
26884
- };
26885
- }
26886
- if (item.type === "webSearch") {
26887
- return {
26888
- id: `web-search-${item.id}`,
26889
- type: "web_search",
26890
- query: item.query,
26891
- status: normalizeCodexAspTranscriptStatus(item.status),
26892
- timestamp: item.timestamp
26893
- };
26894
- }
26895
- if (item.type === "contextCompaction") {
26896
- return {
26897
- id: `reasoning-${item.id}`,
26898
- type: "reasoning",
26899
- content: "Context compacted",
26900
- status: normalizeCodexAspTranscriptStatus(item.status),
26901
- timestamp: item.timestamp
26902
- };
26903
- }
26904
- return {
26905
- id: `error-${item.id}`,
26906
- type: "error",
26907
- message: item.message,
26908
- timestamp: item.timestamp
26909
- };
26910
- }
26911
- function skillMessagesForItem(item) {
26912
- if (item.type !== "userMessage" || !item.skillNames) return [];
26913
- return item.skillNames.filter((skillName) => skillName.trim().length > 0).map((skillName, index) => ({
26914
- id: `skill-${item.id}-${index}`,
26915
- type: "skill",
26916
- skillName,
26917
- status: "completed",
26918
- timestamp: item.timestamp
26919
- }));
26920
- }
26921
- function stableString(value) {
26922
- if (value === void 0) return "";
26923
- if (typeof value !== "object" || value === null) return String(value);
26924
- try {
26925
- return JSON.stringify(value, Object.keys(value).sort());
26926
- } catch {
26927
- return String(value);
26928
- }
26929
- }
26930
- function duplicateKey(message) {
26931
- if (message.type === "user" || message.type === "agent" || message.type === "reasoning") {
26932
- return JSON.stringify([message.type, message.content]);
26933
- }
26934
- if (message.type === "command") return JSON.stringify([message.type, message.command]);
26935
- if (message.type === "web_search") return JSON.stringify([message.type, message.query]);
26936
- if (message.type === "subagent") {
26937
- return JSON.stringify([
26938
- message.type,
26939
- message.description,
26940
- message.prompt,
26941
- message.subagentType,
26942
- message.model
26943
- ]);
26944
- }
26945
- if (message.type === "todo_list") {
26946
- return JSON.stringify([message.type, stableString(message.items)]);
26947
- }
26948
- if (message.type === "patch") {
26949
- return JSON.stringify([message.type, stableString(message.operations)]);
26950
- }
26951
- if (message.type === "tool_call") {
26952
- return JSON.stringify([
26953
- message.type,
26954
- message.server,
26955
- message.tool,
26956
- stableString(message.input)
26957
- ]);
26958
- }
26959
- return null;
26960
- }
26961
- function duplicateBucketKey(message, bucketOffset = 0) {
26962
- const key = duplicateKey(message);
26963
- if (key === null) return null;
26964
- const bucket = Math.floor(parseTimestampMs(message.timestamp) / DUPLICATE_WINDOW_MS) + bucketOffset;
26965
- return JSON.stringify([bucket, key]);
26966
- }
26967
- function mergeCodexAspDisplayMessages(primary, supplemental) {
26968
- const merged = [...primary];
26969
- const primaryCount = primary.length;
26970
- const firstIndexById = /* @__PURE__ */ new Map();
26971
- const indexesByDuplicateBucket = /* @__PURE__ */ new Map();
26972
- const indexMessage = (message, index) => {
26973
- if (!firstIndexById.has(message.id)) firstIndexById.set(message.id, index);
26974
- const key = duplicateBucketKey(message);
26975
- if (key === null) return;
26976
- const indexes = indexesByDuplicateBucket.get(key) ?? /* @__PURE__ */ new Set();
26977
- indexes.add(index);
26978
- indexesByDuplicateBucket.set(key, indexes);
26979
- };
26980
- const unindexMessage = (message, index) => {
26981
- const key = duplicateBucketKey(message);
26982
- if (key === null) return;
26983
- const indexes = indexesByDuplicateBucket.get(key);
26984
- indexes?.delete(index);
26985
- if (indexes?.size === 0) indexesByDuplicateBucket.delete(key);
26986
- };
26987
- merged.forEach(indexMessage);
26988
- for (const message of supplemental) {
26989
- let duplicateIndex = firstIndexById.get(message.id);
26990
- if (duplicateIndex === void 0) {
26991
- for (let bucketOffset = -1; bucketOffset <= 1; bucketOffset += 1) {
26992
- const key = duplicateBucketKey(message, bucketOffset);
26993
- for (const index of (key === null ? void 0 : indexesByDuplicateBucket.get(key)) ?? []) {
26994
- if (nearTimestamp(merged[index].timestamp, message.timestamp) && (duplicateIndex === void 0 || index < duplicateIndex)) {
26995
- duplicateIndex = index;
26996
- }
26997
- }
26998
- }
26999
- }
27000
- if (duplicateIndex === void 0) {
27001
- indexMessage(message, merged.push(message) - 1);
27002
- } else if (message.type === "user") {
27003
- unindexMessage(merged[duplicateIndex], duplicateIndex);
27004
- merged[duplicateIndex] = {
27005
- ...merged[duplicateIndex],
27006
- id: message.id
27007
- };
27008
- firstIndexById.set(message.id, duplicateIndex);
27009
- indexMessage(merged[duplicateIndex], duplicateIndex);
27010
- }
27011
- }
27012
- const ordered = merged.slice(0, primaryCount);
27013
- const supplementalOnly = merged.slice(primaryCount).map((message, index) => ({ message, index })).sort((a, b) => parseTimestampMs(a.message.timestamp) - parseTimestampMs(b.message.timestamp) || a.index - b.index);
27014
- for (const { message } of supplementalOnly) {
27015
- insertDisplayMessageByTimestamp(ordered, message);
27016
- }
27017
- return ordered;
27018
- }
27019
- function parseCodexAspTranscript(transcript) {
27020
- const messages = [];
27021
- const orderedItems = transcript.turns.map((turn, turnIndex) => ({ turn, turnIndex })).flatMap(({ turn, turnIndex }) => turn.items.map((item, itemIndex) => ({ item, turn, turnIndex, itemIndex }))).sort((a, b) => {
27022
- const aSequence = a.item.sequence ?? Number.MAX_SAFE_INTEGER;
27023
- const bSequence = b.item.sequence ?? Number.MAX_SAFE_INTEGER;
27024
- return aSequence - bSequence || parseTimestampMs(a.item.timestamp) - parseTimestampMs(b.item.timestamp) || a.turnIndex - b.turnIndex || a.itemIndex - b.itemIndex;
27025
- });
27026
- const reasoningByTurnId = /* @__PURE__ */ new Map();
27027
- for (const { item, turn } of orderedItems) {
27028
- if (item.type !== "reasoning" || !item.text.trim()) continue;
27029
- const reasoning = reasoningByTurnId.get(turn.id) ?? [];
27030
- reasoning.push(item);
27031
- reasoningByTurnId.set(turn.id, reasoning);
27032
- }
27033
- const emittedReasoningTurnIds = /* @__PURE__ */ new Set();
27034
- const coalescedItems = orderedItems.flatMap((entry) => {
27035
- if (entry.item.type !== "reasoning") return [entry];
27036
- const reasoning = reasoningByTurnId.get(entry.turn.id);
27037
- if (!reasoning || emittedReasoningTurnIds.has(entry.turn.id)) return [];
27038
- emittedReasoningTurnIds.add(entry.turn.id);
27039
- return [{
27040
- ...entry,
27041
- item: {
27042
- type: "reasoning",
27043
- id: entry.turn.id,
27044
- text: reasoning.map(({ text }) => text.trim()).join("\n\n"),
27045
- timestamp: entry.turn.startedAt,
27046
- ...reasoning[0] ? { sourceTimestamp: reasoning[0].timestamp } : {},
27047
- status: reasoning.at(-1)?.status ?? "completed",
27048
- sequence: entry.item.sequence
27049
- }
27050
- }];
27051
- });
27052
- for (const turn of transcript.turns) {
27053
- const reasoningIndex = coalescedItems.findIndex(({ item, turn: itemTurn }) => itemTurn.id === turn.id && item.type === "reasoning");
27054
- if (reasoningIndex === -1) continue;
27055
- const responseItem = getCodexAspTurnResponse({
27056
- status: turn.status,
27057
- items: coalescedItems.filter(({ turn: itemTurn }) => itemTurn.id === turn.id).map(({ item }) => item)
27058
- });
27059
- const finalAnswerIndex = responseItem ? coalescedItems.findIndex(({ item }) => item === responseItem) : -1;
27060
- if (finalAnswerIndex === -1 || reasoningIndex < finalAnswerIndex) continue;
27061
- const [reasoning] = coalescedItems.splice(reasoningIndex, 1);
27062
- coalescedItems.splice(finalAnswerIndex, 0, reasoning);
27063
- }
27064
- for (const { item } of coalescedItems) {
27065
- const message = messageForItem(item);
27066
- if (message) {
27067
- messages.push(message);
27068
- }
27069
- messages.push(...skillMessagesForItem(item));
27070
- }
27071
- return messages;
27072
- }
27073
-
27074
27058
  // ../shared/src/display-message/parsers/index.ts
27075
27059
  var INTERRUPTION_DEDUP_WINDOW_MS = 15e3;
27076
27060
  function parseAgentEvents(events, agentType) {
@@ -27104,22 +27088,19 @@ function parseAgentEvents(events, agentType) {
27104
27088
  }
27105
27089
  return parseClaudeEvents(events);
27106
27090
  }
27107
- function parseDisplayMessages(events, agentType, codexAspTranscript, options = {}) {
27091
+ function parseDisplayMessages(events, agentType, options = {}) {
27108
27092
  events = excludeQueuedAcceptedEvents(events, []);
27109
- const shouldFilter = options.filter ?? true;
27110
27093
  const parsedEvents = agentType === "claude" || agentType === "relay" ? parseClaudeEvents(events, options.parentToolUseId) : parseAgentEvents(events, agentType);
27111
27094
  const reconciledEvents = [];
27112
27095
  for (const message of parsedEvents) {
27113
27096
  if (message.type === "user") upsertDisplayMessage(reconciledEvents, message);
27114
27097
  else reconciledEvents.push(message);
27115
27098
  }
27116
- const legacyMessages = shouldFilter ? filterDisplayMessages(reconciledEvents, agentType) : reconciledEvents;
27117
- const applySyntheticNotices = (messages) => shouldFilter ? applyAuthFallbackNotices(applyInterruptions(messages, events), events) : messages;
27118
- if (agentType !== "codex" || !codexAspTranscript) {
27119
- return applySyntheticNotices(legacyMessages);
27120
- }
27121
- const nativeCodexMessages = shouldFilter ? filterDisplayMessages(parseCodexAspTranscript(codexAspTranscript), agentType) : parseCodexAspTranscript(codexAspTranscript);
27122
- return applySyntheticNotices(mergeCodexAspDisplayMessages(nativeCodexMessages, legacyMessages));
27099
+ if (options.filter === false) return reconciledEvents;
27100
+ return applyAuthFallbackNotices(
27101
+ applyInterruptions(filterDisplayMessages(reconciledEvents, agentType), events),
27102
+ events
27103
+ );
27123
27104
  }
27124
27105
  function applyInterruptions(messages, events) {
27125
27106
  const result = [...messages];
@@ -27369,7 +27350,7 @@ var headlessFilesystemAgentResultSchema = external_exports.object({
27369
27350
  });
27370
27351
 
27371
27352
  // ../shared/src/cli-version.ts
27372
- var CLI_VERSION = "0.2.699";
27353
+ var CLI_VERSION = "0.2.701";
27373
27354
 
27374
27355
  // ../shared/src/version.ts
27375
27356
  function compareVersions(v1, v2) {
@@ -30093,7 +30074,7 @@ Conversation History
30093
30074
  }
30094
30075
  console.log(import_chalk15.default.gray("-".repeat(60)));
30095
30076
  const agentType = response.coding_agent || "claude";
30096
- const displayMessages = parseDisplayMessages(response.events, agentType, response.codexAspTranscript);
30077
+ const displayMessages = parseDisplayMessages(response.events, agentType);
30097
30078
  for (const message of displayMessages) {
30098
30079
  formatDisplayMessage(message);
30099
30080
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-cli",
3
- "version": "0.2.699",
3
+ "version": "0.2.701",
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": {