replicas-engine 0.1.764 → 0.1.765

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-4OLXBASZ.js";
9
+ import "./chunk-WFWT2YFN.js";
10
+ import "./chunk-SQX57KJM.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-UMU4HGV6.js";
12
+ import "./chunk-UQETFAOK.js";
13
13
  import "./chunk-VEQXQN22.js";
14
14
  export {
15
15
  getCodexAspHost,
@@ -5,18 +5,18 @@ import {
5
5
  ENGINE_ENV,
6
6
  monolithRequest,
7
7
  setAgentCredentialSnapshot
8
- } from "./chunk-WOFZOLYF.js";
8
+ } from "./chunk-WFWT2YFN.js";
9
9
  import {
10
10
  AppServerProcess,
11
11
  buildCodexAgentEnv
12
- } from "./chunk-SQWL6FMP.js";
12
+ } from "./chunk-SQX57KJM.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-UQETFAOK.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-X3XQGPRO.js");
236
236
  await restartCodexAspHostIfRunning2();
237
237
  }
238
238
  if (data.scope) {
@@ -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-WFWT2YFN.js";
7
7
  import {
8
8
  extractCommandProtectionCommandText,
9
9
  findGitCommitSignals,
10
10
  findPrMergeSignals
11
- } from "./chunk-UMU4HGV6.js";
11
+ } from "./chunk-UQETFAOK.js";
12
12
 
13
13
  // src/services/command-protection-service.ts
14
14
  var DEFAULT_COMMAND_PROTECTION_BLOCK_MESSAGE = "Blocked by Replicas command protection.";
@@ -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-UQETFAOK.js";
8
8
 
9
9
  // src/services/post-tool-pr-notifier.ts
