@tom2012/cc-web 1.5.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +339 -0
  3. package/backend/dist/auth.d.ts +15 -0
  4. package/backend/dist/auth.d.ts.map +1 -0
  5. package/backend/dist/auth.js +92 -0
  6. package/backend/dist/auth.js.map +1 -0
  7. package/backend/dist/config.d.ts +33 -0
  8. package/backend/dist/config.d.ts.map +1 -0
  9. package/backend/dist/config.js +155 -0
  10. package/backend/dist/config.js.map +1 -0
  11. package/backend/dist/index.d.ts +3 -0
  12. package/backend/dist/index.d.ts.map +1 -0
  13. package/backend/dist/index.js +499 -0
  14. package/backend/dist/index.js.map +1 -0
  15. package/backend/dist/routes/auth.d.ts +3 -0
  16. package/backend/dist/routes/auth.d.ts.map +1 -0
  17. package/backend/dist/routes/auth.js +108 -0
  18. package/backend/dist/routes/auth.js.map +1 -0
  19. package/backend/dist/routes/filesystem.d.ts +3 -0
  20. package/backend/dist/routes/filesystem.d.ts.map +1 -0
  21. package/backend/dist/routes/filesystem.js +243 -0
  22. package/backend/dist/routes/filesystem.js.map +1 -0
  23. package/backend/dist/routes/projects.d.ts +3 -0
  24. package/backend/dist/routes/projects.d.ts.map +1 -0
  25. package/backend/dist/routes/projects.js +235 -0
  26. package/backend/dist/routes/projects.js.map +1 -0
  27. package/backend/dist/routes/shortcuts.d.ts +3 -0
  28. package/backend/dist/routes/shortcuts.d.ts.map +1 -0
  29. package/backend/dist/routes/shortcuts.js +88 -0
  30. package/backend/dist/routes/shortcuts.js.map +1 -0
  31. package/backend/dist/routes/update.d.ts +3 -0
  32. package/backend/dist/routes/update.d.ts.map +1 -0
  33. package/backend/dist/routes/update.js +104 -0
  34. package/backend/dist/routes/update.js.map +1 -0
  35. package/backend/dist/session-manager.d.ts +47 -0
  36. package/backend/dist/session-manager.d.ts.map +1 -0
  37. package/backend/dist/session-manager.js +345 -0
  38. package/backend/dist/session-manager.js.map +1 -0
  39. package/backend/dist/terminal-manager.d.ts +27 -0
  40. package/backend/dist/terminal-manager.d.ts.map +1 -0
  41. package/backend/dist/terminal-manager.js +211 -0
  42. package/backend/dist/terminal-manager.js.map +1 -0
  43. package/backend/dist/types.d.ts +17 -0
  44. package/backend/dist/types.d.ts.map +1 -0
  45. package/backend/dist/types.js +3 -0
  46. package/backend/dist/types.js.map +1 -0
  47. package/backend/dist/usage-terminal.d.ts +18 -0
  48. package/backend/dist/usage-terminal.d.ts.map +1 -0
  49. package/backend/dist/usage-terminal.js +189 -0
  50. package/backend/dist/usage-terminal.js.map +1 -0
  51. package/backend/package-lock.json +1965 -0
  52. package/backend/package.json +31 -0
  53. package/bin/ccweb.js +478 -0
  54. package/electron/dist/main.js +455 -0
  55. package/frontend/dist/assets/index-CQjbS4zv.css +32 -0
  56. package/frontend/dist/assets/index-CtyR65A4.js +434 -0
  57. package/frontend/dist/index.html +14 -0
  58. package/frontend/dist/terminal.svg +4 -0
  59. package/package.json +88 -0
