@rynfar/meridian 1.58.0 → 1.58.2

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.
@@ -4366,6 +4366,13 @@ import { join as join8 } from "node:path";
4366
4366
  import { query } from "@anthropic-ai/claude-agent-sdk";
4367
4367
 
4368
4368
  // src/proxy/rateLimitStore.ts
4369
+ var MIN_EPOCH_MS = 100000000000;
4370
+ function toEpochMs(value) {
4371
+ if (typeof value !== "number" || !Number.isFinite(value) || value <= 0)
4372
+ return;
4373
+ return value < MIN_EPOCH_MS ? Math.round(value * 1000) : value;
4374
+ }
4375
+
4369
4376
  class RateLimitStore {
4370
4377
  byProfile = new Map;
4371
4378
  record(profileId, info, observedAt = Date.now()) {
@@ -4377,7 +4384,12 @@ class RateLimitStore {
4377
4384
  buckets = new Map;
4378
4385
  this.byProfile.set(profileId, buckets);
4379
4386
  }
4380
- buckets.set(key, { ...info, observedAt });
4387
+ buckets.set(key, {
4388
+ ...info,
4389
+ resetsAt: toEpochMs(info.resetsAt),
4390
+ overageResetsAt: toEpochMs(info.overageResetsAt),
4391
+ observedAt
4392
+ });
4381
4393
  }
4382
4394
  getAll(profileId) {
4383
4395
  const buckets = this.byProfile.get(profileId);
@@ -10218,7 +10230,22 @@ var telemetryStore2 = stores.telemetry;
10218
10230
  var diagnosticLog2 = stores.diagnostics;
10219
10231
 
10220
10232
  // src/proxy/errors.ts
10221
- function classifyError(errMsg) {
10233
+ function extendedContextHint(model) {
10234
+ const advise = (v) => ` If you're frequently hitting this, set ${v} to use the 200k model instead.`;
10235
+ if (!model)
10236
+ return advise("MERIDIAN_1M_CONTEXT_SUPPORT=0");
10237
+ const lower = model.toLowerCase();
10238
+ if (!lower.includes("[1m]"))
10239
+ return "";
10240
+ if (lower.includes("fable") || lower.includes("mythos"))
10241
+ return advise("MERIDIAN_FABLE_MODEL=fable");
10242
+ if (lower.includes("opus"))
10243
+ return advise("MERIDIAN_OPUS_MODEL=opus");
10244
+ if (lower.includes("sonnet"))
10245
+ return advise("MERIDIAN_SONNET_MODEL=sonnet");
10246
+ return advise("MERIDIAN_1M_CONTEXT_SUPPORT=0");
10247
+ }
10248
+ function classifyError(errMsg, model) {
10222
10249
  const lower = errMsg.toLowerCase();
10223
10250
  if (lower.includes("oauth token has expired") || lower.includes("not logged in")) {
10224
10251
  return {
@@ -10235,7 +10262,7 @@ function classifyError(errMsg) {
10235
10262
  };
10236
10263
  }
10237
10264
  if (lower.includes("429") || lower.includes("rate limit") || lower.includes("too many requests") || lower.includes("hit your session limit") || lower.includes("usage limit reached")) {
10238
- const hint = lower.includes("1m") || lower.includes("context") ? " If you're frequently hitting this, set MERIDIAN_SONNET_MODEL=sonnet to use the 200k model instead." : "";
10265
+ const hint = lower.includes("1m") || lower.includes("context") ? extendedContextHint(model) : "";
10239
10266
  return {
10240
10267
  status: 429,
10241
10268
  type: "rate_limit_error",
@@ -11484,11 +11511,26 @@ function stripCacheControlForHashing(obj) {
11484
11511
  const { cache_control, ...rest } = obj;
11485
11512
  return rest;
11486
11513
  }
11514
+ var HASH_IGNORED_BLOCK_TYPES = new Set(["thinking", "redacted_thinking"]);
11515
+ var HASH_HANDLED_BLOCK_TYPES = new Set(["text", "tool_use", "tool_result"]);
11516
+ var HASH_SERIALIZED_BLOCK_TYPES = new Set([
11517
+ "image",
11518
+ "document",
11519
+ "search_result",
11520
+ "server_tool_use",
11521
+ "web_search_tool_result",
11522
+ "web_fetch_tool_result",
11523
+ "code_execution_tool_result",
11524
+ "bash_code_execution_tool_result",
11525
+ "text_editor_code_execution_tool_result",
11526
+ "tool_search_tool_result",
11527
+ "container_upload"
11528
+ ]);
11487
11529
  function normalizeContent(content) {
11488
11530
  if (typeof content === "string")
11489
11531
  return content;
11490
11532
  if (Array.isArray(content)) {
11491
- return content.map((block) => {
11533
+ return content.filter((block) => !HASH_IGNORED_BLOCK_TYPES.has(block?.type)).map((block) => {
11492
11534
  if (block.type === "text" && block.text)
11493
11535
  return block.text;
11494
11536
  if (block.type === "tool_use")
@@ -12195,8 +12237,8 @@ var CRUSH_ALLOWED_MCP_TOOLS2 = [
12195
12237
  ];
12196
12238
  var crushAdapter = {
12197
12239
  name: "crush",
12198
- getSessionId(_c) {
12199
- return;
12240
+ getSessionId(c) {
12241
+ return c.req.header("x-session-id") ?? c.req.header("x-session-affinity");
12200
12242
  },
12201
12243
  extractWorkingDirectory(_body) {
12202
12244
  return;
@@ -12865,7 +12907,7 @@ function detectAdapter(c) {
12865
12907
  }
12866
12908
  }
12867
12909
  }
12868
- if (c.req.header("x-opencode-session") || c.req.header("x-session-affinity")) {
12910
+ if (c.req.header("x-opencode-session")) {
12869
12911
  return openCodeAdapter;
12870
12912
  }
12871
12913
  const userAgent = c.req.header("user-agent") || "";
@@ -12878,6 +12920,9 @@ function detectAdapter(c) {
12878
12920
  if (userAgent.startsWith("Charm-Crush/")) {
12879
12921
  return crushAdapter;
12880
12922
  }
12923
+ if (c.req.header("x-session-affinity")) {
12924
+ return openCodeAdapter;
12925
+ }
12881
12926
  if (userAgent.startsWith("claude-cli/")) {
12882
12927
  const claudeCliOverride = (process.env.MERIDIAN_DEFAULT_AGENT || "").toLowerCase();
12883
12928
  if (claudeCliOverride && ADAPTER_MAP[claudeCliOverride] && claudeCliOverride !== "claude-code" && claudeCliOverride !== "claudecode") {
@@ -18624,15 +18669,21 @@ function buildCwdNote(sdkCwd, clientCwd) {
18624
18669
  ` + `You are reached through a proxy. The subprocess running you resides at ` + `"${sdkCwd}" on the proxy host, but that is not the user's working directory. ` + `Always treat "${clientCwd}" as the working directory when referring to files or paths.
18625
18670
  ` + `</meridian-note>`;
18626
18671
  }
18672
+ var GIT_STATUS_PROVENANCE_NOTE = `
18673
+
18674
+ <meridian-note>
18675
+ ` + `You are reached through a proxy that issues a separate request per turn, so ` + `the \`gitStatus\` block in your system prompt is recomputed at the start of ` + `every turn — despite its claim to describe "the start of the conversation". ` + `Read it as the working tree as of this turn and nothing more. It is not ` + `evidence that a file predates the conversation: files you yourself created or ` + `edited in earlier turns appear in it exactly like pre-existing changes. To ` + `judge whether something predates the conversation, rely on the conversation ` + `history and your own prior tool calls, and run \`git status\` when you need ` + `the current tree.
18676
+ ` + `</meridian-note>`;
18627
18677
  function resolveSystemPrompt(systemContext, passthrough, settingSources, codeSystemPrompt, clientSystemPrompt, cwdNote) {
18628
18678
  const hasSettings = settingSources != null && settingSources.length > 0;
18629
18679
  const usePreset = codeSystemPrompt ?? (hasSettings || !passthrough && !!systemContext);
18630
18680
  const includeClient = clientSystemPrompt ?? true;
18631
18681
  const clientContext = includeClient ? systemContext : undefined;
18632
- const append = [clientContext, cwdNote].filter(Boolean).join("") || undefined;
18633
18682
  if (usePreset) {
18634
- return append ? { systemPrompt: { type: "preset", preset: "claude_code", append } } : { systemPrompt: { type: "preset", preset: "claude_code" } };
18683
+ const append2 = [clientContext, cwdNote, GIT_STATUS_PROVENANCE_NOTE].filter(Boolean).join("");
18684
+ return { systemPrompt: { type: "preset", preset: "claude_code", append: append2 } };
18635
18685
  }
18686
+ const append = [clientContext, cwdNote].filter(Boolean).join("") || undefined;
18636
18687
  if (append)
18637
18688
  return { systemPrompt: append };
18638
18689
  if (codeSystemPrompt === false)
@@ -19118,11 +19169,16 @@ var ORCHESTRATION_TAGS = [
19118
19169
  "skill_content",
19119
19170
  "skill_files",
19120
19171
  "directories",
19121
- "available_skills",
19122
- "thinking"
19172
+ "available_skills"
19123
19173
  ];
19124
- var PAIRED_TAG_PATTERNS = ORCHESTRATION_TAGS.map((tag) => new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi"));
19125
- var SELF_CLOSING_TAG_PATTERNS = ORCHESTRATION_TAGS.map((tag) => new RegExp(`<${tag}\\b[^>]*\\/>`, "gi"));
19174
+ function tagPatterns(tag) {
19175
+ return [
19176
+ new RegExp(`<${tag}\\b[^>]*>[\\s\\S]*?<\\/${tag}>`, "gi"),
19177
+ new RegExp(`<${tag}\\b[^>]*\\/>`, "gi")
19178
+ ];
19179
+ }
19180
+ var PAIRED_TAG_PATTERNS = ORCHESTRATION_TAGS.map((tag) => tagPatterns(tag)[0]);
19181
+ var SELF_CLOSING_TAG_PATTERNS = ORCHESTRATION_TAGS.map((tag) => tagPatterns(tag)[1]);
19126
19182
  var NON_XML_PATTERNS = [
19127
19183
  /<!--\s*OMO_INTERNAL_INITIATOR\s*-->/gi,
19128
19184
  /\[SYSTEM DIRECTIVE: OH-MY-OPENCODE[^\]]*\]/gi,
@@ -19134,13 +19190,15 @@ var ALL_PATTERNS = [
19134
19190
  ...SELF_CLOSING_TAG_PATTERNS,
19135
19191
  ...NON_XML_PATTERNS
19136
19192
  ];
19137
- var SYSTEM_REMINDER_PATTERNS = [
19138
- /<system-reminder\b[^>]*>[\s\S]*?<\/system-reminder>/gi,
19139
- /<system-reminder\b[^>]*\/>/gi
19140
- ];
19193
+ var SYSTEM_REMINDER_PATTERNS = tagPatterns("system-reminder");
19194
+ var THINKING_TAG_PATTERNS = tagPatterns("thinking");
19141
19195
  function sanitizeTextContent(text, opts = {}) {
19142
19196
  let result = text;
19143
- const patterns = opts.stripSystemReminder ? [...ALL_PATTERNS, ...SYSTEM_REMINDER_PATTERNS] : ALL_PATTERNS;
19197
+ const patterns = [...ALL_PATTERNS];
19198
+ if (opts.stripSystemReminder)
19199
+ patterns.push(...SYSTEM_REMINDER_PATTERNS);
19200
+ if (opts.stripThinking)
19201
+ patterns.push(...THINKING_TAG_PATTERNS);
19144
19202
  for (const pattern of patterns) {
19145
19203
  pattern.lastIndex = 0;
19146
19204
  result = result.replace(pattern, "");
@@ -19965,6 +20023,8 @@ function createProxyServer(config = {}) {
19965
20023
  }
19966
20024
  function refinePriorityCooldown(profileId) {
19967
20025
  const target = getEffectiveProfiles(finalConfig.profiles).find((p) => p.id === profileId);
20026
+ if ((target?.type ?? "claude-max") !== "claude-max")
20027
+ return;
19968
20028
  fetchOAuthUsage({ profileId, claudeConfigDir: target?.claudeConfigDir, force: true }).then((usage) => {
19969
20029
  if (!usage || usage.stale)
19970
20030
  return;
@@ -20328,7 +20388,8 @@ data: ${JSON.stringify(lastError)}
20328
20388
  }
20329
20389
  systemContext = pipelineCtx.systemContext ?? systemContext;
20330
20390
  const sanitizeOpts = {
20331
- stripSystemReminder: pipelineCtx.leaksCwdViaSystemReminder
20391
+ stripSystemReminder: pipelineCtx.leaksCwdViaSystemReminder,
20392
+ stripThinking: env("STRIP_THINKING") === "1"
20332
20393
  };
20333
20394
  const allMessages = body.messages || [];
20334
20395
  let messagesToConvert;
@@ -21937,7 +21998,7 @@ Subprocess stderr: ${stderrOutput}`;
21937
21998
  status: 504,
21938
21999
  type: "upstream_timeout",
21939
22000
  message: `Upstream stalled: no data for ${error.sinceLastMs}ms`
21940
- } : classifyError(errMsg);
22001
+ } : classifyError(errMsg, model);
21941
22002
  claudeLog("proxy.anthropic.error", { error: errMsg, classified: streamErr.type });
21942
22003
  const sdkTerm = extractSdkTermination(errMsg);
21943
22004
  const canRecoverAsToolUse = (sdkTerm.reason === "max_turns" || sdkTerm.reason === "aborted" && (sawDuplicateToolUse || earlyStopFired)) && passthrough && capturedToolUses.length > 0 && messageStartEmitted;
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxyServer
4
- } from "./cli-5rkcyzzm.js";
4
+ } from "./cli-jwm61pg9.js";
5
5
  import"./cli-h6hfkg3s.js";
6
6
  import"./cli-sry5aqdj.js";
7
7
  import"./cli-xmweegb1.js";
@@ -1 +1 @@
1
- {"version":3,"file":"crush.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/crush.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAgB9C,eAAO,MAAM,YAAY,EAAE,YAyF1B,CAAA;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,CAAA"}
1
+ {"version":3,"file":"crush.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/crush.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAgB9C,eAAO,MAAM,YAAY,EAAE,YAiG1B,CAAA;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA0F9C,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,YAAY,CAsEtD"}
1
+ {"version":3,"file":"detect.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/detect.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA0F9C,wBAAgB,aAAa,CAAC,CAAC,EAAE,OAAO,GAAG,YAAY,CAkFtD"}
@@ -7,10 +7,32 @@ export interface ClassifiedError {
7
7
  type: string;
8
8
  message: string;
9
9
  }
10
+ /**
11
+ * Remediation advice for a rate limit hit on an extended-context request.
12
+ *
13
+ * `model` is the resolved variant (`opus[1m]`, `fable`, `sonnet`, …). The advice
14
+ * has to name the tier that actually failed: the three per-tier variables have
15
+ * opposite polarity, because Sonnet 1M costs Extra Usage on every plan while
16
+ * Fable and Opus 1M are included on Max/Team (#717). So Sonnet opts *in* to 1M
17
+ * and the other two opt *out* of it.
18
+ *
19
+ * Returns "" rather than guessing when there is nothing useful to say:
20
+ *
21
+ * - The request did not use extended context. Suggesting a 1M variable is
22
+ * irrelevant, and for Sonnet — which is 200k by default — the old advice
23
+ * was a literal no-op: the user set the variable to the value it already
24
+ * had, saw no change, and reasonably concluded Meridian was broken (#716).
25
+ * - The tier is unrecognized, where the global switch is the only safe advice.
26
+ */
27
+ export declare function extendedContextHint(model?: string): string;
10
28
  /**
11
29
  * Detect specific SDK errors and return helpful messages to the client.
30
+ *
31
+ * `model` is the resolved variant for this request, used only to target the
32
+ * extended-context remediation hint. Optional because the outer error handler
33
+ * may not have assigned it yet when a request fails early.
12
34
  */
13
- export declare function classifyError(errMsg: string): ClassifiedError;
35
+ export declare function classifyError(errMsg: string, model?: string): ClassifiedError;
14
36
  /**
15
37
  * Detect errors caused by an expired or missing OAuth access token.
16
38
  * Triggers an inline token refresh + retry in server.ts.
@@ -1 +1 @@
1
- {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAoH7D;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,SAAS,CAAA;IAC5D,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAuCpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
1
+ {"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/proxy/errors.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,OAAO,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAc1D;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,eAAe,CAoH7E;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAM3D;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAO3D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAI3E;AAED;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAGjE;AAED;;;;;GAKG;AACH,MAAM,WAAW,cAAc;IAC7B,MAAM,EAAE,WAAW,GAAG,cAAc,GAAG,SAAS,GAAG,SAAS,CAAA;IAC5D,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,wDAAwD;IACxD,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,wDAAwD;IACxD,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB;;wCAEoC;IACpC,OAAO,CAAC,EAAE,MAAM,CAAA;CACjB;AAuBD;;;;;;GAMG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAuCpE;AAED;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAClC,CAAC,EAAE,cAAc,EACjB,GAAG,EAAE;IACH,KAAK,CAAC,EAAE,MAAM,CAAA;IACd,aAAa,CAAC,EAAE,MAAM,CAAA;IACtB,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAA;CACtB,GACA,MAAM,CAYR"}
@@ -1,11 +1,59 @@
1
1
  /**
2
2
  * Message parsing and normalization utilities.
3
3
  */
4
+ /**
5
+ * Content block types that contribute nothing to the lineage hash.
6
+ *
7
+ * Thinking blocks are model-emitted reasoning. Their `signature` is an opaque,
8
+ * high-entropy, per-generation blob, and `redacted_thinking` carries only
9
+ * opaque `data` — none of it identifies the conversation prefix, which is the
10
+ * only question the hash exists to answer.
11
+ *
12
+ * They are dropped entirely rather than reduced to their text, because the
13
+ * failure mode is a client that stops echoing thinking blocks once a tool loop
14
+ * finishes — a common pattern, since only the active loop strictly needs them.
15
+ * Hashing `thinking:<text>` would still change that message's hash the moment
16
+ * the block disappears; contributing nothing is what makes the hash stable
17
+ * across its presence, absence, and any re-signature (#710).
18
+ *
19
+ * Deliberate trade-off: two prefixes differing ONLY in thinking now hash alike.
20
+ * That is correct — thinking always accompanies the same text and tool calls in
21
+ * its own turn, and those are still hashed, so it never distinguishes two
22
+ * genuinely different prefixes on its own.
23
+ */
24
+ export declare const HASH_IGNORED_BLOCK_TYPES: Set<string>;
25
+ /**
26
+ * Block types with an explicit case in {@link normalizeContent}, hashed on
27
+ * their semantic fields only.
28
+ */
29
+ export declare const HASH_HANDLED_BLOCK_TYPES: Set<string>;
30
+ /**
31
+ * Block types deliberately serialized whole by the fallback.
32
+ *
33
+ * Reviewed against `ContentBlockParam` and confirmed to carry no
34
+ * per-generation opaque field: their payloads (`source`, `content`, `title`,
35
+ * `file_id`) are stable for the same logical content, so serializing them is
36
+ * safe. `cache_control` is stripped separately.
37
+ *
38
+ * The `*_tool_use` / `*_tool_result` entries reference `id` / `tool_use_id`,
39
+ * which ARE per-generation — but that matches how `tool_use` and `tool_result`
40
+ * are already hashed, and clients echo the same ids back. Same accepted risk,
41
+ * not a new one.
42
+ *
43
+ * Membership here is a decision, not a default. `sdk-block-type-coverage`
44
+ * fails when the installed SDK adds a type absent from all three sets, so a
45
+ * new block type cannot silently land in the fallback the way `thinking` did
46
+ * (#710).
47
+ */
48
+ export declare const HASH_SERIALIZED_BLOCK_TYPES: Set<string>;
4
49
  /**
5
50
  * Normalize message content to a string for hashing and comparison.
6
51
  * Handles both string content and array content (Anthropic content blocks).
7
52
  * Strips cache_control metadata to ensure hash stability across requests.
8
53
  *
54
+ * Used only for lineage hashing — see {@link HASH_IGNORED_BLOCK_TYPES}, which
55
+ * drops content a display-oriented normalizer would need to keep.
56
+ *
9
57
  * NOTE: OpenCode sends content as a string on the first request but as
10
58
  * an array on subsequent ones. This normalizer handles both formats.
11
59
  * Other agents may behave differently — this will move to the adapter pattern.
@@ -1 +1 @@
1
- {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/proxy/messages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,CAiBrD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAM7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC,CAKzH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAerF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAU3D;AAED,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,aAAyC,CAAA;AAEtE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iCAAiC,CAC/C,CAAC,SAAS;IAAE,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,EAC3C,UAAU,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAyCtB;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,8EAA8E;IAC9E,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAyCD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC,GAC9C,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAyB3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAO3D"}
1
+ {"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/proxy/messages.ts"],"names":[],"mappings":"AAAA;;GAEG;AAcH;;;;;;;;;;;;;;;;;;;GAmBG;AACH,eAAO,MAAM,wBAAwB,aAA6C,CAAA;AAElF;;;GAGG;AACH,eAAO,MAAM,wBAAwB,aAA+C,CAAA;AAEpF;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,2BAA2B,aAYtC,CAAA;AAEF;;;;;;;;;;;GAWG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,CAmBrD;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAUtE;AAED;;;GAGG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,OAAO,EAAE,GAAG,OAAO,EAAE,CAM7D;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC,GAAG,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC,CAKzH;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,CAAC,GAAG,MAAM,CAerF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,4BAA4B,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAU3D;AAED,yEAAyE;AACzE,eAAO,MAAM,gBAAgB,aAAyC,CAAA;AAEtE;;;;;;;;;;;;;;;;;;;;;GAqBG;AACH,wBAAgB,iCAAiC,CAC/C,CAAC,SAAS;IAAE,OAAO,EAAE;QAAE,OAAO,EAAE,OAAO,CAAA;KAAE,CAAA;CAAE,EAC3C,UAAU,EAAE,CAAC,EAAE,GAAG,CAAC,EAAE,CAyCtB;AAED,kEAAkE;AAClE,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAA;IACZ,8EAA8E;IAC9E,MAAM,EAAE,MAAM,GAAG,SAAS,CAAA;IAC1B;;;;;;;OAOG;IACH,cAAc,EAAE,MAAM,GAAG,SAAS,CAAA;CACnC;AAyCD;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,GAAG,CAAA;CAAE,CAAC,GAC9C,GAAG,CAAC,MAAM,EAAE,YAAY,CAAC,CAyB3B;AAED;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAO3D"}
@@ -121,5 +121,30 @@ export interface BuildQueryResult {
121
121
  * reports that as its working directory.
122
122
  */
123
123
  export declare function buildCwdNote(sdkCwd: string, clientCwd?: string): string;
124
+ /**
125
+ * Correct the provenance claim on the preset's `gitStatus` block.
126
+ *
127
+ * The `claude_code` preset injects a `gitStatus:` section stating verbatim that
128
+ * it is "the git status at the start of the conversation" and "will not update
129
+ * during the conversation". In the real Claude Code CLI that holds: one
130
+ * long-lived process serves the whole conversation, so the snapshot really is
131
+ * from its start.
132
+ *
133
+ * Meridian breaks that invariant. Every turn is a separate HTTP request and a
134
+ * separate `query()`, so the SDK recomputes the block each time while it keeps
135
+ * asserting it is the conversation's starting state. Files the model created in
136
+ * earlier turns therefore reappear as apparently pre-existing work, and the
137
+ * model concludes it overwrote the user's uncommitted changes — #694, where it
138
+ * reported destroying two work-in-progress files it had written itself.
139
+ *
140
+ * Verified live: a file created by a third party after session start appears in
141
+ * the block under the "start of the conversation" caveat, on a session whose
142
+ * lineage is an unbroken continuation chain. This is not a history-loss bug, so
143
+ * the resume fixes (#705, #719) do not address it.
144
+ *
145
+ * Only meaningful alongside the preset — it is the preset that injects the block
146
+ * being corrected — so it is appended in that branch only.
147
+ */
148
+ export declare const GIT_STATUS_PROVENANCE_NOTE: string;
124
149
  export declare function buildQueryOptions(ctx: QueryContext, abortController?: AbortController): BuildQueryResult;
125
150
  //# sourceMappingURL=query.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../src/proxy/query.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@
9
9
  * type: "rate_limit_event",
10
10
  * rate_limit_info: {
11
11
  * status: "allowed" | "allowed_warning" | "rejected",
12
- * resetsAt?: number, // epoch ms
12
+ * resetsAt?: number, // epoch SECONDS — see toEpochMs
13
13
  * rateLimitType?: "five_hour" | "seven_day"
14
14
  * | "seven_day_opus" | "seven_day_sonnet"
15
15
  * | "overage",
@@ -39,6 +39,22 @@
39
39
  * used by tests.
40
40
  */
41
41
  import type { SDKRateLimitInfo } from "@anthropic-ai/claude-agent-sdk";
42
+ /**
43
+ * Normalize an SDK reset timestamp to epoch milliseconds.
44
+ *
45
+ * The SDK reports these in epoch SECONDS while everything downstream —
46
+ * `Date.now()` comparisons in the priority-cooldown chain, the documented
47
+ * `/v1/usage/quota` contract, and consumers like the telemetry badge and Pylon
48
+ * — is epoch milliseconds. Proven by observing one profile's `five_hour` reset
49
+ * from both sources minutes apart: OAuth reported `1785234600292` and the SDK
50
+ * reported `1785234600` for the same instant (#708).
51
+ *
52
+ * Detects the unit rather than multiplying unconditionally, because
53
+ * `SDKRateLimitInfo.resetsAt` is typed `number` with no documented unit. An
54
+ * unconditional `* 1000` would silently corrupt every value if the SDK ever
55
+ * switched to milliseconds; this stays correct under either.
56
+ */
57
+ export declare function toEpochMs(value: number | undefined): number | undefined;
42
58
  export interface RateLimitEntry extends SDKRateLimitInfo {
43
59
  /** When this entry was captured (epoch ms). */
44
60
  observedAt: number;
@@ -1 +1 @@
1
- {"version":3,"file":"rateLimitStore.d.ts","sourceRoot":"","sources":["../../src/proxy/rateLimitStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAEtE,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,qDAAqD;AACrD,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,GAAG,SAAS,CAAA;AAE3F,cAAM,cAAc;IAClB,gFAAgF;IAChF,OAAO,CAAC,SAAS,CAA6D;IAE9E;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,EAAE,UAAU,GAAE,MAAmB,GAAG,IAAI;IAW3G,kEAAkE;IAClE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE;IAM3C,8EAA8E;IAC9E,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS;IAI3E,yEAAyE;IACzE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAOhC;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;CAIhC;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAA;AAElD,wCAAwC;AACxC,OAAO,EAAE,cAAc,IAAI,uBAAuB,EAAE,CAAA"}
1
+ {"version":3,"file":"rateLimitStore.d.ts","sourceRoot":"","sources":["../../src/proxy/rateLimitStore.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAuCG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,gCAAgC,CAAA;AAYtE;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAGvE;AAED,MAAM,WAAW,cAAe,SAAQ,gBAAgB;IACtD,+CAA+C;IAC/C,UAAU,EAAE,MAAM,CAAA;CACnB;AAED,qDAAqD;AACrD,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,gBAAgB,CAAC,eAAe,CAAC,CAAC,GAAG,SAAS,CAAA;AAE3F,cAAM,cAAc;IAClB,gFAAgF;IAChF,OAAO,CAAC,SAAS,CAA6D;IAE9E;;;;;;;;OAQG;IACH,MAAM,CAAC,SAAS,EAAE,MAAM,EAAE,IAAI,EAAE,gBAAgB,GAAG,SAAS,GAAG,IAAI,EAAE,UAAU,GAAE,MAAmB,GAAG,IAAI;IAkB3G,kEAAkE;IAClE,MAAM,CAAC,SAAS,EAAE,MAAM,GAAG,cAAc,EAAE;IAM3C,8EAA8E;IAC9E,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,EAAE,kBAAkB,GAAG,cAAc,GAAG,SAAS;IAI3E,yEAAyE;IACzE,IAAI,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM;IAOhC;;;;OAIG;IACH,KAAK,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI;CAIhC;AAED;;;GAGG;AACH,eAAO,MAAM,cAAc,gBAAuB,CAAA;AAElD,wCAAwC;AACxC,OAAO,EAAE,cAAc,IAAI,uBAAuB,EAAE,CAAA"}
@@ -20,6 +20,10 @@ export interface SanitizeOptions {
20
20
  /** Strip `<system-reminder>` blocks. Enable for adapters (Droid) that leak
21
21
  * CWD/env through this tag. */
22
22
  stripSystemReminder?: boolean;
23
+ /** Strip raw `<thinking>` tags. Off by default: the tag is a common
24
+ * chain-of-thought convention in user-authored prompts (#720). Enable only
25
+ * for an adapter observed leaking it. */
26
+ stripThinking?: boolean;
23
27
  }
24
28
  /**
25
29
  * Strip orchestration wrappers from a single text string.
@@ -1 +1 @@
1
- {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/proxy/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAwEH,MAAM,WAAW,eAAe;IAC9B;oCACgC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAA;CAC9B;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,MAAM,CAapF"}
1
+ {"version":3,"file":"sanitize.d.ts","sourceRoot":"","sources":["../../src/proxy/sanitize.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAiGH,MAAM,WAAW,eAAe;IAC9B;oCACgC;IAChC,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B;;8CAE0C;IAC1C,aAAa,CAAC,EAAE,OAAO,CAAA;CACxB;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,GAAE,eAAoB,GAAG,MAAM,CAapF"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAkDnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAA+B,iBAAiB,EAAE,mBAAmB,EAAsC,MAAM,iBAAiB,CAAA;AAGzI,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AAgR7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA0/HhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmGhG"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAgBA,OAAO,KAAK,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,SAAS,CAAA;AACtE,YAAY,EAAE,WAAW,EAAE,aAAa,EAAE,WAAW,EAAE,CAAA;AAGvD,YAAY,EACV,SAAS,EACT,cAAc,EACd,eAAe,EACf,gBAAgB,EAChB,cAAc,EACd,cAAc,EACd,iBAAiB,EACjB,YAAY,EACZ,aAAa,EACb,WAAW,GACZ,MAAM,aAAa,CAAA;AAKpB,OAAO,EAAE,gBAAgB,EAAE,cAAc,EAAE,aAAa,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAA;AAkDnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAI1B,OAAO,EAA+B,iBAAiB,EAAE,mBAAmB,EAAsC,MAAM,iBAAiB,CAAA;AAGzI,OAAO,EAAE,kBAAkB,EAAE,WAAW,EAAE,oBAAoB,EAAE,CAAA;AAChE,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,CAAA;AACjD,YAAY,EAAE,aAAa,EAAE,CAAA;AAgR7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA2gIhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmGhG"}
package/dist/server.js CHANGED
@@ -11,7 +11,7 @@ import {
11
11
  runObserveHook,
12
12
  runTransformHook,
13
13
  startProxyServer
14
- } from "./cli-5rkcyzzm.js";
14
+ } from "./cli-jwm61pg9.js";
15
15
  import"./cli-h6hfkg3s.js";
16
16
  import"./cli-sry5aqdj.js";
17
17
  import"./cli-xmweegb1.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rynfar/meridian",
3
- "version": "1.58.0",
3
+ "version": "1.58.2",
4
4
  "description": "Local Anthropic API powered by your Claude Max subscription. One subscription, every agent.",
5
5
  "type": "module",
6
6
  "main": "./dist/server.js",