replicas-engine 0.1.764 → 0.1.766

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.
@@ -5,11 +5,11 @@ import {
5
5
  getCodexAspHost,
6
6
  restartCodexAspHost,
7
7
  restartCodexAspHostIfRunning
8
- } from "./chunk-ZXO6LQFR.js";
9
- import "./chunk-WOFZOLYF.js";
10
- import "./chunk-SQWL6FMP.js";
8
+ } from "./chunk-AL25Z6UZ.js";
9
+ import "./chunk-5R2WQ34N.js";
10
+ import "./chunk-FFNEC4SD.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-UMU4HGV6.js";
12
+ import "./chunk-DC6RPXQZ.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
  export {
15
15
  getCodexAspHost,
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  monolithRequest
6
- } from "./chunk-WOFZOLYF.js";
6
+ } from "./chunk-5R2WQ34N.js";
7
7
  import {
8
8
  extractCommandProtectionCommandText,
9
9
  findGitCommitSignals,
10
10
  findPrMergeSignals
11
- } from "./chunk-UMU4HGV6.js";
11
+ } from "./chunk-DC6RPXQZ.js";
12
12
 
13
13
  // src/services/command-protection-service.ts
14
14
  var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by Replicas command protection.";
@@ -15,7 +15,7 @@ import {
15
15
  isValidRelayBaseProvider,
16
16
  parsePosixEnvFile,
17
17
  readReplicasRuntimeEnv
18
- } from "./chunk-UMU4HGV6.js";
18
+ } from "./chunk-DC6RPXQZ.js";
19
19
 
20
20
  // src/engine-env.ts
21
21
  import { readFileSync as readFileSync2 } from "fs";
@@ -5,18 +5,18 @@ import {
5
5
  ENGINE_ENV,
6
6
  monolithRequest,
7
7
  setAgentCredentialSnapshot
8
- } from "./chunk-WOFZOLYF.js";
8
+ } from "./chunk-5R2WQ34N.js";
9
9
  import {
10
10
  AppServerProcess,
11
11
  buildCodexAgentEnv
12
- } from "./chunk-SQWL6FMP.js";
12
+ } from "./chunk-FFNEC4SD.js";
13
13
  import {
14
14
  CODEX_AUTH_ENV_KEYS,
15
15
  CODEX_AUTH_ENV_KEYS_BY_METHOD,
16
16
  codexAuthEnvFromResponse,
17
17
  createErrorResult,
18
18
  createSuccessResult
19
- } from "./chunk-UMU4HGV6.js";
19
+ } from "./chunk-DC6RPXQZ.js";
20
20
 
21
21
  // src/managers/codex-token-manager.ts
22
22
  import { promises as fs } from "fs";
