@rynfar/meridian 1.45.2 → 1.45.4

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.
@@ -296,12 +296,14 @@ async function scheduleNext(store, bufferMs, failureRetryMs, gen) {
296
296
  }
297
297
  armTimer(dueIn, store, bufferMs, failureRetryMs, gen);
298
298
  }
299
+ var MAX_TIMEOUT_MS = 2147483647;
299
300
  function armTimer(delayMs, store, bufferMs, failureRetryMs, gen) {
301
+ const safeDelayMs = delayMs > MAX_TIMEOUT_MS ? MAX_TIMEOUT_MS : delayMs;
300
302
  scheduledRefreshTimer = setTimeout(async () => {
301
303
  if (!scheduledRefreshActive || gen !== scheduledRefreshGeneration)
302
304
  return;
303
305
  scheduleNext(store, bufferMs, failureRetryMs, gen);
304
- }, delayMs);
306
+ }, safeDelayMs);
305
307
  if (scheduledRefreshTimer && scheduledRefreshTimer.unref) {
306
308
  scheduledRefreshTimer.unref();
307
309
  }
@@ -47,7 +47,7 @@ import {
47
47
  startBackgroundRefresh,
48
48
  stopBackgroundRefresh,
49
49
  withClaudeLogContext
50
- } from "./cli-1kbcm3yn.js";
50
+ } from "./cli-aq5zz92m.js";
51
51
  import {
52
52
  __commonJS,
53
53
  __esm,
@@ -1463,6 +1463,7 @@ const FEATURES = [
1463
1463
 
1464
1464
  const ADAPTER_LABELS = {
1465
1465
  opencode: 'OpenCode',
1466
+ openai: 'OpenAI (/v1/chat/completions)',
1466
1467
  crush: 'Crush',
1467
1468
  forgecode: 'ForgeCode',
1468
1469
  pi: 'Pi',
@@ -9736,6 +9737,23 @@ function translateAnthropicSseEvent(event, completionId, model, created, toolCal
9736
9737
  }
9737
9738
  return null;
9738
9739
  }
9740
+ var yes = { supported: true };
9741
+ var FULL_CAPABILITIES = Object.freeze({
9742
+ batch: yes,
9743
+ citations: yes,
9744
+ code_execution: yes,
9745
+ context_management: {
9746
+ clear_thinking_20251015: yes,
9747
+ clear_tool_uses_20250919: yes,
9748
+ compact_20260112: yes,
9749
+ supported: true
9750
+ },
9751
+ effort: { high: yes, low: yes, max: yes, medium: yes, xhigh: yes, supported: true },
9752
+ image_input: yes,
9753
+ pdf_input: yes,
9754
+ structured_outputs: yes,
9755
+ thinking: { supported: true, types: { adaptive: yes, enabled: yes } }
9756
+ });
9739
9757
  function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000)) {
9740
9758
  return [
9741
9759
  {
@@ -9744,7 +9762,8 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
9744
9762
  created: now,
9745
9763
  owned_by: "anthropic",
9746
9764
  display_name: "Claude Sonnet 4.6",
9747
- context_window: 200000
9765
+ context_window: 200000,
9766
+ capabilities: FULL_CAPABILITIES
9748
9767
  },
9749
9768
  {
9750
9769
  id: "claude-opus-4-6",
@@ -9752,7 +9771,8 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
9752
9771
  created: now,
9753
9772
  owned_by: "anthropic",
9754
9773
  display_name: "Claude Opus 4.6",
9755
- context_window: isMaxSubscription ? 1e6 : 200000
9774
+ context_window: isMaxSubscription ? 1e6 : 200000,
9775
+ capabilities: FULL_CAPABILITIES
9756
9776
  },
9757
9777
  {
9758
9778
  id: "claude-opus-4-7",
@@ -9760,7 +9780,8 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
9760
9780
  created: now,
9761
9781
  owned_by: "anthropic",
9762
9782
  display_name: "Claude Opus 4.7",
9763
- context_window: isMaxSubscription ? 1e6 : 200000
9783
+ context_window: isMaxSubscription ? 1e6 : 200000,
9784
+ capabilities: FULL_CAPABILITIES
9764
9785
  },
9765
9786
  {
9766
9787
  id: "claude-opus-4-8",
@@ -9768,7 +9789,8 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
9768
9789
  created: now,
9769
9790
  owned_by: "anthropic",
9770
9791
  display_name: "Claude Opus 4.8",
9771
- context_window: isMaxSubscription ? 1e6 : 200000
9792
+ context_window: isMaxSubscription ? 1e6 : 200000,
9793
+ capabilities: FULL_CAPABILITIES
9772
9794
  },
9773
9795
  {
9774
9796
  id: "claude-fable-5",
@@ -9776,7 +9798,8 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
9776
9798
  created: now,
9777
9799
  owned_by: "anthropic",
9778
9800
  display_name: "Claude Fable 5",
9779
- context_window: isMaxSubscription ? 1e6 : 200000
9801
+ context_window: isMaxSubscription ? 1e6 : 200000,
9802
+ capabilities: FULL_CAPABILITIES
9780
9803
  },
9781
9804
  {
9782
9805
  id: "claude-haiku-4-5",
@@ -9784,7 +9807,8 @@ function buildModelList(isMaxSubscription, now = Math.floor(Date.now() / 1000))
9784
9807
  created: now,
9785
9808
  owned_by: "anthropic",
9786
9809
  display_name: "Claude Haiku 4.5",
9787
- context_window: 200000
9810
+ context_window: 200000,
9811
+ capabilities: FULL_CAPABILITIES
9788
9812
  }
9789
9813
  ];
9790
9814
  }
@@ -9847,6 +9871,90 @@ function getLastUserMessage(messages) {
9847
9871
  }
9848
9872
  return messages.slice(-1);
9849
9873
  }
9874
+ function stripNonStandardStreamFields(event) {
9875
+ if (event && typeof event === "object") {
9876
+ const e = event;
9877
+ delete e.context_management;
9878
+ const delta = e.delta;
9879
+ if (delta && typeof delta === "object") {
9880
+ delete delta.context_management;
9881
+ }
9882
+ }
9883
+ return event;
9884
+ }
9885
+ var MULTIMODAL_TYPES = new Set(["image", "document", "file"]);
9886
+ function consolidateMultimodalOntoLastUser(structured) {
9887
+ let targetIdx = -1;
9888
+ for (let i = structured.length - 1;i >= 0; i--) {
9889
+ if (Array.isArray(structured[i].message.content)) {
9890
+ targetIdx = i;
9891
+ break;
9892
+ }
9893
+ }
9894
+ if (targetIdx < 0)
9895
+ return structured;
9896
+ const carried = [];
9897
+ const result = structured.map((entry, i) => {
9898
+ const content = entry.message.content;
9899
+ if (i === targetIdx || !Array.isArray(content))
9900
+ return entry;
9901
+ const kept = content.filter((block) => {
9902
+ if (block && typeof block === "object" && MULTIMODAL_TYPES.has(block.type)) {
9903
+ carried.push(block);
9904
+ return false;
9905
+ }
9906
+ return true;
9907
+ });
9908
+ if (kept.length === content.length)
9909
+ return entry;
9910
+ return { ...entry, message: { ...entry.message, content: kept } };
9911
+ });
9912
+ if (carried.length === 0)
9913
+ return structured;
9914
+ const target = result[targetIdx];
9915
+ const existing = target.message.content;
9916
+ const seen = new Set(existing.map((b) => JSON.stringify(b)));
9917
+ const toAppend = carried.filter((b) => {
9918
+ const key = JSON.stringify(b);
9919
+ if (seen.has(key))
9920
+ return false;
9921
+ seen.add(key);
9922
+ return true;
9923
+ });
9924
+ result[targetIdx] = {
9925
+ ...target,
9926
+ message: { ...target.message, content: [...existing, ...toAppend] }
9927
+ };
9928
+ return result;
9929
+ }
9930
+ var TOOL_TARGET_KEYS = ["filePath", "file_path", "path", "command", "pattern", "query", "url"];
9931
+ function buildToolUseIndex(messages) {
9932
+ const index = new Map;
9933
+ for (const m of messages) {
9934
+ if (m.role !== "assistant" || !Array.isArray(m.content))
9935
+ continue;
9936
+ for (const block of m.content) {
9937
+ if (block?.type !== "tool_use" || !block.id || typeof block.name !== "string")
9938
+ continue;
9939
+ let target;
9940
+ const input = block.input;
9941
+ if (input && typeof input === "object") {
9942
+ for (const key of TOOL_TARGET_KEYS) {
9943
+ const v = input[key];
9944
+ if (typeof v === "string" && v) {
9945
+ target = v.length > 80 ? v.slice(0, 77) + "..." : v;
9946
+ break;
9947
+ }
9948
+ }
9949
+ }
9950
+ index.set(block.id, { name: block.name, target });
9951
+ }
9952
+ }
9953
+ return index;
9954
+ }
9955
+ function describeToolCall(info) {
9956
+ return info.target ? `[${info.name} ${info.target}]` : `[${info.name}]`;
9957
+ }
9850
9958
 
9851
9959
  // src/proxy/auth.ts
9852
9960
  import { createHmac, timingSafeEqual } from "node:crypto";
@@ -9919,15 +10027,17 @@ function createFileChangeHook(changes, mcpPrefix) {
9919
10027
  };
9920
10028
  }
