@tokagent/tokagentos 2.0.24 → 2.0.29
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/package.json +1 -1
- package/scaffold-patches/packages/app-core/src/api/automations-compat-routes.ts +924 -0
- package/templates/fullstack-app/plugins/plugin-tokagent-billing/package.json +1 -1
- package/templates/fullstack-app/plugins/plugin-tokagent-billing/src/__tests__/routes/estimate-routes.test.ts +5 -2
- package/templates/fullstack-app/plugins/plugin-tokagent-billing/src/dashboard/app.js +896 -19
- package/templates/fullstack-app/plugins/plugin-tokagent-billing/src/dashboard/index.html +280 -94
- package/templates/fullstack-app/plugins/plugin-tokagent-billing/src/dashboard/style.css +969 -235
- package/templates/fullstack-app/plugins/plugin-tokagent-billing/src/routes/keys-routes.ts +170 -0
- package/templates-manifest.json +1 -1
|
@@ -6,14 +6,22 @@
|
|
|
6
6
|
<meta name="color-scheme" content="dark" />
|
|
7
7
|
<meta name="theme-color" content="#0a0a0f" />
|
|
8
8
|
<meta name="robots" content="noindex,nofollow" />
|
|
9
|
-
<title>Tokamak.AI —
|
|
10
|
-
<meta name="description" content="API key issuance, PTON top-up, credit balance, and 90-day usage history for the Tokamak.AI x402 gateway." />
|
|
9
|
+
<title>Tokamak.AI — Billing</title>
|
|
10
|
+
<meta name="description" content="API key issuance, PTON top-up, credit balance, swap-to-credits, and 90-day usage history for the Tokamak.AI x402 gateway." />
|
|
11
11
|
|
|
12
12
|
<!-- Resolve all relative asset URLs (style.css, app.js, config.js) under
|
|
13
13
|
the plugin's mount point. The trailing slash is required so style.css
|
|
14
14
|
resolves to /v1/billing/dashboard/style.css. -->
|
|
15
15
|
<base href="/v1/billing/dashboard/" />
|
|
16
16
|
|
|
17
|
+
<!-- Inter (UI sans) + JetBrains Mono (numeric / address mono).
|
|
18
|
+
Loaded preconnect-first so first paint of the balance hero hits
|
|
19
|
+
the locked monospace face without a FOUT-jiggle. -->
|
|
20
|
+
<link rel="preconnect" href="https://fonts.googleapis.com" />
|
|
21
|
+
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin />
|
|
22
|
+
<link rel="stylesheet"
|
|
23
|
+
href="https://fonts.googleapis.com/css2?family=Inter:wght@400;500;600;700&family=JetBrains+Mono:wght@400;500;600;700&display=swap" />
|
|
24
|
+
|
|
17
25
|
<link rel="stylesheet" href="style.css" />
|
|
18
26
|
|
|
19
27
|
<!-- Pre-paint embed-mode detection: when loaded inside the parent app
|
|
@@ -38,20 +46,39 @@
|
|
|
38
46
|
<body>
|
|
39
47
|
<header class="topbar">
|
|
40
48
|
<div class="brand">
|
|
41
|
-
<span class="brand-mark" aria-hidden="true"
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
<span class="brand-mark" aria-hidden="true">
|
|
50
|
+
<svg viewBox="0 0 40 40" width="26" height="26" aria-hidden="true">
|
|
51
|
+
<defs>
|
|
52
|
+
<linearGradient id="brand-key-grad" x1="0" y1="0" x2="0" y2="1">
|
|
53
|
+
<stop offset="0%" stop-color="#f3ba2f"/>
|
|
54
|
+
<stop offset="100%" stop-color="#d8a000"/>
|
|
55
|
+
</linearGradient>
|
|
56
|
+
</defs>
|
|
57
|
+
<rect x="6" y="6" width="28" height="6" rx="1.2" fill="url(#brand-key-grad)"/>
|
|
58
|
+
<rect x="7" y="6.5" width="26" height="1.2" fill="rgba(255,255,255,0.42)"/>
|
|
59
|
+
<rect x="17" y="12" width="6" height="18" fill="url(#brand-key-grad)"/>
|
|
60
|
+
<rect x="23" y="22" width="5" height="3.2" fill="url(#brand-key-grad)"/>
|
|
61
|
+
<rect x="23" y="27" width="3.5" height="3.2" fill="url(#brand-key-grad)"/>
|
|
62
|
+
<rect x="17" y="30" width="6" height="3.5" rx="0.6" fill="url(#brand-key-grad)"/>
|
|
63
|
+
</svg>
|
|
64
|
+
</span>
|
|
65
|
+
<div class="brand-text">
|
|
66
|
+
<strong>Tokamak</strong>
|
|
67
|
+
<span class="brand-sub">Billing</span>
|
|
68
|
+
</div>
|
|
44
69
|
</div>
|
|
45
70
|
<div class="topbar-right">
|
|
46
71
|
<span id="chain-pill" class="pill" hidden>
|
|
47
|
-
<span
|
|
72
|
+
<span class="dot" aria-hidden="true"></span>
|
|
73
|
+
<span id="chain-name">—</span>
|
|
74
|
+
<code id="chain-id" class="pill-mono">—</code>
|
|
48
75
|
</span>
|
|
49
76
|
<button id="switch-chain-btn" class="btn btn-ghost btn-small" type="button" hidden>Switch network</button>
|
|
50
|
-
<span id="wallet-pill" class="pill" hidden>
|
|
77
|
+
<span id="wallet-pill" class="pill pill-wallet" hidden>
|
|
51
78
|
<span class="dot dot-ok" aria-hidden="true"></span>
|
|
52
|
-
<code id="wallet-addr">—</code>
|
|
79
|
+
<code id="wallet-addr" class="pill-mono">—</code>
|
|
53
80
|
</span>
|
|
54
|
-
<button id="logout-btn" class="btn btn-ghost" type="button" hidden>
|
|
81
|
+
<button id="logout-btn" class="btn btn-ghost btn-small" type="button" hidden>Disconnect</button>
|
|
55
82
|
</div>
|
|
56
83
|
</header>
|
|
57
84
|
|
|
@@ -59,20 +86,22 @@
|
|
|
59
86
|
<!-- ====================== LOGIN ====================== -->
|
|
60
87
|
<section id="view-login" class="view view-login">
|
|
61
88
|
<div class="login-card">
|
|
62
|
-
<
|
|
63
|
-
<
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
</
|
|
71
|
-
|
|
89
|
+
<div class="login-eyebrow">SIWE · EIP-712</div>
|
|
90
|
+
<h1>Connect your wallet</h1>
|
|
91
|
+
<p class="muted">
|
|
92
|
+
One signature exchanges your wallet for a 24-hour session token. The
|
|
93
|
+
dashboard never reads your private key.
|
|
94
|
+
</p>
|
|
95
|
+
|
|
96
|
+
<ol class="login-steps">
|
|
97
|
+
<li><span class="step-num">1</span> Connect a browser wallet (MetaMask, Rabby, …).</li>
|
|
98
|
+
<li><span class="step-num">2</span> Approve the <code>LoginAuth</code> typed-data signature.</li>
|
|
99
|
+
<li><span class="step-num">3</span> Manage keys, top up credits, swap to PTON.</li>
|
|
100
|
+
</ol>
|
|
72
101
|
|
|
73
102
|
<div class="login-actions">
|
|
74
|
-
<button id="connect-btn" class="btn btn-primary" type="button">Connect wallet</button>
|
|
75
|
-
<button id="signin-btn" class="btn btn-primary" type="button" hidden>Sign in</button>
|
|
103
|
+
<button id="connect-btn" class="btn btn-primary btn-block" type="button">Connect wallet</button>
|
|
104
|
+
<button id="signin-btn" class="btn btn-primary btn-block" type="button" hidden>Sign in</button>
|
|
76
105
|
</div>
|
|
77
106
|
|
|
78
107
|
<p id="login-status" class="status-line" role="status" aria-live="polite"></p>
|
|
@@ -90,91 +119,223 @@
|
|
|
90
119
|
|
|
91
120
|
<!-- ====================== APP ====================== -->
|
|
92
121
|
<section id="view-app" class="view view-app" hidden>
|
|
93
|
-
<!-- ---- Balance + price summary ---- -->
|
|
94
|
-
<section class="grid grid-3">
|
|
95
|
-
<article class="card">
|
|
96
|
-
<header><h2>Spendable balance</h2><span class="card-sub">on-chain credit + ledger</span></header>
|
|
97
|
-
<p class="big-num"><span id="kpi-balance">—</span><em>PTON</em></p>
|
|
98
|
-
<p class="muted small">
|
|
99
|
-
Reserved <code id="kpi-reserved">—</code> · Pending consume <code id="kpi-accrued">—</code>
|
|
100
|
-
</p>
|
|
101
|
-
<p class="muted small">≈ <span id="kpi-balance-usd">—</span> USD at the current TWAP</p>
|
|
102
|
-
<p class="muted small">
|
|
103
|
-
Wallet <code id="kpi-wallet-pton">—</code> PTON · <code id="kpi-wallet-eth">—</code> ETH
|
|
104
|
-
</p>
|
|
105
|
-
</article>
|
|
106
122
|
|
|
123
|
+
<!-- ---- Balance hero ---- -->
|
|
124
|
+
<section class="hero">
|
|
125
|
+
<div class="hero-main">
|
|
126
|
+
<div class="hero-eyebrow">Spendable balance</div>
|
|
127
|
+
<div class="hero-balance">
|
|
128
|
+
<span id="kpi-balance" class="hero-num">—</span>
|
|
129
|
+
<span class="hero-unit">PTON</span>
|
|
130
|
+
</div>
|
|
131
|
+
<div class="hero-meta">
|
|
132
|
+
<span class="hero-usd">≈ $<span id="kpi-balance-usd">—</span> USD</span>
|
|
133
|
+
<span class="hero-sep">·</span>
|
|
134
|
+
<span>1 TON = $<span id="kpi-price">—</span></span>
|
|
135
|
+
<span class="hero-sep">·</span>
|
|
136
|
+
<span><span id="kpi-price-source">—</span> · <span id="kpi-price-age">—</span></span>
|
|
137
|
+
</div>
|
|
138
|
+
</div>
|
|
139
|
+
<div class="hero-side">
|
|
140
|
+
<div class="hero-stat">
|
|
141
|
+
<div class="stat-label">Reserved</div>
|
|
142
|
+
<div class="stat-num"><span id="kpi-reserved">—</span></div>
|
|
143
|
+
</div>
|
|
144
|
+
<div class="hero-stat">
|
|
145
|
+
<div class="stat-label">Pending consume</div>
|
|
146
|
+
<div class="stat-num"><span id="kpi-accrued">—</span></div>
|
|
147
|
+
</div>
|
|
148
|
+
<div class="hero-stat">
|
|
149
|
+
<div class="stat-label">Wallet PTON</div>
|
|
150
|
+
<div class="stat-num"><span id="kpi-wallet-pton">—</span></div>
|
|
151
|
+
</div>
|
|
152
|
+
<div class="hero-stat">
|
|
153
|
+
<div class="stat-label">Wallet ETH</div>
|
|
154
|
+
<div class="stat-num"><span id="kpi-wallet-eth">—</span></div>
|
|
155
|
+
</div>
|
|
156
|
+
</div>
|
|
157
|
+
</section>
|
|
158
|
+
|
|
159
|
+
<!-- ---- KPI strip ---- -->
|
|
160
|
+
<section class="kpi-strip">
|
|
161
|
+
<div class="kpi">
|
|
162
|
+
<div class="kpi-label">Calls (30d)</div>
|
|
163
|
+
<div class="kpi-val"><span id="kpi-calls">—</span></div>
|
|
164
|
+
</div>
|
|
165
|
+
<div class="kpi">
|
|
166
|
+
<div class="kpi-label">Success</div>
|
|
167
|
+
<div class="kpi-val ok"><span id="kpi-calls-ok">—</span></div>
|
|
168
|
+
</div>
|
|
169
|
+
<div class="kpi">
|
|
170
|
+
<div class="kpi-label">Failed</div>
|
|
171
|
+
<div class="kpi-val err"><span id="kpi-calls-fail">—</span></div>
|
|
172
|
+
</div>
|
|
173
|
+
<div class="kpi">
|
|
174
|
+
<div class="kpi-label">Retention</div>
|
|
175
|
+
<div class="kpi-val muted"><span id="usage-retention">90</span><span class="kpi-unit">d</span></div>
|
|
176
|
+
</div>
|
|
177
|
+
</section>
|
|
178
|
+
|
|
179
|
+
<!-- ---- Top up + Swap (2-col grid) ---- -->
|
|
180
|
+
<section class="grid-cards">
|
|
181
|
+
|
|
182
|
+
<!-- ---- Top up card ---- -->
|
|
107
183
|
<article class="card">
|
|
108
|
-
<header
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
184
|
+
<header class="card-header">
|
|
185
|
+
<div>
|
|
186
|
+
<div class="card-eyebrow">Deposit</div>
|
|
187
|
+
<h2 class="card-title">Top up credits</h2>
|
|
188
|
+
</div>
|
|
189
|
+
<span class="card-tag">EIP-3009 · gasless</span>
|
|
190
|
+
</header>
|
|
191
|
+
|
|
192
|
+
<div class="form-row">
|
|
193
|
+
<label for="topup-amount" class="field-label">Amount</label>
|
|
194
|
+
<div class="amount-input">
|
|
195
|
+
<input id="topup-amount" type="number" step="0.1" min="0.1" value="5" inputmode="decimal" />
|
|
196
|
+
<span class="amount-unit">PTON</span>
|
|
197
|
+
</div>
|
|
198
|
+
</div>
|
|
199
|
+
|
|
200
|
+
<div class="preset-row" id="topup-preset-row">
|
|
201
|
+
<button type="button" class="chip" data-preset="1">1</button>
|
|
202
|
+
<button type="button" class="chip" data-preset="5">5</button>
|
|
203
|
+
<button type="button" class="chip" data-preset="10">10</button>
|
|
204
|
+
<button type="button" class="chip" data-preset="50">50</button>
|
|
205
|
+
</div>
|
|
206
|
+
|
|
207
|
+
<div class="estimate-line">
|
|
208
|
+
<span class="est-label">You deposit</span>
|
|
209
|
+
<span class="est-val"><span id="topup-est-pton">5</span> PTON</span>
|
|
210
|
+
</div>
|
|
211
|
+
<div class="estimate-line subtle">
|
|
212
|
+
<span class="est-label">≈ USD</span>
|
|
213
|
+
<span class="est-val">$<span id="topup-usd">—</span></span>
|
|
214
|
+
</div>
|
|
215
|
+
|
|
216
|
+
<button id="topup-btn" class="btn btn-primary btn-block btn-cta" type="button">Sign & deposit</button>
|
|
217
|
+
<p id="topup-status" class="status-line" role="status" aria-live="polite"></p>
|
|
218
|
+
<p class="muted xsmall">
|
|
219
|
+
The proxy pulls PTON into <code>ClaudeVault</code> via EIP-3009 and credits your wallet — no on-chain tx from you.
|
|
112
220
|
</p>
|
|
113
221
|
</article>
|
|
114
222
|
|
|
223
|
+
<!-- ---- Swap card (NEW) ---- -->
|
|
115
224
|
<article class="card">
|
|
116
|
-
<header
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
225
|
+
<header class="card-header">
|
|
226
|
+
<div>
|
|
227
|
+
<div class="card-eyebrow">Swap</div>
|
|
228
|
+
<h2 class="card-title">Swap to credits</h2>
|
|
229
|
+
</div>
|
|
230
|
+
<span class="card-tag">Route via TON</span>
|
|
231
|
+
</header>
|
|
123
232
|
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
<div class="topup-amount">
|
|
132
|
-
<label for="topup-amount">Amount</label>
|
|
133
|
-
<div class="topup-input">
|
|
134
|
-
<input id="topup-amount" type="number" step="0.1" min="0.1" value="5" inputmode="decimal" />
|
|
135
|
-
<span class="suffix">PTON</span>
|
|
233
|
+
<div class="form-row">
|
|
234
|
+
<div class="field-label-row">
|
|
235
|
+
<label for="swap-amount" class="field-label">You pay</label>
|
|
236
|
+
<span class="field-meta">
|
|
237
|
+
Balance <span id="swap-input-balance">—</span>
|
|
238
|
+
<button type="button" id="swap-max-btn" class="link-btn">Max</button>
|
|
239
|
+
</span>
|
|
136
240
|
</div>
|
|
137
|
-
<div class="
|
|
138
|
-
<
|
|
139
|
-
<
|
|
140
|
-
|
|
141
|
-
|
|
241
|
+
<div class="amount-input amount-input-with-token">
|
|
242
|
+
<input id="swap-amount" type="number" step="0.000001" min="0" value="" placeholder="0.0" inputmode="decimal" />
|
|
243
|
+
<div class="token-select" id="swap-token-select" role="combobox" aria-haspopup="listbox" aria-expanded="false" tabindex="0">
|
|
244
|
+
<img id="swap-token-icon" class="token-icon" alt="" src="" />
|
|
245
|
+
<span id="swap-token-label">USDC</span>
|
|
246
|
+
<svg class="caret" width="10" height="6" viewBox="0 0 10 6" aria-hidden="true"><path d="M1 1l4 4 4-4" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
247
|
+
<div class="token-menu" id="swap-token-menu" role="listbox" hidden>
|
|
248
|
+
<!-- Populated by app.js from SWAP_TOKENS -->
|
|
249
|
+
</div>
|
|
250
|
+
</div>
|
|
142
251
|
</div>
|
|
143
|
-
<p class="muted small">
|
|
144
|
-
≈ <span id="topup-usd">—</span> USD at current TWAP. The proxy will pull this PTON into <code>ClaudeVault</code> and credit your wallet.
|
|
145
|
-
</p>
|
|
146
252
|
</div>
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
<
|
|
253
|
+
|
|
254
|
+
<div class="swap-arrow" aria-hidden="true">
|
|
255
|
+
<svg width="14" height="14" viewBox="0 0 14 14"><path d="M7 1v12M3 9l4 4 4-4" stroke="currentColor" stroke-width="1.5" fill="none" stroke-linecap="round" stroke-linejoin="round"/></svg>
|
|
150
256
|
</div>
|
|
151
|
-
|
|
257
|
+
|
|
258
|
+
<div class="form-row">
|
|
259
|
+
<label class="field-label">You receive</label>
|
|
260
|
+
<div class="receive-box">
|
|
261
|
+
<span class="receive-num" id="swap-output-pton">0.00</span>
|
|
262
|
+
<span class="receive-unit">PTON</span>
|
|
263
|
+
</div>
|
|
264
|
+
<div class="estimate-line subtle compact">
|
|
265
|
+
<span class="est-label">≈ USD</span>
|
|
266
|
+
<span class="est-val">$<span id="swap-output-usd">—</span></span>
|
|
267
|
+
</div>
|
|
268
|
+
</div>
|
|
269
|
+
|
|
270
|
+
<div class="route-section">
|
|
271
|
+
<div class="route-label">Route</div>
|
|
272
|
+
<div class="route-chain" id="swap-route">
|
|
273
|
+
<span class="route-step">USDC</span>
|
|
274
|
+
<span class="route-arrow">→</span>
|
|
275
|
+
<span class="route-step">ETH</span>
|
|
276
|
+
<span class="route-arrow">→</span>
|
|
277
|
+
<span class="route-step">TON</span>
|
|
278
|
+
<span class="route-arrow">→</span>
|
|
279
|
+
<span class="route-step route-step-end">PTON</span>
|
|
280
|
+
</div>
|
|
281
|
+
</div>
|
|
282
|
+
|
|
283
|
+
<div class="slippage-row">
|
|
284
|
+
<span class="field-label">Slippage</span>
|
|
285
|
+
<div class="slippage-buttons" role="radiogroup" aria-label="Slippage tolerance">
|
|
286
|
+
<button type="button" class="chip slippage-btn" data-slippage="10">0.1%</button>
|
|
287
|
+
<button type="button" class="chip slippage-btn is-active" data-slippage="50">0.5%</button>
|
|
288
|
+
<button type="button" class="chip slippage-btn" data-slippage="100">1%</button>
|
|
289
|
+
</div>
|
|
290
|
+
</div>
|
|
291
|
+
|
|
292
|
+
<button id="swap-btn" class="btn btn-primary btn-block btn-cta" type="button" disabled>Enter an amount</button>
|
|
293
|
+
<p id="swap-status" class="status-line" role="status" aria-live="polite"></p>
|
|
294
|
+
<p class="muted xsmall">
|
|
295
|
+
Swaps route via DEX aggregator to TON, then wrap + deposit into <code>ClaudeVault</code>. Each step prompts a separate wallet signature.
|
|
296
|
+
</p>
|
|
297
|
+
</article>
|
|
152
298
|
</section>
|
|
153
299
|
|
|
154
300
|
<!-- ---- Usage tabs ---- -->
|
|
155
301
|
<section class="card section-card">
|
|
156
|
-
<header class="card-
|
|
157
|
-
<
|
|
302
|
+
<header class="card-header card-header-stack">
|
|
303
|
+
<div>
|
|
304
|
+
<div class="card-eyebrow">Usage</div>
|
|
305
|
+
<h2 class="card-title">Activity · last 30 days</h2>
|
|
306
|
+
</div>
|
|
158
307
|
<div class="tabs" role="tablist">
|
|
159
|
-
<button class="tab active" type="button" data-tab="overview" role="tab" aria-selected="true">Overview</button>
|
|
308
|
+
<button class="tab is-active" type="button" data-tab="overview" role="tab" aria-selected="true">Overview</button>
|
|
160
309
|
<button class="tab" type="button" data-tab="byday" role="tab" aria-selected="false">Daily</button>
|
|
161
310
|
<button class="tab" type="button" data-tab="bymodel" role="tab" aria-selected="false">By model</button>
|
|
162
|
-
<button class="tab" type="button" data-tab="bykey" role="tab" aria-selected="false">By
|
|
163
|
-
<button class="tab" type="button" data-tab="calls" role="tab" aria-selected="false">
|
|
311
|
+
<button class="tab" type="button" data-tab="bykey" role="tab" aria-selected="false">By key</button>
|
|
312
|
+
<button class="tab" type="button" data-tab="calls" role="tab" aria-selected="false">Calls</button>
|
|
164
313
|
</div>
|
|
165
|
-
<span class="card-sub">Window: last 30 days · retention <code id="usage-retention">90</code> days</span>
|
|
166
314
|
</header>
|
|
167
315
|
|
|
168
316
|
<!-- Overview -->
|
|
169
|
-
<div class="tab-pane active" data-pane="overview">
|
|
170
|
-
<div class="grid
|
|
171
|
-
<div class="metric"
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
317
|
+
<div class="tab-pane is-active" data-pane="overview">
|
|
318
|
+
<div class="metric-grid">
|
|
319
|
+
<div class="metric">
|
|
320
|
+
<div class="metric-label">Input tokens</div>
|
|
321
|
+
<div class="metric-val"><span id="usage-input">—</span></div>
|
|
322
|
+
</div>
|
|
323
|
+
<div class="metric">
|
|
324
|
+
<div class="metric-label">Output tokens</div>
|
|
325
|
+
<div class="metric-val"><span id="usage-output">—</span></div>
|
|
326
|
+
</div>
|
|
327
|
+
<div class="metric">
|
|
328
|
+
<div class="metric-label">Total spend</div>
|
|
329
|
+
<div class="metric-val"><span id="usage-spent">—</span><span class="metric-unit">PTON</span></div>
|
|
330
|
+
</div>
|
|
331
|
+
<div class="metric metric-soft">
|
|
332
|
+
<div class="metric-label">Cache reads</div>
|
|
333
|
+
<div class="metric-val"><span id="usage-cache-read">—</span><span class="metric-unit">tok</span></div>
|
|
334
|
+
</div>
|
|
335
|
+
<div class="metric metric-soft">
|
|
336
|
+
<div class="metric-label">Cache writes</div>
|
|
337
|
+
<div class="metric-val"><span id="usage-cache-write">—</span><span class="metric-unit">tok</span></div>
|
|
338
|
+
</div>
|
|
178
339
|
</div>
|
|
179
340
|
</div>
|
|
180
341
|
|
|
@@ -183,7 +344,7 @@
|
|
|
183
344
|
<div class="chart-frame">
|
|
184
345
|
<canvas id="chart-byday" width="900" height="220" aria-label="Calls per day, last 30 days"></canvas>
|
|
185
346
|
</div>
|
|
186
|
-
<p class="muted
|
|
347
|
+
<p class="muted xsmall">Bars are call counts per UTC day. Empty days show no bar.</p>
|
|
187
348
|
</div>
|
|
188
349
|
|
|
189
350
|
<!-- By model -->
|
|
@@ -193,7 +354,7 @@
|
|
|
193
354
|
</div>
|
|
194
355
|
<table class="data-table" aria-label="By model breakdown">
|
|
195
356
|
<thead>
|
|
196
|
-
<tr><th>Model</th><th class="num">Calls</th><th class="num">Input
|
|
357
|
+
<tr><th>Model</th><th class="num">Calls</th><th class="num">Input</th><th class="num">Output</th><th class="num">Spend (PTON)</th></tr>
|
|
197
358
|
</thead>
|
|
198
359
|
<tbody id="bymodel-rows"></tbody>
|
|
199
360
|
</table>
|
|
@@ -203,7 +364,7 @@
|
|
|
203
364
|
<div class="tab-pane" data-pane="bykey" hidden>
|
|
204
365
|
<table class="data-table" aria-label="Per-API-key usage">
|
|
205
366
|
<thead>
|
|
206
|
-
<tr><th>Key</th><th>Name</th><th class="num">Calls</th><th class="num">Input
|
|
367
|
+
<tr><th>Key</th><th>Name</th><th class="num">Calls</th><th class="num">Input</th><th class="num">Output</th><th class="num">Spend (PTON)</th><th>Last used</th></tr>
|
|
207
368
|
</thead>
|
|
208
369
|
<tbody id="bykey-rows"></tbody>
|
|
209
370
|
</table>
|
|
@@ -218,7 +379,7 @@
|
|
|
218
379
|
<tbody id="calls-rows"></tbody>
|
|
219
380
|
</table>
|
|
220
381
|
<div class="pager">
|
|
221
|
-
<button id="calls-load-more" class="btn btn-ghost" type="button">Load older</button>
|
|
382
|
+
<button id="calls-load-more" class="btn btn-ghost btn-small" type="button">Load older</button>
|
|
222
383
|
<span id="calls-status" class="muted small"></span>
|
|
223
384
|
</div>
|
|
224
385
|
</div>
|
|
@@ -226,12 +387,15 @@
|
|
|
226
387
|
|
|
227
388
|
<!-- ---- API keys ---- -->
|
|
228
389
|
<section class="card section-card">
|
|
229
|
-
<header>
|
|
230
|
-
<
|
|
231
|
-
|
|
390
|
+
<header class="card-header">
|
|
391
|
+
<div>
|
|
392
|
+
<div class="card-eyebrow">Auth</div>
|
|
393
|
+
<h2 class="card-title">API keys</h2>
|
|
394
|
+
</div>
|
|
395
|
+
<span class="card-tag">For Claude Code / anthropic-sdk · <code>x-api-key</code></span>
|
|
232
396
|
</header>
|
|
233
397
|
<form id="key-create-form" class="key-create">
|
|
234
|
-
<input id="key-name" type="text" maxlength="64" placeholder="
|
|
398
|
+
<input id="key-name" type="text" maxlength="64" placeholder="Key name (optional, e.g. claude-code-laptop)" />
|
|
235
399
|
<button class="btn btn-primary" type="submit">Mint key</button>
|
|
236
400
|
</form>
|
|
237
401
|
<p id="key-create-status" class="status-line" role="status" aria-live="polite"></p>
|
|
@@ -248,19 +412,41 @@
|
|
|
248
412
|
<!-- One-shot key reveal modal — appears after a successful POST /v1/keys -->
|
|
249
413
|
<div id="key-modal" class="modal" hidden role="dialog" aria-modal="true" aria-labelledby="key-modal-title">
|
|
250
414
|
<div class="modal-body">
|
|
415
|
+
<div class="modal-eyebrow">One-time secret</div>
|
|
251
416
|
<h2 id="key-modal-title">Save this key — shown once</h2>
|
|
252
417
|
<p class="muted small">The proxy stores only an HMAC of the key. If you lose the plaintext, mint a new one.</p>
|
|
253
418
|
<pre id="key-modal-value" class="key-value">sk-ai-…</pre>
|
|
254
419
|
<div class="modal-actions">
|
|
255
|
-
<button id="key-modal-
|
|
420
|
+
<button id="key-modal-install" class="btn btn-primary" type="button">Install & Restart Agent</button>
|
|
421
|
+
<button id="key-modal-copy" class="btn btn-ghost" type="button">Copy</button>
|
|
256
422
|
<button id="key-modal-close" class="btn btn-ghost" type="button">I have saved it</button>
|
|
257
423
|
</div>
|
|
258
424
|
<p id="key-modal-copy-status" class="status-line" role="status" aria-live="polite"></p>
|
|
259
425
|
</div>
|
|
260
426
|
</div>
|
|
261
427
|
|
|
428
|
+
<!-- Confirm-restart modal: shown before posting to /v1/keys/install. -->
|
|
429
|
+
<div id="key-install-modal" class="modal" hidden role="dialog" aria-modal="true" aria-labelledby="key-install-title">
|
|
430
|
+
<div class="modal-body">
|
|
431
|
+
<div class="modal-eyebrow">Confirm install</div>
|
|
432
|
+
<h2 id="key-install-title">Install this key into your local .env?</h2>
|
|
433
|
+
<p class="muted small">
|
|
434
|
+
This will write <code>BILLING_CHAT_KEY=<key></code> into the
|
|
435
|
+
<code>.env</code> in your project root and restart the agent so the
|
|
436
|
+
new key takes effect. The chat will be unavailable for a few seconds
|
|
437
|
+
while it relaunches.
|
|
438
|
+
</p>
|
|
439
|
+
<p class="muted small">If your agent isn't running under a supervisor (the standard <code>bun dev</code> setup), you may need to relaunch it manually.</p>
|
|
440
|
+
<div class="modal-actions">
|
|
441
|
+
<button id="key-install-confirm" class="btn btn-primary" type="button">Install & restart</button>
|
|
442
|
+
<button id="key-install-cancel" class="btn btn-ghost" type="button">Cancel</button>
|
|
443
|
+
</div>
|
|
444
|
+
<p id="key-install-status" class="status-line" role="status" aria-live="polite"></p>
|
|
445
|
+
</div>
|
|
446
|
+
</div>
|
|
447
|
+
|
|
262
448
|
<footer>
|
|
263
|
-
<span class="muted small">SIWE-protected
|
|
449
|
+
<span class="muted small">SIWE-protected · 90-day call audit log · <a href="/" target="_blank" rel="noopener">project landing</a></span>
|
|
264
450
|
</footer>
|
|
265
451
|
|
|
266
452
|
<script src="app.js" defer></script>
|