@@ -232,7 +232,7 @@ var CodexTokenManager = class extends BaseRefreshManager {
232
232
  const data = await response.json();
233
233
  await this.applyCredentialsResponse(data);
234
234
  if (restartOnChange && CODEX_AUTH_ENV_KEYS.some((key, index) => process.env[key] !== previousEnv[index])) {
235
- const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-GYPV5SL7.js");
235
+ const { restartCodexAspHostIfRunning: restartCodexAspHostIfRunning2 } = await import("./asp-host-QO7E55G6.js");
236
236
  await restartCodexAspHostIfRunning2();
237
237
  }
238
238
  if (data.scope) {
@@ -646,6 +646,8 @@ function getClaudePartialMessageStreamId(event) {
646
646
  return typeof event.payload.streamId === "string" && event.payload.streamId ? event.payload.streamId : null;
647
647
  }
648
648
  var ACCEPTED_USER_MESSAGE_SOURCE = "replicas-chat-turn-accepted";
649
+ var QUEUED_MESSAGE_REMOVED_EVENT_TYPE = "replicas-queued-message-removed";
650
+ var REMOVED_MESSAGE_IDS_PAYLOAD_KEY = "removedMessageIds";
649
651
  var USER_MESSAGE_ID_PAYLOAD_KEY = "replicasMessageId";
650
652
  var CODEX_ASP_ITEM_ID_PAYLOAD_KEY = "codexAspItemId";
651
653
  var CODEX_ASP_TRANSCRIPT_UPDATED_EVENT_TYPE = "codex-asp-transcript-updated";
@@ -1537,7 +1539,8 @@ function upsertDisplayMessage(messages, message) {
1537
1539
  }
1538
1540
  function applyToolInputEvent(event, messages, provider, state, questionFilter) {
1539
1541
  if (event.type === "replicas-tool-input-request" && typeof event.payload.toolUseId === "string" && typeof event.payload.requestId === "string" && (Array.isArray(event.payload.options) || Array.isArray(event.payload.questions))) {
1540
- const resolved = state.resolutions.get(event.payload.toolUseId);
1542
+ const previous = state.resolutions.get(event.payload.toolUseId);
1543
+ const resolved = previous && (!previous.requestId || previous.requestId === event.payload.requestId) ? previous : void 0;
1541
1544
  const inputRequest = {
1542
1545
  requestId: event.payload.requestId,
1543
1546
  status: resolved?.selectionId === "aborted" || resolved?.selectionId === "declined" ? "aborted" : resolved ? "resolved" : "pending",
@@ -1553,12 +1556,13 @@ function applyToolInputEvent(event, messages, provider, state, questionFilter) {
1553
1556
  }
1554
1557
  if (event.type === "replicas-tool-input-resolved" && typeof event.payload.toolUseId === "string" && typeof event.payload.selectionId === "string") {
1555
1558
  const resolved = {
1559
+ ...typeof event.payload.requestId === "string" ? { requestId: event.payload.requestId } : {},
1556
1560
  selectionId: event.payload.selectionId,
1557
1561
  ...typeof event.payload.selectionSummary === "string" ? { selectionSummary: event.payload.selectionSummary } : {}
1558
1562
  };
1559
1563
  state.resolutions.set(event.payload.toolUseId, resolved);
1560
1564
  const inputRequest = state.requests.get(event.payload.toolUseId);
1561
- if (inputRequest) {
1565
+ if (inputRequest && (!resolved.requestId || resolved.requestId === inputRequest.requestId)) {
1562
1566
  inputRequest.status = resolved.selectionId === "aborted" || resolved.selectionId === "declined" ? "aborted" : "resolved";
1563
1567
  inputRequest.selectionId = resolved.selectionId;
1564
1568
  if (resolved.selectionSummary) inputRequest.selectionSummary = resolved.selectionSummary;
@@ -1607,6 +1611,7 @@ function skillNameFromToolCall(tool, input) {
1607
1611
  return parseSkillFilePath(input);
1608
1612
  }
1609
1613
  function createCallDisplayMessage(message) {
1614
+ if (message.inputRequest) return { ...message, type: "tool_call" };
1610
1615
  const skillName = message.server.toLowerCase() === "skills" ? message.tool : skillNameFromToolCall(message.tool, message.input);
1611
1616
  if (skillName === null) return { ...message, type: "tool_call" };
1612
1617
  return {
@@ -4516,12 +4521,12 @@ function parseMuseEvents(events) {
4516
4521
  id: `muse-tool-${item.itemId}`,
4517
4522
  server: "muse",
4518
4523
  tool: typeof item.tool === "string" ? item.tool : "tool",
4524
+ inputRequest: inputState.requests.get(item.itemId),
4519
4525
  input: isRecord(input) ? input : typeof input === "string" ? input : void 0,
4520
4526
  output: typeof item.visibleOutput === "string" ? item.visibleOutput : item.failureReason === void 0 ? void 0 : stringifyDisplayValue(item.failureReason),
4521
4527
  status: item.status === "failed" || item.status === "rejected" ? "failed" : terminal ? "completed" : "in_progress",
4522
4528
  timestamp: typeof item.recordedAt === "string" ? item.recordedAt : event.timestamp
4523
4529
  });
4524
- if (message.type === "tool_call") message.inputRequest = inputState.requests.get(item.itemId);
4525
4530
  upsertDisplayMessage(messages, message);
4526
4531
  }
4527
4532
  }
@@ -5582,6 +5587,7 @@ function parseCodexAspTranscript(transcript) {
5582
5587
  // ../shared/src/display-message/parsers/index.ts
5583
5588
  var INTERRUPTION_DEDUP_WINDOW_MS = 15e3;
5584
5589
  function parseAgentEvents(events, agentType) {
5590
+ events = excludeQueuedAcceptedEvents(events, []);
5585
5591
  if (agentType === "codex") {
5586
5592
  return parseCodexEvents(events);
5587
5593
  }
@@ -5609,6 +5615,7 @@ function parseAgentEvents(events, agentType) {
5609
5615
  return parseClaudeEvents(events);
5610
5616
  }
5611
5617
  function parseDisplayMessages(events, agentType, codexAspTranscript, options = {}) {
5618
+ events = excludeQueuedAcceptedEvents(events, []);
5612
5619
  const shouldFilter = options.filter ?? true;
5613
5620
  const parsedEvents = agentType === "claude" || agentType === "relay" ? parseClaudeEvents(events, options.parentToolUseId) : parseAgentEvents(events, agentType);
5614
5621
  const reconciledEvents = [];
@@ -5759,10 +5766,24 @@ function getUserMessageId(event) {
5759
5766
  const messageId = event.payload[USER_MESSAGE_ID_PAYLOAD_KEY];
5760
5767
  return typeof messageId === "string" ? messageId : null;
5761
5768
  }
5769
+ function getRemovedMessageIds(event) {
5770
+ if (event.type !== QUEUED_MESSAGE_REMOVED_EVENT_TYPE) return [];
5771
+ const messageIds = event.payload[REMOVED_MESSAGE_IDS_PAYLOAD_KEY];
5772
+ if (Array.isArray(messageIds)) return messageIds.filter((id) => typeof id === "string");
5773
+ const messageId = getUserMessageId(event);
5774
+ return messageId ? [messageId] : [];
5775
+ }
5762
5776
  function getUserMessageItemId(event) {
5763
5777
  const itemId = event.payload[CODEX_ASP_ITEM_ID_PAYLOAD_KEY];
5764
5778
  return typeof itemId === "string" ? itemId : null;
5765
5779
  }
5780
+ function excludeQueuedAcceptedEvents(events, queue, removedMessageIds = []) {
5781
+ const queuedMessageIds = /* @__PURE__ */ new Set([...queue.map((message) => message.id), ...removedMessageIds]);
5782
+ for (const event of events) {
5783
+ for (const messageId of getRemovedMessageIds(event)) queuedMessageIds.add(messageId);
5784
+ }
5785
+ return events.filter((event) => event.payload.source !== ACCEPTED_USER_MESSAGE_SOURCE || !queuedMessageIds.has(getUserMessageId(event) ?? ""));
5786
+ }
5766
5787
  function getEventTimestampMs(event) {
5767
5788
  return parseTimestampMs(event.timestamp);
5768
5789
  }
@@ -7284,13 +7305,15 @@ async function readJsonlPage(args) {
7284
7305
  }
7285
7306
  function parseChatTranscriptHistoryIndex(value) {
7286
7307
  if (!isRecord(value) || value.version !== 2 || !isNonNegativeInteger(value.sourceSize)) return void 0;
7308
+ const removedMessageIds = Array.isArray(value.removedMessageIds) ? value.removedMessageIds.filter((id) => typeof id === "string") : [];
7287
7309
  if (value.codexAspTranscript === void 0) {
7288
- return { version: 2, sourceSize: value.sourceSize };
7310
+ return { version: 2, sourceSize: value.sourceSize, ...removedMessageIds.length ? { removedMessageIds } : {} };
7289
7311
  }
7290
7312
  if (!isRecord(value.codexAspTranscript) || typeof value.codexAspTranscript.threadId !== "string" || typeof value.codexAspTranscript.updatedAt !== "string" || !isNonNegativeInteger(value.codexAspTranscript.size)) return void 0;
7291
7313
  return {
7292
7314
  version: 2,
7293
7315
  sourceSize: value.sourceSize,
7316
+ ...removedMessageIds.length ? { removedMessageIds } : {},
7294
7317
  codexAspTranscript: {
7295
7318
  threadId: value.codexAspTranscript.threadId,
7296
7319
  updatedAt: value.codexAspTranscript.updatedAt,
@@ -7303,6 +7326,10 @@ function getChatTranscriptHistorySize(index) {
7303
7326
  }
7304
7327
  function createChatTranscriptPages(sourceBytes) {
7305
7328
  const history = parseAgentEventJsonlWithCodexAspTranscript(new TextDecoder("utf-8", { fatal: true }).decode(sourceBytes));
7329
+ const removedMessageIds = /* @__PURE__ */ new Set();
7330
+ for (const event of history.events) {
7331
+ for (const messageId of getRemovedMessageIds(event)) removedMessageIds.add(messageId);
7332
+ }
7306
7333
  const bytes = new TextEncoder().encode(history.transcript?.turns.length ? `${history.transcript.turns.map((turn) => JSON.stringify(turn)).join("\n")}
7307
7334
  ` : "");
7308
7335
  return {
@@ -7310,6 +7337,7 @@ function createChatTranscriptPages(sourceBytes) {
7310
7337
  index: {
7311
7338
  version: 2,
7312
7339
  sourceSize: sourceBytes.byteLength,
7340
+ ...removedMessageIds.size ? { removedMessageIds: [...removedMessageIds] } : {},
7313
7341
  ...history.transcript ? {
7314
7342
  codexAspTranscript: {
7315
7343
  threadId: history.transcript.threadId,
@@ -7525,6 +7553,8 @@ export {
7525
7553
  CLAUDE_PARTIAL_MESSAGE_EVENT_TYPE,
7526
7554
  getClaudePartialMessageStreamId,
7527
7555
  ACCEPTED_USER_MESSAGE_SOURCE,
7556
+ QUEUED_MESSAGE_REMOVED_EVENT_TYPE,
7557
+ REMOVED_MESSAGE_IDS_PAYLOAD_KEY,
7528
7558
  USER_MESSAGE_ID_PAYLOAD_KEY,
7529
7559
  CODEX_ASP_TRANSCRIPT_UPDATED_EVENT_TYPE,
7530
7560
  CODEX_QUOTA_STATUS_EVENT_TYPE,
@@ -7581,6 +7611,8 @@ export {
7581
7611
  isAgentBackendEvent,
7582
7612
  getUserMessage,
7583
7613
  getUserMessageId,
7614
+ getRemovedMessageIds,
7615
+ excludeQueuedAcceptedEvents,
7584
7616
  getEventTimestampMs,
7585
7617
  areSameUserMessageEvents,
7586
7618
  parseAgentEventJsonlWithCodexAspTranscript,
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  HOOK_EXEC_MAX_BUFFER_BYTES,
6
6
  isVersionBelow
7
- } from "./chunk-UMU4HGV6.js";
7
+ } from "./chunk-DC6RPXQZ.js";
8
8
 
9
9
  // src/utils/codex-agent-env.ts
10
10
  function buildCodexAgentEnv(source = process.env) {
@@ -241,7 +241,7 @@ var DEFAULT_CODEX_ARGS = [
241
241
  var MIN_CODEX_CLI_VERSION = "0.153.3";
242
242
  var CODEX_UPGRADE_TIMEOUT_MS = 12e4;
243
243
  var codexCliVersionEnsured = null;
244
- var ENGINE_PACKAGE_VERSION = "0.1.764";
244
+ var ENGINE_PACKAGE_VERSION = "0.1.766";
245
245
  var INITIALIZE_METHOD = "initialize";
246
246
  var INITIALIZED_NOTIFICATION = "initialized";
247
247
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  findCodeHostPullRequestUrls,
6
6
  mayCreatePullRequest
7
- } from "./chunk-UMU4HGV6.js";
7
+ } from "./chunk-DC6RPXQZ.js";
8
8
 
9
9
  // src/services/post-tool-pr-notifier.ts
10
10
  async function notifyPostToolUse(toolName, toolInput, toolResult) {
@@ -3,12 +3,12 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  evaluateCommandProtection
6
- } from "./chunk-N3ACGL4O.js";
7
- import "./chunk-WOFZOLYF.js";
6
+ } from "./chunk-2ZDB6AIE.js";
7
+ import "./chunk-5R2WQ34N.js";
8
8
  import {
9
9
  isRecord
10
10
  } from "./chunk-UZSNFLDQ.js";
11
- import "./chunk-UMU4HGV6.js";
11
+ import "./chunk-DC6RPXQZ.js";
12
12
  import "./chunk-VEQXQN22.js";
13
13
 
14
14
  // src/command-protection-hook.ts
@@ -3,13 +3,13 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  evaluateCommandProtection
6
- } from "./chunk-N3ACGL4O.js";
6
+ } from "./chunk-2ZDB6AIE.js";
7
7
  import {
8
8
  notifyPostToolUse
9
- } from "./chunk-RCRX7ATX.js";
10
- import "./chunk-WOFZOLYF.js";
9
+ } from "./chunk-ZXZ2COVG.js";
10
+ import "./chunk-5R2WQ34N.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-UMU4HGV6.js";
12
+ import "./chunk-DC6RPXQZ.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
 
15
15
  // src/deepseek-command-protection-plugin.ts
@@ -8,12 +8,12 @@ import {
8
8
  import {
9
9
  AppServerProcess,
10
10
  buildCodexAgentEnv
11
- } from "./chunk-SQWL6FMP.js";
11
+ } from "./chunk-FFNEC4SD.js";
12
12
  import {
13
13
  AGENT,
14
14
  getMemoryOutputSafetyViolation,
15
15
  headlessAgentRequestSchema
16
- } from "./chunk-UMU4HGV6.js";
16
+ } from "./chunk-DC6RPXQZ.js";
17
17
  import "./chunk-VEQXQN22.js";
18
18
 
19
19
  // src/headless-agent.ts
package/dist/src/index.js CHANGED
@@ -91,7 +91,7 @@ import {
91
91
  evaluateCommandProtection,
92
92
  extractToolCommand,
93
93
  reportCommandProtectionBlock
94
- } from "./chunk-N3ACGL4O.js";
94
+ } from "./chunk-2ZDB6AIE.js";
95
95
  import {
96
96
  ACCOUNT_RATE_LIMITS_UPDATED_METHOD,
97
97
  AGENT_MESSAGE_DELTA_METHOD,
@@ -124,20 +124,20 @@ import {
124
124
  recordCredentialFallback,
125
125
  recordExhaustedCredential,
126
126
  restartCodexAspHost
127
- } from "./chunk-ZXO6LQFR.js";
127
+ } from "./chunk-AL25Z6UZ.js";
128
128
  import {
129
129
  ENGINE_ENV,
130
130
  IS_WARMING_MODE,
131
131
  monolithRequest,
132
132
  monolithService,
133
133
  setAgentCredentialSnapshot
134
- } from "./chunk-WOFZOLYF.js";
134
+ } from "./chunk-5R2WQ34N.js";
135
135
  import {
136
136
  AspClient,
137
137
  SUBPROCESS_MAX_BUFFER,
138
138
  execAsync,
139
139
  execFileAsync
140
- } from "./chunk-SQWL6FMP.js";
140
+ } from "./chunk-FFNEC4SD.js";
141
141
  import {
142
142
  isRecord as isRecord2
143
143
  } from "./chunk-UZSNFLDQ.js";
@@ -207,6 +207,8 @@ import {
207
207
  MEMORY_INDEX_FILENAME,
208
208
  MEMORY_ROOT,
209
209
  MERGED_MESSAGE_SEPARATOR,
210
+ QUEUED_MESSAGE_REMOVED_EVENT_TYPE,
211
+ REMOVED_MESSAGE_IDS_PAYLOAD_KEY,
210
212
  REPLICAS_CONFIG_FILENAMES,
211
213
  SANDBOX_PATHS,
212
214
  TIMEOUT,
@@ -248,6 +250,7 @@ import {
248
250
  describeQuotaLimit,
249
251
  detectAgentQuotaLimit,
250
252
  detectLanguageByPath,
253
+ excludeQueuedAcceptedEvents,
251
254
  extractErrorText,
252
255
  extractToolResultText,
253
256
  fetchAiGatewayModels,
@@ -268,6 +271,7 @@ import {
268
271
  getGoalCommand,
269
272
  getGoalCommandObjectiveValidationError,
270
273
  getProviderDisplayName,
274
+ getRemovedMessageIds,
271
275
  getSlashCommandsForProvider,
272
276
  getUserMessage,
273
277
  getUserMessageId,
@@ -333,7 +337,7 @@ import {
333
337
  spawnRelaySubagentRequestSchema,
334
338
  stripAgentDiagnosticErrors,
335
339
  withTimeout
336
- } from "./chunk-UMU4HGV6.js";
340
+ } from "./chunk-DC6RPXQZ.js";
337
341
  import {
338
342
  __commonJS,
339
343
  __export,
@@ -10684,7 +10688,7 @@ function workspaceChatEventSignals(event) {
10684
10688
  streamId: getClaudePartialMessageStreamId(event),
10685
10689
  json,
10686
10690
  userMessage: getComparableUserMessage(event),
10687
- userMessageId: getUserMessageId(event)
10691
+ userMessageId: event.type === QUEUED_MESSAGE_REMOVED_EVENT_TYPE ? null : getUserMessageId(event)
10688
10692
  };
10689
10693
  }
10690
10694
  var emptyIndex = () => ({
@@ -10749,7 +10753,17 @@ function findDuplicatePosition(index, event) {
10749
10753
  }
10750
10754
  return match;
10751
10755
  }
10752
- function mergeWorkspaceChatHistoryEvents(primary, supplemental) {
10756
+ function mergeWorkspaceChatHistoryEvents(primary, supplemental, removedMessageIds = []) {
10757
+ const removed = new Set(removedMessageIds);
10758
+ for (const events of [primary, supplemental]) {
10759
+ for (const event of events) {
10760
+ for (const messageId of getRemovedMessageIds(event)) removed.add(messageId);
10761
+ }
10762
+ }
10763
+ if (removed.size > 0) {
10764
+ primary = excludeQueuedAcceptedEvents(primary, [], [...removed]);
10765
+ supplemental = excludeQueuedAcceptedEvents(supplemental, [], [...removed]);
10766
+ }
10753
10767
  if (supplemental.length === 0) return [...primary];
10754
10768
  const merged = [...primary];
10755
10769
  const index = emptyIndex();
@@ -11573,22 +11587,6 @@ var MessageQueueService = class {
11573
11587
  getQueue() {
11574
11588
  return [...this.queue];
11575
11589
  }
11576
- /**
11577
- * Remove a message from the queue by its ID
11578
- * @returns true if the message was found and removed
11579
- */
11580
- removeFromQueue(messageId) {
11581
- const index = this.queue.findIndex((m) => m.id === messageId);
11582
- if (index === -1) return false;
11583
- this.queue.splice(index, 1);
11584
- return true;
11585
- }
11586
- clearQueue() {
11587
- const hadMessages = this.queue.length > 0;
11588
- this.queueCancellationVersion++;
11589
- this.queue = [];
11590
- return hadMessages;
11591
- }
11592
11590
  updateQueuedMessage(messageId, message) {
11593
11591
  const queuedMessage = this.queue.find((item) => item.id === messageId);
11594
11592
  if (!queuedMessage) return false;
@@ -11742,7 +11740,7 @@ var CodingAgentManager = class {
11742
11740
  );
11743
11741
  this.initialized = this.initialize();
11744
11742
  }
11745
- async persistAcceptedMessage(event) {
11743
+ async persistHistoryEvent(event) {
11746
11744
  const history = this.getHistorySink();
11747
11745
  if (!history?.appendDurably) throw new Error("Chat history is unavailable");
11748
11746
  await history.appendDurably(event);
@@ -11782,11 +11780,32 @@ var CodingAgentManager = class {
11782
11780
  ...m.senderDisplayName ? { senderDisplayName: m.senderDisplayName } : {}
11783
11781
  }));
11784
11782
  }
11785
- removeFromQueue(messageId) {
11786
- return this.messageQueue.removeFromQueue(messageId);
11783
+ async removeFromQueue(messageId, persistRemoval) {
11784
+ return this.removeQueuedMessages([messageId], persistRemoval);
11785
+ }
11786
+ async clearQueue(persistRemoval) {
11787
+ const messageIds = this.messageQueue.getQueue().map(({ id }) => id);
11788
+ return this.removeQueuedMessages(messageIds, () => persistRemoval(messageIds));
11787
11789
  }
11788
- clearQueue() {
11789
- return this.messageQueue.clearQueue();
11790
+ async removeQueuedMessages(messageIds, persistRemoval) {
11791
+ const taken = messageIds.flatMap((messageId) => {
11792
+ const item = this.messageQueue.takeFromQueue(messageId);
11793
+ return item ? [item] : [];
11794
+ });
11795
+ if (taken.length === 0) return false;
11796
+ try {
11797
+ await persistRemoval();
11798
+ return true;
11799
+ } catch (error) {
11800
+ this.restoreQueuedMessages(taken);
11801
+ throw error;
11802
+ }
11803
+ }
11804
+ restoreQueuedMessages(taken) {
11805
+ for (let index = taken.length - 1; index >= 0; index--) {
11806
+ this.messageQueue.restoreToQueue(taken[index].message, taken[index].index);
11807
+ }
11808
+ this.messageQueue.resumeIfIdle();
11790
11809
  }
11791
11810
  updateQueuedMessage(messageId, message) {
11792
11811
  return this.messageQueue.updateQueuedMessage(messageId, message);
@@ -11818,11 +11837,10 @@ var CodingAgentManager = class {
11818
11837
  if (!steered) {
11819
11838
  if (keepQueued) {
11820
11839
  const prioritized = this.messageQueue.takeFromQueue(messageId);
11821
- if (prioritized) this.messageQueue.restoreToQueue(prioritized.message, taken.index);
11840
+ if (prioritized) this.restoreQueuedMessages([{ message: prioritized.message, index: taken.index }]);
11822
11841
  } else {
11823
- this.messageQueue.restoreToQueue(taken.message, taken.index);
11842
+ this.restoreQueuedMessages([taken]);
11824
11843
  }
11825
- this.messageQueue.resumeIfIdle();
11826
11844
  }
11827
11845
  return {
11828
11846
  success: steered,
@@ -17638,6 +17656,8 @@ var MuseManager = class extends CodingAgentManager {
17638
17656
  turnError = null;
17639
17657
  compactionComplete = null;
17640
17658
  pendingInput = null;
17659
+ pendingApprovals = /* @__PURE__ */ new Map();
17660
+ resolvedApprovals = /* @__PURE__ */ new Set();
17641
17661
  slashCommands = null;
17642
17662
  constructor(options) {
17643
17663
  super({ ...options, provider: "muse" });
@@ -17663,6 +17683,15 @@ var MuseManager = class extends CodingAgentManager {
17663
17683
  const client2 = new AspClient({ stdin: child.stdin, stdout: child.stdout, jsonRpcVersion: "2.0" });
17664
17684
  this.client = client2;
17665
17685
  client2.on("notification", (notification) => this.handleNotification(notification));
17686
+ client2.on("serverRequest", (request) => {
17687
+ const frame = request;
17688
+ if (isRecord(frame) && frame.method === "approval/request") {
17689
+ this.handleNotification({ method: "approval/requested", params: frame.params });
17690
+ client2.respond(request.id, {});
17691
+ } else {
17692
+ client2.reject(request.id, -32601, "Unsupported Muse request");
17693
+ }
17694
+ });
17666
17695
  child.stderr.on("data", (chunk) => console.error("[muse MSP]", chunk.toString().trimEnd()));
17667
17696
  child.on("error", (error) => this.handleProcessExit(child, error));
17668
17697
  child.on("exit", (code, signal) => this.handleProcessExit(
@@ -17681,6 +17710,7 @@ var MuseManager = class extends CodingAgentManager {
17681
17710
  } catch {
17682
17711
  this.sessionId = null;
17683
17712
  }
17713
+ if (this.sessionId) await this.refreshPendingApprovals();
17684
17714
  }
17685
17715
  if (!this.sessionId) {
17686
17716
  const result = await this.request("session/start", {
@@ -17703,12 +17733,92 @@ var MuseManager = class extends CodingAgentManager {
17703
17733
  notify(method, params) {
17704
17734
  this.client?.notify(method, params);
17705
17735
  }
17736
+ async refreshPendingApprovals() {
17737
+ if (!this.sessionId) return;
17738
+ const previous = new Map(this.pendingApprovals);
17739
+ const result = await this.request("approval/listPending", { sessionId: this.sessionId }).catch(() => null);
17740
+ if (!isRecord(result) || !Array.isArray(result.approvals)) return;
17741
+ for (const [approvalId, pending] of previous) {
17742
+ if (this.pendingApprovals.get(approvalId) === pending && !result.approvals.some((approval) => isRecord(approval) && approval.approvalId === approvalId)) {
17743
+ this.resolveApproval(approvalId, "resolved");
17744
+ }
17745
+ }
17746
+ for (const approval of result.approvals) {
17747
+ this.handleNotification({ method: "approval/requested", params: approval });
17748
+ }
17749
+ }
17750
+ resolveApproval(approvalId, selectionId, terminal = true) {
17751
+ const pending = this.pendingApprovals.get(approvalId);
17752
+ if (terminal) this.resolvedApprovals.add(approvalId);
17753
+ if (!pending) return;
17754
+ this.pendingApprovals.delete(approvalId);
17755
+ const choice = pending.availableChoices.find((choice2) => choice2.choiceId === selectionId);
17756
+ this.recordHistoryEvent("replicas-tool-input-resolved", {
17757
+ requestId: pending.requestId,
17758
+ toolUseId: pending.itemId,
17759
+ toolName: pending.toolName,
17760
+ selectionId: choice ? JSON.stringify({ approval: { options: [choice.choiceId] } }) : selectionId,
17761
+ selectionSummary: choice?.label,
17762
+ parent_tool_use_id: null
17763
+ }, this.historyFile);
17764
+ }
17765
+ handleApproval(params) {
17766
+ if (!this.sessionId || params.sessionId !== this.sessionId || typeof params.approvalId !== "string" || this.resolvedApprovals.has(params.approvalId)) return;
17767
+ const previous = this.pendingApprovals.get(params.approvalId);
17768
+ const value = { ...previous, ...params };
17769
+ const requirement = value.currentRequirementId;
17770
+ if (!isRecord(requirement) || requirement.approvalId !== params.approvalId || typeof requirement.sourceIndex !== "number" || !Number.isSafeInteger(requirement.sourceIndex) || requirement.sourceIndex < 0 || typeof value.itemId !== "string" || typeof value.toolName !== "string" || typeof value.rawArgs !== "string" || !isRecord(value.subject) || !Array.isArray(value.availableChoices)) return;
17771
+ const choices = value.availableChoices.filter((choice) => isRecord(choice) && typeof choice.choiceId === "string" && typeof choice.label === "string" && typeof choice.decision === "string" && (choice.rulePreview === void 0 || typeof choice.rulePreview === "string"));
17772
+ if (choices.length === 0 || choices.length !== value.availableChoices.length) return;
17773
+ if (previous && (requirement.sourceIndex < previous.currentRequirementId.sourceIndex || typeof params.viewCursor === "string" && params.viewCursor === previous.viewCursor)) return;
17774
+ const requestId = previous?.currentRequirementId.sourceIndex === requirement.sourceIndex ? previous.requestId : `muse-approval:${params.approvalId}:${requirement.sourceIndex}:${uuidV7()}`;
17775
+ const pending = {
17776
+ approvalId: params.approvalId,
17777
+ sessionId: this.sessionId,
17778
+ itemId: value.itemId,
17779
+ toolName: value.toolName,
17780
+ rawArgs: value.rawArgs,
17781
+ currentRequirementId: { approvalId: params.approvalId, sourceIndex: requirement.sourceIndex },
17782
+ availableChoices: choices,
17783
+ subject: value.subject,
17784
+ requestId,
17785
+ ...typeof params.viewCursor === "string" ? { viewCursor: params.viewCursor } : {},
17786
+ ...previous?.requestId === requestId ? { selectionId: previous.selectionId } : {}
17787
+ };
17788
+ if (previous && previous.requestId !== requestId) {
17789
+ this.resolveApproval(pending.approvalId, previous.selectionId ?? "resolved", false);
17790
+ }
17791
+ this.pendingApprovals.set(pending.approvalId, pending);
17792
+ const stages = Array.isArray(pending.subject.stages) ? pending.subject.stages : [];
17793
+ const stage = stages.find((stage2) => isRecord(stage2) && isRecord(stage2.requirementId) && stage2.requirementId.sourceIndex === requirement.sourceIndex);
17794
+ const stageLabel = isRecord(stage) ? ` (stage ${stage.position} of ${stage.totalStages})` : "";
17795
+ this.recordHistoryEvent("replicas-tool-input-request", {
17796
+ requestId,
17797
+ toolUseId: pending.itemId,
17798
+ toolName: pending.toolName,
17799
+ questions: [{
17800
+ id: "approval",
17801
+ prompt: `Allow ${pending.toolName}${stageLabel}?
17802
+
17803
+ ${typeof pending.subject.command === "string" ? pending.subject.command : JSON.stringify(pending.subject, null, 2)}`,
17804
+ multiSelect: false,
17805
+ allowCustom: false,
17806
+ options: choices.map((choice) => ({ id: choice.choiceId, label: choice.label, ...choice.rulePreview ? { preview: choice.rulePreview } : {} }))
17807
+ }],
17808
+ parent_tool_use_id: null
17809
+ }, this.historyFile);
17810
+ this.recordHistoryEvent("muse-item-started", {
17811
+ item: { itemId: pending.itemId, kind: "toolCall", tool: pending.toolName, args: pending.rawArgs, status: "inProgress" }
17812
+ }, this.historyFile);
17813
+ }
17706
17814
  handleProcessExit(child, error) {
17707
17815
  if (this.process !== child) return;
17708
17816
  const hadPendingRequest = (this.client?.pendingRequestCount ?? 0) > 0;
17709
17817
  this.process = null;
17710
17818
  this.client?.dispose(error);
17711
17819
  this.client = null;
17820
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17821
+ this.resolvedApprovals.clear();
17712
17822
  if (this.turnComplete && !hadPendingRequest) {
17713
17823
  this.recordHistoryEvent("muse-error", { message: error.message }, this.historyFile);
17714
17824
  }
@@ -17722,6 +17832,8 @@ var MuseManager = class extends CodingAgentManager {
17722
17832
  this.process = null;
17723
17833
  this.client?.dispose();
17724
17834
  this.client = null;
17835
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17836
+ this.resolvedApprovals.clear();
17725
17837
  process10?.kill("SIGTERM");
17726
17838
  }
17727
17839
  createTurnInput(text, images) {
@@ -17734,8 +17846,17 @@ var MuseManager = class extends CodingAgentManager {
17734
17846
  }
17735
17847
  handleNotification(frame) {
17736
17848
  if (!isRecord(frame) || typeof frame.method !== "string" || !isRecord(frame.params)) return;
17849
+ if (typeof frame.params.sessionId === "string" && this.sessionId && frame.params.sessionId !== this.sessionId) return;
17737
17850
  this.recordHistoryEvent(`muse-${frame.method.replaceAll("/", "-")}`, frame.params, this.historyFile);
17738
- if (frame.method === "turn/completed") {
17851
+ if (frame.method === "approval/requested" || frame.method === "approval/updated") {
17852
+ this.handleApproval(frame.params);
17853
+ } else if (frame.method === "approval/resolved" && typeof frame.params.approvalId === "string") {
17854
+ const pending = this.pendingApprovals.get(frame.params.approvalId);
17855
+ const decision = typeof frame.params.decision === "string" ? frame.params.decision : "resolved";
17856
+ const choice = pending?.availableChoices.find((choice2) => choice2.decision === decision && choice2.choiceId === pending.selectionId) ?? pending?.availableChoices.find((choice2) => choice2.decision === decision);
17857
+ this.resolveApproval(frame.params.approvalId, choice?.choiceId ?? decision);
17858
+ } else if (frame.method === "turn/completed") {
17859
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17739
17860
  this.turnError = isRecord(frame.params.error) && typeof frame.params.error.message === "string" ? frame.params.error.message : null;
17740
17861
  this.activeTurnId = null;
17741
17862
  this.turnComplete?.resolve();
@@ -17878,6 +17999,7 @@ ${pending}
17878
17999
  this.activeTurnId = null;
17879
18000
  this.turnError = null;
17880
18001
  this.pendingInput = null;
18002
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17881
18003
  this.compactionComplete?.resolve();
17882
18004
  this.compactionComplete = null;
17883
18005
  try {
@@ -17907,6 +18029,36 @@ ${pending}
17907
18029
  return true;
17908
18030
  }
17909
18031
  async respondToToolInput(requestId, selectionId) {
18032
+ const approval = [...this.pendingApprovals.values()].find((pending2) => pending2.requestId === requestId);
18033
+ if (approval) {
18034
+ if (!this.sessionId || approval.selectionId) return false;
18035
+ let selections;
18036
+ try {
18037
+ selections = JSON.parse(selectionId);
18038
+ } catch {
18039
+ }
18040
+ const answer = isRecord(selections) && isRecord(selections.approval) ? selections.approval : null;
18041
+ const choiceId = selectionId === "declined" ? approval.availableChoices.find((choice2) => choice2.decision === "abort" || choice2.decision === "denied")?.choiceId : answer && !answer.custom && Array.isArray(answer.options) && answer.options.length === 1 ? answer.options[0] : selectionId;
18042
+ const choice = approval.availableChoices.find((candidate) => candidate.choiceId === choiceId);
18043
+ if (!choice) return false;
18044
+ approval.selectionId = choice.choiceId;
18045
+ try {
18046
+ await this.request("approval/decide", {
18047
+ commandId: uuidV7(),
18048
+ sessionId: approval.sessionId,
18049
+ approvalId: approval.approvalId,
18050
+ requirementId: approval.currentRequirementId,
18051
+ choiceId: choice.choiceId
18052
+ });
18053
+ } catch (error) {
18054
+ approval.selectionId = void 0;
18055
+ const current = this.pendingApprovals.get(approval.approvalId);
18056
+ if (current?.requestId === requestId) current.selectionId = void 0;
18057
+ await this.refreshPendingApprovals();
18058
+ throw error;
18059
+ }
18060
+ return true;
18061
+ }
17910
18062
  if (!this.pendingInput || this.pendingInput.userInputId !== requestId || !this.sessionId) return false;
17911
18063
  const pending = this.pendingInput;
17912
18064
  if (selectionId === "declined") {
@@ -17944,7 +18096,7 @@ ${pending}
17944
18096
  return true;
17945
18097
  }
17946
18098
  isAwaitingInput() {
17947
- return this.pendingInput !== null;
18099
+ return this.pendingInput !== null || this.pendingApprovals.size > 0;
17948
18100
  }
17949
18101
  async getHistory(page2 = {}) {
17950
18102
  await this.historyFile.flush();
@@ -60869,7 +61021,9 @@ async function uploadChatTranscript(chatId, filePath, chat, capture) {
60869
61021
  } catch (error) {
60870
61022
  if (!(error && typeof error === "object" && "code" in error && error.code === "ENOENT")) throw error;
60871
61023
  }
60872
- if (historyPages.index.codexAspTranscript) metadata.historyIndex = historyPages.index;
61024
+ if (historyPages.index.codexAspTranscript || historyPages.index.removedMessageIds?.length) {
61025
+ metadata.historyIndex = historyPages.index;
61026
+ }
60873
61027
  const uploadRequest = { chatId, size, metadata };
60874
61028
  const prepareResponse = await monolithRequest("/v1/engine/chat-transcripts/upload-url", {
60875
61029
  body: uploadRequest
@@ -61176,6 +61330,7 @@ function acceptedEventInCodexTranscript(acceptedEvent, transcript) {
61176
61330
  }
61177
61331
  var LAST_MESSAGE_PREVIEW_MAX = 200;
61178
61332
  var MAX_ACCEPTED_SEND_RESPONSES = 50;
61333
+ var MAX_REMOVED_MESSAGE_IDS = 6e3;
61179
61334
  var RELAY_SUBAGENT_POLL_INTERVAL_MS = 2e3;
61180
61335
  var DEFAULT_RELAY_SUBAGENT_TIMEOUT_MS = 6e5;
61181
61336
  async function resolveRelayBaseProvider(provider, requested) {
@@ -61212,6 +61367,7 @@ function normalizePersistedChat(chat) {
61212
61367
  lastMessageText: chat.lastMessageText ?? null,
61213
61368
  deletedAt: chat.deletedAt ?? null,
61214
61369
  fork: coerceChatForkInfo(chat.fork),
61370
+ removedMessageIds: Array.isArray(chat.removedMessageIds) ? chat.removedMessageIds.filter((id) => typeof id === "string").slice(-MAX_REMOVED_MESSAGE_IDS) : [],
61215
61371
  acceptedSendResponses: isRecord2(chat.acceptedSendResponses) ? Object.fromEntries(Object.entries(chat.acceptedSendResponses).filter((entry) => {
61216
61372
  const response = entry[1];
61217
61373
  return isRecord2(response) && typeof response.messageId === "string" && typeof response.queued === "boolean" && typeof response.position === "number";
@@ -61474,7 +61630,7 @@ var ChatService = class {
61474
61630
  submittedAt
61475
61631
  );
61476
61632
  try {
61477
- await chat.provider.persistAcceptedMessage(acceptedEvent);
61633
+ await chat.provider.persistHistoryEvent(acceptedEvent);
61478
61634
  } catch (error) {
61479
61635
  throw new ChatMessagePersistenceError(error);
61480
61636
  }
@@ -61493,10 +61649,12 @@ var ChatService = class {
61493
61649
  }
61494
61650
  chat.persisted.acceptedSendResponses = Object.fromEntries(chat.acceptedSendResponses);
61495
61651
  }
61496
- if (!chat.pendingMessageIds.includes(result.messageId)) {
61497
- chat.pendingMessageIds.push(result.messageId);
61652
+ if (!chat.persisted.removedMessageIds?.includes(result.messageId)) {
61653
+ if (!chat.pendingMessageIds.includes(result.messageId)) {
61654
+ chat.pendingMessageIds.push(result.messageId);
61655
+ }
61656
+ chat.acceptedUserEvents.set(result.messageId, acceptedEvent);
61498
61657
  }
61499
- chat.acceptedUserEvents.set(result.messageId, acceptedEvent);
61500
61658
  chat.persisted.lastMessageText = request.message.trim().slice(0, LAST_MESSAGE_PREVIEW_MAX) || null;
61501
61659
  chat.persisted.updatedAt = (/* @__PURE__ */ new Date()).toISOString();
61502
61660
  try {
@@ -61616,43 +61774,56 @@ var ChatService = class {
61616
61774
  queue: chat.provider.getQueue()
61617
61775
  };
61618
61776
  }
61619
- // A message removed from the queue will never run a turn, so its pending
61620
- // bookkeeping must go with it or hasActiveChatTurn stays true forever.
61621
- forgetPendingMessages(chat, messageIds) {
61777
+ async forgetPendingMessages(chat, messageIds) {
61622
61778
  if (messageIds.length === 0) return;
61623
61779
  const removed = new Set(messageIds);
61780
+ const event = {
61781
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
61782
+ type: QUEUED_MESSAGE_REMOVED_EVENT_TYPE,
61783
+ payload: { [REMOVED_MESSAGE_IDS_PAYLOAD_KEY]: [...removed] }
61784
+ };
61785
+ await chat.provider.persistHistoryEvent(event);
61786
+ chat.persisted.removedMessageIds = [.../* @__PURE__ */ new Set([...chat.persisted.removedMessageIds ?? [], ...removed])].slice(-MAX_REMOVED_MESSAGE_IDS);
61624
61787
  chat.pendingMessageIds = chat.pendingMessageIds.filter((messageId) => !removed.has(messageId));
61625
61788
  for (const messageId of removed) {
61626
61789
  chat.acceptedUserEvents.delete(messageId);
61627
61790
  chat.errorNotificationTargets.delete(messageId);
61628
61791
  }
61792
+ await this.persistAllChats().catch((error) => {
61793
+ console.error("[ChatService] Failed to persist queued-message removals:", error);
61794
+ });
61795
+ await this.publish({
61796
+ type: "chat.turn.delta",
61797
+ payload: { chatId: chat.persisted.id, event }
61798
+ }).catch((error) => {
61799
+ console.error("[ChatService] Failed to publish queued-message removals:", error);
61800
+ });
61629
61801
  this.publish({
61630
61802
  type: "chat.updated",
61631
61803
  payload: { chat: this.toSummary(chat) }
61632
61804
  }).catch(() => {
61633
61805
  });
61634
61806
  }
61635
- removeFromQueue(chatId, messageId) {
61807
+ async removeFromQueue(chatId, messageId) {
61636
61808
  const chat = this.requireChat(chatId);
61637
- const success = chat.provider.removeFromQueue(messageId);
61638
- if (success) {
61639
- this.forgetPendingMessages(chat, [messageId]);
61640
- }
61809
+ const success = await chat.provider.removeFromQueue(messageId, () => this.forgetPendingMessages(chat, [messageId]));
61641
61810
  return {
61642
61811
  success,
61643
- queue: chat.provider.getQueue()
61812
+ queue: chat.provider.getQueue(),
61813
+ removedMessageIds: success ? [messageId] : []
61644
61814
  };
61645
61815
  }
61646
- clearQueue(chatId) {
61816
+ async clearQueue(chatId) {
61647
61817
  const chat = this.requireChat(chatId);
61648
- const queuedIds = chat.provider.getQueue().map((message) => message.id);
61649
- const success = chat.provider.clearQueue();
61650
- if (success) {
61651
- this.forgetPendingMessages(chat, queuedIds);
61652
- }
61818
+ let queuedIds = [];
61819
+ const success = await chat.provider.clearQueue(async (messageIds) => {
61820
+ queuedIds = messageIds;
61821
+ await this.forgetPendingMessages(chat, messageIds);
61822
+ });
61653
61823
  return {
61654
61824
  success,
61655
- queue: chat.provider.getQueue()
61825
+ queue: chat.provider.getQueue(),
61826
+ removedMessageIds: success ? queuedIds : []
61656
61827
  };
61657
61828
  }
61658
61829
  updateQueuedMessage(chatId, messageId, message) {
@@ -61904,7 +62075,11 @@ var ChatService = class {
61904
62075
  chat.provider.getHistory(page2),
61905
62076
  this.readSenders(chatId)
61906
62077
  ]);
61907
- const historyEvents = mergeWorkspaceChatHistoryEvents([], history.events);
62078
+ const historyEvents = excludeQueuedAcceptedEvents(
62079
+ mergeWorkspaceChatHistoryEvents([], history.events),
62080
+ chat.provider.getQueue(),
62081
+ chat.persisted.removedMessageIds
62082
+ );
61908
62083
  for (const [messageId, acceptedEvent] of chat.acceptedUserEvents) {
61909
62084
  if (acceptedEventInCodexTranscript(acceptedEvent, history.codexAspTranscript) || historyEvents.some((event) => isSameAcceptedUserEvent(event, acceptedEvent))) {
61910
62085
  chat.acceptedUserEvents.delete(messageId);
@@ -61913,12 +62088,17 @@ var ChatService = class {
61913
62088
  const isLatestPage = isLatestChatHistoryPage(page2);
61914
62089
  const queuedMessageIds = new Set(chat.provider.getQueue().map((message) => message.id));
61915
62090
  const acceptedEvents = (isLatestPage ? [...chat.acceptedUserEvents.entries()] : []).filter(([messageId]) => messageId === chat.activeMessageId || !chat.hasActiveTurn && chat.pendingMessageIds[0] === messageId && !queuedMessageIds.has(messageId)).map(([, acceptedEvent]) => acceptedEvent).filter((acceptedEvent) => !acceptedEventInCodexTranscript(acceptedEvent, history.codexAspTranscript) && !historyEvents.some((event) => isSameAcceptedUserEvent(event, acceptedEvent)));
61916
- const events = [...historyEvents, ...acceptedEvents].sort((a, b) => getEventTimestampMs(a) - getEventTimestampMs(b));
62091
+ const events = excludeQueuedAcceptedEvents(
62092
+ [...historyEvents, ...acceptedEvents].sort((a, b) => getEventTimestampMs(a) - getEventTimestampMs(b)),
62093
+ [],
62094
+ chat.persisted.removedMessageIds
62095
+ );
61917
62096
  if (page2.limit !== void 0 && "beforeCursor" in history) {
61918
62097
  const cursor = parseChatHistoryCursor(history.beforeCursor ?? void 0);
61919
62098
  return {
61920
62099
  ...history,
61921
62100
  events,
62101
+ removedMessageIds: chat.persisted.removedMessageIds,
61922
62102
  goal: history.goal ?? chat.provider.getGoal?.() ?? null,
61923
62103
  senders: getChatHistoryPageSenders(senders, page2),
61924
62104
  beforeCursor: createChatHistoryCursor({
@@ -61931,6 +62111,7 @@ var ChatService = class {
61931
62111
  return {
61932
62112
  ...history,
61933
62113
  events,
62114
+ removedMessageIds: chat.persisted.removedMessageIds,
61934
62115
  totalEvents: (history.totalEvents ?? history.eventsStartIndex + history.events.length) - (history.events.length - historyEvents.length) + acceptedEvents.length,
61935
62116
  goal: history.goal ?? chat.provider.getGoal?.() ?? null,
61936
62117
  senders
@@ -61939,6 +62120,7 @@ var ChatService = class {
61939
62120
  return paginateChatHistory({
61940
62121
  thread_id: history.thread_id,
61941
62122
  events,
62123
+ removedMessageIds: chat.persisted.removedMessageIds,
61942
62124
  codexAspTranscript: history.codexAspTranscript ?? null,
61943
62125
  goal: history.goal ?? chat.provider.getGoal?.() ?? null,
61944
62126
  senders
@@ -63784,9 +63966,9 @@ function createV1Routes(deps) {
63784
63966
  return c.json(jsonError("Failed to get queue", error instanceof Error ? error.message : "Unknown error"), 500);
63785
63967
  }
63786
63968
  });
63787
- app2.delete("/chats/:chatId/queue", (c) => {
63969
+ app2.delete("/chats/:chatId/queue", async (c) => {
63788
63970
  try {
63789
- const result = deps.chatService.clearQueue(c.req.param("chatId"));
63971
+ const result = await deps.chatService.clearQueue(c.req.param("chatId"));
63790
63972
  return c.json(result);
63791
63973
  } catch (error) {
63792
63974
  if (error instanceof ChatNotFoundError) {
@@ -63795,9 +63977,9 @@ function createV1Routes(deps) {
63795
63977
  return c.json(jsonError("Failed to clear queue", error instanceof Error ? error.message : "Unknown error"), 500);
63796
63978
  }
63797
63979
  });
63798
- app2.delete("/chats/:chatId/queue/:messageId", (c) => {
63980
+ app2.delete("/chats/:chatId/queue/:messageId", async (c) => {
63799
63981
  try {
63800
- const result = deps.chatService.removeFromQueue(c.req.param("chatId"), c.req.param("messageId"));
63982
+ const result = await deps.chatService.removeFromQueue(c.req.param("chatId"), c.req.param("messageId"));
63801
63983
  return c.json(result);
63802
63984
  } catch (error) {
63803
63985
  if (error instanceof ChatNotFoundError) {
@@ -3,11 +3,11 @@ import { createRequire as __createRequire } from 'node:module';
3
3
  const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  notifyPostToolUse
6
- } from "./chunk-RCRX7ATX.js";
6
+ } from "./chunk-ZXZ2COVG.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
- import "./chunk-UMU4HGV6.js";
10
+ import "./chunk-DC6RPXQZ.js";
11
11
  import "./chunk-VEQXQN22.js";
12
12
 
13
13
  // src/post-tool-pr-hook.ts
@@ -4,7 +4,7 @@ const require = __createRequire(import.meta.url);
4
4
  import {
5
5
  messageRelaySubagentRequestSchema,
6
6
  spawnRelaySubagentRequestSchema
7
- } from "./chunk-UMU4HGV6.js";
7
+ } from "./chunk-DC6RPXQZ.js";
8
8
  import "./chunk-VEQXQN22.js";
9
9
 
10
10
  // src/relay-mcp.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "replicas-engine",
3
- "version": "0.1.764",
3
+ "version": "0.1.766",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",