9921
10029
  function isLikelyFilePath(s) {
9922
- if (/[()[\]]/.test(s))
9923
- return false;
9924
- if (/^-?\d+$/.test(s))
10030
+ if (s.length > 4096)
9925
10031
  return false;
9926
- if (/^[{}]$/.test(s))
10032
+ if (/[<>$`\\()[\]{}=]/.test(s))
9927
10033
  return false;
9928
- if (!/[\w/.]/.test(s))
10034
+ if (/^-?\d+$/.test(s))
9929
10035
  return false;
9930
- return true;
10036
+ if (s.includes("/"))
10037
+ return true;
10038
+ if (/\.[A-Za-z0-9]{1,16}$/.test(s))
10039
+ return true;
10040
+ return false;
9931
10041
  }
9932
10042
  function extractFileChangesFromBash(command) {
9933
10043
  const changes = [];
@@ -10083,7 +10193,7 @@ var ALLOWED_MCP_TOOLS = [
10083
10193
  var openCodeTransforms = [
10084
10194
  {
10085
10195
  name: "opencode-core",
10086
- adapters: ["opencode"],
10196
+ adapters: ["opencode", "openai"],
10087
10197
  onRequest(ctx) {
10088
10198
  const body = ctx.body;
10089
10199
  const blockedTools = BLOCKED_BUILTIN_TOOLS;
@@ -10797,10 +10907,30 @@ function extractClaudeCodeClientCwd(body) {
10797
10907
  const match2 = systemText.match(/Primary working directory:\s*([^\n<]+)/i);
10798
10908
  return match2?.[1]?.trim() || undefined;
10799
10909
  }
10910
+ function extractClaudeCodeSessionId(body) {
10911
+ if (!body || typeof body !== "object")
10912
+ return;
10913
+ const metadata = body.metadata;
10914
+ if (!metadata || typeof metadata !== "object")
10915
+ return;
10916
+ const rawUserId = metadata.user_id;
10917
+ let userMetadata = rawUserId;
10918
+ if (typeof rawUserId === "string") {
10919
+ try {
10920
+ userMetadata = JSON.parse(rawUserId);
10921
+ } catch {
10922
+ return;
10923
+ }
10924
+ }
10925
+ if (!userMetadata || typeof userMetadata !== "object")
10926
+ return;
10927
+ const sessionId = userMetadata.session_id;
10928
+ return typeof sessionId === "string" && sessionId.length > 0 ? sessionId : undefined;
10929
+ }
10800
10930
  var claudeCodeAdapter = {
10801
10931
  name: "claude-code",
10802
- getSessionId(_c) {
10803
- return;
10932
+ getSessionId(_c, body) {
10933
+ return extractClaudeCodeSessionId(body);
10804
10934
  },
10805
10935
  extractWorkingDirectory(_body) {
10806
10936
  return;
@@ -16809,7 +16939,7 @@ import { join as join2, isAbsolute as isAbsolute2, extname } from "path";
16809
16939
  import { pathToFileURL } from "url";
16810
16940
 
16811
16941
  // src/proxy/plugins/validation.ts
16812
- var KNOWN_ADAPTERS = ["opencode", "crush", "droid", "pi", "forgecode", "passthrough"];
16942
+ var KNOWN_ADAPTERS = ["opencode", "openai", "crush", "droid", "pi", "forgecode", "passthrough"];
16813
16943
  var KNOWN_HOOKS = ["onRequest", "onResponse", "onTelemetry", "onSession", "onToolUse", "onToolResult", "onError"];
16814
16944
  function validateTransform(exported) {
16815
16945
  if (exported == null || typeof exported !== "object") {
@@ -17008,12 +17138,13 @@ function filterBetasForProfile(rawBetaHeader, profileType, policy = DEFAULT_BETA
17008
17138
 
17009
17139
  // src/proxy/tokenHealth.ts
17010
17140
  var CONTEXT_SPIKE_THRESHOLD = 0.6;
17141
+ var CONTEXT_SPIKE_MIN_BASELINE = 1000;
17011
17142
  var CACHE_MISS_THRESHOLD = 0.05;
17012
17143
  var OUTPUT_EXPLOSION_RATIO = 2;
17013
17144
  var fmt = (n) => n > 1000 ? `${Math.round(n / 1000)}k` : String(n);
17014
17145
  function detectTokenAnomalies(current, previous) {
17015
17146
  const anomalies = [];
17016
- if (previous && previous.inputTokens > 0) {
17147
+ if (previous && previous.inputTokens >= CONTEXT_SPIKE_MIN_BASELINE) {
17017
17148
  const growth = (current.inputTokens - previous.inputTokens) / previous.inputTokens;
17018
17149
  if (growth > CONTEXT_SPIKE_THRESHOLD) {
17019
17150
  const pct = Math.round(growth * 100);
@@ -17686,7 +17817,6 @@ async function ensureFreshTokenForProfiles(config) {
17686
17817
  await ensureFreshToken(store).catch(() => {});
17687
17818
  }
17688
17819
  }
17689
- var MULTIMODAL_TYPES = new Set(["image", "document", "file"]);
17690
17820
  function hasMultimodalContent(content) {
17691
17821
  if (!Array.isArray(content))
17692
17822
  return false;
@@ -17746,7 +17876,7 @@ function flattenAssistantContent(content) {
17746
17876
  return content.map((b) => b?.type === "text" && b.text ? b.text : "").filter(Boolean).join(`
17747
17877
  `);
17748
17878
  }
17749
- function flattenUserContent(content, sanitizeOpts = {}) {
17879
+ function flattenUserContent(content, sanitizeOpts = {}, toolIndex) {
17750
17880
  if (typeof content === "string")
17751
17881
  return sanitizeTextContent(content, sanitizeOpts);
17752
17882
  if (!Array.isArray(content))
@@ -17755,14 +17885,20 @@ function flattenUserContent(content, sanitizeOpts = {}) {
17755
17885
  if (b?.type === "text" && b.text)
17756
17886
  return sanitizeTextContent(b.text, sanitizeOpts);
17757
17887
  if (b?.type === "tool_result") {
17888
+ const info = toolIndex?.get(b.tool_use_id);
17889
+ const label = info ? describeToolCall(info) : undefined;
17758
17890
  const inner = b.content;
17891
+ let flat = "";
17759
17892
  if (typeof inner === "string")
17760
- return inner;
17761
- if (Array.isArray(inner)) {
17762
- return inner.map((ib) => ib?.type === "text" && ib.text ? ib.text : "").filter(Boolean).join(`
17893
+ flat = inner;
17894
+ else if (Array.isArray(inner)) {
17895
+ flat = inner.map((ib) => ib?.type === "text" && ib.text ? ib.text : "").filter(Boolean).join(`
17763
17896
  `);
17764
17897
  }
17765
- return "";
17898
+ if (label)
17899
+ return flat ? `${label}:
17900
+ ${flat}` : label;
17901
+ return flat;
17766
17902
  }
17767
17903
  if (b?.type === "image")
17768
17904
  return "[Image attached]";
@@ -17776,6 +17912,7 @@ function flattenUserContent(content, sanitizeOpts = {}) {
17776
17912
  }
17777
17913
  function buildFreshPrompt(messages, sanitizeOpts = {}) {
17778
17914
  const hasMultimodal = messages.some((m) => hasMultimodalContent(m.content));
17915
+ const toolIndex = buildToolUseIndex(messages);
17779
17916
  if (hasMultimodal) {
17780
17917
  const structured = [];
17781
17918
  for (const m of messages) {
@@ -17796,14 +17933,15 @@ function buildFreshPrompt(messages, sanitizeOpts = {}) {
17796
17933
  }
17797
17934
  }
17798
17935
  }
17936
+ const prompt = structured.length > 1 ? consolidateMultimodalOntoLastUser(structured) : structured;
17799
17937
  return async function* () {
17800
- for (const msg of structured)
17938
+ for (const msg of prompt)
17801
17939
  yield msg;
17802
17940
  }();
17803
17941
  }
17804
17942
  return messages.map((m) => {
17805
17943
  const role = m.role === "assistant" ? "Assistant" : "Human";
17806
- const content = m.role === "assistant" ? flattenAssistantContent(m.content) : flattenUserContent(m.content, sanitizeOpts);
17944
+ const content = m.role === "assistant" ? flattenAssistantContent(m.content) : flattenUserContent(m.content, sanitizeOpts, toolIndex);
17807
17945
  return content ? `${role}: ${content}` : "";
17808
17946
  }).filter(Boolean).join(`
17809
17947
 
@@ -18041,12 +18179,12 @@ function createProxyServer(config = {}) {
18041
18179
  const parsedBudget = taskBudgetHeader ? Number.parseInt(taskBudgetHeader, 10) : NaN;
18042
18180
  const taskBudget = Number.isFinite(parsedBudget) ? { total: parsedBudget } : body.task_budget ? { total: body.task_budget.total ?? body.task_budget } : undefined;
18043
18181
  const betas = betaFilter.forwarded;
18044
- const agentSessionId = adapter.getSessionId(c);
18182
+ const agentSessionId = adapter.getSessionId(c, body);
18045
18183
  const profileSessionId = profile.id !== "default" && agentSessionId ? `${profile.id}:${agentSessionId}` : agentSessionId;
18046
18184
  const profileScopedCwd = profile.id !== "default" ? `${clientWorkingDirectory}::profile=${profile.id}` : clientWorkingDirectory;
18047
18185
  const lastMessage = Array.isArray(body.messages) ? body.messages[body.messages.length - 1] : undefined;
18048
18186
  const lastIsToolResult = Array.isArray(lastMessage?.content) && lastMessage.content.some((b) => b?.type === "tool_result");
18049
- const isClientDrivenLoop = !agentSessionId && lastIsToolResult;
18187
+ const isClientDrivenLoop = adapter.name !== "claude-code" && !agentSessionId && lastIsToolResult;
18050
18188
  const isIndependentSession = requestSource?.startsWith("fork-") || requestSource?.startsWith("subagent-") || isClientDrivenLoop || false;
18051
18189
  let lineageResult = isIndependentSession ? { type: "diverged" } : lookupSession(profileSessionId, body.messages || [], profileScopedCwd);
18052
18190
  if (lineageResult.type === "undo" && adapter.name === "opencode" && !agentSessionId) {
@@ -18145,10 +18283,14 @@ function createProxyServer(config = {}) {
18145
18283
  }
18146
18284
  }
18147
18285
  }
18286
+ if (structuredMessages.length > 1) {
18287
+ structuredMessages = consolidateMultimodalOntoLastUser(structuredMessages);
18288
+ }
18148
18289
  } else {
18290
+ const toolIndex = buildToolUseIndex(allMessages ?? messagesToConvert ?? []);
18149
18291
  textPrompt = messagesToConvert?.map((m) => {
18150
18292
  const role = m.role === "assistant" ? "Assistant" : "Human";
18151
- const content = m.role === "assistant" ? flattenAssistantContent(m.content) : flattenUserContent(m.content, sanitizeOpts);
18293
+ const content = m.role === "assistant" ? flattenAssistantContent(m.content) : flattenUserContent(m.content, sanitizeOpts, toolIndex);
18152
18294
  return content ? `${role}: ${content}` : "";
18153
18295
  }).filter(Boolean).join(`
18154
18296
 
@@ -18785,6 +18927,7 @@ Subprocess stderr: ${stderrOutput}`;
18785
18927
  let hasStructuredOutput = false;
18786
18928
  let structuredOutput;
18787
18929
  const streamedToolUseIds = new Set;
18930
+ const openClientBlocks = new Set;
18788
18931
  try {
18789
18932
  let currentSessionId;
18790
18933
  const MAX_RATE_LIMIT_RETRIES = 2;
@@ -19200,6 +19343,7 @@ data: ${JSON.stringify({
19200
19343
  }
19201
19344
  }
19202
19345
  }
19346
+ stripNonStandardStreamFields(event);
19203
19347
  const payload = encoder.encode(`event: ${eventType}
19204
19348
  data: ${JSON.stringify(event)}
19205
19349
 
@@ -19208,6 +19352,15 @@ data: ${JSON.stringify(event)}
19208
19352
  break;
19209
19353
  }
19210
19354
  eventsForwarded += 1;
19355
+ if (eventType === "content_block_start") {
19356
+ const idx = event.index;
19357
+ if (typeof idx === "number")
19358
+ openClientBlocks.add(idx);
19359
+ } else if (eventType === "content_block_stop") {
19360
+ const idx = event.index;
19361
+ if (typeof idx === "number")
19362
+ openClientBlocks.delete(idx);
19363
+ }
19211
19364
  if (passthrough && eventType === "message_delta" && event.delta?.stop_reason === "tool_use" && streamedToolUseIds.size > 0) {
19212
19365
  safeEnqueue(encoder.encode(`event: message_stop
19213
19366
  data: ${JSON.stringify({ type: "message_stop" })}
@@ -19495,6 +19648,13 @@ Subprocess stderr: ${stderrOutput}`;
19495
19648
  hasDeferredTools,
19496
19649
  sdkSessionId: resumeSessionId
19497
19650
  })} captured=${capturedToolUses.length}`, requestMeta.requestId);
19651
+ for (const idx of openClientBlocks) {
19652
+ safeEnqueue(encoder.encode(`event: content_block_stop
19653
+ data: ${JSON.stringify({ type: "content_block_stop", index: idx })}
19654
+
19655
+ `), "recover_close_dangling_block");
19656
+ }
19657
+ openClientBlocks.clear();
19498
19658
  const unseenToolUses = capturedToolUses.filter((tu) => !streamedToolUseIds.has(tu.id));
19499
19659
  for (let i = 0;i < unseenToolUses.length; i++) {
19500
19660
  const tu = unseenToolUses[i];
package/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  import {
3
3
  startProxyServer
4
- } from "./cli-kgrg9sq3.js";
4
+ } from "./cli-nb2xe1wm.js";
5
5
  import"./cli-cx463q74.js";
6
6
  import"./cli-sry5aqdj.js";
7
7
  import"./cli-4rqtm83g.js";
@@ -10,7 +10,7 @@ import {
10
10
  } from "./cli-7bygmvmv.js";
11
11
  import"./cli-340h1chz.js";
12
12
  import"./cli-je60fevk.js";
13
- import"./cli-1kbcm3yn.js";
13
+ import"./cli-aq5zz92m.js";
14
14
  import {
15
15
  __require
16
16
  } from "./cli-p9swy5t3.js";
@@ -53,7 +53,7 @@ See https://github.com/rynfar/meridian for full documentation.`);
53
53
  process.exit(0);
54
54
  }
