@rynfar/meridian 1.72.0 → 1.74.0
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.
- package/README.md +119 -107
- package/assets/banner.svg +18 -43
- package/assets/how-it-works.svg +40 -86
- package/assets/providers/README.md +10 -0
- package/assets/providers/antigravity.png +0 -0
- package/assets/providers/claude.png +0 -0
- package/dist/antigravity-clients/opencode.js +173 -0
- package/dist/antigravity-clients/pi.js +21 -0
- package/dist/antigravitySetup-35pd5xqn.js +191 -0
- package/dist/cli-1jstkdj9.js +30 -0
- package/dist/{cli-9e5cxp89.js → cli-2h3w5n6g.js} +163 -65
- package/dist/cli-3zwfvexc.js +56 -0
- package/dist/{cli-hxxy0m1z.js → cli-82e2m44k.js} +2 -1
- package/dist/cli-8sw5wr9j.js +136 -0
- package/dist/{cli-khhjyk04.js → cli-chsp880k.js} +214 -21
- package/dist/cli-dh0a1bw4.js +619 -0
- package/dist/cli-eehk3052.js +57 -0
- package/dist/{cli-ab7zkp1a.js → cli-fveyj34s.js} +32261 -18952
- package/dist/cli-grfp0s1j.js +330 -0
- package/dist/cli-qpfky8wy.js +133 -0
- package/dist/{cli-hj61zpt7.js → cli-wbsmhxcx.js} +26 -2
- package/dist/cli.js +111 -38
- package/dist/cliDashboard-c0dvkj4y.js +325 -0
- package/dist/configDir.d.ts +30 -0
- package/dist/configDir.d.ts.map +1 -0
- package/dist/organizationName-90f0atkn.js +29 -0
- package/dist/{pluginPage-f5gdmbxc.js → pluginPage-pp72d2j8.js} +1 -1
- package/dist/{profileCli-1eecbmgk.js → profileCli-1bfgc05h.js} +13 -3
- package/dist/{profilePage-mamej7kp.js → profilePage-vs319rvf.js} +252 -60
- package/dist/profileRename-4a4km6g8.js +22 -0
- package/dist/{profiles-wch9h234.js → profiles-0mp32ek9.js} +16 -3
- package/dist/proxy/adapterInstances.d.ts +1 -1
- package/dist/proxy/adapterInstances.d.ts.map +1 -1
- package/dist/proxy/adapters/claudecode.d.ts.map +1 -1
- package/dist/proxy/adapters/droid.d.ts.map +1 -1
- package/dist/proxy/auth.d.ts +2 -0
- package/dist/proxy/auth.d.ts.map +1 -1
- package/dist/proxy/authDiscovery.d.ts +52 -0
- package/dist/proxy/authDiscovery.d.ts.map +1 -0
- package/dist/proxy/backends/antigravity.d.ts +8 -0
- package/dist/proxy/backends/antigravity.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityAttachments.d.ts +16 -0
- package/dist/proxy/backends/antigravityAttachments.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityGrammar.d.ts +12 -0
- package/dist/proxy/backends/antigravityGrammar.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityJobs.d.ts +19 -0
- package/dist/proxy/backends/antigravityJobs.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityMedia.d.ts +9 -0
- package/dist/proxy/backends/antigravityMedia.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityNative.d.ts +8 -0
- package/dist/proxy/backends/antigravityNative.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityOpenai.d.ts +9 -0
- package/dist/proxy/backends/antigravityOpenai.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityOpenaiMedia.d.ts +9 -0
- package/dist/proxy/backends/antigravityOpenaiMedia.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityPlugins.d.ts +41 -0
- package/dist/proxy/backends/antigravityPlugins.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityProbe.d.ts +16 -0
- package/dist/proxy/backends/antigravityProbe.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityProcess.d.ts +4 -0
- package/dist/proxy/backends/antigravityProcess.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityProtocol.d.ts +582 -0
- package/dist/proxy/backends/antigravityProtocol.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityReplay.d.ts +41 -0
- package/dist/proxy/backends/antigravityReplay.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityResponses.d.ts +35 -0
- package/dist/proxy/backends/antigravityResponses.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityRuntime.d.ts +189 -0
- package/dist/proxy/backends/antigravityRuntime.d.ts.map +1 -0
- package/dist/proxy/backends/antigravitySchema.d.ts +10 -0
- package/dist/proxy/backends/antigravitySchema.d.ts.map +1 -0
- package/dist/proxy/backends/antigravitySessions.d.ts +28 -0
- package/dist/proxy/backends/antigravitySessions.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityState.d.ts +22 -0
- package/dist/proxy/backends/antigravityState.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityStops.d.ts +10 -0
- package/dist/proxy/backends/antigravityStops.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityTokens.d.ts +14 -0
- package/dist/proxy/backends/antigravityTokens.d.ts.map +1 -0
- package/dist/proxy/backends/antigravityUrl.d.ts +7 -0
- package/dist/proxy/backends/antigravityUrl.d.ts.map +1 -0
- package/dist/proxy/backends/providerStatus.d.ts +15 -0
- package/dist/proxy/backends/providerStatus.d.ts.map +1 -0
- package/dist/proxy/credentialsMode.d.ts +77 -0
- package/dist/proxy/credentialsMode.d.ts.map +1 -0
- package/dist/proxy/design.d.ts.map +1 -1
- package/dist/proxy/followActive.d.ts +262 -0
- package/dist/proxy/followActive.d.ts.map +1 -0
- package/dist/proxy/limitDetection.d.ts +110 -0
- package/dist/proxy/limitDetection.d.ts.map +1 -0
- package/dist/proxy/models.d.ts.map +1 -1
- package/dist/proxy/oauthPlan.d.ts +63 -0
- package/dist/proxy/oauthPlan.d.ts.map +1 -0
- package/dist/proxy/oauthUsage.d.ts +65 -2
- package/dist/proxy/oauthUsage.d.ts.map +1 -1
- package/dist/proxy/openai.d.ts +6 -2
- package/dist/proxy/openai.d.ts.map +1 -1
- package/dist/proxy/organizationName.d.ts +71 -0
- package/dist/proxy/organizationName.d.ts.map +1 -0
- package/dist/proxy/passthroughEarlyStop.d.ts +10 -0
- package/dist/proxy/passthroughEarlyStop.d.ts.map +1 -1
- package/dist/proxy/planAllowance.d.ts +75 -0
- package/dist/proxy/planAllowance.d.ts.map +1 -0
- package/dist/proxy/probes.d.ts +85 -0
- package/dist/proxy/probes.d.ts.map +1 -0
- package/dist/proxy/profileCli.d.ts +53 -1
- package/dist/proxy/profileCli.d.ts.map +1 -1
- package/dist/proxy/profileHealth.d.ts +127 -0
- package/dist/proxy/profileHealth.d.ts.map +1 -0
- package/dist/proxy/profileRename.d.ts +83 -0
- package/dist/proxy/profileRename.d.ts.map +1 -0
- package/dist/proxy/profiles.d.ts +72 -6
- package/dist/proxy/profiles.d.ts.map +1 -1
- package/dist/proxy/query.d.ts +7 -0
- package/dist/proxy/query.d.ts.map +1 -1
- package/dist/proxy/routing.d.ts +59 -1
- package/dist/proxy/routing.d.ts.map +1 -1
- package/dist/proxy/sdkFeatures.d.ts +1 -1
- package/dist/proxy/sdkFeatures.d.ts.map +1 -1
- package/dist/proxy/server.d.ts.map +1 -1
- package/dist/proxy/session/fingerprint.d.ts +5 -0
- package/dist/proxy/session/fingerprint.d.ts.map +1 -1
- package/dist/proxy/session/lineage.d.ts.map +1 -1
- package/dist/proxy/setup.d.ts.map +1 -1
- package/dist/proxy/supervision.d.ts +41 -0
- package/dist/proxy/supervision.d.ts.map +1 -0
- package/dist/proxy/tokenRefresh.d.ts +38 -4
- package/dist/proxy/tokenRefresh.d.ts.map +1 -1
- package/dist/proxy/types.d.ts +32 -0
- package/dist/proxy/types.d.ts.map +1 -1
- package/dist/server.js +11 -7
- package/dist/settings.d.ts +83 -0
- package/dist/settings.d.ts.map +1 -0
- package/dist/{setup-ndmjpy23.js → setup-7fr49z92.js} +1 -1
- package/dist/statusProbe-9x9q261e.js +151 -0
- package/dist/telemetry/dashboard.d.ts.map +1 -1
- package/dist/telemetry/index.d.ts +20 -2
- package/dist/telemetry/index.d.ts.map +1 -1
- package/dist/telemetry/landing.d.ts +1 -1
- package/dist/telemetry/landing.d.ts.map +1 -1
- package/dist/telemetry/logStore.d.ts +11 -0
- package/dist/telemetry/logStore.d.ts.map +1 -1
- package/dist/telemetry/pricingStore.d.ts +2 -2
- package/dist/telemetry/pricingStore.d.ts.map +1 -1
- package/dist/telemetry/profileBar.d.ts +3 -3
- package/dist/telemetry/profileBar.d.ts.map +1 -1
- package/dist/telemetry/profileFacts.d.ts +17 -0
- package/dist/telemetry/profileFacts.d.ts.map +1 -0
- package/dist/telemetry/profileOrder.d.ts +68 -0
- package/dist/telemetry/profileOrder.d.ts.map +1 -0
- package/dist/telemetry/profilePage.d.ts.map +1 -1
- package/dist/telemetry/profileSort.d.ts +35 -0
- package/dist/telemetry/profileSort.d.ts.map +1 -0
- package/dist/telemetry/profileSpent.d.ts +68 -0
- package/dist/telemetry/profileSpent.d.ts.map +1 -0
- package/dist/telemetry/providerPage.d.ts +2 -0
- package/dist/telemetry/providerPage.d.ts.map +1 -0
- package/dist/telemetry/providerSetup.d.ts +5 -0
- package/dist/telemetry/providerSetup.d.ts.map +1 -0
- package/dist/telemetry/providerView.d.ts +45 -0
- package/dist/telemetry/providerView.d.ts.map +1 -0
- package/dist/telemetry/routeChain.d.ts +32 -0
- package/dist/telemetry/routeChain.d.ts.map +1 -0
- package/dist/telemetry/routes.d.ts.map +1 -1
- package/dist/telemetry/settingsPage.d.ts +1 -1
- package/dist/telemetry/settingsPage.d.ts.map +1 -1
- package/dist/telemetry/sqlite.d.ts.map +1 -1
- package/dist/telemetry/store.d.ts +6 -1
- package/dist/telemetry/store.d.ts.map +1 -1
- package/dist/telemetry/types.d.ts +132 -2
- package/dist/telemetry/types.d.ts.map +1 -1
- package/dist/{tokenRefresh-kzz08kea.js → tokenRefresh-eg9h83wd.js} +6 -1
- package/package.json +11 -4
- package/dist/cli-5jxyma6z.js +0 -277
- package/dist/cli-vj9cv18n.js +0 -38
- package/dist/proxy/settings.d.ts +0 -30
- package/dist/proxy/settings.d.ts.map +0 -1
|
@@ -1,29 +1,23 @@
|
|
|
1
|
+
import {
|
|
2
|
+
WINDOW_LABELS
|
|
3
|
+
} from "./cli-3zwfvexc.js";
|
|
4
|
+
import {
|
|
5
|
+
profileFactsJs,
|
|
6
|
+
reorderClientJs,
|
|
7
|
+
reorderCss,
|
|
8
|
+
reorderLiveRegionHtml
|
|
9
|
+
} from "./cli-grfp0s1j.js";
|
|
1
10
|
import {
|
|
2
11
|
init_profileBar,
|
|
3
12
|
profileBarCss,
|
|
4
13
|
profileBarHtml,
|
|
5
14
|
profileBarJs,
|
|
6
15
|
themeCss
|
|
7
|
-
} from "./cli-
|
|
16
|
+
} from "./cli-wbsmhxcx.js";
|
|
8
17
|
import"./cli-p9swy5t3.js";
|
|
9
18
|
|
|
10
19
|
// src/telemetry/profilePage.ts
|
|
11
20
|
init_profileBar();
|
|
12
|
-
|
|
13
|
-
// src/telemetry/profileUsage.ts
|
|
14
|
-
var WINDOW_LABELS = {
|
|
15
|
-
five_hour: "5h",
|
|
16
|
-
seven_day: "7d",
|
|
17
|
-
seven_day_opus: "7d Opus",
|
|
18
|
-
seven_day_sonnet: "7d Sonnet",
|
|
19
|
-
seven_day_fable: "7d Fable",
|
|
20
|
-
seven_day_oauth_apps: "7d Apps",
|
|
21
|
-
seven_day_cowork: "7d Cowork",
|
|
22
|
-
seven_day_omelette: "7d Omelette"
|
|
23
|
-
};
|
|
24
|
-
var SEVEN_DAYS_MS = 7 * 86400000;
|
|
25
|
-
|
|
26
|
-
// src/telemetry/profilePage.ts
|
|
27
21
|
var profilePageHtml = `<!DOCTYPE html>
|
|
28
22
|
<html lang="en">
|
|
29
23
|
<head>
|
|
@@ -48,18 +42,40 @@ var profilePageHtml = `<!DOCTYPE html>
|
|
|
48
42
|
}
|
|
49
43
|
.profile-card.active { border-color: var(--accent); }
|
|
50
44
|
.profile-card-header { display: flex; align-items: center; gap: 12px; margin-bottom: 12px; }
|
|
45
|
+
${reorderCss}
|
|
51
46
|
.profile-name { font-size: 16px; font-weight: 600; }
|
|
47
|
+
.profile-card-actions { margin-left: auto; display: flex; align-items: center; gap: 6px; }
|
|
48
|
+
.icon-btn {
|
|
49
|
+
background: var(--bg); color: var(--muted); border: 1px solid var(--border);
|
|
50
|
+
border-radius: 4px; padding: 4px 6px; cursor: pointer; display: inline-flex;
|
|
51
|
+
align-items: center; transition: all 0.15s;
|
|
52
|
+
}
|
|
53
|
+
.icon-btn:hover { border-color: var(--accent); color: var(--accent); }
|
|
54
|
+
.rename-input {
|
|
55
|
+
background: var(--surface2); color: var(--text); border: 1px solid var(--accent);
|
|
56
|
+
border-radius: 6px; padding: 4px 8px; font-size: 14px; font-weight: 600;
|
|
57
|
+
font-family: 'SF Mono', SFMono-Regular, Consolas, monospace; width: 200px;
|
|
58
|
+
}
|
|
59
|
+
.rename-input:focus { outline: none; }
|
|
60
|
+
.rename-hint { font-size: 11px; color: var(--muted); }
|
|
61
|
+
.rename-error { font-size: 12px; color: var(--red); margin-bottom: 12px; }
|
|
52
62
|
.profile-badge {
|
|
53
63
|
font-size: 10px; padding: 2px 8px; border-radius: 4px; text-transform: uppercase;
|
|
54
64
|
letter-spacing: 0.5px; font-weight: 500;
|
|
55
65
|
}
|
|
56
66
|
.badge-active { background: rgba(88,166,255,0.15); color: var(--accent); }
|
|
57
67
|
.badge-type { background: var(--bg); color: var(--muted); border: 1px solid var(--border); }
|
|
68
|
+
.badge-spent { background: rgba(248,81,73,0.15); color: var(--red); border: 1px solid rgba(248,81,73,0.35); }
|
|
69
|
+
.spent-note { margin: 10px 0; padding: 10px 14px; border-radius: 8px; font-size: 12px; line-height: 1.5;
|
|
70
|
+
background: rgba(248,81,73,0.08); border: 1px solid rgba(248,81,73,0.3); color: var(--text); }
|
|
71
|
+
.spent-note .spent-why { color: var(--muted); }
|
|
58
72
|
.profile-details {
|
|
59
73
|
display: grid; grid-template-columns: 120px 1fr; gap: 6px 16px; font-size: 13px;
|
|
60
74
|
}
|
|
61
75
|
.detail-label { color: var(--muted); }
|
|
62
76
|
.detail-value { font-family: 'SF Mono', SFMono-Regular, Consolas, monospace; font-size: 12px; }
|
|
77
|
+
.cached-tag { color: var(--muted); font-size: 10px; font-style: italic; margin-left: 6px; white-space: nowrap; }
|
|
78
|
+
.detail-unknown { color: var(--muted); font-style: italic; }
|
|
63
79
|
.status-ok { color: var(--green); }
|
|
64
80
|
.status-err { color: var(--red); }
|
|
65
81
|
.switch-btn {
|
|
@@ -115,6 +131,7 @@ var profilePageHtml = `<!DOCTYPE html>
|
|
|
115
131
|
margin-bottom: 10px; display: flex; align-items: center; gap: 8px;
|
|
116
132
|
}
|
|
117
133
|
.usage-as-of { font-size: 10px; color: var(--muted); text-transform: none; letter-spacing: 0; opacity: 0.7; }
|
|
134
|
+
.usage-stale-note { font-size: 11px; color: var(--yellow); line-height: 1.4; margin: -2px 0 10px; }
|
|
118
135
|
.usage-grid {
|
|
119
136
|
display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr));
|
|
120
137
|
gap: 8px;
|
|
@@ -159,6 +176,7 @@ var profilePageHtml = `<!DOCTYPE html>
|
|
|
159
176
|
<div class="subtitle">Manage Claude account profiles</div>
|
|
160
177
|
|
|
161
178
|
<div id="content"><div style="color:var(--muted);padding:40px;text-align:center">Loading…</div></div>
|
|
179
|
+
${reorderLiveRegionHtml}
|
|
162
180
|
|
|
163
181
|
<div class="section" style="margin-top:32px">
|
|
164
182
|
<div class="section-title">Setup Guide</div>
|
|
@@ -195,13 +213,20 @@ var profilePageHtml = `<!DOCTYPE html>
|
|
|
195
213
|
<div style="font-size:13px;margin-top:8px">
|
|
196
214
|
<code>meridian profile list</code> — show all profiles and auth status<br>
|
|
197
215
|
<code>meridian profile login <name></code> — re-authenticate an expired profile<br>
|
|
216
|
+
<code>meridian profile rename <old> <new></code> — rename a profile (or use the pencil above)<br>
|
|
198
217
|
<code>meridian profile remove <name></code> — remove a profile
|
|
199
218
|
</div>
|
|
219
|
+
<p style="font-size:13px;color:var(--muted);margin-top:12px">
|
|
220
|
+
Renaming keeps the old name working: requests still naming it are served by
|
|
221
|
+
the renamed profile, so nothing breaks mid-flight. That redirect is dropped
|
|
222
|
+
as soon as the old name is taken again by a new profile.
|
|
223
|
+
</p>
|
|
200
224
|
</div>
|
|
201
225
|
</div>
|
|
202
226
|
</div>
|
|
203
227
|
|
|
204
228
|
<script>
|
|
229
|
+
` + profileFactsJs + `
|
|
205
230
|
// Inlined from src/telemetry/profileUsage.ts. The TS source is unit-tested
|
|
206
231
|
// (see profile-usage.test.ts) and the labels object is interpolated here so
|
|
207
232
|
// the browser script and TS module share their data.
|
|
@@ -252,15 +277,80 @@ function formatExtraUsage(eu) {
|
|
|
252
277
|
};
|
|
253
278
|
}
|
|
254
279
|
|
|
280
|
+
${reorderClientJs}
|
|
281
|
+
|
|
255
282
|
// Cache the last seen quota response so the /profiles/list refresh can
|
|
256
283
|
// keep showing usage even if a single /v1/usage/quota/all call fails.
|
|
257
284
|
var lastQuota = null;
|
|
285
|
+
// Last profile payload, so a rename can redraw from cache without refetching.
|
|
286
|
+
var lastProfiles = null;
|
|
287
|
+
// Profile whose name is being edited in place, and the error from the last
|
|
288
|
+
// rejected attempt. While editing, the poll is suspended — it rewrites
|
|
289
|
+
// innerHTML, which would blank the input mid-keystroke.
|
|
290
|
+
var editingProfile = null;
|
|
291
|
+
var renameError = null;
|
|
292
|
+
|
|
293
|
+
var ICON_PENCIL = '<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M11.013 1.427a1.75 1.75 0 012.474 0l1.086 1.086a1.75 1.75 0 010 2.474l-8.61 8.61c-.21.21-.47.364-.756.445l-3.251.93a.75.75 0 01-.927-.928l.929-3.25c.081-.286.235-.547.445-.758l8.61-8.61zm1.414 1.06a.25.25 0 00-.354 0L10.811 3.75l1.439 1.44 1.263-1.263a.25.25 0 000-.354l-1.086-1.086zM11.189 6.25L9.75 4.81l-6.286 6.287a.25.25 0 00-.064.108l-.558 1.953 1.953-.558a.249.249 0 00.108-.064l6.286-6.286z"/></svg>';
|
|
294
|
+
var ICON_CHECK = '<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M13.78 4.22a.75.75 0 010 1.06l-7.25 7.25a.75.75 0 01-1.06 0L2.22 9.28a.75.75 0 011.06-1.06L6 10.94l6.72-6.72a.75.75 0 011.06 0z"/></svg>';
|
|
295
|
+
var ICON_X = '<svg width="14" height="14" viewBox="0 0 16 16" fill="currentColor"><path d="M3.72 3.72a.75.75 0 011.06 0L8 6.94l3.22-3.22a.75.75 0 111.06 1.06L9.06 8l3.22 3.22a.75.75 0 11-1.06 1.06L8 9.06l-3.22 3.22a.75.75 0 01-1.06-1.06L6.94 8 3.72 4.78a.75.75 0 010-1.06z"/></svg>';
|
|
296
|
+
|
|
297
|
+
function focusRenameInput() {
|
|
298
|
+
var el = document.getElementById('rename-input');
|
|
299
|
+
if (el) { el.focus(); el.select(); }
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
function redraw() {
|
|
303
|
+
if (lastProfiles) render(lastProfiles, lastQuota);
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
function startRename(id) {
|
|
307
|
+
editingProfile = id;
|
|
308
|
+
renameError = null;
|
|
309
|
+
redraw();
|
|
310
|
+
focusRenameInput();
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
function cancelRename() {
|
|
314
|
+
editingProfile = null;
|
|
315
|
+
renameError = null;
|
|
316
|
+
redraw();
|
|
317
|
+
}
|
|
318
|
+
|
|
319
|
+
async function commitRename(from) {
|
|
320
|
+
var input = document.getElementById('rename-input');
|
|
321
|
+
if (!input) return;
|
|
322
|
+
var to = input.value.trim();
|
|
323
|
+
if (!to || to === from) { cancelRename(); return; }
|
|
324
|
+
var data;
|
|
325
|
+
try {
|
|
326
|
+
var res = await fetch('/profiles/rename', {
|
|
327
|
+
method: 'POST',
|
|
328
|
+
headers: { 'Content-Type': 'application/json' },
|
|
329
|
+
body: JSON.stringify({ from: from, to: to })
|
|
330
|
+
});
|
|
331
|
+
data = await res.json();
|
|
332
|
+
} catch (err) {
|
|
333
|
+
data = { error: 'Could not reach Meridian.' };
|
|
334
|
+
}
|
|
335
|
+
if (data && data.success) {
|
|
336
|
+
editingProfile = null;
|
|
337
|
+
renameError = null;
|
|
338
|
+
await refresh();
|
|
339
|
+
if (window.meridianHeaderRefresh) window.meridianHeaderRefresh();
|
|
340
|
+
return;
|
|
341
|
+
}
|
|
342
|
+
renameError = (data && data.error) || 'Rename failed.';
|
|
343
|
+
redraw();
|
|
344
|
+
focusRenameInput();
|
|
345
|
+
}
|
|
258
346
|
|
|
259
347
|
async function refresh() {
|
|
348
|
+
if (editingProfile) return;
|
|
260
349
|
try {
|
|
261
|
-
var [profilesRes, quotaRes] = await Promise.all([
|
|
350
|
+
var [profilesRes, quotaRes, routingRes] = await Promise.all([
|
|
262
351
|
fetch('/profiles/list'),
|
|
263
352
|
fetch('/v1/usage/quota/all').catch(function () { return null; }),
|
|
353
|
+
fetch('/settings/api/routing').catch(function () { return null; }),
|
|
264
354
|
]);
|
|
265
355
|
var profiles = await profilesRes.json();
|
|
266
356
|
var quota = null;
|
|
@@ -268,6 +358,10 @@ async function refresh() {
|
|
|
268
358
|
try { quota = await quotaRes.json(); } catch (_) { quota = null; }
|
|
269
359
|
}
|
|
270
360
|
if (quota) lastQuota = quota;
|
|
361
|
+
if (routingRes && routingRes.ok) {
|
|
362
|
+
try { meridianReorder.adopt(await routingRes.json()); } catch (_) { /* keep the last good order */ }
|
|
363
|
+
}
|
|
364
|
+
lastProfiles = profiles;
|
|
271
365
|
render(profiles, lastQuota);
|
|
272
366
|
} catch {
|
|
273
367
|
document.getElementById('content').innerHTML = '<div class="empty-state"><h2>Could not load profiles</h2><p>Is Meridian running?</p></div>';
|
|
@@ -276,6 +370,88 @@ async function refresh() {
|
|
|
276
370
|
|
|
277
371
|
function esc(s) { var d = document.createElement('div'); d.textContent = s; return d.innerHTML; }
|
|
278
372
|
|
|
373
|
+
function factRows(facts) {
|
|
374
|
+
return facts.map(function (f) {
|
|
375
|
+
var tone = f.tone === 'ok' ? ' status-ok' : f.tone === 'err' ? ' status-err' : '';
|
|
376
|
+
var title = f.title ? ' title="' + esc(f.title) + '"' : '';
|
|
377
|
+
var cached = f.cached ? ' <span class="cached-tag">(cached)</span>' : '';
|
|
378
|
+
return '<span class="detail-label">' + esc(f.label) + '</span>'
|
|
379
|
+
+ '<span class="detail-value' + tone + '"' + title + '>' + esc(f.value) + cached + '</span>';
|
|
380
|
+
}).join('');
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
// Mirrors src/telemetry/cachedFacts.ts (unit-tested there). Marked per value
|
|
384
|
+
// rather than per card: a card mixes a live status with a remembered email, so
|
|
385
|
+
// one banner across it would mislabel whichever half it doesn't apply to.
|
|
386
|
+
function factProvenance(value, stale) {
|
|
387
|
+
if (value == null || value === '') return 'never';
|
|
388
|
+
return stale ? 'cached' : 'live';
|
|
389
|
+
}
|
|
390
|
+
function cachedTag(provenance) {
|
|
391
|
+
return provenance === 'cached' ? '<span class="cached-tag">(cached)</span>' : '';
|
|
392
|
+
}
|
|
393
|
+
function renderFactValue(value, stale, extraClass) {
|
|
394
|
+
var provenance = factProvenance(value, stale);
|
|
395
|
+
if (provenance === 'never' && !stale) return null;
|
|
396
|
+
var classes = 'detail-value' + (extraClass ? ' ' + extraClass : '');
|
|
397
|
+
if (provenance === 'never') {
|
|
398
|
+
return '<span class="' + classes + ' detail-unknown">never read</span>';
|
|
399
|
+
}
|
|
400
|
+
return '<span class="' + classes + '">' + esc(String(value)) + cachedTag(provenance) + '</span>';
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
// "last 4 checks failed (rate limited upstream)" — the run of failed checks
|
|
404
|
+
// since the last good reading, or '' when the last check succeeded. Reasons map
|
|
405
|
+
// through a fixed vocabulary rather than being echoed, so nothing the server
|
|
406
|
+
// sends reaches the DOM.
|
|
407
|
+
function describeFailedRun(failure) {
|
|
408
|
+
if (!failure) return '';
|
|
409
|
+
var why = failure.reason === 'rate_limited' ? 'rate limited upstream'
|
|
410
|
+
: failure.reason === 'no_token' ? 'no credentials readable'
|
|
411
|
+
: 'usage endpoint unavailable';
|
|
412
|
+
var n = Math.floor(Number(failure.consecutiveFailures));
|
|
413
|
+
if (!isFinite(n) || n < 1) n = 1;
|
|
414
|
+
return (n > 1 ? 'last ' + n + ' checks failed' : 'last check failed') + ' (' + why + ')';
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// A refusal and the cached percentages are different kinds of fact, so they
|
|
418
|
+
// are rendered as different things: the badge states what the API is doing
|
|
419
|
+
// now, the bars below stay as the last successful read. Measured: an account
|
|
420
|
+
// showed 5h 67% / 7d 7% while every request through it was refused.
|
|
421
|
+
function spentSummary(spent) {
|
|
422
|
+
if (!spent) return null;
|
|
423
|
+
var bucket = spent.diagnosis && spent.diagnosis.bucket
|
|
424
|
+
? labelForWindow(spent.diagnosis.bucket)
|
|
425
|
+
: 'unknown limit';
|
|
426
|
+
var reported = !!(spent.diagnosis && spent.diagnosis.reported);
|
|
427
|
+
var reset = formatResetCountdown(spent.until);
|
|
428
|
+
return {
|
|
429
|
+
bucket: bucket,
|
|
430
|
+
reported: reported,
|
|
431
|
+
label: bucket + (reported ? '' : ' (guess)'),
|
|
432
|
+
reset: reset,
|
|
433
|
+
why: (spent.diagnosis && spent.diagnosis.rationale) || '',
|
|
434
|
+
at: spent.at,
|
|
435
|
+
};
|
|
436
|
+
}
|
|
437
|
+
|
|
438
|
+
function renderSpentBadge(spent) {
|
|
439
|
+
var s = spentSummary(spent);
|
|
440
|
+
if (!s) return '';
|
|
441
|
+
return '<span class="profile-badge badge-spent" title="' + esc(s.why) + '">out of ' + esc(s.label) + '</span>';
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
function renderSpentNote(spent) {
|
|
445
|
+
var s = spentSummary(spent);
|
|
446
|
+
if (!s) return '';
|
|
447
|
+
return '<div class="spent-note">'
|
|
448
|
+
+ '<strong style="color:var(--red)">⚠ Anthropic is refusing this account</strong> - '
|
|
449
|
+
+ 'out of <strong>' + esc(s.label) + '</strong>'
|
|
450
|
+
+ (s.reset ? ', expected back ' + esc(s.reset) : '')
|
|
451
|
+
+ '. Refused ' + esc(timeAgo(s.at)) + '.'
|
|
452
|
+
+ '<div class="spent-why">' + esc(s.why) + '. The percentages below are the last successful read, not live.</div>'
|
|
453
|
+
+ '</div>';
|
|
454
|
+
|
|
279
455
|
function renderUsageSection(profileQuota) {
|
|
280
456
|
// No quota data for this profile yet (cold start or fetch failed) — hide
|
|
281
457
|
// entirely so we don't render an empty box.
|
|
@@ -288,6 +464,13 @@ function renderUsageSection(profileQuota) {
|
|
|
288
464
|
});
|
|
289
465
|
var extra = formatExtraUsage(profileQuota.extraUsage);
|
|
290
466
|
|
|
467
|
+
var failedRun = describeFailedRun(profileQuota.failure);
|
|
468
|
+
var usageTag = cachedTag(profileQuota.stale ? 'cached' : 'live');
|
|
469
|
+
|
|
470
|
+
// No figures at all means this profile has never been read successfully —
|
|
471
|
+
// the route serves the last good reading at any age, so an empty windows
|
|
472
|
+
// array is no longer "the stale window lapsed". Saying so keeps it distinct
|
|
473
|
+
// from a profile genuinely sitting at 0%.
|
|
291
474
|
if (windows.length === 0 && !extra) {
|
|
292
475
|
if (profileQuota.error === 'no_token') {
|
|
293
476
|
return '<div class="usage-section">'
|
|
@@ -296,12 +479,13 @@ function renderUsageSection(profileQuota) {
|
|
|
296
479
|
+ '</div>';
|
|
297
480
|
}
|
|
298
481
|
// Credentials are fine here — Anthropic is throttling the usage endpoint
|
|
299
|
-
// and
|
|
300
|
-
// would send the user chasing a problem they don't have.
|
|
482
|
+
// and there has never been a reading to fall back on. Saying "run claude
|
|
483
|
+
// login" would send the user chasing a problem they don't have.
|
|
301
484
|
if (profileQuota.error === 'rate_limited') {
|
|
302
485
|
return '<div class="usage-section">'
|
|
303
486
|
+ '<div class="usage-section-title">Usage</div>'
|
|
304
|
-
+ '<div class="usage-empty">
|
|
487
|
+
+ '<div class="usage-empty">No reading yet — '
|
|
488
|
+
+ esc(failedRun || 'rate limited upstream') + ', retrying.</div>'
|
|
305
489
|
+ '</div>';
|
|
306
490
|
}
|
|
307
491
|
return ''; // nothing fetched yet
|
|
@@ -311,6 +495,15 @@ function renderUsageSection(profileQuota) {
|
|
|
311
495
|
? '<span class="usage-as-of">updated ' + timeAgo(profileQuota.fetchedAt) + '</span>'
|
|
312
496
|
: '';
|
|
313
497
|
|
|
498
|
+
// Figures are only ever this old because a later check failed, so the note
|
|
499
|
+
// and the "updated Xm ago" beside the title answer the two halves of the
|
|
500
|
+
// same question: how old these numbers are, and why they haven't moved.
|
|
501
|
+
var staleNote = failedRun
|
|
502
|
+
? '<div class="usage-stale-note">'
|
|
503
|
+
+ esc(failedRun.charAt(0).toUpperCase() + failedRun.slice(1))
|
|
504
|
+
+ ' — figures below are the last successful read.</div>'
|
|
505
|
+
: '';
|
|
506
|
+
|
|
314
507
|
var cards = windows.map(function (w) {
|
|
315
508
|
var pct = Math.max(0, Math.min(1, w.utilization));
|
|
316
509
|
var pctRound = Math.round(pct * 100);
|
|
@@ -321,7 +514,7 @@ function renderUsageSection(profileQuota) {
|
|
|
321
514
|
return '<div class="usage-card status-' + esc(status) + '" title="' + esc(tip) + '">'
|
|
322
515
|
+ '<div class="usage-row">'
|
|
323
516
|
+ '<span class="usage-label">' + esc(label) + '</span>'
|
|
324
|
-
+ '<span class="usage-pct">' + pctRound + '
|
|
517
|
+
+ '<span class="usage-pct">' + pctRound + '%' + usageTag + '</span>'
|
|
325
518
|
+ '</div>'
|
|
326
519
|
+ '<div class="usage-bar"><div class="usage-fill" style="width:' + (pct * 100).toFixed(1) + '%"></div></div>'
|
|
327
520
|
+ (reset ? '<div class="usage-reset">' + esc(reset) + '</div>' : '')
|
|
@@ -333,7 +526,7 @@ function renderUsageSection(profileQuota) {
|
|
|
333
526
|
extraBlock = '<div class="usage-extra status-' + esc(extra.status) + '">'
|
|
334
527
|
+ '<div class="usage-extra-row">'
|
|
335
528
|
+ '<span class="usage-label">Extra usage</span>'
|
|
336
|
-
+ '<span class="usage-pct">' + extra.utilizationPct + '
|
|
529
|
+
+ '<span class="usage-pct">' + extra.utilizationPct + '%' + usageTag + '</span>'
|
|
337
530
|
+ '</div>'
|
|
338
531
|
+ '<div class="usage-bar"><div class="usage-fill" style="width:' + extra.utilizationPct + '%"></div></div>'
|
|
339
532
|
+ '<div class="usage-extra-row" style="margin-top:4px">'
|
|
@@ -344,14 +537,16 @@ function renderUsageSection(profileQuota) {
|
|
|
344
537
|
|
|
345
538
|
return '<div class="usage-section">'
|
|
346
539
|
+ '<div class="usage-section-title">Usage' + asOf + '</div>'
|
|
540
|
+
+ staleNote
|
|
347
541
|
+ (cards ? '<div class="usage-grid">' + cards + '</div>' : '')
|
|
348
542
|
+ extraBlock
|
|
349
543
|
+ '</div>';
|
|
350
544
|
}
|
|
351
545
|
|
|
352
546
|
function render(data, quotaData) {
|
|
353
|
-
const profiles = data.profiles || [];
|
|
547
|
+
const profiles = meridianReorder.sortProfiles(data.profiles || []);
|
|
354
548
|
const active = data.activeProfile;
|
|
549
|
+
const refocusId = meridianReorder.focusAnchor();
|
|
355
550
|
// Build quick lookup: profileId -> per-profile quota entry from
|
|
356
551
|
// /v1/usage/quota/all. Endpoint may be unavailable (older Meridian)
|
|
357
552
|
// or have errored — in that case quotaById is empty and the per-card
|
|
@@ -371,39 +566,43 @@ function render(data, quotaData) {
|
|
|
371
566
|
return;
|
|
372
567
|
}
|
|
373
568
|
|
|
569
|
+
const reorderable = profiles.length > 1 && !meridianReorder.envPinned();
|
|
570
|
+
|
|
374
571
|
let html = '<div class="section"><div class="section-title">Configured Profiles</div>';
|
|
572
|
+
if (profiles.length > 1) html += meridianReorder.noteHtml(reorderable);
|
|
375
573
|
|
|
376
|
-
for (
|
|
574
|
+
for (let idx = 0; idx < profiles.length; idx++) {
|
|
575
|
+
const p = profiles[idx];
|
|
377
576
|
const isActive = p.id === active;
|
|
378
|
-
html += '<div class="profile-card' + (isActive ? ' active' : '') + '">';
|
|
577
|
+
html += '<div class="profile-card' + (isActive ? ' active' : '') + '" data-id="' + esc(p.id) + '" data-index="' + idx + '">';
|
|
379
578
|
html += '<div class="profile-card-header">';
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
579
|
+
if (editingProfile === p.id) {
|
|
580
|
+
html += "<input class="rename-input" id="rename-input" value="" + esc(p.id) + "" spellcheck="false" autocomplete="off""
|
|
581
|
+
+ " onkeydown="if(event.key==="Enter"){event.preventDefault();commitRename("" + esc(p.id) + "")}"
|
|
582
|
+
+ "else if(event.key==="Escape"){cancelRename()}">";
|
|
583
|
+
html += "<span class="rename-hint">Enter to save · Esc to cancel</span>";
|
|
584
|
+
html += "<span class="profile-card-actions">";
|
|
585
|
+
html += "<button class="icon-btn" title="Save new name" onclick="commitRename(""+esc(p.id)+"")">" + ICON_CHECK + "</button>";
|
|
586
|
+
html += "<button class="icon-btn" title="Cancel" onclick="cancelRename()">" + ICON_X + "</button>";
|
|
587
|
+
html += "</span>";
|
|
588
|
+
} else {
|
|
589
|
+
if (reorderable) html += meridianReorder.handleHtml(p.id, idx, profiles.length);
|
|
590
|
+
html += "<span class="profile-name">" + esc(p.id) + "</span>";
|
|
591
|
+
if (isActive) html += "<span class="profile-badge badge-active">active</span>";
|
|
592
|
+
html += "<span class="profile-badge badge-type">" + esc(p.type || "claude-max") + "</span>";
|
|
593
|
+
html += renderSpentBadge((quotaById[p.id] || {}).spent);
|
|
594
|
+
html += "<span class="profile-card-actions">";
|
|
595
|
+
html += "<button class="icon-btn" title="Rename profile" onclick="startRename(""+esc(p.id)+"")">" + ICON_PENCIL + "</button>";
|
|
596
|
+
html += "</span>";
|
|
597
|
+
}
|
|
383
598
|
html += '</div>';
|
|
599
|
+
html += renderSpentNote((quotaById[p.id] || {}).spent);
|
|
384
600
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
html += '<span class="detail-value ' + (p.loggedIn ? 'status-ok' : 'status-err') + '">'
|
|
388
|
-
+ (p.loggedIn ? '✓ Authenticated' : '✗ Not logged in') + '</span>';
|
|
389
|
-
|
|
390
|
-
if (p.email) {
|
|
391
|
-
html += '<span class="detail-label">Email</span>';
|
|
392
|
-
html += '<span class="detail-value">' + esc(p.email) + '</span>';
|
|
601
|
+
if (editingProfile === p.id && renameError) {
|
|
602
|
+
html += '<div class="rename-error">' + esc(renameError) + '</div>';
|
|
393
603
|
}
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
html += '<span class="detail-value">' + esc(p.subscriptionType) + '</span>';
|
|
397
|
-
}
|
|
398
|
-
if (p.lastSuccessAt) {
|
|
399
|
-
html += '<span class="detail-label">Last Verified</span>';
|
|
400
|
-
html += '<span class="detail-value" style="color:var(--green)">' + timeAgo(p.lastSuccessAt) + '</span>';
|
|
401
|
-
}
|
|
402
|
-
if (p.lastCheckedAt && (!p.lastSuccessAt || p.lastCheckedAt !== p.lastSuccessAt)) {
|
|
403
|
-
html += '<span class="detail-label">Last Checked</span>';
|
|
404
|
-
html += '<span class="detail-value">' + timeAgo(p.lastCheckedAt) + '</span>';
|
|
405
|
-
}
|
|
406
|
-
html += '</div>';
|
|
604
|
+
|
|
605
|
+
html += '<div class="profile-details">' + factRows(profileFacts(p)) + '</div>';
|
|
407
606
|
|
|
408
607
|
if (!p.loggedIn) {
|
|
409
608
|
html += '<div style="margin-top:12px;padding:10px 14px;background:rgba(210,153,34,0.1);border:1px solid rgba(210,153,34,0.3);border-radius:8px;font-size:12px">';
|
|
@@ -432,16 +631,7 @@ function render(data, quotaData) {
|
|
|
432
631
|
|
|
433
632
|
html += '</div>';
|
|
434
633
|
document.getElementById('content').innerHTML = html;
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
function timeAgo(ts) {
|
|
438
|
-
if (!ts) return '—';
|
|
439
|
-
var s = Math.floor((Date.now() - ts) / 1000);
|
|
440
|
-
if (s < 5) return 'just now';
|
|
441
|
-
if (s < 60) return s + 's ago';
|
|
442
|
-
if (s < 3600) return Math.floor(s/60) + 'm ago';
|
|
443
|
-
if (s < 86400) return Math.floor(s/3600) + 'h ago';
|
|
444
|
-
return new Date(ts).toLocaleString();
|
|
634
|
+
meridianReorder.restoreFocus(refocusId);
|
|
445
635
|
}
|
|
446
636
|
|
|
447
637
|
function copyCmd(btn) {
|
|
@@ -463,10 +653,12 @@ async function switchProfile(id) {
|
|
|
463
653
|
});
|
|
464
654
|
const data = await res.json();
|
|
465
655
|
if (data.success) refresh();
|
|
656
|
+
else if (data.error) alert(data.error);
|
|
466
657
|
}
|
|
467
658
|
|
|
659
|
+
meridianReorder.init({ onSaved: refresh });
|
|
468
660
|
refresh();
|
|
469
|
-
setInterval(refresh, 10000);
|
|
661
|
+
setInterval(function () { if (!meridianReorder.dragging()) refresh(); }, 10000);
|
|
470
662
|
` + profileBarJs + `
|
|
471
663
|
</script>
|
|
472
664
|
</body>
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import {
|
|
2
|
+
applyProfileRename,
|
|
3
|
+
defaultProfilesConfigFile,
|
|
4
|
+
defaultProfilesDir,
|
|
5
|
+
isValidProfileId,
|
|
6
|
+
loadProfileConfigFrom,
|
|
7
|
+
planProfileRename,
|
|
8
|
+
reclaimAlias,
|
|
9
|
+
saveProfileConfigTo
|
|
10
|
+
} from "./cli-qpfky8wy.js";
|
|
11
|
+
import"./cli-eehk3052.js";
|
|
12
|
+
import"./cli-p9swy5t3.js";
|
|
13
|
+
export {
|
|
14
|
+
saveProfileConfigTo,
|
|
15
|
+
reclaimAlias,
|
|
16
|
+
planProfileRename,
|
|
17
|
+
loadProfileConfigFrom,
|
|
18
|
+
isValidProfileId,
|
|
19
|
+
defaultProfilesDir,
|
|
20
|
+
defaultProfilesConfigFile,
|
|
21
|
+
applyProfileRename
|
|
22
|
+
};
|
|
@@ -1,26 +1,39 @@
|
|
|
1
1
|
import {
|
|
2
2
|
enableDiskProfileDiscovery,
|
|
3
|
+
findProfileByIdOrAlias,
|
|
3
4
|
getActiveProfileId,
|
|
5
|
+
getEffectiveActiveProfileId,
|
|
4
6
|
getEffectiveProfiles,
|
|
5
7
|
hasProfiles,
|
|
8
|
+
invalidateDiskProfileCache,
|
|
6
9
|
listProfiles,
|
|
7
10
|
loadProfilesFromDisk,
|
|
11
|
+
profilesRelocationNotice,
|
|
8
12
|
resetActiveProfile,
|
|
13
|
+
resolveActiveProfileId,
|
|
9
14
|
resolveProfile,
|
|
10
15
|
restoreActiveProfile,
|
|
11
|
-
setActiveProfile
|
|
12
|
-
|
|
13
|
-
|
|
16
|
+
setActiveProfile,
|
|
17
|
+
shareableCredentialDir
|
|
18
|
+
} from "./cli-dh0a1bw4.js";
|
|
19
|
+
import"./cli-1jstkdj9.js";
|
|
20
|
+
import"./cli-eehk3052.js";
|
|
14
21
|
import"./cli-p9swy5t3.js";
|
|
15
22
|
export {
|
|
23
|
+
shareableCredentialDir,
|
|
16
24
|
setActiveProfile,
|
|
17
25
|
restoreActiveProfile,
|
|
18
26
|
resolveProfile,
|
|
27
|
+
resolveActiveProfileId,
|
|
19
28
|
resetActiveProfile,
|
|
29
|
+
profilesRelocationNotice,
|
|
20
30
|
loadProfilesFromDisk,
|
|
21
31
|
listProfiles,
|
|
32
|
+
invalidateDiskProfileCache,
|
|
22
33
|
hasProfiles,
|
|
23
34
|
getEffectiveProfiles,
|
|
35
|
+
getEffectiveActiveProfileId,
|
|
24
36
|
getActiveProfileId,
|
|
37
|
+
findProfileByIdOrAlias,
|
|
25
38
|
enableDiskProfileDiscovery
|
|
26
39
|
};
|
|
@@ -17,7 +17,7 @@
|
|
|
17
17
|
*
|
|
18
18
|
* Config sources (first wins):
|
|
19
19
|
* 1. MERIDIAN_ADAPTER_INSTANCES env var (JSON string)
|
|
20
|
-
* 2.
|
|
20
|
+
* 2. adapter-instances.json in the config directory (5s TTL cache)
|
|
21
21
|
*
|
|
22
22
|
* With no instances configured, adapter detection is byte-identical to the
|
|
23
23
|
* built-in chain. Built-in adapter names cannot be shadowed.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"adapterInstances.d.ts","sourceRoot":"","sources":["../../src/proxy/adapterInstances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;
|
|
1
|
+
{"version":3,"file":"adapterInstances.d.ts","sourceRoot":"","sources":["../../src/proxy/adapterInstances.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAIH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAA;AAEpD,MAAM,WAAW,oBAAoB;IACnC,oFAAoF;IACpF,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;IAC/B,+BAA+B;IAC/B,eAAe,CAAC,EAAE,MAAM,CAAA;CACzB;AAED,MAAM,WAAW,kBAAkB;IACjC,uFAAuF;IACvF,IAAI,EAAE,MAAM,CAAA;IACZ,iFAAiF;IACjF,QAAQ,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAA;IACnC,iFAAiF;IACjF,WAAW,CAAC,EAAE,OAAO,CAAA;IACrB,2EAA2E;IAC3E,KAAK,CAAC,EAAE,oBAAoB,CAAA;CAC7B;AAED,MAAM,MAAM,kBAAkB,GAAG,MAAM,CAAC,MAAM,EAAE,kBAAkB,CAAC,CAAA;AAEnE;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,kBAAkB,CAkCjF;AAUD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,kBAAkB,CAezD;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,GAAG,EAAE,kBAAkB,EACvB,SAAS,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAAG,SAAS,GAC9C,OAAO,CAiBT"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"claudecode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/claudecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiC9C;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAClC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CA+BrG;AAED,sFAAsF;AACtF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE5E;AAED,kFAAkF;AAClF,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED,eAAO,MAAM,iBAAiB,EAAE,
|
|
1
|
+
{"version":3,"file":"claudecode.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/claudecode.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AACnC,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AAiC9C;;;;;;;GAOG;AACH,MAAM,WAAW,yBAAyB;IACxC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAA;IAC1B;;;;OAIG;IACH,QAAQ,CAAC,eAAe,CAAC,EAAE,MAAM,CAAA;CAClC;AAED;;;;;;;;GAQG;AACH,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,yBAAyB,GAAG,SAAS,CA+BrG;AAED,sFAAsF;AACtF,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAE5E;AAED,kFAAkF;AAClF,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAElF;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,OAAO,GAAG,OAAO,CAEtD;AAED,eAAO,MAAM,iBAAiB,EAAE,YAkH/B,CAAA"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"droid.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/droid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;
|
|
1
|
+
{"version":3,"file":"droid.d.ts","sourceRoot":"","sources":["../../../src/proxy/adapters/droid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAA;AA0D9C,eAAO,MAAM,YAAY,EAAE,YAkF1B,CAAA;AAED,OAAO,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAA;AACrD,OAAO,EAAE,eAAe,EAAE,CAAA"}
|
package/dist/proxy/auth.d.ts
CHANGED
|
@@ -13,6 +13,8 @@ import type { Context, Next } from "hono";
|
|
|
13
13
|
* True when MERIDIAN_API_KEY is set to a non-empty value.
|
|
14
14
|
*/
|
|
15
15
|
export declare function authEnabled(): boolean;
|
|
16
|
+
/** Shared by the Hono default backend and standard-Request runtime backends. */
|
|
17
|
+
export declare function hasValidApiKey(headers: Headers): boolean;
|
|
16
18
|
/**
|
|
17
19
|
* Hono middleware that rejects requests without a valid API key.
|
|
18
20
|
* No-op when MERIDIAN_API_KEY is not set.
|
package/dist/proxy/auth.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/proxy/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAMzC;;;GAGG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;
|
|
1
|
+
{"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/proxy/auth.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAMzC;;;GAGG;AACH,wBAAgB,WAAW,IAAI,OAAO,CAErC;AAYD,gFAAgF;AAChF,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAMxD;AAgBD;;;GAGG;AACH,wBAAsB,WAAW,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,IAAI;;;;;;kBAgBvD"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* What Anthropic told us during authentication, rendered safe to log.
|
|
3
|
+
*
|
|
4
|
+
* Three payloads decide what Meridian knows about an account — the token
|
|
5
|
+
* endpoint's response, `GET /api/oauth/profile`, and `claude auth status` —
|
|
6
|
+
* and none of them is currently observable. When a field is absent, or renamed,
|
|
7
|
+
* or Anthropic starts returning a plan tier nobody has seen before, the only
|
|
8
|
+
* symptom downstream is a profile that reads `unknown`, with nothing in any log
|
|
9
|
+
* to say whether the field was missing from the response or dropped on the way
|
|
10
|
+
* to disk. That distinction is the whole of the diagnosis.
|
|
11
|
+
*
|
|
12
|
+
* The obstacle is that two of those payloads carry credentials, so they cannot
|
|
13
|
+
* simply be logged. `logger.ts`'s `sanitize()` redacts by key name, which is
|
|
14
|
+
* the wrong polarity here: it protects the names somebody already thought of,
|
|
15
|
+
* and a field discovered tomorrow is by definition not one of them.
|
|
16
|
+
*
|
|
17
|
+
* So this inverts it. Every string is redacted to its length unless its key is
|
|
18
|
+
* on an allow-list of values known to carry no secret. A new field is therefore
|
|
19
|
+
* reported by NAME and TYPE — enough to see it arrived and to decide what it is
|
|
20
|
+
* — while its contents stay out of the log until somebody deliberately adds it
|
|
21
|
+
* to the list.
|
|
22
|
+
*
|
|
23
|
+
* This is a leaf module — pure, no imports.
|
|
24
|
+
*/
|
|
25
|
+
/**
|
|
26
|
+
* String-valued keys whose contents are safe to print.
|
|
27
|
+
*
|
|
28
|
+
* Every one is either a duration, a timestamp, an enum Anthropic publishes, or
|
|
29
|
+
* the scope list that already appears in plaintext in the authorize URL. A key
|
|
30
|
+
* that identifies a person or an organization is deliberately absent: `email`,
|
|
31
|
+
* `email_address`, `name`, `display_name` and `uuid` are all reported by length
|
|
32
|
+
* only, because a debug log is routinely pasted into an issue.
|
|
33
|
+
*/
|
|
34
|
+
export declare const SAFE_AUTH_STRING_KEYS: ReadonlySet<string>;
|
|
35
|
+
/**
|
|
36
|
+
* Render a parsed auth response as a loggable field map.
|
|
37
|
+
*
|
|
38
|
+
* The shape mirrors the payload rather than flattening it, so a nested
|
|
39
|
+
* `organization.rate_limit_tier` reads the same way in the log as it does in
|
|
40
|
+
* Anthropic's documentation and in the code that consumes it.
|
|
41
|
+
*/
|
|
42
|
+
export declare function describeAuthFields(payload: unknown): unknown;
|
|
43
|
+
/**
|
|
44
|
+
* The keys a payload actually carried, nested ones included, as dotted paths.
|
|
45
|
+
*
|
|
46
|
+
* Logged alongside the described payload because it is the line worth grepping:
|
|
47
|
+
* comparing two logins reduces to comparing two key lists, which answers "did
|
|
48
|
+
* this account's response even contain the field" without reading the values at
|
|
49
|
+
* all.
|
|
50
|
+
*/
|
|
51
|
+
export declare function authFieldPaths(payload: unknown, prefix?: string): string[];
|
|
52
|
+
//# sourceMappingURL=authDiscovery.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"authDiscovery.d.ts","sourceRoot":"","sources":["../../src/proxy/authDiscovery.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;;;;;;GAQG;AACH,eAAO,MAAM,qBAAqB,EAAE,WAAW,CAAC,MAAM,CAepD,CAAA;AA0BF;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAE5D;AAED;;;;;;;GAOG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,SAAK,GAAG,MAAM,EAAE,CAStE"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { type ProviderUsage } from '../../telemetry/providerView';
|
|
2
|
+
import type { ProxyConfig, ProxyServer } from "../types";
|
|
3
|
+
import { AntigravityRuntime } from "./antigravityRuntime";
|
|
4
|
+
export declare function createAntigravityServer(config: ProxyConfig, runtime?: AntigravityRuntime): ProxyServer & {
|
|
5
|
+
closeBackend(): Promise<void>;
|
|
6
|
+
providerStatus(): Promise<ProviderUsage>;
|
|
7
|
+
};
|
|
8
|
+
//# sourceMappingURL=antigravity.d.ts.map
|