@rynfar/meridian 1.70.0 → 1.71.1

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.
@@ -900,17 +900,20 @@ var pluginlessWarned = new LRUMap(256);
900
900
  function clearPluginlessWarnings() {
901
901
  pluginlessWarned.clear();
902
902
  }
903
- function notePluginlessOpenCodeRequest(input) {
903
+ function isPluginlessOpenCodeRequest(input) {
904
904
  if (!input.userAgent?.toLowerCase().startsWith("opencode/"))
905
- return;
906
- if (input.agentModeHeader)
905
+ return false;
906
+ return !input.agentModeHeader;
907
+ }
908
+ function notePluginlessOpenCodeRequest(input) {
909
+ if (!isPluginlessOpenCodeRequest(input))
907
910
  return;
908
911
  const key = input.sessionId || "(keyless)";
909
912
  if (pluginlessWarned.get(key))
910
913
  return;
911
914
  pluginlessWarned.set(key, true);
912
915
  const shortId = input.sessionId ? `${input.sessionId.slice(0, 12)}…` : "(no session header)";
913
- return `OpenCode request without the Meridian plugin's agent headers (session ${shortId}). ` + `OpenCode runs its internal title/summary agents under your session id, so Meridian ` + `cannot tell them apart from your conversation: the first turn of each session can fail ` + `with a 400 or replay against a cold cache. Fix: meridian setup (or update the plugin).`;
916
+ return `OpenCode request without the Meridian plugin's agent headers (session ${shortId}). ` + `OpenCode runs its internal title/summary agents under your session id, so Meridian ` + `cannot tell them apart from your conversation: concurrent turns are admitted rather ` + `than refused, but the one that loses the race replays against a cold prompt cache — ` + `slower and billed as uncached input. Fix: meridian setup (or update the plugin).`;
914
917
  }
915
918
  function runSetup(pluginPath, configPath, generation = "v1") {
916
919
  const path = configPath ?? findOpencodeConfigPath();
@@ -971,4 +974,4 @@ function runSetup(pluginPath, configPath, generation = "v1") {
971
974
  return { configPath: path, pluginPath, alreadyConfigured, removedStale, created: false };
972
975
  }
973
976
 
974
- export { LRUMap, PRIORITY_ATTESTATION_HEADER, verifyPriorityAttestation, init_priorityAttestation, UnparseableConfigError, MissingV1PluginError, MissingV2PluginError, DuplicateMeridianConfigError, findOpencodeConfigPath, findPluginPath, SUPPORTED_OPENCODE_V2_VERSIONS, findV2PluginPath, classifyOpenCodeVersion, detectOpenCodeGeneration, pluginPathForGeneration, checkPluginConfigured, clearPluginlessWarnings, notePluginlessOpenCodeRequest, runSetup };
977
+ export { LRUMap, PRIORITY_ATTESTATION_HEADER, verifyPriorityAttestation, init_priorityAttestation, UnparseableConfigError, MissingV1PluginError, MissingV2PluginError, DuplicateMeridianConfigError, findOpencodeConfigPath, findPluginPath, SUPPORTED_OPENCODE_V2_VERSIONS, findV2PluginPath, classifyOpenCodeVersion, detectOpenCodeGeneration, pluginPathForGeneration, checkPluginConfigured, clearPluginlessWarnings, isPluginlessOpenCodeRequest, notePluginlessOpenCodeRequest, runSetup };
@@ -75,9 +75,10 @@ import {
75
75
  PRIORITY_ATTESTATION_HEADER,
76
76
  checkPluginConfigured,
77
77
  init_priorityAttestation,
78
+ isPluginlessOpenCodeRequest,
78
79
  notePluginlessOpenCodeRequest,
79
80
  verifyPriorityAttestation
80
- } from "./cli-zdbv40d5.js";
81
+ } from "./cli-hxxy0m1z.js";
81
82
  import {
82
83
  __commonJS,
83
84
  __esm,
@@ -6870,6 +6871,13 @@ function ordinalSuffix(n) {
6870
6871
  function linkRequestAbort(signal) {
6871
6872
  const controller = new AbortController;
6872
6873
  let attached = false;
6874
+ const linkedAt = Date.now();
6875
+ let cause;
6876
+ const classify = () => {
6877
+ if (!controller.signal.aborted)
6878
+ return "none";
6879
+ return cause ?? "unknown_abort";
6880
+ };
6873
6881
  const abort = (reason) => {
6874
6882
  if (!controller.signal.aborted)
6875
6883
  controller.abort(reason);
@@ -6889,6 +6897,19 @@ function linkRequestAbort(signal) {
6889
6897
  return;
6890
6898
  signal.removeEventListener("abort", forwardAbort);
6891
6899
  attached = false;
6900
+ },
6901
+ setCause: (labeled) => {
6902
+ cause ??= labeled;
6903
+ },
6904
+ abortSnapshot: () => {
6905
+ const snapshot = {
6906
+ cause: classify(),
6907
+ aborted: controller.signal.aborted
6908
+ };
6909
+ if (controller.signal.aborted) {
6910
+ snapshot.elapsedMs = Math.max(0, Date.now() - linkedAt);
6911
+ }
6912
+ return snapshot;
6892
6913
  }
6893
6914
  };
6894
6915
  }
@@ -23873,6 +23894,45 @@ function canRecoverCapturedToolUses(input) {
23873
23894
  return false;
23874
23895
  }
23875
23896
  }
23897
+ function isStreamedToolBlockComplete(record2) {
23898
+ if (!record2.forwardedStart)
23899
+ return false;
23900
+ if (!record2.naturalStop)
23901
+ return false;
23902
+ if (record2.startedInputObject)
23903
+ return true;
23904
+ if (!record2.json.trim())
23905
+ return false;
23906
+ try {
23907
+ const parsed = JSON.parse(record2.json);
23908
+ return typeof parsed === "object" && parsed !== null && !Array.isArray(parsed);
23909
+ } catch {
23910
+ return false;
23911
+ }
23912
+ }
23913
+ function canRecoverUncapturedToolUses(input) {
23914
+ if (!input.uncapturedRecoveryEnabled)
23915
+ return false;
23916
+ if (!input.passthrough)
23917
+ return false;
23918
+ if (input.reason !== "max_turns")
23919
+ return false;
23920
+ if (input.attemptedMaxTurns !== 1)
23921
+ return false;
23922
+ if (input.capturedToolUses > 0)
23923
+ return false;
23924
+ if (input.streamedToolUses <= 0)
23925
+ return false;
23926
+ if (input.droppedToolUseIds > 0)
23927
+ return false;
23928
+ if (input.sawDuplicateToolUse)
23929
+ return false;
23930
+ if (input.forceSingleToolUse)
23931
+ return false;
23932
+ if (input.earlyStopFired)
23933
+ return false;
23934
+ return true;
23935
+ }
23876
23936
  function extractSdkTermination(errMsg) {
23877
23937
  const stderrTail = extractStderrTail(errMsg);
23878
23938
  const haystack = `${errMsg}
@@ -23937,6 +23997,9 @@ function formatSdkTermination(t, ctx) {
23937
23997
  parts.push(`deferred=${ctx.hasDeferredTools}`);
23938
23998
  if (ctx.sdkSessionId)
23939
23999
  parts.push(`session=${ctx.sdkSessionId.slice(0, 8)}`);
24000
+ if (ctx.abort) {
24001
+ parts.push(`abort=${ctx.abort.cause}`);
24002
+ }
23940
24003
  if (t.rawTail)
23941
24004
  parts.push(`raw=${JSON.stringify(t.rawTail)}`);
23942
24005
  if (t.stderrTail)
@@ -36925,6 +36988,7 @@ function createProxyServer(config2 = {}) {
36925
36988
  let durableWritesRevoked = false;
36926
36989
  let inFlightRequests = 0;
36927
36990
  const activeRequestAborts = new Set;
36991
+ const activeShutdownLabels = new Map;
36928
36992
  const internalHopToken = randomUUID6();
36929
36993
  const errorEnvelope = (shape, type, message) => shape === "anthropic" ? { type: "error", error: { type, message } } : { error: { type, message, code: null } };
36930
36994
  const DRAIN_MESSAGE = "Meridian is shutting down and is not accepting new requests. Retry against another instance.";
@@ -37216,6 +37280,7 @@ function createProxyServer(config2 = {}) {
37216
37280
  body: options.body,
37217
37281
  forcedProfileId: candidate,
37218
37282
  turnWatchdogSignal: options.turnWatchdogSignal,
37283
+ requestAbortLink: options.requestAbortLink,
37219
37284
  forceFreshPriorityReplay: priorityPublication !== undefined && (options.durableRoute?.forceFreshReplay === true || options.currentProfileId !== undefined && candidate !== options.currentProfileId),
37220
37285
  priorityPublication,
37221
37286
  priorityAttemptExposure: exposure
@@ -37293,7 +37358,7 @@ data: ${JSON.stringify(lastError)}
37293
37358
  const handleMessages = async (c, requestMeta, options) => {
37294
37359
  const requestStartAt = requestMeta.queueEnteredAt;
37295
37360
  const requestSignal = options.turnWatchdogSignal ? AbortSignal.any([c.req.raw.signal, options.turnWatchdogSignal]) : c.req.raw.signal;
37296
- const requestAbort = linkRequestAbort(requestSignal);
37361
+ const requestAbort = options.requestAbortLink ?? linkRequestAbort(requestSignal);
37297
37362
  let streamOwnsAbortLink = false;
37298
37363
  return withClaudeLogContext({ requestId: requestMeta.requestId, endpoint: requestMeta.endpoint }, async () => {
37299
37364
  const adapter = detectAdapter(c);
@@ -37628,6 +37693,7 @@ data: ${JSON.stringify(lastError)}
37628
37693
  wantsStream: body.stream === true,
37629
37694
  currentProfileId: assignedProfile,
37630
37695
  turnWatchdogSignal: options.turnWatchdogSignal,
37696
+ requestAbortLink: options.requestAbortLink,
37631
37697
  publicationTurn,
37632
37698
  claimTurn: trustedTurn,
37633
37699
  durableRoute
@@ -37776,6 +37842,10 @@ data: ${JSON.stringify(lastError)}
37776
37842
  const taskBudget = Number.isFinite(parsedBudget) ? { total: parsedBudget } : body.task_budget ? { total: body.task_budget.total ?? body.task_budget } : undefined;
37777
37843
  const betas = betaFilter.forwarded;
37778
37844
  const agentSessionId = adapter.getSessionId(c, body);
37845
+ const pluginlessOpenCode = isPluginlessOpenCodeRequest({
37846
+ userAgent: c.req.header("user-agent"),
37847
+ agentModeHeader: c.req.header("x-opencode-agent-mode")
37848
+ });
37779
37849
  const pluginlessWarning = notePluginlessOpenCodeRequest({
37780
37850
  userAgent: c.req.header("user-agent"),
37781
37851
  agentModeHeader: c.req.header("x-opencode-agent-mode"),
@@ -37842,8 +37912,9 @@ data: ${JSON.stringify(lastError)}
37842
37912
  if (lineageResult.type === "undo" && adapterBase === "opencode" && !agentSessionId) {
37843
37913
  lineageResult = { type: "diverged", reason: "missing-session-header" };
37844
37914
  }
37915
+ const protocolRunsConcurrentTurnsPerSessionKey = adapter.runsConcurrentTurnsPerSessionKey === true || pluginlessOpenCode;
37845
37916
  const declaresPerRequestConcurrentFlow = requestSource?.startsWith("fork-") === true || isSubagentRequest;
37846
- const declaresConcurrentFlow = declaresPerRequestConcurrentFlow || adapter.runsConcurrentTurnsPerSessionKey === true;
37917
+ const declaresConcurrentFlow = declaresPerRequestConcurrentFlow || protocolRunsConcurrentTurnsPerSessionKey;
37847
37918
  const durableCheckpointIds = durableMappingAtTurn.status === "found" ? durableMappingAtTurn.session.passthroughToolCallIds : undefined;
37848
37919
  const trailingSystemReminderOptions = adapterBase === "claude-code" ? { allowTrailingSystemReminder: true } : undefined;
37849
37920
  const durableCheckpointContinuation = durableCheckpointIds?.length && durableMappingAtTurn.status === "found" && matchesStoredLineagePrefix(durableMappingAtTurn.session, lineageMessages) ? coalesceCompleteToolResultContinuation((body.messages || []).slice(durableMappingAtTurn.session.messageCount), durableCheckpointIds, trailingSystemReminderOptions) : undefined;
@@ -37903,7 +37974,7 @@ data: ${JSON.stringify(lastError)}
37903
37974
  headers: { "Content-Type": "application/json" }
37904
37975
  });
37905
37976
  }
37906
- if (lostRaceWhileWaiting && !declaresPerRequestConcurrentFlow && adapter.runsConcurrentTurnsPerSessionKey === true && lineageResult.type === "undo") {
37977
+ if (lostRaceWhileWaiting && !declaresPerRequestConcurrentFlow && protocolRunsConcurrentTurnsPerSessionKey && lineageResult.type === "undo") {
37907
37978
  lineageResult = { type: "diverged", reason: "concurrent-race" };
37908
37979
  }
37909
37980
  if (options.forceFreshPriorityReplay) {
@@ -38310,6 +38381,7 @@ data: ${JSON.stringify(lastError)}
38310
38381
  name: toolName,
38311
38382
  reason: exceedsForcedSingle ? "forced_single" : "same_tool_repeat"
38312
38383
  });
38384
+ requestAbort.setCause("passthrough_single_step");
38313
38385
  requestAbort.abort("passthrough single-step complete");
38314
38386
  } else {
38315
38387
  capturedSignatures.add(signature);
@@ -38880,7 +38952,8 @@ Subprocess stderr: ${stderrOutput}`;
38880
38952
  requestSource,
38881
38953
  isResume,
38882
38954
  hasDeferredTools,
38883
- sdkSessionId: currentSessionId || resumeSessionId
38955
+ sdkSessionId: currentSessionId || resumeSessionId,
38956
+ abort: requestAbort.abortSnapshot()
38884
38957
  })} captured=${capturedToolUses.length}`, requestMeta.requestId);
38885
38958
  claudeLog("passthrough.max_turns_recovered", {
38886
38959
  mode: "non_stream",
@@ -39165,11 +39238,14 @@ Subprocess stderr: ${stderrOutput}`;
39165
39238
  let nextPassthroughToolCallAssistantUuid;
