agent-session-inspector 0.1.4 → 0.1.6

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.
Files changed (86) hide show
  1. package/README.md +157 -65
  2. package/VERSION +1 -1
  3. package/app/.next/BUILD_ID +1 -1
  4. package/app/.next/build-manifest.json +3 -3
  5. package/app/.next/prerender-manifest.json +5 -5
  6. package/app/.next/required-server-files.json +1 -1
  7. package/app/.next/server/app/_global-error.html +1 -1
  8. package/app/.next/server/app/_global-error.rsc +1 -1
  9. package/app/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  10. package/app/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  11. package/app/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  12. package/app/.next/server/app/_not-found/page.js.nft.json +1 -1
  13. package/app/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  14. package/app/.next/server/app/_not-found.html +1 -1
  15. package/app/.next/server/app/_not-found.rsc +16 -16
  16. package/app/.next/server/app/_not-found.segments/_full.segment.rsc +16 -16
  17. package/app/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +19 -18
  18. package/app/.next/server/app/_not-found.segments/_tree.segment.rsc +3 -3
  19. package/app/.next/server/app/api/analytics/route.js.nft.json +1 -1
  20. package/app/.next/server/app/api/logs/route.js.nft.json +1 -1
  21. package/app/.next/server/app/api/pricing/route.js.nft.json +1 -1
  22. package/app/.next/server/app/api/providers/route.js.nft.json +1 -1
  23. package/app/.next/server/app/api/search/route.js.nft.json +1 -1
  24. package/app/.next/server/app/api/sessions/[provider]/[id]/reveal/route.js.nft.json +1 -1
  25. package/app/.next/server/app/api/sessions/[provider]/[id]/route.js.nft.json +1 -1
  26. package/app/.next/server/app/api/sessions/route.js.nft.json +1 -1
  27. package/app/.next/server/app/index.html +1 -1
  28. package/app/.next/server/app/index.rsc +18 -18
  29. package/app/.next/server/app/index.segments/__PAGE__.segment.rsc +16 -16
  30. package/app/.next/server/app/index.segments/_full.segment.rsc +18 -18
  31. package/app/.next/server/app/index.segments/_tree.segment.rsc +3 -3
  32. package/app/.next/server/app/page.js.nft.json +1 -1
  33. package/app/.next/server/app/page_client-reference-manifest.js +1 -1
  34. package/app/.next/server/app/sessions/[provider]/[id]/page.js.nft.json +1 -1
  35. package/app/.next/server/app/sessions/[provider]/[id]/page_client-reference-manifest.js +1 -1
  36. package/app/.next/server/chunks/[root-of-the-server]__0dyq0rc._.js +1 -1
  37. package/app/.next/server/chunks/[root-of-the-server]__0kgkqhn._.js +1 -1
  38. package/app/.next/server/chunks/[root-of-the-server]__0yxic1z._.js +3 -3
  39. package/app/.next/server/chunks/[root-of-the-server]__10p8y9z._.js +1 -1
  40. package/app/.next/server/chunks/[root-of-the-server]__1cceere._.js +1 -1
  41. package/app/.next/server/chunks/[root-of-the-server]__1eclfq8._.js +1 -1
  42. package/app/.next/server/chunks/[root-of-the-server]__1lz20wm._.js +1 -1
  43. package/app/.next/server/chunks/[root-of-the-server]__1zdh1mi._.js +1 -1
  44. package/app/.next/server/chunks/[root-of-the-server]__20epvou._.js +1 -1
  45. package/app/.next/server/chunks/ssr/[root-of-the-server]__1ei65vj._.js +1 -1
  46. package/app/.next/server/chunks/ssr/_0f8nmc3._.js +1 -1
  47. package/app/.next/server/chunks/ssr/_0o294sf._.js +1 -1
  48. package/app/.next/server/chunks/ssr/_0wfo2z0._.js +3 -0
  49. package/app/.next/server/chunks/ssr/_12__495._.js +1 -1
  50. package/app/.next/server/chunks/ssr/src_app_page_tsx_1chiuah._.js +1 -1
  51. package/app/.next/server/chunks/ssr/src_app_sessions_[provider]_[id]_page_tsx_0uf635h._.js +3 -3
  52. package/app/.next/server/middleware-build-manifest.js +3 -3
  53. package/app/.next/server/pages/404.html +1 -1
  54. package/app/.next/server/pages/500.html +1 -1
  55. package/app/.next/server/server-reference-manifest.js +1 -1
  56. package/app/.next/server/server-reference-manifest.json +1 -1
  57. package/app/.next/static/chunks/{10x4j1wts3xx2.js → 0mihgzifdany7.js} +1 -1
  58. package/app/.next/static/chunks/{367imffzz5g8x.css → 0ua57-s0meis5.css} +2 -2
  59. package/app/.next/static/chunks/{31hdfb4m8lwzz.js → 1fe2mxakoweia.js} +1 -1
  60. package/app/.next/static/chunks/1uvlni5bd236c.js +6 -0
  61. package/app/.next/static/chunks/1z_genu21d6mc.js +1 -0
  62. package/app/.next/static/chunks/3-g9jvt_m-6_4.js +1 -0
  63. package/app/.next/static/chunks/3xq2kqjs_2byl.css +1 -0
  64. package/app/CONTRIBUTING.md +21 -2
  65. package/app/README.md +157 -65
  66. package/app/bin/agent-session-inspector.mjs +37 -11
  67. package/app/eslint.config.mjs +1 -0
  68. package/app/package.json +6 -2
  69. package/app/pnpm-lock.yaml +271 -0
  70. package/app/pnpm-workspace.yaml +1 -0
  71. package/app/scripts/build-cli.mjs +26 -0
  72. package/app/scripts/demo-data.mjs +48 -1
  73. package/app/scripts/deploy-docker.sh +6 -2
  74. package/app/scripts/package-release.sh +3 -1
  75. package/app/server.js +1 -1
  76. package/bin/agent-session-inspector.mjs +37 -11
  77. package/cli/cli.mjs +7612 -0
  78. package/package.json +5 -2
  79. package/app/.next/server/chunks/ssr/_1-5v1mi._.js +0 -3
  80. package/app/.next/static/chunks/1dz8a9ds45tdb.js +0 -6
  81. package/app/.next/static/chunks/1g3ep2o7fhgpe.css +0 -1
  82. package/app/.next/static/chunks/2iedud09ou282.js +0 -1
  83. package/app/.next/static/chunks/2k65elb1vo-2z.js +0 -1
  84. /package/app/.next/static/{KFq9wlUt8U-Sma3McE5Jw → rpBXcMOzD9z_w4Y9uQJJ-}/_buildManifest.js +0 -0
  85. /package/app/.next/static/{KFq9wlUt8U-Sma3McE5Jw → rpBXcMOzD9z_w4Y9uQJJ-}/_clientMiddlewareManifest.js +0 -0
  86. /package/app/.next/static/{KFq9wlUt8U-Sma3McE5Jw → rpBXcMOzD9z_w4Y9uQJJ-}/_ssgManifest.js +0 -0
