@vladar107/claudescope 0.5.3 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (584) hide show
  1. package/README.md +82 -89
  2. package/cli.js +8 -8
  3. package/package.json +2 -2
  4. package/pricing.default.json +49 -4
  5. package/server.js +293 -212
  6. package/web/assets/abap-CLvhMVsD.js +1 -0
  7. package/web/assets/actionscript-3--17pq3dv.js +1 -0
  8. package/web/assets/ada-C5qYipkI.js +1 -0
  9. package/web/assets/andromeeda-vGVdxbeo.js +1 -0
  10. package/web/assets/angular-html-B6NB-Lrz.js +1 -0
  11. package/web/assets/angular-ts-BDcbdMTl.js +1 -0
  12. package/web/assets/apache-U0d_L8uA.js +1 -0
  13. package/web/assets/apex-VAyPSnFM.js +1 -0
  14. package/web/assets/apl-D87dAdQv.js +1 -0
  15. package/web/assets/applescript-CCn79oCD.js +1 -0
  16. package/web/assets/ara-4CJ0cIlV.js +1 -0
  17. package/web/assets/asciidoc-DE70LPWp.js +1 -0
  18. package/web/assets/asm-Cmm7eHzH.js +1 -0
  19. package/web/assets/astro-bcfuTGb0.js +1 -0
  20. package/web/assets/aurora-x-CDeNXAV0.js +1 -0
  21. package/web/assets/awk-BWXHIvNe.js +1 -0
  22. package/web/assets/ayu-dark-DluEY0Gj.js +1 -0
  23. package/web/assets/ayu-light-C3h-C4tm.js +1 -0
  24. package/web/assets/ayu-mirage-Bqwy1Gya.js +1 -0
  25. package/web/assets/ballerina-B7ZEbQpA.js +1 -0
  26. package/web/assets/bat-Bo4NYOV-.js +1 -0
  27. package/web/assets/beancount-D-usSTwE.js +1 -0
  28. package/web/assets/berry-DKpUyyne.js +1 -0
  29. package/web/assets/bibtex-Ci_nEsc7.js +1 -0
  30. package/web/assets/bicep-CUHmPFLl.js +1 -0
  31. package/web/assets/bird2-C6vDhewU.js +1 -0
  32. package/web/assets/blade-DqNvyd_n.js +1 -0
  33. package/web/assets/bsl-BkkzgIyY.js +1 -0
  34. package/web/assets/c-CFHXi1VN.js +1 -0
  35. package/web/assets/c3-BFHwR3_K.js +1 -0
  36. package/web/assets/cadence-CQ2zXKGN.js +1 -0
  37. package/web/assets/cairo-DLTphjLi.js +1 -0
  38. package/web/assets/catppuccin-frappe-3VR1Za6u.js +1 -0
  39. package/web/assets/catppuccin-latte-DwIHMF0Q.js +1 -0
  40. package/web/assets/catppuccin-macchiato-DYnBP6_5.js +1 -0
  41. package/web/assets/catppuccin-mocha-DYhrFGRu.js +1 -0
  42. package/web/assets/clarity-SemFz856.js +1 -0
  43. package/web/assets/clojure-DqKBuwfJ.js +1 -0
  44. package/web/assets/cmake-Bj61d0ZC.js +1 -0
  45. package/web/assets/cobol-DhPScjyw.js +1 -0
  46. package/web/assets/codeowners-C8r90Shi.js +1 -0
  47. package/web/assets/codeql-oeQT6MSM.js +1 -0
  48. package/web/assets/coffee-XYu_qqrv.js +1 -0
  49. package/web/assets/common-lisp-Cv5bFMCO.js +1 -0
  50. package/web/assets/coq-BrsZFFmf.js +1 -0
  51. package/web/assets/cpp-BkCHE5eS.js +1 -0
  52. package/web/assets/crystal-CNV132yn.js +1 -0
  53. package/web/assets/csharp-oqKa8noW.js +1 -0
  54. package/web/assets/css-Bpkww5d5.js +1 -0
  55. package/web/assets/csv-Dx-8-gkx.js +1 -0
  56. package/web/assets/cue-CE9AQfxI.js +1 -0
  57. package/web/assets/cypher-ClKdZ_lG.js +1 -0
  58. package/web/assets/d-qD-0Kul2.js +1 -0
  59. package/web/assets/dark-plus-Cs2F2srj.js +1 -0
  60. package/web/assets/dart-CnvKMtbv.js +1 -0
  61. package/web/assets/dax-BkyTk9wS.js +1 -0
  62. package/web/assets/desktop-Dlh5hvp9.js +1 -0
  63. package/web/assets/diff-woXpYk--.js +1 -0
  64. package/web/assets/dist-zdl1ZQgS.js +153 -0
  65. package/web/assets/docker-IyjqRm3v.js +1 -0
  66. package/web/assets/dotenv-_5a1GRtc.js +1 -0
  67. package/web/assets/dracula-BHWKrbxM.js +1 -0
  68. package/web/assets/dracula-soft-5eyTD99u.js +1 -0
  69. package/web/assets/dream-maker-DW3nJb8Q.js +1 -0
  70. package/web/assets/edge-G4Yo44nA.js +1 -0
  71. package/web/assets/elixir-DMCXOTGZ.js +1 -0
  72. package/web/assets/elm-DzPIDYyD.js +1 -0
  73. package/web/assets/emacs-lisp-B4R74twV.js +1 -0
  74. package/web/assets/erb-CQ-EHLcw.js +1 -0
  75. package/web/assets/erlang-Cphh6RMH.js +1 -0
  76. package/web/assets/everforest-dark-sB-x3p7T.js +1 -0
  77. package/web/assets/everforest-light-Df2xbC6M.js +1 -0
  78. package/web/assets/fennel-DQxkIbk2.js +1 -0
  79. package/web/assets/fish-BJitypiv.js +1 -0
  80. package/web/assets/fluent-C03EYrpw.js +1 -0
  81. package/web/assets/fortran-fixed-form-DEKoE2YW.js +1 -0
  82. package/web/assets/fortran-free-form-CYNrtFtB.js +1 -0
  83. package/web/assets/fsharp-D13ZGOAj.js +1 -0
  84. package/web/assets/gdresource-C0sCabJj.js +1 -0
  85. package/web/assets/gdscript-Cp2uCuqX.js +1 -0
  86. package/web/assets/gdshader-CBce3t8t.js +1 -0
  87. package/web/assets/genie-CV2tkWYe.js +1 -0
  88. package/web/assets/gherkin-DExj1W_8.js +1 -0
  89. package/web/assets/git-commit-BSykSTBG.js +1 -0
  90. package/web/assets/git-rebase-B74l1Fg6.js +1 -0
  91. package/web/assets/github-dark-C-LZuMrd.js +1 -0
  92. package/web/assets/github-dark-default-DXG-b-1a.js +1 -0
  93. package/web/assets/github-dark-dimmed-Bx1FflLF.js +1 -0
  94. package/web/assets/github-dark-high-contrast-B_tTalzw.js +1 -0
  95. package/web/assets/github-light-EUqPIrTm.js +1 -0
  96. package/web/assets/github-light-default-BXViO-2h.js +1 -0
  97. package/web/assets/github-light-high-contrast-B68TUdTA.js +1 -0
  98. package/web/assets/gleam-CSRkHgEL.js +1 -0
  99. package/web/assets/glimmer-js-DwfilnY-.js +1 -0
  100. package/web/assets/glimmer-ts-lqOxujlw.js +1 -0
  101. package/web/assets/glsl-Btm-wpMB.js +1 -0
  102. package/web/assets/gn-ilITqXS6.js +1 -0
  103. package/web/assets/gnuplot-7GGW24-e.js +1 -0
  104. package/web/assets/go-rLFTqkRN.js +1 -0
  105. package/web/assets/graphql-D4juvwip.js +1 -0
  106. package/web/assets/groovy-CacY0gHj.js +1 -0
  107. package/web/assets/gruvbox-dark-hard-C820rvS2.js +1 -0
  108. package/web/assets/gruvbox-dark-medium-BPjhmG05.js +1 -0
  109. package/web/assets/gruvbox-dark-soft-MrdJrrXF.js +1 -0
  110. package/web/assets/gruvbox-light-hard-BC_s9l72.js +1 -0
  111. package/web/assets/gruvbox-light-medium-BAWPOn9u.js +1 -0
  112. package/web/assets/gruvbox-light-soft-BSMLrYjP.js +1 -0
  113. package/web/assets/hack-D7H1saAD.js +1 -0
  114. package/web/assets/haml-TnG94d4e.js +1 -0
  115. package/web/assets/handlebars-xdoeLJnk.js +1 -0
  116. package/web/assets/haskell-D8IpX4py.js +1 -0
  117. package/web/assets/haxe-OTjmBuCE.js +1 -0
  118. package/web/assets/hcl-Dh228itO.js +1 -0
  119. package/web/assets/hjson-CxZEssPk.js +1 -0
  120. package/web/assets/hlsl-Cvrh5tZx.js +1 -0
  121. package/web/assets/horizon-CE9ld1lL.js +1 -0
  122. package/web/assets/horizon-bright-DSNQnXHK.js +1 -0
  123. package/web/assets/houston-CsvMBhTu.js +1 -0
  124. package/web/assets/html-CUd8lrfJ.js +1 -0
  125. package/web/assets/html-derivative-D2ambePY.js +1 -0
  126. package/web/assets/http-BOOVV1eF.js +1 -0
  127. package/web/assets/hurl-CDZ2zmM1.js +1 -0
  128. package/web/assets/hxml-B0Qn7Nwc.js +1 -0
  129. package/web/assets/hy-CZbG8q4J.js +1 -0
  130. package/web/assets/imba-DsUTQ-LC.js +1 -0
  131. package/web/assets/index-B8-nNAFE.js +93 -0
  132. package/web/assets/index-Cf7qioAW.css +1 -0
  133. package/web/assets/ini-B5eOa1yu.js +1 -0
  134. package/web/assets/java-BAb26fG0.js +1 -0
  135. package/web/assets/javascript-DexBdMmo.js +1 -0
  136. package/web/assets/jinja-DjC8r-Rg.js +1 -0
  137. package/web/assets/jison-DzijxeQZ.js +1 -0
  138. package/web/assets/json-CvduXCpK.js +1 -0
  139. package/web/assets/json5-BR5RXkoi.js +1 -0
  140. package/web/assets/jsonc-CYpm1nAK.js +1 -0
  141. package/web/assets/jsonl-CmCQp5Yx.js +1 -0
  142. package/web/assets/jsonnet-CJTPZ8u_.js +1 -0
  143. package/web/assets/jssm-DXw9l8Rf.js +1 -0
  144. package/web/assets/jsx-BL2uvdrx.js +1 -0
  145. package/web/assets/julia-BBbzoUWG.js +1 -0
  146. package/web/assets/just-n3VauGbU.js +1 -0
  147. package/web/assets/kanagawa-dragon-CXtmUGW6.js +1 -0
  148. package/web/assets/kanagawa-lotus-BN08jTvb.js +1 -0
  149. package/web/assets/kanagawa-wave-CTweb8Dz.js +1 -0
  150. package/web/assets/kdl-CsD5j6eV.js +1 -0
  151. package/web/assets/kotlin-DhhofPvG.js +1 -0
  152. package/web/assets/kusto-C7mF5XQf.js +1 -0
  153. package/web/assets/laserwave-C_8bwKvT.js +1 -0
  154. package/web/assets/latex-Sq9QbgGf.js +1 -0
  155. package/web/assets/lean-CewbzKMR.js +1 -0
  156. package/web/assets/less-DVTAwKKz.js +1 -0
  157. package/web/assets/light-plus-DVQuIRkW.js +1 -0
  158. package/web/assets/liquid-CBAHQbd7.js +1 -0
  159. package/web/assets/llvm-Cm23YOpf.js +1 -0
  160. package/web/assets/log-BNLmms1o.js +1 -0
  161. package/web/assets/logo-Cluzi2Zq.js +1 -0
  162. package/web/assets/lua-BNXicGIf.js +1 -0
  163. package/web/assets/luau-FMPmPwt6.js +1 -0
  164. package/web/assets/make-Dixweg8N.js +1 -0
  165. package/web/assets/markdown-BYOwaDjH.js +1 -0
  166. package/web/assets/marko-BPMPXUHH.js +1 -0
  167. package/web/assets/material-theme-Bm3Qr25_.js +1 -0
  168. package/web/assets/material-theme-darker-2IIEA8gg.js +1 -0
  169. package/web/assets/material-theme-lighter-uhdI0v04.js +1 -0
  170. package/web/assets/material-theme-ocean-CHQ94UKr.js +1 -0
  171. package/web/assets/material-theme-palenight-B5W6OYN7.js +1 -0
  172. package/web/assets/matlab-D7qyCx1q.js +1 -0
  173. package/web/assets/mdc-BO4kSC2Y.js +1 -0
  174. package/web/assets/mdx-DQZ5AkYe.js +1 -0
  175. package/web/assets/mermaid-Bk4SNUv9.js +1 -0
  176. package/web/assets/min-dark-BSWPekZh.js +1 -0
  177. package/web/assets/min-light-DDpmG2fV.js +1 -0
  178. package/web/assets/mipsasm-BMqwQI7S.js +1 -0
  179. package/web/assets/mojo-BgCJLMeH.js +1 -0
  180. package/web/assets/monokai-CdkpiU2Y.js +1 -0
  181. package/web/assets/moonbit-CaWjb8XO.js +1 -0
  182. package/web/assets/move-B1IS1UjX.js +1 -0
  183. package/web/assets/narrat-_X_XdTYD.js +1 -0
  184. package/web/assets/nextflow-BJtWHP5T.js +1 -0
  185. package/web/assets/nextflow-groovy-DJMQeKeT.js +1 -0
  186. package/web/assets/nginx-CxnU3cuO.js +1 -0
  187. package/web/assets/night-owl-DhmEMT88.js +1 -0
  188. package/web/assets/night-owl-light-eJ-hLW7d.js +1 -0
  189. package/web/assets/nim-pL7_W6bY.js +1 -0
  190. package/web/assets/nix-IvuFDN5E.js +1 -0
  191. package/web/assets/nord-Cb4Vim4T.js +1 -0
  192. package/web/assets/nushell-DcLAeLz5.js +1 -0
  193. package/web/assets/objective-c-D1A_Heim.js +1 -0
  194. package/web/assets/objective-cpp-BsSzOQcm.js +1 -0
  195. package/web/assets/ocaml-O90oeIOV.js +1 -0
  196. package/web/assets/odin-B1RWQWA5.js +1 -0
  197. package/web/assets/one-dark-pro-CLwyXe_n.js +1 -0
  198. package/web/assets/{one-light-PoHY5YXO.js → one-light-D7Lr4KcI.js} +1 -1
  199. package/web/assets/openscad-BUDT5pXO.js +1 -0
  200. package/web/assets/pascal-4ZHwLPI5.js +1 -0
  201. package/web/assets/perl-Beo8lGSs.js +1 -0
  202. package/web/assets/php-BJv7Qdc7.js +1 -0
  203. package/web/assets/pkl-ot-7Btpt.js +1 -0
  204. package/web/assets/plastic-DQwYfKfQ.js +1 -0
  205. package/web/assets/plsql-DGHpHOYJ.js +1 -0
  206. package/web/assets/po-BiJDBrnU.js +1 -0
  207. package/web/assets/poimandres-DRFjx7u4.js +1 -0
  208. package/web/assets/polar-C7UOKdEL.js +1 -0
  209. package/web/assets/postcss-BXeXVLqQ.js +1 -0
  210. package/web/assets/powerquery-DNMTfnFr.js +1 -0
  211. package/web/assets/powershell-DshXNtvi.js +1 -0
  212. package/web/assets/prisma-BsRQq5mF.js +1 -0
  213. package/web/assets/prolog-iXnhIJG7.js +1 -0
  214. package/web/assets/proto-DB4EqR-F.js +1 -0
  215. package/web/assets/pug-B0coObuQ.js +1 -0
  216. package/web/assets/puppet-CDv2pdJW.js +1 -0
  217. package/web/assets/purescript-9MfHhQsQ.js +1 -0
  218. package/web/assets/python-gzcpVVnB.js +1 -0
  219. package/web/assets/qml-CEiV0Zee.js +1 -0
  220. package/web/assets/qmldir-DCQb3MpD.js +1 -0
  221. package/web/assets/qss-Fe1Jh2GI.js +1 -0
  222. package/web/assets/r-Bdc3t_C9.js +1 -0
  223. package/web/assets/racket-DcIDlBhZ.js +1 -0
  224. package/web/assets/raku-B3gFvitq.js +1 -0
  225. package/web/assets/razor-HaLflGdK.js +1 -0
  226. package/web/assets/red-CJ3rzSJv.js +1 -0
  227. package/web/assets/reg-CRGYupPL.js +1 -0
  228. package/web/assets/regexp-78ZMOPj1.js +1 -0
  229. package/web/assets/rel-BtDbiS_P.js +1 -0
  230. package/web/assets/riscv-Ckw8ddFX.js +1 -0
  231. package/web/assets/ron-VUp2lXgN.js +1 -0
  232. package/web/assets/rose-pine-BthvhNj6.js +1 -0
  233. package/web/assets/rose-pine-dawn-Dg85fqjY.js +1 -0
  234. package/web/assets/rose-pine-moon-hon4tzzS.js +1 -0
  235. package/web/assets/rosmsg-CAekHB0j.js +1 -0
  236. package/web/assets/rst-Dr5cW8XD.js +1 -0
  237. package/web/assets/ruby-D_qoWsgX.js +1 -0
  238. package/web/assets/rust-Cfkwpbl8.js +1 -0
  239. package/web/assets/sas-DpFly6Dd.js +1 -0
  240. package/web/assets/sass-DXrisJhu.js +1 -0
  241. package/web/assets/scala-DKOlJaKm.js +1 -0
  242. package/web/assets/scheme-DQCgrYNe.js +1 -0
  243. package/web/assets/scss-C-o_ERCH.js +1 -0
  244. package/web/assets/sdbl-bTVj8UrX.js +1 -0
  245. package/web/assets/shaderlab-TOUzSsQk.js +1 -0
  246. package/web/assets/shellscript-zLQiq6L1.js +1 -0
  247. package/web/assets/shellsession-DhKDV3vj.js +1 -0
  248. package/web/assets/slack-dark-DnToyrRv.js +1 -0
  249. package/web/assets/slack-ochin-B2OO5cIa.js +1 -0
  250. package/web/assets/smalltalk-B16xEiuN.js +1 -0
  251. package/web/assets/snazzy-light-4G7pJPwS.js +1 -0
  252. package/web/assets/solarized-dark-DV17i1UV.js +1 -0
  253. package/web/assets/solarized-light-DSh2HLQt.js +1 -0
  254. package/web/assets/solidity-CKzVLygQ.js +1 -0
  255. package/web/assets/soy-hig7C243.js +1 -0
  256. package/web/assets/sparql-D_iOobhT.js +1 -0
  257. package/web/assets/splunk-BC2Px7Mm.js +1 -0
  258. package/web/assets/sql-B2_JLaff.js +1 -0
  259. package/web/assets/ssh-config-BgfXC-Er.js +1 -0
  260. package/web/assets/stata-DjrTXApL.js +1 -0
  261. package/web/assets/stylus-B6D30XZt.js +1 -0
  262. package/web/assets/surrealql-D_oTqMWW.js +1 -0
  263. package/web/assets/svelte-CDUT4yjj.js +1 -0
  264. package/web/assets/swift-DonLKvLd.js +1 -0
  265. package/web/assets/synthwave-84-nFMaYfgc.js +1 -0
  266. package/web/assets/system-verilog-DJ5XKQeo.js +1 -0
  267. package/web/assets/systemd-BxMlprV5.js +1 -0
  268. package/web/assets/talonscript-CohzipZa.js +1 -0
  269. package/web/assets/tasl-DMoTqEGO.js +1 -0
  270. package/web/assets/tcl-CZd0xW_V.js +1 -0
  271. package/web/assets/templ-B0LcfNYE.js +1 -0
  272. package/web/assets/terraform-DswuEJGm.js +1 -0
  273. package/web/assets/tex-CpmyLb9X.js +1 -0
  274. package/web/assets/tokyo-night-oM2G3aXe.js +1 -0
  275. package/web/assets/toml-CcmNWLt0.js +1 -0
  276. package/web/assets/ts-tags-Dr3JbOr-.js +1 -0
  277. package/web/assets/tsv-sltzmVWM.js +1 -0
  278. package/web/assets/tsx-B7pXKuSp.js +1 -0
  279. package/web/assets/turtle-ByJddavk.js +1 -0
  280. package/web/assets/twig-D9GEvn7J.js +1 -0
  281. package/web/assets/typescript-SPtI-RVE.js +1 -0
  282. package/web/assets/typespec-BRdr0IET.js +1 -0
  283. package/web/assets/typst-DI99ib-x.js +1 -0
  284. package/web/assets/v-DETTlOr0.js +1 -0
  285. package/web/assets/vala-zf12oZj6.js +1 -0
  286. package/web/assets/vb-Djn5o6TS.js +1 -0
  287. package/web/assets/verilog-CiiDBU1e.js +1 -0
  288. package/web/assets/vesper-DdrHHSXu.js +1 -0
  289. package/web/assets/vhdl-BroJfC0k.js +1 -0
  290. package/web/assets/viml-DvXPmvsu.js +1 -0
  291. package/web/assets/vitesse-black-fwtXNY1n.js +1 -0
  292. package/web/assets/vitesse-dark-BZCL-v6S.js +1 -0
  293. package/web/assets/vitesse-light-VbXTXTou.js +1 -0
  294. package/web/assets/vue-C16kg_Qb.js +1 -0
  295. package/web/assets/vue-html-D3DhRdge.js +1 -0
  296. package/web/assets/vue-vine-CrkoclNL.js +1 -0
  297. package/web/assets/vyper-CgoNMtux.js +1 -0
  298. package/web/assets/{wasm-CG6Dc4jp.js → wasm-BnjxR4X6.js} +1 -1
  299. package/web/assets/wasm-ByWQv1Qj.js +1 -0
  300. package/web/assets/wenyan-C8pVoKbM.js +1 -0
  301. package/web/assets/wgsl-BsKzXJz4.js +1 -0
  302. package/web/assets/wikitext-ClFFjSW2.js +1 -0
  303. package/web/assets/wit-DdvCle-K.js +1 -0
  304. package/web/assets/wolfram-DLL8P-h_.js +1 -0
  305. package/web/assets/xml-B3sFvp65.js +1 -0
  306. package/web/assets/xsl-DGIZr3DO.js +1 -0
  307. package/web/assets/yaml-BWA_oTog.js +1 -0
  308. package/web/assets/zenscript-BnlCZFoB.js +1 -0
  309. package/web/assets/zig-CMLA9XwU.js +1 -0
  310. package/web/index.html +6 -3
  311. package/web/assets/abap-DsBKuouk.js +0 -1
  312. package/web/assets/actionscript-3-D_z4Izcz.js +0 -1
  313. package/web/assets/ada-727ZlQH0.js +0 -1
  314. package/web/assets/andromeeda-C3khCPGq.js +0 -1
  315. package/web/assets/angular-html-LfdN0zeE.js +0 -1
  316. package/web/assets/angular-ts-CKsD7JZE.js +0 -1
  317. package/web/assets/apache-Dn00JSTd.js +0 -1
  318. package/web/assets/apex-COJ4H7py.js +0 -1
  319. package/web/assets/apl-BBq3IX1j.js +0 -1
  320. package/web/assets/applescript-Bu5BbsvL.js +0 -1
  321. package/web/assets/ara-7O62HKoU.js +0 -1
  322. package/web/assets/asciidoc-BPT9niGB.js +0 -1
  323. package/web/assets/asm-Dhn9LcZ4.js +0 -1
  324. package/web/assets/astro-CqkE3fuf.js +0 -1
  325. package/web/assets/aurora-x-D-2ljcwZ.js +0 -1
  326. package/web/assets/awk-eg146-Ew.js +0 -1
  327. package/web/assets/ayu-dark-Cv9koXgw.js +0 -1
  328. package/web/assets/ballerina-Du268qiB.js +0 -1
  329. package/web/assets/bat-fje9CFhw.js +0 -1
  330. package/web/assets/beancount-BwXTMy5W.js +0 -1
  331. package/web/assets/berry-3xVqZejG.js +0 -1
  332. package/web/assets/bibtex-xW4inM5L.js +0 -1
  333. package/web/assets/bicep-DHo0CJ0O.js +0 -1
  334. package/web/assets/blade-a8OxSdnT.js +0 -1
  335. package/web/assets/bsl-Dgyn0ogV.js +0 -1
  336. package/web/assets/c-C3t2pwGQ.js +0 -1
  337. package/web/assets/cadence-DNquZEk8.js +0 -1
  338. package/web/assets/cairo--RitsXJZ.js +0 -1
  339. package/web/assets/catppuccin-frappe-CD_QflpE.js +0 -1
  340. package/web/assets/catppuccin-latte-DRW-0cLl.js +0 -1
  341. package/web/assets/catppuccin-macchiato-C-_shW-Y.js +0 -1
  342. package/web/assets/catppuccin-mocha-LGGdnPYs.js +0 -1
  343. package/web/assets/clarity-BHOwM8T6.js +0 -1
  344. package/web/assets/clojure-DxSadP1t.js +0 -1
  345. package/web/assets/cmake-DbXoA79R.js +0 -1
  346. package/web/assets/cobol-PTqiYgYu.js +0 -1
  347. package/web/assets/codeowners-Bp6g37R7.js +0 -1
  348. package/web/assets/codeql-sacFqUAJ.js +0 -1
  349. package/web/assets/coffee-dyiR41kL.js +0 -1
  350. package/web/assets/common-lisp-C7gG9l05.js +0 -1
  351. package/web/assets/coq-Dsg_Bt_b.js +0 -1
  352. package/web/assets/cpp-BksuvNSY.js +0 -1
  353. package/web/assets/crystal-DtDmRg-F.js +0 -1
  354. package/web/assets/csharp-D9R-vmeu.js +0 -1
  355. package/web/assets/css-BPhBrDlE.js +0 -1
  356. package/web/assets/csv-B0qRVHPH.js +0 -1
  357. package/web/assets/cue-DtFQj3wx.js +0 -1
  358. package/web/assets/cypher-m2LEI-9-.js +0 -1
  359. package/web/assets/d-BoXegm-a.js +0 -1
  360. package/web/assets/dark-plus-C3mMm8J8.js +0 -1
  361. package/web/assets/dart-B9wLZaAG.js +0 -1
  362. package/web/assets/dax-ClGRhx96.js +0 -1
  363. package/web/assets/desktop-DEIpsLCJ.js +0 -1
  364. package/web/assets/diff-BgYniUM_.js +0 -1
  365. package/web/assets/docker-COcR7UxN.js +0 -1
  366. package/web/assets/dotenv-BjQB5zDj.js +0 -1
  367. package/web/assets/dracula-BzJJZx-M.js +0 -1
  368. package/web/assets/dracula-soft-BXkSAIEj.js +0 -1
  369. package/web/assets/dream-maker-C-nORZOA.js +0 -1
  370. package/web/assets/edge-D5gP-w-T.js +0 -1
  371. package/web/assets/elixir-CLiX3zqd.js +0 -1
  372. package/web/assets/elm-CmHSxxaM.js +0 -1
  373. package/web/assets/emacs-lisp-BX77sIaO.js +0 -1
  374. package/web/assets/erb-BYTLMnw6.js +0 -1
  375. package/web/assets/erlang-B-DoSBHF.js +0 -1
  376. package/web/assets/everforest-dark-BgDCqdQA.js +0 -1
  377. package/web/assets/everforest-light-C8M2exoo.js +0 -1
  378. package/web/assets/fennel-bCA53EVm.js +0 -1
  379. package/web/assets/fish-w-ucz2PV.js +0 -1
  380. package/web/assets/fluent-Dayu4EKP.js +0 -1
  381. package/web/assets/fortran-fixed-form-TqA4NnZg.js +0 -1
  382. package/web/assets/fortran-free-form-DKXYxT9g.js +0 -1
  383. package/web/assets/fsharp-XplgxFYe.js +0 -1
  384. package/web/assets/gdresource-BHYsBjWJ.js +0 -1
  385. package/web/assets/gdscript-DfxzS6Rs.js +0 -1
  386. package/web/assets/gdshader-SKMF96pI.js +0 -1
  387. package/web/assets/genie-ajMbGru0.js +0 -1
  388. package/web/assets/gherkin--30QC5Em.js +0 -1
  389. package/web/assets/git-commit-i4q6IMui.js +0 -1
  390. package/web/assets/git-rebase-B-v9cOL2.js +0 -1
  391. package/web/assets/github-dark-DHJKELXO.js +0 -1
  392. package/web/assets/github-dark-default-Cuk6v7N8.js +0 -1
  393. package/web/assets/github-dark-dimmed-DH5Ifo-i.js +0 -1
  394. package/web/assets/github-dark-high-contrast-E3gJ1_iC.js +0 -1
  395. package/web/assets/github-light-DAi9KRSo.js +0 -1
  396. package/web/assets/github-light-default-D7oLnXFd.js +0 -1
  397. package/web/assets/github-light-high-contrast-BfjtVDDH.js +0 -1
  398. package/web/assets/gleam-B430Bg39.js +0 -1
  399. package/web/assets/glimmer-js-D-cwc0-E.js +0 -1
  400. package/web/assets/glimmer-ts-pgjy16dm.js +0 -1
  401. package/web/assets/glsl-DBO2IWDn.js +0 -1
  402. package/web/assets/gnuplot-CM8KxXT1.js +0 -1
  403. package/web/assets/go-B1SYOhNW.js +0 -1
  404. package/web/assets/graphql-cDcHW_If.js +0 -1
  405. package/web/assets/groovy-DkBy-JyN.js +0 -1
  406. package/web/assets/hack-D1yCygmZ.js +0 -1
  407. package/web/assets/haml-B2EZWmdv.js +0 -1
  408. package/web/assets/handlebars-BQGss363.js +0 -1
  409. package/web/assets/haskell-BILxekzW.js +0 -1
  410. package/web/assets/haxe-C5wWYbrZ.js +0 -1
  411. package/web/assets/hcl-HzYwdGDm.js +0 -1
  412. package/web/assets/hjson-T-Tgc4AT.js +0 -1
  413. package/web/assets/hlsl-ifBTmRxC.js +0 -1
  414. package/web/assets/houston-DnULxvSX.js +0 -1
  415. package/web/assets/html-C2L_23MC.js +0 -1
  416. package/web/assets/html-derivative-CSfWNPLT.js +0 -1
  417. package/web/assets/http-FRrOvY1W.js +0 -1
  418. package/web/assets/hxml-TIA70rKU.js +0 -1
  419. package/web/assets/hy-BMj5Y0dO.js +0 -1
  420. package/web/assets/imba-bv_oIlVt.js +0 -1
  421. package/web/assets/index-B5q7ho_L.js +0 -149
  422. package/web/assets/index-BolFDI5c.css +0 -1
  423. package/web/assets/index-DU1niWbC.js +0 -200
  424. package/web/assets/ini-BjABl1g7.js +0 -1
  425. package/web/assets/java-xI-RfyKK.js +0 -1
  426. package/web/assets/javascript-ySlJ1b_l.js +0 -1
  427. package/web/assets/jinja-DGy0s7-h.js +0 -1
  428. package/web/assets/jison-BqZprYcd.js +0 -1
  429. package/web/assets/json-BQoSv7ci.js +0 -1
  430. package/web/assets/json5-w8dY5SsB.js +0 -1
  431. package/web/assets/jsonc-TU54ms6u.js +0 -1
  432. package/web/assets/jsonl-DREVFZK8.js +0 -1
  433. package/web/assets/jsonnet-BfivnA6A.js +0 -1
  434. package/web/assets/jssm-P4WzXJd0.js +0 -1
  435. package/web/assets/jsx-BAng5TT0.js +0 -1
  436. package/web/assets/julia-BBuGR-5E.js +0 -1
  437. package/web/assets/kanagawa-dragon-CkXjmgJE.js +0 -1
  438. package/web/assets/kanagawa-lotus-CfQXZHmo.js +0 -1
  439. package/web/assets/kanagawa-wave-DWedfzmr.js +0 -1
  440. package/web/assets/kotlin-B5lbUyaz.js +0 -1
  441. package/web/assets/kusto-mebxcVVE.js +0 -1
  442. package/web/assets/laserwave-DUszq2jm.js +0 -1
  443. package/web/assets/latex-C-cWTeAZ.js +0 -1
  444. package/web/assets/lean-XBlWyCtg.js +0 -1
  445. package/web/assets/less-BfCpw3nA.js +0 -1
  446. package/web/assets/light-plus-B7mTdjB0.js +0 -1
  447. package/web/assets/liquid-D3W5UaiH.js +0 -1
  448. package/web/assets/log-Cc5clBb7.js +0 -1
  449. package/web/assets/logo-IuBKFhSY.js +0 -1
  450. package/web/assets/lua-CvWAzNxB.js +0 -1
  451. package/web/assets/luau-Du5NY7AG.js +0 -1
  452. package/web/assets/make-Bvotw-X0.js +0 -1
  453. package/web/assets/markdown-UIAJJxZW.js +0 -1
  454. package/web/assets/marko-z0MBrx5-.js +0 -1
  455. package/web/assets/material-theme-D5KoaKCx.js +0 -1
  456. package/web/assets/material-theme-darker-BfHTSMKl.js +0 -1
  457. package/web/assets/material-theme-lighter-B0m2ddpp.js +0 -1
  458. package/web/assets/material-theme-ocean-CyktbL80.js +0 -1
  459. package/web/assets/material-theme-palenight-Csfq5Kiy.js +0 -1
  460. package/web/assets/matlab-D9-PGadD.js +0 -1
  461. package/web/assets/mdc-DB_EDNY_.js +0 -1
  462. package/web/assets/mdx-sdHcTMYB.js +0 -1
  463. package/web/assets/mermaid-Ci6OQyBP.js +0 -1
  464. package/web/assets/min-dark-CafNBF8u.js +0 -1
  465. package/web/assets/min-light-CTRr51gU.js +0 -1
  466. package/web/assets/mipsasm-BC5c_5Pe.js +0 -1
  467. package/web/assets/mojo-Tz6hzZYG.js +0 -1
  468. package/web/assets/monokai-D4h5O-jR.js +0 -1
  469. package/web/assets/move-DB_GagMm.js +0 -1
  470. package/web/assets/narrat-DLbgOhZU.js +0 -1
  471. package/web/assets/nextflow-B0XVJmRM.js +0 -1
  472. package/web/assets/nginx-D_VnBJ67.js +0 -1
  473. package/web/assets/night-owl-C39BiMTA.js +0 -1
  474. package/web/assets/nim-ZlGxZxc3.js +0 -1
  475. package/web/assets/nix-shcSOmrb.js +0 -1
  476. package/web/assets/nord-Ddv68eIx.js +0 -1
  477. package/web/assets/nushell-D4Tzg5kh.js +0 -1
  478. package/web/assets/objective-c-Deuh7S70.js +0 -1
  479. package/web/assets/objective-cpp-BUEGK8hf.js +0 -1
  480. package/web/assets/ocaml-BNioltXt.js +0 -1
  481. package/web/assets/one-dark-pro-GBQ2dnAY.js +0 -1
  482. package/web/assets/pascal-JqZropPD.js +0 -1
  483. package/web/assets/perl-CHQXSrWU.js +0 -1
  484. package/web/assets/php-B5ebYQev.js +0 -1
  485. package/web/assets/plastic-3e1v2bzS.js +0 -1
  486. package/web/assets/plsql-LKU2TuZ1.js +0 -1
  487. package/web/assets/po-BFLt1xDp.js +0 -1
  488. package/web/assets/poimandres-CS3Unz2-.js +0 -1
  489. package/web/assets/polar-DKykz6zU.js +0 -1
  490. package/web/assets/postcss-B3ZDOciz.js +0 -1
  491. package/web/assets/powerquery-CSHBycmS.js +0 -1
  492. package/web/assets/powershell-BIEUsx6d.js +0 -1
  493. package/web/assets/prisma-B48N-Iqd.js +0 -1
  494. package/web/assets/prolog-BY-TUvya.js +0 -1
  495. package/web/assets/proto-zocC4JxJ.js +0 -1
  496. package/web/assets/pug-CM9l7STV.js +0 -1
  497. package/web/assets/puppet-Cza_XSSt.js +0 -1
  498. package/web/assets/purescript-Bg-kzb6g.js +0 -1
  499. package/web/assets/python-DhUJRlN_.js +0 -1
  500. package/web/assets/qml-D8XfuvdV.js +0 -1
  501. package/web/assets/qmldir-C8lEn-DE.js +0 -1
  502. package/web/assets/qss-DhMKtDLN.js +0 -1
  503. package/web/assets/r-CwjWoCRV.js +0 -1
  504. package/web/assets/racket-CzouJOBO.js +0 -1
  505. package/web/assets/raku-B1bQXN8T.js +0 -1
  506. package/web/assets/razor-CNLDkMZG.js +0 -1
  507. package/web/assets/red-bN70gL4F.js +0 -1
  508. package/web/assets/reg-5LuOXUq_.js +0 -1
  509. package/web/assets/regexp-DWJ3fJO_.js +0 -1
  510. package/web/assets/rel-DJlmqQ1C.js +0 -1
  511. package/web/assets/riscv-QhoSD0DR.js +0 -1
  512. package/web/assets/rose-pine-CmCqftbK.js +0 -1
  513. package/web/assets/rose-pine-dawn-Ds-gbosJ.js +0 -1
  514. package/web/assets/rose-pine-moon-CjDtw9vr.js +0 -1
  515. package/web/assets/rst-4NLicBqY.js +0 -1
  516. package/web/assets/ruby-DeZ3UC14.js +0 -1
  517. package/web/assets/rust-Be6lgOlo.js +0 -1
  518. package/web/assets/sas-BmTFh92c.js +0 -1
  519. package/web/assets/sass-BJ4Li9vH.js +0 -1
  520. package/web/assets/scala-DQVVAn-B.js +0 -1
  521. package/web/assets/scheme-BJGe-b2p.js +0 -1
  522. package/web/assets/scss-C31hgJw-.js +0 -1
  523. package/web/assets/sdbl-BLhTXw86.js +0 -1
  524. package/web/assets/shaderlab-B7qAK45m.js +0 -1
  525. package/web/assets/shellscript-atvbtKCR.js +0 -1
  526. package/web/assets/shellsession-C_rIy8kc.js +0 -1
  527. package/web/assets/slack-dark-BthQWCQV.js +0 -1
  528. package/web/assets/slack-ochin-DqwNpetd.js +0 -1
  529. package/web/assets/smalltalk-DkLiglaE.js +0 -1
  530. package/web/assets/snazzy-light-Bw305WKR.js +0 -1
  531. package/web/assets/solarized-dark-DXbdFlpD.js +0 -1
  532. package/web/assets/solarized-light-L9t79GZl.js +0 -1
  533. package/web/assets/solidity-C1w2a3ep.js +0 -1
  534. package/web/assets/soy-C-lX7w71.js +0 -1
  535. package/web/assets/sparql-bYkjHRlG.js +0 -1
  536. package/web/assets/splunk-Cf8iN4DR.js +0 -1
  537. package/web/assets/sql-COK4E0Yg.js +0 -1
  538. package/web/assets/ssh-config-BknIz3MU.js +0 -1
  539. package/web/assets/stata-DorPZHa4.js +0 -1
  540. package/web/assets/stylus-BeQkCIfX.js +0 -1
  541. package/web/assets/svelte-MSaWC3Je.js +0 -1
  542. package/web/assets/swift-BSxZ-RaX.js +0 -1
  543. package/web/assets/synthwave-84-CbfX1IO0.js +0 -1
  544. package/web/assets/system-verilog-C7L56vO4.js +0 -1
  545. package/web/assets/systemd-CUnW07Te.js +0 -1
  546. package/web/assets/talonscript-C1XDQQGZ.js +0 -1
  547. package/web/assets/tasl-CQjiPCtT.js +0 -1
  548. package/web/assets/tcl-DQ1-QYvQ.js +0 -1
  549. package/web/assets/templ-dwX3ZSMB.js +0 -1
  550. package/web/assets/terraform-BbSNqyBO.js +0 -1
  551. package/web/assets/tex-rYs2v40G.js +0 -1
  552. package/web/assets/tokyo-night-DBQeEorK.js +0 -1
  553. package/web/assets/toml-CB2ApiWb.js +0 -1
  554. package/web/assets/ts-tags-CipyTH0X.js +0 -1
  555. package/web/assets/tsv-B_m7g4N7.js +0 -1
  556. package/web/assets/tsx-B6W0miNI.js +0 -1
  557. package/web/assets/turtle-BMR_PYu6.js +0 -1
  558. package/web/assets/twig-NC5TFiHP.js +0 -1
  559. package/web/assets/typescript-Dj6nwHGl.js +0 -1
  560. package/web/assets/typespec-BpWG_bgh.js +0 -1
  561. package/web/assets/typst-BVUVsWT6.js +0 -1
  562. package/web/assets/v-CAQ2eGtk.js +0 -1
  563. package/web/assets/vala-BFOHcciG.js +0 -1
  564. package/web/assets/vb-CdO5JTpU.js +0 -1
  565. package/web/assets/verilog-CJaU5se_.js +0 -1
  566. package/web/assets/vesper-BEBZ7ncR.js +0 -1
  567. package/web/assets/vhdl-DYoNaHQp.js +0 -1
  568. package/web/assets/viml-m4uW47V2.js +0 -1
  569. package/web/assets/vitesse-black-Bkuqu6BP.js +0 -1
  570. package/web/assets/vitesse-dark-D0r3Knsf.js +0 -1
  571. package/web/assets/vitesse-light-CVO1_9PV.js +0 -1
  572. package/web/assets/vue-BuYVFjOK.js +0 -1
  573. package/web/assets/vue-html-xdeiXROB.js +0 -1
  574. package/web/assets/vyper-nyqBNV6O.js +0 -1
  575. package/web/assets/wasm-C6j12Q_x.js +0 -1
  576. package/web/assets/wenyan-7A4Fjokl.js +0 -1
  577. package/web/assets/wgsl-CB0Krxn9.js +0 -1
  578. package/web/assets/wikitext-DCE3LsBG.js +0 -1
  579. package/web/assets/wolfram-C3FkfJm5.js +0 -1
  580. package/web/assets/xml-e3z08dGr.js +0 -1
  581. package/web/assets/xsl-Dd0NUgwM.js +0 -1
  582. package/web/assets/yaml-CVw76BM1.js +0 -1
  583. package/web/assets/zenscript-HnGAYVZD.js +0 -1
  584. package/web/assets/zig-BVz_zdnA.js +0 -1