55
55
  if (args[0] === "profile") {
56
- const { profileAdd, profileAddOauthToken, profileList, profileRemove, profileSwitch, profileLogin, profileHelp } = await import("./profileCli-w5gpxkyh.js");
56
+ const { profileAdd, profileAddOauthToken, profileList, profileRemove, profileSwitch, profileLogin, profileHelp } = await import("./profileCli-mm8yxb2j.js");
57
57
  const subcommand = args[1];
58
58
  const profileId = args[2];
59
59
  const headless = args.includes("--headless");
@@ -111,7 +111,7 @@ Restart OpenCode for the plugin to take effect.`);
111
111
  process.exit(0);
112
112
  }
113
113
  if (args[0] === "refresh-token") {
114
- const { refreshOAuthToken } = await import("./tokenRefresh-pvc2q8ea.js");
114
+ const { refreshOAuthToken } = await import("./tokenRefresh-tkeg8wjq.js");
115
115
  const success = await refreshOAuthToken();
116
116
  if (success) {
117
117
  console.log("Token refreshed successfully");
@@ -6,7 +6,7 @@ import {
6
6
  } from "./cli-340h1chz.js";
7
7
  import {
8
8
  createPlatformCredentialStore
9
- } from "./cli-1kbcm3yn.js";
9
+ } from "./cli-aq5zz92m.js";
10
10
  import"./cli-p9swy5t3.js";
11
11
 
12
12
  // src/proxy/profileCli.ts
@@ -18,7 +18,7 @@ export interface AgentIdentity {
18
18
  * Extract a session ID from the request.
19
19
  * Returns undefined if the agent doesn't provide session tracking.
20
20
  */
21
- getSessionId(c: Context): string | undefined;
21
+ getSessionId(c: Context, body?: unknown): string | undefined;
22
22
  /**
23
23
  * Extract the SDK subprocess working directory from the request body.
24
24
  *
@@ -1 +1 @@
1
- {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/proxy/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAEnE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,YAAY,CAAC,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IAE5C;;;;;;;;;;;;;;;;OAgBG;IACH,uBAAuB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAAA;IAEtD;;;;;;;;;;;OAWG;IACH,6BAA6B,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAAA;IAE7D;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,CAAA;IAEtC;;;OAGG;IACH,gBAAgB,IAAI,MAAM,CAAA;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD;;;OAGG;IACH,sBAAsB,IAAI,SAAS,MAAM,EAAE,CAAA;IAE3C;;;;OAIG;IACH,yBAAyB,IAAI,SAAS,MAAM,EAAE,CAAA;IAE9C;;OAEG;IACH,kBAAkB,IAAI,SAAS,MAAM,EAAE,CAAA;IAEvC;;;;OAIG;IACH,cAAc,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEhF;;;OAGG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAA;IAE9D;;;OAGG;IACH,0BAA0B,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAA;IAE9E;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;IAErC;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,OAAO,CAAA;IAE3B;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,SAAS,MAAM,EAAE,CAAA;IAEtC;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,IAAI,aAAa,EAAE,CAAA;IAErC;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,OAAO,CAAA;IAE5B;;;;;;OAMG;IACH,sBAAsB,CAAC,IAAI,OAAO,CAAA;IAElC;;;;;;;;OAQG;IACH,yBAAyB,CAAC,IAAI,OAAO,CAAA;IAErC;;;;;;;;;;;;;;;OAeG;IACH,6BAA6B,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,eAAe,EAAE,UAAU,EAAE,CAAA;CAC3G"}
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/proxy/adapter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,gCAAgC,CAAA;AAEnE;;;;GAIG;AACH,MAAM,WAAW,aAAa;IAC5B,4DAA4D;IAC5D,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IAErB;;;OAGG;IACH,YAAY,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAAA;IAE5D;;;;;;;;;;;;;;;;OAgBG;IACH,uBAAuB,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAAA;IAEtD;;;;;;;;;;;OAWG;IACH,6BAA6B,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,MAAM,GAAG,SAAS,CAAA;IAE7D;;;OAGG;IACH,gBAAgB,CAAC,OAAO,EAAE,GAAG,GAAG,MAAM,CAAA;IAEtC;;;OAGG;IACH,gBAAgB,IAAI,MAAM,CAAA;CAC3B;AAED;;;;GAIG;AACH,MAAM,WAAW,YAAa,SAAQ,aAAa;IACjD;;;OAGG;IACH,sBAAsB,IAAI,SAAS,MAAM,EAAE,CAAA;IAE3C;;;;OAIG;IACH,yBAAyB,IAAI,SAAS,MAAM,EAAE,CAAA;IAE9C;;OAEG;IACH,kBAAkB,IAAI,SAAS,MAAM,EAAE,CAAA;IAEvC;;;;OAIG;IACH,cAAc,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,YAAY,EAAE,SAAS,MAAM,EAAE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;IAEhF;;;OAGG;IACH,aAAa,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,GAAG,CAAA;IAE9D;;;OAGG;IACH,0BAA0B,CAAC,CAAC,IAAI,EAAE,GAAG,EAAE,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,GAAG,MAAM,CAAA;IAE9E;;;;;;OAMG;IACH,gBAAgB,CAAC,CAAC,IAAI,EAAE,GAAG,GAAG,OAAO,CAAA;IAErC;;;;;;;;OAQG;IACH,eAAe,CAAC,IAAI,OAAO,CAAA;IAE3B;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,SAAS,MAAM,EAAE,CAAA;IAEtC;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,IAAI,aAAa,EAAE,CAAA;IAErC;;;;;;;OAOG;IACH,gBAAgB,CAAC,IAAI,OAAO,CAAA;IAE5B;;;;;;OAMG;IACH,sBAAsB,CAAC,IAAI,OAAO,CAAA;IAElC;;;;;;;;OAQG;IACH,yBAAyB,CAAC,IAAI,OAAO,CAAA;IAErC;;;;;;;;;;;;;;;OAeG;IACH,6BAA6B,CAAC,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,GAAG,OAAO,eAAe,EAAE,UAAU,EAAE,CAAA;CAC3G"}
@@ -17,5 +17,7 @@
17
17
  * fingerprinting and a system-prompt hint (see server.ts + query.ts).
18
18
  */
19
19
  import type { AgentAdapter } from "../adapter";
20
+ /** Extract the stable conversation ID embedded by Claude Code in metadata.user_id. */
21
+ export declare function extractClaudeCodeSessionId(body: unknown): string | undefined;
20
22
  export declare const claudeCodeAdapter: AgentAdapter;
21
23
  //# sourceMappingURL=claudecode.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"claudecode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/claudecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiC9C,eAAO,MAAM,iBAAiB,EAAE,YA0F/B,CAAA"}
1
+ {"version":3,"file":"claudecode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/claudecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiC9C,sFAAsF;AACtF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAoB5E;AAED,eAAO,MAAM,iBAAiB,EAAE,YA0F/B,CAAA"}
@@ -1 +1 @@
1
- {"version":3,"file":"fileChanges.d.ts","sourceRoot":"","sources":["../../src/proxy/fileChanges.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,SAAS,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC7B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,MAAM,GAChB,UAAU,GAAG,SAAS,CAexB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,UAAU,EAAE,EACrB,SAAS,EAAE,MAAM;;oBAIO;QACpB,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,EAAE,OAAO,CAAA;QACnB,aAAa,EAAE,OAAO,CAAA;QACtB,WAAW,EAAE,MAAM,CAAA;KACpB;EAkBJ;AAcD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAwCxE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,EACnD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,UAAU,EAAE,GAChE,UAAU,EAAE,CA0Bd;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,SAAS,CAgBjF"}
1
+ {"version":3,"file":"fileChanges.d.ts","sourceRoot":"","sources":["../../src/proxy/fileChanges.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,4DAA4D;AAC5D,MAAM,WAAW,UAAU;IACzB,8CAA8C;IAC9C,SAAS,EAAE,OAAO,GAAG,QAAQ,CAAA;IAC7B,wCAAwC;IACxC,IAAI,EAAE,MAAM,CAAA;CACb;AAED;;;;;;;;;GASG;AACH,wBAAgB,iBAAiB,CAC/B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,OAAO,EAClB,SAAS,EAAE,MAAM,GAChB,UAAU,GAAG,SAAS,CAexB;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,UAAU,EAAE,EACrB,SAAS,EAAE,MAAM;;oBAIO;QACpB,SAAS,EAAE,MAAM,CAAA;QACjB,UAAU,EAAE,OAAO,CAAA;QACnB,aAAa,EAAE,OAAO,CAAA;QACtB,WAAW,EAAE,MAAM,CAAA;KACpB;EAkBJ;AAwBD;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,EAAE,CAwCxE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,8BAA8B,CAC5C,QAAQ,EAAE,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC,EACnD,SAAS,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,KAAK,UAAU,EAAE,GAChE,UAAU,EAAE,CA0Bd;AAED;;;;;;;GAOG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,UAAU,EAAE,GAAG,MAAM,GAAG,SAAS,CAgBjF"}
@@ -32,4 +32,76 @@ export declare function getLastUserMessage(messages: Array<{
32
32
  role: string;
33
33
  content: any;
34
34
  }>;
35
+ /**
36
+ * Remove fields the Claude Agent SDK attaches to streamed events that are not
37
+ * part of the public Anthropic streaming schema.
38
+ *
39
+ * The SDK adds `context_management` (advisory metadata about upstream context
40
+ * edits) to `message_delta`. The real Anthropic API does not return it on a
41
+ * normal (non-beta) request, and stock clients — e.g. langchain-anthropic —
42
+ * assume any present field is a typed SDK model and call `.model_dump()` on it,
43
+ * crashing on the raw dict (#525). The context edit already happened upstream,
44
+ * so the field is safe to drop.
45
+ *
46
+ * Mutates and returns the event for convenient inline use in the SSE forward
47
+ * path; a no-op when the field is absent, so it is safe to call on every event.
48
+ */
49
+ export declare function stripNonStandardStreamFields<T>(event: T): T;
50
+ /** Content block types that carry non-text data the model must "see". */
51
+ export declare const MULTIMODAL_TYPES: Set<string>;
52
+ /**
53
+ * Consolidate multimodal blocks (image/document/file) from earlier user turns
54
+ * onto the final user turn of a structured (AsyncIterable) prompt.
55
+ *
56
+ * When the Claude Agent SDK is handed multiple user messages as a streaming
57
+ * iterable, it only surfaces multimodal blocks from the LAST user turn to the
58
+ * model — images sitting in earlier turns (e.g. an image a `read` tool returned
59
+ * mid-conversation) are silently dropped, and the model answers "I cannot see
60
+ * the image" (#553). Moving those blocks onto the final array-content user turn
61
+ * makes them visible; accompanying text is left in place.
62
+ *
63
+ * Notes:
64
+ * - The target is the last entry whose `message.content` is an ARRAY. Flattened
65
+ * assistant turns are string content and can never hold image blocks, so a
66
+ * conversation ending on an assistant turn still lands images on the last
67
+ * real user turn.
68
+ * - Blocks structurally identical to ones already on the target are not
69
+ * re-appended (avoids duplicating a client-re-attached image).
70
+ *
71
+ * Pure: returns a new array; the input and its messages are not mutated. No-op
72
+ * when there are fewer than two array-content user turns or nothing to carry.
73
+ */
74
+ export declare function consolidateMultimodalOntoLastUser<T extends {
75
+ message: {
76
+ content: unknown;
77
+ };
78
+ }>(structured: T[]): T[];
79
+ /** A tool call the assistant made earlier in the conversation. */
80
+ export interface ToolCallInfo {
81
+ name: string;
82
+ /** Compact human-readable target (file path, command, pattern...), if any. */
83
+ target: string | undefined;
84
+ }
85
+ /**
86
+ * Index every assistant tool_use block in a conversation by id.
87
+ *
88
+ * Used to attribute tool_result blocks during full-history replay: the
89
+ * flattened replay drops assistant tool_use blocks (issues #111/#386 — verbose
90
+ * `[Tool Use: ...]` strings taught the model to imitate fake tool syntax), so
91
+ * without attribution the model sees raw tool outputs as bare user text with
92
+ * no cause — it then denies having made the calls at all ("a file I never
93
+ * created", #552).
94
+ */
95
+ export declare function buildToolUseIndex(messages: Array<{
96
+ role: string;
97
+ content: any;
98
+ }>): Map<string, ToolCallInfo>;
99
+ /**
100
+ * Render a compact attribution label for a replayed tool result, e.g.
101
+ * `[write tmp/test2.txt]` or `[bash echo hi]`. Deliberately terse and
102
+ * bracket-formatted differently from the banned `[Tool Use: ...]` /
103
+ * `[Tool Result ...]` shapes (#111/#386) so the model reads it as context,
104
+ * not as tool-call syntax to imitate.
105
+ */
106
+ export declare function describeToolCall(info: ToolCallInfo): string;
35
107
  //# sourceMappingURL=messages.d.ts.map
@@ -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"}
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;;;;;;;;;;;;;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;CAC3B;AAKD;;;;;;;;;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,CAqB3B;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,YAAY,GAAG,MAAM,CAE3D"}
@@ -212,6 +212,45 @@ export interface OpenAiCompletion {
212
212
  total_tokens: number;
213
213
  };
214
214
  }
215
+ /** A single capability flag, matching the Anthropic Models API. */
216
+ interface CapabilitySupport {
217
+ supported: boolean;
218
+ }
219
+ /**
220
+ * Model capability information, mirroring the Anthropic `GET /v1/models`
221
+ * `capabilities` object. Clients (e.g. Home Assistant's Anthropic integration)
222
+ * read these fields — notably `image_input` — to decide which content types a
223
+ * model accepts (#498).
224
+ */
225
+ export interface ModelCapabilities {
226
+ batch: CapabilitySupport;
227
+ citations: CapabilitySupport;
228
+ code_execution: CapabilitySupport;
229
+ context_management: {
230
+ clear_thinking_20251015: CapabilitySupport;
231
+ clear_tool_uses_20250919: CapabilitySupport;
232
+ compact_20260112: CapabilitySupport;
233
+ supported: boolean;
234
+ };
235
+ effort: {
236
+ high: CapabilitySupport;
237
+ low: CapabilitySupport;
238
+ max: CapabilitySupport;
239
+ medium: CapabilitySupport;
240
+ xhigh: CapabilitySupport;
241
+ supported: boolean;
242
+ };
243
+ image_input: CapabilitySupport;
244
+ pdf_input: CapabilitySupport;
245
+ structured_outputs: CapabilitySupport;
246
+ thinking: {
247
+ supported: boolean;
248
+ types: {
249
+ adaptive: CapabilitySupport;
250
+ enabled: CapabilitySupport;
251
+ };
252
+ };
253
+ }
215
254
  export interface OpenAiModel {
216
255
  id: string;
217
256
  object: "model";
@@ -219,6 +258,7 @@ export interface OpenAiModel {
219
258
  owned_by: string;
220
259
  display_name: string;
221
260
  context_window: number;
261
+ capabilities?: ModelCapabilities;
222
262
  }
223
263
  /**
224
264
  * Normalise an OpenAI message content field to a plain string.
@@ -316,4 +356,5 @@ export declare function translateAnthropicSseEvent(event: AnthropicSseEvent, com
316
356
  * Context windows reflect subscription capabilities.
317
357
  */
318
358
  export declare function buildModelList(isMaxSubscription: boolean, now?: number): OpenAiModel[];
359
+ export {};
319
360
  //# sourceMappingURL=openai.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/proxy/openai.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"openai.d.ts","sourceRoot":"","sources":["../../src/proxy/openai.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/proxy/server.ts"],"names":[],"mappings":"AAeA,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;AAkCnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAG1B,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;AAiQ7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA8+FhF;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":"AAeA,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;AAkCnG,OAAO,EACL,kBAAkB,EAClB,WAAW,EACX,oBAAoB,EAEpB,KAAK,aAAa,EAGnB,MAAM,mBAAmB,CAAA;AAG1B,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;AA2Q7B,wBAAgB,iBAAiB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,WAAW,CA6hGhF;AAWD,wBAAgB,gCAAgC,IAAI,IAAI,CAavD;AAED,wBAAsB,gBAAgB,CAAC,MAAM,GAAE,OAAO,CAAC,WAAW,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmGhG"}
@@ -1 +1 @@
1
- {"version":3,"file":"tokenHealth.d.ts","sourceRoot":"","sources":["../../src/proxy/tokenHealth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,wBAAwB,EAAE,MAAM,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,eAAe,GAAG,YAAY,GAAG,kBAAkB,CAAA;IACzD,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;CACf;AAaD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,aAAa,GAAG,SAAS,GAClC,YAAY,EAAE,CA6ChB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAK1F"}
1
+ {"version":3,"file":"tokenHealth.d.ts","sourceRoot":"","sources":["../../src/proxy/tokenHealth.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,aAAa;IAC5B,SAAS,EAAE,MAAM,CAAA;IACjB,UAAU,EAAE,MAAM,CAAA;IAClB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,wBAAwB,EAAE,MAAM,CAAA;IAChC,YAAY,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,OAAO,CAAA;IACjB,aAAa,EAAE,OAAO,CAAA;CACvB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,eAAe,GAAG,YAAY,GAAG,kBAAkB,CAAA;IACzD,QAAQ,EAAE,MAAM,GAAG,UAAU,CAAA;IAC7B,MAAM,EAAE,MAAM,CAAA;CACf;AAqBD;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,aAAa,EACtB,QAAQ,EAAE,aAAa,GAAG,SAAS,GAClC,YAAY,EAAE,CA8ChB;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,SAAS,EAAE,YAAY,EAAE,GAAG,MAAM,EAAE,CAK1F"}
@@ -1 +1 @@
1
- {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../../src/proxy/tokenRefresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED,gEAAgE;AAChE,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,UAAU,eAAe;IACvB,aAAa,EAAE,gBAAgB,CAAA;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAMD,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IACvC,KAAK,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,eAAe,GAAG,MAAM,CAEzE;AA4GD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAQlG;AAED,uGAAuG;AACvG,wBAAgB,6BAA6B,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9E;AAUD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBjF;AAiED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,CAAC,EAAE,eAAe,EACvB,QAAQ,SAAgB,GACvB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAiBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,CAAC,EAAE,eAAe,EACvB,QAAQ,SAAgB,EACxB,cAAc,SAAgB,GAC7B,IAAI,CAKN;AAED,iDAAiD;AACjD,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C;AA2DD,wBAAwB;AACxB,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED,gDAAgD;AAChD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
1
+ {"version":3,"file":"tokenRefresh.d.ts","sourceRoot":"","sources":["../../src/proxy/tokenRefresh.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAkBH;;;;;;;;GAQG;AACH,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAK1E;AAED,gEAAgE;AAChE,wBAAgB,0BAA0B,CAAC,eAAe,EAAE,MAAM,GAAG,MAAM,CAE1E;AAED,UAAU,gBAAgB;IACxB,WAAW,EAAE,MAAM,CAAA;IACnB,YAAY,EAAE,MAAM,CAAA;IACpB,SAAS,EAAE,MAAM,CAAA;IACjB,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,gBAAgB,CAAC,EAAE,MAAM,CAAA;IACzB,aAAa,CAAC,EAAE,MAAM,CAAA;CACvB;AAED,UAAU,eAAe;IACvB,aAAa,EAAE,gBAAgB,CAAA;IAC/B,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;CACvB;AAMD,MAAM,WAAW,eAAe;IAC9B,kFAAkF;IAClF,UAAU,CAAC,EAAE,MAAM,CAAA;IACnB,IAAI,IAAI,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAAA;IACvC,KAAK,CAAC,WAAW,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAAA;CACtD;AAED;;;;;;;;;GASG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,eAAe,GAAG,MAAM,CAEzE;AA4GD;;;;;;;GAOG;AACH,wBAAgB,6BAA6B,CAAC,IAAI,CAAC,EAAE;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,eAAe,CAQlG;AAED,uGAAuG;AACvG,wBAAgB,6BAA6B,CAAC,eAAe,CAAC,EAAE,MAAM,GAAG,MAAM,CAE9E;AAUD;;;;;;;;;;GAUG;AACH,wBAAsB,iBAAiB,CAAC,KAAK,CAAC,EAAE,eAAe,GAAG,OAAO,CAAC,OAAO,CAAC,CAsBjF;AAiED;;;;;;;;;;;;;GAaG;AACH,wBAAsB,gBAAgB,CACpC,KAAK,CAAC,EAAE,eAAe,EACvB,QAAQ,SAAgB,GACvB,OAAO,CAAC,OAAO,CAAC,CAOlB;AAiBD;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,CAAC,EAAE,eAAe,EACvB,QAAQ,SAAgB,EACxB,cAAc,SAAgB,GAC7B,IAAI,CAKN;AAED,iDAAiD;AACjD,wBAAgB,qBAAqB,IAAI,IAAI,CAK5C;AAoED,wBAAwB;AACxB,wBAAgB,yBAAyB,IAAI,OAAO,CAEnD;AAED,gDAAgD;AAChD,wBAAgB,oBAAoB,IAAI,IAAI,CAE3C"}
@@ -1 +1 @@
1
- {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/proxy/transforms/opencode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,cAAc,CAAA;AAO7D,eAAO,MAAM,kBAAkB,EAAE,SAAS,EA0FzC,CAAA"}
1
+ {"version":3,"file":"opencode.d.ts","sourceRoot":"","sources":["../../../src/proxy/transforms/opencode.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAkB,MAAM,cAAc,CAAA;AAO7D,eAAO,MAAM,kBAAkB,EAAE,SAAS,EA6FzC,CAAA"}
package/dist/server.js CHANGED
@@ -11,14 +11,14 @@ import {
11
11
  runObserveHook,
12
12
  runTransformHook,
13
13
  startProxyServer
14
- } from "./cli-kgrg9sq3.js";
14
+ } from "./cli-nb2xe1wm.js";
15
15
  import"./cli-cx463q74.js";
16
16
  import"./cli-sry5aqdj.js";
17
17
  import"./cli-4rqtm83g.js";
18
18
  import"./cli-7bygmvmv.js";
19
19
  import"./cli-340h1chz.js";
20
20
  import"./cli-je60fevk.js";
21
- import"./cli-1kbcm3yn.js";
21
+ import"./cli-aq5zz92m.js";
22
22
  import"./cli-p9swy5t3.js";
23
23
  export {
24
24
  startProxyServer,
@@ -2,5 +2,5 @@
2
2
  * SDK Features settings page — per-adapter toggle UI.
3
3
  * Same dark theme as the telemetry dashboard. No framework, no CDN.
4
4
  */
5
- export declare const settingsPageHtml = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Meridian \u2014 SDK Features</title>\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/telemetry/icon.svg\">\n<style>\n \n :root {\n /* Cool-gray neutral palette \u2014 matches the original dashboard/profiles/\n settings look. Better for data-dense dashboards: high contrast,\n surface/border separation, no color cast muddying the text. Purple\n accents are retained as secondary brand color for hover states,\n gradients, and a handful of telemetry badges. */\n --bg: #0d1117;\n --surface: #161b22;\n --surface2: #1c2128;\n --border: #30363d;\n /* Text */\n --text: #e6edf3;\n --muted: #8b949e;\n /* Brand \u2014 blue primary, purple secondary */\n --accent: #58a6ff;\n --accent2: #bc8cff;\n --violet: #bc8cff;\n --lavender: #d2a8ff;\n /* Semantic */\n --green: #3fb950;\n --yellow: #d29922;\n --red: #f85149;\n /* Telemetry-specific aliases (waterfall + lineage badges) */\n --blue: #58a6ff;\n --purple: #bc8cff;\n --queue: #d29922;\n --ttfb: #58a6ff;\n --upstream: #3fb950;\n }\n\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;\n background: var(--bg); color: var(--text); padding: 0; line-height: 1.5; }\n \n .meridian-profile-bar {\n position: sticky; top: 0; z-index: 100;\n display: none; align-items: center; gap: 12px;\n padding: 8px 24px;\n background: rgba(13, 17, 23, 0.92);\n backdrop-filter: blur(12px);\n border-bottom: 1px solid var(--border, #30363d);\n font-size: 12px;\n color: var(--muted, #8b949e);\n }\n .meridian-profile-bar.visible { display: flex; }\n .meridian-profile-bar .profile-label {\n font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px;\n font-size: 10px; color: var(--muted, #8b949e);\n }\n .meridian-profile-bar select {\n background: var(--surface, #161b22); color: var(--text, #e6edf3);\n border: 1px solid var(--border, #30363d); border-radius: 6px;\n padding: 4px 24px 4px 10px; font-size: 12px; cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 5l3 3 3-3' fill='none' stroke='%238b949e' stroke-width='1.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 6px center;\n }\n .meridian-profile-bar select:hover { border-color: var(--accent, #58a6ff); }\n .meridian-profile-bar select:focus { outline: none; border-color: var(--accent, #58a6ff); box-shadow: 0 0 0 1px var(--accent, #58a6ff); }\n .meridian-profile-bar .profile-status {\n font-size: 11px; color: var(--green, #3fb950); opacity: 0;\n transition: opacity 0.3s;\n }\n .meridian-profile-bar .profile-status.show { opacity: 1; }\n .meridian-profile-bar .profile-type {\n font-size: 10px; padding: 2px 8px; border-radius: 4px;\n background: var(--surface, #161b22); border: 1px solid var(--border, #30363d);\n }\n .meridian-profile-bar .spacer { flex: 1; }\n .meridian-profile-bar .profile-nav a {\n color: var(--muted, #8b949e); text-decoration: none; font-size: 11px;\n padding: 4px 8px; border-radius: 4px; transition: color 0.15s;\n }\n .meridian-profile-bar .profile-nav a:hover { color: var(--text, #e6edf3); }\n .meridian-profile-bar .profile-nav a.active { color: var(--accent, #58a6ff); }\n\n .content { max-width: 900px; margin: 0 auto; padding: 24px; }\n h1 { font-size: 20px; font-weight: 600; margin-bottom: 4px; }\n .subtitle { color: var(--muted); font-size: 13px; margin-bottom: 24px; }\n .nav { display: flex; gap: 16px; margin-bottom: 24px; font-size: 13px; }\n .nav a { color: var(--muted); text-decoration: none; }\n .nav a:hover { color: var(--accent); }\n .nav a.active { color: var(--accent); }\n\n .adapter-card {\n background: var(--surface); border: 1px solid var(--border); border-radius: 8px;\n padding: 20px; margin-bottom: 16px;\n }\n .adapter-header {\n display: flex; align-items: center; justify-content: space-between;\n margin-bottom: 16px;\n }\n .adapter-name { font-size: 16px; font-weight: 600; }\n .adapter-badge {\n font-size: 10px; padding: 2px 8px; border-radius: 10px;\n text-transform: uppercase; letter-spacing: 0.5px;\n }\n .badge-active { background: rgba(63, 185, 80, 0.15); color: var(--green); }\n .badge-inactive { background: rgba(139, 148, 158, 0.15); color: var(--muted); }\n\n .feature-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }\n @media (max-width: 600px) { .feature-grid { grid-template-columns: 1fr; } }\n\n .feature-row {\n display: flex; align-items: center; justify-content: space-between;\n padding: 10px 14px; border-radius: 6px;\n background: var(--bg); border: 1px solid var(--border);\n }\n .feature-info { display: flex; flex-direction: column; }\n .feature-label { font-size: 13px; font-weight: 500; }\n .feature-desc { font-size: 11px; color: var(--muted); margin-top: 2px; }\n\n /* Toggle switch */\n .toggle { position: relative; width: 36px; height: 20px; flex-shrink: 0; }\n .toggle input { opacity: 0; width: 0; height: 0; }\n .toggle-track {\n position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;\n background: var(--border); border-radius: 10px; transition: background 0.2s;\n }\n .toggle-track::after {\n content: \"\"; position: absolute; height: 14px; width: 14px;\n left: 3px; bottom: 3px; background: var(--muted); border-radius: 50%;\n transition: transform 0.2s, background 0.2s;\n }\n .toggle input:checked + .toggle-track { background: var(--accent); }\n .toggle input:checked + .toggle-track::after {\n transform: translateX(16px); background: var(--text);\n }\n\n /* Select dropdown */\n .feature-select {\n background: var(--surface); color: var(--text); border: 1px solid var(--border);\n border-radius: 6px; padding: 4px 8px; font-size: 12px; cursor: pointer;\n }\n\n .save-indicator {\n position: fixed; bottom: 24px; right: 24px;\n background: var(--green); color: #000; padding: 8px 16px;\n border-radius: 6px; font-size: 13px; font-weight: 500;\n opacity: 0; transition: opacity 0.3s; pointer-events: none;\n }\n .save-indicator.visible { opacity: 1; }\n\n .reset-btn {\n background: none; border: 1px solid var(--border); color: var(--muted);\n border-radius: 6px; padding: 4px 12px; font-size: 11px; cursor: pointer;\n }\n .reset-btn:hover { border-color: var(--red); color: var(--red); }\n</style>\n</head>\n<body>\n\n<div class=\"meridian-profile-bar\" id=\"meridianProfileBar\">\n <span class=\"profile-label\">Profile</span>\n <select id=\"meridianProfileSelect\"></select>\n <span class=\"profile-type\" id=\"meridianProfileType\"></span>\n <span class=\"profile-status\" id=\"meridianProfileStatus\">\u2713 Switched</span>\n <div class=\"spacer\"></div>\n <div class=\"profile-nav\">\n <a href=\"/\" id=\"nav-home\">Home</a>\n <a href=\"/settings\" id=\"nav-settings\">Settings</a>\n <a href=\"/profiles\" id=\"nav-profiles\">Profiles</a>\n <a href=\"/telemetry\" id=\"nav-telemetry\">Telemetry</a>\n <a href=\"/plugins\" id=\"nav-plugins\">Plugins</a>\n </div>\n</div>\n\n<div class=\"content\">\n <h1>SDK Features <span style=\"font-size:11px;padding:2px 8px;border-radius:10px;background:rgba(210,153,34,0.15);color:var(--yellow);vertical-align:middle;margin-left:8px\">Experimental</span></h1>\n <p class=\"subtitle\" style=\"max-width:720px;line-height:1.6\">\n Unlock Claude Code features for any connected agent. Capabilities like auto-memory, dreaming, and CLAUDE.md \u2014 normally\n exclusive to Claude Code \u2014 become available to OpenCode, Crush, Droid, and any other harness routed through Meridian.\n Each agent keeps its own toolchain while gaining access to these additional features.<br><br>\n <strong style=\"color:var(--text)\">System prompts:</strong> For these features to work correctly, both the Claude Code prompt and your client prompt\n should be enabled. When both are active, they are appended together \u2014 Claude Code's base instructions come first,\n followed by your agent's specific instructions.\n </p>\n\n <div id=\"adapters\"></div>\n</div>\n\n<div class=\"save-indicator\" id=\"saveIndicator\">Saved</div>\n\n<script>\nconst FEATURES = [\n { key: 'codeSystemPrompt', label: 'Claude Code Prompt', desc: 'Include the built-in Claude Code system prompt (tool usage rules, safety guidelines, coding best practices)', type: 'toggle' },\n { key: 'clientSystemPrompt', label: 'Client Prompt', desc: 'Include the system prompt sent by the connecting agent (e.g. OpenCode or Crush instructions)', type: 'toggle' },\n { key: 'claudeMd', label: 'CLAUDE.md', desc: 'Load CLAUDE.md instruction files \u2014 Off: none, Project: ./CLAUDE.md only, Full: ~/.claude/CLAUDE.md + ./CLAUDE.md', type: 'select', options: ['off', 'project', 'full'] },\n { key: 'memory', label: 'Memory', desc: 'Read and write memories across sessions', type: 'toggle' },\n { key: 'dreaming', label: 'Auto-Dream', desc: 'Background memory consolidation', type: 'toggle' },\n { key: 'thinking', label: 'Thinking', desc: 'Extended thinking mode', type: 'select', options: ['disabled', 'adaptive', 'enabled'] },\n { key: 'thinkingPassthrough', label: 'Thinking Passthrough', desc: 'Forward thinking blocks to the client', type: 'toggle' },\n { key: 'sharedMemory', label: 'Shared Memory', desc: 'Share memory with Claude Code (~/.claude) instead of isolated storage', type: 'toggle' },\n { key: 'maxBudgetUsd', label: 'Max Budget (USD)', desc: 'Per-request cost cap \u2014 query aborts if exceeded (0 = disabled)', type: 'number' },\n { key: 'fallbackModel', label: 'Fallback Model', desc: 'Auto-fallback model if primary fails', type: 'select', options: ['', 'sonnet', 'opus', 'haiku', 'sonnet[1m]', 'opus[1m]'] },\n { key: 'sdkDebug', label: 'SDK Debug Logging', desc: 'Enable verbose SDK debug output to proxy stderr', type: 'toggle' },\n { key: 'additionalDirectories', label: 'Additional Directories', desc: 'Comma-separated extra paths Claude can access (monorepo libs, etc.)', type: 'text' },\n];\n\nconst ADAPTER_LABELS = {\n opencode: 'OpenCode',\n crush: 'Crush',\n forgecode: 'ForgeCode',\n pi: 'Pi',\n droid: 'Droid',\n passthrough: 'LiteLLM / Passthrough',\n};\n\nlet currentConfig = {};\n\nasync function loadConfig() {\n const res = await fetch('/settings/api/features');\n currentConfig = await res.json();\n render();\n}\n\nasync function saveFeature(adapter, key, value) {\n const patch = {};\n patch[key] = value;\n await fetch('/settings/api/features/' + adapter, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(patch),\n });\n currentConfig[adapter][key] = value;\n showSaved();\n}\n\nasync function resetAdapter(adapter) {\n await fetch('/settings/api/features/' + adapter, { method: 'DELETE' });\n await loadConfig();\n showSaved();\n}\n\nfunction showSaved() {\n const el = document.getElementById('saveIndicator');\n el.classList.add('visible');\n setTimeout(() => el.classList.remove('visible'), 1500);\n}\n\nfunction hasAnyEnabled(features) {\n return features.codeSystemPrompt || !features.clientSystemPrompt || features.claudeMd !== 'off' || features.memory || features.dreaming ||\n features.thinking !== 'disabled' || features.thinkingPassthrough ||\n features.sharedMemory || features.maxBudgetUsd > 0 ||\n features.fallbackModel || features.sdkDebug ||\n features.additionalDirectories;\n}\n\nfunction render() {\n const container = document.getElementById('adapters');\n container.innerHTML = '';\n\n for (const [adapter, label] of Object.entries(ADAPTER_LABELS)) {\n const features = currentConfig[adapter] || {};\n const active = hasAnyEnabled(features);\n\n const card = document.createElement('div');\n card.className = 'adapter-card';\n card.innerHTML = '<div class=\"adapter-header\">' +\n '<span class=\"adapter-name\">' + label + '</span>' +\n '<div style=\"display:flex;gap:8px;align-items:center\">' +\n '<span class=\"adapter-badge ' + (active ? 'badge-active' : 'badge-inactive') + '\">' +\n (active ? 'Active' : 'Default') +\n '</span>' +\n '<button class=\"reset-btn\" onclick=\"resetAdapter(\\''+adapter+'\\')\">Reset</button>' +\n '</div>' +\n '</div>';\n\n const grid = document.createElement('div');\n grid.className = 'feature-grid';\n\n for (const feat of FEATURES) {\n const row = document.createElement('div');\n row.className = 'feature-row';\n\n const info = '<div class=\"feature-info\"><span class=\"feature-label\">' +\n feat.label + '</span><span class=\"feature-desc\">' + feat.desc + '</span></div>';\n\n if (feat.type === 'toggle') {\n const checked = features[feat.key] ? 'checked' : '';\n row.innerHTML = info +\n '<label class=\"toggle\"><input type=\"checkbox\" ' + checked +\n ' onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', this.checked)\">' +\n '<span class=\"toggle-track\"></span></label>';\n } else if (feat.type === 'select') {\n const options = feat.options.map(o => {\n const label = o === '' ? '(None)' : o.charAt(0).toUpperCase()+o.slice(1);\n return '<option value=\"'+o+'\"'+(features[feat.key]===o?' selected':'')+'>'+label+'</option>';\n }).join('');\n row.innerHTML = info +\n '<select class=\"feature-select\" onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', this.value)\">' +\n options + '</select>';\n } else if (feat.type === 'number') {\n const value = features[feat.key] ?? 0;\n row.innerHTML = info +\n '<input type=\"number\" class=\"feature-select\" style=\"width:80px;text-align:right\" min=\"0\" step=\"0.01\" value=\"'+value+'\"' +\n ' onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', parseFloat(this.value)||0)\">';\n } else if (feat.type === 'text') {\n const value = (features[feat.key] ?? '').toString().replace(/\"/g, '&quot;');\n row.innerHTML = info +\n '<input type=\"text\" class=\"feature-select\" style=\"width:180px\" value=\"'+value+'\"' +\n ' onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', this.value)\">';\n }\n\n grid.appendChild(row);\n }\n\n card.appendChild(grid);\n container.appendChild(card);\n }\n}\n\nloadConfig();\n\n(function() {\n var profileBar = document.getElementById('meridianProfileBar');\n var profileSelect = document.getElementById('meridianProfileSelect');\n var profileType = document.getElementById('meridianProfileType');\n var profileStatus = document.getElementById('meridianProfileStatus');\n var statusTimeout;\n\n // Highlight active nav link\n var path = location.pathname;\n var navLinks = document.querySelectorAll('.profile-nav a');\n navLinks.forEach(function(a) {\n if (a.getAttribute('href') === path || (path === '/telemetry' && a.id === 'nav-telemetry') || (path === '/' && a.id === 'nav-home')) {\n a.classList.add('active');\n }\n });\n\n function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }\n\n function loadProfiles() {\n fetch('/profiles/list').then(function(r) { return r.json(); }).then(function(data) {\n if (!data.profiles || data.profiles.length === 0) {\n profileBar.classList.remove('visible');\n return;\n }\n profileBar.classList.add('visible');\n var current = data.profiles.find(function(p) { return p.isActive; });\n profileSelect.innerHTML = data.profiles.map(function(p) {\n return '<option value=\"' + esc(p.id) + '\"' + (p.isActive ? ' selected' : '') + '>' + esc(p.id) + '</option>';\n }).join('');\n if (current) profileType.textContent = current.type;\n }).catch(function() {});\n }\n\n profileSelect.onchange = function() {\n fetch('/profiles/active', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ profile: profileSelect.value })\n }).then(function(r) { return r.json(); }).then(function(data) {\n if (data.success) {\n profileStatus.classList.add('show');\n clearTimeout(statusTimeout);\n statusTimeout = setTimeout(function() { profileStatus.classList.remove('show'); }, 2000);\n loadProfiles();\n }\n }).catch(function() {});\n };\n\n loadProfiles();\n setInterval(loadProfiles, 10000);\n})();\n\n</script>\n</body>\n</html>";
5
+ export declare const settingsPageHtml = "<!DOCTYPE html>\n<html lang=\"en\">\n<head>\n<meta charset=\"utf-8\">\n<meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n<title>Meridian \u2014 SDK Features</title>\n<link rel=\"icon\" type=\"image/svg+xml\" href=\"/telemetry/icon.svg\">\n<style>\n \n :root {\n /* Cool-gray neutral palette \u2014 matches the original dashboard/profiles/\n settings look. Better for data-dense dashboards: high contrast,\n surface/border separation, no color cast muddying the text. Purple\n accents are retained as secondary brand color for hover states,\n gradients, and a handful of telemetry badges. */\n --bg: #0d1117;\n --surface: #161b22;\n --surface2: #1c2128;\n --border: #30363d;\n /* Text */\n --text: #e6edf3;\n --muted: #8b949e;\n /* Brand \u2014 blue primary, purple secondary */\n --accent: #58a6ff;\n --accent2: #bc8cff;\n --violet: #bc8cff;\n --lavender: #d2a8ff;\n /* Semantic */\n --green: #3fb950;\n --yellow: #d29922;\n --red: #f85149;\n /* Telemetry-specific aliases (waterfall + lineage badges) */\n --blue: #58a6ff;\n --purple: #bc8cff;\n --queue: #d29922;\n --ttfb: #58a6ff;\n --upstream: #3fb950;\n }\n\n * { box-sizing: border-box; margin: 0; padding: 0; }\n body { font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Helvetica, Arial, sans-serif;\n background: var(--bg); color: var(--text); padding: 0; line-height: 1.5; }\n \n .meridian-profile-bar {\n position: sticky; top: 0; z-index: 100;\n display: none; align-items: center; gap: 12px;\n padding: 8px 24px;\n background: rgba(13, 17, 23, 0.92);\n backdrop-filter: blur(12px);\n border-bottom: 1px solid var(--border, #30363d);\n font-size: 12px;\n color: var(--muted, #8b949e);\n }\n .meridian-profile-bar.visible { display: flex; }\n .meridian-profile-bar .profile-label {\n font-weight: 500; text-transform: uppercase; letter-spacing: 0.5px;\n font-size: 10px; color: var(--muted, #8b949e);\n }\n .meridian-profile-bar select {\n background: var(--surface, #161b22); color: var(--text, #e6edf3);\n border: 1px solid var(--border, #30363d); border-radius: 6px;\n padding: 4px 24px 4px 10px; font-size: 12px; cursor: pointer;\n appearance: none;\n background-image: url(\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' viewBox='0 0 12 12'%3E%3Cpath d='M3 5l3 3 3-3' fill='none' stroke='%238b949e' stroke-width='1.5'/%3E%3C/svg%3E\");\n background-repeat: no-repeat; background-position: right 6px center;\n }\n .meridian-profile-bar select:hover { border-color: var(--accent, #58a6ff); }\n .meridian-profile-bar select:focus { outline: none; border-color: var(--accent, #58a6ff); box-shadow: 0 0 0 1px var(--accent, #58a6ff); }\n .meridian-profile-bar .profile-status {\n font-size: 11px; color: var(--green, #3fb950); opacity: 0;\n transition: opacity 0.3s;\n }\n .meridian-profile-bar .profile-status.show { opacity: 1; }\n .meridian-profile-bar .profile-type {\n font-size: 10px; padding: 2px 8px; border-radius: 4px;\n background: var(--surface, #161b22); border: 1px solid var(--border, #30363d);\n }\n .meridian-profile-bar .spacer { flex: 1; }\n .meridian-profile-bar .profile-nav a {\n color: var(--muted, #8b949e); text-decoration: none; font-size: 11px;\n padding: 4px 8px; border-radius: 4px; transition: color 0.15s;\n }\n .meridian-profile-bar .profile-nav a:hover { color: var(--text, #e6edf3); }\n .meridian-profile-bar .profile-nav a.active { color: var(--accent, #58a6ff); }\n\n .content { max-width: 900px; margin: 0 auto; padding: 24px; }\n h1 { font-size: 20px; font-weight: 600; margin-bottom: 4px; }\n .subtitle { color: var(--muted); font-size: 13px; margin-bottom: 24px; }\n .nav { display: flex; gap: 16px; margin-bottom: 24px; font-size: 13px; }\n .nav a { color: var(--muted); text-decoration: none; }\n .nav a:hover { color: var(--accent); }\n .nav a.active { color: var(--accent); }\n\n .adapter-card {\n background: var(--surface); border: 1px solid var(--border); border-radius: 8px;\n padding: 20px; margin-bottom: 16px;\n }\n .adapter-header {\n display: flex; align-items: center; justify-content: space-between;\n margin-bottom: 16px;\n }\n .adapter-name { font-size: 16px; font-weight: 600; }\n .adapter-badge {\n font-size: 10px; padding: 2px 8px; border-radius: 10px;\n text-transform: uppercase; letter-spacing: 0.5px;\n }\n .badge-active { background: rgba(63, 185, 80, 0.15); color: var(--green); }\n .badge-inactive { background: rgba(139, 148, 158, 0.15); color: var(--muted); }\n\n .feature-grid { display: grid; grid-template-columns: 1fr 1fr; gap: 12px; }\n @media (max-width: 600px) { .feature-grid { grid-template-columns: 1fr; } }\n\n .feature-row {\n display: flex; align-items: center; justify-content: space-between;\n padding: 10px 14px; border-radius: 6px;\n background: var(--bg); border: 1px solid var(--border);\n }\n .feature-info { display: flex; flex-direction: column; }\n .feature-label { font-size: 13px; font-weight: 500; }\n .feature-desc { font-size: 11px; color: var(--muted); margin-top: 2px; }\n\n /* Toggle switch */\n .toggle { position: relative; width: 36px; height: 20px; flex-shrink: 0; }\n .toggle input { opacity: 0; width: 0; height: 0; }\n .toggle-track {\n position: absolute; cursor: pointer; top: 0; left: 0; right: 0; bottom: 0;\n background: var(--border); border-radius: 10px; transition: background 0.2s;\n }\n .toggle-track::after {\n content: \"\"; position: absolute; height: 14px; width: 14px;\n left: 3px; bottom: 3px; background: var(--muted); border-radius: 50%;\n transition: transform 0.2s, background 0.2s;\n }\n .toggle input:checked + .toggle-track { background: var(--accent); }\n .toggle input:checked + .toggle-track::after {\n transform: translateX(16px); background: var(--text);\n }\n\n /* Select dropdown */\n .feature-select {\n background: var(--surface); color: var(--text); border: 1px solid var(--border);\n border-radius: 6px; padding: 4px 8px; font-size: 12px; cursor: pointer;\n }\n\n .save-indicator {\n position: fixed; bottom: 24px; right: 24px;\n background: var(--green); color: #000; padding: 8px 16px;\n border-radius: 6px; font-size: 13px; font-weight: 500;\n opacity: 0; transition: opacity 0.3s; pointer-events: none;\n }\n .save-indicator.visible { opacity: 1; }\n\n .reset-btn {\n background: none; border: 1px solid var(--border); color: var(--muted);\n border-radius: 6px; padding: 4px 12px; font-size: 11px; cursor: pointer;\n }\n .reset-btn:hover { border-color: var(--red); color: var(--red); }\n</style>\n</head>\n<body>\n\n<div class=\"meridian-profile-bar\" id=\"meridianProfileBar\">\n <span class=\"profile-label\">Profile</span>\n <select id=\"meridianProfileSelect\"></select>\n <span class=\"profile-type\" id=\"meridianProfileType\"></span>\n <span class=\"profile-status\" id=\"meridianProfileStatus\">\u2713 Switched</span>\n <div class=\"spacer\"></div>\n <div class=\"profile-nav\">\n <a href=\"/\" id=\"nav-home\">Home</a>\n <a href=\"/settings\" id=\"nav-settings\">Settings</a>\n <a href=\"/profiles\" id=\"nav-profiles\">Profiles</a>\n <a href=\"/telemetry\" id=\"nav-telemetry\">Telemetry</a>\n <a href=\"/plugins\" id=\"nav-plugins\">Plugins</a>\n </div>\n</div>\n\n<div class=\"content\">\n <h1>SDK Features <span style=\"font-size:11px;padding:2px 8px;border-radius:10px;background:rgba(210,153,34,0.15);color:var(--yellow);vertical-align:middle;margin-left:8px\">Experimental</span></h1>\n <p class=\"subtitle\" style=\"max-width:720px;line-height:1.6\">\n Unlock Claude Code features for any connected agent. Capabilities like auto-memory, dreaming, and CLAUDE.md \u2014 normally\n exclusive to Claude Code \u2014 become available to OpenCode, Crush, Droid, and any other harness routed through Meridian.\n Each agent keeps its own toolchain while gaining access to these additional features.<br><br>\n <strong style=\"color:var(--text)\">System prompts:</strong> For these features to work correctly, both the Claude Code prompt and your client prompt\n should be enabled. When both are active, they are appended together \u2014 Claude Code's base instructions come first,\n followed by your agent's specific instructions.\n </p>\n\n <div id=\"adapters\"></div>\n</div>\n\n<div class=\"save-indicator\" id=\"saveIndicator\">Saved</div>\n\n<script>\nconst FEATURES = [\n { key: 'codeSystemPrompt', label: 'Claude Code Prompt', desc: 'Include the built-in Claude Code system prompt (tool usage rules, safety guidelines, coding best practices)', type: 'toggle' },\n { key: 'clientSystemPrompt', label: 'Client Prompt', desc: 'Include the system prompt sent by the connecting agent (e.g. OpenCode or Crush instructions)', type: 'toggle' },\n { key: 'claudeMd', label: 'CLAUDE.md', desc: 'Load CLAUDE.md instruction files \u2014 Off: none, Project: ./CLAUDE.md only, Full: ~/.claude/CLAUDE.md + ./CLAUDE.md', type: 'select', options: ['off', 'project', 'full'] },\n { key: 'memory', label: 'Memory', desc: 'Read and write memories across sessions', type: 'toggle' },\n { key: 'dreaming', label: 'Auto-Dream', desc: 'Background memory consolidation', type: 'toggle' },\n { key: 'thinking', label: 'Thinking', desc: 'Extended thinking mode', type: 'select', options: ['disabled', 'adaptive', 'enabled'] },\n { key: 'thinkingPassthrough', label: 'Thinking Passthrough', desc: 'Forward thinking blocks to the client', type: 'toggle' },\n { key: 'sharedMemory', label: 'Shared Memory', desc: 'Share memory with Claude Code (~/.claude) instead of isolated storage', type: 'toggle' },\n { key: 'maxBudgetUsd', label: 'Max Budget (USD)', desc: 'Per-request cost cap \u2014 query aborts if exceeded (0 = disabled)', type: 'number' },\n { key: 'fallbackModel', label: 'Fallback Model', desc: 'Auto-fallback model if primary fails', type: 'select', options: ['', 'sonnet', 'opus', 'haiku', 'sonnet[1m]', 'opus[1m]'] },\n { key: 'sdkDebug', label: 'SDK Debug Logging', desc: 'Enable verbose SDK debug output to proxy stderr', type: 'toggle' },\n { key: 'additionalDirectories', label: 'Additional Directories', desc: 'Comma-separated extra paths Claude can access (monorepo libs, etc.)', type: 'text' },\n];\n\nconst ADAPTER_LABELS = {\n opencode: 'OpenCode',\n openai: 'OpenAI (/v1/chat/completions)',\n crush: 'Crush',\n forgecode: 'ForgeCode',\n pi: 'Pi',\n droid: 'Droid',\n passthrough: 'LiteLLM / Passthrough',\n};\n\nlet currentConfig = {};\n\nasync function loadConfig() {\n const res = await fetch('/settings/api/features');\n currentConfig = await res.json();\n render();\n}\n\nasync function saveFeature(adapter, key, value) {\n const patch = {};\n patch[key] = value;\n await fetch('/settings/api/features/' + adapter, {\n method: 'PATCH',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify(patch),\n });\n currentConfig[adapter][key] = value;\n showSaved();\n}\n\nasync function resetAdapter(adapter) {\n await fetch('/settings/api/features/' + adapter, { method: 'DELETE' });\n await loadConfig();\n showSaved();\n}\n\nfunction showSaved() {\n const el = document.getElementById('saveIndicator');\n el.classList.add('visible');\n setTimeout(() => el.classList.remove('visible'), 1500);\n}\n\nfunction hasAnyEnabled(features) {\n return features.codeSystemPrompt || !features.clientSystemPrompt || features.claudeMd !== 'off' || features.memory || features.dreaming ||\n features.thinking !== 'disabled' || features.thinkingPassthrough ||\n features.sharedMemory || features.maxBudgetUsd > 0 ||\n features.fallbackModel || features.sdkDebug ||\n features.additionalDirectories;\n}\n\nfunction render() {\n const container = document.getElementById('adapters');\n container.innerHTML = '';\n\n for (const [adapter, label] of Object.entries(ADAPTER_LABELS)) {\n const features = currentConfig[adapter] || {};\n const active = hasAnyEnabled(features);\n\n const card = document.createElement('div');\n card.className = 'adapter-card';\n card.innerHTML = '<div class=\"adapter-header\">' +\n '<span class=\"adapter-name\">' + label + '</span>' +\n '<div style=\"display:flex;gap:8px;align-items:center\">' +\n '<span class=\"adapter-badge ' + (active ? 'badge-active' : 'badge-inactive') + '\">' +\n (active ? 'Active' : 'Default') +\n '</span>' +\n '<button class=\"reset-btn\" onclick=\"resetAdapter(\\''+adapter+'\\')\">Reset</button>' +\n '</div>' +\n '</div>';\n\n const grid = document.createElement('div');\n grid.className = 'feature-grid';\n\n for (const feat of FEATURES) {\n const row = document.createElement('div');\n row.className = 'feature-row';\n\n const info = '<div class=\"feature-info\"><span class=\"feature-label\">' +\n feat.label + '</span><span class=\"feature-desc\">' + feat.desc + '</span></div>';\n\n if (feat.type === 'toggle') {\n const checked = features[feat.key] ? 'checked' : '';\n row.innerHTML = info +\n '<label class=\"toggle\"><input type=\"checkbox\" ' + checked +\n ' onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', this.checked)\">' +\n '<span class=\"toggle-track\"></span></label>';\n } else if (feat.type === 'select') {\n const options = feat.options.map(o => {\n const label = o === '' ? '(None)' : o.charAt(0).toUpperCase()+o.slice(1);\n return '<option value=\"'+o+'\"'+(features[feat.key]===o?' selected':'')+'>'+label+'</option>';\n }).join('');\n row.innerHTML = info +\n '<select class=\"feature-select\" onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', this.value)\">' +\n options + '</select>';\n } else if (feat.type === 'number') {\n const value = features[feat.key] ?? 0;\n row.innerHTML = info +\n '<input type=\"number\" class=\"feature-select\" style=\"width:80px;text-align:right\" min=\"0\" step=\"0.01\" value=\"'+value+'\"' +\n ' onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', parseFloat(this.value)||0)\">';\n } else if (feat.type === 'text') {\n const value = (features[feat.key] ?? '').toString().replace(/\"/g, '&quot;');\n row.innerHTML = info +\n '<input type=\"text\" class=\"feature-select\" style=\"width:180px\" value=\"'+value+'\"' +\n ' onchange=\"saveFeature(\\''+adapter+'\\', \\''+feat.key+'\\', this.value)\">';\n }\n\n grid.appendChild(row);\n }\n\n card.appendChild(grid);\n container.appendChild(card);\n }\n}\n\nloadConfig();\n\n(function() {\n var profileBar = document.getElementById('meridianProfileBar');\n var profileSelect = document.getElementById('meridianProfileSelect');\n var profileType = document.getElementById('meridianProfileType');\n var profileStatus = document.getElementById('meridianProfileStatus');\n var statusTimeout;\n\n // Highlight active nav link\n var path = location.pathname;\n var navLinks = document.querySelectorAll('.profile-nav a');\n navLinks.forEach(function(a) {\n if (a.getAttribute('href') === path || (path === '/telemetry' && a.id === 'nav-telemetry') || (path === '/' && a.id === 'nav-home')) {\n a.classList.add('active');\n }\n });\n\n function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }\n\n function loadProfiles() {\n fetch('/profiles/list').then(function(r) { return r.json(); }).then(function(data) {\n if (!data.profiles || data.profiles.length === 0) {\n profileBar.classList.remove('visible');\n return;\n }\n profileBar.classList.add('visible');\n var current = data.profiles.find(function(p) { return p.isActive; });\n profileSelect.innerHTML = data.profiles.map(function(p) {\n return '<option value=\"' + esc(p.id) + '\"' + (p.isActive ? ' selected' : '') + '>' + esc(p.id) + '</option>';\n }).join('');\n if (current) profileType.textContent = current.type;\n }).catch(function() {});\n }\n\n profileSelect.onchange = function() {\n fetch('/profiles/active', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({ profile: profileSelect.value })\n }).then(function(r) { return r.json(); }).then(function(data) {\n if (data.success) {\n profileStatus.classList.add('show');\n clearTimeout(statusTimeout);\n statusTimeout = setTimeout(function() { profileStatus.classList.remove('show'); }, 2000);\n loadProfiles();\n }\n }).catch(function() {});\n };\n\n loadProfiles();\n setInterval(loadProfiles, 10000);\n})();\n\n</script>\n</body>\n</html>";
6
6
  //# sourceMappingURL=settingsPage.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"settingsPage.d.ts","sourceRoot":"","sources":["../../src/telemetry/settingsPage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,gBAAgB,8nhBA8OrB,CAAA"}
1
+ {"version":3,"file":"settingsPage.d.ts","sourceRoot":"","sources":["../../src/telemetry/settingsPage.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAIH,eAAO,MAAM,gBAAgB,0qhBA+OrB,CAAA"}
@@ -10,7 +10,7 @@ import {
10
10
  serializeCredentials,
11
11
  startBackgroundRefresh,
12
12
  stopBackgroundRefresh
13
- } from "./cli-1kbcm3yn.js";
13
+ } from "./cli-aq5zz92m.js";
14
14
  import"./cli-p9swy5t3.js";
15
15
  export {
16
16
  stopBackgroundRefresh,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rynfar/meridian",
3
- "version": "1.45.2",
3
+ "version": "1.45.4",
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",