@@ -66,6 +66,9 @@ importers:
66
66
  '@types/react-dom':
67
67
  specifier: ^19
68
68
  version: 19.2.4(@types/react@19.2.18)
69
+ esbuild:
70
+ specifier: ^0.28.2
71
+ version: 0.28.2
69
72
  eslint:
70
73
  specifier: ^9
71
74
  version: 9.39.5(jiti@2.7.0)(supports-color@7.2.0)
@@ -267,6 +270,162 @@ packages:
267
270
  '@emnapi/wasi-threads@1.2.1':
268
271
  resolution: {integrity: sha512-uTII7OYF+/Mes/MrcIOYp5yOtSMLBWSIoLPpcgwipoiKbli6k322tcoFsxoIIxPDqW01SQGAgko4EzZi2BNv2w==}
269
272
 
273
+ '@esbuild/aix-ppc64@0.28.2':
274
+ resolution: {integrity: sha512-XExcO+dvLKvVtNTibSTBej1NCAbaGhWn9Ww1ZPx80qsahhPFe/8jgWP0IchNe0F3HwkU7n8ejhH8bjonqht8mQ==}
275
+ engines: {node: '>=18'}
276
+ cpu: [ppc64]
277
+ os: [aix]
278
+
279
+ '@esbuild/android-arm64@0.28.2':
280
+ resolution: {integrity: sha512-5YfKeeI8qWfBZIX+u2xZC3Zlb3Os/gLS2sbEKM+I4ZOcsWmHS2WLysCcQZDAFRslDUU5Oiq44gf6PYN1vGwG5A==}
281
+ engines: {node: '>=18'}
282
+ cpu: [arm64]
283
+ os: [android]
284
+
285
+ '@esbuild/android-arm@0.28.2':
286
+ resolution: {integrity: sha512-kXXoiPVVGQcnIYGOeaovwOURpniDBpSq4A03qkQ+BMQqtGG6HYap3xne9C1O1yo4TR3qxlCX5IqqmX6fFo2Lqg==}
287
+ engines: {node: '>=18'}
288
+ cpu: [arm]
289
+ os: [android]
290
+
291
+ '@esbuild/android-x64@0.28.2':
292
+ resolution: {integrity: sha512-O387ite7SzUyCcy3JQX4P4bLtEA7bLLkx+esve5JHnyYfNTxcVpXZo9jhdB0lTKN44gztELTdU7nS8Nr16Fs1Q==}
293
+ engines: {node: '>=18'}
294
+ cpu: [x64]
295
+ os: [android]
296
+
297
+ '@esbuild/darwin-arm64@0.28.2':
298
+ resolution: {integrity: sha512-n4KqkOQrraxHJcgjM1RvwbigfQKIKJVpM7xp+KsxiyUSrRdIXnt73VhrPAx0fV44hgfmIVKjxMN9J1t5jySVkw==}
299
+ engines: {node: '>=18'}
300
+ cpu: [arm64]
301
+ os: [darwin]
302
+
303
+ '@esbuild/darwin-x64@0.28.2':
304
+ resolution: {integrity: sha512-uq6suIWYP37qzGddBKPw5QEQPi6HiLGsO7UmkpfyaYNQ3D+rN6w6WfwH+nuqcGXWvawGwxOEroO4YGnFh95azw==}
305
+ engines: {node: '>=18'}
306
+ cpu: [x64]
307
+ os: [darwin]
308
+
309
+ '@esbuild/freebsd-arm64@0.28.2':
310
+ resolution: {integrity: sha512-n+I0BTSRIoy+d6RPKnEVwql5UwBJolytvY4mAOIEJorKlqgPII8ix6slVVrfZ5Tnj7glIZvloylbB/EJPMWEXw==}
311
+ engines: {node: '>=18'}
312
+ cpu: [arm64]
313
+ os: [freebsd]
314
+
315
+ '@esbuild/freebsd-x64@0.28.2':
316
+ resolution: {integrity: sha512-78XJTJkvPs0kz2w61301PJjXl4g7q3JqiYMZ/M/yVI73EHBrCRTgkhu9oqG7vPqq+a/yadEW8aD+agKlk5xrmg==}
317
+ engines: {node: '>=18'}
318
+ cpu: [x64]
319
+ os: [freebsd]
320
+
321
+ '@esbuild/linux-arm64@0.28.2':
322
+ resolution: {integrity: sha512-pW4AC0P3it8c7do9MVM4p51FzHzdM/TZrerurgRcHJ2WTa1VQ1CIq18xncfpBJw4ojkiZZrKW2yIBWBP92j6Ug==}
323
+ engines: {node: '>=18'}
324
+ cpu: [arm64]
325
+ os: [linux]
326
+
327
+ '@esbuild/linux-arm@0.28.2':
328
+ resolution: {integrity: sha512-XlDnu2q5yoqems+xay6wSAcg9DDD7K9RLKZEBOMZm3ckNpJBvOX20tSfby8KfrrhINDyv9V2YVZKY/SpoGJI8w==}
329
+ engines: {node: '>=18'}
330
+ cpu: [arm]
331
+ os: [linux]
332
+
333
+ '@esbuild/linux-ia32@0.28.2':
334
+ resolution: {integrity: sha512-CYbnj78HsIeA+DhgUKgFCfvNsTHFhMMrinUrMZpDXJXKN8T3XViTZ/+wtHeVxEWY8ewSzTFN+nRmSwO2tZaLUQ==}
335
+ engines: {node: '>=18'}
336
+ cpu: [ia32]
337
+ os: [linux]
338
+
339
+ '@esbuild/linux-loong64@0.28.2':
340
+ resolution: {integrity: sha512-buwkd8nsph4R+ajRvw0qM5Hja/TXQow3ptzWO2EbG/cqcIkHloRrdlBtQlshyYGTNFvfkfJ5tpPLVkY4DtsPfQ==}
341
+ engines: {node: '>=18'}
342
+ cpu: [loong64]
343
+ os: [linux]
344
+
345
+ '@esbuild/linux-mips64el@0.28.2':
346
+ resolution: {integrity: sha512-ZVykbDyk7519VwiNb9Lcj9m8XM6v5V9uKPvrEMkkEedVewf+0itkhahp4HDpgERXhwLRpWFypsGbG/J8s0QjJA==}
347
+ engines: {node: '>=18'}
348
+ cpu: [mips64el]
349
+ os: [linux]
350
+
351
+ '@esbuild/linux-ppc64@0.28.2':
352
+ resolution: {integrity: sha512-CAXl+Dtd9UUuJd8pKKdwh6MLm3MUMiqMPmhZ3tTSXPqfyQ3vDl6R5hZdZ/kYojK4ofXtdfSv1tFq8XzWx3heNQ==}
353
+ engines: {node: '>=18'}
354
+ cpu: [ppc64]
355
+ os: [linux]
356
+
357
+ '@esbuild/linux-riscv64@0.28.2':
358
+ resolution: {integrity: sha512-GeXCej4IQtU1B+QlDV8W/RRvbzI3O/Stss+/bCXv4lZls5WGRtu2a+3JkA3i4qIUlMXpcHebWpF8AkJhATowuA==}
359
+ engines: {node: '>=18'}
360
+ cpu: [riscv64]
361
+ os: [linux]
362
+
363
+ '@esbuild/linux-s390x@0.28.2':
364
+ resolution: {integrity: sha512-3H1weTYZPxt/WOhByszQZybS9w5lKzUn1FDMsgEChbHWQwHYQQRfBxgCcZvPhjHfKyJjIievvMmEUawJrdY9Dg==}
365
+ engines: {node: '>=18'}
366
+ cpu: [s390x]
367
+ os: [linux]
368
+
369
+ '@esbuild/linux-x64@0.28.2':
370
+ resolution: {integrity: sha512-4xTZr1FUmSoQW4XIWmit3tzQrUTZM+N3P0XV8xROKYF50XfI7xeO90+1bZvNwxIufQ9hDQVRJH5YhgPVF8A/HQ==}
371
+ engines: {node: '>=18'}
372
+ cpu: [x64]
373
+ os: [linux]
374
+
375
+ '@esbuild/netbsd-arm64@0.28.2':
376
+ resolution: {integrity: sha512-sSATRjPeDBg3pdgHoQfoYBob11Kk1FGa9lui5RIHZCoCkJa9QKlvl3/vKz2usCmYYjs7ymJR/2Nnsqe+Hjt5nw==}
377
+ engines: {node: '>=18'}
378
+ cpu: [arm64]
379
+ os: [netbsd]
380
+
381
+ '@esbuild/netbsd-x64@0.28.2':
382
+ resolution: {integrity: sha512-lqnzCV+mM0gIADaKihiCg6ifgfU2L3h5E33rNQBN1Y4MaVGnzryzmvvf7UHxprpQdE8hpqLolJ9Rl+SkIRDpyw==}
383
+ engines: {node: '>=18'}
384
+ cpu: [x64]
385
+ os: [netbsd]
386
+
387
+ '@esbuild/openbsd-arm64@0.28.2':
388
+ resolution: {integrity: sha512-AL2qJILH7lNjrDmCQDvdxMfAUIv8KMNZOvrwAQ8i8//ntL9FflhOyMJ8OZSMBb8/AWXe3/5v5S20y3zCoZWKoQ==}
389
+ engines: {node: '>=18'}
390
+ cpu: [arm64]
391
+ os: [openbsd]
392
+
393
+ '@esbuild/openbsd-x64@0.28.2':
394
+ resolution: {integrity: sha512-QtiuPytchRyC4rwUKhexJdQKvDuZ6hWloi3igqPQNUJCS1/v9EiO3UTOXR6A3FoMo4fnAKbWJdqaIwhOzh8qEw==}
395
+ engines: {node: '>=18'}
396
+ cpu: [x64]
397
+ os: [openbsd]
398
+
399
+ '@esbuild/openharmony-arm64@0.28.2':
400
+ resolution: {integrity: sha512-WkhYDmpTjLvGlScA1rwjRUmhl4k8oXR3cIbtqWmELgU/dFeHHlEllxDvdWcNJV9rbzCexB5vz8gtNewWLgCT7Q==}
401
+ engines: {node: '>=18'}
402
+ cpu: [arm64]
403
+ os: [openharmony]
404
+
405
+ '@esbuild/sunos-x64@0.28.2':
406
+ resolution: {integrity: sha512-GPMSkTOtMnv2U2F8gxe4Io6qmVs+YKyp832Etqqxr0hFngmXQ3rzwytelm3GIn7T4VviRUlf3sOgBOiTdvaf7g==}
407
+ engines: {node: '>=18'}
408
+ cpu: [x64]
409
+ os: [sunos]
410
+
411
+ '@esbuild/win32-arm64@0.28.2':
412
+ resolution: {integrity: sha512-PIhhEkE9uPBleRBrQEJpUn7MBnibZzbGzYWPmY3x+YoVg/95zbjB4CxPPOQ8l5tYYM4mMaCthF8/1DIfBQQyWQ==}
413
+ engines: {node: '>=18'}
414
+ cpu: [arm64]
415
+ os: [win32]
416
+
417
+ '@esbuild/win32-ia32@0.28.2':
418
+ resolution: {integrity: sha512-YmJbfTlvU7Sdn9BB+4PRES4oB6pxgS37MAONj+hBr/cpXS1aBPKXxNnDbu+QCWPj0o9dgyxeq79g6c5P8KeuYA==}
419
+ engines: {node: '>=18'}
420
+ cpu: [ia32]
421
+ os: [win32]
422
+
423
+ '@esbuild/win32-x64@0.28.2':
424
+ resolution: {integrity: sha512-5ebpxr3nWMzrL/rnUI755Jkuee0bHL/Gq0WTF9lvcpv73wAp5eu8MfBUgWK9bhWvZjj7yX8etf/8tI8Ney695g==}
425
+ engines: {node: '>=18'}
426
+ cpu: [x64]
427
+ os: [win32]
428
+
270
429
  '@eslint-community/eslint-utils@4.10.1':
271
430
  resolution: {integrity: sha512-cuadcxVFE8sDK6iWJbs8Sn0av2Nrh2QSGQhVlBW9AaAHqHwjWsZHT8LJ4hFGPh7ASBV2deFdM7H/DPjulmh8rg==}
272
431
  engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0}
