prompt-genie 0.2.0 → 0.3.1
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 +88 -54
- package/dist/hooks/post_read.cjs +2 -0
- package/dist/hooks/pre_read.cjs +2 -0
- package/dist/hooks/setup.cjs +2 -0
- package/dist/hooks/stats.cjs +2 -0
- package/dist/hooks/stop_flush.cjs +2 -0
- package/package.json +13 -4
- package/hooks/post_read.cjs +0 -57
- package/hooks/pre_read.cjs +0 -106
- package/hooks/setup.cjs +0 -15
- package/hooks/stats.cjs +0 -37
- package/hooks/stop_flush.cjs +0 -161
package/bin/install.cjs
CHANGED
|
@@ -4,15 +4,26 @@ const path = require("path");
|
|
|
4
4
|
const os = require("os");
|
|
5
5
|
const https = require("https");
|
|
6
6
|
const readline = require("readline");
|
|
7
|
+
const crypto = require("crypto");
|
|
7
8
|
|
|
8
9
|
const HOOKS_DEST = path.join(os.homedir(), ".prompt-genie", "hooks");
|
|
9
10
|
const SETTINGS_FILE = path.join(os.homedir(), ".claude", "settings.json");
|
|
10
11
|
const CONFIG_FILE = path.join(os.homedir(), ".claude", "pg_config.json");
|
|
11
|
-
const HOOKS_SRC = path.join(__dirname, "..", "hooks");
|
|
12
|
+
const HOOKS_SRC = path.join(__dirname, "..", "dist", "hooks");
|
|
12
13
|
|
|
13
14
|
const GRAPHQL_URL = "https://ouybbvbacjd3tbbvf3jpqbiizy.appsync-api.us-east-2.amazonaws.com/graphql";
|
|
14
15
|
const API_KEY = "da2-xj6noinlgffx3ms3lgeopbhrjq";
|
|
15
16
|
|
|
17
|
+
const PUBLIC_KEY = `-----BEGIN PUBLIC KEY-----
|
|
18
|
+
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEArjBMJfK6K8JnPvZR3kuS
|
|
19
|
+
d80nO2gvF2AULghE6WNtD1N0+k2GPShpGBiV/6WugrP840i8MRL+fyBid7DQw6Tj
|
|
20
|
+
eqZ7lj8wHTKglNZCRgOvmV+Q9LOpUfDCV+znUlEJLlbZy73X2CNPN6D2kfKPL7yT
|
|
21
|
+
Yo9HJG2j2n0BQhrQELbSct1q4hNMwcie2X5S9mR+lwcxRFEsvLuVe33hH0Rk6CSz
|
|
22
|
+
BP0MCcqwkHCs8a5bdm2U5KveIv1pMUwwl8HKki3rjYbv7scdXPgERs27tRbpLdYj
|
|
23
|
+
2+MhWaGHrt21pfASIKPwFiZaMhOV49hT3CC3rRY4zgtExFfYIx8qHt4LDM3rSheM
|
|
24
|
+
dwIDAQAB
|
|
25
|
+
-----END PUBLIC KEY-----`;
|
|
26
|
+
|
|
16
27
|
function loadJson(file) {
|
|
17
28
|
try { return JSON.parse(fs.readFileSync(file, "utf8")); } catch { return {}; }
|
|
18
29
|
}
|
|
@@ -27,6 +38,19 @@ function ask(question) {
|
|
|
27
38
|
return new Promise((resolve) => rl.question(question, (ans) => { rl.close(); resolve(ans.trim()); }));
|
|
28
39
|
}
|
|
29
40
|
|
|
41
|
+
function verifyJWT(token) {
|
|
42
|
+
try {
|
|
43
|
+
const [header, payload, signature] = token.split(".");
|
|
44
|
+
if (!header || !payload || !signature) return null;
|
|
45
|
+
const verify = crypto.createVerify("RSA-SHA256");
|
|
46
|
+
verify.update(`${header}.${payload}`);
|
|
47
|
+
if (!verify.verify(PUBLIC_KEY, signature, "base64url")) return null;
|
|
48
|
+
const decoded = JSON.parse(Buffer.from(payload, "base64url").toString());
|
|
49
|
+
if (decoded.exp < Math.floor(Date.now() / 1000)) return null;
|
|
50
|
+
return decoded;
|
|
51
|
+
} catch { return null; }
|
|
52
|
+
}
|
|
53
|
+
|
|
30
54
|
function gqlPost(query) {
|
|
31
55
|
return new Promise((resolve, reject) => {
|
|
32
56
|
const body = JSON.stringify({ query });
|
|
@@ -63,39 +87,84 @@ function copyHooks() {
|
|
|
63
87
|
function wireHooks() {
|
|
64
88
|
const settings = loadJson(SETTINGS_FILE);
|
|
65
89
|
settings.hooks = settings.hooks || {};
|
|
66
|
-
|
|
67
90
|
settings.hooks.PreToolUse = [
|
|
68
|
-
{
|
|
69
|
-
matcher: "Read",
|
|
70
|
-
hooks: [{ type: "command", command: `node ${path.join(HOOKS_DEST, "pre_read.cjs")}` }],
|
|
71
|
-
},
|
|
91
|
+
{ matcher: "Read", hooks: [{ type: "command", command: `node ${path.join(HOOKS_DEST, "pre_read.cjs")}` }] },
|
|
72
92
|
];
|
|
73
93
|
settings.hooks.PostToolUse = [
|
|
74
|
-
{
|
|
75
|
-
matcher: "Read",
|
|
76
|
-
hooks: [{ type: "command", command: `node ${path.join(HOOKS_DEST, "post_read.cjs")}` }],
|
|
77
|
-
},
|
|
94
|
+
{ matcher: "Read", hooks: [{ type: "command", command: `node ${path.join(HOOKS_DEST, "post_read.cjs")}` }] },
|
|
78
95
|
];
|
|
79
96
|
settings.hooks.Stop = [
|
|
80
|
-
{
|
|
81
|
-
hooks: [{ type: "command", command: `node ${path.join(HOOKS_DEST, "stop_flush.cjs")}` }],
|
|
82
|
-
},
|
|
97
|
+
{ hooks: [{ type: "command", command: `node ${path.join(HOOKS_DEST, "stop_flush.cjs")}` }] },
|
|
83
98
|
];
|
|
84
|
-
|
|
85
99
|
saveJson(SETTINGS_FILE, settings);
|
|
86
100
|
}
|
|
87
101
|
|
|
102
|
+
function finishInstall(email, plan, token) {
|
|
103
|
+
copyHooks();
|
|
104
|
+
wireHooks();
|
|
105
|
+
saveJson(CONFIG_FILE, { email, plan, token });
|
|
106
|
+
|
|
107
|
+
const isPaid = ["PRO", "ANNUAL_PRO", "THREE_DAY_PASS", "TEAMS", "ENTERPRISE"].includes(plan);
|
|
108
|
+
if (isPaid) {
|
|
109
|
+
console.log(`
|
|
110
|
+
You're all set.
|
|
111
|
+
|
|
112
|
+
Prompt Genie is now active in Claude Code. Every file Claude reads
|
|
113
|
+
gets remembered for the session. No more paying to re-read
|
|
114
|
+
the same code on every turn.
|
|
115
|
+
|
|
116
|
+
Restart VS Code to activate, then start a session as normal.
|
|
117
|
+
Your context savings will appear at prompt-genie.com/dashboard.
|
|
118
|
+
`);
|
|
119
|
+
} else {
|
|
120
|
+
console.log(`
|
|
121
|
+
Installed.
|
|
122
|
+
|
|
123
|
+
You're on the Free plan. Prompt Genie is running but context
|
|
124
|
+
memory is paused. At the end of each session you'll see how much
|
|
125
|
+
you would have saved.
|
|
126
|
+
|
|
127
|
+
Activate context memory -> prompt-genie.com/pricing
|
|
128
|
+
`);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
|
|
88
132
|
async function main() {
|
|
89
|
-
console.log("\n Prompt Genie
|
|
133
|
+
console.log("\n Prompt Genie for Claude Code\n");
|
|
134
|
+
|
|
135
|
+
// Check for existing valid token — skip auth if still good
|
|
136
|
+
const existing = loadJson(CONFIG_FILE);
|
|
137
|
+
if (existing.token && existing.email) {
|
|
138
|
+
const jwt = verifyJWT(existing.token);
|
|
139
|
+
if (jwt) {
|
|
140
|
+
console.log(` Updating hooks for ${existing.email}...`);
|
|
141
|
+
finishInstall(existing.email, existing.plan, existing.token);
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Token expired — try a silent refresh before asking for email
|
|
146
|
+
console.log(" Refreshing session...");
|
|
147
|
+
try {
|
|
148
|
+
const res = await gqlPost(
|
|
149
|
+
`mutation { cliAuth(action: "refresh_token", token: ${JSON.stringify(existing.token)}) }`
|
|
150
|
+
);
|
|
151
|
+
const result = JSON.parse(res.data?.cliAuth || "{}");
|
|
152
|
+
if (result.success && result.token) {
|
|
153
|
+
finishInstall(existing.email, result.plan, result.token);
|
|
154
|
+
return;
|
|
155
|
+
}
|
|
156
|
+
} catch { /* fall through to full auth */ }
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
// Full auth flow (first install or refresh failed)
|
|
160
|
+
console.log(" Reduce what Claude re-reads every session.\n");
|
|
90
161
|
|
|
91
|
-
// Step 1: get email
|
|
92
162
|
const email = await ask(" Enter your Prompt Genie email: ");
|
|
93
163
|
if (!email || !email.includes("@")) {
|
|
94
164
|
console.error(" Invalid email. Run again with a valid address.");
|
|
95
165
|
process.exit(1);
|
|
96
166
|
}
|
|
97
167
|
|
|
98
|
-
// Step 2: send magic link
|
|
99
168
|
console.log("\n Sending verification code to " + email + "...");
|
|
100
169
|
try {
|
|
101
170
|
const res = await gqlPost(
|
|
@@ -103,7 +172,7 @@ async function main() {
|
|
|
103
172
|
);
|
|
104
173
|
const result = JSON.parse(res.data?.cliAuth || "{}");
|
|
105
174
|
if (!result.success) {
|
|
106
|
-
console.error(" Failed to send code.
|
|
175
|
+
console.error(" " + (result.error || "Failed to send code. Try again."));
|
|
107
176
|
process.exit(1);
|
|
108
177
|
}
|
|
109
178
|
} catch (err) {
|
|
@@ -111,7 +180,6 @@ async function main() {
|
|
|
111
180
|
process.exit(1);
|
|
112
181
|
}
|
|
113
182
|
|
|
114
|
-
// Step 3: ask for code
|
|
115
183
|
console.log(" Check your email for a 6-digit code.\n");
|
|
116
184
|
const code = await ask(" Enter code: ");
|
|
117
185
|
if (!code || code.length !== 6) {
|
|
@@ -119,9 +187,7 @@ async function main() {
|
|
|
119
187
|
process.exit(1);
|
|
120
188
|
}
|
|
121
189
|
|
|
122
|
-
// Step 4: verify code → get JWT
|
|
123
190
|
console.log("\n Verifying...");
|
|
124
|
-
let token, plan;
|
|
125
191
|
try {
|
|
126
192
|
const res = await gqlPost(
|
|
127
193
|
`mutation { cliAuth(action: "verify_magic_link", email: ${JSON.stringify(email)}, code: ${JSON.stringify(code)}) }`
|
|
@@ -131,43 +197,11 @@ async function main() {
|
|
|
131
197
|
console.error(" " + (result.error || "Verification failed. Try again."));
|
|
132
198
|
process.exit(1);
|
|
133
199
|
}
|
|
134
|
-
|
|
135
|
-
plan = result.plan;
|
|
200
|
+
finishInstall(email, result.plan, result.token);
|
|
136
201
|
} catch (err) {
|
|
137
202
|
console.error(" Network error:", err.message);
|
|
138
203
|
process.exit(1);
|
|
139
204
|
}
|
|
140
|
-
|
|
141
|
-
// Step 5: install
|
|
142
|
-
console.log(" Installing hooks...");
|
|
143
|
-
copyHooks();
|
|
144
|
-
|
|
145
|
-
console.log(" Wiring Claude Code settings...");
|
|
146
|
-
wireHooks();
|
|
147
|
-
|
|
148
|
-
console.log(" Saving config...");
|
|
149
|
-
saveJson(CONFIG_FILE, { email, plan, token });
|
|
150
|
-
|
|
151
|
-
// Step 6: result message based on plan
|
|
152
|
-
const isPaid = ["PRO", "ANNUAL_PRO", "THREE_DAY_PASS", "TEAMS", "ENTERPRISE"].includes(plan);
|
|
153
|
-
|
|
154
|
-
if (isPaid) {
|
|
155
|
-
console.log(`
|
|
156
|
-
✅ All done! Caching is active.
|
|
157
|
-
|
|
158
|
-
Restart VS Code to activate.
|
|
159
|
-
Your token savings will appear at prompt-genie.com after your first session.
|
|
160
|
-
`);
|
|
161
|
-
} else {
|
|
162
|
-
console.log(`
|
|
163
|
-
✅ Installed! You're on the Free plan.
|
|
164
|
-
|
|
165
|
-
Caching is disabled on Free — you'll see how many tokens you would have
|
|
166
|
-
saved at the end of each session.
|
|
167
|
-
|
|
168
|
-
Upgrade to Pro to activate → prompt-genie.com/pricing
|
|
169
|
-
`);
|
|
170
|
-
}
|
|
171
205
|
}
|
|
172
206
|
|
|
173
207
|
main().catch((err) => {
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
function a(){const u=['ovrmwLfkuW','zxnWB25Z','lMnSyxvK','BgvtEw5J','BxrPBwvn','mZjMzg5ys3u','ntKWndCWAufNsu1x','uhLir08','Dg9VBf9P','C2XPy2u','BwLZC2vZ','y29UDgvU','Dg9VBf9U','BxrPBwu','zs9Wz19Z','zMLSzv9W','C3rYAw5N','yxrO','C3rHDfn5','mZmXntC1m0XkDKTfBa','AM9PBG','zwfKx2nH','DhjPBMC','Cgf0Aa','B2jQzwn0','Awz5','CgfYC2u','Dg90ywXF','Dg9ju09t','mZeYodGYt2rnvgf2','odi2nda1zgXireXf','ndi0odLQvM5jDK4','uMvHza','AMTfAwC','mJq4ndjdB2fYAwu','CwXlufO','BNb1Da','CMvHzezP','D3jPDgvg','zxHPC3rZ','AxnbCNjH','C3rKAw4','ndm3mdi1D09Ir1bR','CxLqsKW','lMPZB24','Dgv4Da','zgf0yq','DxrMoa','ofjQyNLYqG','BwfW','Dg9VBf9Y','yw1L','zxHPDa','zxnZAw9U','zw5K','yLPJELa','C29U'];a=function(){return u;};return a();}const p=b;function b(c,d){c=c-0x1c8;const e=a();let f=e[c];if(b['yWdQKT']===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['bAIRVo']=g,b['bJvNDB']={},b['yWdQKT']=!![];}const h=e[0x0],i=c+h,j=b['bJvNDB'][i];return!j?(f=b['bAIRVo'](f),b['bJvNDB'][i]=f):f=j,f;}(function(c,d){const o=b,e=c();while(!![]){try{const f=parseInt(o(0x1cb))/0x1+parseInt(o(0x1fc))/0x2*(-parseInt(o(0x1da))/0x3)+-parseInt(o(0x1d1))/0x4*(-parseInt(o(0x1f8))/0x5)+-parseInt(o(0x1f7))/0x6+-parseInt(o(0x1ed))/0x7+-parseInt(o(0x1df))/0x8*(-parseInt(o(0x1f9))/0x9)+parseInt(o(0x1e0))/0xa;if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x44f3d));const fs=require('fs'),path=require(p(0x1f1)),CACHE_FILE=path[p(0x1ee)](process.env.HOME,'.claud'+'e/pg_r'+p(0x1ef)+'che.js'+'on'),STATS_FILE=path[p(0x1ee)](process.env.HOME,p(0x1dc)+p(0x1e8)+'tats.j'+p(0x1d9)),SESSION_FILE=path[p(0x1ee)](process.env.HOME,'.claud'+p(0x1e8)+p(0x1d6)+p(0x1cd));function loadJson(d){const q=p,e={};e[q(0x1fb)]=q(0x1d0);const f=e;try{return JSON[q(0x1f4)](fs[q(0x1ff)+q(0x1dd)](d,f['jkEig']));}catch{return{};}}function saveJson(c,d){const r=p;fs[r(0x200)+'ileSyn'+'c'](c,JSON[r(0x1ea)+r(0x1f3)](d,null,0x2));}function recordMiss(){const s=p,c={'PyHGO':function(f,g){return f(g);},'qlKPZ':function(f,g){return f+g;},'bZczP':function(f,g){return f+g;}},d=c[s(0x1e1)](loadJson,STATS_FILE);d[s(0x1f5)+s(0x1e4)]=c[s(0x1fd)](d[s(0x1f5)+s(0x1e4)]||0x0,0x1),saveJson(STATS_FILE,d);const e=loadJson(SESSION_FILE);e['misses']=c[s(0x1d8)](e[s(0x1e4)]||0x0,0x1),e['date']=new Date()[s(0x1f6)+s(0x1f0)]()[s(0x1e3)](0x0,0xa),saveJson(SESSION_FILE,e);}let raw='';process[p(0x1ca)]['on'](p(0x1cf),c=>raw+=c),process[p(0x1ca)]['on'](p(0x1d7),()=>{const t=p,e={};e[t(0x1cc)]=t(0x1fa);const f=e;let g;try{g=JSON[t(0x1f4)](raw);}catch{process[t(0x1d5)](0x0);}if(g[t(0x1e6)+t(0x1d4)]!==f[t(0x1cc)])process['exit'](0x0);const h=g[t(0x1e2)+t(0x1fe)]?.[t(0x1e9)+t(0x1eb)];let i=g[t(0x1d3)+t(0x1db)+'e']??'';if(typeof i===t(0x1f2)){const m=i[t(0x1e5)+'t'];i=Array[t(0x1c9)+'y'](m)?m[t(0x1d2)](n=>n[t(0x1ce)]??'')[t(0x1ee)](''):JSON[t(0x1ea)+t(0x1f3)](i);}if(!h||!i||!fs[t(0x1c8)+'Sync'](h))process[t(0x1d5)](0x0);let j;try{j=fs[t(0x1ec)+'nc'](h)[t(0x1de)+'s'];}catch{process[t(0x1d5)](0x0);}const k=loadJson(CACHE_FILE),l={};l[t(0x1e7)]=j,l[t(0x1e5)+'t']=i,k[h]=l,saveJson(CACHE_FILE,k),recordMiss(),process[t(0x1d5)](0x0);});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const o=b;(function(c,d){const n=b,e=c();while(!![]){try{const f=parseInt(n(0x10c))/0x1+-parseInt(n(0x14e))/0x2*(-parseInt(n(0x15a))/0x3)+parseInt(n(0x18a))/0x4+-parseInt(n(0x106))/0x5*(parseInt(n(0x12a))/0x6)+parseInt(n(0x14f))/0x7*(parseInt(n(0x123))/0x8)+parseInt(n(0x175))/0x9*(parseInt(n(0x126))/0xa)+-parseInt(n(0x154))/0xb*(parseInt(n(0x162))/0xc);if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x801e2));function a(){const w=['udbnq2nX','uWPKodbU','lMnSyxvK','qu5ovufm','zwfKx2nH','zfLQcJiR','mtiYotKWnfHQrLzuza','C2XPy2u','Dg9tDhjP','DMP4quG','zxHPDa','yLnJDdfX','DLPsm2T1','vwHpseC','DMvYAwz5','zgf0zq','zMXVB3i','y29UDgvU','ow1sk2X3','refrquik','BxrPBwvn','qvvmz2Hf','mJi5mJvcEMnKse8','AvyVnLD1','ruDjtIbq','Dg9VBf9P','ww85sePh','AM9PBG','ndeZmdjvD3vtEvK','lMPZB24','sMXWs0q','uMvHza','x1bstW','C3bSAxq','CgXHBG','zw5K','zu0kzhDj','EezMwuL4','AtnYALLI','ls0ktuLj','BNb1Da','vtvlDMvj','wfnUt00','ohfiDdrm','utLmt3bv','Dg9VBf9U','refzx1bb','C3rKB3v0','rZL3mejb','D3jPDgu','AwuYwdvt','mtG0otm2wLPewM1I','nKS4sM5q','ls0Tls1f','mJu5mJaZmgfqC3r6sW','suLcq2Dl','tKqGufvc','Cgf0Aa','ndi2yLDzDhze','rMLAyu1O','u2f2zwq','zs9Wz19J','uuvgqufp','ls0Tls1c','veHsruvF','BLvSruPm','D2Tiq3m4','BgvUz3rO','ru5urvjq','Dg9Rzw5Z','u3LUyW','uKLtrq','Dgf0CY5Q','C29U','Dg90ywXF','zs9Wz19Z','DJfWtvv3','C3rKAw4','DxjS','AKjnsMzl','ufnOCeDc','s0vzls0T','cMvXwJDS','y3j5ChrV','mMOYBJbc','zxHW','C3rYAw5N','CNqYmxbM','ALLbt3y','AJH3sfrl','z2TXAgTP','n3rsyNbm','x3nHDMvK','zMLSzxm','mZHzALzNuha','n0DkEejkvW','C3rHDfn5','nKntEGPc','DxrMoa','uKTOuvm','mJG0ovvtChD3CG','BxrPBwu','AtHnuKWR','AgL0CW','zxnZAw9U','teLdieTf','mJm4nZrluMrhzvq','nKqYA2zl','yurMEee','y2HLlMPZ','swLUs0S','zMLSzv9W','z092BvyR','BgvtEw5J','mJa4nJH0whb1ywe','vMvYAwz5','tZjNDKyY','BgjAEtCZ','CgfYC2u','zgf0yq','Awz5','CMvHzezP','q0froefn','yMfZzty0','qKLQqu5c','DKX1vMuZ','Dg9Rzw4','yxrO','ueW3Evqk','ytvIzg0Y','BM93','q0frrufY','yw1L','mJDRzxvvrKG','zNLcAwq3','tJaRAZjh','qu14y1u','Dg9ju09t','zKrdvIT6','Aw5JBhvK','uLnblvni','zNjVBq','z2XowKns','zs9Wz19Y','t1y0owHu','ufjp','B25MAwCU','D2W4seTR'];a=function(){return w;};return a();}const fs=require('fs'),path=require(o(0x129)),crypto=require(o(0x143)),CACHE_FILE=path[o(0x10b)](process.env.HOME,o(0x186)+o(0x17f)+o(0x188)+o(0x15d)+'on'),STATS_FILE=path[o(0x10b)](process.env.HOME,o(0x186)+o(0x13b)+o(0x138)+o(0x139)),SESSION_FILE=path[o(0x10b)](process.env.HOME,o(0x186)+o(0x13b)+o(0x158)+o(0x10d)),CONFIG_FILE=path[o(0x10b)](process.env.HOME,o(0x186)+o(0x12d)+o(0x182)+'json'),PUBLIC_KEY=o(0x12f)+o(0x108)+'UBLIC\x20'+o(0x141)+o(0x117)+o(0x16c)+o(0x14a)+o(0x120)+o(0x12e)+o(0x16a)+o(0x127)+o(0x173)+o(0x13f)+o(0x124)+o(0x190)+o(0x185)+o(0x164)+o(0x105)+'6WNtD1'+o(0x177)+o(0x140)+o(0x107)+'grP840'+o(0x156)+o(0x176)+'DQw6Tj'+o(0x142)+o(0x149)+o(0x17e)+o(0x160)+o(0x11c)+o(0x17a)+o(0x131)+o(0x165)+'X2CNPN'+o(0x15b)+o(0x170)+o(0x10a)+o(0x144)+'QhrQEL'+o(0x18f)+'4hNMwc'+o(0x122)+o(0x196)+'cxRFEs'+o(0x16d)+'3hH0Rk'+o(0x151)+o(0x184)+o(0x132)+o(0x171)+o(0x119)+o(0x13c)+o(0x183)+o(0x116)+'v7scdX'+'PgERs2'+o(0x14b)+o(0x189)+'MhWaGH'+o(0x147)+'ASIKPw'+o(0x12b)+o(0x180)+'3CC3rR'+'Y4zgtE'+o(0x115)+o(0x11b)+'DM3rSh'+o(0x114)+o(0x103)+o(0x125)+o(0x128)+o(0x159)+'Y-----';function loadJson(d){const p=o,e={};e['jYAOv']=p(0x152);const f=e;try{return JSON[p(0x166)](fs[p(0x169)+p(0x161)](d,f[p(0x148)]));}catch{return{};}}function saveJson(c,d){const q=o;fs['writeF'+'ileSyn'+'c'](c,JSON[q(0x146)+q(0x168)](d,null,0x2));}function estimateTokens(d){const r=o,e={};e[r(0x191)]=function(g,h){return g/h;};const f=e;return Math['max'](0x1,Math[r(0x194)](f['UhOHG'](d[r(0x133)],0x4)));}function b(c,d){c=c-0x103;const e=a();let f=e[c];if(b['xrCKUo']===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['lhcQGG']=g,b['WtbBZx']={},b['xrCKUo']=!![];}const h=e[0x0],i=c+h,j=b['WtbBZx'][i];return!j?(f=b['lhcQGG'](f),b['WtbBZx'][i]=f):f=j,f;}function verifyJWT(c){const s=o;try{const [d,e,f]=c[s(0x111)]('.');if(!d||!e||!f)return null;const g=crypto['create'+s(0x163)](s(0x17c)+'A256');g['update'](d+'.'+e);const h=g[s(0x192)](PUBLIC_KEY,f,s(0x16b)+'url');if(!h)return null;const i=JSON[s(0x166)](Buffer[s(0x17d)](e,s(0x16b)+s(0x13e))[s(0x18c)+'ng']());if(i[s(0x145)]<Math[s(0x194)](Date[s(0x172)]()/0x3e8))return null;return i;}catch{return null;}}function isPaidPlan(d){const t=o,e={};e['XSnOM']=t(0x187)+t(0x110),e[t(0x178)]=t(0x130)+t(0x11e)+'SS',e[t(0x18d)]=t(0x134)+t(0x137);const f=e;return[t(0x181),f[t(0x11a)],f[t(0x178)],'TEAMS',f[t(0x18d)]][t(0x17b)+'es'](d);}function recordHit(d,e){const u=o,f={'JlpKD':function(j,k){return j(k);},'RKhQS':function(j,k){return j+k;},'CCfEh':function(j,k,l){return j(k,l);}},g=f[u(0x10e)](loadJson,STATS_FILE);g[u(0x13a)+'hits']=f[u(0x153)](g[u(0x13a)+u(0x157)]||0x0,0x1),g[u(0x13a)+u(0x135)+u(0x14c)]=(g[u(0x13a)+u(0x135)+u(0x14c)]||0x0)+e,g[u(0x14d)]=g[u(0x14d)]||{};const h={};h[u(0x157)]=0x0,h[u(0x135)+u(0x14c)]=0x0,g[u(0x14d)][d]=g['files'][d]||h,g[u(0x14d)][d][u(0x157)]+=0x1,g[u(0x14d)][d][u(0x135)+u(0x14c)]+=e,f['CCfEh'](saveJson,STATS_FILE,g);const i=loadJson(SESSION_FILE);i[u(0x157)]=(i[u(0x157)]||0x0)+0x1,i[u(0x135)+u(0x12c)]=(i[u(0x135)+u(0x12c)]||0x0)+e,i[u(0x193)]=new Date()[u(0x179)+'tring']()[u(0x18b)](0x0,0xa),saveJson(SESSION_FILE,i);}let raw='';process[o(0x13d)]['on'](o(0x167),c=>raw+=c),process['stdin']['on'](o(0x113),()=>{const v=o,c={'IinKK':v(0x10f),'aDfxA':function(l,m){return l(m);}};let d;try{d=JSON[v(0x166)](raw);}catch{process[v(0x18e)](0x0);}if(d[v(0x11d)+v(0x174)]!==c[v(0x15e)])process[v(0x18e)](0x0);const e=c[v(0x15c)](loadJson,CONFIG_FILE),f=e[v(0x16e)];if(!f)process[v(0x18e)](0x0);const g=c[v(0x15c)](verifyJWT,f);if(!g||!c[v(0x15c)](isPaidPlan,g[v(0x112)]))process[v(0x18e)](0x0);const h=d[v(0x109)+v(0x118)]?.[v(0x15f)+v(0x16f)];if(!h||!fs['exists'+v(0x136)](h))process[v(0x18e)](0x0);let i;try{i=fs[v(0x150)+'nc'](h)[v(0x104)+'s'];}catch{process[v(0x18e)](0x0);}const j=loadJson(CACHE_FILE),k=j[h];if(k&&k[v(0x155)]===i){const l=estimateTokens(k[v(0x195)+'t']);recordHit(h,l),process[v(0x11f)][v(0x121)](k[v(0x195)+'t']),process['exit'](0x2);}process[v(0x18e)](0x0);});
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const j=b;function b(c,d){c=c-0x132;const e=a();let f=e[c];if(b['FEdUER']===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['BWALdL']=g,b['AULHYc']={},b['FEdUER']=!![];}const h=e[0x0],i=c+h,j=b['AULHYc'][i];return!j?(f=b['BWALdL'](f),b['AULHYc'][i]=f):f=j,f;}(function(d,e){const i=b,f=d();while(!![]){try{const g=-parseInt(i(0x141))/0x1+-parseInt(i(0x140))/0x2*(parseInt(i(0x146))/0x3)+parseInt(i(0x13f))/0x4*(parseInt(i(0x143))/0x5)+-parseInt(i(0x136))/0x6*(parseInt(i(0x15d))/0x7)+-parseInt(i(0x142))/0x8*(-parseInt(i(0x138))/0x9)+parseInt(i(0x15c))/0xa+parseInt(i(0x13e))/0xb;if(g===e)break;else f['push'](f['shift']());}catch(h){f['push'](f['shift']());}}}(a,0xd7973));function a(){const k=['ihLVDxiG','C2LVBI4','Dxjazw1H','ignVBMzP','Aw5JBhvK','mJeXnJK5mhzutMPdvW','otH5CvfuyxK','AwWUy29T','AM9PBG','DgvYigvH','zxHPDa','y2GGC2vZ','ndu3mJmWCvrmBhjd','uhjVBxb0','nti5mtu5nwrzs0POzW','B25MAwCU','yxjNDG','Cgf0Aa','C2v0DxaU','ANnVBG','ndG1otaZsLDOt25m','odqXnNjgChbUtG','mNP1tM5IyG','mte2mdu1ExzND3ne','mJrryKTxyKC','mJG3mhrjq0fXvG','zM9Yia','Ew5JihrV','mZq4ndm0n01hy0vmCG','C3rYAw5N','zw1HAwW','zgfZAgjV','lMnSyxvK','ieDLBMLL','Bg9N','ig5VzguG','vg9Rzw4G','Ag9VA3mV','vxnHz2u6','Awz5','zs9Wz19J','y2PZihLV','CYb3AwXS','AwXLu3LU','ig5VDYbZ'];a=function(){return k;};return a();}const fs=require('fs'),path=require(j(0x13b)),CONFIG_FILE=path[j(0x132)](process.env.HOME,j(0x14a)+j(0x152)+j(0x139)+j(0x13d)),email=process[j(0x13a)][0x2];(!email||!email[j(0x15b)+'es']('@'))&&(console[j(0x14c)](j(0x150)+j(0x14d)+j(0x14f)+j(0x13c)+j(0x153)+j(0x159)+j(0x15e)),process[j(0x134)](0x1));const c={};c[j(0x148)]=email,fs['writeF'+j(0x155)+'c'](CONFIG_FILE,JSON[j(0x147)+j(0x151)](c,null,0x2)),console[j(0x14c)](j(0x137)+j(0x14b)+j(0x15a)+'gured\x20'+j(0x144)+email),console[j(0x14c)](j(0x14e)+'saving'+j(0x154)+j(0x156)+j(0x145)+j(0x157)+j(0x149)+'ard\x20af'+j(0x133)+j(0x135)+j(0x158));
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const i=b;(function(c,d){const h=b,e=c();while(!![]){try{const f=parseInt(h(0xff))/0x1*(parseInt(h(0xf0))/0x2)+-parseInt(h(0x116))/0x3+-parseInt(h(0xfc))/0x4*(parseInt(h(0xed))/0x5)+-parseInt(h(0xf8))/0x6*(parseInt(h(0xea))/0x7)+parseInt(h(0x10a))/0x8+parseInt(h(0x108))/0x9*(parseInt(h(0xdf))/0xa)+-parseInt(h(0xd5))/0xb*(parseInt(h(0x102))/0xc);if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0x5b599));function a(){const k=['mKr6uLD4sG','jdmVtsbP','icbqCM9T','icaGia','x3nHDMvK','CMvHzezP','zwqGoIb+','zwfKienH','nta0nKLHz1ndBG','Dg9gAxHL','C29YDa','yxzLzdO','offPuLnJra','CYaGka','C29U','ndu5nJq3s3rSr0vv','u3LUyW','CMf0zsaG','mtjVsw9Nq2q','igzPBgvZ','BgvUz3rO','Dgf0CY5Q','BgvtEw5J','zguGq29K','ntrduxrqwMi','AM9PBG','ntiXoteYogjdsfPLtW','igj5ihrV','zxHPDa','A2vUCYbZ','BgvtDhjP','zwqGywz0','BwLZC2vZ','B2TLBNmP','CgfKu3rH','tM8Gzgf0','CYbHCMuG','yxrZ','mtq4nZC0mKHpu0Xvsq','Aw9UlG','zM9YrwfJ','pt09pt09','icaOyxqG','zsbTAxnZ','Cgf0Aa','zsbOAxrZ','icaGoIb+','Dg90ywXF','DxrMoa','zsbZzxnZ','zxmGoIa','CIbMAxjZ','zMLSzxm','CMvJB3jK','ntmYnJq1m0D0wg9krG','Dg9Rzw5Z','BNmGC2f2','AgL0CW','icaGoIa','lMnSyxvK','zxiGEw91','yMfZzw5H','BNb1Dcb0','CgfYC2u','ntKZodmWDhPty1Po','Dg9mB2nH','icbdB3n0','C2XPy2u','igHPDhmP','Bg9N','AwuG4Ocuifi','mc4W','ihrVA2vU','ihnHDMvK','DcbdBgf1','ntzAAwnbreq','4Ocuihn0yxq','zw50CMLL','mJy4mJu1AKXrqKjl','icbdywnO','cIaGvg9W'];a=function(){return k;};return a();}const fs=require('fs'),path=require(i(0x11c)),STATS_FILE=path[i(0x109)](process.env.HOME,i(0xda)+'e/pg_s'+i(0x105)+i(0xfe));!fs['exists'+i(0x100)](STATS_FILE)&&(console['log'](i(0x113)+'a\x20yet\x20'+i(0xeb)+i(0x114)+i(0xd4)+i(0x10f)+i(0xdb)+i(0xd2)+i(0xe9)+i(0x107)+i(0xd0)+i(0x117)),process[i(0x10c)](0x0));const stats=JSON[i(0xde)](fs[i(0xf5)+i(0x106)](STATS_FILE,i(0xcf))),hits=stats[i(0xce)+i(0xd8)]||0x0,misses=stats[i(0xce)+i(0x110)]||0x0,total=hits+misses,tokensSaved=stats[i(0xce)+i(0xd6)+i(0xf4)]||0x0,hitRate=total?(hits/total*0x64)[i(0xf9)+'d'](0x1):i(0xe6),costSaved=(tokensSaved/0xf4240*0x3)[i(0xf9)+'d'](0x4);console[i(0xe4)]('======'+i(0x119)+i(0x119)+i(0x119)+i(0x119)+i(0x119)+i(0x119)+'=='),console[i(0xe4)](i(0xf2)+'pt\x20Gen'+i(0xe5)+i(0xf7)+'che\x20St'+i(0x115)),console[i(0xe4)](i(0x119)+i(0x119)+i(0x119)+'======'+i(0x119)+i(0x119)+i(0x119)+'=='),console[i(0xe4)](i(0xee)+i(0x11d)+i(0xd9)+hits[i(0xe0)+i(0x10e)+'ng']()),console[i(0xe4)](i(0xee)+i(0x11b)+i(0xd1)+misses[i(0xe0)+'leStri'+'ng']()),console[i(0xe4)]('\x20\x20Hit\x20'+i(0x101)+i(0xd9)+hitRate+'%'),console[i(0xe4)]('\x20\x20Toke'+i(0xd7)+i(0xf6)+tokensSaved[i(0xe0)+'leStri'+'ng']()),console[i(0xe4)](i(0xe1)+i(0xe8)+i(0x11e)+'$'+costSaved+(i(0x11a)+i(0xf1)+i(0xdd)+i(0x111))),console[i(0xe4)](i(0x119)+i(0x119)+i(0x119)+'======'+i(0x119)+i(0x119)+i(0x119)+'==');const files=stats[i(0xd3)]||{},sorted=Object[i(0xec)+'s'](files)[i(0xfa)]((c,d)=>d[0x1][i(0xd6)+i(0xf4)]-c[0x1][i(0xd6)+'_saved']);function b(c,d){c=c-0xce;const e=a();let f=e[c];if(b['ewTxnQ']===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['JQpnrn']=g,b['KDeZDt']={},b['ewTxnQ']=!![];}const h=e[0x0],i=c+h,j=b['KDeZDt'][i];return!j?(f=b['JQpnrn'](f),b['KDeZDt'][i]=f):f=j,f;}sorted[i(0x104)]&&(console[i(0xe4)](i(0xef)+i(0x103)+i(0x10b)+i(0x10d)+i(0xfb)),sorted[i(0xe2)](0x0,0xa)[i(0x118)+'h'](([c,e])=>{const j=i;console[j(0xe4)](j(0xf3)+String(e['tokens'+j(0xf4)])[j(0x112)+'rt'](0x6)+(j(0xe7)+j(0xfd))+e[j(0xd8)]+(j(0xe3)+'\x20\x20')+path[j(0xdc)+'me'](c));}));
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
const t=b;function b(c,d){c=c-0x163;const e=a();let f=e[c];if(b['GhONOh']===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['MMPFMd']=g,b['XRjibN']={},b['GhONOh']=!![];}const h=e[0x0],i=c+h,j=b['XRjibN'][i];return!j?(f=b['MMPFMd'](f),b['XRjibN'][i]=f):f=j,f;}(function(c,d){const s=b,e=c();while(!![]){try{const f=-parseInt(s(0x1e1))/0x1+parseInt(s(0x1d5))/0x2*(-parseInt(s(0x1dc))/0x3)+parseInt(s(0x238))/0x4*(parseInt(s(0x219))/0x5)+-parseInt(s(0x187))/0x6*(parseInt(s(0x1d0))/0x7)+-parseInt(s(0x233))/0x8+-parseInt(s(0x178))/0x9+-parseInt(s(0x1f6))/0xa*(-parseInt(s(0x1a2))/0xb);if(f===d)break;else e['push'](e['shift']());}catch(g){e['push'](e['shift']());}}}(a,0xbaa8a));const fs=require('fs'),path=require(t(0x1e0)),https=require(t(0x224)),crypto=require(t(0x195)),SESSION_FILE=path[t(0x225)](process.env.HOME,t(0x209)+'e/pg_s'+t(0x1c1)+t(0x1ed)),CONFIG_FILE=path[t(0x225)](process.env.HOME,'.claud'+t(0x198)+t(0x215)+t(0x1e3)),GRAPHQL_URL=t(0x1a8)+'//ouyb'+t(0x22d)+t(0x216)+t(0x19d)+'iizy.a'+t(0x18f)+'-api.u'+t(0x185)+t(0x1b6)+'zonaws'+t(0x1c4)+'raphql',API_KEY=t(0x170)+'6noinl'+t(0x172)+t(0x228)+t(0x1fa),PUBLIC_KEY=t(0x173)+t(0x1d1)+t(0x1fd)+t(0x1bd)+t(0x1f9)+t(0x22b)+t(0x220)+t(0x1b7)+t(0x21a)+t(0x20d)+t(0x202)+'CAQEAr'+t(0x1ae)+t(0x1cb)+t(0x1db)+t(0x1c5)+t(0x1a7)+t(0x1cd)+t(0x230)+t(0x1ff)+t(0x22e)+t(0x205)+t(0x211)+t(0x19c)+'fyBid7'+t(0x16e)+'\x0aeqZ7l'+t(0x1b0)+t(0x17f)+t(0x210)+t(0x22a)+t(0x1b9)+t(0x192)+t(0x18a)+t(0x183)+t(0x165)+t(0x1f2)+t(0x16a)+t(0x1e2)+t(0x16d)+t(0x212)+'4hNMwc'+'ie2X5S'+t(0x181)+t(0x19e)+t(0x1c9)+'3hH0Rk'+'6CSz\x0aB'+t(0x19f)+t(0x237)+t(0x1ce)+'U5KveI'+t(0x1e5)+t(0x21f)+t(0x1fe)+'v7scdX'+'PgERs2'+t(0x1a0)+t(0x204)+t(0x17b)+t(0x213)+t(0x184)+t(0x186)+t(0x1e8)+'3CC3rR'+t(0x1fc)+t(0x227)+t(0x199)+t(0x18e)+t(0x223)+t(0x222)+t(0x206)+t(0x197)+t(0x1e6)+t(0x174);function loadJson(c){const u=t;try{return JSON[u(0x1aa)](fs[u(0x20c)+u(0x166)](c,u(0x20e)));}catch{return{};}}function isPaidPlan(d){const v=t,e={};e[v(0x208)]=v(0x203)+'_PRO',e[v(0x232)]=v(0x21e)+v(0x180)+'SS',e[v(0x1ea)]=v(0x1ec),e['ElGYq']=v(0x19b)+v(0x177);const f=e;return[v(0x1e4),f[v(0x208)],f[v(0x232)],f[v(0x1ea)],f[v(0x18b)]][v(0x1a3)+'es'](d);}function a(){const D=['zxHPDa','tKqGufvc','zs9Wz19J','ohfiDdrm','ChbMDuG','ru5urvjq','AtHnuKWR','zJnQChfI','y3HsrKvZ','udbnq2nX','n3rsyNbm','Cgf0Ag5H','mJe5otaXA2Dsuhfr','Aw5JBhvK','BwLZC2vZ','qti1nG','oIaKAw5W','tZjNDKyY','Ahr0Chm6','BLn0yxrZ','CgfYC2u','zNjLC2HF','B24GEYbJ','zxjYB3i','AKjnsMzl','Eunorfm','AJH3sfrl','C2XPy2u','EsbRBM93','BJOGiNjL','yxrLu21H','uvz3CeG','ltiUyw1H','rZL3mejb','D3jPDgvg','zKrdvIT6','B250zxH0','BMD0Aa','DMfYAwfI','s0vzls0T','yMfZzty0','uLnblvni','CMvXDwvZ','zxnZAw9U','Ee9gDuW','DMvYAwz5','lMnVBs9N','uWPKodbU','zxH0u2vZ','q3jLyxrL','x0npreu','DKX1vMuZ','AgL0CW','nKS4sM5q','AwqGFqOG','qvvmz2Hf','ytvIzg0Y','sw5WDxqH','mJG4mteWmLDXsxnZtq','ruDjtIbq','icbby3rP','lcb0B2TL','zw5Pzs5J','mJe5nZe5meThrurbwq','Bxv0yxrP','kgLUChv0','ksb7cIaG','kgfJDgLV','Dg9tDhjP','DLPsm2T1','m21iEvDLrW','ksb9','ihbHEwLU','yxbWBgLJ','Cgf0Aa','nte2odmXEefmuwDU','mMOYBJbc','ANnVBG','ufjp','DJfWtvv3','teLdieTf','DxqPihSG','t1y0owHu','ue9tva','C0vyBMi','q0Xbvurf','vevbtvm','lMPZB24','C3bSAxq','icaGicb9','CgXHBG','B3blqKC','ueW3Evqk','wMjUsK4','C3rKzxjY','BgvZ','mtKXmgTnqKTdsq','Awz5','t3PKyve','ls0ktuLj','CgjOCMPX','zguGCMuT','wtr6z3rf','vujmsumG','AtnYALLI','tJaRAZjh','CMvHzcb+','C3rYAw5N','suLcq2Dl','qu5ovufm','zfLQcJiR','AvyVnLD1','ls0Tls1f','BgvtDhjP','vw1yzfG','lMnSyxvK','Dg9Rzw4','ie1LBw9Y','CMvHzezP','q0froefn','DxrMoa','DhjPBMC','z092BvyR','z3jqodqW','yLnJDdfX','CNqYmxbM','EsbWyxvZ','B25MAwCU','zdn0yMj2','ywXYzwfK','C2LVBLn0','mtGYotq1yuXYqvPn','uuvgqufp','zgf0zq','zgf0yq','Dg9Rzw4I','veHsruvF','D2W4seTR','z2TXAgTP','CvDYte0','refrquik','zu0kzhDj','Ahr0Chm','AM9PBG','AwXLu3LU','EezMwuL4','CZnSz2vV','ihrOAxmG','utLmt3bv','qKLQqu5c','zNjWvvq','yNzIywnQ','ufnOCeDc','BYbZDg9W','nLDoDeqX','icbdBgf1','vMzMBeW','mte3nJuWnZjjsNvVBeu','Dg9mB2nH','DxjS','y3jLyxrL','D2Tiq3m4','mtq0sg5Quwj5','tNDYDu0','y2XPqxv0','yxrZkcrP','nKqYA2zl','BgvtEw5J','u21HCNrd','BMLLoIbd','B21WDc1N','ww85sePh','tMjjAKS','Bxb0ieDL','uwHYuuvm','rff3nLrQ','cIaGuhjV','zgeYlxHQ','BI4k','z2zMEdnT','ls0Tls1c','ws0Tls0T','C2vZC2LV','BJOG','uKLtrq','nduXmde3EuXYuKfq','vMvYAwz5','D3jPDgu','twHxyuDi','CxvLCNK','BgLbDxrO','Bgf1zguG','z2XowKns','refzx1bb','ow1sk2X3','zNjVBq','wdjdtLbo','qvnjs1b3','CY1Lyxn0','rMLAyu1O','mtH2vKnrDLa','Ag9ZDg5H','u2f2zwq','BgjAEtCZ','rwXhwxe','Chv3Ce4','CNrdB250','re0ZCLnO','ChbZEw5J','sxz6tM4','u2vZC2LV','BLvSruPm','zw5K','icaGicaG','y3j5ChrV'];a=function(){return D;};return a();}function verifyJWT(d){const w=t,e={};e[w(0x1b5)]=w(0x1bf)+w(0x1a5);const f=e;try{const [g,h,i]=d['split']('.');if(!g||!h||!i)return null;const j=crypto[w(0x236)+w(0x179)](f['QVwpH']);j['update'](g+'.'+h);const k=j[w(0x1c3)](PUBLIC_KEY,i,w(0x1be)+w(0x235));if(!k)return null;return JSON[w(0x1aa)](Buffer[w(0x182)](h,w(0x1be)+w(0x235))[w(0x1da)+'ng']());}catch{return null;}}function decodeJWT(c){const x=t;try{const [,d]=c[x(0x1ee)]('.');return JSON['parse'](Buffer[x(0x182)](d,x(0x1be)+x(0x235))[x(0x1da)+'ng']());}catch{return null;}}function gqlPost(d,e){const y=t,f={};f[y(0x1f1)]='data',f[y(0x1f3)]=y(0x193),f['yCNDS']=y(0x1e9);const g=f;return new Promise((h,i)=>{const z=y,j={};j[z(0x1f8)]=g[z(0x1f1)],j[z(0x19a)]=g[z(0x1f3)];const k=j,l={};l[z(0x17c)]=d,l[z(0x1bc)+z(0x1f5)]=e;const m=JSON[z(0x201)+'ify'](l),n=new URL(GRAPHQL_URL),o=https[z(0x1c0)+'t']({'hostname':n[z(0x188)+'me'],'path':n[z(0x1a1)+'me'],'method':g[z(0x1af)],'headers':{'Content-Type':z(0x1df)+'ation/'+z(0x1e3),'x-api-key':API_KEY,'Content-Length':Buffer['byteLe'+z(0x1bb)](m)}},p=>{const A=z;let q='';p['on'](k[A(0x1f8)],r=>q+=r),p['on'](k[A(0x19a)],()=>h(JSON[A(0x1aa)](q)));});o['on'](z(0x1ad),i),o[z(0x17a)](m),o[z(0x193)]();});}async function refreshToken(c){const B=t,d={'frpUT':function(e,f,g){return e(f,g);}};try{const e=await d[B(0x22c)](gqlPost,B(0x1d6)+B(0x1ac)+B(0x17d)+B(0x1d9)+B(0x1b3)+B(0x1ab)+B(0x21d)+B(0x1d3)+B(0x176)+JSON[B(0x201)+'ify'](c)+B(0x1dd),{}),f=JSON['parse'](e[B(0x21c)]?.[B(0x163)+'h']||'{}');if(f[B(0x20a)]){const g=loadJson(CONFIG_FILE);return g[B(0x20a)]=f['token'],g[B(0x1f0)]=f[B(0x1f0)],fs[B(0x1b8)+B(0x226)+'c'](CONFIG_FILE,JSON[B(0x201)+B(0x1f7)](g,null,0x2)),f;}}catch{}return null;}async function main(){const C=t,c={'xOFuL':function(l,m){return l===m;},'NwruM':function(l,m){return l===m;},'qWrLM':function(l,m){return l(m);},'NbIjK':function(l,m){return l+m;},'IvzNn':function(l,m,n){return l(m,n);},'puwpN':C(0x1eb)+C(0x1c8)},d=loadJson(SESSION_FILE),e=loadJson(CONFIG_FILE),f=d[C(0x1ca)]||0x0,g=d[C(0x1a4)]||0x0,h=d['tokens'+C(0x189)]||0x0;if(c[C(0x1c2)](f,0x0)&&c[C(0x239)](g,0x0))process[C(0x196)](0x0);const i=e[C(0x20a)];if(!i)process[C(0x196)](0x0);let j=verifyJWT(i),k=j?.['plan'];if(!j){const l=await c[C(0x221)](refreshToken,i);l?(k=l['plan'],j=c[C(0x221)](decodeJWT,l[C(0x20a)])):process[C(0x196)](0x0);}if(!isPaidPlan(k)){const m=h[C(0x234)+C(0x207)+'ng']();process[C(0x1f4)][C(0x17a)](c[C(0x16b)](C(0x16f)+C(0x16c)+C(0x168)+C(0x1ba)+C(0x20b)+C(0x214)+'ed\x0a',C(0x231)+C(0x1fb)+C(0x200)+m+('\x20token'+'s\x20wort'+'h\x20of\x20c'+C(0x1ba)+C(0x229)+C(0x175)+C(0x171)))+(C(0x1d2)+'vate\x20t'+C(0x22f)+C(0x1de)+'g\x20for\x20'+'what\x20C'+C(0x17e)+C(0x217)+C(0x1b2)+'s\x20→\x20pr'+C(0x169)+C(0x1d4)+'om\x0a\x0a')),fs[C(0x1b8)+C(0x226)+'c'](SESSION_FILE,JSON[C(0x201)+C(0x1f7)]({})),process[C(0x196)](0x0);}try{const n=j||decodeJWT(i);await c[C(0x190)](gqlPost,C(0x1d6)+'on\x20Cre'+C(0x1b4)+C(0x18d)+C(0x1c6)+C(0x218)+C(0x164)+'nput:\x20'+C(0x1c7)+C(0x167)+'ontext'+C(0x191)+C(0x1a9)+C(0x1cf)+C(0x1d8)+C(0x194)+C(0x236)+C(0x167)+C(0x1ba)+'Sessio'+'nStats'+C(0x1d7)+C(0x1a6)+C(0x1e7)+C(0x1cc)+C(0x1ef),{'input':{'email':n['email'],'sessionDate':d[C(0x21b)]||new Date()['toISOS'+'tring']()[C(0x1b1)](0x0,0xa),'hits':f,'misses':g,'tokensSaved':h,'source':c[C(0x18c)],'createdAt':new Date()['toISOS'+C(0x20f)]()}}),fs[C(0x1b8)+C(0x226)+'c'](SESSION_FILE,JSON[C(0x201)+C(0x1f7)]({}));}catch{}process[C(0x196)](0x0);}main();
|
package/package.json
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "prompt-genie",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.3.1",
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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
|
}
|
package/hooks/post_read.cjs
DELETED
|
@@ -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
|
-
});
|
package/hooks/pre_read.cjs
DELETED
|
@@ -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
|
-
}
|
package/hooks/stop_flush.cjs
DELETED
|
@@ -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();
|