@vladar107/claudescope 0.6.0 → 0.8.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 (85) hide show
  1. package/README.md +1 -1
  2. package/cli.js +1 -1
  3. package/package.json +1 -1
  4. package/server.js +269 -203
  5. package/web/apple-touch-icon.png +0 -0
  6. package/web/assets/{angular-html-CDxfOaS2.js → angular-html-ClxhEKBf.js} +1 -1
  7. package/web/assets/{angular-ts-D_kLPPhy.js → angular-ts-CesQLVaD.js} +1 -1
  8. package/web/assets/{apl-DjMvUFxS.js → apl-CgNftxDX.js} +1 -1
  9. package/web/assets/{astro-ChfFK9Uu.js → astro-Cxs2k2KK.js} +1 -1
  10. package/web/assets/{blade-J7W8bw63.js → blade-B4fas6DD.js} +1 -1
  11. package/web/assets/{c-dWJZFTAI.js → c-CtJpO1jy.js} +1 -1
  12. package/web/assets/{cobol-Dx9-ddH-.js → cobol-U0awSMC8.js} +1 -1
  13. package/web/assets/{coffee-Bq3TfOYt.js → coffee-C2mU5ncg.js} +1 -1
  14. package/web/assets/{cpp-1rH44WVB.js → cpp-BTzRVYzo.js} +1 -1
  15. package/web/assets/{crystal-BxEo6HJX.js → crystal-B2B_3Zni.js} +1 -1
  16. package/web/assets/{css-wwPXnSKj.js → css-B281sWZ-.js} +1 -1
  17. package/web/assets/{dist-D2aalZyN.js → dist-CSsuLrkC.js} +2 -2
  18. package/web/assets/{edge-BMFqR0HG.js → edge-BQr7POiA.js} +1 -1
  19. package/web/assets/{elixir-DZ7fM9D_.js → elixir-DtZYmaXp.js} +1 -1
  20. package/web/assets/{elm-DyoOvv6W.js → elm-CCiTUtEf.js} +1 -1
  21. package/web/assets/{erb-CdHUJ0Pn.js → erb-DxtcOrsr.js} +1 -1
  22. package/web/assets/{git-rebase-D78DxK9B.js → git-rebase-D0VrXZUb.js} +1 -1
  23. package/web/assets/{glimmer-js-Cg2IEi5v.js → glimmer-js-BbcLAXqU.js} +1 -1
  24. package/web/assets/{glimmer-ts-C1ciDZqB.js → glimmer-ts-gF0GelFz.js} +1 -1
  25. package/web/assets/{glsl-DcoWbP8K.js → glsl-Dy3rJrlX.js} +1 -1
  26. package/web/assets/{graphql-DQkMBaCi.js → graphql-Bv8G_A1n.js} +1 -1
  27. package/web/assets/{hack-BGGkNM5i.js → hack-D8arNvxg.js} +1 -1
  28. package/web/assets/{haml-hp-LrmJ-.js → haml-GVUDx0FX.js} +1 -1
  29. package/web/assets/{handlebars-u-2T0J2N.js → handlebars-D6d6XjJg.js} +1 -1
  30. package/web/assets/{html-DvhDRfbF.js → html-C9EpNCrN.js} +1 -1
  31. package/web/assets/{html-derivative-HeYr1EAb.js → html-derivative-BU7056uq.js} +1 -1
  32. package/web/assets/{http-DYa4c3Y6.js → http-TJA8usnG.js} +1 -1
  33. package/web/assets/{hurl-UVrs89Sp.js → hurl-BGvgMr7c.js} +1 -1
  34. package/web/assets/index-CUSXYaxc.js +93 -0
  35. package/web/assets/index-F6S4W9MR.css +1 -0
  36. package/web/assets/{java-Bv6A4oCu.js → java-CGohXz8Q.js} +1 -1
  37. package/web/assets/{javascript-D1gKHZZT.js → javascript-Bhro_xGF.js} +1 -1
  38. package/web/assets/{jinja-N00f5d6m.js → jinja-D0HzAkVc.js} +1 -1
  39. package/web/assets/{jison-C8fiiomI.js → jison-GvJwUGjq.js} +1 -1
  40. package/web/assets/{json-DPQsqsKS.js → json-BJyw99Ub.js} +1 -1
  41. package/web/assets/{jsx-DQ0xeA0e.js → jsx-YwbWgei_.js} +1 -1
  42. package/web/assets/{julia-DI-Bu6u1.js → julia-Z-zfCHdJ.js} +1 -1
  43. package/web/assets/{just-DxTDZdTb.js → just-DnLCIti8.js} +1 -1
  44. package/web/assets/{latex-WTF70PcV.js → latex-CLAlJF7r.js} +1 -1
  45. package/web/assets/{liquid-D0jg1F8f.js → liquid-Bi4ZU_1G.js} +1 -1
  46. package/web/assets/{lua-il9m4Mxz.js → lua-DfHGjVtj.js} +1 -1
  47. package/web/assets/{marko-BUHsWPgY.js → marko-BNqPi6OM.js} +1 -1
  48. package/web/assets/{mdc-CJUWIOQE.js → mdc-BukVp9uA.js} +1 -1
  49. package/web/assets/{nginx-BEOofcAo.js → nginx-BwqyoxLn.js} +1 -1
  50. package/web/assets/{nim-2gAKgJmF.js → nim-m2ZVzJ2j.js} +1 -1
  51. package/web/assets/{perl-B17v25da.js → perl-CV7RfFZx.js} +1 -1
  52. package/web/assets/{php-jleqe21z.js → php-BOjD4K3q.js} +1 -1
  53. package/web/assets/{pug-sP4pH5db.js → pug-6RbVQoCL.js} +1 -1
  54. package/web/assets/{qml-BeRrPPw_.js → qml-Bmt3HOv4.js} +1 -1
  55. package/web/assets/{r-DYKodMJW.js → r-CeBUt0pM.js} +1 -1
  56. package/web/assets/{razor-BQqNm8Ve.js → razor-Dn9bR1Ho.js} +1 -1
  57. package/web/assets/{regexp-jbfZBuRL.js → regexp-aEfCE6EV.js} +1 -1
  58. package/web/assets/{rst-CBWIRwrD.js → rst-Cz3BmFcx.js} +1 -1
  59. package/web/assets/{ruby-YVlorT2L.js → ruby-BtAkoAFf.js} +1 -1
  60. package/web/assets/{sas-Brg8CK_k.js → sas-gZzCQGai.js} +1 -1
  61. package/web/assets/{scss-D-2tF0Ur.js → scss-DrGWN6Ii.js} +1 -1
  62. package/web/assets/{shellscript-BCbTAXKW.js → shellscript-dW5Ac5iV.js} +1 -1
  63. package/web/assets/{shellsession-BRR9iv9e.js → shellsession-Dvgh9NAh.js} +1 -1
  64. package/web/assets/{soy-BnCQ29iU.js → soy-BR5_sYgC.js} +1 -1
  65. package/web/assets/{sql-BbmrrsxR.js → sql-BuyLmAyY.js} +1 -1
  66. package/web/assets/{stata-BWUhKNQc.js → stata-Cj98M8mp.js} +1 -1
  67. package/web/assets/{surrealql-oBwBF7xE.js → surrealql-Dm8SOJ8Q.js} +1 -1
  68. package/web/assets/{svelte-Denm0Atj.js → svelte-ConqXcto.js} +1 -1
  69. package/web/assets/{templ-BO0t0Yfy.js → templ-D_ROu-Jv.js} +1 -1
  70. package/web/assets/{tex-Bpz7DAvi.js → tex-DsUo2iP-.js} +1 -1
  71. package/web/assets/{ts-tags-CUsHLhXB.js → ts-tags-D9c_SvGj.js} +1 -1
  72. package/web/assets/{tsx-Dxw4bhzB.js → tsx-B1KusGdY.js} +1 -1
  73. package/web/assets/{twig-BCXsqC_p.js → twig-C-soC8u8.js} +1 -1
  74. package/web/assets/{typescript-bONSyxU0.js → typescript-CO2ZC1_1.js} +1 -1
  75. package/web/assets/{vue-Cir9Q4HX.js → vue-Bv8jF_au.js} +1 -1
  76. package/web/assets/{vue-html-C1IAtVS0.js → vue-html-DP268FQC.js} +1 -1
  77. package/web/assets/{vue-vine-BI-Ktr-N.js → vue-vine-BLsguVFb.js} +1 -1
  78. package/web/assets/{xml-BmhigNom.js → xml-R39PJcMB.js} +1 -1
  79. package/web/assets/{xsl-DRrVllgx.js → xsl-BB5bW0tf.js} +1 -1
  80. package/web/assets/{yaml-DsuXJ207.js → yaml-DRpVzaNV.js} +1 -1
  81. package/web/favicon-32.png +0 -0
  82. package/web/favicon.svg +13 -0
  83. package/web/index.html +5 -2
  84. package/web/assets/index-C4vHD9Wc.css +0 -1
  85. package/web/assets/index-Dx75KLr2.js +0 -93
package/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Claudescope
1
+ # <img src="docs/logo.svg" alt="" width="40" height="40" align="bottom"> Claudescope
2
2
 
3
3
  [![CI](https://github.com/vladar107/claudescope/actions/workflows/ci.yml/badge.svg)](https://github.com/vladar107/claudescope/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/@vladar107/claudescope)](https://www.npmjs.com/package/@vladar107/claudescope)
package/cli.js CHANGED
@@ -1,7 +1,7 @@
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 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.6.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)}
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.8.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
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
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(`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vladar107/claudescope",
3
- "version": "0.6.0",
3
+ "version": "0.8.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",