@@ -1441,6 +1600,11 @@ packages:
1441
1600
  resolution: {integrity: sha512-yPDz7wqpg1/mmHLmS3tcfTfbw5f1eryXvyghYBffGdERwe+mV7ZcWzTR8LR17Kvqt3qfPurjlonmnq3MKXIOXw==}
1442
1601
  engines: {node: '>= 0.4'}
1443
1602
 
1603
+ esbuild@0.28.2:
1604
+ resolution: {integrity: sha512-HKVLS8dvII+xoKW9kmqxbRKrnWEXfJJr/FZhhJmiqIB0e053QNYFqOBouTMO/k5sID4MvCiUCvv8b9M4h32wIA==}
1605
+ engines: {node: '>=18'}
1606
+ hasBin: true
1607
+
1444
1608
  escalade@3.2.0:
1445
1609
  resolution: {integrity: sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA==}
1446
1610
  engines: {node: '>=6'}
@@ -3471,6 +3635,84 @@ snapshots:
3471
3635
  tslib: 2.8.1
3472
3636
  optional: true
3473
3637
 
3638
+ '@esbuild/aix-ppc64@0.28.2':
3639
+ optional: true
3640
+
3641
+ '@esbuild/android-arm64@0.28.2':
3642
+ optional: true
3643
+
3644
+ '@esbuild/android-arm@0.28.2':
3645
+ optional: true
3646
+
3647
+ '@esbuild/android-x64@0.28.2':
3648
+ optional: true
3649
+
3650
+ '@esbuild/darwin-arm64@0.28.2':
3651
+ optional: true
3652
+
3653
+ '@esbuild/darwin-x64@0.28.2':
3654
+ optional: true
3655
+
3656
+ '@esbuild/freebsd-arm64@0.28.2':
3657
+ optional: true
3658
+
3659
+ '@esbuild/freebsd-x64@0.28.2':
3660
+ optional: true
3661
+
3662
+ '@esbuild/linux-arm64@0.28.2':
3663
+ optional: true
3664
+
3665
+ '@esbuild/linux-arm@0.28.2':
3666
+ optional: true
3667
+
3668
+ '@esbuild/linux-ia32@0.28.2':
3669
+ optional: true
3670
+
3671
+ '@esbuild/linux-loong64@0.28.2':
3672
+ optional: true
3673
+
3674
+ '@esbuild/linux-mips64el@0.28.2':
3675
+ optional: true
3676
+
3677
+ '@esbuild/linux-ppc64@0.28.2':
3678
+ optional: true
3679
+
3680
+ '@esbuild/linux-riscv64@0.28.2':
3681
+ optional: true
3682
+
3683
+ '@esbuild/linux-s390x@0.28.2':
3684
+ optional: true
3685
+
3686
+ '@esbuild/linux-x64@0.28.2':
3687
+ optional: true
3688
+
3689
+ '@esbuild/netbsd-arm64@0.28.2':
3690
+ optional: true
3691
+
3692
+ '@esbuild/netbsd-x64@0.28.2':
3693
+ optional: true
3694
+
3695
+ '@esbuild/openbsd-arm64@0.28.2':
3696
+ optional: true
3697
+
3698
+ '@esbuild/openbsd-x64@0.28.2':
3699
+ optional: true
3700
+
3701
+ '@esbuild/openharmony-arm64@0.28.2':
3702
+ optional: true
3703
+
3704
+ '@esbuild/sunos-x64@0.28.2':
3705
+ optional: true
3706
+
3707
+ '@esbuild/win32-arm64@0.28.2':
3708
+ optional: true
3709
+
3710
+ '@esbuild/win32-ia32@0.28.2':
3711
+ optional: true
3712
+
3713
+ '@esbuild/win32-x64@0.28.2':
3714
+ optional: true
3715
+
3474
3716
  '@eslint-community/eslint-utils@4.10.1(eslint@9.39.5(jiti@2.7.0)(supports-color@7.2.0))':