package/README.md CHANGED
@@ -20,24 +20,29 @@ machine and only ever reads your transcripts.
20
20
  | [Claude Code](https://claude.com/claude-code) | `~/.claude/projects/**/*.jsonl` |
21
21
  | [OpenAI Codex](https://openai.com/codex) | `~/.codex/sessions/**/rollout-*.jsonl` |
22
22
  | [JetBrains Junie](https://www.jetbrains.com/junie/) | `~/.junie/sessions/session-*/events.jsonl` |
23
+ | [pi](https://pi.dev) | `~/.pi/agent/sessions/**/*.jsonl` |
24
+ | [opencode](https://opencode.ai) | `~/.local/share/opencode/opencode.db` (SQLite) |
25
+ | [GitHub Copilot CLI](https://github.com/features/copilot) | `~/.copilot/session-state/**/events.jsonl` |
23
26
 
24
27
  Each source is optional — a directory that doesn't exist is simply skipped, so
25
- Claudescope works whether you use one agent or all three. Adding another is just
26
- [adding another connector](#how-it-works).
28
+ Claudescope works whether you use one agent or all six. Adding another is just
29
+ [adding another connector](./CONTRIBUTING.md#adding-an-agent-connector).
27
30
 
28
31
  ## What it can do
29
32
 
30
- - **Multi-agent** — Claude Code, Codex, and Junie sessions side by side, each labeled with an **agent badge**. A project that several agents touched shows one card with all its agent tags; drill in and **filter the session list by agent**.
33
+ - **Multi-agent** — Claude Code, Codex, Junie, pi, opencode, and GitHub Copilot CLI sessions side by side, each labeled with an **agent badge**. A project that several agents touched shows one card with all its agent tags; drill in and **filter the session list by agent**.
31
34
  - **Browse** every session grouped by project — titles, dates, message/tool counts, token totals, cost, git branch, PR links.
32
35
  - **Read** a session as a clean threaded conversation: markdown, syntax-highlighted code, collapsible thinking, paired tool calls + results, **syntax-highlighted red/green diffs** for edits, attachments, and sidechain/subagent turns. A built-in **find-in-session** bar (⌘/Ctrl+F) searches the whole transcript — including collapsed thinking, tool, and subagent content — auto-expanding and highlighting matches, with a user/assistant filter.
33
36
  - **Review changes** via a **Files changed** tab that aggregates every edit/write in the session by file, with per-file diffs and +/− counts (diffs load lazily per file).
34
37
  - **Export / share** a session to Markdown — download or copy it, with an optional toggle to **redact** home-dir paths and likely secrets.
38
+ - **Memory** — browse each agent's long-lived **instruction files** (`CLAUDE.md`, `AGENTS.md`, …) and **agent-distilled per-project memory**, read live from each agent's home directory; Claude Code facts deep-link back to the session that produced them.
35
39
  - **Search** full-text across all sessions, all agents (DuckDB BM25), with highlighted snippets that deep-link to the exact message.
36
40
  - **Analyze** token usage and cost over time, by project, by model, and **by agent** — including cache-hit ratio.
37
41
  - **Light & dark themes** — follows your system appearance, with a manual toggle.
38
42
 
39
43
  > **Privacy:** Everything runs locally on `127.0.0.1`. The app **never** writes to
40
- > `~/.claude`, `~/.codex`, or `~/.junie` — all are read-only sources. Its only persistent
44
+ > any agent's data — every source (`~/.claude`, `~/.codex`, `~/.junie`, `~/.pi`,
45
+ > `~/.copilot`, and opencode's database) is treated as strictly read-only. Its only persistent
41
46
  > state lives in `~/.claudescope/` — a DuckDB index, a copy of the pricing file, and
42
47
  > a cached pricing snapshot (`pricing.fetched.json`), all safe to delete anytime. The
43
48
  > sole outbound requests are an optional daily check for a newer published version
@@ -49,10 +54,8 @@ Claudescope works whether you use one agent or all three. Adding another is just
49
54
  ## Screenshots
50
55
 
51
56
  > The screenshots below use **synthetic demo data** — every project name, path,
52
- > and message is fabricated (`acme-web` is a multi-agent project: Claude Code +
53
- > Codex). They render light or dark to match your system. Regenerate them with
54
- > **`npm run screenshots`** (seeds the demo data, boots the app, and captures
55
- > every view in both themes via Playwright).
57
+ > and message is fabricated. `acme-web` is a multi-agent project worked by all
58
+ > six agents at once. They render light or dark to match your system.
56
59
 
57
60
  **Browse** — every project and its sessions at a glance, each tagged with the
58
61
  agents that worked in it: titles, dates, message & tool counts, token totals,
@@ -92,44 +95,53 @@ agent**, with a cache-read breakdown. Click a chart legend to toggle a series.
92
95
  <img alt="Token and cost analytics dashboard" src="docs/screenshots/analytics-light.png">
93
96
  </picture>
94
97
 
98
+ **Remember** — every agent's memory in one place: global instruction files
99
+ (`CLAUDE.md`, `AGENTS.md`, Copilot instructions) and Claude Code's
100
+ **agent-distilled per-project facts**, each with provenance and category. Read
101
+ live from every agent's home dir — never indexed — and Claude facts deep-link
102
+ back to the session that produced them.
103
+
104
+ <picture>
105
+ <source media="(prefers-color-scheme: dark)" srcset="docs/screenshots/memory-dark.png">
106
+ <img alt="Memory: each agent's global instruction files and distilled per-project facts in one place" src="docs/screenshots/memory-light.png">
107
+ </picture>
108
+
95
109
  ---
96
110
 
97
111
  ## Quick start
98
112
 
99
- **Prerequisite:** [Node.js](https://nodejs.org) **22 or newer** (`node -v`).
113
+ Install from any one of three channels — all wrap the same package. However you
114
+ install it, `claudescope` serves the whole app (UI + API) from a single port
115
+ (**http://localhost:4317** by default), runs in the **background**, and opens
116
+ your browser. Run it once and forget it; new sessions appear automatically.
100
117
 
101
- ### Install (recommended)
118
+ ### npm (recommended)
119
+
120
+ **Prerequisite:** [Node.js](https://nodejs.org) **22.12 or newer** (`node -v`).
102
121
 
103
122
  ```bash
104
123
  npm install -g @vladar107/claudescope
105
124
  claudescope # starts the app in the background and opens your browser
106
125
  ```
107
126
 
108
- `claudescope` serves the whole app (UI + API) from a single port
109
- (**http://localhost:4317** by default), runs in the **background**, and opens
110
- your browser. Run it once and forget it; new sessions appear automatically.
127
+ No global install? `npx @vladar107/claudescope` runs the published CLI once
128
+ without installing it.
111
129
 
112
- Try it without installing:
130
+ ### Homebrew (macOS / Linux)
113
131
 
114
132
  ```bash
115
- npx @vladar107/claudescope
133
+ brew tap vladar107/tap
134
+ brew install claudescope
135
+ claudescope
116
136
  ```
117
137
 
118
- ### Other install methods
138
+ ### Nix (any platform)
119
139
 
120
140
  ```bash
121
- # Homebrew (macOS / Linux)
122
- brew tap vladar107/tap
123
- brew install claudescope
124
-
125
- # Nix (any platform) — run without installing, or add to a profile
126
- nix run github:vladar107/claudescope
127
- nix profile install github:vladar107/claudescope
141
+ nix run github:vladar107/claudescope # run without installing
142
+ nix profile install github:vladar107/claudescope # or add it to your profile
128
143
  ```
129
144
 
130
- All channels wrap the same package; `claudescope update` detects how you
131
- installed it and points you at the right upgrade command.
132
-
133
145
  ### Commands
134
146
 
135
147
  ```bash
@@ -158,7 +170,8 @@ npm install # installs all workspace dependencies
158
170
  npm start # builds on first run, then serves the app in the foreground
159
171
  ```
160
172
 
161
- `npm start` runs in the foreground (`Ctrl-C` to stop) handy for development.
173
+ `npm start` runs in the foreground (`Ctrl-C` to stop). For the watch-mode dev
174
+ loop and how to contribute, see [`CONTRIBUTING.md`](./CONTRIBUTING.md).
162
175
 
163
176
  ---
164
177
 
@@ -172,11 +185,14 @@ All optional — set via environment variables.
172
185
  | `CLAUDE_PROJECTS_DIR` | `~/.claude/projects` | Where to read Claude Code transcripts from. A leading `~` is expanded. |
173
186
  | `CODEX_SESSIONS_DIR` | `~/.codex/sessions` | Where to read OpenAI Codex transcripts from. A leading `~` is expanded.|
174
187
  | `JUNIE_SESSIONS_DIR` | `~/.junie/sessions` | Where to read JetBrains Junie transcripts from. A leading `~` is expanded.|
188
+ | `PI_SESSIONS_DIR` | `~/.pi/agent/sessions` | Where to read pi transcripts from. A leading `~` is expanded. |
189
+ | `OPENCODE_DATA_DIR` | `~/.local/share/opencode` | Dir holding opencode's `opencode.db` (read-only). Honors `$XDG_DATA_HOME`; override the DB path directly with `OPENCODE_DB_PATH`. |
190
+ | `COPILOT_SESSIONS_DIR`| `~/.copilot/session-state` | Where to read GitHub Copilot CLI transcripts from. A leading `~` is expanded. |
175
191
  | `CLAUDESCOPE_HOME` | `~/.claudescope` | Where the app keeps its own state (index, pricing copy, logs, PID). |
176
192
  | `REINDEX_INTERVAL_MS` | `15000` | How often to auto-pick-up new/updated sessions. Set `0` to disable. |
177
193
 
178
194
  Each agent source is optional — if a directory doesn't exist it's simply skipped,
179
- so the app works whether you use one agent or all three.
195
+ so the app works whether you use one agent or all six.
180
196
 
181
197
  Examples:
182
198
 
@@ -185,6 +201,9 @@ claudescope --port 8080 # custom port
185
201
  CLAUDE_PROJECTS_DIR=/path/to/exported/projects claudescope # view someone else's transcripts
186
202
  CODEX_SESSIONS_DIR=/path/to/codex/sessions claudescope # point at Codex sessions elsewhere
187
203
  JUNIE_SESSIONS_DIR=/path/to/junie/sessions claudescope # point at Junie sessions elsewhere
204
+ PI_SESSIONS_DIR=/path/to/pi/sessions claudescope # point at pi sessions elsewhere
205
+ OPENCODE_DATA_DIR=/path/to/opencode claudescope # point at an opencode data dir elsewhere
206
+ COPILOT_SESSIONS_DIR=/path/to/copilot/session-state claudescope # point at Copilot CLI sessions elsewhere
188
207
  claudescope --no-open # don't pop a browser tab
189
208
  ```
190
209
 
@@ -244,6 +263,11 @@ Shipped fallback rates (USD per 1M tokens):
244
263
  - Edit `~/.claudescope/pricing.json` to override families, the default rate, or
245
264
  pin specific model prices. Re-index (`POST /api/reindex` or `claudescope
246
265
  restart`) to recompute stored costs at the new rates.
266
+ - `pricing.json` carries a `schemaVersion`. When an upgrade ships a newer default
267
+ (new families/models or a changed default rate), the app **reconciles your copy
268
+ on startup**: it backs the old file up to `pricing.json.bak`, adds the new
269
+ shipped keys, and **keeps every value you customized**. Your edits are never
270
+ discarded; a copy you've left current is not rewritten.
247
271
  - The `opus`/`sonnet`/`haiku`/`gemini`/`gpt` family rules use **current**
248
272
  pricing; the deprecated Opus 4 / 4.1 ($15/$75) and specific GPT-5 versions are
249
273
  pinned via exact `models` entries. Add an exact entry to override any model.
@@ -274,79 +298,48 @@ served from cache (legitimately high for Claude Code, which re-reads cached cont
274
298
  (and Codex only encrypted reasoning), not the plaintext — the app notes this
275
299
  explicitly. (Not a bug.)
276
300
  - **Codex sessions have no stored title**, so the title falls back to the first
277
- user message.
301
+ user message. The same is true for **pi** sessions.
278
302
  - **Junie sessions render differently.** Junie records an event-sourced UI stream
279
303
  rather than a chat log, so a session reads as tool / terminal / file blocks plus
280
304
  a final result — there's no assistant prose or thinking to show. Pasted
281
305
  screenshots are surfaced inline. Older Junie sessions don't record a working
282
306
  directory and group under an **"(unknown — Junie)"** project.
307
+ - **pi reasoning renders in full.** Unlike Claude Code / Codex, pi stores the
308
+ plaintext of its thinking blocks, so they show real reasoning rather than an
309
+ empty placeholder. pi keeps no memory in its home dir, so it contributes nothing
310
+ to the memory viewer.
311
+ - **opencode is SQLite-backed.** opencode stores all sessions in one read-only
312
+ SQLite database (`opencode.db`), not per-session files; Claudescope reads it via
313
+ Node's built-in `node:sqlite`. Its reasoning renders in full (plaintext), its
314
+ file edits (made via `apply_patch`) show in the **Files changed** tab and as
315
+ diffs, and pasted screenshots embed. Like pi, it contributes no memory.
316
+ - **GitHub Copilot CLI records an event-sourced stream**
317
+ (`~/.copilot/session-state/<id>/events.jsonl`). Cost is **session-level** — only
318
+ a cleanly-closed session reports tokens, so a crashed or still-running one shows
319
+ no cost. Reasoning is encrypted (renders empty, like Codex). File edits show in
320
+ the **Files changed** tab; a denied edit is shown but doesn't count as a change.
321
+ Pasted screenshots embed when screenshot-saving is enabled (otherwise a marker
322
+ remains). Its global `copilot-instructions.md` appears in the memory viewer; it
323
+ keeps no per-project memory.
283
324
 
284
325
  ---
285
326
 
286
- ## How it works
287
-
288
- npm-workspaces monorepo:
289
-
290
- | Package | Role |
291
- | ------------------ | --------------------------------------------------------------------- |
292
- | `packages/shared` | TypeScript types — the API + data contract shared by server and web. |
293
- | `packages/server` | Fastify API + DuckDB index (`@duckdb/node-api`). Serves the built UI. |
294
- | `packages/web` | Vite + React UI (react-markdown, Shiki, Recharts). |
295
-
296
- DuckDB reads the JSONL natively (`read_ndjson`) for indexing, full-text search,
297
- and analytics; a small TypeScript parser assembles the threaded view for a single
298
- session. The index is a derived cache — if it's ever corrupted (e.g. the process
299
- is killed mid-write) the app discards and rebuilds it automatically.
300
-
301
- Each agent is a **connector** (`packages/server/src/connectors/`). Claude Code
302
- JSONL is projected per-row; Codex spreads a session across record types and Junie
303
- records an event-sourced UI stream, so those connectors normalize a session to
304
- canonical NDJSON first — after that the indexing, search, cost, and threading
305
- paths are shared. Adding another agent is adding another connector.
306
-
307
- ---
308
-
309
- ## Development
310
-
311
- ```bash
312
- npm run dev # server (watch) on :4317 + Vite dev server on :5317 with HMR
313
- npm run typecheck # tsc -b across all packages
314
- npm run build # production build (shared → web → server)
315
- npm run serve # run the built server without rebuilding
316
- npm test # run the test suite (Vitest)
317
- npm run test:watch # watch mode
318
- ```
319
-
320
- Tests use [Vitest](https://vitest.dev). Unit tests cover the thread/subagent
321
- parser and pure helpers; the **integration suite** builds a real DuckDB index
322
- from synthetic fixtures (in a temp dir / temp DB — your real `~/.claude` is never
323
- touched) and exercises every API endpoint end-to-end via Fastify `inject()`.
324
-
325
- In dev, open the **Vite** URL (http://localhost:5317); it proxies `/api` to the
326
- server.
327
-
328
- ### Releasing
329
-
330
- The published package is a single bundle assembled by `npm run bundle` (esbuild
331
- inlines the server + shared lib; the web build and a default pricing file are
332
- copied alongside; only `@duckdb/node-api` stays an external native dependency).
333
- Releases are **tag-only** — never published from a laptop:
334
-
335
- ```bash
336
- npm version patch # bumps package.json + creates the vX.Y.Z tag
337
- git push --follow-tags # the tag triggers .github/workflows/release.yml → npm publish
338
- ```
327
+ ## Contributing & development
339
328
 
340
- The release workflow verifies the tag matches `package.json`, runs the tests,
341
- bundles, and publishes. Auth uses npm **Trusted Publishing** (OIDC) no
342
- `NPM_TOKEN` secret and provenance is attached automatically.
329
+ Claudescope is open source and contributions are welcome. How it works (the
330
+ DuckDB index, the per-agent **connectors**, and the threading parser), the local
331
+ dev loop, the test suite, **how to add a connector for another agent**, and the
332
+ release process all live in [`CONTRIBUTING.md`](./CONTRIBUTING.md), with
333
+ [`CLAUDE.md`](./CLAUDE.md) as the deeper architectural source of truth. To run a
334
+ local copy, see [Run from source](#run-from-source) above.
343
335
 
344
336
  ---
345
337
 
346
338
  ## Security & privacy
347
339
 
348
- Claudescope runs entirely on your machine. It treats `~/.claude`, `~/.codex`, and
349
- `~/.junie` as **read-only**, **binds to `127.0.0.1` only**, and sends **no telemetry**. Its only
340
+ Claudescope runs entirely on your machine. It treats every agent source
341
+ (`~/.claude`, `~/.codex`, `~/.junie`, `~/.pi`, `~/.copilot`, and opencode's database) as
342
+ **read-only**, **binds to `127.0.0.1` only**, and sends **no telemetry**. Its only
350
343
  outbound requests are a cached npm-registry version check for the update notice
351
344
  and a daily fetch of public model pricing rates from LiteLLM (disable with
352
345
  `PRICING_REFRESH_INTERVAL_MS=0`). See
@@ -358,11 +351,11 @@ shell, and self-update behavior — and how to report a vulnerability.
358
351
  ## Troubleshooting
359
352
 
360
353
  - **App is empty / "sessions directory not found"** — none of `CLAUDE_PROJECTS_DIR`,
361
- `CODEX_SESSIONS_DIR`, or `JUNIE_SESSIONS_DIR` points at real transcripts. Check
354
+ `CODEX_SESSIONS_DIR`, `JUNIE_SESSIONS_DIR`, `PI_SESSIONS_DIR`, `OPENCODE_DATA_DIR`, or `COPILOT_SESSIONS_DIR` points at real transcripts. Check
362
355
  the banner and set them correctly. Any source can be absent; only the present
363
356
  ones are indexed.
364
357
  - **`Error: listen EADDRINUSE :4317`** — the port is taken; run `claudescope --port <n>`.
365
- - **Node version errors** — you need Node ≥ 22 (`node -v`).
358
+ - **Node version errors** — you need Node ≥ 22.12 (`node -v`).
366
359
  - **Stale or wrong data** — delete `~/.claudescope/index.duckdb*` and
367
360
  `claudescope restart` to rebuild the index from scratch.
368
361
  - **`@duckdb/node-api` install issues** — it ships prebuilt native binaries;
package/cli.js CHANGED
@@ -1,14 +1,14 @@
1
1
  #!/usr/bin/env node
2
2
  import { createRequire as __cr } from 'node:module';
3
3
  const require = __cr(import.meta.url);
4
- import{spawn as G,spawnSync as I}from"node:child_process";import{existsSync as D,mkdirSync as B,openSync as ue,readFileSync as A,realpathSync as de,rmSync as C,writeFileSync as J}from"node:fs";import{dirname as fe,join as E}from"node:path";import{createInterface as me}from"node:readline/promises";import{parseArgs as ge}from"node:util";import{fileURLToPath as he}from"node:url";import{copyFileSync as ke,existsSync as X,mkdirSync as De}from"node:fs";import{homedir as l}from"node:os";import{dirname as Y,join as i}from"node:path";import{fileURLToPath as q}from"node:url";var R=Y(q(import.meta.url));function T(e,t){return e.find(n=>X(n))??t}var v=Number(process.env.PORT??4317),h=i(R,"..");function _(e){return e==="~"?l():e.startsWith("~/")?i(l(),e.slice(2)):e}var b=_(process.env.CLAUDE_PROJECTS_DIR??i(l(),".claude","projects")),Te=_(process.env.CODEX_SESSIONS_DIR??i(l(),".codex","sessions")),$e=_(process.env.JUNIE_SESSIONS_DIR??i(l(),".junie","sessions")),Me=process.env.OPEN_BROWSER==="1",Ue=Number(process.env.REINDEX_INTERVAL_MS??15e3),a=_(process.env.CLAUDESCOPE_HOME??i(l(),".claudescope")),Fe=process.env.DUCKDB_PATH??i(a,"index.duckdb"),He=T([i(R,"pricing.default.json"),i(h,"pricing.json")],i(h,"pricing.json")),je=process.env.PRICING_PATH??i(a,"pricing.json"),p=process.env.FETCHED_PRICING_PATH??i(a,"pricing.fetched.json"),$=process.env.LITELLM_PRICING_URL??"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",Ge=Number(process.env.PRICING_REFRESH_INTERVAL_MS??1440*60*1e3),Be=process.env.WEB_DIST_DIR??T([i(R,"web"),i(h,"..","web","dist")],i(h,"..","web","dist")),c="0.5.3";import{mkdirSync as z,readFileSync as Q,renameSync as Z,writeFileSync as ee}from"node:fs";import{dirname as M,join as te}from"node:path";var oe=new Set(["anthropic","openai","gemini","xai","mistral","deepseek"]),ne=new Set(["chat","responses"]),re=1e6,se=1e4,ie=3e4;function y(e){if(typeof e!="number"||!Number.isFinite(e)||e<0)return null;let t=e*re;return t<=se?t:null}function U(e){return e==null?0:y(e)}function ce(e){let t={};if(typeof e!="object"||e===null)return t;for(let[n,r]of Object.entries(e)){if(n==="sample_spec"||n.includes("/")||typeof r!="object"||r===null)continue;let o=r;if(typeof o.litellm_provider!="string"||!oe.has(o.litellm_provider)||typeof o.mode!="string"||!ne.has(o.mode))continue;let s=y(o.input_cost_per_token),d=y(o.output_cost_per_token),f=U(o.cache_creation_input_token_cost),x=U(o.cache_read_input_token_cost);s===null||d===null||f===null||x===null||(t[n]={input:s,output:d,cacheWrite:f,cacheRead:x})}return t}function ae(e){let t=Object.keys(e),n=t.some(o=>o.startsWith("claude")),r=t.some(o=>/^(gpt|o\d|chatgpt|codex)/.test(o));if(!n||!r){let o=[!n&&"anthropic",!r&&"openai"].filter(Boolean).join(", ");throw new Error(`Fetched pricing failed validation: no ${o} model survived mapping (${t.length} model(s) total). LiteLLM schema may have drifted.`)}}function le(e){try{return JSON.parse(Q(e,"utf8"))?.models??{}}catch{return{}}}function pe(e,t){let n=0;for(let[r,o]of Object.entries(e)){let s=t[r];(!s||s.input!==o.input||s.output!==o.output||s.cacheWrite!==o.cacheWrite||s.cacheRead!==o.cacheRead)&&(n+=1)}return n}async function F(){let e=await fetch($,{signal:AbortSignal.timeout(ie)});if(!e.ok)throw new Error(`Pricing fetch failed: ${e.status} ${e.statusText}`);let t=await e.json(),n=ce(t);ae(n);let r=le(p),o=pe(n,r),s=new Date().toISOString(),d={fetchedAt:s,models:n};z(M(p),{recursive:!0});let f=te(M(p),`.pricing.fetched.${process.pid}.tmp`);return ee(f,`${JSON.stringify(d,null,2)}
5
- `),Z(f,p),{fetchedAt:s,modelCount:Object.keys(n).length,changed:o,path:p}}var O=fe(he(import.meta.url)),_e=E(O,"server.js"),u=E(a,"daemon.json"),w=E(a,"daemon.log"),P=E(a,"update-check.json"),m="@vladar107/claudescope",we=1440*60*1e3;function S(){if(!D(u))return null;try{return JSON.parse(A(u,"utf8"))}catch{return null}}function g(e){try{return process.kill(e,0),!0}catch{return!1}}async function N(e){try{return(await fetch(`http://127.0.0.1:${e}/api/health`,{signal:AbortSignal.timeout(1500)})).ok}catch{return!1}}async function Ee(e,t){let n=Date.now()+t;for(;Date.now()<n;){if(await N(e))return!0;process.stdout.write("."),await new Promise(r=>setTimeout(r,500))}return!1}function L(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{G(t,[e],{stdio:"ignore",detached:!0,shell:process.platform==="win32"}).unref()}catch{}}async function H(e,t){B(a,{recursive:!0});let n=S();if(n&&g(n.pid)&&await N(n.port)){console.log(`\u2713 claudescope is already running \u2192 ${n.url}`),t&&L(n.url);return}n&&!g(n.pid)&&C(u,{force:!0});let r=`http://localhost:${e}`,o=ue(w,"a"),s=G(process.execPath,[_e],{detached:!0,stdio:["ignore",o,o],env:{...process.env,PORT:String(e),OPEN_BROWSER:"0"}});if(s.unref(),J(u,JSON.stringify({pid:s.pid,port:e,url:r,version:c,startedAt:new Date().toISOString()},null,2)),process.stdout.write("\u203A Starting claudescope"),!await Ee(e,2e4)){console.error(`
4
+ import{spawn as Ee,spawnSync as D}from"node:child_process";import{existsSync as R,mkdirSync as B,openSync as we,readFileSync as T,realpathSync as N,renameSync as ye,rmSync as E,statSync as ve,writeFileSync as J}from"node:fs";import{dirname as Re,join as b}from"node:path";import{createInterface as be}from"node:readline/promises";import{parseArgs as Ie}from"node:util";import{fileURLToPath as W}from"node:url";import{copyFileSync as Ge,existsSync as Q,mkdirSync as Be,readFileSync as Je,renameSync as We,writeFileSync as Ke}from"node:fs";import{homedir as l}from"node:os";import{dirname as h,join as s}from"node:path";import{fileURLToPath as Z}from"node:url";var P=h(Z(import.meta.url));function M(e,t){return e.find(o=>Q(o))??t}var O=Number(process.env.PORT??4317),w=s(P,"..");function d(e){return e==="~"?l():e.startsWith("~/")?s(l(),e.slice(2)):e}var y=d(process.env.CLAUDE_PROJECTS_DIR??s(l(),".claude","projects")),ee=d(process.env.CODEX_SESSIONS_DIR??s(l(),".codex","sessions")),te=d(process.env.JUNIE_SESSIONS_DIR??s(l(),".junie","sessions")),ze=d(process.env.PI_SESSIONS_DIR??s(l(),".pi","agent","sessions")),oe=d(process.env.OPENCODE_DATA_DIR??s(process.env.XDG_DATA_HOME??s(l(),".local","share"),"opencode")),Qe=process.env.OPENCODE_DB_PATH??s(oe,"opencode.db"),ne=d(process.env.COPILOT_SESSIONS_DIR??s(l(),".copilot","session-state")),Ze=h(y),et=h(ee),tt=h(te),ot=h(ne),nt=process.env.OPEN_BROWSER==="1",rt=Number(process.env.REINDEX_INTERVAL_MS??15e3),a=d(process.env.CLAUDESCOPE_HOME??s(l(),".claudescope")),st=process.env.DUCKDB_PATH??s(a,"index.duckdb"),it=M([s(P,"pricing.default.json"),s(w,"pricing.json")],s(w,"pricing.json")),ct=process.env.PRICING_PATH??s(a,"pricing.json"),g=process.env.FETCHED_PRICING_PATH??s(a,"pricing.fetched.json"),U=process.env.LITELLM_PRICING_URL??"https://raw.githubusercontent.com/BerriAI/litellm/main/model_prices_and_context_window.json",at=Number(process.env.PRICING_REFRESH_INTERVAL_MS??1440*60*1e3),lt=process.env.WEB_DIST_DIR??M([s(P,"web"),s(w,"..","web","dist")],s(w,"..","web","dist")),c="0.7.0";import{mkdirSync as re,readFileSync as se,renameSync as ie,writeFileSync as ce}from"node:fs";import{dirname as H,join as ae}from"node:path";var le=new Set(["anthropic","openai","gemini","xai","mistral","deepseek"]),pe=new Set(["chat","responses"]),ue=1e6,de=1e4,fe=3e4;function C(e){if(typeof e!="number"||!Number.isFinite(e)||e<0)return null;let t=e*ue;return t<=de?t:null}function F(e){return e==null?0:C(e)}function me(e){let t={};if(typeof e!="object"||e===null)return t;for(let[o,r]of Object.entries(e)){if(o==="sample_spec"||o.includes("/")||typeof r!="object"||r===null)continue;let n=r;if(typeof n.litellm_provider!="string"||!le.has(n.litellm_provider)||typeof n.mode!="string"||!pe.has(n.mode))continue;let i=C(n.input_cost_per_token),u=C(n.output_cost_per_token),m=F(n.cache_creation_input_token_cost),$=F(n.cache_read_input_token_cost);i===null||u===null||m===null||$===null||(t[o]={input:i,output:u,cacheWrite:m,cacheRead:$})}return t}function ge(e){let t=Object.keys(e),o=t.some(n=>n.startsWith("claude")),r=t.some(n=>/^(gpt|o\d|chatgpt|codex)/.test(n));if(!o||!r){let n=[!o&&"anthropic",!r&&"openai"].filter(Boolean).join(", ");throw new Error(`Fetched pricing failed validation: no ${n} model survived mapping (${t.length} model(s) total). LiteLLM schema may have drifted.`)}}function _e(e){try{return JSON.parse(se(e,"utf8"))?.models??{}}catch{return{}}}function he(e,t){let o=0;for(let[r,n]of Object.entries(e)){let i=t[r];(!i||i.input!==n.input||i.output!==n.output||i.cacheWrite!==n.cacheWrite||i.cacheRead!==n.cacheRead)&&(o+=1)}return o}async function j(){let e=await fetch(U,{signal:AbortSignal.timeout(fe)});if(!e.ok)throw new Error(`Pricing fetch failed: ${e.status} ${e.statusText}`);let t=await e.json(),o=me(t);ge(o);let r=_e(g),n=he(o,r),i=new Date().toISOString(),u={fetchedAt:i,models:o};re(H(g),{recursive:!0});let m=ae(H(g),`.pricing.fetched.${process.pid}.tmp`);return ce(m,`${JSON.stringify(u,null,2)}
5
+ `),ie(m,g),{fetchedAt:i,modelCount:Object.keys(o).length,changed:n,path:g}}import{spawn as Se}from"node:child_process";function v(e){let t=process.platform==="darwin"?"open":process.platform==="win32"?"start":"xdg-open";try{Se(t,[e],{stdio:"ignore",detached:!0,shell:process.platform==="win32"}).unref()}catch{}}var L=Re(W(import.meta.url)),Pe=b(L,"server.js"),f=b(a,"daemon.json"),p=b(a,"daemon.log"),x=b(a,"update-check.json"),S="@vladar107/claudescope",Oe=1440*60*1e3,Ce=5*1024*1024,K=5e3;function I(){if(!R(f))return null;try{return JSON.parse(T(f,"utf8"))}catch{return null}}function _(e){try{return process.kill(e,0),!0}catch{return!1}}async function k(e){try{return(await fetch(`http://127.0.0.1:${e}/api/health`,{signal:AbortSignal.timeout(1500)})).ok}catch{return!1}}async function xe(e,t){let o=Date.now()+t;for(;Date.now()<o;){if(await k(e))return!0;process.stdout.write("."),await new Promise(r=>setTimeout(r,500))}return!1}async function X(e,t){let o=Date.now()+t;for(;Date.now()<o;){if(!_(e))return!0;await new Promise(r=>setTimeout(r,100))}return!_(e)}async function De(e,t,o){return e?t(e.pid)?await o(e.port)?"healthy":"wedged":"stale":"none"}function Ne(){try{R(p)&&ve(p).size>Ce&&(E(`${p}.1`,{force:!0}),ye(p,`${p}.1`))}catch{}}async function V(e,t){B(a,{recursive:!0});let o=I(),r=await De(o,_,k);if(r==="healthy"&&o){console.log(`\u2713 claudescope is already running \u2192 ${o.url}`),t&&v(o.url);return}if(r==="stale"&&E(f,{force:!0}),r==="wedged"&&o){console.log(`claudescope (pid ${o.pid}) is unresponsive; restarting it\u2026`);try{process.kill(o.pid,"SIGTERM")}catch{}if(!await X(o.pid,K)){console.error(`\u2717 Could not stop the unresponsive process (pid ${o.pid}). Kill it manually and retry: kill -9 ${o.pid}`),process.exitCode=1;return}E(f,{force:!0})}let n=`http://localhost:${e}`;Ne();let i=we(p,"a"),u=Ee(process.execPath,[Pe],{detached:!0,stdio:["ignore",i,i],env:{...process.env,PORT:String(e),OPEN_BROWSER:"0"}});if(u.unref(),J(f,JSON.stringify({pid:u.pid,port:e,url:n,version:c,startedAt:new Date().toISOString()},null,2)),process.stdout.write("\u203A Starting claudescope"),!await xe(e,2e4)){console.error(`
6
6
  \u2717 Server did not become healthy in time. Inspect: claudescope logs`),process.exitCode=1;return}console.log(`
7
- \u2713 claudescope running \u2192 ${r}`),console.log(` Sessions: ${b} (read-only)`),t&&L(r),await K(!1)}function k(){let e=S();if(!e||!g(e.pid)){console.log("claudescope is not running."),C(u,{force:!0});return}try{process.kill(e.pid,"SIGTERM")}catch{}C(u,{force:!0}),console.log(`\u2713 Stopped claudescope (pid ${e.pid}).`)}async function Se(){let e=S();e&&g(e.pid)&&await N(e.port)?console.log(`\u25CF running ${e.url} (pid ${e.pid}, v${e.version})`):console.log(`\u25CB stopped (installed v${c})`),await K(!0)}function Re(){let e=S();e&&g(e.pid)?L(e.url):console.log("claudescope is not running. Start it with: claudescope start")}function ve(e){if(!D(w)){console.log("No logs yet.");return}e&&process.platform!=="win32"?I("tail",["-f",w],{stdio:"inherit"}):process.stdout.write(A(w,"utf8"))}async function be(e,t){if(!process.stdin.isTTY)return t;let n=me({input:process.stdin,output:process.stdout});try{let r=(await n.question(`${e} ${t?"[Y/n]":"[y/N]"} `)).trim().toLowerCase();return r?r==="y"||r==="yes":t}finally{n.close()}}function ye(){let e=O;try{e=de(O)}catch{}return e.includes("/nix/store/")?"nix":/[\\/]Cellar[\\/]claudescope[\\/]/.test(e)?"brew":"npm"}async function Pe(e){let t=await W(!0);if(t&&!V(t,c)){console.log(`\u2713 Already on the latest version (v${c}).`);return}let n=ye();if(n==="brew"){console.log("claudescope was installed via Homebrew."),console.log(" Run: brew upgrade vladar107/tap/claudescope");return}if(n==="nix"){console.log("claudescope was installed via Nix."),console.log(" Run: nix profile upgrade claudescope"),console.log(" (flake users: re-run `nix run --refresh github:vladar107/claudescope`)");return}t||console.log("\u26A0 Could not reach the npm registry to confirm the latest version.");let r=t?`v${c} \u2192 v${t}`:`v${c} \u2192 latest`;if(console.log(`\u203A Will run: npm install -g ${m}@latest (${r})`),!e&&!await be("Proceed?",!0)){console.log("Aborted.");return}console.log(`\u203A Updating ${m}\u2026`);let o=process.platform==="win32"?"npm.cmd":"npm";if(I(o,["install","-g",`${m}@latest`],{stdio:"inherit"}).status!==0){console.error(`\u2717 Update failed. If you run via npx, just re-run \`npx ${m}\` to get the latest.`),process.exitCode=1;return}k(),console.log("\u2713 Updated. Restarting\u2026"),I("claudescope",["start"],{stdio:"inherit",shell:process.platform==="win32"})}function V(e,t){let n=e.split(".").map(o=>Number.parseInt(o,10)||0),r=t.split(".").map(o=>Number.parseInt(o,10)||0);for(let o=0;o<3;o++){if((n[o]??0)>(r[o]??0))return!0;if((n[o]??0)<(r[o]??0))return!1}return!1}async function W(e){let t=Date.now();if(!e&&D(P))try{let s=JSON.parse(A(P,"utf8"));if(t-s.lastCheck<we)return s.latest}catch{}let n=`https://registry.npmjs.org/${m.replaceAll("/","%2f")}/latest`,r=await fetch(n,{signal:AbortSignal.timeout(2500)});if(!r.ok)return null;let o=await r.json();return o.version?(B(a,{recursive:!0}),J(P,JSON.stringify({lastCheck:t,latest:o.version})),o.version):null}async function K(e){try{let t=await W(e);t&&V(t,c)&&console.log(`
8
- \u2B06 Update available: v${c} \u2192 v${t}. Run: claudescope update`)}catch{}}async function Ie(){try{let{modelCount:e,changed:t,path:n}=await F();console.log(`\u2713 Pricing updated: ${e} models (${t} changed) \u2192 ${n}`),console.log(" A running server picks up the new rates automatically (newly indexed events).")}catch(e){console.error(`\u2717 Pricing update failed: ${e instanceof Error?e.message:String(e)}`),console.error(" Existing rates are unchanged."),process.exitCode=1}}function Ce(){console.log(`Usage: claudescope pricing <subcommand>
7
+ \u2713 claudescope running \u2192 ${n}`),console.log(` Sessions: ${y} (read-only)`),t&&v(n),await z(!1)}async function A(){let e=I();if(!e||!_(e.pid)){console.log("claudescope is not running."),E(f,{force:!0});return}try{process.kill(e.pid,"SIGTERM")}catch{}await X(e.pid,K),E(f,{force:!0}),console.log(`\u2713 Stopped claudescope (pid ${e.pid}).`)}async function Le(){let e=I();e&&_(e.pid)&&await k(e.port)?console.log(`\u25CF running ${e.url} (pid ${e.pid}, v${e.version})`):console.log(`\u25CB stopped (installed v${c})`),await z(!0)}function Ae(){let e=I();e&&_(e.pid)?v(e.url):console.log("claudescope is not running. Start it with: claudescope start")}function Te(e){if(!R(p)){console.log("No logs yet.");return}e&&process.platform!=="win32"?D("tail",["-f",p],{stdio:"inherit"}):process.stdout.write(T(p,"utf8"))}async function ke(e,t){if(!process.stdin.isTTY)return t;let o=be({input:process.stdin,output:process.stdout});try{let r=(await o.question(`${e} ${t?"[Y/n]":"[y/N]"} `)).trim().toLowerCase();return r?r==="y"||r==="yes":t}finally{o.close()}}function $e(){let e=L;try{e=N(L)}catch{}return e.includes("/nix/store/")?"nix":/[\\/]Cellar[\\/]claudescope[\\/]/.test(e)?"brew":"npm"}async function Me(e){let t=await q(!0);if(t&&!Y(t,c)){console.log(`\u2713 Already on the latest version (v${c}).`);return}let o=$e();if(o==="brew"){console.log("claudescope was installed via Homebrew."),console.log(" Run: brew upgrade vladar107/tap/claudescope");return}if(o==="nix"){console.log("claudescope was installed via Nix."),console.log(" Run: nix profile upgrade claudescope"),console.log(" (flake users: re-run `nix run --refresh github:vladar107/claudescope`)");return}t||console.log("\u26A0 Could not reach the npm registry to confirm the latest version.");let r=t?`v${c} \u2192 v${t}`:`v${c} \u2192 latest`;if(console.log(`\u203A Will run: npm install -g ${S}@latest (${r})`),!e&&!await ke("Proceed?",!0)){console.log("Aborted.");return}console.log(`\u203A Updating ${S}\u2026`);let n=process.platform==="win32"?"npm.cmd":"npm";if(D(n,["install","-g",`${S}@latest`],{stdio:"inherit"}).status!==0){console.error(`\u2717 Update failed. If you run via npx, just re-run \`npx ${S}\` to get the latest.`),process.exitCode=1;return}await A(),console.log("\u2713 Updated. Restarting\u2026"),D("claudescope",["start"],{stdio:"inherit",shell:process.platform==="win32"})}function Y(e,t){let o=e.split(".").map(n=>Number.parseInt(n,10)||0),r=t.split(".").map(n=>Number.parseInt(n,10)||0);for(let n=0;n<3;n++){if((o[n]??0)>(r[n]??0))return!0;if((o[n]??0)<(r[n]??0))return!1}return!1}async function q(e){let t=Date.now();if(!e&&R(x))try{let i=JSON.parse(T(x,"utf8"));if(t-i.lastCheck<Oe)return i.latest}catch{}let o=`https://registry.npmjs.org/${S.replaceAll("/","%2f")}/latest`,r=await fetch(o,{signal:AbortSignal.timeout(2500)});if(!r.ok)return null;let n=await r.json();return n.version?(B(a,{recursive:!0}),J(x,JSON.stringify({lastCheck:t,latest:n.version})),n.version):null}async function z(e){try{let t=await q(e);t&&Y(t,c)&&console.log(`
8
+ \u2B06 Update available: v${c} \u2192 v${t}. Run: claudescope update`)}catch{}}async function Ue(){try{let{modelCount:e,changed:t,path:o}=await j();console.log(`\u2713 Pricing updated: ${e} models (${t} changed) \u2192 ${o}`),console.log(" A running server picks up the new rates automatically (newly indexed events).")}catch(e){console.error(`\u2717 Pricing update failed: ${e instanceof Error?e.message:String(e)}`),console.error(" Existing rates are unchanged."),process.exitCode=1}}function He(){console.log(`Usage: claudescope pricing <subcommand>
9
9
 
10
10
  Subcommands:
11
- update Fetch current model prices (LiteLLM) into the local rate table`)}function j(){console.log(`claudescope v${c} \u2014 local viewer for Claude Code transcripts
11
+ update Fetch current model prices (LiteLLM) into the local rate table`)}function G(){console.log(`claudescope v${c} \u2014 local viewer for Claude Code transcripts
12
12
 
13
13
  Usage: claudescope [command] [options]
14
14
 
@@ -25,11 +25,11 @@ Commands:
25
25
  version Print the installed version
26
26
 
27
27
  Options:
28
- --port <n> Port to listen on (default ${v}, or $PORT)
28
+ --port <n> Port to listen on (default ${O}, or $PORT)
29
29
  --no-open Don't open the browser on start
30
30
  -y, --yes Skip the confirmation prompt (for \`update\`)
31
31
 
32
32
  State (index, pricing, logs, PID) lives in ${a}
33
33
  (override with $CLAUDESCOPE_HOME). Sessions are read from
34
- ${b} (override with $CLAUDE_PROJECTS_DIR).`)}async function Oe(){let{values:e,positionals:t}=ge({allowPositionals:!0,options:{port:{type:"string"},follow:{type:"boolean",short:"f"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"},yes:{type:"boolean",short:"y"},"no-open":{type:"boolean"}}}),n=e.port?Number(e.port):v,r=!e["no-open"],o=t[0];switch(o||(o=e.help?"help":e.version?"version":"start"),o){case"start":await H(n,r);break;case"stop":k();break;case"restart":k(),await H(n,r);break;case"status":await Se();break;case"open":Re();break;case"logs":ve(!!e.follow);break;case"update":await Pe(!!e.yes);break;case"pricing":{t[1]==="update"?await Ie():Ce();break}case"version":console.log(c);break;case"help":j();break;default:console.error(`Unknown command: ${o}
35
- `),j(),process.exitCode=1}}Oe().catch(e=>{console.error(e),process.exit(1)});
34
+ ${y} (override with $CLAUDE_PROJECTS_DIR).`)}async function Fe(){let{values:e,positionals:t}=Ie({allowPositionals:!0,options:{port:{type:"string"},follow:{type:"boolean",short:"f"},help:{type:"boolean",short:"h"},version:{type:"boolean",short:"v"},yes:{type:"boolean",short:"y"},"no-open":{type:"boolean"}}}),o=e.port?Number(e.port):O,r=!e["no-open"],n=t[0];switch(n||(n=e.help?"help":e.version?"version":"start"),n){case"start":await V(o,r);break;case"stop":await A();break;case"restart":await A(),await V(o,r);break;case"status":await Le();break;case"open":Ae();break;case"logs":Te(!!e.follow);break;case"update":await Me(!!e.yes);break;case"pricing":{t[1]==="update"?await Ue():He();break}case"version":console.log(c);break;case"help":G();break;default:console.error(`Unknown command: ${n}
35
+ `),G(),process.exitCode=1}}function je(){let e=process.argv[1];if(!e)return!1;try{return N(e)===N(W(import.meta.url))}catch{return!1}}je()&&Fe().catch(e=>{console.error(e),process.exit(1)});export{De as classifyExisting,_ as isAlive,k as isHealthy,I as readDaemon,X as waitForExit,xe as waitForHealth};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vladar107/claudescope",
3
- "version": "0.5.3",
3
+ "version": "0.7.0",
4
4
  "description": "Local, read-only web app to browse, read, search, and analyze your AI coding-agent transcripts — Claude Code, OpenAI Codex, and JetBrains Junie.",
5
5
  "keywords": [
6
6
  "claude",
@@ -36,7 +36,7 @@
36
36
  "README.md"
37
37
  ],
38
38
  "engines": {
39
- "node": ">=22"
39
+ "node": ">=22.12"
40
40
  },
41
41
  "dependencies": {
42
42
  "@duckdb/node-api": "^1.5.3-r.3"
@@ -1,19 +1,64 @@
1
1
  {
2
+ "schemaVersion": 2,
2
3
  "models": {
3
4
  "claude-opus-4-1": { "input": 15, "output": 75, "cacheWrite": 18.75, "cacheRead": 1.5 },
4
5
  "claude-opus-4": { "input": 15, "output": 75, "cacheWrite": 18.75, "cacheRead": 1.5 },
5
6
  "<synthetic>": { "input": 0, "output": 0, "cacheWrite": 0, "cacheRead": 0 },
6
- "gpt-5": { "input": 0.625, "output": 5, "cacheWrite": 0, "cacheRead": 0.125 },
7
- "gpt-5.4": { "input": 2.5, "output": 15, "cacheWrite": 0, "cacheRead": 0.5 },
7
+
8
8
  "gpt-5.5": { "input": 5, "output": 30, "cacheWrite": 0, "cacheRead": 0.5 },
9
- "gpt-5.5-pro": { "input": 30, "output": 180, "cacheWrite": 0, "cacheRead": 30 }
9
+ "gpt-5.5-pro": { "input": 30, "output": 180, "cacheWrite": 0, "cacheRead": 30 },
10
+ "gpt-5.5-cyber": { "input": 20, "output": 120, "cacheWrite": 0, "cacheRead": 2 },
11
+
12
+ "gpt-5.4": { "input": 2.5, "output": 15, "cacheWrite": 0, "cacheRead": 0.25 },
13
+ "gpt-5.4-mini": { "input": 0.75, "output": 4.5, "cacheWrite": 0, "cacheRead": 0.075 },
14
+ "gpt-5.4-mini-fast": { "input": 0.75, "output": 4.5, "cacheWrite": 0, "cacheRead": 0.075 },
15
+ "gpt-5.4-nano": { "input": 0.2, "output": 1.25, "cacheWrite": 0, "cacheRead": 0.02 },
16
+ "gpt-5.4-pro": { "input": 30, "output": 180, "cacheWrite": 0, "cacheRead": 30 },
17
+
18
+ "gpt-5.3-codex": { "input": 1.75, "output": 14, "cacheWrite": 0, "cacheRead": 0.175 },
19
+ "gpt-5.3-chat-latest": { "input": 1.75, "output": 14, "cacheWrite": 0, "cacheRead": 0.175 },
20
+
21
+ "gpt-5.2": { "input": 1.75, "output": 14, "cacheWrite": 0, "cacheRead": 0.175 },
22
+ "gpt-5.2-pro": { "input": 21, "output": 168, "cacheWrite": 0, "cacheRead": 21 },
23
+ "gpt-5.2-codex": { "input": 1.75, "output": 14, "cacheWrite": 0, "cacheRead": 0.175 },
24
+ "gpt-5.2-chat-latest": { "input": 1.75, "output": 14, "cacheWrite": 0, "cacheRead": 0.175 },
25
+
26
+ "gpt-5.1": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
27
+ "gpt-5.1-codex-max": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
28
+ "gpt-5.1-codex": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
29
+ "gpt-5.1-codex-mini": { "input": 0.25, "output": 2, "cacheWrite": 0, "cacheRead": 0.025 },
30
+ "gpt-5.1-chat-latest": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
31
+
32
+ "gpt-5": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
33
+ "gpt-5-mini": { "input": 0.25, "output": 2, "cacheWrite": 0, "cacheRead": 0.025 },
34
+ "gpt-5-nano": { "input": 0.05, "output": 0.4, "cacheWrite": 0, "cacheRead": 0.005 },
35
+ "gpt-5-pro": { "input": 15, "output": 120, "cacheWrite": 0, "cacheRead": 15 },
36
+ "gpt-5-codex": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
37
+ "gpt-5-chat-latest": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
38
+ "gpt-5-search-api": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.125 },
39
+
40
+ "gpt-4.1": { "input": 2, "output": 8, "cacheWrite": 0, "cacheRead": 0.5 },
41
+ "gpt-4.1-mini": { "input": 0.4, "output": 1.6, "cacheWrite": 0, "cacheRead": 0.1 },
42
+ "gpt-4.1-nano": { "input": 0.1, "output": 0.4, "cacheWrite": 0, "cacheRead": 0.025 },
43
+
44
+ "gpt-4o": { "input": 2.5, "output": 10, "cacheWrite": 0, "cacheRead": 1.25 },
45
+ "gpt-4o-mini": { "input": 0.15, "output": 0.6, "cacheWrite": 0, "cacheRead": 0.075 },
46
+ "chatgpt-4o-latest": { "input": 5, "output": 15, "cacheWrite": 0, "cacheRead": 5 },
47
+
48
+ "codex-mini-latest": { "input": 1.5, "output": 6, "cacheWrite": 0, "cacheRead": 0.375 },
49
+
50
+ "o4-mini": { "input": 1.1, "output": 4.4, "cacheWrite": 0, "cacheRead": 0.275 },
51
+ "o3": { "input": 2, "output": 8, "cacheWrite": 0, "cacheRead": 0.5 },
52
+ "o3-mini": { "input": 1.1, "output": 4.4, "cacheWrite": 0, "cacheRead": 0.55 },
53
+ "o3-pro": { "input": 20, "output": 80, "cacheWrite": 0, "cacheRead": 20 },
54
+ "o1": { "input": 15, "output": 60, "cacheWrite": 0, "cacheRead": 7.5 }
10
55
  },
11
56
  "families": {
12
57
  "opus": { "input": 5, "output": 25, "cacheWrite": 6.25, "cacheRead": 0.5 },
13
58
  "sonnet": { "input": 3, "output": 15, "cacheWrite": 3.75, "cacheRead": 0.3 },
14
59
  "haiku": { "input": 1, "output": 5, "cacheWrite": 1.25, "cacheRead": 0.1 },
15
60
  "gemini": { "input": 1.25, "output": 10, "cacheWrite": 0, "cacheRead": 0.31 },
16
- "gpt": { "input": 2.5, "output": 15, "cacheWrite": 0, "cacheRead": 0.5 }
61
+ "gpt": { "input": 2.5, "output": 15, "cacheWrite": 0, "cacheRead": 0.25 }
17
62
  },
18
63
  "default": { "input": 3, "output": 15, "cacheWrite": 3.75, "cacheRead": 0.3 }
19
64
  }