prompt-genie 0.2.0 → 0.3.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.
package/bin/install.cjs CHANGED
@@ -8,7 +8,7 @@ const readline = require("readline");
8
8
  const HOOKS_DEST = path.join(os.homedir(), ".prompt-genie", "hooks");
9
9
  const SETTINGS_FILE = path.join(os.homedir(), ".claude", "settings.json");
10
10
  const CONFIG_FILE = path.join(os.homedir(), ".claude", "pg_config.json");
11
- const HOOKS_SRC = path.join(__dirname, "..", "hooks");
11
+ const HOOKS_SRC = path.join(__dirname, "..", "dist", "hooks");
12
12
 
13
13
  const GRAPHQL_URL = "https://ouybbvbacjd3tbbvf3jpqbiizy.appsync-api.us-east-2.amazonaws.com/graphql";
14
14
  const API_KEY = "da2-xj6noinlgffx3ms3lgeopbhrjq";
@@ -86,7 +86,8 @@ function wireHooks() {
86
86
  }
87
87
 
88
88
  async function main() {
89
- console.log("\n Prompt Genie — Token Saver for Claude Code\n");
89
+ console.log("\n Prompt Genie for Claude Code\n");
90
+ console.log(" Reduce what Claude re-reads every session.\n");
90
91
 
91
92
  // Step 1: get email
92
93
  const email = await ask(" Enter your Prompt Genie email: ");
@@ -103,7 +104,7 @@ async function main() {
103
104
  );
104
105
  const result = JSON.parse(res.data?.cliAuth || "{}");
105
106
  if (!result.success) {
106
- console.error(" Failed to send code. Check your email and try again.");
107
+ console.error(" " + (result.error || "Failed to send code. Try again."));
107
108
  process.exit(1);
108
109
  }
109
110
  } catch (err) {
@@ -139,13 +140,9 @@ async function main() {
139
140
  }
140
141
 
141
142
  // Step 5: install
142
- console.log(" Installing hooks...");
143
+ console.log(" Installing...");
143
144
  copyHooks();
144
-
145
- console.log(" Wiring Claude Code settings...");
146
145
  wireHooks();
147
-
148
- console.log(" Saving config...");
149
146
  saveJson(CONFIG_FILE, { email, plan, token });
150
147
 
151
148
  // Step 6: result message based on plan
@@ -153,19 +150,24 @@ async function main() {
153
150
 
154
151
  if (isPaid) {
155
152
  console.log(`
156
- All done! Caching is active.
153
+ You're all set.
154
+
155
+ Prompt Genie is now active in Claude Code. Every file Claude reads
156
+ gets remembered for the session. No more paying to re-read
157
+ the same code on every turn.
157
158
 
158
- Restart VS Code to activate.
159
- Your token savings will appear at prompt-genie.com after your first session.
159
+ Restart VS Code to activate, then start a session as normal.
160
+ Your context savings will appear at prompt-genie.com/dashboard.
160
161
  `);
161
162
  } else {
162
163
  console.log(`
163
- ✅ Installed! You're on the Free plan.
164
+ ✅ Installed.
164
165
 
165
- Caching is disabled on Free you'll see how many tokens you would have
166
- saved at the end of each session.
166
+ You're on the Free plan. Prompt Genie is running but context
167
+ memory is paused. At the end of each session you'll see how much
168
+ you would have saved.
167
169
 
168
- Upgrade to Pro to activate → prompt-genie.com/pricing
170
+ Activate context memory → prompt-genie.com/pricing
169
171
  `);
170
172
  }
171
173
  }
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ const n=b;(function(c,d){const m=b,e=c();while(!![]){try{const f=parseInt(m(0x1fd))/0x1*(parseInt(m(0x1ee))/0x2)+-parseInt(m(0x201))/0x3*(-parseInt(m(0x203))/0x4)+parseInt(m(0x1e1))/0x5+-parseInt(m(0x1e2))/0x6+-parseInt(m(0x1ed))/0x7+-parseInt(m(0x1e5))/0x8*(parseInt(m(0x1f0))/0x9)+-parseInt(m(0x1fa))/0xa*(-parseInt(m(0x1d5))/0xb);if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x2f2ce));const fs=require('fs'),path=require(n(0x1f5)),CACHE_FILE=path[n(0x1e8)](process.env.HOME,n(0x1fb)+n(0x1f8)+n(0x1d3)+n(0x1f1)+'on'),STATS_FILE=path[n(0x1e8)](process.env.HOME,n(0x1fb)+n(0x1df)+n(0x1ff)+n(0x1ce)),SESSION_FILE=path['join'](process.env.HOME,'.claud'+'e/pg_s'+n(0x1cf)+n(0x1ec));function loadJson(c){const o=n;try{return JSON[o(0x1d1)](fs[o(0x200)+'leSync'](c,'utf8'));}catch{return{};}}function saveJson(c,d){const p=n;fs[p(0x1da)+p(0x1f6)+'c'](c,JSON[p(0x1db)+p(0x1ca)](d,null,0x2));}function b(c,d){c=c-0x1ca;const e=a();let f=e[c];if(b['AodqZB']===undefined){var g=function(l){const m='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let n='',o='';for(let p=0x0,q,r,s=0x0;r=l['charAt'](s++);~r&&(q=p%0x4?q*0x40+r:r,p++%0x4)?n+=String['fromCharCode'](0xff&q>>(-0x2*p&0x6)):0x0){r=m['indexOf'](r);}for(let t=0x0,u=n['length'];t<u;t++){o+='%'+('00'+n['charCodeAt'](t)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(o);};b['mTPDCE']=g,b['tMcYsl']={},b['AodqZB']=!![];}const h=e[0x0],i=c+h,j=b['tMcYsl'][i];return!j?(f=b['mTPDCE'](f),b['tMcYsl'][i]=f):f=j,f;}function recordMiss(){const q=n,c={'FRvgX':function(f,g){return f(g);},'GoQwq':function(f,g,h){return f(g,h);},'EOQJv':function(f,g){return f(g);}},d=c[q(0x1dd)](loadJson,STATS_FILE);d[q(0x1e3)+q(0x1e7)]=(d[q(0x1e3)+q(0x1e7)]||0x0)+0x1,c[q(0x1e9)](saveJson,STATS_FILE,d);const e=c[q(0x1f7)](loadJson,SESSION_FILE);e[q(0x1e7)]=(e[q(0x1e7)]||0x0)+0x1,e[q(0x1d0)]=new Date()[q(0x1dc)+q(0x1cb)]()[q(0x1ef)](0x0,0xa),saveJson(SESSION_FILE,e);}function a(){const s=['zgf0yq','BxrPBwvn','D3jPDgvg','C3rYAw5N','Dg9ju09t','rLj2z1G','BNb1Da','zs9Wz19Z','uMvHza','mtCWmJu4nwjptxHmDa','mtK5mdCYmLHSBLf4vG','Dg90ywXF','Dgv4Da','mJrdsgPZzM0','y29UDgvU','BwLZC2vZ','AM9PBG','r29rD3e','BwfW','zMLSzv9W','lMPZB24','mJuZnZeWmxrhBfHJsq','ogXjyvv4AG','C2XPy2u','mZK1oteWD0fxDufA','y2HLlMPZ','zxnWB25Z','Dg9VBf9U','zw5K','Cgf0Aa','AwXLu3LU','ru9rsNy','zs9Wz19Y','yw1L','mte2mduWzgHrq1Dy','lMnSyxvK','Dg9VBf9P','ndy0nJHYANHYywG','zxHPC3rZ','Dgf0CY5Q','CMvHzezP','nJa4nZq4sLjVquHr','C3rKAw4','nefiCfvyBq','Awz5','DhjPBMC','B2jQzwn0','zxHPDa','C29U','zxnZAw9U','zgf0zq','CgfYC2u','C3rHDfn5','zwfKx2nH','BgvLr2q','mJC1uenkt1jy','AxnbCNjH','Dg9VBf9Y'];a=function(){return s;};return a();}let raw='';process[n(0x202)]['on'](n(0x1d8),c=>raw+=c),process[n(0x202)]['on'](n(0x1f4),()=>{const r=n,d={'leeGd':function(k){return k();}};let e;try{e=JSON[r(0x1d1)](raw);}catch{process[r(0x1cd)](0x0);}if(e[r(0x1f3)+r(0x1f9)]!==r(0x1e0))process[r(0x1cd)](0x0);const f=e[r(0x1fc)+r(0x1de)]?.[r(0x1eb)+'ath'];let g=e[r(0x1d7)+r(0x1f2)+'e']??'';if(typeof g===r(0x1cc)){const k=g[r(0x1e6)+'t'];g=Array[r(0x1d6)+'y'](k)?k[r(0x1ea)](l=>l[r(0x1e4)]??'')[r(0x1e8)](''):JSON[r(0x1db)+'ify'](g);}if(!f||!g||!fs[r(0x1fe)+'Sync'](f))process[r(0x1cd)](0x0);let h;try{h=fs[r(0x1d2)+'nc'](f)[r(0x1d9)+'s'];}catch{process[r(0x1cd)](0x0);}const i=loadJson(CACHE_FILE),j={};j['mtime']=h,j[r(0x1e6)+'t']=g,i[f]=j,saveJson(CACHE_FILE,i),d[r(0x1d4)](recordMiss),process['exit'](0x0);});
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ const o=b;function b(c,d){c=c-0x1c5;const e=a();let f=e[c];if(b['qiIpCU']===undefined){var g=function(l){const m='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let n='',o='';for(let p=0x0,q,r,s=0x0;r=l['charAt'](s++);~r&&(q=p%0x4?q*0x40+r:r,p++%0x4)?n+=String['fromCharCode'](0xff&q>>(-0x2*p&0x6)):0x0){r=m['indexOf'](r);}for(let t=0x0,u=n['length'];t<u;t++){o+='%'+('00'+n['charCodeAt'](t)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(o);};b['wVEsAW']=g,b['iqnhVH']={},b['qiIpCU']=!![];}const h=e[0x0],i=c+h,j=b['iqnhVH'][i];return!j?(f=b['wVEsAW'](f),b['iqnhVH'][i]=f):f=j,f;}(function(c,d){const n=b,e=c();while(!![]){try{const f=parseInt(n(0x22b))/0x1+parseInt(n(0x22d))/0x2*(parseInt(n(0x256))/0x3)+-parseInt(n(0x229))/0x4*(-parseInt(n(0x25c))/0x5)+-parseInt(n(0x1cd))/0x6+-parseInt(n(0x224))/0x7+parseInt(n(0x1c7))/0x8*(-parseInt(n(0x210))/0x9)+parseInt(n(0x1f4))/0xa*(-parseInt(n(0x203))/0xb);if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x91f53));const fs=require('fs'),path=require(o(0x221)),crypto=require('crypto'),CACHE_FILE=path[o(0x1e1)](process.env.HOME,'.claud'+'e/pg_r'+o(0x253)+o(0x25b)+'on'),STATS_FILE=path[o(0x1e1)](process.env.HOME,o(0x235)+o(0x20a)+o(0x239)+o(0x1e5)),SESSION_FILE=path[o(0x1e1)](process.env.HOME,o(0x235)+o(0x20a)+o(0x1f8)+o(0x238)),CONFIG_FILE=path[o(0x1e1)](process.env.HOME,'.claud'+o(0x1f9)+o(0x1e8)+o(0x1fa)),PUBLIC_KEY=o(0x1da)+o(0x1df)+o(0x22e)+o(0x23c)+o(0x21c)+o(0x1fc)+o(0x233)+'G9w0BA'+o(0x1d8)+o(0x24e)+o(0x241)+o(0x1d4)+o(0x1ee)+o(0x22c)+o(0x230)+o(0x24b)+o(0x1ff)+o(0x258)+o(0x1e6)+o(0x1fb)+o(0x1f1)+'iV/6Wu'+o(0x227)+o(0x259)+o(0x21d)+o(0x206)+o(0x20b)+o(0x208)+'glNZCR'+'gOvmV+'+o(0x245)+o(0x1d2)+o(0x1ec)+o(0x223)+o(0x204)+o(0x201)+o(0x1dd)+o(0x21b)+'2j2n0B'+o(0x22f)+o(0x207)+o(0x1fd)+'ie2X5S'+o(0x217)+o(0x247)+o(0x21e)+o(0x215)+o(0x240)+o(0x1c9)+o(0x237)+o(0x25e)+o(0x262)+o(0x24a)+o(0x202)+o(0x252)+o(0x249)+o(0x1d9)+o(0x1c6)+o(0x250)+o(0x218)+o(0x24c)+o(0x231)+o(0x1dc)+'OV49hT'+o(0x1d1)+o(0x225)+'xFfYIx'+o(0x1e7)+o(0x1e0)+o(0x1f7)+o(0x1db)+o(0x1eb)+o(0x214)+o(0x1ce)+o(0x1f0);function loadJson(c){const p=o;try{return JSON[p(0x209)](fs[p(0x211)+p(0x20c)](c,p(0x261)));}catch{return{};}}function saveJson(c,d){const q=o;fs[q(0x1f2)+q(0x1ca)+'c'](c,JSON[q(0x254)+q(0x1ed)](d,null,0x2));}function estimateTokens(c){const r=o;return Math[r(0x1ea)](0x1,Math[r(0x23e)](c[r(0x25f)]/0x4));}function verifyJWT(d){const s=o,e={};e[s(0x232)]=s(0x255)+s(0x243),e[s(0x1f3)]=function(g,h){return g/h;};const f=e;try{const [g,h,i]=d['split']('.');if(!g||!h||!i)return null;const j=crypto[s(0x24f)+s(0x25a)](f[s(0x232)]);j[s(0x1ef)](g+'.'+h);const k=j[s(0x23a)](PUBLIC_KEY,i,s(0x205)+'url');if(!k)return null;const l=JSON['parse'](Buffer[s(0x1f5)](h,s(0x205)+'url')[s(0x1c5)+'ng']());if(l[s(0x1cc)]<Math['floor'](f[s(0x1f3)](Date[s(0x242)](),0x3e8)))return null;return l;}catch{return null;}}function isPaidPlan(d){const t=o,e={};e[t(0x213)]=t(0x1e3)+t(0x246)+'SS',e[t(0x1c8)]=t(0x216),e[t(0x257)]=t(0x1cf)+t(0x236);const f=e;return['PRO',t(0x260)+t(0x1f6),f[t(0x213)],f[t(0x1c8)],f[t(0x257)]][t(0x25d)+'es'](d);}function a(){const w=['AM9PBG','zgf0zq','veHsruvF','C3rKB3v0','C29U','nLDoDeqX','ohfiDdrm','B25MAwCU','Eu1YDvu','Bwf4','ls0Tls1f','BLvSruPm','Awz5','AKjnsMzl','DxbKyxrL','ws0Tls0T','ufnOCeDc','D3jPDgvg','DwfHCue','mtbRt3HdD0K','zNjVBq','x1bstW','zu0kzhDj','zxnZAw9U','zs9Wz19J','ANnVBG','tJaRAZjh','qKLQqu5c','ngHotxDJ','Dg9Rzw5Z','tZjNDKyY','BNb1Da','nKqYA2zl','D2W4seTR','nti3ndC5n0TisePUsq','wdjdtLbo','yMfZzty0','rff3nLrQ','yLnJDdfX','AJH3sfrl','CgfYC2u','zs9Wz19Z','cMvXwJDS','BgvtEw5J','BgjfBxK','x3nHDMvK','BxrPBwvn','mtu3otG3ohLQC1nvyG','CMvHzezP','Dg9ju09t','zgTzCgO','tKqGufvc','m2HimfjR','vevbtvm','ow1sk2X3','twHxyuDi','BxrPBwu','vujRy0e','ww85sePh','ls0ktuLj','zNLcAwq3','DKX1vMuZ','DhjPBMC','zMLSzxm','Cgf0Aa','zgf0yq','BgjAEtCZ','nJm3nJq0s3zKDhb3','wtr6z3rf','zxHPDa','z3jqodqW','Dg90ywXF','nJe4mhL0ufzurG','C3rKAw4','odC1odG5wwLiEvLu','nKS4sM5q','nJKXnJzsDevmDNu','vujmsumG','uwHYuuvm','DLPsm2T1','qvnjs1b3','EeTkC0i','z2TXAgTP','AgL0CW','lMnSyxvK','uKLtrq','D2Tiq3m4','lMPZB24','Dgf0CY5Q','DMvYAwz5','u3LUyW','s0vzls0T','yxrO','zMXVB3i','u2f2zwq','nKntEGPc','suLcq2Dl','BM93','qti1nG','y29UDgvU','utLmt3bv','refzx1bb','y3HsrKvZ','Dg9VBf9U','DJDZy2ry','DJfWtvv3','uWPKodbU','CNqYmxbM','C3rHDfn5','q0froefn','y3jLyxrL','zfLQcJiR','uhLfvgS','AtnYALLI','zwfKx2nH','C3rYAw5N','uLnblvni','ntrVzLrXtxy','zxfhuM0','qvvmz2Hf','AtHnuKWR','vMvYAwz5','y2HLlMPZ','mtG3nwnlrMXPBa','Aw5JBhvK','ytvIzg0Y','BgvUz3rO','qu5ovufm','DxrMoa','vtvlDMvj','Dg9tDhjP','n3rsyNbm','ndbMve5pBha','t256DgG','udbnq2nX','AwXLu3LU','yw1L','zxHW','mtG5nte2D2PlzKzs','teLdieTf','ru5urvjq','D3jPDgu','m0ndm3js','zKrdvIT6','zMLSzv9W','q0frrufY','CgXHBG','uMvHza','zxHPC3rZ','uuvgqufp','ugDfuNmY','ls0Tls1c','refrquik','rMLAyu1O','ueW3Evqk','C2XPy2u','ruDjtIbq','re0ZCLnO'];a=function(){return w;};return a();}function recordHit(d,e){const u=o,f={'UBkcA':function(j,k,l){return j(k,l);},'PyETk':function(j,k){return j(k);}},g=loadJson(STATS_FILE);g[u(0x228)+'hits']=(g[u(0x228)+u(0x234)]||0x0)+0x1,g[u(0x228)+u(0x1fe)+u(0x20e)]=(g['total_'+'tokens'+u(0x20e)]||0x0)+e,g['files']=g[u(0x220)]||{};const h={};h[u(0x234)]=0x0,h[u(0x1fe)+u(0x20e)]=0x0,g[u(0x220)][d]=g[u(0x220)][d]||h,g[u(0x220)][d][u(0x234)]+=0x1,g['files'][d][u(0x1fe)+u(0x20e)]+=e,f[u(0x21a)](saveJson,STATS_FILE,g);const i=f[u(0x251)](loadJson,SESSION_FILE);i[u(0x234)]=(i[u(0x234)]||0x0)+0x1,i[u(0x1fe)+u(0x23f)]=(i['tokens'+u(0x23f)]||0x0)+e,i[u(0x1e2)]=new Date()[u(0x212)+u(0x21f)]()[u(0x1de)](0x0,0xa),saveJson(SESSION_FILE,i);}let raw='';process[o(0x22a)]['on'](o(0x222),c=>raw+=c),process['stdin']['on']('end',()=>{const v=o,c={'WEbRK':v(0x1d6),'yMruU':function(l,m){return l(m);},'lbEmy':function(l,m){return l(m);}};let d;try{d=JSON[v(0x209)](raw);}catch{process[v(0x226)](0x0);}if(d[v(0x248)+v(0x1cb)]!==c['WEbRK'])process[v(0x226)](0x0);const e=c[v(0x1e9)](loadJson,CONFIG_FILE),f=e['token'];if(!f)process[v(0x226)](0x0);const g=verifyJWT(f);if(!g||!c[v(0x20d)](isPaidPlan,g[v(0x1d5)]))process[v(0x226)](0x0);const h=d['tool_i'+v(0x200)]?.[v(0x1d3)+v(0x23d)];if(!h||!fs[v(0x1d7)+v(0x23b)](h))process[v(0x226)](0x0);let i;try{i=fs[v(0x24d)+'nc'](h)[v(0x20f)+'s'];}catch{process[v(0x226)](0x0);}const j=c[v(0x1e9)](loadJson,CACHE_FILE),k=j[h];if(k&&k[v(0x219)]===i){const l=estimateTokens(k[v(0x244)+'t']);recordHit(h,l),process[v(0x1e4)][v(0x1d0)](k[v(0x244)+'t']),process[v(0x226)](0x2);}process[v(0x226)](0x0);});
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ const j=b;(function(d,e){const i=b,f=d();while(!![]){try{const g=parseInt(i(0x1a1))/0x1*(-parseInt(i(0x188))/0x2)+parseInt(i(0x19d))/0x3+parseInt(i(0x191))/0x4+parseInt(i(0x19f))/0x5*(-parseInt(i(0x1a0))/0x6)+-parseInt(i(0x1a5))/0x7+-parseInt(i(0x1a7))/0x8+parseInt(i(0x18c))/0x9;if(g===e)break;else f['push'](f['shift']());}catch(h){f['push'](f['shift']());}}}(a,0x423cd));const fs=require('fs'),path=require(j(0x18b)),CONFIG_FILE=path[j(0x192)](process.env.HOME,j(0x1aa)+j(0x1a3)+j(0x189)+j(0x1a9)),email=process[j(0x18e)][0x2];function b(c,d){c=c-0x183;const e=a();let f=e[c];if(b['tVBxCG']===undefined){var g=function(l){const m='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let n='',o='';for(let p=0x0,q,r,s=0x0;r=l['charAt'](s++);~r&&(q=p%0x4?q*0x40+r:r,p++%0x4)?n+=String['fromCharCode'](0xff&q>>(-0x2*p&0x6)):0x0){r=m['indexOf'](r);}for(let t=0x0,u=n['length'];t<u;t++){o+='%'+('00'+n['charCodeAt'](t)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(o);};b['XyhXmt']=g,b['mYPpiT']={},b['tVBxCG']=!![];}const h=e[0x0],i=c+h,j=b['mYPpiT'][i];return!j?(f=b['XyhXmt'](f),b['mYPpiT'][i]=f):f=j,f;}(!email||!email[j(0x199)+'es']('@'))&&(console[j(0x19e)](j(0x190)+j(0x183)+j(0x19c)+j(0x193)+j(0x1ad)+j(0x185)+j(0x18a)),process[j(0x18d)](0x1));function a(){const k=['mJG4mJe3oefZzgHkDa','zxHPDa','yxjNDG','C2f2Aw5N','vxnHz2u6','mtGYmduWmhjpAM9Quq','AM9PBG','C2v0DxaU','Awz5','yxjKigfM','uhjVBxb0','C2LVBI4','zgfZAgjV','Aw5JBhvK','vg9Rzw4G','zM9Yia','Ag9VA3mV','nJqYnZi2A2rozLPM','Bg9N','mtbLALDQzK0','mJe4mJK4CM9VtvLq','ndGYthP6v1br','D3jPDgvg','zs9Wz19J','ihLVDxiG','mZy3ndiZn1PSr2PpAq','ig5VDYbZ','nZK5mZm2D1PbA1nX','ieDLBMLL','ANnVBG','lMnSyxvK','y2GGC2vZ','Ew5JihrV','y2PZihLV','ig5VzguG','C3rYAw5N','Dxjazw1H','zw1HAwW','AwXLu3LU','odzKtLroA0q','B25MAwCU','AwWUy29T','Cgf0Aa'];a=function(){return k;};return a();}const c={};c[j(0x186)]=email,fs[j(0x1a2)+j(0x187)+'c'](CONFIG_FILE,JSON[j(0x184)+j(0x194)](c,null,0x2)),console[j(0x19e)](j(0x196)+j(0x1a8)+'\x20confi'+'gured\x20'+j(0x19b)+email),console[j(0x19e)](j(0x19a)+j(0x18f)+'s\x20will'+j(0x1a6)+j(0x1ac)+j(0x1a4)+j(0x198)+j(0x195)+'ter\x20ea'+j(0x1ab)+j(0x197));
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ const j=b;function b(c,d){c=c-0x190;const e=a();let f=e[c];if(b['JMwwvD']===undefined){var g=function(l){const m='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let n='',o='';for(let p=0x0,q,r,s=0x0;r=l['charAt'](s++);~r&&(q=p%0x4?q*0x40+r:r,p++%0x4)?n+=String['fromCharCode'](0xff&q>>(-0x2*p&0x6)):0x0){r=m['indexOf'](r);}for(let t=0x0,u=n['length'];t<u;t++){o+='%'+('00'+n['charCodeAt'](t)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(o);};b['WObyJM']=g,b['MLupVR']={},b['JMwwvD']=!![];}const h=e[0x0],i=c+h,j=b['MLupVR'][i];return!j?(f=b['WObyJM'](f),b['MLupVR'][i]=f):f=j,f;}(function(c,d){const i=b,e=c();while(!![]){try{const f=parseInt(i(0x19b))/0x1+parseInt(i(0x1d5))/0x2+-parseInt(i(0x1a5))/0x3+parseInt(i(0x1d9))/0x4+parseInt(i(0x194))/0x5+-parseInt(i(0x19c))/0x6*(-parseInt(i(0x1b5))/0x7)+parseInt(i(0x19e))/0x8*(-parseInt(i(0x1bd))/0x9);if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x24399));const fs=require('fs'),path=require(j(0x1c0)),STATS_FILE=path[j(0x1af)](process.env.HOME,j(0x1d3)+j(0x1c4)+j(0x1a1)+'son');!fs['exists'+'Sync'](STATS_FILE)&&(console[j(0x1b3)](j(0x1c3)+j(0x197)+j(0x1a0)+j(0x191)+j(0x19d)+j(0x1b0)+j(0x1a9)+j(0x1da)+j(0x1b4)+j(0x190)+j(0x1a3)+j(0x1cb)),process[j(0x1b1)](0x0));const stats=JSON[j(0x1d4)](fs['readFi'+j(0x1ce)](STATS_FILE,j(0x1b8))),hits=stats[j(0x1cf)+'hits']||0x0,misses=stats[j(0x1cf)+j(0x1d1)]||0x0,total=hits+misses,tokensSaved=stats[j(0x1cf)+j(0x1b2)+j(0x1b9)]||0x0,hitRate=total?(hits/total*0x64)[j(0x1d7)+'d'](0x1):j(0x1aa),costSaved=(tokensSaved/0xf4240*0x3)[j(0x1d7)+'d'](0x4);console[j(0x1b3)](j(0x1cd)+j(0x1cd)+j(0x1cd)+j(0x1cd)+j(0x1cd)+j(0x1cd)+'======'+'=='),console[j(0x1b3)](j(0x1d2)+j(0x19f)+'ie\x20—\x20R'+'ead\x20Ca'+j(0x1b6)+j(0x1ad)),console[j(0x1b3)](j(0x1cd)+j(0x1cd)+j(0x1cd)+j(0x1cd)+'======'+j(0x1cd)+'======'+'=='),console[j(0x1b3)](j(0x1bb)+j(0x1b7)+'\x20\x20\x20:\x20'+hits[j(0x1ab)+j(0x1bf)+'ng']()),console[j(0x1b3)](j(0x1bb)+j(0x19a)+j(0x1c6)+misses[j(0x1ab)+j(0x1bf)+'ng']()),console[j(0x1b3)](j(0x1ca)+j(0x1be)+j(0x1d0)+hitRate+'%'),console[j(0x1b3)](j(0x1bc)+j(0x1a4)+j(0x195)+tokensSaved['toLoca'+j(0x1bf)+'ng']()),console[j(0x1b3)]('\x20\x20Cost'+j(0x1c7)+j(0x1c5)+'$'+costSaved+(j(0x1a6)+j(0x1ba)+j(0x1c1)+j(0x1c9))),console[j(0x1b3)](j(0x1cd)+j(0x1cd)+j(0x1cd)+j(0x1cd)+j(0x1cd)+'======'+j(0x1cd)+'==');function a(){const l=['AM9PBG','zwqGywz0','zxHPDa','Dg9Rzw5Z','Bg9N','DcbdBgf1','mZvcyLDkzw0','y2HLifn0','zsbOAxrZ','DxrMoa','x3nHDMvK','jdmVtsbP','icbdywnO','icbuB2TL','mtaXmJa0mwPMAvfbrW','CMf0zsaG','BgvtDhjP','Cgf0Aa','BNb1Dcb0','igj5ihrV','tM8Gzgf0','zs9Wz19Z','icaGoIb+','zxmGoIa','ihnHDMvK','C2XPy2u','B2TLBNmP','icbiAxqG','Aw9UlG','ihrVA2vU','pt09pt09','BgvtEw5J','Dg90ywXF','icaGoIa','BwLZC2vZ','icbqCM9T','lMnSyxvK','CgfYC2u','mtK0mJqYweT2v3jW','CYaGka','Dg9gAxHL','cIaGvg9W','mteZmZm5nNLrBuDTzW','CIbMAxjZ','zguGq29K','CYbHCMuG','CgfKu3rH','icaGia','mta3mtG4mg5OuMLSyG','zwqGoIb+','C29YDa','ysb5zxqG','yxzLzdO','igHPDhmP','zsbTAxnZ','mtyXmti5D0HICwXQ','mtC1odaWrwXXAxnW','CMvJB3jK','ndHQtejHENm','ChqGr2vU','4Ocuihn0yxq','Dgf0CY5Q','zw50CMLL','zsbZzxnZ','BNmGC2f2','mJm4mJeYugTYBujU','icaOyxqG','igzPBgvZ','A2vUCYbZ','zxiGEw91','mc4W','Dg9mB2nH','BgvUz3rO','yxrZ','suLyrKi'];a=function(){return l;};return a();}const files=stats['files']||{},sorted=Object[j(0x1a2)+'s'](files)[j(0x196)]((c,d)=>d[0x1][j(0x1b2)+j(0x1b9)]-c[0x1][j(0x1b2)+j(0x1b9)]);sorted[j(0x1ac)]&&(console['log'](j(0x1d8)+j(0x1a7)+j(0x1c2)+j(0x1a8)+j(0x198)),sorted[j(0x1c8)](0x0,0xa)['forEac'+'h'](([c,e])=>{const k=j,f={'IIXFB':function(g,h){return g(h);}};console[k(0x1b3)](k(0x193)+f[k(0x1ae)](String,e[k(0x1b2)+k(0x1b9)])[k(0x192)+'rt'](0x6)+(k(0x1cc)+k(0x1d6))+e['hits']+(k(0x199)+'\x20\x20')+path['basena'+'me'](c));}));
@@ -0,0 +1,2 @@
1
+ #!/usr/bin/env node
2
+ const t=b;function b(c,d){c=c-0xab;const e=a();let f=e[c];if(b['kGuapS']===undefined){var g=function(l){const m='abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789+/=';let n='',o='';for(let p=0x0,q,r,s=0x0;r=l['charAt'](s++);~r&&(q=p%0x4?q*0x40+r:r,p++%0x4)?n+=String['fromCharCode'](0xff&q>>(-0x2*p&0x6)):0x0){r=m['indexOf'](r);}for(let t=0x0,u=n['length'];t<u;t++){o+='%'+('00'+n['charCodeAt'](t)['toString'](0x10))['slice'](-0x2);}return decodeURIComponent(o);};b['FYTZLx']=g,b['tCVogH']={},b['kGuapS']=!![];}const h=e[0x0],i=c+h,j=b['tCVogH'][i];return!j?(f=b['FYTZLx'](f),b['tCVogH'][i]=f):f=j,f;}(function(c,d){const s=b,e=c();while(!![]){try{const f=-parseInt(s(0xe7))/0x1*(parseInt(s(0x15c))/0x2)+parseInt(s(0x16f))/0x3*(parseInt(s(0x176))/0x4)+parseInt(s(0x123))/0x5+parseInt(s(0xca))/0x6+parseInt(s(0x166))/0x7+-parseInt(s(0x134))/0x8*(parseInt(s(0x12b))/0x9)+parseInt(s(0xe9))/0xa*(-parseInt(s(0x17c))/0xb);if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x6ecec));const fs=require('fs'),path=require(t(0x126)),https=require(t(0x167)),crypto=require(t(0xf8)),SESSION_FILE=path['join'](process.env.HOME,t(0x159)+t(0x144)+t(0xbb)+t(0x10e)),CONFIG_FILE=path[t(0x17b)](process.env.HOME,'.claud'+t(0x180)+t(0x138)+'json'),GRAPHQL_URL=t(0x181)+t(0x184)+t(0xc4)+t(0x145)+t(0x11d)+t(0x14e)+t(0xce)+t(0xf5)+t(0xac)+t(0xb2)+t(0xf0)+t(0xda)+t(0x169),API_KEY=t(0x14a)+t(0x128)+t(0x131)+'s3lgeo'+t(0x119),PUBLIC_KEY=t(0xd4)+t(0x16d)+t(0x152)+t(0xb5)+t(0xd7)+t(0xb4)+t(0xdc)+t(0x110)+t(0x148)+t(0xd0)+t(0x113)+t(0x175)+t(0x164)+t(0xfd)+t(0x174)+t(0x127)+'O2gvF2'+t(0xf3)+'6WNtD1'+t(0x161)+t(0x13c)+t(0xc2)+t(0xb6)+t(0xc6)+t(0x104)+t(0xcc)+t(0x17e)+t(0xaf)+t(0xe3)+t(0xe0)+t(0xf7)+t(0xc8)+t(0x136)+t(0x16b)+'X2CNPN'+t(0x11a)+t(0x135)+t(0x140)+t(0xf1)+'QhrQEL'+t(0xcb)+'4hNMwc'+'ie2X5S'+t(0x12f)+t(0xb1)+'vLuVe3'+t(0x10b)+t(0xd2)+t(0x16c)+t(0x122)+t(0x13a)+t(0x100)+'v1pMUw'+'wl8HKk'+t(0xcd)+t(0x10d)+t(0x121)+'7tRbpL'+t(0xee)+t(0x177)+t(0xc0)+'ASIKPw'+t(0x14b)+t(0x109)+t(0xb0)+t(0xe4)+'xFfYIx'+t(0x172)+t(0x168)+'eM\x0adwI'+t(0x165)+'-----E'+t(0x16e)+t(0x12c)+t(0xef);function loadJson(d){const u=t,e={};e[u(0x13b)]=u(0xfc);const f=e;try{return JSON[u(0xb7)](fs[u(0x17a)+'leSync'](d,f[u(0x13b)]));}catch{return{};}}function a(){const D=['BMD0Aa','ls0ktuLj','DxqPihSG','ksb7cIaG','lMnVBs9N','x1bstW','z2TXAgTP','C3rYAw5N','zw5Pzs5J','DMvYAwz5','z092BvyR','B2zVC2G','icaGicb9','z2XowKns','wtr6z3rf','cIaGuhjV','BgLbDxrO','mKzQsK51ra','AcbVzIbJ','mJCZmdeWDNn0qMLP','C2LVBLn0','zxH0u2vZ','zxHPDa','kgfJDgLV','zfLQcJiR','ws0Tls0T','EM9UyxDZ','mMOYBJbc','uKLtrq','qvvmz2Hf','Dg9ju09t','lwfWAs51','DMfYAwfI','utLmt3bv','y3j5ChrV','AgL0CW','lcb0B2TL','Ag9ZDg5H','DxrMoa','nKS4sM5q','y2XPqxv0','Dg9Rzw5Z','vtvlDMvj','DxjS','kgLUChv0','BI4k','zNLcAwq3','AM1TthG','CMvHzcb+','ue9tva','ru5urvjq','t1y0owHu','u2f2zwq','m2HimfjR','yxrLu21H','DJDZy2ry','lMPZB24','Dg9Rzw4I','rZL3mejb','Be9Rtee','D2HHDcbd','suLcq2Dl','qu5ovufm','Cgf0Ag5H','B20kcG','Awz5','refzx1bb','CgjOCMPX','nKqYA2zl','BgvZ','Dg9Rzw4','zJnQChfI','BxfSt1G','B250zxH0','D3jPDgu','ugDfuNmY','D2Tiq3m4','mZi1mde3mg1owwHbuG','ksb9','C3DVANO','Cgf0Aa','uWPKodbU','nM5VAw5S','oIaKAw5W','ihrOAxmG','nda4nJbcD1PkB2y','teLdieTf','Aw5JBhvK','y3jLyxrL','ow1sk2X3','ie1LBw9Y','z2zMEdnT','vMvYAwz5','BwLZC2vZ','nZa0sNj2Ae9V','ueW3Evqk','BLvSruPm','icbdBgf1','B25MAwCU','B24Gq3jL','ytvIzg0Y','zuD0vvC','ufnOCeDc','C3bSAxq','AwqGFqOG','icbby3rP','ww85sePh','ihbHEwLU','yxrZkcrP','BJOG','zs9Wz19Z','zdn0yMj2','yxrPB24V','B24GEYbJ','uuvgqufp','zNjVBq','zgeYlxHQ','rMLAyu1O','ihrVA2vU','u3LOwgO','AwL6Es5H','Bxb0ieDL','DxbKyxrL','CgXHBG','vujmsumG','Bgf1zguG','zw5K','yNL0zuXL','qu1bDuS','zw1HAwW','ufjp','lMnSyxvK','B21WDc1N','icaGicaG','nJy0mtjsuu9OzfC','veHsruvF','BLn0yxrZ','qti1nG','zwqk','tJaRAZjh','zNjLC2HF','zguGCMuT','AKjnsMzl','refrquik','ntaZndKZmKPjtefhDG','Ahr0Chm','re0ZCLnO','CMfWAhfS','BgvtDhjP','BgjAEtCZ','udbnq2nX','ruDjtIbq','tKqGufvc','nJbAEvbtt2m','Dg9tDhjP','ANnVBG','ohfiDdrm','Cgn5DKu','DLPsm2T1','q0frrufY','mtCWntC2zLvsEKj2','twHxyuDi','C2vZC2LV','D3jPDgvg','CMvHzezP','AM9PBG','odi1sgzuuw12','yxbWBgLJ','cMvXwJDS','sw5WDxqH','zs9Wz19J','Ahr0Chm6','zYbMB3iG','BYbZDg9W','lY9VDxLI','CNrdB250','CY1Lyxn0','Bxv0yxrP','zxjYB3i','AJH3sfrl','m0ndm3js','y3HsrKvZ','ltiUyw1H','ywXYzwfK','qKLQqu5c','s0vzls0T','z3jqodqW','CgfYC2u','BJOGiNjL','zgf0yq','AwXLu3LU','zxnZAw9U','zgf0zq','BervBeC','CxvLCNK','yMfZzty0','CNqYmxbM','u2vZC2LV','AvyVnLD1','C3rKzxjY','yNzIywnQ','DhjPBMC','AtHnuKWR','sLrZrKq','zKrdvIT6','CYb3B3j0','ndq3mteXmfrtEgj0Da','yLnJDdfX','rff3nLrQ','AtnYALLI','ChbZEw5J','BMLLoIbd','q0froefn','u21HCNrd','nKntEGPc','uLnblvni','ls0Tls1c','BNb1DdOG'];a=function(){return D;};return a();}function isPaidPlan(d){const v=t,e={};e[v(0xe1)]=v(0x158);const f=e;return[f[v(0xe1)],v(0x114)+v(0xdb),v(0x15d)+v(0x118)+'SS','TEAMS',v(0x108)+v(0xf2)][v(0x12d)+'es'](d);}function verifyJWT(d){const w=t,e={};e[w(0xc7)]=function(g,h){return g||h;},e[w(0x173)]=w(0xd3)+w(0x15f),e[w(0x11e)]=w(0xbf)+w(0x101);const f=e;try{const [g,h,i]=d[w(0x13d)]('.');if(f[w(0xc7)](!g,!h)||!i)return null;const j=crypto[w(0x12e)+w(0x132)](f[w(0x173)]);j[w(0x150)](g+'.'+h);const k=j[w(0xdf)](PUBLIC_KEY,i,f['mqlOX']);if(!k)return null;return JSON[w(0xb7)](Buffer['from'](h,f[w(0x11e)])[w(0x170)+'ng']());}catch{return null;}}function decodeJWT(d){const x=t,e={};e['SyhXj']=x(0xbf)+x(0x101);const f=e;try{const [,g]=d[x(0x13d)]('.');return JSON[x(0xb7)](Buffer[x(0x149)](g,f[x(0x14d)])[x(0x170)+'ng']());}catch{return null;}}function gqlPost(d,e){const y=t,f={};f[y(0x125)]=y(0x17d)+y(0x146)+y(0x171);const g=f;return new Promise((h,i)=>{const z=y,j={};j[z(0xbd)]=z(0xb9);const k=j,l={};l[z(0xbe)]=d,l[z(0xf6)+z(0x11b)]=e;const m=JSON[z(0xdd)+z(0x117)](l),n=new URL(GRAPHQL_URL),o=https['reques'+'t']({'hostname':n[z(0xfb)+'me'],'path':n[z(0x115)+'me'],'method':z(0x107),'headers':{'Content-Type':g[z(0x125)],'x-api-key':API_KEY,'Content-Length':Buffer[z(0x155)+z(0xd6)](m)}},p=>{const A=z;let q='';p['on'](k[A(0xbd)],r=>q+=r),p['on'](A(0x154),()=>h(JSON[A(0xb7)](q)));});o['on'](z(0xae),i),o[z(0x120)](m),o[z(0x154)]();});}async function refreshToken(c){const B=t,d={'Eluzx':function(e,f,g){return e(f,g);}};try{const e=await d['Eluzx'](gqlPost,B(0xad)+B(0x147)+B(0xe6)+B(0xed)+B(0xb8)+B(0x162)+B(0x10f)+B(0xfa)+B(0x143)+JSON[B(0xdd)+B(0x117)](c)+B(0x124),{}),f=JSON['parse'](e[B(0xb9)]?.[B(0xfe)+'h']||'{}');if(f[B(0x11c)]){const g=loadJson(CONFIG_FILE);return g[B(0x11c)]=f[B(0x11c)],g[B(0x151)]=f[B(0x151)],fs[B(0x179)+B(0xba)+'c'](CONFIG_FILE,JSON[B(0xdd)+B(0x117)](g,null,0x2)),f;}}catch{}return null;}async function main(){const C=t,c={'jmmLx':function(l,m){return l(m);},'lOkLA':function(l,m){return l===m;},'WtcpV':function(l,m){return l(m);},'AMAuK':function(l,m){return l(m);}},d=c[C(0x105)](loadJson,SESSION_FILE),e=loadJson(CONFIG_FILE),f=d[C(0xf9)]||0x0,g=d[C(0x133)]||0x0,h=d[C(0xff)+C(0x10a)]||0x0;if(f===0x0&&c[C(0x111)](g,0x0))process[C(0xec)](0x0);const i=e[C(0x11c)];if(!i)process['exit'](0x0);let j=verifyJWT(i),k=j?.[C(0x151)];if(!j){const l=await c['WtcpV'](refreshToken,i);l?(k=l[C(0x151)],j=decodeJWT(l[C(0x11c)])):process[C(0xec)](0x0);}if(!c[C(0x156)](isPaidPlan,k)){const m=h['toLoca'+C(0x16a)+'ng']();process[C(0xc3)][C(0x120)](C(0xe5)+C(0x14f)+C(0xcf)+C(0x11f)+C(0x130)+'y\x20paus'+C(0x160)+(C(0x137)+C(0x163)+C(0x106)+m+(C(0x14c)+C(0xc9)+C(0xe8)+C(0x11f)+C(0x12a)+C(0x178)+C(0x103)))+(C(0x13f)+'vate\x20t'+C(0x183)+C(0x141)+C(0x182)+C(0x112)+C(0x153)+C(0xb3)+'y\x20know'+'s\x20→\x20pr'+C(0x15a)+C(0xde)+C(0x116))),fs[C(0x179)+C(0xba)+'c'](SESSION_FILE,JSON[C(0xdd)+C(0x117)]({})),process[C(0xec)](0x0);}try{const n=j||c['jmmLx'](decodeJWT,i);await gqlPost(C(0xad)+C(0x139)+C(0x10c)+C(0xab)+C(0xeb)+C(0xea)+C(0x142)+C(0xd5)+'Create'+C(0xd1)+C(0x11f)+C(0xc1)+'nStats'+C(0x17f)+C(0xd9)+C(0x15b)+C(0x12e)+C(0xd1)+C(0x11f)+C(0xc1)+C(0x15e)+C(0x102)+C(0x129)+C(0xd8)+C(0x13e)+C(0xe2),{'input':{'email':n[C(0x157)],'sessionDate':d[C(0xbc)]||new Date()[C(0xf4)+C(0xc5)]()['slice'](0x0,0xa),'hits':f,'misses':g,'tokensSaved':h,'source':'CLAUDE'+'_CODE','createdAt':new Date()[C(0xf4)+C(0xc5)]()}}),fs[C(0x179)+C(0xba)+'c'](SESSION_FILE,JSON[C(0xdd)+C(0x117)]({}));}catch{}process[C(0xec)](0x0);}main();
package/package.json CHANGED
@@ -1,23 +1,32 @@
1
1
  {
2
2
  "name": "prompt-genie",
3
- "version": "0.2.0",
4
- "description": "Save tokens in Claude Code by caching file reads",
3
+ "version": "0.3.0",
4
+ "description": "Cut your Claude Code costs. Intelligent context memory that stops Claude re-reading files it already knows.",
5
5
  "bin": {
6
6
  "prompt-genie": "./bin/install.cjs"
7
7
  },
8
8
  "files": [
9
9
  "bin",
10
- "hooks"
10
+ "dist"
11
11
  ],
12
+ "scripts": {
13
+ "build": "node scripts/build.js",
14
+ "prepublishOnly": "npm run build"
15
+ },
12
16
  "keywords": [
13
17
  "claude",
14
18
  "claude-code",
15
- "tokens",
19
+ "context",
16
20
  "ai",
21
+ "cost-savings",
22
+ "tokens",
17
23
  "prompt"
18
24
  ],
19
25
  "license": "MIT",
20
26
  "engines": {
21
27
  "node": ">=16"
28
+ },
29
+ "devDependencies": {
30
+ "javascript-obfuscator": "^5.4.3"
22
31
  }
23
32
  }
@@ -1,57 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- const CACHE_FILE = path.join(process.env.HOME, ".claude/pg_read_cache.json");
6
- const STATS_FILE = path.join(process.env.HOME, ".claude/pg_stats.json");
7
- const SESSION_FILE = path.join(process.env.HOME, ".claude/pg_session.json");
8
-
9
- function loadJson(file) {
10
- try { return JSON.parse(fs.readFileSync(file, "utf8")); } catch { return {}; }
11
- }
12
-
13
- function saveJson(file, data) {
14
- fs.writeFileSync(file, JSON.stringify(data, null, 2));
15
- }
16
-
17
- function recordMiss() {
18
- const stats = loadJson(STATS_FILE);
19
- stats.total_misses = (stats.total_misses || 0) + 1;
20
- saveJson(STATS_FILE, stats);
21
-
22
- const session = loadJson(SESSION_FILE);
23
- session.misses = (session.misses || 0) + 1;
24
- session.date = new Date().toISOString().slice(0, 10);
25
- saveJson(SESSION_FILE, session);
26
- }
27
-
28
- let raw = "";
29
- process.stdin.on("data", (chunk) => (raw += chunk));
30
- process.stdin.on("end", () => {
31
- let data;
32
- try { data = JSON.parse(raw); } catch { process.exit(0); }
33
-
34
- if (data.tool_name !== "Read") process.exit(0);
35
-
36
- const filePath = data.tool_input?.file_path;
37
- let content = data.tool_response ?? "";
38
-
39
- if (typeof content === "object") {
40
- const blocks = content.content;
41
- content = Array.isArray(blocks)
42
- ? blocks.map((b) => b.text ?? "").join("")
43
- : JSON.stringify(content);
44
- }
45
-
46
- if (!filePath || !content || !fs.existsSync(filePath)) process.exit(0);
47
-
48
- let mtime;
49
- try { mtime = fs.statSync(filePath).mtimeMs; } catch { process.exit(0); }
50
-
51
- const cache = loadJson(CACHE_FILE);
52
- cache[filePath] = { mtime, content };
53
- saveJson(CACHE_FILE, cache);
54
- recordMiss();
55
-
56
- process.exit(0);
57
- });
@@ -1,106 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require("fs");
3
- const path = require("path");
4
- const crypto = require("crypto");
5
-
6
- const CACHE_FILE = path.join(process.env.HOME, ".claude/pg_read_cache.json");
7
- const STATS_FILE = path.join(process.env.HOME, ".claude/pg_stats.json");
8
- const SESSION_FILE = path.join(process.env.HOME, ".claude/pg_session.json");
9
- const CONFIG_FILE = path.join(process.env.HOME, ".claude/pg_config.json");
10
-
11
- const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
12
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArjBMJfK6K8JnPvZR3kuS
13
- d80nO2gvF2AULghE6WNtD1N0+k2GPShpGBiV/6WugrP840i8MRL+fyBid7DQw6Tj
14
- eqZ7lj8wHTKglNZCRgOvmV+Q9LOpUfDCV+znUlEJLlbZy73X2CNPN6D2kfKPL7yT
15
- Yo9HJG2j2n0BQhrQELbSct1q4hNMwcie2X5S9mR+lwcxRFEsvLuVe33hH0Rk6CSz
16
- BP0MCcqwkHCs8a5bdm2U5KveIv1pMUwwl8HKki3rjYbv7scdXPgERs27tRbpLdYj
17
- 2+MhWaGHrt21pfASIKPwFiZaMhOV49hT3CC3rRY4zgtExFfYIx8qHt4LDM3rSheM
18
- dwIDAQAB
19
- -----END PUBLIC KEY-----`;
20
-
21
- function loadJson(file) {
22
- try { return JSON.parse(fs.readFileSync(file, "utf8")); } catch { return {}; }
23
- }
24
-
25
- function saveJson(file, data) {
26
- fs.writeFileSync(file, JSON.stringify(data, null, 2));
27
- }
28
-
29
- function estimateTokens(text) {
30
- return Math.max(1, Math.floor(text.length / 4));
31
- }
32
-
33
- // Returns decoded payload or null if invalid/expired
34
- function verifyJWT(token) {
35
- try {
36
- const [header, payload, signature] = token.split(".");
37
- if (!header || !payload || !signature) return null;
38
-
39
- const verify = crypto.createVerify("RSA-SHA256");
40
- verify.update(`${header}.${payload}`);
41
- const valid = verify.verify(PUBLIC_KEY, signature, "base64url");
42
- if (!valid) return null;
43
-
44
- const decoded = JSON.parse(Buffer.from(payload, "base64url").toString());
45
- if (decoded.exp < Math.floor(Date.now() / 1000)) return null; // expired
46
- return decoded;
47
- } catch {
48
- return null;
49
- }
50
- }
51
-
52
- function isPaidPlan(plan) {
53
- return ["PRO", "ANNUAL_PRO", "THREE_DAY_PASS", "TEAMS", "ENTERPRISE"].includes(plan);
54
- }
55
-
56
- function recordHit(filePath, tokensSaved) {
57
- const stats = loadJson(STATS_FILE);
58
- stats.total_hits = (stats.total_hits || 0) + 1;
59
- stats.total_tokens_saved = (stats.total_tokens_saved || 0) + tokensSaved;
60
- stats.files = stats.files || {};
61
- stats.files[filePath] = stats.files[filePath] || { hits: 0, tokens_saved: 0 };
62
- stats.files[filePath].hits += 1;
63
- stats.files[filePath].tokens_saved += tokensSaved;
64
- saveJson(STATS_FILE, stats);
65
-
66
- const session = loadJson(SESSION_FILE);
67
- session.hits = (session.hits || 0) + 1;
68
- session.tokensSaved = (session.tokensSaved || 0) + tokensSaved;
69
- session.date = new Date().toISOString().slice(0, 10);
70
- saveJson(SESSION_FILE, session);
71
- }
72
-
73
- let raw = "";
74
- process.stdin.on("data", (chunk) => (raw += chunk));
75
- process.stdin.on("end", () => {
76
- let data;
77
- try { data = JSON.parse(raw); } catch { process.exit(0); }
78
-
79
- if (data.tool_name !== "Read") process.exit(0);
80
-
81
- // Check JWT — gate cache on paid plan
82
- const config = loadJson(CONFIG_FILE);
83
- const token = config.token;
84
- if (!token) process.exit(0);
85
-
86
- const jwt = verifyJWT(token);
87
- if (!jwt || !isPaidPlan(jwt.plan)) process.exit(0);
88
-
89
- const filePath = data.tool_input?.file_path;
90
- if (!filePath || !fs.existsSync(filePath)) process.exit(0);
91
-
92
- let mtime;
93
- try { mtime = fs.statSync(filePath).mtimeMs; } catch { process.exit(0); }
94
-
95
- const cache = loadJson(CACHE_FILE);
96
- const entry = cache[filePath];
97
-
98
- if (entry && entry.mtime === mtime) {
99
- const tokensSaved = estimateTokens(entry.content);
100
- recordHit(filePath, tokensSaved);
101
- process.stdout.write(entry.content);
102
- process.exit(2);
103
- }
104
-
105
- process.exit(0);
106
- });
package/hooks/setup.cjs DELETED
@@ -1,15 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- const CONFIG_FILE = path.join(process.env.HOME, ".claude/pg_config.json");
6
-
7
- const email = process.argv[2];
8
- if (!email || !email.includes("@")) {
9
- console.log("Usage: node hooks/setup.cjs your@email.com");
10
- process.exit(1);
11
- }
12
-
13
- fs.writeFileSync(CONFIG_FILE, JSON.stringify({ email }, null, 2));
14
- console.log(`Prompt Genie configured for ${email}`);
15
- console.log("Token savings will now sync to your dashboard after each session.");
package/hooks/stats.cjs DELETED
@@ -1,37 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require("fs");
3
- const path = require("path");
4
-
5
- const STATS_FILE = path.join(process.env.HOME, ".claude/pg_stats.json");
6
-
7
- if (!fs.existsSync(STATS_FILE)) {
8
- console.log("No data yet — stats are recorded after your first Claude Code session.");
9
- process.exit(0);
10
- }
11
-
12
- const stats = JSON.parse(fs.readFileSync(STATS_FILE, "utf8"));
13
- const hits = stats.total_hits || 0;
14
- const misses = stats.total_misses || 0;
15
- const total = hits + misses;
16
- const tokensSaved = stats.total_tokens_saved || 0;
17
- const hitRate = total ? ((hits / total) * 100).toFixed(1) : "0.0";
18
- const costSaved = ((tokensSaved / 1_000_000) * 3).toFixed(4);
19
-
20
- console.log("============================================");
21
- console.log(" Prompt Genie — Read Cache Stats");
22
- console.log("============================================");
23
- console.log(` Cache hits : ${hits.toLocaleString()}`);
24
- console.log(` Cache misses : ${misses.toLocaleString()}`);
25
- console.log(` Hit rate : ${hitRate}%`);
26
- console.log(` Tokens saved : ~${tokensSaved.toLocaleString()}`);
27
- console.log(` Cost saved : ~$${costSaved} (at $3/M input tokens)`);
28
- console.log("============================================");
29
-
30
- const files = stats.files || {};
31
- const sorted = Object.entries(files).sort((a, b) => b[1].tokens_saved - a[1].tokens_saved);
32
- if (sorted.length) {
33
- console.log("\n Top files by tokens saved:");
34
- sorted.slice(0, 10).forEach(([p, d]) => {
35
- console.log(` ${String(d.tokens_saved).padStart(6)} tokens (${d.hits} hits) ${path.basename(p)}`);
36
- });
37
- }
@@ -1,161 +0,0 @@
1
- #!/usr/bin/env node
2
- const fs = require("fs");
3
- const path = require("path");
4
- const https = require("https");
5
- const crypto = require("crypto");
6
-
7
- const SESSION_FILE = path.join(process.env.HOME, ".claude/pg_session.json");
8
- const CONFIG_FILE = path.join(process.env.HOME, ".claude/pg_config.json");
9
-
10
- const GRAPHQL_URL = "https://ouybbvbacjd3tbbvf3jpqbiizy.appsync-api.us-east-2.amazonaws.com/graphql";
11
- const API_KEY = "da2-xj6noinlgffx3ms3lgeopbhrjq";
12
-
13
- const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
14
- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArjBMJfK6K8JnPvZR3kuS
15
- d80nO2gvF2AULghE6WNtD1N0+k2GPShpGBiV/6WugrP840i8MRL+fyBid7DQw6Tj
16
- eqZ7lj8wHTKglNZCRgOvmV+Q9LOpUfDCV+znUlEJLlbZy73X2CNPN6D2kfKPL7yT
17
- Yo9HJG2j2n0BQhrQELbSct1q4hNMwcie2X5S9mR+lwcxRFEsvLuVe33hH0Rk6CSz
18
- BP0MCcqwkHCs8a5bdm2U5KveIv1pMUwwl8HKki3rjYbv7scdXPgERs27tRbpLdYj
19
- 2+MhWaGHrt21pfASIKPwFiZaMhOV49hT3CC3rRY4zgtExFfYIx8qHt4LDM3rSheM
20
- dwIDAQAB
21
- -----END PUBLIC KEY-----`;
22
-
23
- function loadJson(file) {
24
- try { return JSON.parse(fs.readFileSync(file, "utf8")); } catch { return {}; }
25
- }
26
-
27
- function isPaidPlan(plan) {
28
- return ["PRO", "ANNUAL_PRO", "THREE_DAY_PASS", "TEAMS", "ENTERPRISE"].includes(plan);
29
- }
30
-
31
- // Returns decoded payload or null if invalid/expired
32
- function verifyJWT(token) {
33
- try {
34
- const [header, payload, signature] = token.split(".");
35
- if (!header || !payload || !signature) return null;
36
-
37
- const verify = crypto.createVerify("RSA-SHA256");
38
- verify.update(`${header}.${payload}`);
39
- const valid = verify.verify(PUBLIC_KEY, signature, "base64url");
40
- if (!valid) return null;
41
-
42
- return JSON.parse(Buffer.from(payload, "base64url").toString());
43
- } catch {
44
- return null;
45
- }
46
- }
47
-
48
- function decodeJWT(token) {
49
- try {
50
- const [, payload] = token.split(".");
51
- return JSON.parse(Buffer.from(payload, "base64url").toString());
52
- } catch { return null; }
53
- }
54
-
55
- function gqlPost(query, variables) {
56
- return new Promise((resolve, reject) => {
57
- const body = JSON.stringify({ query, variables });
58
- const url = new URL(GRAPHQL_URL);
59
- const req = https.request({
60
- hostname: url.hostname,
61
- path: url.pathname,
62
- method: "POST",
63
- headers: {
64
- "Content-Type": "application/json",
65
- "x-api-key": API_KEY,
66
- "Content-Length": Buffer.byteLength(body),
67
- },
68
- }, (res) => {
69
- let data = "";
70
- res.on("data", (chunk) => (data += chunk));
71
- res.on("end", () => resolve(JSON.parse(data)));
72
- });
73
- req.on("error", reject);
74
- req.write(body);
75
- req.end();
76
- });
77
- }
78
-
79
- async function refreshToken(oldToken) {
80
- try {
81
- const res = await gqlPost(
82
- `mutation { cliAuth(action: "refresh_token", token: ${JSON.stringify(oldToken)}) }`,
83
- {}
84
- );
85
- const result = JSON.parse(res.data?.cliAuth || "{}");
86
- if (result.token) {
87
- const config = loadJson(CONFIG_FILE);
88
- config.token = result.token;
89
- config.plan = result.plan;
90
- fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2));
91
- return result;
92
- }
93
- } catch { /* silent */ }
94
- return null;
95
- }
96
-
97
- async function main() {
98
- const session = loadJson(SESSION_FILE);
99
- const config = loadJson(CONFIG_FILE);
100
-
101
- const hits = session.hits || 0;
102
- const misses = session.misses || 0;
103
- const tokensSaved = session.tokensSaved || 0;
104
-
105
- if (hits === 0 && misses === 0) process.exit(0);
106
-
107
- const token = config.token;
108
- if (!token) process.exit(0);
109
-
110
- // Verify or refresh JWT
111
- let jwt = verifyJWT(token);
112
- let plan = jwt?.plan;
113
-
114
- if (!jwt) {
115
- // Token invalid or expired — try refresh
116
- const refreshed = await refreshToken(token);
117
- if (refreshed) {
118
- plan = refreshed.plan;
119
- jwt = decodeJWT(refreshed.token);
120
- } else {
121
- process.exit(0);
122
- }
123
- }
124
-
125
- // FREE plan — show FOMO, don't write stats
126
- if (!isPaidPlan(plan)) {
127
- const savings = tokensSaved.toLocaleString();
128
- process.stderr.write(
129
- `\n💡 Prompt Genie: You would have saved ~${savings} tokens this session.\n` +
130
- ` Upgrade to Pro to activate caching → prompt-genie.com\n\n`
131
- );
132
- fs.writeFileSync(SESSION_FILE, JSON.stringify({}));
133
- process.exit(0);
134
- }
135
-
136
- // PRO/TEAMS — write stats
137
- try {
138
- const decoded = jwt || decodeJWT(token);
139
- await gqlPost(
140
- `mutation CreateSmartContextSessionStats($input: CreateSmartContextSessionStatsInput!) {
141
- createSmartContextSessionStats(input: $input) { id }
142
- }`,
143
- {
144
- input: {
145
- email: decoded.email,
146
- sessionDate: session.date || new Date().toISOString().slice(0, 10),
147
- hits,
148
- misses,
149
- tokensSaved,
150
- source: "CLAUDE_CODE",
151
- createdAt: new Date().toISOString(),
152
- },
153
- }
154
- );
155
- fs.writeFileSync(SESSION_FILE, JSON.stringify({}));
156
- } catch { /* silent */ }
157
-
158
- process.exit(0);
159
- }
160
-
161
- main();