3475
3717
  dependencies:
3476
3718
  eslint: 9.39.5(jiti@2.7.0)(supports-color@7.2.0)
@@ -4592,6 +4834,35 @@ snapshots:
4592
4834
  is-date-object: 1.1.0
4593
4835
  is-symbol: 1.1.1
4594
4836
 
4837
+ esbuild@0.28.2:
4838
+ optionalDependencies:
4839
+ '@esbuild/aix-ppc64': 0.28.2
4840
+ '@esbuild/android-arm': 0.28.2
4841
+ '@esbuild/android-arm64': 0.28.2
4842
+ '@esbuild/android-x64': 0.28.2
4843
+ '@esbuild/darwin-arm64': 0.28.2
4844
+ '@esbuild/darwin-x64': 0.28.2
4845
+ '@esbuild/freebsd-arm64': 0.28.2
4846
+ '@esbuild/freebsd-x64': 0.28.2
4847
+ '@esbuild/linux-arm': 0.28.2
4848
+ '@esbuild/linux-arm64': 0.28.2
4849
+ '@esbuild/linux-ia32': 0.28.2
4850
+ '@esbuild/linux-loong64': 0.28.2
4851
+ '@esbuild/linux-mips64el': 0.28.2
4852
+ '@esbuild/linux-ppc64': 0.28.2
4853
+ '@esbuild/linux-riscv64': 0.28.2
4854
+ '@esbuild/linux-s390x': 0.28.2
4855
+ '@esbuild/linux-x64': 0.28.2
4856
+ '@esbuild/netbsd-arm64': 0.28.2
4857
+ '@esbuild/netbsd-x64': 0.28.2
4858
+ '@esbuild/openbsd-arm64': 0.28.2
4859
+ '@esbuild/openbsd-x64': 0.28.2
4860
+ '@esbuild/openharmony-arm64': 0.28.2
4861
+ '@esbuild/sunos-x64': 0.28.2
4862
+ '@esbuild/win32-arm64': 0.28.2
4863
+ '@esbuild/win32-ia32': 0.28.2
4864
+ '@esbuild/win32-x64': 0.28.2
4865
+
4595
4866
  escalade@3.2.0: {}
