claudedesk 1.0.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.
Files changed (182) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +431 -0
  3. package/config/repos.example.json +128 -0
  4. package/config/settings.example.json +64 -0
  5. package/config/skills/code-review.md +76 -0
  6. package/config/skills/full-check.md +26 -0
  7. package/config/skills/lint-fix.md +23 -0
  8. package/dist/api/agent-routes.d.ts +2 -0
  9. package/dist/api/agent-routes.d.ts.map +1 -0
  10. package/dist/api/agent-routes.js +251 -0
  11. package/dist/api/agent-routes.js.map +1 -0
  12. package/dist/api/app-routes.d.ts +2 -0
  13. package/dist/api/app-routes.d.ts.map +1 -0
  14. package/dist/api/app-routes.js +150 -0
  15. package/dist/api/app-routes.js.map +1 -0
  16. package/dist/api/docker-routes.d.ts +2 -0
  17. package/dist/api/docker-routes.d.ts.map +1 -0
  18. package/dist/api/docker-routes.js +167 -0
  19. package/dist/api/docker-routes.js.map +1 -0
  20. package/dist/api/middleware.d.ts +6 -0
  21. package/dist/api/middleware.d.ts.map +1 -0
  22. package/dist/api/middleware.js +293 -0
  23. package/dist/api/middleware.js.map +1 -0
  24. package/dist/api/pin-auth.d.ts +65 -0
  25. package/dist/api/pin-auth.d.ts.map +1 -0
  26. package/dist/api/pin-auth.js +218 -0
  27. package/dist/api/pin-auth.js.map +1 -0
  28. package/dist/api/routes.d.ts +2 -0
  29. package/dist/api/routes.d.ts.map +1 -0
  30. package/dist/api/routes.js +473 -0
  31. package/dist/api/routes.js.map +1 -0
  32. package/dist/api/settings-routes.d.ts +2 -0
  33. package/dist/api/settings-routes.d.ts.map +1 -0
  34. package/dist/api/settings-routes.js +570 -0
  35. package/dist/api/settings-routes.js.map +1 -0
  36. package/dist/api/skill-routes.d.ts +2 -0
  37. package/dist/api/skill-routes.d.ts.map +1 -0
  38. package/dist/api/skill-routes.js +88 -0
  39. package/dist/api/skill-routes.js.map +1 -0
  40. package/dist/api/terminal-routes.d.ts +2 -0
  41. package/dist/api/terminal-routes.d.ts.map +1 -0
  42. package/dist/api/terminal-routes.js +3524 -0
  43. package/dist/api/terminal-routes.js.map +1 -0
  44. package/dist/api/tunnel-routes.d.ts +2 -0
  45. package/dist/api/tunnel-routes.d.ts.map +1 -0
  46. package/dist/api/tunnel-routes.js +196 -0
  47. package/dist/api/tunnel-routes.js.map +1 -0
  48. package/dist/api/workspace-routes.d.ts +3 -0
  49. package/dist/api/workspace-routes.d.ts.map +1 -0
  50. package/dist/api/workspace-routes.js +649 -0
  51. package/dist/api/workspace-routes.js.map +1 -0
  52. package/dist/cli.d.ts +3 -0
  53. package/dist/cli.d.ts.map +1 -0
  54. package/dist/cli.js +276 -0
  55. package/dist/cli.js.map +1 -0
  56. package/dist/client/assets/index-B4r0njGe.js +780 -0
  57. package/dist/client/assets/index-CY_9MyE0.css +1 -0
  58. package/dist/client/favicon.svg +5 -0
  59. package/dist/client/icons/icon-192.svg +5 -0
  60. package/dist/client/icons/icon-512.svg +5 -0
  61. package/dist/client/icons/logo-with-message.png +0 -0
  62. package/dist/client/icons/logo.png +0 -0
  63. package/dist/client/index.html +25 -0
  64. package/dist/client/manifest.json +62 -0
  65. package/dist/client/sw.js +243 -0
  66. package/dist/config/agent-usage.d.ts +34 -0
  67. package/dist/config/agent-usage.d.ts.map +1 -0
  68. package/dist/config/agent-usage.js +87 -0
  69. package/dist/config/agent-usage.js.map +1 -0
  70. package/dist/config/repos.d.ts +34 -0
  71. package/dist/config/repos.d.ts.map +1 -0
  72. package/dist/config/repos.js +412 -0
  73. package/dist/config/repos.js.map +1 -0
  74. package/dist/config/settings.d.ts +634 -0
  75. package/dist/config/settings.d.ts.map +1 -0
  76. package/dist/config/settings.js +459 -0
  77. package/dist/config/settings.js.map +1 -0
  78. package/dist/config/skills.d.ts +18 -0
  79. package/dist/config/skills.d.ts.map +1 -0
  80. package/dist/config/skills.js +174 -0
  81. package/dist/config/skills.js.map +1 -0
  82. package/dist/config/workspaces.d.ts +961 -0
  83. package/dist/config/workspaces.d.ts.map +1 -0
  84. package/dist/config/workspaces.js +482 -0
  85. package/dist/config/workspaces.js.map +1 -0
  86. package/dist/core/app-manager.d.ts +85 -0
  87. package/dist/core/app-manager.d.ts.map +1 -0
  88. package/dist/core/app-manager.js +447 -0
  89. package/dist/core/app-manager.js.map +1 -0
  90. package/dist/core/claude-invoker.d.ts +49 -0
  91. package/dist/core/claude-invoker.d.ts.map +1 -0
  92. package/dist/core/claude-invoker.js +583 -0
  93. package/dist/core/claude-invoker.js.map +1 -0
  94. package/dist/core/claude-session-reader.d.ts +25 -0
  95. package/dist/core/claude-session-reader.d.ts.map +1 -0
  96. package/dist/core/claude-session-reader.js +184 -0
  97. package/dist/core/claude-session-reader.js.map +1 -0
  98. package/dist/core/claude-usage-query.d.ts +78 -0
  99. package/dist/core/claude-usage-query.d.ts.map +1 -0
  100. package/dist/core/claude-usage-query.js +294 -0
  101. package/dist/core/claude-usage-query.js.map +1 -0
  102. package/dist/core/git-credential-helper.d.ts +57 -0
  103. package/dist/core/git-credential-helper.d.ts.map +1 -0
  104. package/dist/core/git-credential-helper.js +176 -0
  105. package/dist/core/git-credential-helper.js.map +1 -0
  106. package/dist/core/git-sandbox.d.ts +135 -0
  107. package/dist/core/git-sandbox.d.ts.map +1 -0
  108. package/dist/core/git-sandbox.js +907 -0
  109. package/dist/core/git-sandbox.js.map +1 -0
  110. package/dist/core/github-integration.d.ts +66 -0
  111. package/dist/core/github-integration.d.ts.map +1 -0
  112. package/dist/core/github-integration.js +350 -0
  113. package/dist/core/github-integration.js.map +1 -0
  114. package/dist/core/github-oauth.d.ts +88 -0
  115. package/dist/core/github-oauth.d.ts.map +1 -0
  116. package/dist/core/github-oauth.js +244 -0
  117. package/dist/core/github-oauth.js.map +1 -0
  118. package/dist/core/gitlab-integration.d.ts +66 -0
  119. package/dist/core/gitlab-integration.d.ts.map +1 -0
  120. package/dist/core/gitlab-integration.js +353 -0
  121. package/dist/core/gitlab-integration.js.map +1 -0
  122. package/dist/core/gitlab-oauth.d.ts +100 -0
  123. package/dist/core/gitlab-oauth.d.ts.map +1 -0
  124. package/dist/core/gitlab-oauth.js +366 -0
  125. package/dist/core/gitlab-oauth.js.map +1 -0
  126. package/dist/core/insights-extractor.d.ts +68 -0
  127. package/dist/core/insights-extractor.d.ts.map +1 -0
  128. package/dist/core/insights-extractor.js +402 -0
  129. package/dist/core/insights-extractor.js.map +1 -0
  130. package/dist/core/logger.d.ts +27 -0
  131. package/dist/core/logger.d.ts.map +1 -0
  132. package/dist/core/logger.js +70 -0
  133. package/dist/core/logger.js.map +1 -0
  134. package/dist/core/process-runner.d.ts +27 -0
  135. package/dist/core/process-runner.d.ts.map +1 -0
  136. package/dist/core/process-runner.js +147 -0
  137. package/dist/core/process-runner.js.map +1 -0
  138. package/dist/core/project-detector.d.ts +30 -0
  139. package/dist/core/project-detector.d.ts.map +1 -0
  140. package/dist/core/project-detector.js +482 -0
  141. package/dist/core/project-detector.js.map +1 -0
  142. package/dist/core/qr-generator.d.ts +18 -0
  143. package/dist/core/qr-generator.d.ts.map +1 -0
  144. package/dist/core/qr-generator.js +61 -0
  145. package/dist/core/qr-generator.js.map +1 -0
  146. package/dist/core/remote-tunnel-manager.d.ts +59 -0
  147. package/dist/core/remote-tunnel-manager.d.ts.map +1 -0
  148. package/dist/core/remote-tunnel-manager.js +235 -0
  149. package/dist/core/remote-tunnel-manager.js.map +1 -0
  150. package/dist/core/shared-docker-manager.d.ts +41 -0
  151. package/dist/core/shared-docker-manager.d.ts.map +1 -0
  152. package/dist/core/shared-docker-manager.js +409 -0
  153. package/dist/core/shared-docker-manager.js.map +1 -0
  154. package/dist/core/skill-executor.d.ts +25 -0
  155. package/dist/core/skill-executor.d.ts.map +1 -0
  156. package/dist/core/skill-executor.js +171 -0
  157. package/dist/core/skill-executor.js.map +1 -0
  158. package/dist/core/terminal-session.d.ts +149 -0
  159. package/dist/core/terminal-session.d.ts.map +1 -0
  160. package/dist/core/terminal-session.js +2340 -0
  161. package/dist/core/terminal-session.js.map +1 -0
  162. package/dist/core/tunnel-manager.d.ts +35 -0
  163. package/dist/core/tunnel-manager.d.ts.map +1 -0
  164. package/dist/core/tunnel-manager.js +137 -0
  165. package/dist/core/tunnel-manager.js.map +1 -0
  166. package/dist/core/usage-manager.d.ts +57 -0
  167. package/dist/core/usage-manager.d.ts.map +1 -0
  168. package/dist/core/usage-manager.js +363 -0
  169. package/dist/core/usage-manager.js.map +1 -0
  170. package/dist/core/ws-manager.d.ts +39 -0
  171. package/dist/core/ws-manager.d.ts.map +1 -0
  172. package/dist/core/ws-manager.js +190 -0
  173. package/dist/core/ws-manager.js.map +1 -0
  174. package/dist/index.d.ts +7 -0
  175. package/dist/index.d.ts.map +1 -0
  176. package/dist/index.js +229 -0
  177. package/dist/index.js.map +1 -0
  178. package/dist/types.d.ts +868 -0
  179. package/dist/types.d.ts.map +1 -0
  180. package/dist/types.js +119 -0
  181. package/dist/types.js.map +1 -0
  182. package/package.json +96 -0
