@juspay/shooter 1.6.0 → 1.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/client/_app/immutable/assets/0.BXHU1bFd.css +1 -0
- package/build/client/_app/immutable/assets/0.BXHU1bFd.css.br +0 -0
- package/build/client/_app/immutable/assets/0.BXHU1bFd.css.gz +0 -0
- package/build/client/_app/immutable/assets/{2.Dk9NfqnS.css → 2.Bxu934IC.css} +1 -1
- package/build/client/_app/immutable/assets/2.Bxu934IC.css.br +0 -0
- package/build/client/_app/immutable/assets/2.Bxu934IC.css.gz +0 -0
- package/build/client/_app/immutable/chunks/{CqfYvnci.js → B7UYUXav.js} +1 -1
- package/build/client/_app/immutable/chunks/B7UYUXav.js.br +0 -0
- package/build/client/_app/immutable/chunks/B7UYUXav.js.gz +0 -0
- package/build/client/_app/immutable/chunks/{y_g-KC7l.js → CAWtH3Iy.js} +1 -1
- package/build/client/_app/immutable/chunks/CAWtH3Iy.js.br +0 -0
- package/build/client/_app/immutable/chunks/{y_g-KC7l.js.gz → CAWtH3Iy.js.gz} +0 -0
- package/build/client/_app/immutable/chunks/{EhLZwqfu.js → DMGoTOyn.js} +2 -2
- package/build/client/_app/immutable/chunks/DMGoTOyn.js.br +0 -0
- package/build/client/_app/immutable/chunks/DMGoTOyn.js.gz +0 -0
- package/build/client/_app/immutable/entry/{app.zJvbFXsj.js → app.DLyiS7a7.js} +2 -2
- package/build/client/_app/immutable/entry/app.DLyiS7a7.js.br +0 -0
- package/build/client/_app/immutable/entry/app.DLyiS7a7.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.iu831vTf.js +1 -0
- package/build/client/_app/immutable/entry/start.iu831vTf.js.br +2 -0
- package/build/client/_app/immutable/entry/start.iu831vTf.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{0.B_E4j3MX.js → 0.B76xpgU3.js} +1 -1
- package/build/client/_app/immutable/nodes/0.B76xpgU3.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.B76xpgU3.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{1.B0oFqb8X.js → 1.C8HQaM7E.js} +1 -1
- package/build/client/_app/immutable/nodes/1.C8HQaM7E.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.C8HQaM7E.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.BAtXcLWF.js +13 -0
- package/build/client/_app/immutable/nodes/2.BAtXcLWF.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.BAtXcLWF.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{3.CTqUQKSN.js → 3.CYU2wJvk.js} +1 -1
- package/build/client/_app/immutable/nodes/3.CYU2wJvk.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CYU2wJvk.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{6.BvjUfHnH.js → 6.C_uZdnK8.js} +1 -1
- package/build/client/_app/immutable/nodes/6.C_uZdnK8.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.C_uZdnK8.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{7.5K7Od8ba.js → 7.Cuv-AoHz.js} +1 -1
- package/build/client/_app/immutable/nodes/7.Cuv-AoHz.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.Cuv-AoHz.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{8.Bs1DrW0_.js → 8.jzwOIQUM.js} +1 -1
- package/build/client/_app/immutable/nodes/8.jzwOIQUM.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.jzwOIQUM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/{9.1fMlGdqv.js → 9.BDETv_rs.js} +1 -1
- package/build/client/_app/immutable/nodes/9.BDETv_rs.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.BDETv_rs.js.gz +0 -0
- package/build/client/_app/version.json +1 -1
- package/build/client/_app/version.json.br +0 -0
- package/build/client/_app/version.json.gz +0 -0
- package/build/server/chunks/{0-e1fgD9Mi.js → 0-JnYsOPFg.js} +4 -4
- package/build/server/chunks/{0-e1fgD9Mi.js.map → 0-JnYsOPFg.js.map} +1 -1
- package/build/server/chunks/{1-D2_XVthm.js → 1-uXVmLPvu.js} +3 -3
- package/build/server/chunks/{1-D2_XVthm.js.map → 1-uXVmLPvu.js.map} +1 -1
- package/build/server/chunks/{2-DADX86JZ.js → 2-CVN3QR62.js} +4 -4
- package/build/server/chunks/{2-DADX86JZ.js.map → 2-CVN3QR62.js.map} +1 -1
- package/build/server/chunks/{3-CHacdiCg.js → 3-BGXBcTfb.js} +3 -3
- package/build/server/chunks/{3-CHacdiCg.js.map → 3-BGXBcTfb.js.map} +1 -1
- package/build/server/chunks/{4-0UE_6Ep-.js → 4-DOCzBx63.js} +2 -2
- package/build/server/chunks/{4-0UE_6Ep-.js.map → 4-DOCzBx63.js.map} +1 -1
- package/build/server/chunks/{5-BBIP1PzX.js → 5-7A7zBuKk.js} +2 -2
- package/build/server/chunks/{5-BBIP1PzX.js.map → 5-7A7zBuKk.js.map} +1 -1
- package/build/server/chunks/{6-CWLNQu6F.js → 6-DWdCl-Zi.js} +3 -3
- package/build/server/chunks/{6-CWLNQu6F.js.map → 6-DWdCl-Zi.js.map} +1 -1
- package/build/server/chunks/{7-DmQ3B8uy.js → 7-DUY-pQp0.js} +3 -3
- package/build/server/chunks/{7-DmQ3B8uy.js.map → 7-DUY-pQp0.js.map} +1 -1
- package/build/server/chunks/{8-CnFVjQtZ.js → 8-vdkbC7-0.js} +3 -3
- package/build/server/chunks/{8-CnFVjQtZ.js.map → 8-vdkbC7-0.js.map} +1 -1
- package/build/server/chunks/{9-Dw7-P6aF.js → 9-Bo4T88xL.js} +3 -3
- package/build/server/chunks/{9-Dw7-P6aF.js.map → 9-Bo4T88xL.js.map} +1 -1
- package/build/server/chunks/{Button-WKgiLWZI.js → Button-DdjxOkSZ.js} +2 -2
- package/build/server/chunks/{Button-WKgiLWZI.js.map → Button-DdjxOkSZ.js.map} +1 -1
- package/build/server/chunks/{EmptyState-BUBqASsp.js → EmptyState-Do0HSexX.js} +3 -3
- package/build/server/chunks/{EmptyState-BUBqASsp.js.map → EmptyState-Do0HSexX.js.map} +1 -1
- package/build/server/chunks/{Icon-BNBAg85a.js → Icon-CmfQpMj8.js} +2 -2
- package/build/server/chunks/{Icon-BNBAg85a.js.map → Icon-CmfQpMj8.js.map} +1 -1
- package/build/server/chunks/{Shimmer-C4uBVwxz.js → Shimmer-5rSdw-ut.js} +2 -2
- package/build/server/chunks/{Shimmer-C4uBVwxz.js.map → Shimmer-5rSdw-ut.js.map} +1 -1
- package/build/server/chunks/{_error.svelte-DkIwmECt.js → _error.svelte-B3eSa4PI.js} +5 -5
- package/build/server/chunks/{_error.svelte-DkIwmECt.js.map → _error.svelte-B3eSa4PI.js.map} +1 -1
- package/build/server/chunks/{_layout.svelte-DllETxmJ.js → _layout.svelte-DIibCT-o.js} +6 -6
- package/build/server/chunks/{_layout.svelte-DllETxmJ.js.map → _layout.svelte-DIibCT-o.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-BZSdLKE_.js → _page.svelte-BCVxxMg-.js} +4 -4
- package/build/server/chunks/{_page.svelte-BZSdLKE_.js.map → _page.svelte-BCVxxMg-.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-Co5sF7W-.js → _page.svelte-BnIJOtvm.js} +11 -11
- package/build/server/chunks/{_page.svelte-Co5sF7W-.js.map → _page.svelte-BnIJOtvm.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-Cmuco1mC.js → _page.svelte-D4TBiar7.js} +5 -5
- package/build/server/chunks/{_page.svelte-Cmuco1mC.js.map → _page.svelte-D4TBiar7.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-JIkgFUFf.js → _page.svelte-DQZWJdHb.js} +4 -4
- package/build/server/chunks/{_page.svelte-JIkgFUFf.js.map → _page.svelte-DQZWJdHb.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-fcX09N4d.js → _page.svelte-DYhv6WTT.js} +9 -9
- package/build/server/chunks/{_page.svelte-fcX09N4d.js.map → _page.svelte-DYhv6WTT.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-Y9-O5a5w.js → _page.svelte-DZK06z97.js} +8 -8
- package/build/server/chunks/{_page.svelte-Y9-O5a5w.js.map → _page.svelte-DZK06z97.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-CpL3R-VI.js → _page.svelte-qNZy4ITB.js} +8 -8
- package/build/server/chunks/{_page.svelte-CpL3R-VI.js.map → _page.svelte-qNZy4ITB.js.map} +1 -1
- package/build/server/chunks/{_page.svelte-DDSzYLUs.js → _page.svelte-vwYD3-TB.js} +29 -12
- package/build/server/chunks/_page.svelte-vwYD3-TB.js.map +1 -0
- package/build/server/chunks/{_server.ts-ByIrRtCx.js → _server.ts-BQarRaho.js} +138 -87
- package/build/server/chunks/_server.ts-BQarRaho.js.map +1 -0
- package/build/server/chunks/{_server.ts-B__YN2kX.js → _server.ts-G8OeADGj.js} +21 -3
- package/build/server/chunks/_server.ts-G8OeADGj.js.map +1 -0
- package/build/server/chunks/{client-DRtPDkMh.js → client-CHdjSh4H.js} +4 -4
- package/build/server/chunks/{client-DRtPDkMh.js.map → client-CHdjSh4H.js.map} +1 -1
- package/build/server/chunks/client2-BTUnRGQp.js +7 -0
- package/build/server/chunks/{client2-bqqmu0b7.js.map → client2-BTUnRGQp.js.map} +1 -1
- package/build/server/chunks/{close-BGlLztTb.js → close-DAiakm6B.js} +2 -2
- package/build/server/chunks/{close-BGlLztTb.js.map → close-DAiakm6B.js.map} +1 -1
- package/build/server/chunks/{index-DP9bWJrR.js → index-C2COL4R7.js} +2 -2
- package/build/server/chunks/{index-DP9bWJrR.js.map → index-C2COL4R7.js.map} +1 -1
- package/build/server/chunks/{index-server-BUmV4MIG.js → index-server-Cpgjzv_S.js} +2 -2
- package/build/server/chunks/{index-server-BUmV4MIG.js.map → index-server-Cpgjzv_S.js.map} +1 -1
- package/build/server/chunks/{index2-D5Y19GKR.js → index2-CKXBGyRH.js} +2 -2
- package/build/server/chunks/{index2-D5Y19GKR.js.map → index2-CKXBGyRH.js.map} +1 -1
- package/build/server/chunks/{root-CATOR_0t.js → root-CeOG24Ij.js} +2 -2
- package/build/server/chunks/{root-CATOR_0t.js.map → root-CeOG24Ij.js.map} +1 -1
- package/build/server/chunks/{state.svelte-CftllyvC.js → state.svelte-BMNP49Le.js} +3 -3
- package/build/server/chunks/{state.svelte-CftllyvC.js.map → state.svelte-BMNP49Le.js.map} +1 -1
- package/build/server/chunks/{stores-BjL57aOK.js → stores-NzQ5oCpr.js} +4 -4
- package/build/server/chunks/{stores-BjL57aOK.js.map → stores-NzQ5oCpr.js.map} +1 -1
- package/build/server/index.js +4 -4
- package/build/server/index.js.map +1 -1
- package/build/server/manifest.js +13 -13
- package/build/server/manifest.js.map +1 -1
- package/package.json +1 -1
- package/src/app.css +41 -18
- package/src/lib/modules/server/sessions/jsonl-reader.ts +178 -108
- package/src/routes/+page.svelte +60 -2
- package/src/routes/api/notify/+server.ts +31 -3
- package/build/client/_app/immutable/assets/0.BhZOCxO4.css +0 -1
- package/build/client/_app/immutable/assets/0.BhZOCxO4.css.br +0 -0
- package/build/client/_app/immutable/assets/0.BhZOCxO4.css.gz +0 -0
- package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.br +0 -0
- package/build/client/_app/immutable/assets/2.Dk9NfqnS.css.gz +0 -0
- package/build/client/_app/immutable/chunks/CqfYvnci.js.br +0 -0
- package/build/client/_app/immutable/chunks/CqfYvnci.js.gz +0 -0
- package/build/client/_app/immutable/chunks/EhLZwqfu.js.br +0 -0
- package/build/client/_app/immutable/chunks/EhLZwqfu.js.gz +0 -0
- package/build/client/_app/immutable/chunks/y_g-KC7l.js.br +0 -0
- package/build/client/_app/immutable/entry/app.zJvbFXsj.js.br +0 -0
- package/build/client/_app/immutable/entry/app.zJvbFXsj.js.gz +0 -0
- package/build/client/_app/immutable/entry/start.B2Jf5iFd.js +0 -1
- package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.br +0 -2
- package/build/client/_app/immutable/entry/start.B2Jf5iFd.js.gz +0 -0
- package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.br +0 -0
- package/build/client/_app/immutable/nodes/0.B_E4j3MX.js.gz +0 -0
- package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.br +0 -0
- package/build/client/_app/immutable/nodes/1.B0oFqb8X.js.gz +0 -0
- package/build/client/_app/immutable/nodes/2.Bqul0XyM.js +0 -13
- package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.br +0 -0
- package/build/client/_app/immutable/nodes/2.Bqul0XyM.js.gz +0 -0
- package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.br +0 -0
- package/build/client/_app/immutable/nodes/3.CTqUQKSN.js.gz +0 -0
- package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.br +0 -0
- package/build/client/_app/immutable/nodes/6.BvjUfHnH.js.gz +0 -0
- package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.br +0 -0
- package/build/client/_app/immutable/nodes/7.5K7Od8ba.js.gz +0 -0
- package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.br +0 -0
- package/build/client/_app/immutable/nodes/8.Bs1DrW0_.js.gz +0 -0
- package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.br +0 -0
- package/build/client/_app/immutable/nodes/9.1fMlGdqv.js.gz +0 -0
- package/build/server/chunks/_page.svelte-DDSzYLUs.js.map +0 -1
- package/build/server/chunks/_server.ts-B__YN2kX.js.map +0 -1
- package/build/server/chunks/_server.ts-ByIrRtCx.js.map +0 -1
- package/build/server/chunks/client2-bqqmu0b7.js +0 -7
package/src/routes/+page.svelte
CHANGED
|
@@ -163,6 +163,24 @@
|
|
|
163
163
|
</Button>
|
|
164
164
|
</div>
|
|
165
165
|
</div>
|
|
166
|
+
{#if projects.length > 0}
|
|
167
|
+
<div class="stats-bar">
|
|
168
|
+
<div class="stat-chip">
|
|
169
|
+
<span class="stat-value">{projects.length}</span>
|
|
170
|
+
<span class="stat-label">{projects.length === 1 ? 'project' : 'projects'}</span>
|
|
171
|
+
</div>
|
|
172
|
+
<div class="stat-chip">
|
|
173
|
+
<span class="stat-value">{totalSessionCount()}</span>
|
|
174
|
+
<span class="stat-label">{totalSessionCount() === 1 ? 'session' : 'sessions'}</span>
|
|
175
|
+
</div>
|
|
176
|
+
{#if cards.length > 0}
|
|
177
|
+
<div class="stat-chip stat-chip-active">
|
|
178
|
+
<span class="stat-value">{cards.length}</span>
|
|
179
|
+
<span class="stat-label">active</span>
|
|
180
|
+
</div>
|
|
181
|
+
{/if}
|
|
182
|
+
</div>
|
|
183
|
+
{/if}
|
|
166
184
|
</div>
|
|
167
185
|
|
|
168
186
|
{#if fetchError}
|
|
@@ -258,7 +276,7 @@
|
|
|
258
276
|
|
|
259
277
|
.page-title {
|
|
260
278
|
font-size: var(--text-2xl);
|
|
261
|
-
font-weight:
|
|
279
|
+
font-weight: 700;
|
|
262
280
|
letter-spacing: -0.03em;
|
|
263
281
|
color: var(--text-primary);
|
|
264
282
|
margin-bottom: var(--space-1);
|
|
@@ -275,6 +293,42 @@
|
|
|
275
293
|
flex-shrink: 0;
|
|
276
294
|
}
|
|
277
295
|
|
|
296
|
+
.stats-bar {
|
|
297
|
+
display: flex;
|
|
298
|
+
gap: 10px;
|
|
299
|
+
margin-top: var(--space-4);
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
.stat-chip {
|
|
303
|
+
display: flex;
|
|
304
|
+
align-items: center;
|
|
305
|
+
gap: 6px;
|
|
306
|
+
background: rgba(255, 255, 255, 0.04);
|
|
307
|
+
border: 1px solid rgba(255, 255, 255, 0.06);
|
|
308
|
+
border-radius: 20px;
|
|
309
|
+
padding: 6px 14px;
|
|
310
|
+
}
|
|
311
|
+
|
|
312
|
+
.stat-chip-active {
|
|
313
|
+
background: rgba(34, 197, 94, 0.1);
|
|
314
|
+
border-color: rgba(34, 197, 94, 0.25);
|
|
315
|
+
}
|
|
316
|
+
|
|
317
|
+
.stat-value {
|
|
318
|
+
font-weight: 700;
|
|
319
|
+
font-size: 0.9rem;
|
|
320
|
+
color: #f0f0f0;
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
.stat-chip-active .stat-value {
|
|
324
|
+
color: #22c55e;
|
|
325
|
+
}
|
|
326
|
+
|
|
327
|
+
.stat-label {
|
|
328
|
+
font-size: 0.78rem;
|
|
329
|
+
color: rgba(163, 163, 163, 0.8);
|
|
330
|
+
}
|
|
331
|
+
|
|
278
332
|
.dashboard-section {
|
|
279
333
|
margin-bottom: var(--space-6);
|
|
280
334
|
}
|
|
@@ -291,7 +345,7 @@
|
|
|
291
345
|
.projects-container {
|
|
292
346
|
display: flex;
|
|
293
347
|
flex-direction: column;
|
|
294
|
-
gap: var(--space-
|
|
348
|
+
gap: var(--space-3);
|
|
295
349
|
animation: fadeIn 0.2s ease;
|
|
296
350
|
}
|
|
297
351
|
|
|
@@ -300,6 +354,10 @@
|
|
|
300
354
|
flex-direction: column;
|
|
301
355
|
gap: var(--space-4);
|
|
302
356
|
}
|
|
357
|
+
|
|
358
|
+
.stats-bar {
|
|
359
|
+
flex-wrap: wrap;
|
|
360
|
+
}
|
|
303
361
|
}
|
|
304
362
|
|
|
305
363
|
@media (max-width: 480px) {
|
|
@@ -9,9 +9,31 @@ import { isFCMConfigured, sendFCMNotification } from '$lib/modules/server/fcm/fc
|
|
|
9
9
|
import { toErrorMessage } from '$lib/modules/server/utils/error';
|
|
10
10
|
import { broadcastEvent } from '$lib/modules/server/ws/server';
|
|
11
11
|
import { json } from '@sveltejs/kit';
|
|
12
|
+
import { existsSync, readFileSync } from 'fs';
|
|
13
|
+
import { homedir } from 'os';
|
|
14
|
+
import { join } from 'path';
|
|
12
15
|
|
|
13
16
|
import type { RequestHandler } from './$types';
|
|
14
17
|
|
|
18
|
+
// Reads tokens persisted by /api/device-token — populated automatically when
|
|
19
|
+
// the Android or iOS app registers on first launch.
|
|
20
|
+
function readPersistedDeviceToken(platform: 'android' | 'ios'): string | undefined {
|
|
21
|
+
const tokensFile = join(homedir(), '.shooter', 'device-tokens.json');
|
|
22
|
+
if (!existsSync(tokensFile)) {
|
|
23
|
+
return undefined;
|
|
24
|
+
}
|
|
25
|
+
try {
|
|
26
|
+
const parsed: unknown = JSON.parse(readFileSync(tokensFile, 'utf-8'));
|
|
27
|
+
if (parsed && typeof parsed === 'object' && !Array.isArray(parsed)) {
|
|
28
|
+
const value = (parsed as Record<string, unknown>)[platform];
|
|
29
|
+
return typeof value === 'string' && value ? value : undefined;
|
|
30
|
+
}
|
|
31
|
+
} catch {
|
|
32
|
+
// corrupt / unreadable — fall through
|
|
33
|
+
}
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
|
|
15
37
|
// Singleton APNs client - reuses HTTP/2 connection across requests
|
|
16
38
|
let apnsSingleton: LibraryAPNsService | null = null;
|
|
17
39
|
function getAPNsClient(): LibraryAPNsService {
|
|
@@ -376,15 +398,21 @@ export const POST: RequestHandler = async ({ request }) => {
|
|
|
376
398
|
);
|
|
377
399
|
}
|
|
378
400
|
|
|
379
|
-
// Honor request-scoped deviceToken,
|
|
401
|
+
// Honor request-scoped deviceToken, then the Android-specific env var,
|
|
402
|
+
// then the token auto-registered by the Android app via /api/device-token.
|
|
403
|
+
// env.DEVICE_TOKEN is intentionally NOT in this chain: the iOS branch
|
|
404
|
+
// treats it as an APNs token (see below), and letting it bleed into the
|
|
405
|
+
// FCM path would ship an APNs token to FCM in mixed-platform setups.
|
|
380
406
|
const androidToken =
|
|
381
|
-
requestDeviceToken?.trim() ||
|
|
407
|
+
requestDeviceToken?.trim() ||
|
|
408
|
+
env.ANDROID_DEVICE_TOKEN?.trim() ||
|
|
409
|
+
readPersistedDeviceToken('android');
|
|
382
410
|
|
|
383
411
|
if (!androidToken) {
|
|
384
412
|
return json(
|
|
385
413
|
{
|
|
386
414
|
details:
|
|
387
|
-
'
|
|
415
|
+
'No Android device token available — set ANDROID_DEVICE_TOKEN, pass deviceToken in the request body, or open the Android app so it can auto-register its FCM token.',
|
|
388
416
|
error: 'No device token configured',
|
|
389
417
|
},
|
|
390
418
|
{ status: 500 }
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
:root{--ds-background-100: #0a0a0a;--ds-background-200: #000000;--ds-gray-100: #1a1a1a;--ds-gray-200: #1f1f1f;--ds-gray-300: #292929;--ds-gray-400: #2e2e2e;--ds-gray-500: #454545;--ds-gray-600: #878787;--ds-gray-700: #8f8f8f;--ds-gray-800: #7d7d7d;--ds-gray-900: #a1a1a1;--ds-gray-1000: #ededed;--ds-gray-alpha-100: rgba(255, 255, 255, .06);--ds-gray-alpha-200: rgba(255, 255, 255, .09);--ds-gray-alpha-300: rgba(255, 255, 255, .13);--ds-gray-alpha-400: rgba(255, 255, 255, .14);--ds-blue-100: #0d1d33;--ds-blue-700: #0070f3;--ds-blue-900: #52a8ff;--ds-red-100: #2a1314;--ds-red-700: #e5484d;--ds-red-900: #ff6166;--ds-green-100: #0d1f12;--ds-green-700: #46a758;--ds-green-900: #62c073;--ds-amber-100: #271700;--ds-amber-700: #f5a623;--ds-amber-900: #ffb224;--background: var(--ds-background-100);--background-secondary: var(--ds-background-200);--component-bg: var(--ds-gray-100);--component-bg-hover: var(--ds-gray-200);--component-bg-active: var(--ds-gray-300);--border: var(--ds-gray-400);--border-hover: var(--ds-gray-500);--border-active: var(--ds-gray-600);--text-primary: var(--ds-gray-1000);--text-secondary: var(--ds-gray-900);--text-tertiary: var(--ds-gray-800);--font-sans: "Geist", -apple-system, "BlinkMacSystemFont", "Segoe UI", "Roboto", "Oxygen", "Ubuntu", "Cantarell", "Fira Sans", "Droid Sans", "Helvetica Neue", sans-serif;--font-mono: "Geist Mono", "SF Mono", Monaco, "Cascadia Code", "Roboto Mono", monospace;--text-xs: 12px;--text-sm: 13px;--text-base: 14px;--text-md: 15px;--text-lg: 16px;--text-xl: 20px;--text-2xl: 24px;--text-3xl: 32px;--text-4xl: 40px;--leading-none: 1;--leading-tight: 1.25;--leading-snug: 1.375;--leading-normal: 1.5;--leading-relaxed: 1.625;--tracking-tighter: -.04em;--tracking-tight: -.02em;--tracking-normal: 0;--space-0: 0;--space-1: 4px;--space-2: 8px;--space-3: 12px;--space-4: 16px;--space-5: 20px;--space-6: 24px;--space-8: 32px;--space-10: 40px;--space-12: 48px;--space-16: 64px;--radius-sm: 4px;--radius-md: 6px;--radius-lg: 8px;--radius-xl: 12px;--radius-full: 9999px;--transition-fast: .15s ease;--transition-normal: .2s ease;--max-width: 1100px;--header-height: 64px}*,*:before,*:after{margin:0;padding:0;box-sizing:border-box}html{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale;text-rendering:optimizeLegibility}body{font-family:var(--font-sans);font-size:var(--text-base);line-height:var(--leading-normal);background:var(--background);color:var(--text-primary);min-height:100vh}.app{height:100vh;display:flex;flex-direction:column;overflow:hidden}.header{height:var(--header-height);background:var(--background);border-bottom:1px solid var(--border);position:sticky;top:0;z-index:100}.header-content{max-width:var(--max-width);height:100%;margin:0 auto;padding:0 var(--space-6);display:flex;justify-content:space-between;align-items:center}.logo{display:flex;align-items:center;gap:var(--space-3);text-decoration:none;color:inherit}.logo-icon{width:24px;height:24px;flex-shrink:0}.logo-text{font-size:var(--text-md);font-weight:500;letter-spacing:var(--tracking-tight);color:var(--text-primary)}.nav{display:flex;align-items:center;gap:var(--space-1)}.nav-link{display:flex;align-items:center;gap:var(--space-2);padding:var(--space-2) var(--space-3);border-radius:var(--radius-md);font-size:var(--text-sm);font-weight:400;color:var(--text-secondary);text-decoration:none;background:transparent;border:none;cursor:pointer;transition:color var(--transition-fast),background var(--transition-fast)}.nav-link:hover{color:var(--text-primary);background:var(--component-bg)}.nav-link.active{color:var(--text-primary)}.main{flex:1;max-width:var(--max-width);width:100%;margin:0 auto;padding:var(--space-8) var(--space-6)}.page-header{margin-bottom:var(--space-8)}.page-title{font-size:var(--text-2xl);font-weight:600;letter-spacing:var(--tracking-tighter);color:var(--text-primary);line-height:var(--leading-tight);margin-bottom:var(--space-2)}.page-description{font-size:var(--text-sm);color:var(--text-secondary);line-height:var(--leading-normal)}.card{background:var(--component-bg);border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}.card-header{padding:var(--space-4) var(--space-5);border-bottom:1px solid var(--ds-gray-alpha-200)}.card-title{font-size:var(--text-sm);font-weight:500;color:var(--text-primary);line-height:var(--leading-tight)}.card-description{font-size:var(--text-sm);color:var(--text-tertiary);margin-top:var(--space-1);line-height:var(--leading-normal)}.card-content{padding:var(--space-5)}.status-badge{display:inline-flex;align-items:center;gap:var(--space-2);height:26px;padding:0 var(--space-3);border-radius:var(--radius-full);font-size:var(--text-xs);font-weight:500;text-transform:uppercase;letter-spacing:.02em}.status-badge.online{background:var(--ds-green-100);color:var(--ds-green-900)}.status-badge.offline{background:var(--ds-red-100);color:var(--ds-red-900)}.status-badge.degraded{background:var(--ds-amber-100);color:var(--ds-amber-900)}.status-dot{width:6px;height:6px;border-radius:50%;background:currentColor}.empty-state{display:flex;flex-direction:column;align-items:center;text-align:center;padding:var(--space-16) var(--space-6)}@media(max-width:768px){.empty-state{padding:var(--space-8) var(--space-4)}}@media(max-width:480px){.empty-state{padding:var(--space-6) var(--space-3)}}.empty-state-icon{width:48px;height:48px;margin:0 auto var(--space-5);background:var(--component-bg);border-radius:var(--radius-lg);display:flex;align-items:center;justify-content:center}.empty-state-icon svg{width:24px;height:24px;color:var(--text-tertiary)}.empty-state-title{font-size:var(--text-lg);font-weight:600;color:var(--text-primary);margin-bottom:var(--space-2)}.empty-state-description{font-size:var(--text-sm);color:var(--text-secondary);max-width:320px;margin:0 auto var(--space-6);line-height:var(--leading-relaxed)}.list{border:1px solid var(--border);border-radius:var(--radius-lg);overflow:hidden}.list-item{display:flex;align-items:center;padding:var(--space-4) var(--space-5);background:var(--component-bg);border-bottom:1px solid var(--ds-gray-alpha-200);transition:background var(--transition-fast)}.list-item:last-child{border-bottom:none}.list-item:hover{background:var(--component-bg-hover)}.code{font-family:var(--font-mono);font-size:var(--text-xs);background:var(--component-bg);padding:var(--space-1) var(--space-2);border-radius:var(--radius-sm);color:var(--text-secondary)}.divider{height:1px;background:var(--border);margin:var(--space-6) 0}@keyframes spin{to{transform:rotate(360deg)}}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(4px)}to{opacity:1;transform:translateY(0)}}.sr-only{position:absolute;width:1px;height:1px;padding:0;margin:-1px;overflow:hidden;clip:rect(0,0,0,0);white-space:nowrap;border:0}@media(max-width:768px){:root{--header-height: 56px}.header-content{padding:0 var(--space-4)}.main{padding:var(--space-6) var(--space-4)}.page-title{font-size:var(--text-xl)}.hide-mobile{display:none}}@media(max-width:480px){:root{--header-height: 48px}.main{padding:var(--space-4) var(--space-3)}.header-content{padding:0 var(--space-3)}.logo{gap:var(--space-2)}.logo-text{font-size:var(--text-sm)}.nav{gap:0}.nav-link{padding:var(--space-3) var(--space-2);font-size:13px;min-height:44px;display:inline-flex;align-items:center}.btn{min-height:44px;height:auto;padding:10px 16px}.btn-sm,.input{min-height:44px;height:auto;padding:10px 12px}}.btn:focus-visible,.input:focus-visible,.nav-link:focus-visible{outline:2px solid var(--ds-blue-700);outline-offset:2px}@media(prefers-reduced-motion:reduce){*,*:before,*:after{animation-duration:.01ms!important;animation-iteration-count:1!important;transition-duration:.01ms!important}}::selection{background:var(--ds-blue-700);color:#fff}::-webkit-scrollbar{width:8px;height:8px}::-webkit-scrollbar-track{background:transparent}::-webkit-scrollbar-thumb{background:var(--ds-gray-400);border-radius:var(--radius-full)}::-webkit-scrollbar-thumb:hover{background:var(--ds-gray-500)}.session-card{background:var(--bg-secondary, #141414);border:1px solid var(--border, #2a2a2a);border-radius:var(--radius-lg, 12px);padding:var(--space-4, 1rem) var(--space-5, 1.25rem);cursor:pointer;transition:border-color var(--transition-fast, .15s),background var(--transition-fast, .15s);display:flex;flex-direction:column;overflow:hidden;min-width:0;gap:var(--space-3, .75rem)}.session-card:hover{border-color:var(--gray-600, #525252);background:var(--bg-tertiary, #1a1a1a)}.session-card-header{display:flex;justify-content:space-between;align-items:flex-start;gap:var(--space-3, .75rem);min-width:0;overflow:hidden}.session-card-header>div:first-child{min-width:0;overflow:hidden}.session-card-title{font-size:1rem;font-weight:600;color:var(--text-primary, #fafafa);margin:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.session-card-subtitle{font-size:.8rem;color:var(--text-tertiary, #737373);font-family:var(--font-mono, monospace);margin-top:2px;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;max-width:100%}.session-stats{display:flex;gap:var(--space-4, 1rem);font-size:.8rem;color:var(--text-secondary, #a3a3a3)}.session-stats strong{color:var(--text-primary, #fafafa);font-weight:600}.session-tools{display:flex;flex-wrap:wrap;gap:6px}.session-tool-pill{padding:3px 8px;border-radius:4px;font-size:.7rem;font-weight:600;font-family:var(--font-mono, monospace);border:1px solid}.session-tool-pill[data-tool=Bash]{background:#f59e0b26;color:#f59e0b;border-color:#f59e0b4d}.session-tool-pill[data-tool=Edit]{background:#3b82f626;color:#3b82f6;border-color:#3b82f64d}.session-tool-pill[data-tool=Write]{background:#8b5cf626;color:#8b5cf6;border-color:#8b5cf64d}.session-tool-pill[data-tool=Read]{background:#10b98126;color:#10b981;border-color:#10b9814d}.session-tool-pill[data-tool=Agent]{background:#ef444426;color:#ef4444;border-color:#ef44444d}.session-tool-pill[data-tool=Build]{background:#06b6d426;color:#06b6d4;border-color:#06b6d44d}.session-tool-pill[data-tool=Test]{background:#ec489926;color:#ec4899;border-color:#ec48994d}.session-tool-pill-default{background:#6b728026;color:#9ca3af;border-color:#6b72804d}.session-tool-more{padding:3px 8px;border-radius:4px;font-size:.7rem;color:var(--text-tertiary, #737373);background:#ffffff0d}.session-duration{font-size:.75rem;color:var(--text-tertiary, #737373)}.session-chevron{color:var(--text-tertiary, #737373);font-size:1.2rem;align-self:center}.session-detail-header{display:flex;align-items:center;gap:var(--space-3, .75rem);margin-bottom:var(--space-4, 1rem)}.session-back-btn{display:inline-flex;align-items:center;justify-content:center;width:36px;height:36px;border-radius:var(--radius-md, 8px);background:var(--bg-secondary, #141414);border:1px solid var(--border, #2a2a2a);color:var(--text-secondary, #a3a3a3);cursor:pointer;transition:all var(--transition-fast, .15s);text-decoration:none;font-size:1.1rem}.session-back-btn:hover{background:var(--bg-tertiary, #1a1a1a);color:var(--text-primary, #fafafa);border-color:var(--gray-600, #525252)}.session-info-bar{display:grid;grid-template-columns:repeat(4,1fr);gap:1px;background:var(--border, #2a2a2a);border:1px solid var(--border, #2a2a2a);border-radius:var(--radius-lg, 12px);overflow:hidden;margin-bottom:var(--space-5, 1.25rem)}.session-info-item{background:var(--bg-secondary, #141414);padding:var(--space-3, .75rem) var(--space-4, 1rem)}.session-info-label{font-size:.65rem;text-transform:uppercase;letter-spacing:.08em;color:var(--text-tertiary, #737373);margin-bottom:4px}.session-info-value{font-size:.9rem;font-weight:500;color:var(--text-primary, #fafafa)}.session-events-list{display:flex;flex-direction:column;gap:0}.session-event{display:grid;grid-template-columns:60px auto 1fr;gap:var(--space-3, .75rem);padding:var(--space-3, .75rem) 0;border-bottom:1px solid var(--border, #2a2a2a);align-items:start}.session-event:last-child{border-bottom:none}.session-event-time{font-family:var(--font-mono, monospace);font-size:.8rem;color:var(--text-tertiary, #737373);padding-top:2px}.session-event-tool{padding:3px 8px;border-radius:4px;font-size:.7rem;font-weight:600;font-family:var(--font-mono, monospace);text-align:center;min-width:50px;border:1px solid}.session-event-content{min-width:0}.session-event-title{font-size:.9rem;color:var(--text-primary, #fafafa);font-weight:500;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.session-event-message{font-size:.8rem;color:var(--text-tertiary, #737373);margin-top:2px;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.session-footer{display:flex;justify-content:space-between;align-items:center;padding-top:var(--space-4, 1rem);margin-top:var(--space-3, .75rem);border-top:1px solid var(--border, #2a2a2a);font-size:.8rem;color:var(--text-secondary, #a3a3a3)}@media(max-width:768px){.session-card{padding:var(--space-3, .75rem)}.session-card-header{flex-direction:column;gap:var(--space-2, .5rem)}.session-badge{align-self:flex-start}.session-stats{flex-wrap:wrap;gap:var(--space-2, .5rem)}.session-info-bar{grid-template-columns:1fr 1fr}.session-event{grid-template-columns:50px auto 1fr;gap:var(--space-2, .5rem)}.session-event-title{white-space:normal}.session-footer{flex-direction:column;gap:var(--space-2, .5rem);align-items:flex-start}}@media(max-width:480px){.session-info-bar{grid-template-columns:1fr}.session-event{grid-template-columns:1fr;gap:var(--space-1, .25rem)}.session-event-time{font-size:.7rem}.session-card{padding:10px 12px;gap:var(--space-2)}.session-card-subtitle{font-size:.7rem}.session-stats{gap:var(--space-1);font-size:.75rem}}.chat-container{display:flex;flex-direction:column;gap:var(--space-4, 1rem);padding:var(--space-4, 1rem) 0;overflow-y:auto;flex:1;min-height:0}.chat-message{display:flex;gap:var(--space-3, .75rem);max-width:85%;animation:fadeInUp .2s ease-out}@keyframes fadeInUp{0%{opacity:0;transform:translateY(8px)}to{opacity:1;transform:translateY(0)}}.chat-message-user{align-self:flex-end;flex-direction:row-reverse}.chat-message-assistant{align-self:flex-start}.chat-message-system{align-self:center;max-width:90%}.chat-avatar{width:28px;height:28px;border-radius:50%;display:flex;align-items:center;justify-content:center;font-size:.75rem;flex-shrink:0;margin-top:4px}.chat-avatar-user{background:#3b82f633;color:#60a5fa;border:1px solid rgba(59,130,246,.3)}.chat-avatar-assistant{background:#f9731633;color:#fb923c;border:1px solid rgba(249,115,22,.3)}.chat-bubble{border-radius:var(--radius-lg, 12px);padding:var(--space-3, .75rem) var(--space-4, 1rem);line-height:1.5;font-size:.9rem;word-break:break-word;overflow-wrap:break-word;min-width:0;overflow:hidden}.chat-bubble-user{background:#1e293b;border:1px solid #334155;color:var(--text-primary, #fafafa);border-bottom-right-radius:4px}.chat-bubble-assistant{background:var(--bg-secondary, #141414);border:1px solid var(--border, #2a2a2a);color:var(--text-primary, #fafafa);border-bottom-left-radius:4px}.chat-bubble p{margin:0 0 .5rem}.chat-bubble p:last-child{margin-bottom:0}.chat-bubble code{background:#ffffff14;padding:2px 6px;border-radius:4px;font-family:var(--font-mono, monospace);font-size:.85em}.chat-bubble pre{background:#0000004d;border:1px solid var(--border, #2a2a2a);border-radius:var(--radius-md, 8px);padding:var(--space-3, .75rem);overflow-x:auto;margin:.5rem 0;font-size:.8rem}@media(max-width:768px){.chat-bubble pre{max-width:calc(100vw - 120px)}}.chat-bubble pre code{background:none;padding:0}.chat-bubble h1,.chat-bubble h2,.chat-bubble h3,.chat-bubble h4{margin:.75rem 0 .25rem;font-weight:600;line-height:1.3;color:var(--text-primary, #fafafa)}.chat-bubble h1{font-size:1.15em}.chat-bubble h2{font-size:1.05em}.chat-bubble h3{font-size:.95em}.chat-bubble h4{font-size:.9em}.chat-bubble h1:first-child,.chat-bubble h2:first-child,.chat-bubble h3:first-child{margin-top:0}.chat-bubble ul,.chat-bubble ol{margin:.4rem 0;padding-left:1.4rem}.chat-bubble li{margin-bottom:.2rem;line-height:1.5}.chat-bubble li>ul,.chat-bubble li>ol{margin:.1rem 0}.chat-bubble blockquote{border-left:3px solid var(--gray-600, #525252);margin:.5rem 0;padding:.25rem .75rem;color:var(--text-secondary, #a3a3a3);font-style:italic}.chat-bubble table{border-collapse:collapse;width:100%;margin:.5rem 0;font-size:.85em}.chat-bubble th,.chat-bubble td{border:1px solid var(--border, #2a2a2a);padding:.35rem .6rem;text-align:left}.chat-bubble th{background:#ffffff0a;font-weight:600}.chat-bubble hr{border:none;border-top:1px solid var(--border, #2a2a2a);margin:.75rem 0}.chat-bubble a{color:#60a5fa;text-decoration:none}.chat-bubble a:hover{text-decoration:underline}.chat-bubble strong{font-weight:600;color:var(--text-primary, #fafafa)}.chat-bubble em{font-style:italic}.chat-bubble img{max-width:100%;border-radius:var(--radius-md, 8px)}.chat-timestamp{font-size:.7rem;color:var(--text-tertiary, #737373);margin-top:4px;padding:0 4px}.chat-message-user .chat-timestamp{text-align:right}.chat-tool-card{background:var(--bg-secondary, #141414);border:1px solid var(--border, #2a2a2a);border-radius:var(--radius-md, 8px);overflow:hidden;margin:var(--space-2, .5rem) 0;max-width:90%;align-self:flex-start}.chat-tool-header{display:flex;align-items:center;gap:var(--space-2, .5rem);padding:var(--space-2, .5rem) var(--space-3, .75rem);cursor:pointer;-webkit-user-select:none;user-select:none;transition:background var(--transition-fast, .15s)}.chat-tool-header:hover{background:#ffffff08}.chat-tool-chevron{font-size:.7rem;color:var(--text-tertiary, #737373);transition:transform .2s ease}.chat-tool-chevron.expanded{transform:rotate(90deg)}.chat-tool-name{font-family:var(--font-mono, monospace);font-size:.75rem;font-weight:600;padding:2px 8px;border-radius:4px;border:1px solid}.chat-tool-name[data-tool=Bash]{background:#f59e0b26;color:#f59e0b;border-color:#f59e0b4d}.chat-tool-name[data-tool=Edit]{background:#3b82f626;color:#3b82f6;border-color:#3b82f64d}.chat-tool-name[data-tool=Write]{background:#8b5cf626;color:#8b5cf6;border-color:#8b5cf64d}.chat-tool-name[data-tool=Read]{background:#10b98126;color:#10b981;border-color:#10b9814d}.chat-tool-name[data-tool=Agent]{background:#ef444426;color:#ef4444;border-color:#ef44444d}.chat-tool-name[data-tool=Grep]{background:#06b6d426;color:#06b6d4;border-color:#06b6d44d}.chat-tool-name[data-tool=Glob]{background:#ec489926;color:#ec4899;border-color:#ec48994d}.chat-tool-name[data-tool=Skill]{background:#a855f726;color:#a855f7;border-color:#a855f74d}.chat-tool-description{font-size:.8rem;color:var(--text-secondary, #a3a3a3);flex:1;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.chat-tool-body{border-top:1px solid var(--border, #2a2a2a);padding:var(--space-3, .75rem);font-family:var(--font-mono, monospace);font-size:.75rem;color:var(--text-secondary, #a3a3a3);max-height:300px;overflow-y:auto;white-space:pre-wrap;word-break:break-all}.chat-tool-result{border-top:1px solid var(--border, #2a2a2a);padding:var(--space-3, .75rem);font-family:var(--font-mono, monospace);font-size:.75rem;max-height:200px;overflow-y:auto;white-space:pre-wrap;word-break:break-all}.chat-tool-result-success{color:#10b981;background:#10b9810d}.chat-tool-result-error{color:#ef4444;background:#ef44440d}.chat-thinking{background:#a855f70d;border:1px dashed rgba(168,85,247,.2);border-radius:var(--radius-md, 8px);padding:var(--space-2, .5rem) var(--space-3, .75rem);margin:var(--space-2, .5rem) 0;max-width:90%;align-self:flex-start}.chat-thinking-header{display:flex;align-items:center;gap:var(--space-2, .5rem);cursor:pointer;font-size:.75rem;color:#a855f7;font-weight:500}.chat-thinking-body{font-size:.8rem;color:var(--text-tertiary, #737373);margin-top:var(--space-2, .5rem);line-height:1.5;max-height:200px;overflow-y:auto}.back-link{display:inline-flex;align-items:center;gap:var(--space-2, .5rem);font-size:.85rem;color:var(--text-secondary, #a3a3a3);text-decoration:none;margin-bottom:var(--space-3, .75rem);transition:color var(--transition-fast, .15s);min-height:44px;padding:8px 4px}.back-link:hover{color:var(--text-primary, #fafafa)}.chat-session-header{background:var(--bg-secondary, #141414);border:1px solid var(--border, #2a2a2a);border-radius:var(--radius-lg, 12px);padding:var(--space-4, 1rem) var(--space-5, 1.25rem);margin-bottom:var(--space-4, 1rem)}.chat-session-title{font-size:1.1rem;font-weight:600;color:var(--text-primary, #fafafa);margin-bottom:var(--space-1, .25rem)}.chat-session-meta{display:flex;flex-wrap:wrap;gap:var(--space-3, .75rem);font-size:.8rem;color:var(--text-tertiary, #737373)}.chat-session-meta-item{display:flex;align-items:center;gap:4px}@media(max-width:768px){.chat-container{overflow-x:hidden}.chat-message{max-width:95%;min-width:0}.chat-tool-card,.chat-thinking{max-width:95%}.chat-avatar{width:24px;height:24px;font-size:.65rem}.chat-bubble{padding:var(--space-2, .5rem) var(--space-3, .75rem);font-size:.85rem;overflow-wrap:break-word;word-break:break-word;min-width:0}.chat-bubble pre{overflow-x:auto;max-width:100%}.chat-bubble table{display:block;overflow-x:auto;max-width:100%}.chat-tool-description{max-width:200px}.chat-tool-body{max-width:100%;overflow-x:auto}.chat-session-meta{flex-direction:column;gap:var(--space-1, .25rem)}}@media(max-width:480px){.chat-message{max-width:100%}.chat-message-user,.chat-message-assistant{align-self:stretch}.chat-tool-card,.chat-thinking{max-width:100%}.chat-tool-description{max-width:150px}}.skeleton{background:linear-gradient(90deg,var(--bg-secondary, #1a1a2e) 25%,var(--bg-tertiary, #252540) 50%,var(--bg-secondary, #1a1a2e) 75%);background-size:200% 100%;animation:skeleton-pulse 1.5s ease-in-out infinite;border-radius:var(--radius-sm, 4px)}@keyframes skeleton-pulse{0%{background-position:200% 0}to{background-position:-200% 0}}.loading-container{display:flex;flex-direction:column;gap:var(--space-3, .75rem);padding:var(--space-4, 1rem) 0}.terminal-topbar{display:flex;align-items:center;gap:var(--space-3, .75rem);padding:var(--space-2, .5rem) var(--space-4, 1rem);background:#111827;border-bottom:1px solid #1e293b;min-height:48px;flex-shrink:0}.terminal-topbar .btn{flex-shrink:0}.terminal-body{flex:1;background:#0a0a0f;overflow:hidden;position:relative;min-height:0}.terminal-input{display:flex;align-items:center;gap:var(--space-2, .5rem);padding:var(--space-2, .5rem) var(--space-3, .75rem);background:#111827;border-top:1px solid #1e293b;flex-shrink:0}.terminal-input input{flex:1;height:40px;padding:0 var(--space-3, .75rem);background:#0a0a0f;border:1px solid #1e293b;border-radius:var(--radius-md, 6px);color:var(--text-primary, #ededed);font-family:var(--font-mono);font-size:var(--text-sm, 13px);outline:none;transition:border-color var(--transition-fast, .15s)}.terminal-input input:focus{border-color:#334155}.terminal-input input::placeholder{color:var(--text-tertiary, #7d7d7d)}.term-toggle{display:inline-flex;align-items:center;background:#1e293b;border-radius:var(--radius-full, 9999px);padding:2px;flex-shrink:0}.term-toggle button{height:28px;padding:0 var(--space-3, .75rem);border:none;border-radius:var(--radius-full, 9999px);background:transparent;color:var(--text-tertiary, #7d7d7d);font-family:var(--font-sans);font-size:var(--text-xs, 12px);font-weight:500;cursor:pointer;transition:background var(--transition-fast, .15s),color var(--transition-fast, .15s)}.term-toggle button.active{background:#334155;color:var(--text-primary, #ededed)}.term-toggle button:hover:not(.active){color:var(--text-secondary, #a1a1a1)}.badge-ai{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--radius-full, 9999px);background:#a78bfa26;color:#a78bfa;font-size:var(--text-xs, 12px);font-weight:500;white-space:nowrap}.badge-shell{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--radius-full, 9999px);background:#22c55e26;color:#22c55e;font-size:var(--text-xs, 12px);font-weight:500;white-space:nowrap}.badge-live{display:inline-flex;align-items:center;gap:6px;padding:2px 8px;border-radius:var(--radius-full, 9999px);background:#22c55e26;color:#22c55e;font-size:var(--text-xs, 12px);font-weight:500;white-space:nowrap}.badge-live:before{content:"";width:6px;height:6px;border-radius:50%;background:#22c55e;animation:pulse-dot 2s ease-in-out infinite}.badge-ended{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;border-radius:var(--radius-full, 9999px);background:#6b728026;color:#9ca3af;font-size:var(--text-xs, 12px);font-weight:500;white-space:nowrap}.connection-status{display:inline-flex;align-items:center;gap:6px;font-size:var(--text-xs, 12px);font-weight:500;white-space:nowrap}.connection-status-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.connection-status.connected .connection-status-dot{background:#22c55e}.connection-status.reconnecting .connection-status-dot{background:#f59e0b;animation:pulse-dot 1s ease-in-out infinite}.connection-status.disconnected .connection-status-dot{background:#ef4444}.connection-status.connected{color:#22c55e}.connection-status.reconnecting{color:#f59e0b}.connection-status.disconnected{color:#ef4444}.chat-input-bar{display:flex;align-items:center;gap:var(--space-2, .5rem);padding:var(--space-3, .75rem) var(--space-4, 1rem);padding-bottom:calc(var(--space-3, .75rem) + env(safe-area-inset-bottom,0px));background:#111827;border-top:1px solid #1e293b;flex-shrink:0}.chat-input-bar input{flex:1;height:44px;padding:0 var(--space-4, 1rem);background:#0a0a0f;border:1px solid #1e293b;border-radius:var(--radius-lg, 8px);color:var(--text-primary, #ededed);font-family:var(--font-sans);font-size:var(--text-base, 14px);outline:none;transition:border-color var(--transition-fast, .15s)}.chat-input-bar input:focus{border-color:#334155}.chat-input-bar input::placeholder{color:var(--text-tertiary, #7d7d7d)}.chat-input-bar button{height:44px;min-width:44px;padding:0 var(--space-4, 1rem);background:#22c55e;border:none;border-radius:var(--radius-lg, 8px);color:#0a0a0f;font-family:var(--font-sans);font-size:var(--text-sm, 13px);font-weight:600;cursor:pointer;flex-shrink:0;transition:background var(--transition-fast, .15s),opacity var(--transition-fast, .15s)}.chat-input-bar button:hover{background:#16a34a}.chat-input-bar button:disabled{opacity:.4;cursor:not-allowed}.chat-permission-inline{display:flex;align-items:center;gap:var(--space-2, .5rem);padding:var(--space-3, .75rem) var(--space-4, 1rem);background:#f59e0b14;border:1px solid rgba(245,158,11,.2);border-radius:var(--radius-lg, 8px);margin:var(--space-2, .5rem) 0}.chat-permission-inline .permission-label{flex:1;font-size:var(--text-sm, 13px);color:#f59e0b;font-weight:500}.chat-permission-inline .btn-allow{height:34px;padding:0 var(--space-4, 1rem);background:#22c55e;border:none;border-radius:var(--radius-md, 6px);color:#0a0a0f;font-size:var(--text-sm, 13px);font-weight:600;cursor:pointer;transition:background var(--transition-fast, .15s)}.chat-permission-inline .btn-allow:hover{background:#16a34a}.chat-permission-inline .btn-deny{height:34px;padding:0 var(--space-4, 1rem);background:transparent;border:1px solid #ef4444;border-radius:var(--radius-md, 6px);color:#ef4444;font-size:var(--text-sm, 13px);font-weight:600;cursor:pointer;transition:background var(--transition-fast, .15s),color var(--transition-fast, .15s)}.chat-permission-inline .btn-deny:hover{background:#ef444426}@media(max-width:768px){.terminal-topbar{padding:var(--space-2, .5rem) var(--space-3, .75rem);gap:var(--space-2, .5rem);min-height:44px}.terminal-input input,.chat-input-bar input{min-width:0}.chat-permission-inline{flex-wrap:wrap}.chat-permission-inline .permission-label{width:100%;margin-bottom:var(--space-1, .25rem)}}:root{--button-font-family: var(--font-sans);--button-font-size: var(--text-sm);--button-font-weight: 500;--button-color: var(--ds-blue-700);--button-text-color: #fff;--button-padding: 8px 16px;--button-border-radius: var(--radius-md);--button-border: 1px solid transparent;--button-hover-color: var(--ds-blue-900);--button-hover-text-color: #fff;--button-content-gap: 8px;--input-background: var(--ds-gray-100);--input-font-family: var(--font-sans);--input-font-size: var(--text-base);--input-font-weight: 400;--input-radius: var(--radius-md);--input-padding: 10px 12px;--input-height: 40px;--input-width: 100%;--input-margin: 0;--input-box-shadow: none;--input-border: 1px solid var(--border);--input-focus-border: 1px solid var(--ds-blue-700);--input-text-color: var(--text-primary);--input-placeholder-color: var(--text-tertiary);--input-label-msg-text-color: var(--text-secondary);--input-label-msg-text-size: var(--text-sm);--input-label-msg-text-weight: 400;--input-label-msg-margin: 0 0 var(--space-2) 0;--input-error-msg-text-color: var(--ds-red-700);--input-error-msg-text-size: var(--text-xs);--input-info-msg-text-color: var(--text-tertiary);--input-info-msg-text-size: var(--text-xs);--input-info-msg-margin: var(--space-2) 0 0 0;--input-container-margin: 0 0 var(--space-5) 0;--banner-background: var(--ds-gray-100);--banner-color: var(--text-secondary);--banner-font-family: var(--font-sans);--banner-font-size: var(--text-sm);--banner-font-weight: 500;--banner-padding: 12px 16px;--banner-gap: 10px;--banner-justify-content: flex-start;--banner-icon-size: 16px;--banner-link-color: var(--ds-blue-900);--banner-cursor: default;--banner-position: relative;--banner-z-index: auto;--banner-dismiss-hover-background: var(--ds-gray-alpha-200);--banner-dismiss-color: var(--text-tertiary);--pill-background: var(--ds-gray-300);--pill-color: var(--text-secondary);--pill-font-family: var(--font-sans);--pill-font-size: var(--text-xs);--pill-font-weight: 500;--pill-padding: 4px 10px;--pill-border-radius: var(--radius-full);--pill-border: none;--pill-hover-background: var(--ds-gray-400);--pill-hover-color: var(--text-primary);--badge-background: var(--ds-gray-500);--badge-color: #fff;--badge-font-family: var(--font-sans);--badge-font-size: var(--text-xs);--badge-padding: 2px 6px;--badge-border-radius: var(--radius-full);--badge-border: none;--badge-wrap-margin: 0;--badge-wrap-padding: 0;--badge-img-width: 24px;--badge-img-height: 24px;--badge-img-border-radius: var(--radius-sm);--badge-img-icon-shadow: none;--badge-min-width: 6px;--badge-min-height: 6px;--tabs-bar-background: transparent;--tabs-bar-padding: 0;--tabs-bar-gap: 0;--tabs-bar-border-bottom: 1px solid var(--border);--tabs-item-padding: 10px 16px;--tabs-item-font-size: var(--text-sm);--tabs-item-font-weight: 500;--tabs-item-font-family: var(--font-sans);--tabs-item-color: var(--text-tertiary);--tabs-item-background: transparent;--tabs-active-color: var(--text-primary);--tabs-active-font-weight: 600;--tabs-indicator-color: var(--ds-blue-700);--tabs-indicator-height: 2px;--tabs-hover-color: var(--text-secondary);--tabs-hover-background: var(--ds-gray-alpha-100);--tabs-transition: color .15s ease, background .15s ease;--sheet-overlay-background: rgba(0, 0, 0, .6);--sheet-background: var(--ds-gray-100);--sheet-box-shadow: -4px 0 16px rgba(0, 0, 0, .3);--sheet-border: none;--sheet-header-padding: 16px 20px;--sheet-header-background: var(--ds-gray-100);--sheet-header-border-bottom: 1px solid var(--border);--sheet-title-font-size: var(--text-lg);--sheet-title-font-weight: 600;--sheet-title-font-family: var(--font-sans);--sheet-title-color: var(--text-primary);--sheet-close-button-color: var(--text-tertiary);--sheet-close-button-hover-background: var(--ds-gray-300);--sheet-content-padding: 20px;--sheet-footer-padding: 16px 20px;--sheet-footer-background: var(--ds-gray-100);--sheet-footer-border-top: 1px solid var(--border);--select-bgcolor: var(--ds-gray-100);--select-font-family: var(--font-sans);--select-font-size: var(--text-base);--select-radius: var(--radius-md);--select-box-shadow: none;--select-border: 1px solid var(--border);--select-color: var(--text-primary);--select-hover-color: var(--text-primary);--select-hover-bgcolor: var(--ds-gray-200);--item-padding: 10px 12px;--item-background-color: var(--ds-gray-100);--non-selected-hover-bg: var(--ds-gray-200);--non-selected-hover-color: var(--text-primary);--non-selected-item-bgcolor: var(--ds-gray-100);--non-selected-item-color: var(--text-secondary);--non-selected-items-border-radius: var(--radius-md);--selected-item-background-color: var(--ds-gray-200);--selected-item-padding: 10px 12px;--selected-color: var(--text-primary);--selected-hover-bg: var(--ds-gray-200);--label-text-color: var(--text-secondary);--label-text-size: var(--text-xs);--label-text-weight: 500;--shimmer-background: var(--ds-gray-200);--shimmer-highlight: rgba(255, 255, 255, .04);--shimmer-border-radius: var(--radius-md);--shimmer-duration: 1.5s;--avatar-background: var(--ds-gray-300);--avatar-text-color: var(--text-secondary);--avatar-font-family: var(--font-sans);--avatar-border: none;--avatar-small-width: 28px;--avatar-small-height: 28px;--avatar-medium-width: 36px;--avatar-medium-height: 36px;--avatar-large-width: 48px;--avatar-large-height: 48px;--avatar-small-font-size: 11px;--avatar-medium-font-size: 13px;--avatar-large-font-size: 18px;--choicebox-background: var(--ds-gray-100);--choicebox-border: 2px solid var(--border);--choicebox-border-radius: var(--radius-lg);--choicebox-padding: 16px;--choicebox-gap: 12px;--choicebox-hover-border-color: var(--border-hover);--choicebox-hover-background: var(--ds-gray-200);--choicebox-selected-border-color: var(--ds-blue-700);--choicebox-selected-background: var(--ds-blue-100);--choicebox-title-color: var(--text-primary);--choicebox-title-font-size: var(--text-base);--choicebox-title-font-weight: 500;--choicebox-title-font-family: var(--font-sans);--choicebox-description-color: var(--text-tertiary);--choicebox-description-font-size: var(--text-sm);--choicebox-indicator-border: 2px solid var(--ds-gray-500);--choicebox-indicator-selected-color: var(--ds-blue-700);--choicebox-focus-ring: 0 0 0 3px rgba(0, 112, 243, .2);--toast-font-family: var(--font-sans);--toast-font-size: var(--text-sm);--toast-border-radius: var(--radius-lg);--toast-padding: 12px 16px;--toast-background-color: var(--ds-gray-200);--toast-z-index: 1000;--toast-success-background-color: var(--ds-green-100);--toast-success-text: var(--ds-green-900);--toast-error-background-color: var(--ds-red-100);--toast-error-text: var(--ds-red-900);--toast-info-background-color: var(--ds-blue-100);--toast-info-text: var(--ds-blue-900);--toast-warn-background-color: var(--ds-amber-100);--toast-warn-text: var(--ds-amber-900);--background-color: rgba(0, 0, 0, .6);--modal-content-background-color: var(--ds-gray-100);--modal-border-radius: var(--radius-xl);--modal-scrollbar-width: none;--modal-header-background-color: var(--ds-gray-100);--modal-header-padding: 16px 20px;--modal-header-border-bottom: 1px solid var(--border);--modal-footer-background-color: var(--ds-gray-100);--modal-footer-padding: 16px 20px;--modal-footer-border-top: 1px solid var(--border)}.btn-primary{--button-color: var(--ds-gray-1000);--button-text-color: var(--ds-background-100);--button-border: 1px solid var(--ds-gray-1000);--button-hover-color: #fff;--button-hover-text-color: var(--ds-background-100);--button-hover-border: 1px solid #fff}.btn-secondary{--button-color: var(--ds-background-100);--button-text-color: var(--ds-gray-1000);--button-border: 1px solid var(--ds-gray-400);--button-hover-color: var(--ds-gray-100);--button-hover-text-color: var(--ds-gray-1000);--button-hover-border: 1px solid var(--ds-gray-400)}.btn-ghost{--button-color: transparent;--button-text-color: var(--ds-gray-1000);--button-hover-color: var(--ds-gray-alpha-100);--button-hover-text-color: var(--ds-gray-1000)}.btn-danger{--button-color: #d93036;--button-text-color: #fff;--button-hover-color: #ff6166;--button-hover-text-color: #fff}.btn-warning{--button-color: #ff990a;--button-text-color: var(--ds-background-100);--button-hover-color: #ffb224;--button-hover-text-color: var(--ds-background-100)}.btn-connect{--button-color: #0d9488;--button-text-color: #fff;--button-hover-color: #14b8a6;--button-hover-text-color: #fff;--button-border: 1px solid #0d9488;--button-hover-border: 1px solid #14b8a6}.btn-resume{--button-color: transparent;--button-text-color: var(--ds-gray-900);--button-border: 1px solid var(--ds-gray-400);--button-hover-color: var(--ds-gray-100);--button-hover-text-color: var(--ds-gray-1000);--button-hover-border: 1px solid var(--ds-gray-600)}.btn-sm{--button-height: 32px;--button-padding: 0 10px;--button-font-size: var(--text-base)}.btn-xs{--button-height: 28px;--button-padding: 0 8px;--button-font-size: var(--text-xs);--button-border-radius: var(--radius-sm)}.btn-lg{--button-height: 48px;--button-padding: 0 20px;--button-font-size: var(--text-lg);--button-border-radius: var(--radius-lg)}.banner-alert{border-radius:var(--radius-md)}.banner-success{--banner-background: var(--ds-green-100);--banner-color: var(--ds-green-900);--banner-icon-color: var(--ds-green-900);border-radius:var(--radius-md)}.banner-error{--banner-background: var(--ds-red-100);--banner-color: var(--ds-red-900);--banner-icon-color: var(--ds-red-900);border-radius:var(--radius-md)}.banner-warning{--banner-background: var(--ds-amber-100);--banner-color: var(--ds-amber-900);--banner-icon-color: var(--ds-amber-900);border-radius:var(--radius-md)}.banner-info{--banner-background: var(--ds-blue-100);--banner-color: var(--ds-blue-900);--banner-icon-color: var(--ds-blue-900);border-radius:var(--radius-md)}.input-mono{--input-font-family: var(--font-mono);--input-font-size: var(--text-sm)}.avatar-user{--avatar-background: var(--ds-blue-100);--avatar-text-color: var(--ds-blue-900)}.avatar-assistant{--avatar-background: var(--ds-green-100);--avatar-text-color: var(--ds-green-900)}.btn-remove{--button-height: 24px;--button-width: 24px;--button-padding: 0;--button-font-size: 16px;--button-border-radius: var(--radius-sm)}.pill-session-time{--pill-background: var(--ds-green-100);--pill-color: var(--ds-green-900);--pill-font-size: var(--text-xs);--pill-padding: 4px 10px;--pill-hover-background: var(--ds-green-100);--pill-hover-color: var(--ds-green-900);--pill-cursor: inherit}.pill-tool-name{--pill-background: var(--ds-gray-300);--pill-color: var(--text-primary);--pill-font-size: var(--text-xs);--pill-font-family: var(--font-mono);--pill-padding: 2px 8px;--pill-hover-background: var(--ds-gray-300);--pill-cursor: inherit}.pill-tool-success{--pill-background: var(--ds-green-100);--pill-color: var(--ds-green-900);--pill-font-size: var(--text-xs);--pill-padding: 2px 8px;--pill-hover-background: var(--ds-green-100);--pill-cursor: inherit}.pill-tool-error{--pill-background: var(--ds-red-100);--pill-color: var(--ds-red-900);--pill-font-size: var(--text-xs);--pill-padding: 2px 8px;--pill-hover-background: var(--ds-red-100);--pill-cursor: inherit}.pill-live{--pill-background: rgba(34, 197, 94, .15);--pill-color: #22c55e;--pill-border: 1px solid rgba(34, 197, 94, .3);--pill-font-size: .7rem;--pill-padding: 2px 10px;--pill-hover-background: rgba(34, 197, 94, .15);--pill-hover-color: #22c55e;--pill-cursor: default;font-weight:700;letter-spacing:.05em}.pill-badge-ai{--pill-background: var(--ds-blue-100);--pill-color: var(--ds-blue-900);--pill-font-size: 9px;--pill-padding: 2px 6px;--pill-hover-background: var(--ds-blue-100);--pill-cursor: inherit;font-weight:700;letter-spacing:.05em}.pill-badge-shell{--pill-background: var(--ds-gray-300);--pill-color: var(--text-secondary);--pill-font-size: 9px;--pill-padding: 2px 6px;--pill-hover-background: var(--ds-gray-300);--pill-cursor: inherit;font-weight:700;letter-spacing:.05em}.pill-badge-ended{--pill-background: var(--ds-gray-alpha-200);--pill-color: var(--text-tertiary);--pill-font-size: 9px;--pill-padding: 2px 6px;--pill-hover-background: var(--ds-gray-alpha-200);--pill-cursor: inherit;font-weight:700;letter-spacing:.05em}.pill-exit-ok{--pill-background: var(--ds-green-100);--pill-color: var(--ds-green-900);--pill-font-size: 10px;--pill-font-family: var(--font-mono);--pill-padding: 2px 6px;--pill-hover-background: var(--ds-green-100);--pill-cursor: inherit}.pill-exit-error{--pill-background: var(--ds-red-100);--pill-color: var(--ds-red-900);--pill-font-size: 10px;--pill-font-family: var(--font-mono);--pill-padding: 2px 6px;--pill-hover-background: var(--ds-red-100);--pill-cursor: inherit}.pill-source-claude{--pill-background: var(--ds-blue-100);--pill-color: var(--ds-blue-900);--pill-font-size: 10px;--pill-padding: 2px 8px;--pill-hover-background: var(--ds-blue-100);--pill-hover-color: var(--ds-blue-900);--pill-cursor: inherit}.pill-source-opencode{--pill-background: var(--ds-amber-100);--pill-color: var(--ds-amber-900);--pill-font-size: 10px;--pill-padding: 2px 8px;--pill-hover-background: var(--ds-amber-100);--pill-hover-color: var(--ds-amber-900);--pill-cursor: inherit}.shimmer-header{--shimmer-height: 80px;--shimmer-border-radius: var(--radius-lg);margin-bottom:1rem}.shimmer-card{--shimmer-height: 120px;--shimmer-border-radius: var(--radius-lg)}.shimmer-bubble{--shimmer-height: 60px;--shimmer-border-radius: var(--radius-lg);margin-bottom:var(--space-3)}.shimmer-bubble-user{--shimmer-width: 60%;margin-left:auto}.shimmer-bubble-assistant{--shimmer-width: 75%}.shimmer-bubble-user-short{--shimmer-width: 50%;margin-left:auto}.shimmer-bubble-assistant-wide{--shimmer-width: 80%}.shimmer-bubble-assistant-short{--shimmer-width: 40%}@media(max-width:768px){.shimmer-card{--shimmer-height: 90px}.btn-xs{min-height:36px;padding:6px 12px}}.nav-right.svelte-12qhfyh{display:flex;align-items:center;gap:var(--space-2)}.btn-gear.svelte-12qhfyh{background:transparent;color:var(--text-muted);border:none;padding:0;height:36px;width:36px;border-radius:var(--radius-md);cursor:pointer;display:flex;align-items:center;justify-content:center}.btn-gear.svelte-12qhfyh:hover{background:var(--component-bg);color:var(--text-primary)}.btn-gear.svelte-12qhfyh:focus-visible{outline:2px solid var(--ds-green-700);outline-offset:2px}.btn-gear-active.svelte-12qhfyh{background:var(--component-bg);color:var(--text-primary)}.content-area.svelte-12qhfyh{flex:1;overflow-y:auto;-webkit-overflow-scrolling:touch;padding-bottom:env(safe-area-inset-bottom,0px)}.bottom-tabs.svelte-12qhfyh{height:64px;background:var(--background);border-top:1px solid var(--border);flex-shrink:0;z-index:100;padding-bottom:env(safe-area-inset-bottom,0)}.bottom-tabs-inner.svelte-12qhfyh{max-width:600px;margin:0 auto;padding:6px var(--space-4) 4px;display:flex;align-items:center;justify-content:space-around;height:100%;box-sizing:border-box}.tab-item.svelte-12qhfyh{display:flex;flex-direction:column;align-items:center;justify-content:center;gap:4px;color:var(--text-muted);font-size:11px;font-weight:500;text-decoration:none;padding:6px 36px;border-radius:var(--radius-md);transition:color var(--transition-fast);-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;min-height:48px}.tab-item.svelte-12qhfyh:hover{color:var(--text-secondary)}.tab-item.active.svelte-12qhfyh{color:var(--ds-green-700)}.tab-item.svelte-12qhfyh svg{width:26px;height:26px;flex-shrink:0}@media(max-width:480px){.btn-gear.svelte-12qhfyh{height:44px;width:44px}.bottom-tabs.svelte-12qhfyh{height:60px}.tab-item.svelte-12qhfyh{padding:6px 28px;font-size:10px;gap:3px;min-height:44px}.tab-item.svelte-12qhfyh svg{width:24px;height:24px}.status-badge{font-size:10px;padding:0 8px;height:22px}.page-header{flex-direction:column!important;gap:var(--space-3)!important}.page-header .btn-group{width:100%}.page-header .btn-group .btn{flex:1;justify-content:center}}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{l as o,a as r}from"../chunks/EhLZwqfu.js";export{o as load_css,r as start};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
import{d as lt,s as E,e as Re,a as h,f as p}from"../chunks/DVl0sebP.js";import{W as Ee,c as d,r as c,d as g,g as r,t as W,Y as Ne,Z as O,f as ie,s as R,A as We,b as m,X as ct,_ as dt,q as ut,a0 as vt,a1 as ft}from"../chunks/CJFjKwJ7.js";import{i as P}from"../chunks/BfJ-f-Tu.js";import{P as Ue,s as xe,e as ee,b as Ie,B as ke,a as mt,i as je}from"../chunks/CNH2HlKj.js";import{h as gt}from"../chunks/CsgHjHGZ.js";import{g as Le}from"../chunks/EhLZwqfu.js";import{g as ht,s as pt,c as _t,S as Me}from"../chunks/CtrCjGZT.js";import{i as St}from"../chunks/gQJcRhou.js";import{E as qe}from"../chunks/CaiJSUi3.js";import{I as yt}from"../chunks/CmczWE_d.js";import{b as bt,a as wt,c as Ct}from"../chunks/DDiOVAd8.js";import{f as kt}from"../chunks/BLszSzTT.js";import{S as At}from"../chunks/CGMJxf7r.js";import{i as xt}from"../chunks/BRkqKgVG.js";import{d as Et}from"../chunks/pRcLbE0d.js";var Nt=p('<p class="goal-text svelte-1qbe2oo"> </p>'),It=p('<span class="summarizing svelte-1qbe2oo">Analyzing…</span>'),Pt=p('<span class="summary-text svelte-1qbe2oo"> </span>'),Tt=p('<span class="summary-fallback svelte-1qbe2oo"> </span>'),Dt=p('<span class="stat stat-error svelte-1qbe2oo"> </span>'),Ot=p('<div class="card svelte-1qbe2oo" role="button" tabindex="0"><div class="card-header svelte-1qbe2oo"><span class="project-name svelte-1qbe2oo"> </span> <!></div> <!> <div class="summary-row svelte-1qbe2oo"><!></div> <div class="stats-row svelte-1qbe2oo"><span class="stat svelte-1qbe2oo"><span></span> </span> <span class="stat svelte-1qbe2oo"> </span> <!> <span class="stat stat-path svelte-1qbe2oo"> </span></div></div>');function Be(t,e){Ee(e,!0);function s(o){const l=Math.floor(o/1e3);if(l<60)return`${l}s`;const f=Math.floor(l/60);return f<60?`${f}m ${l%60}s`:`${Math.floor(f/60)}h ${f%60}m`}function i(o){const l=o.replace(/\/$/,"").split("/");return l.length<=2?o:l.slice(-2).join("/")}const a=O(()=>e.card.status==="running"&&e.card.isActive?"var(--ds-green-700)":e.card.status==="running"?"var(--ds-blue-700)":e.card.status==="idle"?"var(--ds-amber-700)":e.card.status==="error"?"var(--ds-red-700)":"var(--ds-gray-600)"),n=O(()=>e.card.status==="running"&&e.card.isActive||e.card.status==="running"?"● Running":e.card.status==="idle"?"◎ Idle":e.card.status==="exited"?"○ Done":e.card.status==="error"?"✕ Error":e.card.status),_=O(()=>e.card.status==="running"&&e.card.isActive?"status-pill status-pill--running-active":e.card.status==="running"?"status-pill status-pill--running":e.card.status==="idle"?"status-pill status-pill--idle":e.card.status==="exited"?"status-pill status-pill--exited":e.card.status==="error"?"status-pill status-pill--error":"status-pill"),S=O(()=>e.card.toolCallCount===0?"Waiting for activity…":e.card.toolCallCount===1?"1 tool call so far":`${e.card.toolCallCount} tool calls so far`);function w(o){(o.key==="Enter"||o.key===" ")&&(o.key===" "&&o.preventDefault(),e.onclick?.())}var y=Ot(),v=d(y),u=d(v),C=d(u,!0);c(u);var b=g(u,2);Ue(b,{get text(){return r(n)},get classes(){return r(_)}}),c(v);var k=g(v,2);{var ue=o=>{var l=Nt(),f=d(l,!0);c(l),W(()=>E(f,e.card.goal)),h(o,l)};P(k,o=>{e.card.goal&&o(ue)})}var H=g(k,2),ve=d(H);{var fe=o=>{var l=It();h(o,l)},me=o=>{var l=Pt(),f=d(l,!0);c(l),W(()=>E(f,e.card.summary)),h(o,l)},J=o=>{var l=Tt(),f=d(l,!0);c(l),W(()=>E(f,r(S))),h(o,l)};P(ve,o=>{e.card.isSummarizing?o(fe):e.card.summary?o(me,1):e.card.status==="running"&&o(J,2)})}c(H);var M=g(H,2),q=d(M),X=d(q),ge=g(X);c(q);var B=g(q,2),he=d(B);c(B);var se=g(B,2);{var pe=o=>{var l=Dt(),f=d(l);c(l),W(()=>E(f,`${e.card.errorCount??""} errors`)),h(o,l)};P(se,o=>{e.card.errorCount>0&&o(pe)})}var Z=g(se,2),_e=d(Z,!0);c(Z),c(M),c(y),W((o,l)=>{bt(y,`--status-color: ${r(a)??""}`),xe(y,"aria-label",`Open ${e.card.projectName??""} session`),E(C,e.card.projectName),wt(X,1,Ct(e.card.status==="running"&&e.card.isActive?"status-dot-active":"status-dot-static"),"svelte-1qbe2oo"),E(ge,` ${o??""}`),E(he,`${e.card.toolCallCount??""} tools`),xe(Z,"title",e.card.cwd),E(_e,l)},[()=>s(e.card.duration),()=>i(e.card.cwd)]),Re("click",y,function(...o){e.onclick?.apply(this,o)}),Re("keydown",y,w),h(t,y),Ne()}lt(["click","keydown"]);var zt=p('<div class="section svelte-14sxgtb"><h3 class="section-label svelte-14sxgtb">Active</h3> <!></div>'),Rt=p('<div class="section svelte-14sxgtb"><h3 class="section-label svelte-14sxgtb">Recent</h3> <!></div>'),jt=p("<!> <!>",1);function Lt(t,e){Ee(e,!0);const s=O(()=>e.cards.filter(v=>v.status==="running")),i=O(()=>e.cards.filter(v=>v.status!=="running"));function a(v){e.onCardClick?.(v)}var n=jt(),_=ie(n);{var S=v=>{var u=zt(),C=g(d(u),2);ee(C,17,()=>r(s),b=>b.terminalId,(b,k)=>{Be(b,{get card(){return r(k)},onclick:()=>{a(r(k))}})}),c(u),h(v,u)};P(_,v=>{r(s).length>0&&v(S)})}var w=g(_,2);{var y=v=>{var u=Rt(),C=g(d(u),2);ee(C,17,()=>r(i),b=>b.terminalId,(b,k)=>{Be(b,{get card(){return r(k)},onclick:()=>{a(r(k))}})}),c(u),h(v,u)};P(w,v=>{r(i).length>0&&v(y)})}h(t,n),Ne()}const Mt="https://unpkg.com/@juspay/neurolink/dist/browser/neurolink.min.js",qt=new Set(["agent-question","terminal-exited","tool-failed"]);let re=null,ne=null,le=null;class Bt{async summarize(e){const s=this.chooseTone(e),i=s==="conversational"?this.buildConversationalPrompt(e):this.buildStatusReportPrompt(e);try{const a=await Kt();if(!a)return console.log("[SessionSummarizer] NeuroLink not available, using fallback."),{generatedAt:new Date().toISOString(),text:this.fallbackText(e),tone:s};const n=await a.generate({input:{text:i},...le?{model:le.model,provider:le.provider}:{}}),_=Ft(n.content??"").trim()||this.fallbackText(e);return{generatedAt:new Date().toISOString(),text:_,tone:s}}catch(a){return console.warn("[SessionSummarizer] summarize failed:",a instanceof Error?a.message:String(a)),{generatedAt:new Date().toISOString(),text:this.fallbackText(e),tone:s}}}buildConversationalPrompt(e){const s=e.goal??"unknown",i=e.recentEvents.map(a=>{const n=[a.type];return a.tool&&n.push(`tool=${a.tool}`),a.error&&n.push(`error=${a.error}`),a.command&&n.push(`command=${a.command}`),n.join(" ")}).join(", ");return`You are monitoring a coding session. Based on the context below, write ONE sentence (max 100 chars) describing what's happening in plain English. Be specific about what Claude did or is doing.
|
|
2
|
-
|
|
3
|
-
Goal: ${s}
|
|
4
|
-
Recent events: ${i}
|
|
5
|
-
Conversation excerpt: ${e.conversationExcerpt}
|
|
6
|
-
Status: ${e.status}
|
|
7
|
-
|
|
8
|
-
One sentence only, no quotes, no markdown.`}buildStatusReportPrompt(e){return`You are monitoring a coding session. Write a brief status update (max 60 chars) in the format "Doing X, Y done". Focus on the action.
|
|
9
|
-
|
|
10
|
-
Recent tool calls: ${e.recentEvents.flatMap(i=>i.tool?[i.tool]:[]).join(", ")||"none"}
|
|
11
|
-
Status: ${e.status}
|
|
12
|
-
|
|
13
|
-
Short phrase only, no quotes.`}chooseTone(e){return e.status==="error"||e.errorCount>0||e.recentEvents.some(i=>qt.has(i.type))?"conversational":"status-report"}fallbackText(e){const s=e.recentEvents.flatMap(a=>a.tool?[a.tool]:[]),i=[...new Set(s)];return i.length>0?`Running: ${i.join(", ")} (${e.toolCallCount} tools)`:`Status: ${e.status} — ${e.toolCallCount} tool calls`}}async function Kt(){if(ne)return ne;xt();const e=(await Yt()).NeuroLink;if(!e)return null;const s=window.__aiProviders,i=window.process?.env?.NEUROLINK_PROVIDER,a=Et(s,i);if(!a)return console.warn("[SessionSummarizer] No AI provider configured"),null;const n=window.process;return n?.env&&s&&(s["google-ai"]&&!n.env.GOOGLE_AI_API_KEY&&(n.env.GOOGLE_AI_API_KEY="proxy-via-server"),s.anthropic&&!n.env.ANTHROPIC_API_KEY&&(n.env.ANTHROPIC_API_KEY="proxy-via-server"),s.openai&&!n.env.OPENAI_API_KEY&&(n.env.OPENAI_API_KEY="proxy-via-server"),s.mistral&&!n.env.MISTRAL_API_KEY&&(n.env.MISTRAL_API_KEY="proxy-via-server")),ne=new e({provider:a.provider}),le=a,console.log(`[SessionSummarizer] Using provider: ${a.provider}/${a.model}`),ne}function Yt(){return re||(re=import(Mt).catch(t=>{throw console.warn("[SessionSummarizer] Failed to load NeuroLink SDK:",t),re=null,t})),re}function Ft(t){return typeof t=="string"?t:typeof t=="number"||typeof t=="boolean"?String(t):""}function Pe(){return new Date(Date.now()).toISOString()}const Gt=100,Wt=15e3,Ut=3e4,Ve=2e3,Vt=3e4;let D=R(We([])),$=R(!1),N=null,U=null,V=null,ce=Ve,Ht=0,j="";const ae=new Ie,L=new Ie,de=new At;async function Jt(t){j=t||$t(),j&&(await Fe(j),await Je(j),U&&clearInterval(U),U=setInterval(()=>{Fe(j)},Wt))}function Xt(){N&&(N.onclose=null,N.close(),N=null),U&&(clearInterval(U),U=null),V&&(clearTimeout(V),V=null);for(const[,t]of L)t.onclose=null,t.close();L.clear(),de.clear(),ae.clear(),m($,!1),j=""}function Zt(){const t=Date.now();return Te(r(D)).map(e=>{const s=Date.parse(e.createdAt),i=e.events.length>0?Date.parse(e.events[e.events.length-1].timestamp):0;return{...e,duration:t-s,goal:e.goal,isActive:i>0&&t-i<Ut,isSummarizing:e.isSummarizing,summary:e.summary}})}function Ke(t,e){const s=r(D).find(i=>i.terminalId===t);s&&(s.goal=e)}function Qt(t,e){const s=r(D).find(i=>i.terminalId===t);s&&(s.summary=e,s.summaryUpdatedAt=Pe(),s.isSummarizing=!1)}function G(t,e,s){const i={data:s,id:`evt-${++Ht}`,summarized:!1,terminalId:t.terminalId,timestamp:s.timestamp??Pe(),type:e},a=t.events.length>=Gt?[...t.events.slice(1),i]:[...t.events,i];t.events=a,t.eventCount+=1}function He(t){return t.split("/").filter(Boolean).pop()??t}function te(t){const e=L.get(t);e&&(e.onclose=null,e.close(),L.delete(t))}async function Je(t){if(!(N&&N.readyState<=1))try{const e=await fetch("/api/ws-ticket",{headers:{Authorization:`Bearer ${t}`},method:"POST"});if(!e.ok){Ae(t);return}const{ticket:s}=await e.json(),i=window.location.origin.replace(/^http/,"ws");N=new WebSocket(`${i}/ws/events?ticket=${s}`),N.onopen=()=>{m($,!0),ce=Ve},N.onmessage=a=>{try{const n=JSON.parse(a.data);n&&typeof n=="object"&&ea(n)}catch{}},N.onclose=()=>{m($,!1),N=null,Ae(t)},N.onerror=()=>{m($,!1)}}catch{m($,!1),Ae(t)}}function Ye(t){let e="";return typeof t=="string"?e=t:Array.isArray(t)&&(e=t.find(i=>i.type==="text")?.content??""),e.slice(0,200).trim()}async function Fe(t){if(t)try{const e=await fetch("/api/terminals",{headers:{Authorization:`Bearer ${t}`}});if(!e.ok)return;const i=(await e.json()).terminals??[];m(D,Te(aa(r(D),i)),!0)}catch{}}function $t(){try{const t=localStorage.getItem("shooter_config");if(!t)return"";const e=JSON.parse(t);if(e&&typeof e=="object"){const s=e;if(typeof s.apiKey=="string")return s.apiKey}}catch{}return""}function ea(t){const e=t.type;if(!e||e==="welcome")return;const s=t.terminalId??null;if(!s)return;const i=r(D).findIndex(_=>_.terminalId===s);if(i===-1)return;const a=r(D)[i];switch(e){case"agent-idle":case"agent-question":{a.status="idle",G(a,e,t);break}case"terminal-exited":{a.status="exited",a.exitedAt=t.exitedAt??Pe(),G(a,e,t),te(s),ae.delete(s);break}case"tool-completed":{G(a,e,t);break}case"tool-failed":{a.errorCount+=1,G(a,e,t);break}case"tool-started":{a.toolCallCount+=1,a.status="running",G(a,e,t);break}default:{G(a,e,t);break}}(e==="tool-failed"||e==="agent-question"||a.errorCount>=3||a.eventCount>0&&a.eventCount%20===0)&&!a.isSummarizing&&sa(a),m(D,Te(r(D)),!0)}function ta(t){return{command:t.command,createdAt:t.createdAt,cwd:t.cwd,errorCount:0,eventCount:0,events:[],exitedAt:t.exitedAt,goal:"",isSummarizing:!1,projectName:He(t.cwd),projectPath:t.cwd,status:Xe(t.status),summary:"",summaryUpdatedAt:"",terminalId:t.id,toolCallCount:0}}function Xe(t){return t==="running"?"running":t==="idle"?"idle":t==="exited"?"exited":"error"}function aa(t,e){const s=new Set(e.map(a=>a.id));for(const a of t)s.has(a.terminalId)||(te(a.terminalId),ae.delete(a.terminalId));const i=new Ie;for(const a of t)s.has(a.terminalId)&&i.set(a.terminalId,a);for(const a of e){const n=i.get(a.id);n?(n.command=a.command,n.cwd=a.cwd,n.projectName=He(a.cwd),n.projectPath=a.cwd,n.exitedAt=a.exitedAt,n.status!=="error"&&(n.status=Xe(a.status)),n.goal||Ge(a.id)):(i.set(a.id,ta(a)),Ge(a.id))}return Array.from(i.values())}async function Ge(t){if(j&&!(L.has(t)||de.has(t))){de.add(t),console.log(`[DashboardStore] Opening session socket for ${t}`);try{const e=await fetch("/api/ws-ticket",{headers:{Authorization:`Bearer ${j}`},method:"POST"});if(!e.ok){console.warn(`[DashboardStore] Failed to get WS ticket for ${t}:`,e.status);return}const{ticket:s}=await e.json(),a=`${window.location.origin.replace(/^http/,"ws")}/ws/session/${t}?ticket=${s}`;console.log(`[DashboardStore] Connecting session socket for ${t}`);const n=new WebSocket(a);L.set(t,n),n.onopen=()=>{console.log(`[DashboardStore] Session socket opened for ${t}`)},n.onmessage=_=>{try{const S=JSON.parse(_.data);if(!S||typeof S!="object")return;const w=S,y=r(D).find(u=>u.terminalId===t),v=y?.goal&&y.goal.length>0;if(w.type==="history"){console.log(`[DashboardStore] Received history for ${t}, extracting goal...`);const u=w.messages;if(!Array.isArray(u)){console.warn(`[DashboardStore] No messages array in history for ${t}`);return}console.log(`[DashboardStore] Found ${u.length} messages, looking for first user message...`);for(const C of u)if(C.role==="user"){const b=Ye(C.content);console.log(`[DashboardStore] Extracted goal for ${t}: "${b.substring(0,50)}..."`),b&&Ke(t,b),te(t);return}console.log(`[DashboardStore] No user message found in history for ${t}`);return}if(w.type==="message"&&w.role==="user"&&!v){const u=Ye(w.content);u&&(console.log(`[DashboardStore] Extracted goal from message for ${t}: "${u.substring(0,50)}..."`),Ke(t,u),te(t));return}if(!v)return;te(t)}catch(S){console.warn("[DashboardStore] Error processing session message:",S)}},n.onclose=()=>{console.log(`[DashboardStore] Session socket closed for ${t}`),L.delete(t)},n.onerror=_=>{console.warn(`[DashboardStore] Session socket error for ${t}:`,_),L.delete(t)}}catch(e){console.warn("[DashboardStore] Failed to open session socket:",e)}finally{de.delete(t)}}}function Ae(t){V||(V=setTimeout(()=>{V=null,Je(t)},ce),ce=Math.min(ce*2,Vt))}function Te(t){return[...t].sort((e,s)=>{const i={error:2,exited:3,idle:1,running:0},a=i[e.status],n=i[s.status];if(a!==n)return a-n;if(e.status!=="exited"&&s.status!=="exited")return s.createdAt.localeCompare(e.createdAt);const _=e.exitedAt??e.createdAt;return(s.exitedAt??s.createdAt).localeCompare(_)})}function sa(t){t.isSummarizing=!0;let e=ae.get(t.terminalId);e||(e=new Bt,ae.set(t.terminalId,e));const s=t.events.slice(-10).map(a=>({command:typeof a.data.command=="string"?a.data.command:null,error:typeof a.data.error=="string"?a.data.error:null,tool:typeof a.data.tool=="string"?a.data.tool:null,type:a.type})),i={conversationExcerpt:t.goal??"",errorCount:t.errorCount,goal:t.goal,recentEvents:s,status:t.status,toolCallCount:t.toolCallCount};(async()=>{try{const a=await e.summarize(i);Qt(t.terminalId,a.text)}catch(a){console.error(`[dashboard] Summarization failed for ${t.terminalId}:`,a)}finally{t.isSummarizing=!1}})()}var oa=p('<meta name="description" content="Active terminals and Claude Code sessions"/>'),ra=p("<!> Refresh",1),na=p('<div class="loading-container"></div>'),ia=p('<div class="dashboard-section svelte-1uha8ag"><!></div>'),la=p('<div class="loading-container"></div>'),ca=p('<h3 class="section-label svelte-1uha8ag">Sessions</h3>'),da=p('<a class="session-card"><div class="session-card-header"><div><h3 class="session-card-title"> </h3> <div class="session-card-subtitle"> </div></div> <!></div> <div class="session-stats"><span><strong> </strong> </span></div></a>'),ua=p('<div style="text-align: center; padding: 1rem;"><!></div>'),va=p('<!> <div class="projects-container svelte-1uha8ag"></div> <!>',1),fa=p("<!> <!>",1),ma=p('<main class="main"><div class="page-header svelte-1uha8ag"><div class="page-header-content svelte-1uha8ag"><div><h1 class="page-title svelte-1uha8ag">Dashboard</h1> <p class="page-description svelte-1uha8ag">Active terminals and Claude Code sessions</p></div> <div class="page-actions svelte-1uha8ag"><!></div></div></div> <!> <!></main>');function Pa(t,e){Ee(e,!0);const s=1e4,i=20;let a=R(We([])),n=R(!1),_=!1,S=R(null),w=null,y=R(null),v=R(!1),u=R(0);const C=O(Zt);ct(()=>{b();const o=ht("shooter_projects");o&&(m(a,o,!0),m(n,!1)),k(),w=setInterval(()=>{r(S)?.apiKey&&r(u)<=i&&k()},s)}),dt(()=>{w&&(clearInterval(w),w=null),Xt()});function b(){try{const o=localStorage.getItem("shooter_config");if(o){const l=JSON.parse(o);St(l)?(m(S,l,!0),Jt(r(S).apiKey)):(localStorage.removeItem("shooter_config"),m(S,null))}}catch{}}async function k(o=!1,l=!1){if(!r(S)?.apiKey||_)return;_=!0,r(a).length===0&&m(n,!0);const f=o?r(u):0;try{const Q=await fetch(`${l?"/api/sessions?refresh=true&":"/api/sessions?"}limit=${i}&offset=${f}`,{headers:{Authorization:`Bearer ${r(S).apiKey}`}});if(!Q.ok){m(y,`Failed to load projects (HTTP ${Q.status})`);return}m(y,null);const K=await Q.json();o?m(a,[...r(a),...K.projects],!0):m(a,K.projects,!0),m(u,r(a).length,!0),m(v,K.total!==void 0?r(a).length<K.total:!1,!0),pt("shooter_projects",r(a))}catch(z){m(y,"Failed to load projects"),console.error("Failed to fetch sessions:",z)}finally{m(n,!1),_=!1}}async function ue(){await k(!0)}async function H(){m(n,!0),_t("shooter_projects"),await k(!1,!0)}function ve(){Le("/config")}function fe(o){Le(`/terminals/${o}`)}function me(){return r(a).reduce((o,l)=>o+l.sessionCount,0)}var J=ma();gt("1uha8ag",o=>{var l=oa();ut(()=>{vt.title="Dashboard - Shooter"}),h(o,l)});var M=d(J),q=d(M),X=g(d(q),2),ge=d(X);ke(ge,{classes:"btn-secondary",onclick:H,get disabled(){return r(n)},children:(o,l)=>{var f=ra(),z=ie(f);yt(z,{name:"refresh",size:14}),ft(),h(o,f)},$$slots:{default:!0}}),c(X),c(q),c(M);var B=g(M,2);{var he=o=>{mt(o,{get text(){return r(y)},classes:"banner-error"})};P(B,o=>{r(y)&&o(he)})}var se=g(B,2);{var pe=o=>{var l=na();ee(l,20,()=>Array(3),je,(f,z)=>{Me(f,{classes:"shimmer-card"})}),c(l),h(o,l)},Z=o=>{qe(o,{icon:"settings",title:"Configuration Required",description:"Set up your API credentials to start tracking sessions",children:(l,f)=>{ke(l,{classes:"btn-primary",onclick:ve,text:"Configure Settings"})}})},_e=o=>{var l=fa(),f=ie(l);{var z=A=>{var T=ia(),Y=d(T);Lt(Y,{get cards(){return r(C)},onCardClick:oe=>{fe(oe.terminalId)}}),c(T),h(A,T)};P(f,A=>{r(C).length>0&&A(z)})}var Q=g(f,2);{var K=A=>{var T=la();ee(T,20,()=>Array(3),je,(Y,oe)=>{Me(Y,{classes:"shimmer-card"})}),c(T),h(A,T)},Ze=A=>{qe(A,{icon:"bell",title:"No sessions yet",description:"Claude Code sessions will appear here once JSONL files are found"})},Qe=O(()=>me()===0&&r(C).length===0),$e=A=>{var T=va(),Y=ie(T);{var oe=I=>{var x=ca();h(I,x)};P(Y,I=>{r(C).length>0&&I(oe)})}var Se=g(Y,2);ee(Se,21,()=>r(a),I=>I.id,(I,x)=>{var F=da(),ye=d(F),be=d(ye),we=d(be),at=d(we,!0);c(we);var De=g(we,2),st=d(De,!0);c(De),c(be);var ot=g(be,2);{let it=O(()=>kt(r(x).lastModified));Ue(ot,{get text(){return`Last updated ${r(it)??""}`},classes:"pill-session-time"})}c(ye);var Oe=g(ye,2),ze=d(Oe),Ce=d(ze),rt=d(Ce,!0);c(Ce);var nt=g(Ce);c(ze),c(Oe),c(F),W(()=>{xe(F,"href",`/project?id=${r(x).id??""}`),E(at,r(x).name),E(st,r(x).fullPath),E(rt,r(x).sessionCount),E(nt,` ${r(x).sessionCount===1?"session":"sessions"}`)}),h(I,F)}),c(Se);var et=g(Se,2);{var tt=I=>{var x=ua(),F=d(x);ke(F,{classes:"btn-secondary",onclick:ue,text:"Load More"}),c(x),h(I,x)};P(et,I=>{r(v)&&I(tt)})}h(A,T)};P(Q,A=>{r(n)&&r(a).length===0?A(K):r(Qe)?A(Ze,1):r(a).length>0&&A($e,2)})}h(o,l)};P(se,o=>{r(n)&&r(a).length===0&&r(C).length===0?o(pe):r(S)?.apiKey?o(_e,-1):o(Z,1)})}c(J),h(t,J),Ne()}export{Pa as component};
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_page.svelte-DDSzYLUs.js","sources":["../../../.svelte-kit/adapter-node/entries/pages/_page.svelte.js"],"sourcesContent":["import { h as head, d as ensure_array_like, f as derived } from \"../../chunks/index.js\";\nimport { g as goto } from \"../../chunks/client.js\";\nimport { E as EmptyState, c as clearCache } from \"../../chunks/EmptyState.js\";\nimport { I as Icon } from \"../../chunks/Icon.js\";\nimport \"../../chunks/markdown.js\";\nimport { o as onDestroy } from \"../../chunks/index-server.js\";\nimport { B as Button } from \"../../chunks/Button.js\";\n/* empty css */\nimport { S as Shimmer } from \"../../chunks/Shimmer.js\";\nimport { S as SvelteMap, a as SvelteSet } from \"../../chunks/index-server2.js\";\nconst ACTIVE_THRESHOLD_MS = 3e4;\nlet sessions = [];\nconst summarizers = new SvelteMap();\nconst sessionSockets = new SvelteMap();\nconst pendingSessionSockets = new SvelteSet();\nfunction disconnect() {\n for (const [, sock] of sessionSockets) {\n sock.onclose = null;\n sock.close();\n }\n sessionSockets.clear();\n pendingSessionSockets.clear();\n summarizers.clear();\n}\nfunction getCards() {\n const now = Date.now();\n return sortSessions(sessions).map((s) => {\n const createdMs = Date.parse(s.createdAt);\n const lastEventTs = s.events.length > 0 ? Date.parse(s.events[s.events.length - 1].timestamp) : 0;\n return {\n ...s,\n duration: now - createdMs,\n goal: s.goal,\n // Ensure goal is mapped\n isActive: lastEventTs > 0 && now - lastEventTs < ACTIVE_THRESHOLD_MS,\n isSummarizing: s.isSummarizing,\n // Ensure isSummarizing is mapped\n summary: s.summary\n // Ensure summary is mapped\n };\n });\n}\nfunction sortSessions(list) {\n return [...list].sort((a, b) => {\n const order = { error: 2, exited: 3, idle: 1, running: 0 };\n const rankA = order[a.status];\n const rankB = order[b.status];\n if (rankA !== rankB) {\n return rankA - rankB;\n }\n if (a.status !== \"exited\" && b.status !== \"exited\") {\n return b.createdAt.localeCompare(a.createdAt);\n }\n const exitA = a.exitedAt ?? a.createdAt;\n const exitB = b.exitedAt ?? b.createdAt;\n return exitB.localeCompare(exitA);\n });\n}\nfunction _page($$renderer, $$props) {\n $$renderer.component(($$renderer2) => {\n let projects = [];\n let loading = false;\n const cards = derived(getCards);\n onDestroy(() => {\n disconnect();\n });\n async function fetchSessions(append = false, bustCache = false) {\n {\n return;\n }\n }\n async function forceRefresh() {\n loading = true;\n clearCache(\"shooter_projects\");\n await fetchSessions(false, true);\n }\n function navigateToConfig() {\n void goto();\n }\n head(\"1uha8ag\", $$renderer2, ($$renderer3) => {\n $$renderer3.title(($$renderer4) => {\n $$renderer4.push(`<title>Dashboard - Shooter</title>`);\n });\n $$renderer3.push(`<meta name=\"description\" content=\"Active terminals and Claude Code sessions\"/>`);\n });\n $$renderer2.push(`<main class=\"main\"><div class=\"page-header svelte-1uha8ag\"><div class=\"page-header-content svelte-1uha8ag\"><div><h1 class=\"page-title svelte-1uha8ag\">Dashboard</h1> <p class=\"page-description svelte-1uha8ag\">Active terminals and Claude Code sessions</p></div> <div class=\"page-actions svelte-1uha8ag\">`);\n Button($$renderer2, {\n classes: \"btn-secondary\",\n onclick: forceRefresh,\n disabled: loading,\n children: ($$renderer3) => {\n Icon($$renderer3, { name: \"refresh\", size: 14 });\n $$renderer3.push(`<!----> Refresh`);\n },\n $$slots: { default: true }\n });\n $$renderer2.push(`<!----></div></div></div> `);\n {\n $$renderer2.push(\"<!--[-1-->\");\n }\n $$renderer2.push(`<!--]--> `);\n if (loading && projects.length === 0 && cards().length === 0) {\n $$renderer2.push(\"<!--[0-->\");\n $$renderer2.push(`<div class=\"loading-container\"><!--[-->`);\n const each_array = ensure_array_like(Array(3));\n for (let i = 0, $$length = each_array.length; i < $$length; i++) {\n each_array[i];\n Shimmer($$renderer2, { classes: \"shimmer-card\" });\n }\n $$renderer2.push(`<!--]--></div>`);\n } else {\n $$renderer2.push(\"<!--[1-->\");\n EmptyState($$renderer2, {\n icon: \"settings\",\n title: \"Configuration Required\",\n description: \"Set up your API credentials to start tracking sessions\",\n children: ($$renderer3) => {\n Button($$renderer3, {\n classes: \"btn-primary\",\n onclick: navigateToConfig,\n text: \"Configure Settings\"\n });\n }\n });\n }\n $$renderer2.push(`<!--]--></main>`);\n });\n}\nexport {\n _page as default\n};\n"],"names":[],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"_server.ts-B__YN2kX.js","sources":["../../../.svelte-kit/adapter-node/entries/endpoints/api/notify/_server.ts.js"],"sourcesContent":["import { b as private_env } from \"../../../../chunks/shared-server.js\";\nimport { L as LibraryAPNsService } from \"../../../../chunks/library-apns.js\";\nimport { c as createPendingRequest } from \"../../../../chunks/pending-requests.js\";\nimport { v as validateAuth } from \"../../../../chunks/auth.js\";\nimport admin from \"firebase-admin\";\nimport { t as toErrorMessage } from \"../../../../chunks/error.js\";\nimport { b as broadcastEvent } from \"../../../../chunks/events-handler.js\";\nimport { json } from \"@sveltejs/kit\";\nconst MAX_HISTORY = 100;\nconst history = [];\nfunction addNotification(record) {\n history.unshift(record);\n if (history.length > MAX_HISTORY) {\n history.length = MAX_HISTORY;\n }\n}\nfunction getNotifications(limit = 50) {\n return history.slice(0, limit);\n}\nlet app = null;\nfunction isFCMConfigured() {\n return !!(process.env.FCM_PROJECT_ID && process.env.FCM_CLIENT_EMAIL && process.env.FCM_PRIVATE_KEY);\n}\nasync function sendFCMNotification(deviceToken, payload) {\n try {\n const fcmApp = getApp();\n const message = {\n android: {\n priority: \"high\",\n // Ensures delivery even in Doze mode\n ttl: 3e5\n // 5 minutes TTL (matches pending request expiry)\n },\n data: {\n body: payload.body || payload.message || \"\",\n category: payload.category ?? (typeof payload.data?.category === \"string\" ? payload.data.category : \"\"),\n project: typeof payload.data?.project === \"string\" ? payload.data.project : \"\",\n requestId: typeof payload.data?.requestId === \"string\" ? payload.data.requestId : \"\",\n source: typeof payload.data?.source === \"string\" ? payload.data.source : \"\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n title: payload.title,\n toolInput: payload.data?.toolInput ? JSON.stringify(payload.data.toolInput) : \"\",\n toolName: typeof payload.data?.toolName === \"string\" ? payload.data.toolName : \"\",\n type: typeof payload.data?.type === \"string\" ? payload.data.type : \"\"\n },\n token: deviceToken\n };\n const messageId = await admin.messaging(fcmApp).send(message);\n return { messageId, success: true };\n } catch (error) {\n const errorMessage = error instanceof Error ? error.message : String(error);\n console.error(\"[FCM] Send failed:\", errorMessage);\n return { error: errorMessage, success: false };\n }\n}\nfunction getApp() {\n if (!app) {\n const projectId = process.env.FCM_PROJECT_ID;\n const clientEmail = process.env.FCM_CLIENT_EMAIL;\n const privateKey = process.env.FCM_PRIVATE_KEY?.replace(/\\\\n/g, \"\\n\");\n if (!projectId || !clientEmail || !privateKey) {\n throw new Error(\n \"FCM not configured: missing FCM_PROJECT_ID, FCM_CLIENT_EMAIL, or FCM_PRIVATE_KEY\"\n );\n }\n app = admin.initializeApp({\n credential: admin.credential.cert({ clientEmail, privateKey, projectId })\n });\n }\n return app;\n}\nlet apnsSingleton = null;\nfunction getAPNsClient() {\n if (!apnsSingleton) {\n apnsSingleton = new LibraryAPNsService();\n }\n return apnsSingleton;\n}\nconst notificationCache = /* @__PURE__ */ new Map();\nconst DEDUP_WINDOW = 1e4;\nfunction broadcastHookEvent(body) {\n const data = body.data ?? {};\n const eventType = typeof data.eventType === \"string\" ? data.eventType : typeof body.eventType === \"string\" ? body.eventType : \"\";\n const tool = typeof data.tool === \"string\" ? data.tool : \"\";\n const terminalId = typeof data.terminalId === \"string\" ? data.terminalId : void 0;\n const sessionId = typeof data.sessionId === \"string\" ? data.sessionId : void 0;\n switch (eventType) {\n case \"error\":\n broadcastEvent({\n error: typeof data.error === \"string\" ? data.error : typeof data.message === \"string\" ? data.message : \"Unknown error\",\n terminalId,\n tool,\n type: \"tool-failed\"\n });\n break;\n case \"idle_input\":\n case \"session.idle\":\n broadcastEvent({\n message: typeof data.message === \"string\" ? data.message : \"\",\n sessionId,\n terminalId,\n type: \"agent-idle\"\n });\n break;\n case \"permission\":\n case \"permission_notification\":\n if (data.requestId && data.toolName) {\n broadcastEvent({\n input: typeof data.toolInput === \"object\" && data.toolInput !== null ? data.toolInput : {},\n requestId: data.requestId,\n tool: data.toolName,\n type: \"permission-requested\"\n });\n }\n break;\n case \"question\":\n broadcastEvent({\n message: typeof data.message === \"string\" ? data.message : \"\",\n sessionId,\n terminalId,\n type: \"agent-question\"\n });\n break;\n case \"tool.after\":\n broadcastEvent({ success: true, terminalId, tool, type: \"tool-completed\" });\n break;\n case \"tool.before\":\n broadcastEvent({\n command: typeof data.command === \"string\" ? data.command : \"\",\n filePath: typeof data.filePath === \"string\" ? data.filePath : typeof data.files === \"string\" ? data.files : \"\",\n terminalId,\n tool,\n type: \"tool-started\"\n });\n break;\n }\n}\nfunction buildNotificationRecord(id, title, message, status, data, error) {\n return {\n category: data?.category ?? null,\n data: data ?? null,\n error: error ?? null,\n id,\n message,\n project: data?.project ?? null,\n source: data?.source ?? null,\n status,\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n title,\n tool: data?.tool ?? null\n };\n}\nfunction intelligentNotificationFilter(title, message, data, waitForResponse = false) {\n const source = data?.source || \"unknown\";\n if (isDuplicateNotification(title, message, data, waitForResponse)) {\n return {\n reason: \"Duplicate notification within 10-second window\",\n send: false\n };\n }\n if (source === \"smart-completion-detector\" || source === \"shooter-completion-detector\") {\n return {\n reason: \"Smart completion detector - completion or intervention needed\",\n send: true\n };\n }\n if (source === \"stop-hook\") {\n return {\n reason: \"Stop hook completion notification - session finished\",\n send: true\n };\n }\n const spamPatterns = [\n /PreToolUse/i,\n // Any PreToolUse notifications\n /PostToolUse/i,\n // Any PostToolUse notifications\n /^(Read|Write|Edit|Bash)\\s+Starting\\s*\\|\\s*\\w+$/i,\n // Only basic tool starting patterns\n /^unknown\\s*\\|\\s*\\w+$/i\n // Only \"unknown | projectname\" exactly\n ];\n const isSpam = spamPatterns.some((pattern) => pattern.test(title) || pattern.test(message));\n if (isSpam) {\n return {\n reason: \"Filtered spam notification from old hook system\",\n send: false\n };\n }\n const importantPatterns = [\n /session complete/i,\n /intervention needed/i,\n /error/i,\n /failed/i,\n /blocked/i,\n /attention/i\n ];\n const isImportant = importantPatterns.some(\n (pattern) => pattern.test(title) || pattern.test(message)\n );\n if (isImportant) {\n return {\n reason: \"Important notification - completion or intervention\",\n send: true\n };\n }\n return {\n reason: \"General notification - allowing by default\",\n send: true\n };\n}\nfunction isDuplicateNotification(title, message, data, waitForResponse = false) {\n if (waitForResponse) {\n return false;\n }\n const key = `${title}|${message}|${data?.category || \"unknown\"}`;\n const now = Date.now();\n if (notificationCache.has(key)) {\n const lastSent = notificationCache.get(key) ?? 0;\n if (now - lastSent < DEDUP_WINDOW) {\n return true;\n }\n }\n for (const [k, v] of notificationCache.entries()) {\n if (now - v > DEDUP_WINDOW) {\n notificationCache.delete(k);\n }\n }\n return false;\n}\nfunction recordNotification(title, message, data) {\n const key = `${title}|${message}|${data?.category || \"unknown\"}`;\n notificationCache.set(key, Date.now());\n}\nconst POST = async ({ request }) => {\n try {\n const apnsClient = getAPNsClient();\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n const rawBody = await request.json();\n if (!rawBody || typeof rawBody !== \"object\" || Array.isArray(rawBody)) {\n return json({ error: \"Request body must be a JSON object\" }, { status: 400 });\n }\n const body = rawBody;\n const data = body.data;\n const requestDeviceToken = body.deviceToken;\n const message = body.message;\n const title = body.title;\n const skipPush = typeof body.skipPush === \"boolean\" ? body.skipPush : false;\n const waitForResponse = typeof body.waitForResponse === \"boolean\" ? body.waitForResponse : false;\n try {\n broadcastHookEvent(body);\n } catch {\n }\n if (!title || typeof title !== \"string\" || !message || typeof message !== \"string\") {\n return json({ error: \"Title and message are required and must be strings\" }, { status: 400 });\n }\n if (requestDeviceToken !== void 0 && typeof requestDeviceToken !== \"string\") {\n return json({ error: \"deviceToken must be a string\" }, { status: 400 });\n }\n const requestId = Math.random().toString(36).substring(2, 15);\n const dataRequestId = typeof data?.requestId === \"string\" ? data.requestId : void 0;\n const canonicalRequestId = dataRequestId || requestId;\n const shouldSendNotification = intelligentNotificationFilter(\n title,\n message,\n data,\n waitForResponse\n );\n if (!shouldSendNotification.send) {\n addNotification(\n buildNotificationRecord(\n canonicalRequestId,\n title,\n message,\n \"filtered\",\n data,\n shouldSendNotification.reason\n )\n );\n return json({\n message: \"Notification filtered (not sent)\",\n reason: shouldSendNotification.reason,\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n if (skipPush) {\n if (waitForResponse) {\n createPendingRequest(canonicalRequestId, {\n sessionId: data?.sessionId || \"\",\n toolInput: data?.toolInput || {},\n toolName: data?.toolName || \"\"\n });\n }\n addNotification(buildNotificationRecord(canonicalRequestId, title, message, \"skipped\", data));\n return json({\n message: \"Push skipped (WebSocket clients connected)\",\n requestId: canonicalRequestId,\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n }\n const payload = {\n badge: 1,\n body: message,\n category: waitForResponse ? \"CLAUDE_PERMISSION\" : void 0,\n data: {\n ...data,\n requestId: canonicalRequestId,\n source: \"modern-apns-api\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString(),\n waitForResponse: waitForResponse || false\n },\n message: null,\n sound: \"default\",\n title\n };\n const platform = private_env.DEVICE_PLATFORM || \"ios\";\n if (platform === \"android\") {\n if (!isFCMConfigured()) {\n return json(\n {\n details: \"Missing FCM_PROJECT_ID, FCM_CLIENT_EMAIL, or FCM_PRIVATE_KEY environment variables\",\n error: \"FCM not configured\"\n },\n { status: 500 }\n );\n }\n const androidToken = requestDeviceToken?.trim() || (private_env.ANDROID_DEVICE_TOKEN || private_env.DEVICE_TOKEN)?.trim();\n if (!androidToken) {\n return json(\n {\n details: \"ANDROID_DEVICE_TOKEN or DEVICE_TOKEN environment variable is missing and no deviceToken in request body\",\n error: \"No device token configured\"\n },\n { status: 500 }\n );\n }\n const fcmResult = await sendFCMNotification(androidToken, payload);\n if (fcmResult.success) {\n recordNotification(title, message, data);\n if (waitForResponse) {\n createPendingRequest(canonicalRequestId, {\n sessionId: data?.sessionId || \"\",\n toolInput: data?.toolInput || {},\n toolName: data?.toolName || \"\"\n });\n }\n addNotification(buildNotificationRecord(canonicalRequestId, title, message, \"sent\", data));\n return json({\n message: \"Notification sent successfully\",\n requestId: canonicalRequestId,\n result: { messageId: fcmResult.messageId },\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } else {\n console.error(`[notify] FCM delivery failed: ${fcmResult.error}`);\n addNotification(\n buildNotificationRecord(\n canonicalRequestId,\n title,\n message,\n \"failed\",\n data,\n fcmResult.error\n )\n );\n return json(\n {\n details: fcmResult.error,\n error: \"Failed to send notification\",\n requestId: canonicalRequestId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n },\n { status: 500 }\n );\n }\n } else {\n if (!apnsClient.isConfigured()) {\n return json(\n {\n details: \"Missing APNS_KEY, APNS_KEY_ID, or APNS_TEAM_ID environment variables\",\n error: \"APNs client not configured\"\n },\n { status: 500 }\n );\n }\n const deviceToken = requestDeviceToken?.trim() || private_env.DEVICE_TOKEN?.trim();\n if (!deviceToken) {\n return json(\n {\n details: \"DEVICE_TOKEN environment variable is missing and no deviceToken in request body\",\n error: \"No device token configured\"\n },\n { status: 500 }\n );\n }\n try {\n const result = await apnsClient.sendNotification(deviceToken, payload);\n recordNotification(title, message, data);\n if (waitForResponse) {\n createPendingRequest(canonicalRequestId, {\n sessionId: data?.sessionId || \"\",\n toolInput: data?.toolInput || {},\n toolName: data?.toolName || \"\"\n });\n }\n addNotification(buildNotificationRecord(canonicalRequestId, title, message, \"sent\", data));\n return json({\n message: \"Notification sent successfully\",\n requestId: canonicalRequestId,\n result,\n success: true,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n } catch (notificationError) {\n const notifErrMsg = toErrorMessage(notificationError);\n console.error(`[notify] APNs delivery failed: ${notifErrMsg}`);\n addNotification(\n buildNotificationRecord(canonicalRequestId, title, message, \"failed\", data, notifErrMsg)\n );\n return json(\n {\n details: notifErrMsg,\n error: \"Failed to send notification\",\n requestId: canonicalRequestId,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n },\n { status: 500 }\n );\n }\n }\n } catch (error) {\n console.error(\"Notification error:\", error);\n return json(\n {\n details: toErrorMessage(error),\n error: \"Failed to send notification\",\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n },\n { status: 500 }\n );\n }\n};\nconst GET = ({ request, url }) => {\n const authError = validateAuth(request);\n if (authError) {\n return authError;\n }\n const limit = parseInt(url.searchParams.get(\"limit\") || \"50\");\n const notifications = getNotifications(limit);\n return json({\n count: notifications.length,\n notifications,\n timestamp: (/* @__PURE__ */ new Date()).toISOString()\n });\n};\nexport {\n GET,\n POST\n};\n"],"names":[],"mappings":"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"}
|