4596
4867
 
4597
4868
  escape-html@1.0.3: {}
@@ -1,2 +1,3 @@
1
1
  allowBuilds:
2
+ esbuild: false
2
3
  unrs-resolver: true
@@ -0,0 +1,26 @@
1
+ #!/usr/bin/env node
2
+ // Bundles src/cli into the single file the launcher loads for report commands
3
+ // (usage, stats, sessions). Output defaults to cli/cli.mjs beside bin/, which
4
+ // is where bin/agent-session-inspector.mjs looks in a checkout and in the
5
+ // packaged build alike.
6
+ import { build } from "esbuild";
7
+ import path from "node:path";
8
+ import { fileURLToPath } from "node:url";
9
+
10
+ const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
11
+ const outfile = path.resolve(process.argv[2] ?? path.join(ROOT, "cli", "cli.mjs"));
12
+
13
+ await build({
14
+ entryPoints: [path.join(ROOT, "src", "cli", "index.ts")],
15
+ outfile,
16
+ bundle: true,
17
+ platform: "node",
18
+ format: "esm",
19
+ target: "node22",
20
+ alias: { "@": path.join(ROOT, "src") },
21
+ // Bundled CommonJS dependencies call require() for Node built-ins.
22
+ banner: {
23
+ js: 'import { createRequire as __createRequire } from "node:module";\nconst require = __createRequire(import.meta.url);',
24
+ },
25
+ logLevel: "warning",
26
+ });
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- // Writes a fake $HOME with synthetic Claude Code, Codex and Copilot transcripts, so the
2
+ // Writes a fake $HOME with synthetic Claude Code, Codex, Copilot and Gemini CLI transcripts, so the
3
3
  // UI can be demoed (and README screenshots retaken) without exposing real
4
4
  // sessions. Usage:
5
5
  // node scripts/demo-data.mjs /tmp/asi-demo
@@ -284,5 +284,52 @@ const codexId = "0199a3f2-7c41-7d20-9e8b-5a4c3b2d1e0f";
284
284
  );
285
285
  }
286
286
 