39166
39239
  let nextPassthroughToolCallIds;
39167
39240
  let sawCanonicalResult = false;
39241
+ const uncapturedToolRecoveryEnabled = env("PASSTHROUGH_UNCAPTURED_TOOL_RECOVERY") === "1";
39242
+ const streamedToolBlockRecords = new Map;
39168
39243
  const silentTurnRecoveryEnabled = env("SILENT_TURN_RECOVERY") !== "0";
39169
39244
  let silentTurnRecoveryAttempted = false;
39170
39245
  let silentTurnRecovered = false;
39171
39246
  const streamedToolUseIds = new Set;
39172
39247
  let pendingTerminalDelta = null;
39248
+ let lastAttemptMaxTurns;
39173
39249
  let pendingStructuredFrames = [];
39174
39250
  let pendingStructuredTextLength = 0;
39175
39251
  let terminalDeltaSent = false;
@@ -39313,6 +39389,7 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
39313
39389
  advisorModel
39314
39390
  }, requestAbort.controller);
39315
39391
  attemptMaxTurns = attemptQuery.options.maxTurns;
39392
+ lastAttemptMaxTurns = attemptMaxTurns;
39316
39393
  for await (const event of runSdkQueryAttempt(attemptQuery, requestAbort.controller.signal, requestMeta, "stream", managedSdkAttemptLocators())) {
39317
39394
  if (event.type === "rate_limit_event") {
39318
39395
  rateLimitStore.record(profile.id, event.rate_limit_info);
@@ -39760,6 +39837,9 @@ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
39760
39837
  if (eventType === "content_block_stop") {
39761
39838
  flushToolArguments(clientIdx);
39762
39839
  passthroughToolBlockNames.delete(eventIndex);
39840
+ const record3 = streamedToolBlockRecords.get(clientIdx);
39841
+ if (record3)
39842
+ record3.naturalStop = true;
39763
39843
  }
39764
39844
  }
39765
39845
  if (eventType === "content_block_delta" && event.delta?.type === "text_delta" && shouldInjectSilentTurn({
@@ -39793,6 +39873,34 @@ data: ${JSON.stringify(event)}
39793
39873
  if (typeof idx === "number")
39794
39874
  openClientBlocks.delete(idx);
39795
39875
  }
39876
+ if (passthrough && uncapturedToolRecoveryEnabled) {
39877
+ const clientIdx = eventIndex !== undefined ? sdkToClientIndex.get(eventIndex) ?? eventIndex : undefined;
39878
+ if (clientIdx !== undefined) {
39879
+ if (eventType === "content_block_start") {
39880
+ const block = event.content_block;
39881
+ if (block?.type === "tool_use" && typeof block?.id === "string" && block.id) {
39882
+ streamedToolBlockRecords.set(clientIdx, {
39883
+ id: block.id,
39884
+ name: block.name,
39885
+ json: "",
39886
+ startedInputObject: block.input !== undefined && block.input !== null,
39887
+ forwardedStart: true,
39888
+ naturalStop: false
39889
+ });
39890
+ }
39891
+ } else if (eventType === "content_block_delta") {
39892
+ const delta = event.delta;
39893
+ const record3 = streamedToolBlockRecords.get(clientIdx);
39894
+ if (record3 && delta?.type === "input_json_delta" && typeof delta.partial_json === "string") {
39895
+ record3.json += delta.partial_json;
39896
+ }
39897
+ } else if (eventType === "content_block_stop") {
39898
+ const record3 = streamedToolBlockRecords.get(clientIdx);
39899
+ if (record3)
39900
+ record3.naturalStop = true;
39901
+ }
39902
+ }
39903
+ }
39796
39904
  if (passthrough && eventType === "message_delta" && event.delta?.stop_reason === "tool_use" && streamedToolUseIds.size > 0) {
39797
39905
  flushOpenClientBlocks("drain_close");
39798
39906
  if (earlyStopEnabled) {
@@ -40469,8 +40577,40 @@ Subprocess stderr: ${stderrOutput}`;
40469
40577
  capturedToolUses: capturedToolUses.length,
40470
40578
  abortIsOurs: sawDuplicateToolUse
40471
40579
  }) && messageStartEmitted;
40580
+ const uncapturedEligible = (() => {
40581
+ if (!canRecoverUncapturedToolUses({
40582
+ reason: sdkTerm.reason,
40583
+ passthrough,
40584
+ capturedToolUses: capturedToolUses.length,
40585
+ streamedToolUses: streamedToolUseIds.size,
40586
+ droppedToolUseIds: droppedToolUseIds.size,
40587
+ sawDuplicateToolUse,
40588
+ forceSingleToolUse,
40589
+ earlyStopFired,
40590
+ uncapturedRecoveryEnabled: uncapturedToolRecoveryEnabled,
40591
+ attemptedMaxTurns: lastAttemptMaxTurns
40592
+ }))
40593
+ return false;
40594
+ if (!messageStartEmitted || streamClosed || pendingTerminalDelta)
40595
+ return false;
40596
+ if (durableWritesRevoked)
40597
+ return false;
40598
+ if (requestAbort.abortSnapshot().aborted)
40599
+ return false;
40600
+ for (const record3 of streamedToolBlockRecords.values()) {
40601
+ if (!isStreamedToolBlockComplete(record3))
40602
+ return false;
40603
+ const declared = requestTools.some((t) => t.name === record3.name);
40604
+ if (!declared)
40605
+ return false;
40606
+ }
40607
+ if (streamedToolBlockRecords.size !== streamedToolUseIds.size)
40608
+ return false;
40609
+ return true;
40610
+ })();
40611
+ const uncapturedRecoveryActive = uncapturedEligible;
40472
40612
  const recoverableCheckpoint = canRecoverAsToolUse && sdkTerm.reason === "max_turns" && Boolean(currentSessionId) && Boolean(nextPassthroughToolCallAssistantUuid) && Boolean(nextPassthroughToolCallIds?.length) && earlyStopFired && !isIndependentSession && !sawDuplicateToolUse;
40473
- const mustEvictBeforeRecoveredTerminal = !isIndependentSession && canRecoverAsToolUse && !recoverableCheckpoint;
40613
+ const mustEvictBeforeRecoveredTerminal = !isIndependentSession && canRecoverAsToolUse && !recoverableCheckpoint || !isIndependentSession && uncapturedRecoveryActive && !recoverableCheckpoint;
40474
40614
  if (mustEvictBeforeRecoveredTerminal || !isIndependentSession && passthrough && streamedToolUseIds.size > 0 && !sawCanonicalResult && !recoverableCheckpoint) {
40475
40615
  const evicted = evictSession2(profileSessionId, profileScopedCwd, lineageMessages, mappingExpectedGeneration);
40476
40616
  if (mustEvictBeforeRecoveredTerminal && !evicted) {
@@ -40478,15 +40618,16 @@ Subprocess stderr: ${stderrOutput}`;
40478
40618
  }
40479
40619
  claudeLog("passthrough.noncanonical_session_evicted", { mode: "stream", reason: "drain_error" });
40480
40620
  }
40481
- if (canRecoverAsToolUse) {
40621
+ if (canRecoverAsToolUse || uncapturedRecoveryActive) {
40482
40622
  idleStalls.clear(idleStallSessionKey);
40483
- diagnosticLog2.session(`${requestMeta.requestId} sdk_termination_recovered ${formatSdkTermination(sdkTerm, {
40623
+ diagnosticLog2.session(`${requestMeta.requestId} sdk_termination_recovered${uncapturedRecoveryActive ? "_uncaptured" : ""} ${formatSdkTermination(sdkTerm, {
40484
40624
  model,
40485
40625
  requestSource,
40486
40626
  isResume,
40487
40627
  hasDeferredTools,
40488
- sdkSessionId: currentSessionId || resumeSessionId
40489
- })} captured=${capturedToolUses.length}`, requestMeta.requestId);
40628
+ sdkSessionId: currentSessionId || resumeSessionId,
40629
+ abort: requestAbort.abortSnapshot()
40630
+ })} captured=${capturedToolUses.length}${uncapturedRecoveryActive ? ` completed=${streamedToolBlockRecords.size}` : ""}`, requestMeta.requestId);
40490
40631
  flushOpenClientBlocks("recovery");
40491
40632
  const unseenToolUses = capturedToolUses.filter((tu) => !streamedToolUseIds.has(tu.id));
40492
40633
  for (let i = 0;i < unseenToolUses.length; i++) {
@@ -40627,7 +40768,8 @@ data: {"type":"message_stop"}
40627
40768
  requestSource,
40628
40769
  isResume,
40629
40770
  hasDeferredTools,
40630
- sdkSessionId: currentSessionId || resumeSessionId
40771
+ sdkSessionId: currentSessionId || resumeSessionId,
40772
+ abort: requestAbort.abortSnapshot()
40631
40773
  })} blocks=${nextClientBlockIndex}`, requestMeta.requestId);
40632
40774
  claudeLog("passthrough.capped_turn_truncated", {
40633
40775
  mode: "stream",
@@ -40700,7 +40842,8 @@ data: {"type":"message_stop"}
40700
40842
  requestSource,
40701
40843
  isResume,
40702
40844
  hasDeferredTools,
40703
- sdkSessionId: currentSessionId || resumeSessionId
40845
+ sdkSessionId: currentSessionId || resumeSessionId,
40846
+ abort: requestAbort.abortSnapshot()
40704
40847
  })} envelope=${messageStartEmitted ? "open" : "unopened"} blocks=${contentBlocksForwarded} ` + `text=${textEventsForwarded} tools=${capturedToolUses.length}/${streamedToolUseIds.size}`, requestMeta.requestId);
40705
40848
  const streamErrTotalMs = Date.now() - requestStartAt;
40706
40849
  const streamErrQueueWaitMs = totalQueueWaitMs(requestMeta);
@@ -40780,15 +40923,18 @@ data: ${JSON.stringify({
40780
40923
  await abandonManagedFork("stream_complete_without_commit");
40781
40924
  if (priorityRollbackRetirement)
40782
40925
  await priorityRollbackRetirement;
40783
- requestAbort.detach();
40926
+ if (!streamOwnsAbortLink)
40927
+ requestAbort.detach();
40784
40928
  }
40785
40929
  })().finally(() => {
40786
40930
  resolveStreamCompletion();
40787
40931
  });
40788
40932
  },
40789
40933
  cancel(reason) {
40934
+ requestAbort.setCause("stream_cancel");
40790
40935
  requestAbort.abort(reason);
40791
- requestAbort.detach();
40936
+ if (!streamOwnsAbortLink)
40937
+ requestAbort.detach();
40792
40938
  requestMeta.cascadeSubtreeCancel?.("stream_cancel");
40793
40939
  if (!isIndependentSession && (!managedForkTarget || managedForkPublished || clientAssistantContentExposed)) {
40794
40940
  evictSession2(profileSessionId, profileScopedCwd, lineageMessages, mappingExpectedGeneration);
@@ -40821,7 +40967,8 @@ data: ${JSON.stringify({
40821
40967
  claudeLog("proxy.error", { error: errMsg, classified: classified.type });
40822
40968
  const sdkTerm = extractSdkTermination(errMsg);
40823
40969
  diagnosticLog2.error(`${requestMeta.requestId} ${formatSdkTermination(sdkTerm, {
40824
- requestSource: c.req.header("x-meridian-source")?.slice(0, 64) || undefined
40970
+ requestSource: c.req.header("x-meridian-source")?.slice(0, 64) || undefined,
40971
+ abort: requestAbort.abortSnapshot()
40825
40972
  })}`, requestMeta.requestId);
40826
40973
  const errorQueueWaitMs = totalQueueWaitMs(requestMeta);
40827
40974
  const errorTotalMs = Date.now() - requestStartAt;
@@ -40908,6 +41055,14 @@ data: ${JSON.stringify({
40908
41055
  };
40909
41056
  const turnWatchdogAbort = new AbortController;
40910
41057
  activeRequestAborts.add(turnWatchdogAbort);
41058
+ const requestSignalForLink = AbortSignal.any([c.req.raw.signal, turnWatchdogAbort.signal]);
41059
+ const labelClientAbort = () => {
41060
+ if (!turnWatchdogAbort.signal.aborted)
41061
+ requestAbortLink?.setCause("client_abort");
41062
+ };
41063
+ c.req.raw.signal.addEventListener("abort", labelClientAbort, { once: true });
41064
+ const requestAbortLink = linkRequestAbort(requestSignalForLink);
41065
+ activeShutdownLabels.set(turnWatchdogAbort, () => requestAbortLink.setCause("process_shutdown"));
40911
41066
  let finished = false;
40912
41067
  let leaseReleased = false;
40913
41068
  let retainSessionTurnFence = false;
@@ -40936,6 +41091,8 @@ data: ${JSON.stringify({
40936
41091
  if (finished)
40937
41092
  return;
40938
41093
  finished = true;
41094
+ requestAbortLink.detach();
41095
+ c.req.raw.signal.removeEventListener("abort", labelClientAbort);
40939
41096
  if (retainSessionTurnFence && (sessionTurnLease || crossProcessTurnLease)) {
40940
41097
  leaseReleased = true;
40941
41098
  if (leaseWatchdog)
@@ -40950,6 +41107,7 @@ data: ${JSON.stringify({
40950
41107
  sessionTreeRegistration?.release();
40951
41108
  sessionTreeRegistration = undefined;
40952
41109
  activeRequestAborts.delete(turnWatchdogAbort);
41110
+ activeShutdownLabels.delete(turnWatchdogAbort);
40953
41111
  inFlightRequests--;
40954
41112
  };
40955
41113
  let body;
@@ -40981,7 +41139,10 @@ data: ${JSON.stringify({
40981
41139
  requestId,
40982
41140
  sessionKey: agentSessionId,
40983
41141
  parentKey: adapter.getParentSessionId?.(c, body),
40984
- abort: (reason) => turnWatchdogAbort.abort(reason)
41142
+ abort: (reason) => {
41143
+ requestAbortLink.setCause("subtree_cancel");
41144
+ turnWatchdogAbort.abort(reason);
41145
+ }
40985
41146
  });
40986
41147
  subtreeSessionKey = agentSessionId;
40987
41148
  const clientSignal = c.req.raw.signal;
@@ -41002,6 +41163,7 @@ data: ${JSON.stringify({
41002
41163
  leaseWatchdog = setTimeout(() => {
41003
41164
  claudeLog("session.turn_watchdog_abort", { requestId, heldMs: SESSION_TURN_MAX_HOLD_MS });
41004
41165
  plog(`[PROXY] ${requestId} session turn exceeded ${SESSION_TURN_MAX_HOLD_MS}ms — aborting without releasing its fencing lease`);
41166
+ requestAbortLink.setCause("session_watchdog");
41005
41167
  turnWatchdogAbort.abort(new Error("Session turn exceeded its maximum hold time"));
41006
41168
  }, SESSION_TURN_MAX_HOLD_MS);
41007
41169
  leaseWatchdog.unref?.();
@@ -41076,7 +41238,8 @@ data: ${JSON.stringify({
41076
41238
  };
41077
41239
  const response = await handleMessages(c, requestMeta, {
41078
41240
  body,
41079
- turnWatchdogSignal: turnWatchdogAbort.signal
41241
+ turnWatchdogSignal: turnWatchdogAbort.signal,
41242
+ requestAbortLink
41080
41243
  });
41081
41244
  const completion = responseCompletions.get(response);
41082
41245
  if (completion) {
@@ -41901,6 +42064,8 @@ data: ${JSON.stringify({ response: { id: responseId, status: "failed", error: {
41901
42064
  },
41902
42065
  forceAbortInFlight: () => {
41903
42066
  durableWritesRevoked = true;
42067
+ for (const label of activeShutdownLabels.values())
42068
+ label();
41904
42069
  for (const controller of activeRequestAborts) {
41905
42070
  controller.abort(new Error("Proxy shutdown grace period elapsed"));
41906
42071
  }
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxyServer
4
- } from "./cli-198xnjcn.js";
4
+ } from "./cli-ryt69ryf.js";
5
5
  import"./cli-5jxyma6z.js";
6
6
  import"./cli-sry5aqdj.js";
7
7
  import"./cli-8yp89fan.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./cli-9e5cxp89.js";
11
11
  import"./cli-khhjyk04.js";
12
12
  import"./cli-vj9cv18n.js";
13
- import"./cli-zdbv40d5.js";
13
+ import"./cli-hxxy0m1z.js";
14
14
  import {
15
15
  __require
16
16
  } from "./cli-p9swy5t3.js";
@@ -93,7 +93,7 @@ if (args[0] === "setup") {
93
93
  runSetup,
94
94
  SUPPORTED_OPENCODE_V2_VERSIONS,
95
95
  UnparseableConfigError
96
- } = await import("./setup-b3ymd9z8.js");
96
+ } = await import("./setup-ndmjpy23.js");
97
97
  const forceV1 = args.includes("--v1");
98
98
  const forceV2 = args.includes("--v2");
99
99
  if (forceV1 && forceV2) {
@@ -205,7 +205,7 @@ async function runCli(start = startProxyServer, runAuthCheck = async () => {
205
205
  return execFile(claudePath, ["auth", "status"], { timeout: 5000 });
206
206
  }) {
207
207
  try {
208
- const { findOpencodeConfigPath, checkPluginConfigured, findPluginPath } = await import("./setup-b3ymd9z8.js");
208
+ const { findOpencodeConfigPath, checkPluginConfigured, findPluginPath } = await import("./setup-ndmjpy23.js");
209
209
  const configPath = findOpencodeConfigPath();
210
210
  const { existsSync } = await import("fs");
211
211
  if (existsSync(configPath) && !checkPluginConfigured(configPath)) {
@@ -13,9 +13,12 @@ var MAX_HEADER_BYTES = 768;
13
13
  var MAX_PAYLOAD_BYTES = 384;
14
14
  var TURN_DIGEST_PATTERN = /^[A-Za-z0-9_-]{43}$/;
15
15
  var SAFE_ID_PATTERN = /^[A-Za-z0-9._:-]{1,128}$/;
16
- function configDirectory() {
16
+ function meridianConfigDirectory() {
17
17
  return process.env.MERIDIAN_CONFIG_DIR ?? join(homedir(), ".config", "meridian");
18
18
  }
19
+ function configDirectory() {
20
+ return meridianConfigDirectory();
21
+ }
19
22
  function priorityAttestationKeyPath() {
20
23
  return join(configDirectory(), PRIORITY_ATTESTATION_KEY_FILE);
21
24
  }