@@ -0,0 +1,211 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.terminalManager = void 0;
37
+ const pty = __importStar(require("node-pty"));
38
+ const config_1 = require("./config");
39
+ const session_manager_1 = require("./session-manager");
40
+ function buildCommand(tool, permissionMode) {
41
+ const unlimited = permissionMode === 'unlimited';
42
+ switch (tool) {
43
+ case 'claude':
44
+ return unlimited ? 'claude --dangerously-skip-permissions' : 'claude';
45
+ case 'opencode':
46
+ return unlimited ? 'opencode --dangerously-skip-permissions' : 'opencode';
47
+ case 'codex':
48
+ return unlimited ? 'codex --ask-for-approval never --sandbox danger-full-access' : 'codex';
49
+ case 'qwen':
50
+ return unlimited ? 'qwen-code --yolo' : 'qwen-code';
51
+ }
52
+ }
53
+ // Maximum scrollback buffer size per terminal (~5M characters)
54
+ const SCROLLBACK_MAX_CHARS = 5 * 1024 * 1024;
55
+ class TerminalManager {
56
+ constructor() {
57
+ this.terminals = new Map();
58
+ /** Pending auto-restart timers, keyed by projectId. Tracked separately so stop() can cancel them. */
59
+ this.restartTimers = new Map();
60
+ }
61
+ getOrCreate(project, rawBroadcast = () => { }) {
62
+ const existing = this.terminals.get(project.id);
63
+ if (existing) {
64
+ existing.rawBroadcast = rawBroadcast;
65
+ return;
66
+ }
67
+ this.startTerminal(project, rawBroadcast);
68
+ }
69
+ updateBroadcast(projectId, rawBroadcast) {
70
+ const instance = this.terminals.get(projectId);
71
+ if (instance)
72
+ instance.rawBroadcast = rawBroadcast;
73
+ }
74
+ /** Write raw keystrokes directly to the PTY. */
75
+ writeRaw(projectId, data) {
76
+ this.terminals.get(projectId)?.pty.write(data);
77
+ }
78
+ /** Resize the PTY to match the browser terminal. */
79
+ resize(projectId, cols, rows) {
80
+ const instance = this.terminals.get(projectId);
81
+ if (!instance)
82
+ return;
83
+ try {
84
+ instance.pty.resize(Math.max(cols, 10), Math.max(rows, 5));
85
+ }
86
+ catch (err) {
87
+ console.error(`[TerminalManager] Resize error for ${projectId}:`, err);
88
+ }
89
+ }
90
+ stop(projectId) {
91
+ // Cancel any pending auto-restart timer first
92
+ const timer = this.restartTimers.get(projectId);
93
+ if (timer !== undefined) {
94
+ clearTimeout(timer);
95
+ this.restartTimers.delete(projectId);
96
+ }
97
+ const instance = this.terminals.get(projectId);
98
+ if (!instance)
99
+ return;
100
+ instance.intentionalStop = true;
101
+ try {
102
+ instance.pty.kill();
103
+ }
104
+ catch { /* ignore */ }
105
+ this.terminals.delete(projectId);
106
+ // Clean up session watcher to prevent orphaned polling intervals
107
+ session_manager_1.sessionManager.stopWatcherForProject(projectId);
108
+ instance.project.status = 'stopped';
109
+ (0, config_1.saveProject)(instance.project);
110
+ }
111
+ hasTerminal(projectId) {
112
+ return this.terminals.has(projectId);
113
+ }
114
+ /** Return the accumulated raw scrollback for a project (for replay on reconnect). */
115
+ getScrollback(projectId) {
116
+ return this.terminals.get(projectId)?.scrollback ?? '';
117
+ }
118
+ /** Return epoch ms of last PTY data, or null if no terminal / never had data. */
119
+ getLastActivityAt(projectId) {
120
+ const instance = this.terminals.get(projectId);
121
+ return instance ? instance.lastActivityAt : null;
122
+ }
123
+ /** Return activity map for all running terminals: projectId → lastActivityAt ms. */
124
+ getAllActivity() {
125
+ const result = {};
126
+ for (const [id, instance] of this.terminals) {
127
+ if (instance.lastActivityAt !== null) {
128
+ result[id] = instance.lastActivityAt;
129
+ }
130
+ }
131
+ return result;
132
+ }
133
+ resumeAll() {
134
+ for (const project of (0, config_1.getProjects)()) {
135
+ if (project.status === 'running' || project.status === 'restarting') {
136
+ console.log(`[TerminalManager] Resuming project: ${project.name} (${project.id})`);
137
+ this.startTerminal(project, () => { });
138
+ }
139
+ }
140
+ }
141
+ startTerminal(project, rawBroadcast) {
142
+ const command = buildCommand(project.cliTool ?? 'claude', project.permissionMode);
143
+ console.log(`[TerminalManager] Starting terminal for project ${project.id}: ${command}`);
144
+ let ptyProcess;
145
+ try {
146
+ const userShell = process.env.SHELL || '/bin/zsh';
147
+ ptyProcess = pty.spawn(userShell, ['-ilc', command], {
148
+ name: 'xterm-256color',
149
+ cols: 80, // conservative default; resized to browser width on first subscribe
150
+ rows: 24,
151
+ cwd: project.folderPath,
152
+ env: { ...process.env },
153
+ });
154
+ }
155
+ catch (err) {
156
+ console.error(`[TerminalManager] Failed to spawn PTY for ${project.id}:`, err);
157
+ project.status = 'stopped';
158
+ (0, config_1.saveProject)(project);
159
+ return;
160
+ }
161
+ const instance = {
162
+ pty: ptyProcess,
163
+ project,
164
+ intentionalStop: false,
165
+ rawBroadcast,
166
+ scrollback: '',
167
+ lastActivityAt: null,
168
+ };
169
+ this.terminals.set(project.id, instance);
170
+ project.status = 'running';
171
+ (0, config_1.saveProject)(project);
172
+ session_manager_1.sessionManager.startSession(project.id, project.folderPath);
173
+ ptyProcess.onData((data) => {
174
+ instance.lastActivityAt = Date.now();
175
+ // Append to scrollback, trimming from front if over cap
176
+ instance.scrollback += data;
177
+ if (instance.scrollback.length > SCROLLBACK_MAX_CHARS) {
178
+ instance.scrollback = instance.scrollback.slice(instance.scrollback.length - SCROLLBACK_MAX_CHARS);
179
+ }
180
+ // Forward to all live terminal clients
181
+ instance.rawBroadcast(data);
182
+ });
183
+ ptyProcess.onExit(({ exitCode }) => {
184
+ console.log(`[TerminalManager] Terminal exited for ${project.id} (code: ${exitCode})`);
185
+ this.handleExit(project.id);
186
+ });
187
+ }
188
+ handleExit(projectId) {
189
+ const instance = this.terminals.get(projectId);
190
+ if (!instance || instance.intentionalStop) {
191
+ this.terminals.delete(projectId);
192
+ return;
193
+ }
194
+ const { project, rawBroadcast } = instance;
195
+ this.terminals.delete(projectId);
196
+ project.status = 'restarting';
197
+ (0, config_1.saveProject)(project);
198
+ rawBroadcast('\r\n\x1b[33m[Terminal exited — restarting in 3 s…]\x1b[0m\r\n');
199
+ console.log(`[TerminalManager] Auto-restarting terminal for ${projectId} in 3s...`);
200
+ const timer = setTimeout(() => {
201
+ this.restartTimers.delete(projectId);
202
+ // Only restart if stop() hasn't been called during the delay
203
+ if (!this.terminals.has(projectId) && !this.restartTimers.has(projectId)) {
204
+ this.startTerminal(project, rawBroadcast);
205
+ }
206
+ }, 3000);
207
+ this.restartTimers.set(projectId, timer);
208
+ }
209
+ }
210
+ exports.terminalManager = new TerminalManager();
211
+ //# sourceMappingURL=terminal-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"terminal-manager.js","sourceRoot":"","sources":["../src/terminal-manager.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ export type CliTool = 'claude' | 'opencode' | 'codex' | 'qwen';
2
+ export interface Project {
3
+ id: string;
4
+ name: string;
5
+ folderPath: string;
6
+ permissionMode: 'limited' | 'unlimited';
7
+ cliTool: CliTool;
8
+ createdAt: string;
9
+ status: 'running' | 'stopped' | 'restarting';
10
+ archived?: boolean;
11
+ }
12
+ export interface Config {
13
+ username: string;
14
+ passwordHash: string;
15
+ jwtSecret: string;
16
+ }
17
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,OAAO,GAAG,QAAQ,GAAG,UAAU,GAAG,OAAO,GAAG,MAAM,CAAC;AAE/D,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,SAAS,GAAG,WAAW,CAAC;IACxC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,SAAS,GAAG,SAAS,GAAG,YAAY,CAAC;IAC7C,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AAGD,MAAM,WAAW,MAAM;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;CACnB"}
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,18 @@
1
+ export interface UsageBucket {
2
+ utilization?: number;
3
+ resetAt?: string;
4
+ }
5
+ export interface UsageInfo {
6
+ planName?: string;
7
+ fiveHour?: UsageBucket;
8
+ sevenDay?: UsageBucket;
9
+ sevenDaySonnet?: UsageBucket;
10
+ sevenDayOpus?: UsageBucket;
11
+ }
12
+ export declare function queryUsage(): Promise<UsageInfo>;
13
+ export declare function clearUsageCache(): void;
14
+ export declare const usageTerminal: {
15
+ queryUsage: typeof queryUsage;
16
+ clearUsageCache: typeof clearUsageCache;
17
+ };
18
+ //# sourceMappingURL=usage-terminal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-terminal.d.ts","sourceRoot":"","sources":["../src/usage-terminal.ts"],"names":[],"mappings":"AAOA,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,SAAS;IACxB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,cAAc,CAAC,EAAE,WAAW,CAAC;IAC7B,YAAY,CAAC,EAAE,WAAW,CAAC;CAC5B;AAoJD,wBAAsB,UAAU,IAAI,OAAO,CAAC,SAAS,CAAC,CAMrD;AAiCD,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAGD,eAAO,MAAM,aAAa;;;CAAkC,CAAC"}
@@ -0,0 +1,189 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.usageTerminal = void 0;
37
+ exports.queryUsage = queryUsage;
38
+ exports.clearUsageCache = clearUsageCache;
39
+ const https = __importStar(require("https"));
40
+ const os = __importStar(require("os"));
41
+ const fs = __importStar(require("fs"));
42
+ const path = __importStar(require("path"));
43
+ const crypto = __importStar(require("crypto"));
44
+ const child_process_1 = require("child_process");
45
+ const CACHE_TTL_MS = 5 * 60000;
46
+ let memCache = null;
47
+ function getHashedServiceName(homeDir) {
48
+ const configDir = path.join(homeDir, '.claude');
49
+ const normalized = configDir.replace(/\\/g, '/').toLowerCase();
50
+ const hash = crypto.createHash('sha256').update(normalized).digest('hex').slice(0, 8);
51
+ return `Claude Code-credentials-${hash}`;
52
+ }
53
+ function tryKeychainService(serviceName) {
54
+ try {
55
+ const raw = (0, child_process_1.execFileSync)('/usr/bin/security', ['find-generic-password', '-s', serviceName, '-w'], { timeout: 3000, stdio: ['ignore', 'pipe', 'ignore'] }).toString().trim();
56
+ if (!raw)
57
+ return null;
58
+ const data = JSON.parse(raw);
59
+ const token = data.claudeAiOauth?.accessToken;
60
+ if (!token)
61
+ return null;
62
+ const expiresAt = data.claudeAiOauth?.expiresAt;
63
+ if (expiresAt && expiresAt < Date.now())
64
+ return null;
65
+ return { accessToken: token, subscriptionType: data.claudeAiOauth?.subscriptionType };
66
+ }
67
+ catch {
68
+ return null;
69
+ }
70
+ }
71
+ function readCredentials() {
72
+ const homeDir = os.homedir();
73
+ // Try hashed service name (Claude Code 2.x)
74
+ const hashed = tryKeychainService(getHashedServiceName(homeDir));
75
+ if (hashed)
76
+ return hashed;
77
+ // Try legacy service name
78
+ const legacy = tryKeychainService('Claude Code-credentials');
79
+ if (legacy)
80
+ return legacy;
81
+ // Fall back to .credentials.json
82
+ try {
83
+ const credPath = path.join(homeDir, '.claude', '.credentials.json');
84
+ const data = JSON.parse(fs.readFileSync(credPath, 'utf-8'));
85
+ const token = data.claudeAiOauth?.accessToken;
86
+ if (!token)
87
+ return null;
88
+ return { accessToken: token, subscriptionType: data.claudeAiOauth?.subscriptionType };
89
+ }
90
+ catch {
91
+ return null;
92
+ }
93
+ }
94
+ function fetchApi(accessToken) {
95
+ return new Promise((resolve, reject) => {
96
+ const req = https.request({
97
+ hostname: 'api.anthropic.com',
98
+ path: '/api/oauth/usage',
99
+ method: 'GET',
100
+ headers: {
101
+ 'Authorization': `Bearer ${accessToken}`,
102
+ 'anthropic-beta': 'oauth-2025-04-20',
103
+ 'User-Agent': 'claude-code/2.1',
104
+ },
105
+ }, (res) => {
106
+ let body = '';
107
+ res.on('data', (chunk) => { body += chunk.toString(); });
108
+ res.on('end', () => {
109
+ if (res.statusCode !== 200) {
110
+ reject(new Error(`HTTP ${res.statusCode}: ${body}`));
111
+ return;
112
+ }
113
+ try {
114
+ resolve(JSON.parse(body));
115
+ }
116
+ catch {
117
+ reject(new Error('Invalid JSON response'));
118
+ }
119
+ });
120
+ });
121
+ req.setTimeout(15000, () => { req.destroy(); reject(new Error('Timeout')); });
122
+ req.on('error', reject);
123
+ req.end();
124
+ });
125
+ }
126
+ const PLAN_NAMES = {
127
+ pro: 'Pro',
128
+ max: 'Max',
129
+ max_5x: 'Max 5×',
130
+ max_20x: 'Max 20×',
131
+ claude_max: 'Max',
132
+ free: 'Free',
133
+ };
134
+ function getPlanName(subscriptionType) {
135
+ if (!subscriptionType)
136
+ return undefined;
137
+ const key = subscriptionType.toLowerCase();
138
+ return PLAN_NAMES[key] ?? (subscriptionType.charAt(0).toUpperCase() + subscriptionType.slice(1));
139
+ }
140
+ function clamp(v) {
141
+ if (v == null || !Number.isFinite(v))
142
+ return undefined;
143
+ return Math.round(Math.max(0, Math.min(100, v)));
144
+ }
145
+ // ── Public API ──────────────────────────────────────────────────────────────
146
+ let queryInProgress = null;
147
+ async function queryUsage() {
148
+ if (memCache && Date.now() - memCache.at < CACHE_TTL_MS)
149
+ return memCache.data;
150
+ if (queryInProgress)
151
+ return queryInProgress;
152
+ queryInProgress = _fetch().finally(() => { queryInProgress = null; });
153
+ return queryInProgress;
154
+ }
155
+ async function _fetch() {
156
+ const creds = readCredentials();
157
+ if (!creds) {
158
+ console.warn('[UsageAPI] No credentials found');
159
+ return {};
160
+ }
161
+ try {
162
+ const resp = await fetchApi(creds.accessToken);
163
+ function toBucket(b) {
164
+ if (!b || b.utilization == null)
165
+ return undefined;
166
+ return { utilization: clamp(b.utilization), resetAt: b.resets_at ?? undefined };
167
+ }
168
+ const info = {
169
+ planName: getPlanName(creds.subscriptionType),
170
+ fiveHour: toBucket(resp.five_hour),
171
+ sevenDay: toBucket(resp.seven_day),
172
+ sevenDaySonnet: toBucket(resp.seven_day_sonnet),
173
+ sevenDayOpus: toBucket(resp.seven_day_opus),
174
+ };
175
+ memCache = { data: info, at: Date.now() };
176
+ console.log('[UsageAPI] Fetched:', JSON.stringify(info));
177
+ return info;
178
+ }
179
+ catch (err) {
180
+ console.error('[UsageAPI] Fetch failed:', err);
181
+ return {};
182
+ }
183
+ }
184
+ function clearUsageCache() {
185
+ memCache = null;
186
+ }
187
+ // Legacy export for compatibility
188
+ exports.usageTerminal = { queryUsage, clearUsageCache };
189
+ //# sourceMappingURL=usage-terminal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-terminal.js","sourceRoot":"","sources":["../src/usage-terminal.ts"],"names":[],"mappings":"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"}