287
+ // ----------------------------------------------------------------- Gemini CLI
288
+
289
+ {
290
+ const id = "7c1e4a92-5b3d-4f08-9a6e-2d8f0b3c5e71";
291
+ const cwd = "/Users/demo/code/weather-api";
292
+ const start = "2026-09-25T09:10:00Z";
293
+ const at = clock(start);
294
+ const project = path.join(root, ".gemini", "tmp", "weather-api");
295
+ const model = "gemini-3.7-flash";
296
+ fs.mkdirSync(project, { recursive: true });
297
+ fs.writeFileSync(path.join(project, ".project_root"), cwd);
298
+
299
+ const tool = (callId, name, args, output) => ({
300
+ id: callId,
301
+ name,
302
+ args,
303
+ status: "success",
304
+ timestamp: at(2),
305
+ result: [{ functionResponse: { id: callId, name, response: { output } } }],
306
+ });
307
+ const reply = (messageId, fields) => ({ id: messageId, timestamp: at(4), type: "gemini", content: "", model, ...fields });
308
+ const prompt = { id: "m1", timestamp: at(3), type: "user", content: [{ text: "Forecast responses are cached for an hour. Make the TTL configurable." }] };
309
+ const grep = reply("m2", {
310
+ thoughts: [{ subject: "Locating the cache", description: "The forecast handler should own the TTL; search for it first.", timestamp: at(1) }],
311
+ tokens: { input: 11_200, output: 140, cached: 0, thoughts: 220, tool: 0, total: 11_560 },
312
+ });
313
+ writeJsonl(path.join(project, "chats", `session-2026-09-25T09-10-${id.slice(0, 8)}.jsonl`), [
314
+ { sessionId: id, projectHash: "3f9a1c", startTime: start, lastUpdated: start },
315
+ prompt,
316
+ grep,
317
+ // The CLI writes a message again as its tool calls come in; the last copy wins.
318
+ { ...grep, toolCalls: [tool("g1", "search_file_content", { pattern: "CACHE_TTL" }, "src/forecast/cache.ts:4:const CACHE_TTL = 3600;")] },
319
+ reply("m3", {
320
+ toolCalls: [
321
+ tool("g2", "replace", { file_path: `${cwd}/src/forecast/cache.ts`, old_string: "const CACHE_TTL = 3600;", new_string: "const CACHE_TTL = Number(process.env.FORECAST_TTL ?? 3600);" }, "Successfully modified file."),
322
+ tool("g3", "run_shell_command", { command: "npm test -- forecast" }, "Tests: 12 passed, 12 total"),
323
+ ],
324
+ tokens: { input: 12_900, output: 310, cached: 10_400, thoughts: 90, tool: 0, total: 13_300 },
325
+ }),
326
+ reply("m4", {
327
+ content: "The TTL now reads `FORECAST_TTL` (seconds) and falls back to one hour. All 12 forecast tests pass.",
328
+ tokens: { input: 13_600, output: 95, cached: 12_100, thoughts: 0, tool: 0, total: 13_695 },
329
+ }),
330
+ { $set: { lastUpdated: at(0), summary: "Make forecast cache TTL configurable" } },
331
+ ]);
332
+ }
333
+
287
334
  console.log(`Demo home written to ${root}`);
288
335
  console.log(`Run: HOME=${root} pnpm dev`);
@@ -10,8 +10,10 @@ if docker container inspect "$NAME" >/dev/null 2>&1; then
10
10
  fi
11
11
 
12
12
  # Mount only the transcript paths the app reads, read-only. Deliberately narrow:
