@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.
- package/LICENSE +21 -0
- package/README.md +339 -0
- package/backend/dist/auth.d.ts +15 -0
- package/backend/dist/auth.d.ts.map +1 -0
- package/backend/dist/auth.js +92 -0
- package/backend/dist/auth.js.map +1 -0
- package/backend/dist/config.d.ts +33 -0
- package/backend/dist/config.d.ts.map +1 -0
- package/backend/dist/config.js +155 -0
- package/backend/dist/config.js.map +1 -0
- package/backend/dist/index.d.ts +3 -0
- package/backend/dist/index.d.ts.map +1 -0
- package/backend/dist/index.js +499 -0
- package/backend/dist/index.js.map +1 -0
- package/backend/dist/routes/auth.d.ts +3 -0
- package/backend/dist/routes/auth.d.ts.map +1 -0
- package/backend/dist/routes/auth.js +108 -0
- package/backend/dist/routes/auth.js.map +1 -0
- package/backend/dist/routes/filesystem.d.ts +3 -0
- package/backend/dist/routes/filesystem.d.ts.map +1 -0
- package/backend/dist/routes/filesystem.js +243 -0
- package/backend/dist/routes/filesystem.js.map +1 -0
- package/backend/dist/routes/projects.d.ts +3 -0
- package/backend/dist/routes/projects.d.ts.map +1 -0
- package/backend/dist/routes/projects.js +235 -0
- package/backend/dist/routes/projects.js.map +1 -0
- package/backend/dist/routes/shortcuts.d.ts +3 -0
- package/backend/dist/routes/shortcuts.d.ts.map +1 -0
- package/backend/dist/routes/shortcuts.js +88 -0
- package/backend/dist/routes/shortcuts.js.map +1 -0
- package/backend/dist/routes/update.d.ts +3 -0
- package/backend/dist/routes/update.d.ts.map +1 -0
- package/backend/dist/routes/update.js +104 -0
- package/backend/dist/routes/update.js.map +1 -0
- package/backend/dist/session-manager.d.ts +47 -0
- package/backend/dist/session-manager.d.ts.map +1 -0
- package/backend/dist/session-manager.js +345 -0
- package/backend/dist/session-manager.js.map +1 -0
- package/backend/dist/terminal-manager.d.ts +27 -0
- package/backend/dist/terminal-manager.d.ts.map +1 -0
- package/backend/dist/terminal-manager.js +211 -0
- package/backend/dist/terminal-manager.js.map +1 -0
- package/backend/dist/types.d.ts +17 -0
- package/backend/dist/types.d.ts.map +1 -0
- package/backend/dist/types.js +3 -0
- package/backend/dist/types.js.map +1 -0
- package/backend/dist/usage-terminal.d.ts +18 -0
- package/backend/dist/usage-terminal.d.ts.map +1 -0
- package/backend/dist/usage-terminal.js +189 -0
- package/backend/dist/usage-terminal.js.map +1 -0
- package/backend/package-lock.json +1965 -0
- package/backend/package.json +31 -0
- package/bin/ccweb.js +478 -0
- package/electron/dist/main.js +455 -0
- package/frontend/dist/assets/index-CQjbS4zv.css +32 -0
- package/frontend/dist/assets/index-CtyR65A4.js +434 -0
- package/frontend/dist/index.html +14 -0
- package/frontend/dist/terminal.svg +4 -0
- 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 @@
|
|
|
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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"}
|