@@ -0,0 +1,184 @@
1
+ import { existsSync, readdirSync, readFileSync, statSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ /**
5
+ * Convert a repo path to Claude's project folder name format
6
+ * e.g., C:\Users\carlo\Desktop\repos\my-app -> C--Users-carlo-Desktop-repos-my-app
7
+ */
8
+ function pathToClaudeProjectName(repoPath) {
9
+ // Claude converts:
10
+ // - Colon (:) to dash (-)
11
+ // - Backslash (\) to dash (-)
12
+ // - Forward slash (/) to dash (-)
13
+ // So C:\Users\carlo becomes C--Users-carlo (colon and backslash both become dashes)
14
+ return repoPath
15
+ .replace(/:/g, '-')
16
+ .replace(/\\/g, '-')
17
+ .replace(/\//g, '-');
18
+ }
19
+ /**
20
+ * Get the Claude projects directory
21
+ */
22
+ function getClaudeProjectsDir() {
23
+ return join(homedir(), '.claude', 'projects');
24
+ }
25
+ /**
26
+ * Read all Claude sessions for a given repository path
27
+ */
28
+ export function getClaudeSessions(repoPath) {
29
+ const projectsDir = getClaudeProjectsDir();
30
+ const projectName = pathToClaudeProjectName(repoPath);
31
+ const projectDir = join(projectsDir, projectName);
32
+ console.log(`[ClaudeSessionReader] Looking for sessions:`);
33
+ console.log(`[ClaudeSessionReader] Repo path: ${repoPath}`);
34
+ console.log(`[ClaudeSessionReader] Project name: ${projectName}`);
35
+ console.log(`[ClaudeSessionReader] Project dir: ${projectDir}`);
36
+ if (!existsSync(projectDir)) {
37
+ console.log(`[ClaudeSessionReader] No Claude project folder found at ${projectDir}`);
38
+ return [];
39
+ }
40
+ const sessions = [];
41
+ try {
42
+ const files = readdirSync(projectDir);
43
+ for (const file of files) {
44
+ if (!file.endsWith('.jsonl'))
45
+ continue;
46
+ const filePath = join(projectDir, file);
47
+ const sessionId = file.replace('.jsonl', '');
48
+ try {
49
+ const stat = statSync(filePath);
50
+ const content = readFileSync(filePath, 'utf-8');
51
+ const lines = content.split('\n').filter(line => line.trim());
52
+ if (lines.length === 0)
53
+ continue;
54
+ // Parse session data
55
+ let summary = '';
56
+ let branch;
57
+ let messageCount = 0;
58
+ let firstUserMessage = '';
59
+ let lastTimestamp;
60
+ for (const line of lines) {
61
+ try {
62
+ const data = JSON.parse(line);
63
+ // Get the first user message as the title (like Claude Code does)
64
+ if (data.type === 'user' && data.message?.role === 'user' && data.message?.content) {
65
+ messageCount++;
66
+ if (!firstUserMessage) {
67
+ // Extract first user message content
68
+ const content = typeof data.message.content === 'string'
69
+ ? data.message.content
70
+ : Array.isArray(data.message.content)
71
+ ? data.message.content.find((c) => c.type === 'text')?.content || ''
72
+ : '';
73
+ firstUserMessage = content.split('\n')[0].trim(); // First line only
74
+ }
75
+ // Track timestamp
76
+ if (data.timestamp) {
77
+ lastTimestamp = new Date(data.timestamp);
78
+ }
79
+ }
80
+ // Count assistant messages too
81
+ if (data.type === 'assistant' && data.message?.role === 'assistant') {
82
+ messageCount++;
83
+ if (data.timestamp) {
84
+ lastTimestamp = new Date(data.timestamp);
85
+ }
86
+ }
87
+ // Get git branch
88
+ if (data.gitBranch && !branch) {
89
+ branch = data.gitBranch;
90
+ }
91
+ // Also check for summaries as fallback
92
+ if (data.type === 'summary' && data.summary && !summary) {
93
+ summary = data.summary;
94
+ }
95
+ }
96
+ catch {
97
+ // Skip unparseable lines
98
+ }
99
+ }
100
+ // Use first user message as title, fall back to summary
101
+ const displayTitle = firstUserMessage || summary || 'Untitled session';
102
+ sessions.push({
103
+ id: sessionId,
104
+ summary: displayTitle,
105
+ timestamp: lastTimestamp || stat.mtime,
106
+ messageCount,
107
+ branch,
108
+ filePath,
109
+ });
110
+ }
111
+ catch (error) {
112
+ console.error(`[ClaudeSessionReader] Error reading session ${file}:`, error);
113
+ }
114
+ }
115
+ // Sort by timestamp (most recent first)
116
+ sessions.sort((a, b) => b.timestamp.getTime() - a.timestamp.getTime());
117
+ console.log(`[ClaudeSessionReader] Found ${sessions.length} sessions for ${repoPath}`);
118
+ return sessions;
119
+ }
120
+ catch (error) {
121
+ console.error('[ClaudeSessionReader] Error reading sessions:', error);
122
+ return [];
123
+ }
124
+ }
125
+ /**
126
+ * Format relative time (e.g., "10 minutes ago", "3 days ago")
127
+ */
128
+ export function formatRelativeTime(date) {
129
+ const now = Date.now();
130
+ const diff = now - date.getTime();
131
+ const seconds = Math.floor(diff / 1000);
132
+ const minutes = Math.floor(seconds / 60);
133
+ const hours = Math.floor(minutes / 60);
134
+ const days = Math.floor(hours / 24);
135
+ const weeks = Math.floor(days / 7);
136
+ if (weeks > 0)
137
+ return `${weeks} week${weeks > 1 ? 's' : ''} ago`;
138
+ if (days > 0)
139
+ return `${days} day${days > 1 ? 's' : ''} ago`;
140
+ if (hours > 0)
141
+ return `${hours} hour${hours > 1 ? 's' : ''} ago`;
142
+ if (minutes > 0)
143
+ return `${minutes} minute${minutes > 1 ? 's' : ''} ago`;
144
+ return 'just now';
145
+ }
146
+ /**
147
+ * Format session list for display (similar to Claude Code's /resume output)
148
+ */
149
+ export function formatSessionList(sessions, limit = 20) {
150
+ if (sessions.length === 0) {
151
+ return '*No Claude sessions found for this repository.*\n\nStart a conversation to create your first session.';
152
+ }
153
+ const displaySessions = sessions.slice(0, limit);
154
+ const lines = displaySessions.map((session, index) => {
155
+ const relTime = formatRelativeTime(session.timestamp);
156
+ const msgCount = session.messageCount;
157
+ const branch = session.branch ? ` · ${session.branch}` : '';
158
+ // Truncate summary if too long
159
+ const maxSummaryLen = 80;
160
+ const summary = session.summary.length > maxSummaryLen
161
+ ? session.summary.slice(0, maxSummaryLen) + '...'
162
+ : session.summary;
163
+ return `**${index + 1}.** ${summary}\n _${relTime} · ${msgCount} messages${branch}_`;
164
+ });
165
+ const header = `**Resume Session** _(${sessions.length} sessions)_\n`;
166
+ const footer = sessions.length > limit
167
+ ? `\n\n_Showing ${limit} of ${sessions.length} sessions_`
168
+ : '';
169
+ const instructions = '\n\n_Type \`/resume <number>\` to resume a session, or use tabs to switch ClaudeDesk sessions._';
170
+ return header + '\n' + lines.join('\n\n') + footer + instructions;
171
+ }
172
+ /**
173
+ * Get a specific session by index (1-based) or ID
174
+ */
175
+ export function getSessionByRef(sessions, ref) {
176
+ // Try as number first (1-based index)
177
+ const num = parseInt(ref, 10);
178
+ if (!isNaN(num) && num > 0 && num <= sessions.length) {
179
+ return sessions[num - 1];
180
+ }
181
+ // Try as session ID
182
+ return sessions.find(s => s.id === ref || s.id.startsWith(ref));
183
+ }
184
+ //# sourceMappingURL=claude-session-reader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-session-reader.js","sourceRoot":"","sources":["../../src/core/claude-session-reader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,WAAW,EAAE,YAAY,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAC5B,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAW7B;;;GAGG;AACH,SAAS,uBAAuB,CAAC,QAAgB;IAC/C,mBAAmB;IACnB,0BAA0B;IAC1B,8BAA8B;IAC9B,kCAAkC;IAClC,oFAAoF;IACpF,OAAO,QAAQ;SACZ,OAAO,CAAC,IAAI,EAAE,GAAG,CAAC;SAClB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;SACnB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;GAEG;AACH,SAAS,oBAAoB;IAC3B,OAAO,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,EAAE,UAAU,CAAC,CAAC;AAChD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAgB;IAChD,MAAM,WAAW,GAAG,oBAAoB,EAAE,CAAC;IAC3C,MAAM,WAAW,GAAG,uBAAuB,CAAC,QAAQ,CAAC,CAAC;IACtD,MAAM,UAAU,GAAG,IAAI,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;IAElD,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IAC3D,OAAO,CAAC,GAAG,CAAC,sCAAsC,QAAQ,EAAE,CAAC,CAAC;IAC9D,OAAO,CAAC,GAAG,CAAC,yCAAyC,WAAW,EAAE,CAAC,CAAC;IACpE,OAAO,CAAC,GAAG,CAAC,wCAAwC,UAAU,EAAE,CAAC,CAAC;IAElE,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,2DAA2D,UAAU,EAAE,CAAC,CAAC;QACrF,OAAO,EAAE,CAAC;IACZ,CAAC;IAED,MAAM,QAAQ,GAAoB,EAAE,CAAC;IAErC,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,WAAW,CAAC,UAAU,CAAC,CAAC;QAEtC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;YACzB,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC;gBAAE,SAAS;YAEvC,MAAM,QAAQ,GAAG,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;YACxC,MAAM,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,EAAE,EAAE,CAAC,CAAC;YAE7C,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,QAAQ,CAAC,QAAQ,CAAC,CAAC;gBAChC,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBAChD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC;gBAE9D,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;oBAAE,SAAS;gBAEjC,qBAAqB;gBACrB,IAAI,OAAO,GAAG,EAAE,CAAC;gBACjB,IAAI,MAA0B,CAAC;gBAC/B,IAAI,YAAY,GAAG,CAAC,CAAC;gBACrB,IAAI,gBAAgB,GAAG,EAAE,CAAC;gBAC1B,IAAI,aAA+B,CAAC;gBAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,IAAI,CAAC;wBACH,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;wBAE9B,kEAAkE;wBAClE,IAAI,IAAI,CAAC,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,CAAC;4BACnF,YAAY,EAAE,CAAC;4BACf,IAAI,CAAC,gBAAgB,EAAE,CAAC;gCACtB,qCAAqC;gCACrC,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,KAAK,QAAQ;oCACtD,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO;oCACtB,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC;wCACnC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAqC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,MAAM,CAAC,EAAE,OAAO,IAAI,EAAE;wCACxG,CAAC,CAAC,EAAE,CAAC;gCACT,gBAAgB,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,kBAAkB;4BACtE,CAAC;4BACD,kBAAkB;4BAClB,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gCACnB,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;4BAC3C,CAAC;wBACH,CAAC;wBAED,+BAA+B;wBAC/B,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,IAAI,IAAI,CAAC,OAAO,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;4BACpE,YAAY,EAAE,CAAC;4BACf,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;gCACnB,aAAa,GAAG,IAAI,IAAI,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;4BAC3C,CAAC;wBACH,CAAC;wBAED,iBAAiB;wBACjB,IAAI,IAAI,CAAC,SAAS,IAAI,CAAC,MAAM,EAAE,CAAC;4BAC9B,MAAM,GAAG,IAAI,CAAC,SAAS,CAAC;wBAC1B,CAAC;wBAED,uCAAuC;wBACvC,IAAI,IAAI,CAAC,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;4BACxD,OAAO,GAAG,IAAI,CAAC,OAAO,CAAC;wBACzB,CAAC;oBACH,CAAC;oBAAC,MAAM,CAAC;wBACP,yBAAyB;oBAC3B,CAAC;gBACH,CAAC;gBAED,wDAAwD;gBACxD,MAAM,YAAY,GAAG,gBAAgB,IAAI,OAAO,IAAI,kBAAkB,CAAC;gBAEvE,QAAQ,CAAC,IAAI,CAAC;oBACZ,EAAE,EAAE,SAAS;oBACb,OAAO,EAAE,YAAY;oBACrB,SAAS,EAAE,aAAa,IAAI,IAAI,CAAC,KAAK;oBACtC,YAAY;oBACZ,MAAM;oBACN,QAAQ;iBACT,CAAC,CAAC;YACL,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,KAAK,CAAC,+CAA+C,IAAI,GAAG,EAAE,KAAK,CAAC,CAAC;YAC/E,CAAC;QACH,CAAC;QAED,wCAAwC;QACxC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC,SAAS,CAAC,OAAO,EAAE,CAAC,CAAC;QAEvE,OAAO,CAAC,GAAG,CAAC,+BAA+B,QAAQ,CAAC,MAAM,iBAAiB,QAAQ,EAAE,CAAC,CAAC;QACvF,OAAO,QAAQ,CAAC;IAClB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,KAAK,CAAC,+CAA+C,EAAE,KAAK,CAAC,CAAC;QACtE,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,kBAAkB,CAAC,IAAU;IAC3C,MAAM,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACvB,MAAM,IAAI,GAAG,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC;IAElC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,IAAI,CAAC,CAAC;IACxC,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACzC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC,CAAC;IACvC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,GAAG,EAAE,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC;IAEnC,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACjE,IAAI,IAAI,GAAG,CAAC;QAAE,OAAO,GAAG,IAAI,OAAO,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IAC7D,IAAI,KAAK,GAAG,CAAC;QAAE,OAAO,GAAG,KAAK,QAAQ,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACjE,IAAI,OAAO,GAAG,CAAC;QAAE,OAAO,GAAG,OAAO,UAAU,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,MAAM,CAAC;IACzE,OAAO,UAAU,CAAC;AACpB,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,QAAyB,EAAE,QAAgB,EAAE;IAC7E,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC1B,OAAO,uGAAuG,CAAC;IACjH,CAAC;IAED,MAAM,eAAe,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEjD,MAAM,KAAK,GAAG,eAAe,CAAC,GAAG,CAAC,CAAC,OAAO,EAAE,KAAK,EAAE,EAAE;QACnD,MAAM,OAAO,GAAG,kBAAkB,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QACtD,MAAM,QAAQ,GAAG,OAAO,CAAC,YAAY,CAAC;QACtC,MAAM,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,MAAM,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;QAE5D,+BAA+B;QAC/B,MAAM,aAAa,GAAG,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,MAAM,GAAG,aAAa;YACpD,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,aAAa,CAAC,GAAG,KAAK;YACjD,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC;QAEpB,OAAO,KAAK,KAAK,GAAG,CAAC,OAAO,OAAO,SAAS,OAAO,MAAM,QAAQ,YAAY,MAAM,GAAG,CAAC;IACzF,CAAC,CAAC,CAAC;IAEH,MAAM,MAAM,GAAG,wBAAwB,QAAQ,CAAC,MAAM,eAAe,CAAC;IACtE,MAAM,MAAM,GAAG,QAAQ,CAAC,MAAM,GAAG,KAAK;QACpC,CAAC,CAAC,gBAAgB,KAAK,OAAO,QAAQ,CAAC,MAAM,YAAY;QACzD,CAAC,CAAC,EAAE,CAAC;IAEP,MAAM,YAAY,GAAG,iGAAiG,CAAC;IAEvH,OAAO,MAAM,GAAG,IAAI,GAAG,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,MAAM,GAAG,YAAY,CAAC;AACpE,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,eAAe,CAAC,QAAyB,EAAE,GAAW;IACpE,sCAAsC;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;IAC9B,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,GAAG,GAAG,CAAC,IAAI,GAAG,IAAI,QAAQ,CAAC,MAAM,EAAE,CAAC;QACrD,OAAO,QAAQ,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IAC3B,CAAC;IAED,oBAAoB;IACpB,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,GAAG,IAAI,CAAC,CAAC,EAAE,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC;AAClE,CAAC"}
@@ -0,0 +1,78 @@
1
+ import { ClaudeUsageQuota } from '../types.js';
2
+ /**
3
+ * Processed usage data for display
4
+ */
5
+ export interface ClaudeUsageStats {
6
+ today: {
7
+ messageCount: number;
8
+ sessionCount: number;
9
+ toolCallCount: number;
10
+ tokensByModel: Record<string, number>;
11
+ };
12
+ week: {
13
+ messageCount: number;
14
+ sessionCount: number;
15
+ toolCallCount: number;
16
+ tokensByModel: Record<string, number>;
17
+ };
18
+ modelUsage: Record<string, {
19
+ inputTokens: number;
20
+ outputTokens: number;
21
+ cacheReadTokens: number;
22
+ cacheCreationTokens: number;
23
+ }>;
24
+ totalSessions: number;
25
+ totalMessages: number;
26
+ firstSessionDate: string | null;
27
+ lastUpdated: string;
28
+ }
29
+ /**
30
+ * Query Claude Code's local stats cache file.
31
+ * Results are cached for 30 seconds.
32
+ *
33
+ * @param forceRefresh - If true, bypasses the cache
34
+ * @returns Parsed usage stats, or null if unavailable
35
+ */
36
+ export declare function queryClaudeUsage(forceRefresh?: boolean): Promise<ClaudeUsageStats | null>;
37
+ /**
38
+ * Clear the usage cache.
39
+ */
40
+ export declare function clearUsageCache(): void;
41
+ /**
42
+ * Check if Claude usage data is available.
43
+ */
44
+ export declare function hasClaudeUsage(): Promise<boolean>;
45
+ /**
46
+ * Format model name for display (extract short name)
47
+ */
48
+ export declare function formatModelName(modelId: string): string;
49
+ /**
50
+ * Format token count for display
51
+ */
52
+ export declare function formatTokenCount(tokens: number): string;
53
+ /**
54
+ * Query Claude usage quota from the Anthropic OAuth API.
55
+ *
56
+ * This calls: GET https://api.anthropic.com/api/oauth/usage
57
+ * Returns the 5-hour and 7-day utilization buckets.
58
+ *
59
+ * @param forceRefresh - If true, bypasses the cache
60
+ */
61
+ export declare function queryClaudeQuota(forceRefresh?: boolean): Promise<ClaudeUsageQuota | null>;
62
+ /**
63
+ * Clear the quota cache.
64
+ */
65
+ export declare function clearQuotaCache(): void;
66
+ /**
67
+ * Check if Claude quota data is available.
68
+ */
69
+ export declare function hasClaudeQuota(): Promise<boolean>;
70
+ /**
71
+ * Format quota percentage for display
72
+ */
73
+ export declare function formatQuotaPercent(utilization: number): string;
74
+ /**
75
+ * Get time until quota reset in human-readable format
76
+ */
77
+ export declare function getTimeUntilReset(resetsAt: string): string;
78
+ //# sourceMappingURL=claude-usage-query.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-usage-query.d.ts","sourceRoot":"","sources":["../../src/core/claude-usage-query.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAwC/C;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAE/B,KAAK,EAAE;QACL,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACvC,CAAC;IAEF,IAAI,EAAE;QACJ,YAAY,EAAE,MAAM,CAAC;QACrB,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,CAAC;QACtB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;KACvC,CAAC;IAEF,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,YAAY,EAAE,MAAM,CAAC;QACrB,eAAe,EAAE,MAAM,CAAC;QACxB,mBAAmB,EAAE,MAAM,CAAC;KAC7B,CAAC,CAAC;IAEH,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;IACtB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,WAAW,EAAE,MAAM,CAAC;CACrB;AA+ED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,UAAQ,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA8B7F;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAGvD;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAKvD;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAKvD;AAiFD;;;;;;;GAOG;AACH,wBAAsB,gBAAgB,CAAC,YAAY,UAAQ,GAAG,OAAO,CAAC,gBAAgB,GAAG,IAAI,CAAC,CA4D7F;AAED;;GAEG;AACH,wBAAgB,eAAe,IAAI,IAAI,CAEtC;AAED;;GAEG;AACH,wBAAsB,cAAc,IAAI,OAAO,CAAC,OAAO,CAAC,CAGvD;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,MAAM,CAE9D;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAc1D"}
@@ -0,0 +1,294 @@
1
+ import { readFileSync, existsSync } from 'fs';
2
+ import { join } from 'path';
3
+ import { homedir } from 'os';
4
+ // Cache for usage data
5
+ let cachedStats = null;
6
+ let cacheTimestamp = 0;
7
+ const CACHE_TTL_MS = 30_000; // 30 seconds cache
8
+ /**
9
+ * Get the path to Claude Code's stats-cache.json file
10
+ */
11
+ function getStatsCachePath() {
12
+ return join(homedir(), '.claude', 'stats-cache.json');
13
+ }
14
+ /**
15
+ * Parse the stats-cache.json and compute usage stats
16
+ */
17
+ function parseStatsCache(raw) {
18
+ const now = new Date();
19
+ const todayStr = now.toISOString().split('T')[0];
20
+ // Calculate week start (Sunday)
21
+ const dayOfWeek = now.getDay();
22
+ const weekStart = new Date(now);
23
+ weekStart.setDate(now.getDate() - dayOfWeek);
24
+ weekStart.setHours(0, 0, 0, 0);
25
+ // Today's activity
26
+ const todayActivity = raw.dailyActivity.find(d => d.date === todayStr);
27
+ const todayTokens = raw.dailyModelTokens.find(d => d.date === todayStr);
28
+ // Week's activity (sum of last 7 days from week start)
29
+ const weekActivity = raw.dailyActivity
30
+ .filter(d => new Date(d.date) >= weekStart)
31
+ .reduce((acc, day) => ({
32
+ messageCount: acc.messageCount + day.messageCount,
33
+ sessionCount: acc.sessionCount + day.sessionCount,
34
+ toolCallCount: acc.toolCallCount + day.toolCallCount,
35
+ }), { messageCount: 0, sessionCount: 0, toolCallCount: 0 });
36
+ // Week's tokens by model
37
+ const weekTokensByModel = {};
38
+ raw.dailyModelTokens
39
+ .filter(d => new Date(d.date) >= weekStart)
40
+ .forEach(day => {
41
+ Object.entries(day.tokensByModel).forEach(([model, tokens]) => {
42
+ weekTokensByModel[model] = (weekTokensByModel[model] || 0) + tokens;
43
+ });
44
+ });
45
+ return {
46
+ today: {
47
+ messageCount: todayActivity?.messageCount || 0,
48
+ sessionCount: todayActivity?.sessionCount || 0,
49
+ toolCallCount: todayActivity?.toolCallCount || 0,
50
+ tokensByModel: todayTokens?.tokensByModel || {},
51
+ },
52
+ week: {
53
+ ...weekActivity,
54
+ tokensByModel: weekTokensByModel,
55
+ },
56
+ modelUsage: Object.fromEntries(Object.entries(raw.modelUsage).map(([model, usage]) => [
57
+ model,
58
+ {
59
+ inputTokens: usage.inputTokens,
60
+ outputTokens: usage.outputTokens,
61
+ cacheReadTokens: usage.cacheReadInputTokens,
62
+ cacheCreationTokens: usage.cacheCreationInputTokens,
63
+ },
64
+ ])),
65
+ totalSessions: raw.totalSessions,
66
+ totalMessages: raw.totalMessages,
67
+ firstSessionDate: raw.firstSessionDate || null,
68
+ lastUpdated: new Date().toISOString(),
69
+ };
70
+ }
71
+ /**
72
+ * Query Claude Code's local stats cache file.
73
+ * Results are cached for 30 seconds.
74
+ *
75
+ * @param forceRefresh - If true, bypasses the cache
76
+ * @returns Parsed usage stats, or null if unavailable
77
+ */
78
+ export async function queryClaudeUsage(forceRefresh = false) {
79
+ const now = Date.now();
80
+ // Return cached data if still valid
81
+ if (!forceRefresh && cachedStats && (now - cacheTimestamp) < CACHE_TTL_MS) {
82
+ return cachedStats;
83
+ }
84
+ try {
85
+ const statsPath = getStatsCachePath();
86
+ if (!existsSync(statsPath)) {
87
+ console.log('[claude-usage-query] Stats cache file not found:', statsPath);
88
+ return cachedStats; // Return stale cache if available
89
+ }
90
+ const content = readFileSync(statsPath, 'utf-8');
91
+ const raw = JSON.parse(content);
92
+ const parsed = parseStatsCache(raw);
93
+ cachedStats = parsed;
94
+ cacheTimestamp = now;
95
+ return parsed;
96
+ }
97
+ catch (error) {
98
+ if (error instanceof Error) {
99
+ console.log('[claude-usage-query] Error reading stats cache:', error.message);
100
+ }
101
+ return cachedStats; // Return stale cache if available
102
+ }
103
+ }
104
+ /**
105
+ * Clear the usage cache.
106
+ */
107
+ export function clearUsageCache() {
108
+ cacheTimestamp = 0;
109
+ }
110
+ /**
111
+ * Check if Claude usage data is available.
112
+ */
113
+ export async function hasClaudeUsage() {
114
+ const stats = await queryClaudeUsage();
115
+ return stats !== null;
116
+ }
117
+ /**
118
+ * Format model name for display (extract short name)
119
+ */
120
+ export function formatModelName(modelId) {
121
+ if (modelId.includes('opus'))
122
+ return 'Opus';
123
+ if (modelId.includes('sonnet'))
124
+ return 'Sonnet';
125
+ if (modelId.includes('haiku'))
126
+ return 'Haiku';
127
+ return modelId.split('-').slice(1, 3).join(' ');
128
+ }
129
+ /**
130
+ * Format token count for display
131
+ */
132
+ export function formatTokenCount(tokens) {
133
+ if (tokens < 1000)
134
+ return tokens.toString();
135
+ if (tokens < 1_000_000)
136
+ return `${(tokens / 1000).toFixed(1)}K`;
137
+ if (tokens < 1_000_000_000)
138
+ return `${(tokens / 1_000_000).toFixed(1)}M`;
139
+ return `${(tokens / 1_000_000_000).toFixed(2)}B`;
140
+ }
141
+ // ============================================================================
142
+ // Claude OAuth Quota API
143
+ // ============================================================================
144
+ // Cache for quota data
145
+ let cachedQuota = null;
146
+ let quotaCacheTimestamp = 0;
147
+ const QUOTA_CACHE_TTL_MS = 60_000; // 1 minute cache
148
+ /**
149
+ * Get Claude Code OAuth token from local storage.
150
+ *
151
+ * Claude Code stores credentials in ~/.claude/.credentials.json
152
+ * under the 'claudeAiOauth' key.
153
+ */
154
+ async function getClaudeOAuthToken() {
155
+ // Primary location: ~/.claude/.credentials.json
156
+ const credentialsPath = join(homedir(), '.claude', '.credentials.json');
157
+ if (existsSync(credentialsPath)) {
158
+ try {
159
+ const content = readFileSync(credentialsPath, 'utf-8');
160
+ const creds = JSON.parse(content);
161
+ if (creds.claudeAiOauth?.accessToken) {
162
+ // Check if token is expired
163
+ if (creds.claudeAiOauth.expiresAt) {
164
+ const expiresAt = new Date(creds.claudeAiOauth.expiresAt);
165
+ if (expiresAt <= new Date()) {
166
+ console.log('[claude-usage-query] OAuth token is expired');
167
+ // Token is expired, but we'll still try it - the API will tell us for sure
168
+ }
169
+ }
170
+ console.log('[claude-usage-query] Found token in .credentials.json');
171
+ return creds.claudeAiOauth.accessToken;
172
+ }
173
+ }
174
+ catch (error) {
175
+ console.log('[claude-usage-query] Error reading .credentials.json:', error);
176
+ }
177
+ }
178
+ // Fallback: Check for older credentials.json format (without dot prefix)
179
+ const oldCredentialsPath = join(homedir(), '.claude', 'credentials.json');
180
+ if (existsSync(oldCredentialsPath)) {
181
+ try {
182
+ const content = readFileSync(oldCredentialsPath, 'utf-8');
183
+ const creds = JSON.parse(content);
184
+ // Try both formats
185
+ const token = creds.claudeAiOauth?.accessToken || creds.accessToken;
186
+ if (token) {
187
+ console.log('[claude-usage-query] Found token in credentials.json (legacy)');
188
+ return token;
189
+ }
190
+ }
191
+ catch (error) {
192
+ console.log('[claude-usage-query] Error reading credentials.json:', error);
193
+ }
194
+ }
195
+ console.log('[claude-usage-query] No OAuth token found in', credentialsPath);
196
+ return null;
197
+ }
198
+ /**
199
+ * Query Claude usage quota from the Anthropic OAuth API.
200
+ *
201
+ * This calls: GET https://api.anthropic.com/api/oauth/usage
202
+ * Returns the 5-hour and 7-day utilization buckets.
203
+ *
204
+ * @param forceRefresh - If true, bypasses the cache
205
+ */
206
+ export async function queryClaudeQuota(forceRefresh = false) {
207
+ const now = Date.now();
208
+ // Return cached data if still valid
209
+ if (!forceRefresh && cachedQuota && (now - quotaCacheTimestamp) < QUOTA_CACHE_TTL_MS) {
210
+ return cachedQuota;
211
+ }
212
+ try {
213
+ const token = await getClaudeOAuthToken();
214
+ if (!token) {
215
+ console.log('[claude-usage-query] No OAuth token available for quota query');
216
+ return cachedQuota; // Return stale cache if available
217
+ }
218
+ const response = await fetch('https://api.anthropic.com/api/oauth/usage', {
219
+ method: 'GET',
220
+ headers: {
221
+ 'Authorization': `Bearer ${token}`,
222
+ 'anthropic-beta': 'oauth-2025-04-20',
223
+ 'Accept': 'application/json',
224
+ },
225
+ });
226
+ if (!response.ok) {
227
+ const errorText = await response.text();
228
+ console.log(`[claude-usage-query] Quota API error (${response.status}):`, errorText);
229
+ return cachedQuota; // Return stale cache
230
+ }
231
+ const data = await response.json();
232
+ // Parse the response - API returns utilization as 0-100, we normalize to 0-1
233
+ const quota = {
234
+ five_hour: {
235
+ utilization: (data.five_hour?.utilization ?? 0) / 100,
236
+ resets_at: data.five_hour?.resets_at ?? new Date().toISOString(),
237
+ },
238
+ seven_day: {
239
+ utilization: (data.seven_day?.utilization ?? 0) / 100,
240
+ resets_at: data.seven_day?.resets_at ?? new Date().toISOString(),
241
+ },
242
+ lastUpdated: new Date().toISOString(),
243
+ };
244
+ cachedQuota = quota;
245
+ quotaCacheTimestamp = now;
246
+ console.log('[claude-usage-query] Quota fetched successfully:', {
247
+ fiveHour: `${(quota.five_hour.utilization * 100).toFixed(1)}%`,
248
+ sevenDay: `${(quota.seven_day.utilization * 100).toFixed(1)}%`,
249
+ });
250
+ return quota;
251
+ }
252
+ catch (error) {
253
+ if (error instanceof Error) {
254
+ console.log('[claude-usage-query] Error fetching quota:', error.message);
255
+ }
256
+ return cachedQuota; // Return stale cache if available
257
+ }
258
+ }
259
+ /**
260
+ * Clear the quota cache.
261
+ */
262
+ export function clearQuotaCache() {
263
+ quotaCacheTimestamp = 0;
264
+ }
265
+ /**
266
+ * Check if Claude quota data is available.
267
+ */
268
+ export async function hasClaudeQuota() {
269
+ const quota = await queryClaudeQuota();
270
+ return quota !== null;
271
+ }
272
+ /**
273
+ * Format quota percentage for display
274
+ */
275
+ export function formatQuotaPercent(utilization) {
276
+ return `${(utilization * 100).toFixed(1)}%`;
277
+ }
278
+ /**
279
+ * Get time until quota reset in human-readable format
280
+ */
281
+ export function getTimeUntilReset(resetsAt) {
282
+ const now = new Date();
283
+ const resetTime = new Date(resetsAt);
284
+ const diffMs = resetTime.getTime() - now.getTime();
285
+ if (diffMs <= 0)
286
+ return 'now';
287
+ const hours = Math.floor(diffMs / (1000 * 60 * 60));
288
+ const minutes = Math.floor((diffMs % (1000 * 60 * 60)) / (1000 * 60));
289
+ if (hours > 0) {
290
+ return `${hours}h ${minutes}m`;
291
+ }
292
+ return `${minutes}m`;
293
+ }
294
+ //# sourceMappingURL=claude-usage-query.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"claude-usage-query.js","sourceRoot":"","sources":["../../src/core/claude-usage-query.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Creates a temporary credential helper script that returns the OAuth token.
3
+ * The script is compatible with git's credential helper protocol.
4
+ * @param token - The OAuth access token
5
+ * @param platform - The git platform ('github' or 'gitlab')
6
+ * @returns Path to the temporary credential helper script
7
+ */
8
+ export declare function createCredentialHelperScript(token: string, platform: 'github' | 'gitlab'): string;
9
+ /**
10
+ * Removes a temporary credential helper script.
11
+ * SEC-06: Improved cleanup with logging for debugging failed deletions.
12
+ * @param scriptPath - Path to the script to remove
13
+ */
14
+ export declare function removeCredentialHelperScript(scriptPath: string): void;
15
+ /**
16
+ * Get environment variables to inject for git authentication.
17
+ * These environment variables enable git to use the OAuth token for HTTPS operations.
18
+ *
19
+ * @param token - The OAuth access token
20
+ * @param platform - The git platform ('github' or 'gitlab')
21
+ * @param username - Optional username (defaults based on platform)
22
+ * @returns Record of environment variables to set
23
+ */
24
+ export declare function getGitCredentialEnv(token: string, platform: 'github' | 'gitlab', username?: string): Record<string, string>;
25
+ /**
26
+ * Clean up any temporary files created by getGitCredentialEnv.
27
+ * Call this after git operations complete.
28
+ *
29
+ * @param env - The environment object returned by getGitCredentialEnv
30
+ */
31
+ export declare function cleanupGitCredentialEnv(env: Record<string, string>): void;
32
+ /**
33
+ * Configure git to use token authentication for a specific remote URL.
34
+ * This modifies the URL to include the token inline (for temporary use).
35
+ *
36
+ * @param remoteUrl - The original remote URL (e.g., https://github.com/user/repo.git)
37
+ * @param token - The OAuth access token
38
+ * @param platform - The git platform
39
+ * @returns The modified URL with embedded credentials
40
+ */
41
+ export declare function getAuthenticatedRemoteUrl(remoteUrl: string, token: string, platform: 'github' | 'gitlab'): string;
42
+ /**
43
+ * Detect the git platform from a remote URL.
44
+ *
45
+ * @param remoteUrl - The remote URL to analyze
46
+ * @returns 'github', 'gitlab', or null if unknown
47
+ */
48
+ export declare function detectPlatformFromUrl(remoteUrl: string): 'github' | 'gitlab' | null;
49
+ /**
50
+ * Check if a remote URL is using HTTPS (vs SSH).
51
+ * OAuth tokens only work with HTTPS remotes.
52
+ *
53
+ * @param remoteUrl - The remote URL to check
54
+ * @returns true if the URL is HTTPS
55
+ */
56
+ export declare function isHttpsRemote(remoteUrl: string): boolean;
57
+ //# sourceMappingURL=git-credential-helper.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"git-credential-helper.d.ts","sourceRoot":"","sources":["../../src/core/git-credential-helper.ts"],"names":[],"mappings":"AAiBA;;;;;;GAMG;AACH,wBAAgB,4BAA4B,CAAC,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAkCjG;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,CAAC,UAAU,EAAE,MAAM,GAAG,IAAI,CAerE;AAED;;;;;;;;GAQG;AACH,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GAAG,QAAQ,EAC7B,QAAQ,CAAC,EAAE,MAAM,GAChB,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CA8BxB;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAKzE;AAED;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,SAAS,EAAE,MAAM,EACjB,KAAK,EAAE,MAAM,EACb,QAAQ,EAAE,QAAQ,GAAG,QAAQ,GAC5B,MAAM,CAgBR;AAED;;;;;GAKG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,GAAG,IAAI,CAYnF;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAExD"}