13
- # ~/.codex/auth.json, ~/.copilot/config.json and ~/.hermes/auth.json hold
14
- # credentials and stay out.
13
+ # ~/.codex/auth.json, ~/.copilot/config.json, ~/.hermes/auth.json and
14
+ # ~/.gemini/oauth_creds.json hold credentials and stay out. So does Cursor's
15
+ # state.vscdb, which keeps its sign-in next to the chats: Cursor sessions are
16
+ # read from the transcripts under ~/.cursor/projects instead.
15
17
  PATHS=(
16
18
  ".copilot/session-state"
17
19
  ".copilot/logs"
@@ -27,6 +29,8 @@ PATHS=(
27
29
  ".hermes/state.db"
28
30
  ".hermes/state.db-shm"
29
31
  ".hermes/state.db-wal"
32
+ ".gemini/tmp"
33
+ ".cursor/projects"
30
34
  )
31
35
 
32
36
  # Desktop apps keep their data somewhere else on each OS; inside the Linux
@@ -31,6 +31,8 @@ cp -R .next/static "$APP/.next/static"
31
31
  mkdir -p "$STAGE/bin"
32
32
  cp "bin/$NAME.mjs" "$STAGE/bin/$NAME.mjs"
33
33
  chmod +x "$STAGE/bin/$NAME.mjs"
34
+ # The report commands (usage, stats, sessions) run from their own bundle.
35
+ node scripts/build-cli.mjs "$STAGE/cli/cli.mjs"
34
36
  echo "$VERSION" > "$STAGE/VERSION"
35
37
  cp README.md LICENSE "$STAGE/"
36
38
 
@@ -74,7 +76,7 @@ node -e '
74
76
  console.log(JSON.stringify({
75
77
  name, version, description, keywords, author, license, homepage, bugs, repository, engines,
76
78
  bin: { [name]: `bin/${name}.mjs` },
77
- files: ["app", "bin", "VERSION"],
79
+ files: ["app", "bin", "cli", "VERSION"],
78
80
  }, null, 2));
79
81
  ' "$ROOT/package.json" "$NAME" "$VERSION" > "$STAGE/package.json"
80
82
 
package/app/server.js CHANGED
@@ -9,7 +9,7 @@ const currentPort = parseInt(process.env.PORT, 10) || 3000
9
9
  const hostname = process.env.HOSTNAME || '0.0.0.0'
10
10
 
11
11
  let keepAliveTimeout = parseInt(process.env.KEEP_ALIVE_TIMEOUT, 10)
12
- const nextConfig = {"env":{"APP_VERSION":"0.1.4"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"instrumentationClientInject":[],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/agent-session-inspector/agent-session-inspector","enablePrerenderSourceMaps":true,"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"/**":["./.git/**","./.claude/**","./src/**"]},"repoRoot":"/home/runner/work/agent-session-inspector/agent-session-inspector","turbopack":{"root":"/home/runner/work/agent-session-inspector/agent-session-inspector"},"distDirRoot":".next"}
12
+ const nextConfig = {"env":{"APP_VERSION":"0.1.6"},"webpack":null,"typescript":{"ignoreBuildErrors":false},"typedRoutes":false,"distDir":"./.next","cleanDistDir":true,"assetPrefix":"","cacheMaxMemorySize":52428800,"configOrigin":"next.config.ts","useFileSystemPublicRoutes":true,"generateEtags":true,"pageExtensions":["tsx","ts","jsx","js"],"instrumentationClientInject":[],"poweredByHeader":true,"compress":true,"images":{"deviceSizes":[640,750,828,1080,1200,1920,2048,3840],"imageSizes":[32,48,64,96,128,256,384],"path":"/_next/image","loader":"default","loaderFile":"","domains":[],"disableStaticImages":false,"minimumCacheTTL":14400,"formats":["image/webp"],"maximumRedirects":3,"maximumResponseBody":50000000,"dangerouslyAllowLocalIP":false,"dangerouslyAllowSVG":false,"contentSecurityPolicy":"script-src 'none'; frame-src 'none'; sandbox;","contentDispositionType":"attachment","localPatterns":[{"pathname":"**","search":""}],"remotePatterns":[],"qualities":[75],"unoptimized":true,"customCacheHandler":false},"devIndicators":{"position":"bottom-left"},"onDemandEntries":{"maxInactiveAge":60000,"pagesBufferLength":5},"basePath":"","sassOptions":{},"trailingSlash":false,"i18n":null,"productionBrowserSourceMaps":false,"excludeDefaultMomentLocales":true,"reactProductionProfiling":false,"reactStrictMode":null,"reactMaxHeadersLength":6000,"httpAgentOptions":{"keepAlive":true},"logging":{"serverFunctions":true,"browserToTerminal":"warn"},"compiler":{},"expireTime":31536000,"staticPageGenerationTimeout":60,"output":"standalone","modularizeImports":{"@mui/icons-material":{"transform":"@mui/icons-material/{{member}}"},"lodash":{"transform":"lodash/{{member}}"}},"outputFileTracingRoot":"/home/runner/work/agent-session-inspector/agent-session-inspector","enablePrerenderSourceMaps":true,"cacheComponents":false,"cacheLife":{"default":{"stale":300,"revalidate":900,"expire":4294967294},"seconds":{"stale":30,"revalidate":1,"expire":60},"minutes":{"stale":300,"revalidate":60,"expire":3600},"hours":{"stale":300,"revalidate":3600,"expire":86400},"days":{"stale":300,"revalidate":86400,"expire":604800},"weeks":{"stale":300,"revalidate":604800,"expire":2592000},"max":{"stale":300,"revalidate":2592000,"expire":31536000}},"cacheHandlers":{},"experimental":{"appNewScrollHandler":true,"coldCacheBadge":false,"devValidationWorker":true,"useSkewCookie":false,"cssChunking":true,"multiZoneDraftMode":false,"appNavFailHandling":false,"prerenderEarlyExit":true,"serverMinification":true,"linkNoTouchStart":false,"caseSensitiveRoutes":false,"cachedNavigations":false,"dynamicOnHover":false,"useOffline":false,"varyParams":true,"optimisticRouting":true,"instrumentationClientRouterTransitionEvents":false,"prefetchInlining":{"maxSize":2048,"maxBundleSize":10240},"preloadEntriesOnStart":true,"clientRouterFilter":true,"clientRouterFilterRedirects":false,"fetchCacheKeyPrefix":"","proxyPrefetch":"flexible","optimisticClientCache":true,"manualClientBasePath":false,"cpus":3,"memoryBasedWorkersCount":false,"imgOptConcurrency":null,"imgOptOperationCache":null,"imgOptTimeoutInSeconds":7,"imgOptMaxInputPixels":268402689,"imgOptSequentialRead":null,"isrFlushToDisk":true,"workerThreads":false,"optimizeCss":false,"nextScriptWorkers":false,"scrollRestoration":false,"externalDir":false,"devMemoryThresholdRestart":true,"disableOptimizedLoading":false,"gzipSize":true,"craCompat":false,"esmExternals":true,"fullySpecified":false,"swcTraceProfiling":false,"forceSwcTransforms":false,"requestInsights":false,"largePageDataBytes":128000,"typedEnv":false,"parallelServerCompiles":false,"parallelServerBuildTraces":false,"ppr":false,"authInterrupts":false,"webpackMemoryOptimizations":false,"optimizeServerReact":true,"strictRouteTypes":false,"useTypeScriptCli":true,"removeUncaughtErrorAndRejectionListeners":false,"validateRSCRequestHeaders":true,"staleTimes":{"dynamic":0,"static":300},"reactDebugChannel":true,"serverComponentsHmrCache":true,"serverComponentsHmrCancellation":false,"staticGenerationMaxConcurrency":8,"staticGenerationMinPagesPerWorker":25,"transitionIndicator":false,"gestureTransition":false,"inlineCss":false,"useCache":false,"globalNotFound":false,"browserDebugInfoInTerminal":"warn","lockDistDir":true,"proxyClientMaxBodySize":10485760,"hideLogsAfterAbort":false,"mcpServer":true,"turbopackFileSystemCacheForDev":true,"turbopackFileSystemCacheForBuild":true,"turbopackInferModuleSideEffects":true,"turbopackPluginRuntimeStrategy":"childProcesses","turbopackMemoryEvictionMode":"auto","optimizePackageImports":["lucide-react","date-fns","lodash-es","ramda","antd","react-bootstrap","ahooks","@ant-design/icons","@headlessui/react","@headlessui-float/react","@heroicons/react/20/solid","@heroicons/react/24/solid","@heroicons/react/24/outline","@visx/visx","@tremor/react","rxjs","@mui/material","@mui/icons-material","recharts","react-use","effect","@effect/schema","@effect/platform","@effect/platform-node","@effect/platform-browser","@effect/platform-bun","@effect/sql","@effect/sql-mssql","@effect/sql-mysql2","@effect/sql-pg","@effect/sql-sqlite-node","@effect/sql-sqlite-bun","@effect/sql-sqlite-wasm","@effect/sql-sqlite-react-native","@effect/rpc","@effect/rpc-http","@effect/typeclass","@effect/experimental","@effect/opentelemetry","@material-ui/core","@material-ui/icons","@tabler/icons-react","mui-core","react-icons/ai","react-icons/bi","react-icons/bs","react-icons/cg","react-icons/ci","react-icons/di","react-icons/fa","react-icons/fa6","react-icons/fc","react-icons/fi","react-icons/gi","react-icons/go","react-icons/gr","react-icons/hi","react-icons/hi2","react-icons/im","react-icons/io","react-icons/io5","react-icons/lia","react-icons/lib","react-icons/lu","react-icons/md","react-icons/pi","react-icons/ri","react-icons/rx","react-icons/si","react-icons/sl","react-icons/tb","react-icons/tfi","react-icons/ti","react-icons/vsc","react-icons/wi"],"useCacheTimeout":54,"instantInsights":{"validationLevel":"warning"},"trustHostHeader":false,"isExperimentalCompile":false},"htmlLimitedBots":"[\\w-]+-Google|Google-[\\w-]+|Chrome-Lighthouse|Slurp|DuckDuckBot|baiduspider|yandex|sogou|bitlybot|tumblr|vkShare|quora link preview|redditbot|ia_archiver|Bingbot|BingPreview|applebot|facebookexternalhit|facebookcatalog|Twitterbot|LinkedInBot|Slackbot|Discordbot|WhatsApp|SkypeUriPreview|Yeti|googleweblight","bundlePagesRouterDependencies":false,"configFileName":"next.config.ts","outputFileTracingExcludes":{"/**":["./.git/**","./.claude/**","./src/**"]},"repoRoot":"/home/runner/work/agent-session-inspector/agent-session-inspector","turbopack":{"root":"/home/runner/work/agent-session-inspector/agent-session-inspector"},"distDirRoot":".next"}
13
13
 
14
14
  process.env.__NEXT_PRIVATE_STANDALONE_CONFIG = JSON.stringify(nextConfig)
15
15
 
@@ -7,17 +7,30 @@ import { existsSync, readFileSync } from "node:fs";
7
7
  import { createRequire } from "node:module";
8
8
  import net from "node:net";
9
9
  import path from "node:path";
10
- import { fileURLToPath } from "node:url";
10
+ import { fileURLToPath, pathToFileURL } from "node:url";
11
11
 
12
12
  const NAME = "agent-session-inspector";
13
13
  const MIN_NODE = [22, 13];
14
14
  const PKG_DIR = path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
15
15
  const SERVER = path.join(PKG_DIR, "app", "server.js");
16
16
 
17
+ // Report commands print to the terminal instead of starting the server; they
18
+ // live in the bundle scripts/build-cli.mjs writes to <package>/cli/.
19
+ const CLI = path.join(PKG_DIR, "cli", "cli.mjs");
20
+ const COMMANDS = ["usage", "stats", "sessions"];
21
+
17
22
  const HELP = `Usage: ${NAME} [options]
23
+ ${NAME} <command> [options]
24
+
25
+ Browse Claude Code, Codex, Copilot, Cursor, Gemini CLI, OpenCode and Hermes
26
+ session transcripts in a local web UI, or print a report in the terminal.
27
+
28
+ Commands:
29
+ usage Tokens and estimated cost by day, model, project or agent
30
+ stats Sessions, messages, tool calls and time, by agent
31
+ sessions Recent sessions with their cost and health
18
32
 
19
- Browse Claude Code, Codex, Copilot, OpenCode and Hermes session transcripts in a
20
- local web UI.
33
+ Run a command with --help for its options.
21
34
 
22
35
  Options:
23
36
  -p, --port <port> Port to listen on (default: 3000, or the next free one)
@@ -118,7 +131,12 @@ function openBrowser(url) {
118
131
  .unref();
119
132
  }
120
133
 
121
- const opts = parseArgs(process.argv.slice(2));
134
+ const argv = process.argv.slice(2);
135
+ const command = COMMANDS.includes(argv[0]) ? argv[0] : null;
136
+ if (!command && argv[0] && !argv[0].startsWith("-")) {
137
+ fail(`unknown command ${argv[0]}\n\n${HELP}`);
138
+ }
139
+ const opts = command ? null : parseArgs(argv);
122
140
 
123
141
  // npx only warns about package.json "engines", and the app needs node:sqlite.
124
142
  const [major, minor] = process.versions.node.split(".").map(Number);
@@ -126,6 +144,21 @@ if (major < MIN_NODE[0] || (major === MIN_NODE[0] && minor < MIN_NODE[1])) {
126
144
  fail(`Node.js ${MIN_NODE.join(".")} or newer is required (found ${process.version}).`);
127
145
  }
128
146
 
147
+ // node:sqlite still announces itself as experimental on Node 22; not useful here.
148
+ const emitWarning = process.emitWarning;
149
+ process.emitWarning = (warning, ...rest) => {
150
+ if (String(warning).includes("SQLite is an experimental feature")) return;
151
+ emitWarning.call(process, warning, ...rest);
152
+ };
153
+
154
+ if (command) {
155
+ if (!existsSync(CLI)) {
156
+ fail(`no command bundle found at ${CLI}\nRun \`pnpm cli ${command}\` from a checkout.`);
157
+ }
158
+ const { run } = await import(pathToFileURL(CLI).href);
159
+ process.exit(run(command, argv.slice(1)));
160
+ }
161
+
129
162
  if (!existsSync(SERVER)) {
130
163
  fail(`no build found at ${SERVER}\nRun scripts/package-release.sh and use dist/${NAME}/bin/${NAME}.mjs.`);
131
164
  }
@@ -142,13 +175,6 @@ process.env.NEXT_TELEMETRY_DISABLED = "1";
142
175
  process.env.PORT = String(port);
143
176
  process.env.HOSTNAME = opts.host;
144
177
 
145
- // node:sqlite still announces itself as experimental on Node 22; not useful here.
146
- const emitWarning = process.emitWarning;
147
- process.emitWarning = (warning, ...rest) => {
148
- if (String(warning).includes("SQLite is an experimental feature")) return;
149
- emitWarning.call(process, warning, ...rest);
150
- };
151
-
152
178
  // server.js is CommonJS and starts listening on load.
153
179
  createRequire(import.meta.url)(SERVER);
154
180