10
10
  async function notifyPostToolUse(toolName, toolInput, toolResult) {
@@ -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-UQETFAOK.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.765";
245
245
  var INITIALIZE_METHOD = "initialize";
246
246
  var INITIALIZED_NOTIFICATION = "initialized";
247
247
  var ACCOUNT_LOGIN_START_METHOD = "account/login/start";
@@ -1537,7 +1537,8 @@ function upsertDisplayMessage(messages, message) {
1537
1537
  }
1538
1538
  function applyToolInputEvent(event, messages, provider, state, questionFilter) {
1539
1539
  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);
1540
+ const previous = state.resolutions.get(event.payload.toolUseId);
1541
+ const resolved = previous && (!previous.requestId || previous.requestId === event.payload.requestId) ? previous : void 0;
1541
1542
  const inputRequest = {
1542
1543
  requestId: event.payload.requestId,
1543
1544
  status: resolved?.selectionId === "aborted" || resolved?.selectionId === "declined" ? "aborted" : resolved ? "resolved" : "pending",
@@ -1553,12 +1554,13 @@ function applyToolInputEvent(event, messages, provider, state, questionFilter) {
1553
1554
  }
1554
1555
  if (event.type === "replicas-tool-input-resolved" && typeof event.payload.toolUseId === "string" && typeof event.payload.selectionId === "string") {
1555
1556
  const resolved = {
1557
+ ...typeof event.payload.requestId === "string" ? { requestId: event.payload.requestId } : {},
1556
1558
  selectionId: event.payload.selectionId,
1557
1559
  ...typeof event.payload.selectionSummary === "string" ? { selectionSummary: event.payload.selectionSummary } : {}
1558
1560
  };
1559
1561
  state.resolutions.set(event.payload.toolUseId, resolved);
1560
1562
  const inputRequest = state.requests.get(event.payload.toolUseId);
1561
- if (inputRequest) {
1563
+ if (inputRequest && (!resolved.requestId || resolved.requestId === inputRequest.requestId)) {
1562
1564
  inputRequest.status = resolved.selectionId === "aborted" || resolved.selectionId === "declined" ? "aborted" : "resolved";
1563
1565
  inputRequest.selectionId = resolved.selectionId;
1564
1566
  if (resolved.selectionSummary) inputRequest.selectionSummary = resolved.selectionSummary;
@@ -1607,6 +1609,7 @@ function skillNameFromToolCall(tool, input) {
1607
1609
  return parseSkillFilePath(input);
1608
1610
  }
1609
1611
  function createCallDisplayMessage(message) {
1612
+ if (message.inputRequest) return { ...message, type: "tool_call" };
1610
1613
  const skillName = message.server.toLowerCase() === "skills" ? message.tool : skillNameFromToolCall(message.tool, message.input);
1611
1614
  if (skillName === null) return { ...message, type: "tool_call" };
1612
1615
  return {
@@ -4516,12 +4519,12 @@ function parseMuseEvents(events) {
4516
4519
  id: `muse-tool-${item.itemId}`,
4517
4520
  server: "muse",
4518
4521
  tool: typeof item.tool === "string" ? item.tool : "tool",
4522
+ inputRequest: inputState.requests.get(item.itemId),
4519
4523
  input: isRecord(input) ? input : typeof input === "string" ? input : void 0,
4520
4524
  output: typeof item.visibleOutput === "string" ? item.visibleOutput : item.failureReason === void 0 ? void 0 : stringifyDisplayValue(item.failureReason),
4521
4525
  status: item.status === "failed" || item.status === "rejected" ? "failed" : terminal ? "completed" : "in_progress",
4522
4526
  timestamp: typeof item.recordedAt === "string" ? item.recordedAt : event.timestamp
4523
4527
  });
4524
- if (message.type === "tool_call") message.inputRequest = inputState.requests.get(item.itemId);
4525
4528
  upsertDisplayMessage(messages, message);
4526
4529
  }
4527
4530
  }
@@ -15,7 +15,7 @@ import {
15
15
  isValidRelayBaseProvider,
16
16
  parsePosixEnvFile,
17
17
  readReplicasRuntimeEnv
18
- } from "./chunk-UMU4HGV6.js";
18
+ } from "./chunk-UQETFAOK.js";
19
19
 
20
20
  // src/engine-env.ts
21
21
  import { readFileSync as readFileSync2 } from "fs";
@@ -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-CWSZPPD6.js";
7
+ import "./chunk-WFWT2YFN.js";
8
8
  import {
9
9
  isRecord
10
10
  } from "./chunk-UZSNFLDQ.js";
11
- import "./chunk-UMU4HGV6.js";
11
+ import "./chunk-UQETFAOK.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-CWSZPPD6.js";
7
7
  import {
8
8
  notifyPostToolUse
9
- } from "./chunk-RCRX7ATX.js";
10
- import "./chunk-WOFZOLYF.js";
9
+ } from "./chunk-L2BNNGQB.js";
10
+ import "./chunk-WFWT2YFN.js";
11
11
  import "./chunk-UZSNFLDQ.js";
12
- import "./chunk-UMU4HGV6.js";
12
+ import "./chunk-UQETFAOK.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-SQX57KJM.js";
12
12
  import {
13
13
  AGENT,
14
14
  getMemoryOutputSafetyViolation,
15
15
  headlessAgentRequestSchema
16
- } from "./chunk-UMU4HGV6.js";
16
+ } from "./chunk-UQETFAOK.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-CWSZPPD6.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-4OLXBASZ.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-WFWT2YFN.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-SQX57KJM.js";
141
141
  import {
142
142
  isRecord as isRecord2
143
143
  } from "./chunk-UZSNFLDQ.js";
@@ -333,7 +333,7 @@ import {
333
333
  spawnRelaySubagentRequestSchema,
334
334
  stripAgentDiagnosticErrors,
335
335
  withTimeout
336
- } from "./chunk-UMU4HGV6.js";
336
+ } from "./chunk-UQETFAOK.js";
337
337
  import {
338
338
  __commonJS,
339
339
  __export,
@@ -17638,6 +17638,8 @@ var MuseManager = class extends CodingAgentManager {
17638
17638
  turnError = null;
17639
17639
  compactionComplete = null;
17640
17640
  pendingInput = null;
17641
+ pendingApprovals = /* @__PURE__ */ new Map();
17642
+ resolvedApprovals = /* @__PURE__ */ new Set();
17641
17643
  slashCommands = null;
17642
17644
  constructor(options) {
17643
17645
  super({ ...options, provider: "muse" });
@@ -17663,6 +17665,15 @@ var MuseManager = class extends CodingAgentManager {
17663
17665
  const client2 = new AspClient({ stdin: child.stdin, stdout: child.stdout, jsonRpcVersion: "2.0" });
17664
17666
  this.client = client2;
17665
17667
  client2.on("notification", (notification) => this.handleNotification(notification));
17668
+ client2.on("serverRequest", (request) => {
17669
+ const frame = request;
17670
+ if (isRecord(frame) && frame.method === "approval/request") {
17671
+ this.handleNotification({ method: "approval/requested", params: frame.params });
17672
+ client2.respond(request.id, {});
17673
+ } else {
17674
+ client2.reject(request.id, -32601, "Unsupported Muse request");
17675
+ }
17676
+ });
17666
17677
  child.stderr.on("data", (chunk) => console.error("[muse MSP]", chunk.toString().trimEnd()));
17667
17678
  child.on("error", (error) => this.handleProcessExit(child, error));
17668
17679
  child.on("exit", (code, signal) => this.handleProcessExit(
@@ -17681,6 +17692,7 @@ var MuseManager = class extends CodingAgentManager {
17681
17692
  } catch {
17682
17693
  this.sessionId = null;
17683
17694
  }
17695
+ if (this.sessionId) await this.refreshPendingApprovals();
17684
17696
  }
17685
17697
  if (!this.sessionId) {
17686
17698
  const result = await this.request("session/start", {
@@ -17703,12 +17715,92 @@ var MuseManager = class extends CodingAgentManager {
17703
17715
  notify(method, params) {
17704
17716
  this.client?.notify(method, params);
17705
17717
  }
17718
+ async refreshPendingApprovals() {
17719
+ if (!this.sessionId) return;
17720
+ const previous = new Map(this.pendingApprovals);
17721
+ const result = await this.request("approval/listPending", { sessionId: this.sessionId }).catch(() => null);
17722
+ if (!isRecord(result) || !Array.isArray(result.approvals)) return;
17723
+ for (const [approvalId, pending] of previous) {
17724
+ if (this.pendingApprovals.get(approvalId) === pending && !result.approvals.some((approval) => isRecord(approval) && approval.approvalId === approvalId)) {
17725
+ this.resolveApproval(approvalId, "resolved");
17726
+ }
17727
+ }
17728
+ for (const approval of result.approvals) {
17729
+ this.handleNotification({ method: "approval/requested", params: approval });
17730
+ }
17731
+ }
17732
+ resolveApproval(approvalId, selectionId, terminal = true) {
17733
+ const pending = this.pendingApprovals.get(approvalId);
17734
+ if (terminal) this.resolvedApprovals.add(approvalId);
17735
+ if (!pending) return;
17736
+ this.pendingApprovals.delete(approvalId);
17737
+ const choice = pending.availableChoices.find((choice2) => choice2.choiceId === selectionId);
17738
+ this.recordHistoryEvent("replicas-tool-input-resolved", {
17739
+ requestId: pending.requestId,
17740
+ toolUseId: pending.itemId,
17741
+ toolName: pending.toolName,
17742
+ selectionId: choice ? JSON.stringify({ approval: { options: [choice.choiceId] } }) : selectionId,
17743
+ selectionSummary: choice?.label,
17744
+ parent_tool_use_id: null
17745
+ }, this.historyFile);
17746
+ }
17747
+ handleApproval(params) {
17748
+ if (!this.sessionId || params.sessionId !== this.sessionId || typeof params.approvalId !== "string" || this.resolvedApprovals.has(params.approvalId)) return;
17749
+ const previous = this.pendingApprovals.get(params.approvalId);
17750
+ const value = { ...previous, ...params };
17751
+ const requirement = value.currentRequirementId;
17752
+ 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;
17753
+ 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"));
17754
+ if (choices.length === 0 || choices.length !== value.availableChoices.length) return;
17755
+ if (previous && (requirement.sourceIndex < previous.currentRequirementId.sourceIndex || typeof params.viewCursor === "string" && params.viewCursor === previous.viewCursor)) return;
17756
+ const requestId = previous?.currentRequirementId.sourceIndex === requirement.sourceIndex ? previous.requestId : `muse-approval:${params.approvalId}:${requirement.sourceIndex}:${uuidV7()}`;
17757
+ const pending = {
17758
+ approvalId: params.approvalId,
17759
+ sessionId: this.sessionId,
17760
+ itemId: value.itemId,
17761
+ toolName: value.toolName,
17762
+ rawArgs: value.rawArgs,
17763
+ currentRequirementId: { approvalId: params.approvalId, sourceIndex: requirement.sourceIndex },
17764
+ availableChoices: choices,
17765
+ subject: value.subject,
17766
+ requestId,
17767
+ ...typeof params.viewCursor === "string" ? { viewCursor: params.viewCursor } : {},
17768
+ ...previous?.requestId === requestId ? { selectionId: previous.selectionId } : {}
17769
+ };
17770
+ if (previous && previous.requestId !== requestId) {
17771
+ this.resolveApproval(pending.approvalId, previous.selectionId ?? "resolved", false);
17772
+ }
17773
+ this.pendingApprovals.set(pending.approvalId, pending);
17774
+ const stages = Array.isArray(pending.subject.stages) ? pending.subject.stages : [];
17775
+ const stage = stages.find((stage2) => isRecord(stage2) && isRecord(stage2.requirementId) && stage2.requirementId.sourceIndex === requirement.sourceIndex);
17776
+ const stageLabel = isRecord(stage) ? ` (stage ${stage.position} of ${stage.totalStages})` : "";
17777
+ this.recordHistoryEvent("replicas-tool-input-request", {
17778
+ requestId,
17779
+ toolUseId: pending.itemId,
17780
+ toolName: pending.toolName,
17781
+ questions: [{
17782
+ id: "approval",
17783
+ prompt: `Allow ${pending.toolName}${stageLabel}?
17784
+
17785
+ ${typeof pending.subject.command === "string" ? pending.subject.command : JSON.stringify(pending.subject, null, 2)}`,
17786
+ multiSelect: false,
17787
+ allowCustom: false,
17788
+ options: choices.map((choice) => ({ id: choice.choiceId, label: choice.label, ...choice.rulePreview ? { preview: choice.rulePreview } : {} }))
17789
+ }],
17790
+ parent_tool_use_id: null
17791
+ }, this.historyFile);
17792
+ this.recordHistoryEvent("muse-item-started", {
17793
+ item: { itemId: pending.itemId, kind: "toolCall", tool: pending.toolName, args: pending.rawArgs, status: "inProgress" }
17794
+ }, this.historyFile);
17795
+ }
17706
17796
  handleProcessExit(child, error) {
17707
17797
  if (this.process !== child) return;
17708
17798
  const hadPendingRequest = (this.client?.pendingRequestCount ?? 0) > 0;
17709
17799
  this.process = null;
17710
17800
  this.client?.dispose(error);
17711
17801
  this.client = null;
17802
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17803
+ this.resolvedApprovals.clear();
17712
17804
  if (this.turnComplete && !hadPendingRequest) {
17713
17805
  this.recordHistoryEvent("muse-error", { message: error.message }, this.historyFile);
17714
17806
  }
@@ -17722,6 +17814,8 @@ var MuseManager = class extends CodingAgentManager {
17722
17814
  this.process = null;
17723
17815
  this.client?.dispose();
17724
17816
  this.client = null;
17817
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17818
+ this.resolvedApprovals.clear();
17725
17819
  process10?.kill("SIGTERM");
17726
17820
  }
17727
17821
  createTurnInput(text, images) {
@@ -17734,8 +17828,17 @@ var MuseManager = class extends CodingAgentManager {
17734
17828
  }
17735
17829
  handleNotification(frame) {
17736
17830
  if (!isRecord(frame) || typeof frame.method !== "string" || !isRecord(frame.params)) return;
17831
+ if (typeof frame.params.sessionId === "string" && this.sessionId && frame.params.sessionId !== this.sessionId) return;
17737
17832
  this.recordHistoryEvent(`muse-${frame.method.replaceAll("/", "-")}`, frame.params, this.historyFile);
17738
- if (frame.method === "turn/completed") {
17833
+ if (frame.method === "approval/requested" || frame.method === "approval/updated") {
17834
+ this.handleApproval(frame.params);
17835
+ } else if (frame.method === "approval/resolved" && typeof frame.params.approvalId === "string") {
17836
+ const pending = this.pendingApprovals.get(frame.params.approvalId);
17837
+ const decision = typeof frame.params.decision === "string" ? frame.params.decision : "resolved";
17838
+ const choice = pending?.availableChoices.find((choice2) => choice2.decision === decision && choice2.choiceId === pending.selectionId) ?? pending?.availableChoices.find((choice2) => choice2.decision === decision);
17839
+ this.resolveApproval(frame.params.approvalId, choice?.choiceId ?? decision);
17840
+ } else if (frame.method === "turn/completed") {
17841
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17739
17842
  this.turnError = isRecord(frame.params.error) && typeof frame.params.error.message === "string" ? frame.params.error.message : null;
17740
17843
  this.activeTurnId = null;
17741
17844
  this.turnComplete?.resolve();
@@ -17878,6 +17981,7 @@ ${pending}
17878
17981
  this.activeTurnId = null;
17879
17982
  this.turnError = null;
17880
17983
  this.pendingInput = null;
17984
+ for (const approvalId of this.pendingApprovals.keys()) this.resolveApproval(approvalId, "aborted");
17881
17985
  this.compactionComplete?.resolve();
17882
17986
  this.compactionComplete = null;
17883
17987
  try {
@@ -17907,6 +18011,36 @@ ${pending}
17907
18011
  return true;
17908
18012
  }
17909
18013
  async respondToToolInput(requestId, selectionId) {
18014
+ const approval = [...this.pendingApprovals.values()].find((pending2) => pending2.requestId === requestId);
18015
+ if (approval) {
18016
+ if (!this.sessionId || approval.selectionId) return false;
18017
+ let selections;
18018
+ try {
18019
+ selections = JSON.parse(selectionId);
18020
+ } catch {
18021
+ }
18022
+ const answer = isRecord(selections) && isRecord(selections.approval) ? selections.approval : null;
18023
+ 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;
18024
+ const choice = approval.availableChoices.find((candidate) => candidate.choiceId === choiceId);
18025
+ if (!choice) return false;
18026
+ approval.selectionId = choice.choiceId;
18027
+ try {
18028
+ await this.request("approval/decide", {
18029
+ commandId: uuidV7(),
18030
+ sessionId: approval.sessionId,
18031
+ approvalId: approval.approvalId,
18032
+ requirementId: approval.currentRequirementId,
18033
+ choiceId: choice.choiceId
18034
+ });
18035
+ } catch (error) {
18036
+ approval.selectionId = void 0;
18037
+ const current = this.pendingApprovals.get(approval.approvalId);
18038
+ if (current?.requestId === requestId) current.selectionId = void 0;
18039
+ await this.refreshPendingApprovals();
18040
+ throw error;
18041
+ }
18042
+ return true;
18043
+ }
17910
18044
  if (!this.pendingInput || this.pendingInput.userInputId !== requestId || !this.sessionId) return false;
17911
18045
  const pending = this.pendingInput;
17912
18046
  if (selectionId === "declined") {
@@ -17944,7 +18078,7 @@ ${pending}
17944
18078
  return true;
17945
18079
  }
17946
18080
  isAwaitingInput() {
17947
- return this.pendingInput !== null;
18081
+ return this.pendingInput !== null || this.pendingApprovals.size > 0;
17948
18082
  }
17949
18083
  async getHistory(page2 = {}) {
17950
18084
  await this.historyFile.flush();
@@ -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-L2BNNGQB.js";
7
7
  import {
8
8
  isRecord
9
9
  } from "./chunk-UZSNFLDQ.js";
10
- import "./chunk-UMU4HGV6.js";
10
+ import "./chunk-UQETFAOK.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-UQETFAOK.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.765",
4
4
  "description": "Lightweight API server for Replicas workspaces",
5
5
  "type": "module",
6
6
  "main": "dist/src/index.js",