cursor-api-proxy 0.4.0 → 0.5.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/README.md +81 -34
- package/dist/cli/accounts.d.ts +18 -0
- package/dist/cli/accounts.js +149 -0
- package/dist/cli/accounts.js.map +1 -0
- package/dist/cli/args.d.ts +14 -0
- package/dist/cli/args.js +93 -0
- package/dist/cli/args.js.map +1 -0
- package/dist/cli/constants.d.ts +1 -0
- package/dist/cli/constants.js +4 -0
- package/dist/cli/constants.js.map +1 -0
- package/dist/cli/login.d.ts +1 -0
- package/dist/cli/login.js +143 -0
- package/dist/cli/login.js.map +1 -0
- package/dist/cli/reset-hwid.d.ts +24 -0
- package/dist/cli/reset-hwid.js +277 -0
- package/dist/cli/reset-hwid.js.map +1 -0
- package/dist/cli/usage.d.ts +31 -0
- package/dist/cli/usage.js +214 -0
- package/dist/cli/usage.js.map +1 -0
- package/dist/cli.d.ts +1 -4
- package/dist/cli.js +40 -35
- package/dist/cli.js.map +1 -1
- package/dist/lib/account-pool.d.ts +35 -0
- package/dist/lib/account-pool.js +143 -0
- package/dist/lib/account-pool.js.map +1 -0
- package/dist/lib/agent-runner.d.ts +2 -2
- package/dist/lib/agent-runner.js +18 -6
- package/dist/lib/agent-runner.js.map +1 -1
- package/dist/lib/anthropic.js +22 -11
- package/dist/lib/anthropic.js.map +1 -1
- package/dist/lib/config.d.ts +4 -0
- package/dist/lib/config.js +2 -0
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/env.d.ts +4 -0
- package/dist/lib/env.js +68 -8
- package/dist/lib/env.js.map +1 -1
- package/dist/lib/handlers/anthropic-messages.js +60 -11
- package/dist/lib/handlers/anthropic-messages.js.map +1 -1
- package/dist/lib/handlers/chat-completions.js +54 -7
- package/dist/lib/handlers/chat-completions.js.map +1 -1
- package/dist/lib/handlers/models.d.ts +1 -0
- package/dist/lib/handlers/models.js +16 -6
- package/dist/lib/handlers/models.js.map +1 -1
- package/dist/lib/max-mode-preflight.d.ts +1 -1
- package/dist/lib/max-mode-preflight.js +9 -3
- package/dist/lib/max-mode-preflight.js.map +1 -1
- package/dist/lib/openai.d.ts +10 -0
- package/dist/lib/openai.js +53 -1
- package/dist/lib/openai.js.map +1 -1
- package/dist/lib/process.d.ts +6 -0
- package/dist/lib/process.js +71 -9
- package/dist/lib/process.js.map +1 -1
- package/dist/lib/request-listener.js +28 -4
- package/dist/lib/request-listener.js.map +1 -1
- package/dist/lib/request-log.d.ts +3 -0
- package/dist/lib/request-log.js +37 -0
- package/dist/lib/request-log.js.map +1 -1
- package/dist/lib/sanitize.d.ts +21 -0
- package/dist/lib/sanitize.js +79 -0
- package/dist/lib/sanitize.js.map +1 -0
- package/dist/lib/server.d.ts +6 -1
- package/dist/lib/server.js +75 -0
- package/dist/lib/server.js.map +1 -1
- package/package.json +5 -2
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cursor-api-proxy reset-hwid
|
|
3
|
+
*
|
|
4
|
+
* Resets Cursor's telemetry / machine IDs so the app appears as a fresh
|
|
5
|
+
* installation. Mirrors the logic from the open-source cursor-reset tool:
|
|
6
|
+
* • telemetry.machineId — SHA-256 of 32 random bytes
|
|
7
|
+
* • telemetry.macMachineId — SHA-512 of 64 random bytes
|
|
8
|
+
* • telemetry.devDeviceId — random UUID v4
|
|
9
|
+
* • telemetry.sqmId — {UUID_UPPER}
|
|
10
|
+
* • storage.serviceMachineId — random UUID v4
|
|
11
|
+
*
|
|
12
|
+
* Files touched (macOS):
|
|
13
|
+
* ~/Library/Application Support/Cursor/User/globalStorage/storage.json
|
|
14
|
+
* ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
|
|
15
|
+
* ~/Library/Application Support/Cursor/machineId
|
|
16
|
+
*
|
|
17
|
+
* Optionally wipes Cookies / Session Storage / Local Storage so Cursor
|
|
18
|
+
* cannot fingerprint the session.
|
|
19
|
+
*/
|
|
20
|
+
export declare function generateNewIds(): Record<string, string>;
|
|
21
|
+
export declare function handleResetHwid(opts?: {
|
|
22
|
+
deepClean?: boolean;
|
|
23
|
+
dryRun?: boolean;
|
|
24
|
+
}): Promise<void>;
|
|
@@ -0,0 +1,277 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* cursor-api-proxy reset-hwid
|
|
3
|
+
*
|
|
4
|
+
* Resets Cursor's telemetry / machine IDs so the app appears as a fresh
|
|
5
|
+
* installation. Mirrors the logic from the open-source cursor-reset tool:
|
|
6
|
+
* • telemetry.machineId — SHA-256 of 32 random bytes
|
|
7
|
+
* • telemetry.macMachineId — SHA-512 of 64 random bytes
|
|
8
|
+
* • telemetry.devDeviceId — random UUID v4
|
|
9
|
+
* • telemetry.sqmId — {UUID_UPPER}
|
|
10
|
+
* • storage.serviceMachineId — random UUID v4
|
|
11
|
+
*
|
|
12
|
+
* Files touched (macOS):
|
|
13
|
+
* ~/Library/Application Support/Cursor/User/globalStorage/storage.json
|
|
14
|
+
* ~/Library/Application Support/Cursor/User/globalStorage/state.vscdb
|
|
15
|
+
* ~/Library/Application Support/Cursor/machineId
|
|
16
|
+
*
|
|
17
|
+
* Optionally wipes Cookies / Session Storage / Local Storage so Cursor
|
|
18
|
+
* cannot fingerprint the session.
|
|
19
|
+
*/
|
|
20
|
+
import * as crypto from "node:crypto";
|
|
21
|
+
import { execSync, spawnSync } from "node:child_process";
|
|
22
|
+
import * as fs from "node:fs";
|
|
23
|
+
import * as os from "node:os";
|
|
24
|
+
import * as path from "node:path";
|
|
25
|
+
// ---------------------------------------------------------------------------
|
|
26
|
+
// Helpers
|
|
27
|
+
// ---------------------------------------------------------------------------
|
|
28
|
+
function uuid() {
|
|
29
|
+
return crypto.randomUUID();
|
|
30
|
+
}
|
|
31
|
+
function sha256() {
|
|
32
|
+
return crypto.createHash("sha256").update(crypto.randomBytes(32)).digest("hex");
|
|
33
|
+
}
|
|
34
|
+
function sha512() {
|
|
35
|
+
return crypto.createHash("sha512").update(crypto.randomBytes(64)).digest("hex");
|
|
36
|
+
}
|
|
37
|
+
function log(icon, msg) {
|
|
38
|
+
console.log(` ${icon} ${msg}`);
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// Path resolution
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
function getCursorGlobalStorage() {
|
|
44
|
+
if (process.platform === "darwin") {
|
|
45
|
+
return path.join(os.homedir(), "Library", "Application Support", "Cursor", "User", "globalStorage");
|
|
46
|
+
}
|
|
47
|
+
if (process.platform === "win32") {
|
|
48
|
+
const appdata = process.env.APPDATA ?? "";
|
|
49
|
+
return path.join(appdata, "Cursor", "User", "globalStorage");
|
|
50
|
+
}
|
|
51
|
+
// Linux
|
|
52
|
+
const xdg = process.env.XDG_CONFIG_HOME ?? path.join(os.homedir(), ".config");
|
|
53
|
+
return path.join(xdg, "Cursor", "User", "globalStorage");
|
|
54
|
+
}
|
|
55
|
+
function getCursorRoot() {
|
|
56
|
+
return path.dirname(path.dirname(getCursorGlobalStorage()));
|
|
57
|
+
}
|
|
58
|
+
// ---------------------------------------------------------------------------
|
|
59
|
+
// ID generation
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
export function generateNewIds() {
|
|
62
|
+
return {
|
|
63
|
+
"telemetry.machineId": sha256(),
|
|
64
|
+
"telemetry.macMachineId": sha512(),
|
|
65
|
+
"telemetry.devDeviceId": uuid(),
|
|
66
|
+
"telemetry.sqmId": `{${uuid().toUpperCase()}}`,
|
|
67
|
+
"storage.serviceMachineId": uuid(),
|
|
68
|
+
};
|
|
69
|
+
}
|
|
70
|
+
// ---------------------------------------------------------------------------
|
|
71
|
+
// Kill Cursor
|
|
72
|
+
// ---------------------------------------------------------------------------
|
|
73
|
+
function killCursor() {
|
|
74
|
+
log("🔪", "Stopping Cursor processes...");
|
|
75
|
+
try {
|
|
76
|
+
if (process.platform === "win32") {
|
|
77
|
+
spawnSync("taskkill", ["/F", "/IM", "Cursor.exe"], { stdio: "pipe" });
|
|
78
|
+
}
|
|
79
|
+
else {
|
|
80
|
+
spawnSync("pkill", ["-x", "Cursor"], { stdio: "pipe" });
|
|
81
|
+
spawnSync("pkill", ["-f", "Cursor.app"], { stdio: "pipe" });
|
|
82
|
+
}
|
|
83
|
+
}
|
|
84
|
+
catch {
|
|
85
|
+
/* cursor might not be running */
|
|
86
|
+
}
|
|
87
|
+
log("✅", "Cursor stopped (or was not running)");
|
|
88
|
+
}
|
|
89
|
+
// ---------------------------------------------------------------------------
|
|
90
|
+
// storage.json
|
|
91
|
+
// ---------------------------------------------------------------------------
|
|
92
|
+
function updateStorageJson(storagePath, ids) {
|
|
93
|
+
if (!fs.existsSync(storagePath)) {
|
|
94
|
+
log("⚠️ ", `storage.json not found: ${storagePath}`);
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
// Remove immutable flag on macOS
|
|
99
|
+
if (process.platform === "darwin") {
|
|
100
|
+
try {
|
|
101
|
+
execSync(`chflags nouchg "${storagePath}"`, { stdio: "pipe" });
|
|
102
|
+
execSync(`chmod 644 "${storagePath}"`, { stdio: "pipe" });
|
|
103
|
+
}
|
|
104
|
+
catch { /* ignore */ }
|
|
105
|
+
}
|
|
106
|
+
const raw = fs.readFileSync(storagePath, "utf-8");
|
|
107
|
+
const data = JSON.parse(raw);
|
|
108
|
+
Object.assign(data, ids);
|
|
109
|
+
fs.writeFileSync(storagePath, JSON.stringify(data, null, 2), "utf-8");
|
|
110
|
+
log("✅", "storage.json updated");
|
|
111
|
+
}
|
|
112
|
+
catch (e) {
|
|
113
|
+
log("❌", `storage.json error: ${e}`);
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
// ---------------------------------------------------------------------------
|
|
117
|
+
// state.vscdb (SQLite)
|
|
118
|
+
// ---------------------------------------------------------------------------
|
|
119
|
+
function updateStateVscdb(dbPath, ids) {
|
|
120
|
+
if (!fs.existsSync(dbPath)) {
|
|
121
|
+
log("⚠️ ", `state.vscdb not found: ${dbPath}`);
|
|
122
|
+
return;
|
|
123
|
+
}
|
|
124
|
+
const sqlite3 = findSqlite3();
|
|
125
|
+
if (!sqlite3) {
|
|
126
|
+
log("⚠️ ", "sqlite3 not found — skipping state.vscdb (install sqlite3 to fix)");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
try {
|
|
130
|
+
if (process.platform === "darwin") {
|
|
131
|
+
try {
|
|
132
|
+
execSync(`chflags nouchg "${dbPath}"`, { stdio: "pipe" });
|
|
133
|
+
execSync(`chmod 644 "${dbPath}"`, { stdio: "pipe" });
|
|
134
|
+
}
|
|
135
|
+
catch { /* ignore */ }
|
|
136
|
+
}
|
|
137
|
+
// Build SQL
|
|
138
|
+
const stmts = Object.entries(ids)
|
|
139
|
+
.map(([k, v]) => `INSERT OR REPLACE INTO ItemTable (key, value) VALUES ('${k}', '${v}');`)
|
|
140
|
+
.join("\n");
|
|
141
|
+
const result = spawnSync(sqlite3, [dbPath], {
|
|
142
|
+
input: `CREATE TABLE IF NOT EXISTS ItemTable (key TEXT PRIMARY KEY, value TEXT NOT NULL);\n${stmts}`,
|
|
143
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
144
|
+
encoding: "utf-8",
|
|
145
|
+
});
|
|
146
|
+
if (result.status !== 0) {
|
|
147
|
+
log("⚠️ ", `state.vscdb error: ${result.stderr?.trim()}`);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
log("✅", "state.vscdb updated");
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
catch (e) {
|
|
154
|
+
log("❌", `state.vscdb error: ${e}`);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
function findSqlite3() {
|
|
158
|
+
for (const candidate of ["/usr/bin/sqlite3", "/usr/local/bin/sqlite3", "sqlite3"]) {
|
|
159
|
+
try {
|
|
160
|
+
const r = spawnSync(candidate, ["--version"], { stdio: "pipe" });
|
|
161
|
+
if (r.status === 0)
|
|
162
|
+
return candidate;
|
|
163
|
+
}
|
|
164
|
+
catch { /* try next */ }
|
|
165
|
+
}
|
|
166
|
+
return null;
|
|
167
|
+
}
|
|
168
|
+
// ---------------------------------------------------------------------------
|
|
169
|
+
// machineId file
|
|
170
|
+
// ---------------------------------------------------------------------------
|
|
171
|
+
function updateMachineIdFile(machineId, cursorRoot) {
|
|
172
|
+
const candidates = process.platform === "linux"
|
|
173
|
+
? [
|
|
174
|
+
path.join(cursorRoot, "machineid"),
|
|
175
|
+
path.join(cursorRoot, "machineId"),
|
|
176
|
+
]
|
|
177
|
+
: [path.join(cursorRoot, "machineId")];
|
|
178
|
+
const filePath = candidates.find(fs.existsSync) ?? candidates[0];
|
|
179
|
+
try {
|
|
180
|
+
fs.mkdirSync(path.dirname(filePath), { recursive: true });
|
|
181
|
+
if (fs.existsSync(filePath) && process.platform === "darwin") {
|
|
182
|
+
try {
|
|
183
|
+
execSync(`chflags nouchg "${filePath}"`, { stdio: "pipe" });
|
|
184
|
+
execSync(`chmod 644 "${filePath}"`, { stdio: "pipe" });
|
|
185
|
+
}
|
|
186
|
+
catch { /* ignore */ }
|
|
187
|
+
}
|
|
188
|
+
fs.writeFileSync(filePath, machineId + "\n", "utf-8");
|
|
189
|
+
log("✅", `machineId file updated (${path.basename(filePath)})`);
|
|
190
|
+
}
|
|
191
|
+
catch (e) {
|
|
192
|
+
log("⚠️ ", `machineId file error: ${e}`);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
// ---------------------------------------------------------------------------
|
|
196
|
+
// Optional: wipe session / cookie data
|
|
197
|
+
// ---------------------------------------------------------------------------
|
|
198
|
+
const DIRS_TO_WIPE = [
|
|
199
|
+
"Session Storage",
|
|
200
|
+
"Local Storage",
|
|
201
|
+
"IndexedDB",
|
|
202
|
+
"Cache",
|
|
203
|
+
"Code Cache",
|
|
204
|
+
"GPUCache",
|
|
205
|
+
"Service Worker",
|
|
206
|
+
"Network",
|
|
207
|
+
"Cookies",
|
|
208
|
+
"Cookies-journal",
|
|
209
|
+
];
|
|
210
|
+
function deepClean(cursorRoot) {
|
|
211
|
+
log("🧹", "Deep-cleaning session data...");
|
|
212
|
+
let wiped = 0;
|
|
213
|
+
for (const name of DIRS_TO_WIPE) {
|
|
214
|
+
const target = path.join(cursorRoot, name);
|
|
215
|
+
if (!fs.existsSync(target))
|
|
216
|
+
continue;
|
|
217
|
+
try {
|
|
218
|
+
const stat = fs.statSync(target);
|
|
219
|
+
if (stat.isDirectory()) {
|
|
220
|
+
fs.rmSync(target, { recursive: true, force: true });
|
|
221
|
+
}
|
|
222
|
+
else {
|
|
223
|
+
fs.unlinkSync(target);
|
|
224
|
+
}
|
|
225
|
+
wiped++;
|
|
226
|
+
}
|
|
227
|
+
catch { /* ignore */ }
|
|
228
|
+
}
|
|
229
|
+
log("✅", `Wiped ${wiped} cache/session items`);
|
|
230
|
+
}
|
|
231
|
+
// ---------------------------------------------------------------------------
|
|
232
|
+
// Main export
|
|
233
|
+
// ---------------------------------------------------------------------------
|
|
234
|
+
export async function handleResetHwid(opts = {}) {
|
|
235
|
+
console.log("\n🔄 Cursor HWID Reset\n");
|
|
236
|
+
console.log(" Resets all machine / telemetry IDs so Cursor sees a fresh install.");
|
|
237
|
+
console.log(" Cursor must be closed — it will be killed automatically.\n");
|
|
238
|
+
const globalStorage = getCursorGlobalStorage();
|
|
239
|
+
const cursorRoot = getCursorRoot();
|
|
240
|
+
if (!fs.existsSync(globalStorage)) {
|
|
241
|
+
console.log(`❌ Cursor config not found at:\n ${globalStorage}`);
|
|
242
|
+
console.log(" Make sure Cursor is installed and has been run at least once.");
|
|
243
|
+
process.exit(1);
|
|
244
|
+
}
|
|
245
|
+
if (opts.dryRun) {
|
|
246
|
+
console.log(" [DRY RUN] Would reset IDs in:");
|
|
247
|
+
console.log(` ${path.join(globalStorage, "storage.json")}`);
|
|
248
|
+
console.log(` ${path.join(globalStorage, "state.vscdb")}`);
|
|
249
|
+
console.log(` ${path.join(cursorRoot, "machineId")}`);
|
|
250
|
+
return;
|
|
251
|
+
}
|
|
252
|
+
// 1. Kill Cursor
|
|
253
|
+
killCursor();
|
|
254
|
+
// Small delay so the OS can release file handles
|
|
255
|
+
await new Promise((r) => setTimeout(r, 800));
|
|
256
|
+
// 2. Generate new IDs
|
|
257
|
+
const newIds = generateNewIds();
|
|
258
|
+
log("🎲", "Generated new IDs:");
|
|
259
|
+
for (const [k, v] of Object.entries(newIds)) {
|
|
260
|
+
console.log(` ${k}: ${v}`);
|
|
261
|
+
}
|
|
262
|
+
console.log();
|
|
263
|
+
// 3. Update files
|
|
264
|
+
log("📝", "Updating storage.json...");
|
|
265
|
+
updateStorageJson(path.join(globalStorage, "storage.json"), newIds);
|
|
266
|
+
log("🗄️ ", "Updating state.vscdb...");
|
|
267
|
+
updateStateVscdb(path.join(globalStorage, "state.vscdb"), newIds);
|
|
268
|
+
log("🔑", "Updating machineId file...");
|
|
269
|
+
updateMachineIdFile(newIds["telemetry.machineId"], cursorRoot);
|
|
270
|
+
// 4. Optional deep clean
|
|
271
|
+
if (opts.deepClean) {
|
|
272
|
+
console.log();
|
|
273
|
+
deepClean(cursorRoot);
|
|
274
|
+
}
|
|
275
|
+
console.log("\n✅ HWID reset complete. You can now restart Cursor.\n");
|
|
276
|
+
}
|
|
277
|
+
//# sourceMappingURL=reset-hwid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"reset-hwid.js","sourceRoot":"","sources":["../../src/cli/reset-hwid.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,OAAO,KAAK,MAAM,MAAM,aAAa,CAAC;AACtC,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AACzD,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,EAAE,MAAM,SAAS,CAAC;AAC9B,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,8EAA8E;AAC9E,UAAU;AACV,8EAA8E;AAE9E,SAAS,IAAI;IACX,OAAO,MAAM,CAAC,UAAU,EAAE,CAAC;AAC7B,CAAC;AAED,SAAS,MAAM;IACb,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,MAAM;IACb,OAAO,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,GAAG,CAAC,IAAY,EAAE,GAAW;IACpC,OAAO,CAAC,GAAG,CAAC,KAAK,IAAI,IAAI,GAAG,EAAE,CAAC,CAAC;AAClC,CAAC;AAED,8EAA8E;AAC9E,kBAAkB;AAClB,8EAA8E;AAE9E,SAAS,sBAAsB;IAC7B,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAClC,OAAO,IAAI,CAAC,IAAI,CACd,EAAE,CAAC,OAAO,EAAE,EACZ,SAAS,EACT,qBAAqB,EACrB,QAAQ,EACR,MAAM,EACN,eAAe,CAChB,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QACjC,MAAM,OAAO,GAAG,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,EAAE,CAAC;QAC1C,OAAO,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;IAC/D,CAAC;IACD,QAAQ;IACR,MAAM,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IAC9E,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,eAAe,CAAC,CAAC;AAC3D,CAAC;AAED,SAAS,aAAa;IACpB,OAAO,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,sBAAsB,EAAE,CAAC,CAAC,CAAC;AAC9D,CAAC;AAED,8EAA8E;AAC9E,gBAAgB;AAChB,8EAA8E;AAE9E,MAAM,UAAU,cAAc;IAC5B,OAAO;QACL,qBAAqB,EAAE,MAAM,EAAE;QAC/B,wBAAwB,EAAE,MAAM,EAAE;QAClC,uBAAuB,EAAE,IAAI,EAAE;QAC/B,iBAAiB,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,GAAG;QAC9C,0BAA0B,EAAE,IAAI,EAAE;KACnC,CAAC;AACJ,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,SAAS,UAAU;IACjB,GAAG,CAAC,IAAI,EAAE,8BAA8B,CAAC,CAAC;IAC1C,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;YACjC,SAAS,CAAC,UAAU,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,YAAY,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QACxE,CAAC;aAAM,CAAC;YACN,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,QAAQ,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACxD,SAAS,CAAC,OAAO,EAAE,CAAC,IAAI,EAAE,YAAY,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;QAC9D,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,iCAAiC;IACnC,CAAC;IACD,GAAG,CAAC,GAAG,EAAE,qCAAqC,CAAC,CAAC;AAClD,CAAC;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,SAAS,iBAAiB,CACxB,WAAmB,EACnB,GAA2B;IAE3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;QAChC,GAAG,CAAC,KAAK,EAAE,2BAA2B,WAAW,EAAE,CAAC,CAAC;QACrD,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,iCAAiC;QACjC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,QAAQ,CAAC,mBAAmB,WAAW,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC/D,QAAQ,CAAC,cAAc,WAAW,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YAC5D,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1B,CAAC;QAED,MAAM,GAAG,GAAG,EAAE,CAAC,YAAY,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,GAAG,CAA4B,CAAC;QACxD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;QACzB,EAAE,CAAC,aAAa,CAAC,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtE,GAAG,CAAC,GAAG,EAAE,sBAAsB,CAAC,CAAC;IACnC,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,GAAG,EAAE,uBAAuB,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,uBAAuB;AACvB,8EAA8E;AAE9E,SAAS,gBAAgB,CACvB,MAAc,EACd,GAA2B;IAE3B,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QAC3B,GAAG,CAAC,KAAK,EAAE,0BAA0B,MAAM,EAAE,CAAC,CAAC;QAC/C,OAAO;IACT,CAAC;IAED,MAAM,OAAO,GAAG,WAAW,EAAE,CAAC;IAC9B,IAAI,CAAC,OAAO,EAAE,CAAC;QACb,GAAG,CAAC,KAAK,EAAE,mEAAmE,CAAC,CAAC;QAChF,OAAO;IACT,CAAC;IAED,IAAI,CAAC;QACH,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC;gBACH,QAAQ,CAAC,mBAAmB,MAAM,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC1D,QAAQ,CAAC,cAAc,MAAM,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACvD,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1B,CAAC;QAED,YAAY;QACZ,MAAM,KAAK,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC;aAC9B,GAAG,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CACd,0DAA0D,CAAC,OAAO,CAAC,KAAK,CACzE;aACA,IAAI,CAAC,IAAI,CAAC,CAAC;QAEd,MAAM,MAAM,GAAG,SAAS,CACtB,OAAO,EACP,CAAC,MAAM,CAAC,EACR;YACE,KAAK,EAAE,sFAAsF,KAAK,EAAE;YACpG,KAAK,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC;YAC/B,QAAQ,EAAE,OAAO;SAClB,CACF,CAAC;QAEF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACxB,GAAG,CAAC,KAAK,EAAE,sBAAsB,MAAM,CAAC,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC,CAAC;QAC5D,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,GAAG,EAAE,qBAAqB,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,GAAG,EAAE,sBAAsB,CAAC,EAAE,CAAC,CAAC;IACtC,CAAC;AACH,CAAC;AAED,SAAS,WAAW;IAClB,KAAK,MAAM,SAAS,IAAI,CAAC,kBAAkB,EAAE,wBAAwB,EAAE,SAAS,CAAC,EAAE,CAAC;QAClF,IAAI,CAAC;YACH,MAAM,CAAC,GAAG,SAAS,CAAC,SAAS,EAAE,CAAC,WAAW,CAAC,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACjE,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC;gBAAE,OAAO,SAAS,CAAC;QACvC,CAAC;QAAC,MAAM,CAAC,CAAC,cAAc,CAAC,CAAC;IAC5B,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E,SAAS,mBAAmB,CAC1B,SAAiB,EACjB,UAAkB;IAElB,MAAM,UAAU,GACd,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC1B,CAAC,CAAC;YACE,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;YAClC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC;SACnC;QACH,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,CAAC,CAAC;IAE3C,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,IAAI,UAAU,CAAC,CAAC,CAAC,CAAC;IAEjE,IAAI,CAAC;QACH,EAAE,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC1D,IAAI,EAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,IAAI,OAAO,CAAC,QAAQ,KAAK,QAAQ,EAAE,CAAC;YAC7D,IAAI,CAAC;gBACH,QAAQ,CAAC,mBAAmB,QAAQ,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;gBAC5D,QAAQ,CAAC,cAAc,QAAQ,GAAG,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,CAAC,CAAC;YACzD,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1B,CAAC;QACD,EAAE,CAAC,aAAa,CAAC,QAAQ,EAAE,SAAS,GAAG,IAAI,EAAE,OAAO,CAAC,CAAC;QACtD,GAAG,CAAC,GAAG,EAAE,2BAA2B,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IAClE,CAAC;IAAC,OAAO,CAAC,EAAE,CAAC;QACX,GAAG,CAAC,KAAK,EAAE,yBAAyB,CAAC,EAAE,CAAC,CAAC;IAC3C,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,uCAAuC;AACvC,8EAA8E;AAE9E,MAAM,YAAY,GAAG;IACnB,iBAAiB;IACjB,eAAe;IACf,WAAW;IACX,OAAO;IACP,YAAY;IACZ,UAAU;IACV,gBAAgB;IAChB,SAAS;IACT,SAAS;IACT,iBAAiB;CAClB,CAAC;AAEF,SAAS,SAAS,CAAC,UAAkB;IACnC,GAAG,CAAC,IAAI,EAAE,+BAA+B,CAAC,CAAC;IAC3C,IAAI,KAAK,GAAG,CAAC,CAAC;IAEd,KAAK,MAAM,IAAI,IAAI,YAAY,EAAE,CAAC;QAChC,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;QAC3C,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAS;QACrC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,EAAE,CAAC,QAAQ,CAAC,MAAM,CAAC,CAAC;YACjC,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;gBACvB,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;YACtD,CAAC;iBAAM,CAAC;gBACN,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC;YACxB,CAAC;YACD,KAAK,EAAE,CAAC;QACV,CAAC;QAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;IAC1B,CAAC;IAED,GAAG,CAAC,GAAG,EAAE,SAAS,KAAK,sBAAsB,CAAC,CAAC;AACjD,CAAC;AAED,8EAA8E;AAC9E,cAAc;AACd,8EAA8E;AAE9E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,OAGlC,EAAE;IACJ,OAAO,CAAC,GAAG,CAAC,0BAA0B,CAAC,CAAC;IACxC,OAAO,CAAC,GAAG,CAAC,sEAAsE,CAAC,CAAC;IACpF,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAE5E,MAAM,aAAa,GAAG,sBAAsB,EAAE,CAAC;IAC/C,MAAM,UAAU,GAAG,aAAa,EAAE,CAAC;IAEnC,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;QAClC,OAAO,CAAC,GAAG,CAAC,qCAAqC,aAAa,EAAE,CAAC,CAAC;QAClE,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE,CAAC,CAAC;QAC/D,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,WAAW,CAAC,EAAE,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,iBAAiB;IACjB,UAAU,EAAE,CAAC;IAEb,iDAAiD;IACjD,MAAM,IAAI,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC;IAE7C,sBAAsB;IACtB,MAAM,MAAM,GAAG,cAAc,EAAE,CAAC;IAChC,GAAG,CAAC,IAAI,EAAE,oBAAoB,CAAC,CAAC;IAChC,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,CAAC;QAC5C,OAAO,CAAC,GAAG,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,CAAC,GAAG,EAAE,CAAC;IAEd,kBAAkB;IAClB,GAAG,CAAC,IAAI,EAAE,0BAA0B,CAAC,CAAC;IACtC,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,cAAc,CAAC,EAAE,MAAM,CAAC,CAAC;IAEpE,GAAG,CAAC,MAAM,EAAE,yBAAyB,CAAC,CAAC;IACvC,gBAAgB,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,aAAa,CAAC,EAAE,MAAM,CAAC,CAAC;IAElE,GAAG,CAAC,IAAI,EAAE,4BAA4B,CAAC,CAAC;IACxC,mBAAmB,CAAC,MAAM,CAAC,qBAAqB,CAAC,EAAE,UAAU,CAAC,CAAC;IAE/D,yBAAyB;IACzB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,CAAC,GAAG,EAAE,CAAC;QACd,SAAS,CAAC,UAAU,CAAC,CAAC;IACxB,CAAC;IAED,OAAO,CAAC,GAAG,CAAC,wDAAwD,CAAC,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
export declare const TOKEN_FILE = ".cursor-token";
|
|
2
|
+
export declare function readCachedToken(configDir: string): string | undefined;
|
|
3
|
+
export declare function writeCachedToken(configDir: string, token: string): void;
|
|
4
|
+
/** Read the shared macOS Keychain slot used by the Cursor CLI. */
|
|
5
|
+
export declare function readKeychainToken(): string | undefined;
|
|
6
|
+
export declare function decodeJwtPayload(token: string): Record<string, unknown>;
|
|
7
|
+
/** Extract the auth0 user sub from a Cursor access token (e.g. "auth0|user_01KK…"). */
|
|
8
|
+
export declare function tokenSub(token: string): string | undefined;
|
|
9
|
+
export type ModelUsage = {
|
|
10
|
+
numRequests: number;
|
|
11
|
+
numRequestsTotal: number;
|
|
12
|
+
numTokens: number;
|
|
13
|
+
maxTokenUsage: number | null;
|
|
14
|
+
maxRequestUsage: number | null;
|
|
15
|
+
};
|
|
16
|
+
export type UsageData = {
|
|
17
|
+
startOfMonth: string;
|
|
18
|
+
models: Record<string, ModelUsage>;
|
|
19
|
+
};
|
|
20
|
+
export declare function fetchAccountUsage(token: string): Promise<UsageData | null>;
|
|
21
|
+
export type StripeProfile = {
|
|
22
|
+
membershipType: string;
|
|
23
|
+
subscriptionStatus: string;
|
|
24
|
+
daysRemainingOnTrial: number | null;
|
|
25
|
+
isTeamMember: boolean;
|
|
26
|
+
isYearlyPlan: boolean;
|
|
27
|
+
};
|
|
28
|
+
/** Human-readable plan name + limits for display. */
|
|
29
|
+
export declare function describePlan(profile: StripeProfile): string;
|
|
30
|
+
export declare function fetchStripeProfile(token: string): Promise<StripeProfile | null>;
|
|
31
|
+
export declare function formatUsageSummary(usage: UsageData): string[];
|
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
import { execSync } from "node:child_process";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import * as https from "node:https";
|
|
5
|
+
// ---------------------------------------------------------------------------
|
|
6
|
+
// Token file written per-account after each agent run
|
|
7
|
+
// ---------------------------------------------------------------------------
|
|
8
|
+
export const TOKEN_FILE = ".cursor-token";
|
|
9
|
+
export function readCachedToken(configDir) {
|
|
10
|
+
try {
|
|
11
|
+
const p = path.join(configDir, TOKEN_FILE);
|
|
12
|
+
if (fs.existsSync(p))
|
|
13
|
+
return fs.readFileSync(p, "utf-8").trim() || undefined;
|
|
14
|
+
}
|
|
15
|
+
catch {
|
|
16
|
+
/* ignore */
|
|
17
|
+
}
|
|
18
|
+
return undefined;
|
|
19
|
+
}
|
|
20
|
+
export function writeCachedToken(configDir, token) {
|
|
21
|
+
try {
|
|
22
|
+
fs.writeFileSync(path.join(configDir, TOKEN_FILE), token, "utf-8");
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
/* ignore */
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
/** Read the shared macOS Keychain slot used by the Cursor CLI. */
|
|
29
|
+
export function readKeychainToken() {
|
|
30
|
+
try {
|
|
31
|
+
const t = execSync('security find-generic-password -s "cursor-access-token" -w', { stdio: ["pipe", "pipe", "pipe"], timeout: 5000 })
|
|
32
|
+
.toString()
|
|
33
|
+
.trim();
|
|
34
|
+
return t || undefined;
|
|
35
|
+
}
|
|
36
|
+
catch {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
// ---------------------------------------------------------------------------
|
|
41
|
+
// JWT helpers (no external dependencies)
|
|
42
|
+
// ---------------------------------------------------------------------------
|
|
43
|
+
export function decodeJwtPayload(token) {
|
|
44
|
+
try {
|
|
45
|
+
const parts = token.split(".");
|
|
46
|
+
if (parts.length < 2)
|
|
47
|
+
return {};
|
|
48
|
+
const padded = parts[1].replace(/-/g, "+").replace(/_/g, "/");
|
|
49
|
+
return JSON.parse(Buffer.from(padded, "base64").toString("utf-8"));
|
|
50
|
+
}
|
|
51
|
+
catch {
|
|
52
|
+
return {};
|
|
53
|
+
}
|
|
54
|
+
}
|
|
55
|
+
/** Extract the auth0 user sub from a Cursor access token (e.g. "auth0|user_01KK…"). */
|
|
56
|
+
export function tokenSub(token) {
|
|
57
|
+
const p = decodeJwtPayload(token);
|
|
58
|
+
return typeof p.sub === "string" ? p.sub : undefined;
|
|
59
|
+
}
|
|
60
|
+
// ---------------------------------------------------------------------------
|
|
61
|
+
// Cursor API
|
|
62
|
+
// ---------------------------------------------------------------------------
|
|
63
|
+
const API_BASE = "https://api2.cursor.sh";
|
|
64
|
+
function apiGet(path, token) {
|
|
65
|
+
return new Promise((resolve, reject) => {
|
|
66
|
+
const opts = {
|
|
67
|
+
hostname: "api2.cursor.sh",
|
|
68
|
+
path,
|
|
69
|
+
method: "GET",
|
|
70
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
71
|
+
};
|
|
72
|
+
const req = https.request(opts, (res) => {
|
|
73
|
+
let data = "";
|
|
74
|
+
res.on("data", (c) => (data += c));
|
|
75
|
+
res.on("end", () => {
|
|
76
|
+
try {
|
|
77
|
+
resolve(JSON.parse(data));
|
|
78
|
+
}
|
|
79
|
+
catch {
|
|
80
|
+
resolve(null);
|
|
81
|
+
}
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
req.on("error", reject);
|
|
85
|
+
req.setTimeout(8000, () => {
|
|
86
|
+
req.destroy(new Error("timeout"));
|
|
87
|
+
});
|
|
88
|
+
req.end();
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
export async function fetchAccountUsage(token) {
|
|
92
|
+
try {
|
|
93
|
+
const raw = (await apiGet("/auth/usage", token));
|
|
94
|
+
if (!raw || typeof raw !== "object")
|
|
95
|
+
return null;
|
|
96
|
+
const { startOfMonth, ...rest } = raw;
|
|
97
|
+
return {
|
|
98
|
+
startOfMonth: typeof startOfMonth === "string" ? startOfMonth : "",
|
|
99
|
+
models: rest,
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
catch {
|
|
103
|
+
return null;
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
/** Human-readable plan name + limits for display. */
|
|
107
|
+
export function describePlan(profile) {
|
|
108
|
+
const { membershipType, subscriptionStatus, daysRemainingOnTrial } = profile;
|
|
109
|
+
switch (membershipType) {
|
|
110
|
+
case "free_trial": {
|
|
111
|
+
const days = daysRemainingOnTrial ?? 0;
|
|
112
|
+
return `Pro Trial (${days}d left) — unlimited fast requests`;
|
|
113
|
+
}
|
|
114
|
+
case "pro":
|
|
115
|
+
case "pro_plus":
|
|
116
|
+
case "ultra":
|
|
117
|
+
return `${membershipType === "pro" ? "Pro" : membershipType === "pro_plus" ? "Pro+" : "Ultra"} — extended limits`;
|
|
118
|
+
case "free":
|
|
119
|
+
case "hobby":
|
|
120
|
+
return "Hobby (free) — limited agent requests";
|
|
121
|
+
default:
|
|
122
|
+
return `${membershipType} · ${subscriptionStatus}`;
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
export async function fetchStripeProfile(token) {
|
|
126
|
+
try {
|
|
127
|
+
const raw = (await apiGet("/auth/full_stripe_profile", token));
|
|
128
|
+
if (!raw || typeof raw !== "object")
|
|
129
|
+
return null;
|
|
130
|
+
return {
|
|
131
|
+
membershipType: String(raw.membershipType ?? ""),
|
|
132
|
+
subscriptionStatus: String(raw.subscriptionStatus ?? ""),
|
|
133
|
+
daysRemainingOnTrial: typeof raw.daysRemainingOnTrial === "number"
|
|
134
|
+
? raw.daysRemainingOnTrial
|
|
135
|
+
: null,
|
|
136
|
+
isTeamMember: Boolean(raw.isTeamMember),
|
|
137
|
+
isYearlyPlan: Boolean(raw.isYearlyPlan),
|
|
138
|
+
};
|
|
139
|
+
}
|
|
140
|
+
catch {
|
|
141
|
+
return null;
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
// ---------------------------------------------------------------------------
|
|
145
|
+
// Summary helpers
|
|
146
|
+
// ---------------------------------------------------------------------------
|
|
147
|
+
// Human-readable labels for Cursor's internal model/pool keys.
|
|
148
|
+
// Keys are actual identifiers from the agent binary (2026.03.20 build).
|
|
149
|
+
const MODEL_LABELS = {
|
|
150
|
+
// ── Usage pool keys (what the /auth/usage API actually returns) ──
|
|
151
|
+
"gpt-4": "Fast Premium Requests", // main premium pool (all models)
|
|
152
|
+
// ── Claude Sonnet ──
|
|
153
|
+
"claude-sonnet-4-6": "Claude Sonnet 4.6",
|
|
154
|
+
"claude-sonnet-4-5-20250929-v1": "Claude Sonnet 4.5",
|
|
155
|
+
"claude-sonnet-4-20250514-v1": "Claude Sonnet 4",
|
|
156
|
+
// ── Claude Opus ──
|
|
157
|
+
"claude-opus-4-6-v1": "Claude Opus 4.6",
|
|
158
|
+
"claude-opus-4-5-20251101-v1": "Claude Opus 4.5",
|
|
159
|
+
"claude-opus-4-1-20250805-v1": "Claude Opus 4.1",
|
|
160
|
+
"claude-opus-4-20250514-v1": "Claude Opus 4",
|
|
161
|
+
// ── Claude Haiku ──
|
|
162
|
+
"claude-haiku-4-5-20251001-v1": "Claude Haiku 4.5",
|
|
163
|
+
"claude-3-5-haiku-20241022-v1": "Claude 3.5 Haiku",
|
|
164
|
+
// ── GPT / OpenAI ──
|
|
165
|
+
"gpt-5": "GPT-5",
|
|
166
|
+
"gpt-4o": "GPT-4o",
|
|
167
|
+
o1: "o1",
|
|
168
|
+
"o3-mini": "o3-mini",
|
|
169
|
+
// ── Cursor-native ──
|
|
170
|
+
"cursor-small": "Cursor Small (free)",
|
|
171
|
+
};
|
|
172
|
+
function modelLabel(key) {
|
|
173
|
+
return MODEL_LABELS[key] ?? key;
|
|
174
|
+
}
|
|
175
|
+
export function formatUsageSummary(usage) {
|
|
176
|
+
const lines = [];
|
|
177
|
+
const start = usage.startOfMonth
|
|
178
|
+
? new Date(usage.startOfMonth).toLocaleDateString()
|
|
179
|
+
: "?";
|
|
180
|
+
lines.push(` 📅 Billing period from ${start}`);
|
|
181
|
+
const entries = Object.entries(usage.models);
|
|
182
|
+
if (entries.length === 0) {
|
|
183
|
+
lines.push(` 🔢 No requests this billing period`);
|
|
184
|
+
return lines;
|
|
185
|
+
}
|
|
186
|
+
// Sort: entries with limits first, then by usage descending
|
|
187
|
+
const sorted = entries.sort(([, a], [, b]) => {
|
|
188
|
+
if ((a.maxRequestUsage !== null) !== (b.maxRequestUsage !== null))
|
|
189
|
+
return a.maxRequestUsage !== null ? -1 : 1;
|
|
190
|
+
return b.numRequests - a.numRequests;
|
|
191
|
+
});
|
|
192
|
+
for (const [key, v] of sorted) {
|
|
193
|
+
const used = v.numRequests;
|
|
194
|
+
const max = v.maxRequestUsage;
|
|
195
|
+
const label = modelLabel(key);
|
|
196
|
+
if (max !== null && max > 0) {
|
|
197
|
+
const pct = Math.round((used / max) * 100);
|
|
198
|
+
const bar = makeBar(used, max, 12);
|
|
199
|
+
lines.push(` 🔢 ${label}: ${used}/${max} (${pct}%) [${bar}]`);
|
|
200
|
+
}
|
|
201
|
+
else if (used > 0) {
|
|
202
|
+
lines.push(` 🔢 ${label}: ${used} requests`);
|
|
203
|
+
}
|
|
204
|
+
else {
|
|
205
|
+
lines.push(` 🔢 ${label}: 0 requests (unlimited)`);
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return lines;
|
|
209
|
+
}
|
|
210
|
+
function makeBar(used, max, width) {
|
|
211
|
+
const fill = Math.round((used / max) * width);
|
|
212
|
+
return "█".repeat(fill) + "░".repeat(width - fill);
|
|
213
|
+
}
|
|
214
|
+
//# sourceMappingURL=usage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"usage.js","sourceRoot":"","sources":["../../src/cli/usage.ts"],"names":[],"mappings":"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"}
|
package/dist/cli.d.ts
CHANGED